slashvibe-mcp 0.3.21 → 0.3.23

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