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
@@ -43,7 +43,8 @@ const definition = {
43
43
  },
44
44
  char: {
45
45
  type: 'string',
46
- description: 'Character to draw (empty, dot, circle, square, star, heart, tree, house, sun, moon, water, mountain, person, cat, dog, car, plane, flower, umbrella, rainbow)'
46
+ description:
47
+ 'Character to draw (empty, dot, circle, square, star, heart, tree, house, sun, moon, water, mountain, person, cat, dog, car, plane, flower, umbrella, rainbow)'
47
48
  },
48
49
  position: {
49
50
  type: 'number',
@@ -73,7 +74,7 @@ const definition = {
73
74
  // Get or create global game room
74
75
  function getGameRoom(gameType, roomId = 'default') {
75
76
  const key = `${gameType}:${roomId}`;
76
-
77
+
77
78
  if (!globalGameRooms[key]) {
78
79
  if (gameType === 'drawing') {
79
80
  globalGameRooms[key] = drawing.createInitialDrawingState();
@@ -86,7 +87,7 @@ function getGameRoom(gameType, roomId = 'default') {
86
87
  globalGameRooms[key] = storybuilder.createInitialStoryBuilderState();
87
88
  }
88
89
  }
89
-
90
+
90
91
  return globalGameRooms[key];
91
92
  }
92
93
 
@@ -106,7 +107,7 @@ async function handler(args) {
106
107
 
107
108
  // Get current game state
108
109
  const gameState = getGameRoom(game, roomId);
109
-
110
+
110
111
  try {
111
112
  if (game === 'drawing') {
112
113
  if (action === 'join') {
@@ -115,37 +116,41 @@ async function handler(args) {
115
116
  return { display: `❌ ${result.error}` };
116
117
  }
117
118
  updateGameRoom(game, roomId, result.gameState);
118
- return { display: `🎨 **Joined Collaborative Drawing!**\n\n${drawing.formatDrawingDisplay(result.gameState)}\n\nUse commands like:\n• \`vibe multiplayer-game drawing draw --x 10 --y 5 --char star\`\n• \`vibe multiplayer-game drawing theme --theme "house"\`` };
119
-
119
+ return {
120
+ display: `🎨 **Joined Collaborative Drawing!**\n\n${drawing.formatDrawingDisplay(result.gameState)}\n\nUse commands like:\n• \`vibe multiplayer-game drawing draw --x 10 --y 5 --char star\`\n• \`vibe multiplayer-game drawing theme --theme "house"\``
121
+ };
120
122
  } else if (action === 'draw') {
121
123
  if (x === undefined || y === undefined || !char) {
122
- return { display: 'Need x, y coordinates and character to draw. Example: `vibe multiplayer-game drawing draw --x 10 --y 5 --char star`' };
124
+ return {
125
+ display:
126
+ 'Need x, y coordinates and character to draw. Example: `vibe multiplayer-game drawing draw --x 10 --y 5 --char star`'
127
+ };
123
128
  }
124
-
129
+
125
130
  // Convert char name to actual character
126
131
  const charMap = drawing.DRAWING_CHARS;
127
132
  const actualChar = charMap[char] || char;
128
-
133
+
129
134
  const result = drawing.makeMove(gameState, x, y, actualChar, myHandle);
130
135
  if (result.error) {
131
136
  return { display: `❌ ${result.error}` };
132
137
  }
133
138
  updateGameRoom(game, roomId, result.gameState);
134
- return { display: `🎨 **Drew ${actualChar} at (${x},${y})**\n\n${drawing.formatDrawingDisplay(result.gameState)}` };
135
-
139
+ return {
140
+ display: `🎨 **Drew ${actualChar} at (${x},${y})**\n\n${drawing.formatDrawingDisplay(result.gameState)}`
141
+ };
136
142
  } else if (action === 'clear') {
137
143
  const x0 = x || 0;
138
144
  const y0 = y || 0;
139
145
  const x1 = args.x1 || x0;
140
146
  const y1 = args.y1 || y0;
141
-
147
+
142
148
  const result = drawing.clearRegion(gameState, x0, y0, x1, y1, myHandle);
143
149
  if (result.error) {
144
150
  return { display: `❌ ${result.error}` };
145
151
  }
146
152
  updateGameRoom(game, roomId, result.gameState);
147
153
  return { display: `🧹 **Cleared region**\n\n${drawing.formatDrawingDisplay(result.gameState)}` };
148
-
149
154
  } else if (action === 'theme') {
150
155
  if (!theme) {
151
156
  return { display: 'Need a theme! Example: `vibe multiplayer-game drawing theme --theme "house"`' };
@@ -156,12 +161,12 @@ async function handler(args) {
156
161
  }
157
162
  updateGameRoom(game, roomId, result.gameState);
158
163
  const tips = drawing.getDrawingTips(theme);
159
- return { display: `🎯 **Set theme: ${theme}**\n\n**Tips:** ${tips.join(', ')}\n\n${drawing.formatDrawingDisplay(result.gameState)}` };
160
-
164
+ return {
165
+ display: `🎯 **Set theme: ${theme}**\n\n**Tips:** ${tips.join(', ')}\n\n${drawing.formatDrawingDisplay(result.gameState)}`
166
+ };
161
167
  } else if (action === 'show') {
162
168
  return { display: drawing.formatDrawingDisplay(gameState) };
163
169
  }
164
-
165
170
  } else if (game === 'multiplayer-tictactoe') {
166
171
  if (action === 'join') {
167
172
  const result = multiTicTacToe.joinRoom(gameState, myHandle, false);
@@ -169,35 +174,41 @@ async function handler(args) {
169
174
  return { display: `❌ ${result.error}` };
170
175
  }
171
176
  updateGameRoom(game, roomId, result.gameState);
172
- return { display: `🎯 **Joined Multiplayer Tic-Tac-Toe!**\n\n${multiTicTacToe.formatMultiplayerTicTacToeDisplay(result.gameState, myHandle)}` };
173
-
177
+ return {
178
+ display: `🎯 **Joined Multiplayer Tic-Tac-Toe!**\n\n${multiTicTacToe.formatMultiplayerTicTacToeDisplay(result.gameState, myHandle)}`
179
+ };
174
180
  } else if (action === 'spectate') {
175
181
  const result = multiTicTacToe.joinRoom(gameState, myHandle, true);
176
182
  if (result.error) {
177
183
  return { display: `❌ ${result.error}` };
178
184
  }
179
185
  updateGameRoom(game, roomId, result.gameState);
180
- return { display: `👁️ **Now spectating Multiplayer Tic-Tac-Toe**\n\n${multiTicTacToe.formatMultiplayerTicTacToeDisplay(result.gameState, myHandle)}` };
181
-
186
+ return {
187
+ display: `👁️ **Now spectating Multiplayer Tic-Tac-Toe**\n\n${multiTicTacToe.formatMultiplayerTicTacToeDisplay(result.gameState, myHandle)}`
188
+ };
182
189
  } else if (action === 'move') {
183
190
  if (!position) {
184
- return { display: 'Need position (1-9)! Example: `vibe multiplayer-game multiplayer-tictactoe move --position 5`' };
191
+ return {
192
+ display: 'Need position (1-9)! Example: `vibe multiplayer-game multiplayer-tictactoe move --position 5`'
193
+ };
185
194
  }
186
195
  const result = multiTicTacToe.makeMove(gameState, position, myHandle);
187
196
  if (result.error) {
188
197
  return { display: `❌ ${result.error}` };
189
198
  }
190
199
  updateGameRoom(game, roomId, result.gameState);
191
- return { display: `🎯 **Played position ${position}**\n\n${multiTicTacToe.formatMultiplayerTicTacToeDisplay(result.gameState, myHandle)}` };
192
-
200
+ return {
201
+ display: `🎯 **Played position ${position}**\n\n${multiTicTacToe.formatMultiplayerTicTacToeDisplay(result.gameState, myHandle)}`
202
+ };
193
203
  } else if (action === 'restart') {
194
204
  const result = multiTicTacToe.restartGame(gameState, myHandle);
195
205
  if (result.error) {
196
206
  return { display: `❌ ${result.error}` };
197
207
  }
198
208
  updateGameRoom(game, roomId, result.gameState);
199
- return { display: `🔄 **Restarted game!**\n\n${multiTicTacToe.formatMultiplayerTicTacToeDisplay(result.gameState, myHandle)}` };
200
-
209
+ return {
210
+ display: `🔄 **Restarted game!**\n\n${multiTicTacToe.formatMultiplayerTicTacToeDisplay(result.gameState, myHandle)}`
211
+ };
201
212
  } else if (action === 'leave') {
202
213
  const result = multiTicTacToe.leaveRoom(gameState, myHandle);
203
214
  if (result.error) {
@@ -205,41 +216,38 @@ async function handler(args) {
205
216
  }
206
217
  updateGameRoom(game, roomId, result.gameState);
207
218
  return { display: '👋 Left the game room.' };
208
-
209
219
  } else if (action === 'show') {
210
220
  return { display: multiTicTacToe.formatMultiplayerTicTacToeDisplay(gameState, myHandle) };
211
221
  }
212
-
213
222
  } else if (game === 'wordchain') {
214
223
  if (action === 'join') {
215
224
  const result = wordchain.addPlayer && wordchain.addPlayer(gameState, myHandle);
216
225
  if (result && result.error) {
217
226
  return { display: `❌ ${result.error}` };
218
227
  }
219
-
228
+
220
229
  // For wordchain, just show the current state since it doesn't have explicit player management
221
- return { display: `🔗 **Joined Word Chain!**\n\n${wordchain.formatWordChainDisplay(gameState)}\n\nAdd words with: \`vibe multiplayer-game wordchain word --word "apple"\`` };
222
-
230
+ return {
231
+ display: `🔗 **Joined Word Chain!**\n\n${wordchain.formatWordChainDisplay(gameState)}\n\nAdd words with: \`vibe multiplayer-game wordchain word --word "apple"\``
232
+ };
223
233
  } else if (action === 'word') {
224
234
  if (!word) {
225
235
  return { display: 'Need a word! Example: `vibe multiplayer-game wordchain word --word "apple"`' };
226
236
  }
227
-
237
+
228
238
  // For wordchain, we need to determine if this is player 1 or 2 move
229
239
  // For simplicity, let's alternate based on move count
230
240
  const isPlayer1Move = gameState.moves % 2 === 0;
231
-
241
+
232
242
  const result = wordchain.makeMove(gameState, word, isPlayer1Move);
233
243
  if (result.error) {
234
244
  return { display: `❌ ${result.error}` };
235
245
  }
236
246
  updateGameRoom(game, roomId, result.gameState);
237
247
  return { display: `🔗 **Added word: ${word}**\n\n${wordchain.formatWordChainDisplay(result.gameState)}` };
238
-
239
248
  } else if (action === 'show') {
240
249
  return { display: wordchain.formatWordChainDisplay(gameState) };
241
250
  }
242
-
243
251
  } else if (game === 'storybuilder') {
244
252
  if (action === 'join') {
245
253
  const result = storybuilder.addPlayer(gameState, myHandle);
@@ -247,11 +255,15 @@ async function handler(args) {
247
255
  return { display: `❌ ${result.error}` };
248
256
  }
249
257
  updateGameRoom(game, roomId, result.gameState);
250
- return { display: `📚 **Joined Story Builder!**\n\n${storybuilder.formatStoryBuilderDisplay(result.gameState)}\n\nAdd sentences with: \`vibe multiplayer-game storybuilder sentence --sentence "Once upon a time..."\`` };
251
-
258
+ return {
259
+ display: `📚 **Joined Story Builder!**\n\n${storybuilder.formatStoryBuilderDisplay(result.gameState)}\n\nAdd sentences with: \`vibe multiplayer-game storybuilder sentence --sentence "Once upon a time..."\``
260
+ };
252
261
  } else if (action === 'sentence') {
253
262
  if (!sentence) {
254
- return { display: 'Need a sentence! Example: `vibe multiplayer-game storybuilder sentence --sentence "Once upon a time..."`' };
263
+ return {
264
+ display:
265
+ 'Need a sentence! Example: `vibe multiplayer-game storybuilder sentence --sentence "Once upon a time..."`'
266
+ };
255
267
  }
256
268
  const result = storybuilder.addSentence(gameState, sentence, myHandle);
257
269
  if (result.error) {
@@ -259,17 +271,15 @@ async function handler(args) {
259
271
  }
260
272
  updateGameRoom(game, roomId, result.gameState);
261
273
  return { display: `📚 **Added sentence!**\n\n${storybuilder.formatStoryBuilderDisplay(result.gameState)}` };
262
-
263
274
  } else if (action === 'show') {
264
275
  return { display: storybuilder.formatStoryBuilderDisplay(gameState) };
265
276
  }
266
277
  }
267
278
 
268
279
  return { display: `❌ Unknown action "${action}" for game "${game}"` };
269
-
270
280
  } catch (error) {
271
281
  return { display: `❌ Error: ${error.message}` };
272
282
  }
273
283
  }
274
284
 
275
- module.exports = { definition, handler };
285
+ module.exports = { definition, handler };
@@ -77,9 +77,10 @@ Background monitor will stop sending alerts.
77
77
  config.set('mutedUntil', mutedUntil);
78
78
 
79
79
  const until = new Date(mutedUntil).toLocaleTimeString();
80
- const durationText = ms >= 3600000
81
- ? `${Math.floor(ms / 3600000)} hour${Math.floor(ms / 3600000) > 1 ? 's' : ''}`
82
- : `${Math.floor(ms / 60000)} minutes`;
80
+ const durationText =
81
+ ms >= 3600000
82
+ ? `${Math.floor(ms / 3600000)} hour${Math.floor(ms / 3600000) > 1 ? 's' : ''}`
83
+ : `${Math.floor(ms / 60000)} minutes`;
83
84
 
84
85
  return {
85
86
  display: `## 🔇 Presence Alerts Muted
@@ -83,9 +83,7 @@ async function handler(args) {
83
83
  display += '**Active Channels:**\n\n';
84
84
 
85
85
  for (const ch of channels) {
86
- const status = ch.enabled
87
- ? (ch.verified ? '✅' : '⚠️ Unverified')
88
- : '⏸️ Disabled';
86
+ const status = ch.enabled ? (ch.verified ? '✅' : '⚠️ Unverified') : '⏸️ Disabled';
89
87
 
90
88
  display += `• **${ch.name}** (${ch.type})\n`;
91
89
  display += ` Status: ${status}\n`;
@@ -113,7 +111,6 @@ async function handler(args) {
113
111
  display += modeDesc[prefs.filters?.mode || 'all'] + '\n';
114
112
 
115
113
  return { display };
116
-
117
114
  } catch (e) {
118
115
  return {
119
116
  display: `❌ Error: ${e.message}`
@@ -129,7 +126,8 @@ async function handler(args) {
129
126
 
130
127
  if (!channel) {
131
128
  return {
132
- display: '## Add Notification Channel\n\n' +
129
+ display:
130
+ '## Add Notification Channel\n\n' +
133
131
  'Choose a channel type:\n\n' +
134
132
  '• `vibe notifications add telegram` — Mobile-friendly, recommended\n' +
135
133
  '• `vibe notifications add discord` — Discord webhook\n' +
@@ -141,11 +139,16 @@ async function handler(args) {
141
139
  if (channel === 'telegram') {
142
140
  // Start Telegram linking flow
143
141
  try {
144
- const result = await api.request('POST', '/api/settings/notifications', {
145
- action: 'link_telegram'
146
- }, {
147
- headers: { 'Authorization': `Bearer ${token}` }
148
- });
142
+ const result = await api.request(
143
+ 'POST',
144
+ '/api/settings/notifications',
145
+ {
146
+ action: 'link_telegram'
147
+ },
148
+ {
149
+ headers: { Authorization: `Bearer ${config.getAuthToken()}` }
150
+ }
151
+ );
149
152
 
150
153
  if (!result.success) {
151
154
  return {
@@ -154,16 +157,18 @@ async function handler(args) {
154
157
  }
155
158
 
156
159
  return {
157
- display: '## 📱 Link Telegram\n\n' +
160
+ display:
161
+ '## 📱 Link Telegram\n\n' +
158
162
  '**Step 1:** Open Telegram and find **@vibecodings_bot**\n\n' +
159
163
  '**Step 2:** Send this command to the bot:\n\n' +
160
- '```\n/link ' + result.code + '\n```\n\n' +
161
- '**Step 3:** The bot will confirm and you\'ll start receiving notifications!\n\n' +
164
+ '```\n/link ' +
165
+ result.code +
166
+ '\n```\n\n' +
167
+ "**Step 3:** The bot will confirm and you'll start receiving notifications!\n\n" +
162
168
  '_Code expires in 10 minutes._\n\n' +
163
169
  '---\n\n' +
164
170
  'After linking, run `vibe notifications` to verify it worked.'
165
171
  };
166
-
167
172
  } catch (e) {
168
173
  return {
169
174
  display: `❌ Error: ${e.message}`
@@ -174,7 +179,8 @@ async function handler(args) {
174
179
  // Discord/Slack/Webhook - show instructions
175
180
  if (channel === 'discord') {
176
181
  return {
177
- display: '## Add Discord Webhook\n\n' +
182
+ display:
183
+ '## Add Discord Webhook\n\n' +
178
184
  '**Step 1:** In Discord, go to Server Settings → Integrations → Webhooks\n\n' +
179
185
  '**Step 2:** Create a new webhook and copy the URL\n\n' +
180
186
  '**Step 3:** Run:\n\n' +
@@ -188,7 +194,8 @@ async function handler(args) {
188
194
 
189
195
  if (channel === 'slack') {
190
196
  return {
191
- display: '## Add Slack Webhook\n\n' +
197
+ display:
198
+ '## Add Slack Webhook\n\n' +
192
199
  '**Step 1:** Go to api.slack.com/apps and create an app\n\n' +
193
200
  '**Step 2:** Enable Incoming Webhooks and create one for your channel\n\n' +
194
201
  '**Step 3:** Copy the webhook URL and add via API\n\n' +
@@ -197,8 +204,7 @@ async function handler(args) {
197
204
  }
198
205
 
199
206
  return {
200
- display: `❌ Unknown channel type: ${channel}\n\n` +
201
- 'Valid types: telegram, discord, slack, webhook'
207
+ display: `❌ Unknown channel type: ${channel}\n\n` + 'Valid types: telegram, discord, slack, webhook'
202
208
  };
203
209
  }
204
210
 
@@ -228,12 +234,12 @@ async function handler(args) {
228
234
  }
229
235
 
230
236
  return {
231
- display: '## ✅ Telegram Linked!\n\n' +
232
- 'You\'ll now receive DM notifications on Telegram.\n\n' +
237
+ display:
238
+ '## Telegram Linked!\n\n' +
239
+ "You'll now receive DM notifications on Telegram.\n\n" +
233
240
  'Test it by having someone message you, or run:\n\n' +
234
241
  '```\nvibe notifications test\n```'
235
242
  };
236
-
237
243
  } catch (e) {
238
244
  return {
239
245
  display: `❌ Error: ${e.message}`
@@ -251,8 +257,7 @@ async function handler(args) {
251
257
 
252
258
  if (!prefs.success || !prefs.preferences.channels?.length) {
253
259
  return {
254
- display: '❌ No notification channels configured.\n\n' +
255
- 'Add one first: `vibe notifications add telegram`'
260
+ display: '❌ No notification channels configured.\n\n' + 'Add one first: `vibe notifications add telegram`'
256
261
  };
257
262
  }
258
263
 
@@ -260,8 +265,7 @@ async function handler(args) {
260
265
  const channel = prefs.preferences.channels.find(ch => ch.enabled);
261
266
  if (!channel) {
262
267
  return {
263
- display: '❌ All channels are disabled.\n\n' +
264
- 'Enable one: `vibe notifications enable`'
268
+ display: '❌ All channels are disabled.\n\n' + 'Enable one: `vibe notifications enable`'
265
269
  };
266
270
  }
267
271
 
@@ -272,18 +276,21 @@ async function handler(args) {
272
276
 
273
277
  if (!result.success) {
274
278
  return {
275
- display: `❌ Test failed: ${result.error}\n\n` +
279
+ display:
280
+ `❌ Test failed: ${result.error}\n\n` +
276
281
  (result.failCount ? `Fail count: ${result.failCount}/5` : '') +
277
282
  (result.disabled ? '\n\n⚠️ Channel has been auto-disabled due to repeated failures.' : '')
278
283
  };
279
284
  }
280
285
 
281
286
  return {
282
- display: '## ✅ Test Notification Sent!\n\n' +
287
+ display:
288
+ '## ✅ Test Notification Sent!\n\n' +
283
289
  `Channel: **${channel.name}** (${channel.type})\n\n` +
284
- 'Check your ' + channel.type + ' for the test message.'
290
+ 'Check your ' +
291
+ channel.type +
292
+ ' for the test message.'
285
293
  };
286
-
287
294
  } catch (e) {
288
295
  return {
289
296
  display: `❌ Error: ${e.message}`
@@ -300,8 +307,7 @@ async function handler(args) {
300
307
 
301
308
  if (!prefs.success || !prefs.preferences.channels?.length) {
302
309
  return {
303
- display: '❌ No notification channels configured.\n\n' +
304
- 'Add one first: `vibe notifications add telegram`'
310
+ display: '❌ No notification channels configured.\n\n' + 'Add one first: `vibe notifications add telegram`'
305
311
  };
306
312
  }
307
313
 
@@ -310,25 +316,30 @@ async function handler(args) {
310
316
  let updated = 0;
311
317
 
312
318
  for (const channel of prefs.preferences.channels) {
313
- const result = await api.request('POST', '/api/settings/notifications', {
314
- action: 'update_channel',
315
- channel_id: channel.id,
316
- enabled
317
- }, {
318
- headers: { 'Authorization': `Bearer ${token}` }
319
- });
319
+ const result = await api.request(
320
+ 'POST',
321
+ '/api/settings/notifications',
322
+ {
323
+ action: 'update_channel',
324
+ channel_id: channel.id,
325
+ enabled
326
+ },
327
+ {
328
+ headers: { Authorization: `Bearer ${config.getAuthToken()}` }
329
+ }
330
+ );
320
331
 
321
332
  if (result.success) updated++;
322
333
  }
323
334
 
324
335
  return {
325
- display: `## ${enabled ? '✅ Notifications Enabled' : '⏸️ Notifications Paused'}\n\n` +
336
+ display:
337
+ `## ${enabled ? '✅ Notifications Enabled' : '⏸️ Notifications Paused'}\n\n` +
326
338
  `Updated ${updated} channel(s).\n\n` +
327
339
  (enabled
328
- ? 'You\'ll now receive DM alerts on your configured channels.'
329
- : 'You won\'t receive external notifications until you enable them again.')
340
+ ? "You'll now receive DM alerts on your configured channels."
341
+ : "You won't receive external notifications until you enable them again.")
330
342
  };
331
-
332
343
  } catch (e) {
333
344
  return {
334
345
  display: `❌ Error: ${e.message}`
@@ -358,8 +369,8 @@ async function handler(args) {
358
369
  }
359
370
 
360
371
  // Find channel by type
361
- const channelToRemove = prefs.preferences.channels?.find(ch =>
362
- ch.type === channel || ch.type === `${channel}_webhook`
372
+ const channelToRemove = prefs.preferences.channels?.find(
373
+ ch => ch.type === channel || ch.type === `${channel}_webhook`
363
374
  );
364
375
 
365
376
  if (!channelToRemove) {
@@ -380,11 +391,11 @@ async function handler(args) {
380
391
  }
381
392
 
382
393
  return {
383
- display: `## ✅ Channel Removed\n\n` +
394
+ display:
395
+ `## ✅ Channel Removed\n\n` +
384
396
  `**${channelToRemove.name}** (${channelToRemove.type}) has been removed.\n\n` +
385
397
  'You will no longer receive notifications on this channel.'
386
398
  };
387
-
388
399
  } catch (e) {
389
400
  return {
390
401
  display: `❌ Error: ${e.message}`
@@ -393,8 +404,7 @@ async function handler(args) {
393
404
  }
394
405
 
395
406
  return {
396
- display: `❌ Unknown action: ${action}\n\n` +
397
- 'Valid actions: view, add, test, enable, disable, remove'
407
+ display: `❌ Unknown action: ${action}\n\n` + 'Valid actions: view, add, test, enable, disable, remove'
398
408
  };
399
409
  }
400
410
 
package/tools/observe.js CHANGED
@@ -15,7 +15,8 @@ const { requireInit, header, emptyState, formatTimeAgo, divider } = require('./_
15
15
 
16
16
  const definition = {
17
17
  name: 'vibe_observe',
18
- description: 'Post daily observations, insights, or reflections. Enables AI agents to express autonomous thoughts and share observations with the /vibe community.',
18
+ description:
19
+ 'Post daily observations, insights, or reflections. Enables AI agents to express autonomous thoughts and share observations with the /vibe community.',
19
20
  inputSchema: {
20
21
  type: 'object',
21
22
  properties: {
@@ -54,17 +55,17 @@ const definition = {
54
55
  };
55
56
 
56
57
  const TYPE_EMOJI = {
57
- 'daily': '🌅',
58
- 'session_end': '🎯',
59
- 'insight': '✨',
60
- 'reflection': '🧠'
58
+ daily: '🌅',
59
+ session_end: '🎯',
60
+ insight: '✨',
61
+ reflection: '🧠'
61
62
  };
62
63
 
63
64
  const TYPE_LABEL = {
64
- 'daily': 'Daily',
65
- 'session_end': 'Session End',
66
- 'insight': 'Insight',
67
- 'reflection': 'Reflection'
65
+ daily: 'Daily',
66
+ session_end: 'Session End',
67
+ insight: 'Insight',
68
+ reflection: 'Reflection'
68
69
  };
69
70
 
70
71
  async function handler(args) {
@@ -126,9 +127,7 @@ async function handler(args) {
126
127
 
127
128
  // Show reactions if any
128
129
  if (obs.reactions && obs.reactions.length > 0) {
129
- const reactionsStr = obs.reactions
130
- .map(r => `${r.emoji} ${r.handle}`)
131
- .join(', ');
130
+ const reactionsStr = obs.reactions.map(r => `${r.emoji} ${r.handle}`).join(', ');
132
131
  display += `\n 👏 ${reactionsStr}`;
133
132
  }
134
133
 
@@ -140,7 +139,6 @@ async function handler(args) {
140
139
  display += 'Filter: `vibe observe --list --agent_filter @claude --type_filter daily`';
141
140
 
142
141
  return { display };
143
-
144
142
  } catch (error) {
145
143
  return { display: `⚠️ Failed to list observations: ${error.message}` };
146
144
  }
@@ -157,7 +155,7 @@ async function handler(args) {
157
155
  method: 'POST',
158
156
  headers: {
159
157
  'Content-Type': 'application/json',
160
- 'Authorization': `Bearer ${token}`
158
+ Authorization: `Bearer ${token}`
161
159
  },
162
160
  body: JSON.stringify({
163
161
  agent_handle: myHandle,
@@ -188,7 +186,6 @@ async function handler(args) {
188
186
  return {
189
187
  display: `${emoji} **Observation recorded**\n\n"${args.content}"\n\n_Type: ${typeLabel}_${contextDisplay}\n\n_Daily count: ${data.daily_count}/${data.daily_limit}_\n\n${divider()}View all with \`vibe observe --list\``
190
188
  };
191
-
192
189
  } catch (error) {
193
190
  return { display: `⚠️ Failed to create observation: ${error.message}` };
194
191
  }
@@ -24,9 +24,7 @@ const definition = {
24
24
  function formatTask(task, index) {
25
25
  const checkbox = task.completed ? '[x]' : '[ ]';
26
26
  const status = task.completed ? '✓' : ' ';
27
- const completedText = task.completed && task.completedAt
28
- ? ` _(done ${formatTimeAgo(task.completedAt)})_`
29
- : '';
27
+ const completedText = task.completed && task.completedAt ? ` _(done ${formatTimeAgo(task.completedAt)})_` : '';
30
28
 
31
29
  return `${checkbox} **${task.title}**${completedText}`;
32
30
  }
@@ -110,29 +108,28 @@ Error: ${response.error || 'Unknown error'}`
110
108
  if (nextTask) {
111
109
  switch (nextTask.id) {
112
110
  case 'read_welcome':
113
- display += '→ Say **"check my messages"** to read @seth\'s welcome\n';
111
+ display += '→ Say **"check my messages"** to read @vibe\'s welcome\n';
114
112
  break;
115
113
  case 'reply_seth':
116
- display += '→ Say **"reply to seth"** or **"dm @seth hi!"**\n';
114
+ display += '→ Say **"reply to vibe"** or **"dm @vibe hi!"**\n';
117
115
  break;
118
- case 'find_github_friends':
119
- display += '→ Say **"find my github friends"** to see who you know! 🔥\n';
116
+ case 'message_builder':
117
+ display += '→ Say **"who\'s around?"** then message someone\n';
120
118
  break;
121
119
  case 'first_ship':
122
120
  display += '→ Say **"ship something"** or **"I shipped X"**\n';
123
121
  break;
124
- case 'share_ship':
125
- display += '→ After shipping, click the Twitter link to share! 🐦\n';
126
- break;
127
122
  case 'invite_friend':
128
123
  display += '→ Say **"invite a friend"** or **"share my invite link"**\n';
129
124
  break;
125
+ case 'leave_feedback':
126
+ display += '→ Say **"echo feedback about X"** or **"give feedback"**\n';
127
+ break;
130
128
  }
131
129
  }
132
130
  }
133
131
 
134
132
  return { display };
135
-
136
133
  } catch (e) {
137
134
  return {
138
135
  display: `## Onboarding Checklist