slashvibe-mcp 0.3.20 → 0.3.21

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 (167) hide show
  1. package/README.md +47 -252
  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 +27 -15
  14. package/games/arcade.js +406 -0
  15. package/games/chess.js +451 -0
  16. package/games/colorguess.js +343 -0
  17. package/games/crossword-words.js +171 -0
  18. package/games/crossword.js +461 -0
  19. package/games/drawing.js +347 -0
  20. package/games/gameroulette.js +300 -0
  21. package/games/gamerouter.js +336 -0
  22. package/games/gamestatus.js +337 -0
  23. package/games/guessnumber.js +209 -0
  24. package/games/hangman.js +279 -0
  25. package/games/memory.js +338 -0
  26. package/games/multiplayer-tictactoe.js +389 -0
  27. package/games/pixelart.js +399 -0
  28. package/games/quickduel.js +354 -0
  29. package/games/riddle.js +371 -0
  30. package/games/rockpaperscissors.js +291 -0
  31. package/games/snake.js +406 -0
  32. package/games/storybuilder.js +343 -0
  33. package/games/tictactoe.js +345 -0
  34. package/games/twentyquestions.js +286 -0
  35. package/games/twotruths.js +207 -0
  36. package/games/werewolf.js +508 -0
  37. package/games/wordassociation.js +247 -0
  38. package/games/wordchain.js +135 -0
  39. package/index.js +116 -159
  40. package/intelligence/index.js +9 -2
  41. package/intelligence/interests.js +369 -0
  42. package/notification-emitter.js +77 -0
  43. package/notify.js +5 -1
  44. package/package.json +21 -16
  45. package/prompts.js +1 -1
  46. package/protocol/index.js +73 -0
  47. package/setup.js +480 -0
  48. package/smart-inbox.js +276 -0
  49. package/store/api.js +536 -215
  50. package/store/profiles.js +160 -12
  51. package/tools/_actions.js +362 -21
  52. package/tools/_discovery.js +119 -26
  53. package/tools/_shared/index.js +64 -0
  54. package/tools/_shared.js +234 -0
  55. package/tools/_work-context.js +338 -0
  56. package/tools/_work-context.manual-test.js +199 -0
  57. package/tools/_work-context.test.js +260 -0
  58. package/tools/activity.js +220 -0
  59. package/tools/analytics.js +191 -0
  60. package/tools/approve.js +197 -0
  61. package/tools/artifact-create.js +14 -3
  62. package/tools/artifacts-price.js +107 -0
  63. package/tools/available.js +120 -0
  64. package/tools/broadcast.js +325 -0
  65. package/tools/chat.js +202 -0
  66. package/tools/collaborative-drawing.js +1 -1
  67. package/tools/connection-status.js +178 -0
  68. package/tools/discover.js +350 -34
  69. package/tools/dm.js +80 -8
  70. package/tools/earnings.js +126 -0
  71. package/tools/feed.js +35 -4
  72. package/tools/follow.js +224 -0
  73. package/tools/friends.js +207 -0
  74. package/tools/gig-browse.js +206 -0
  75. package/tools/gig-complete.js +144 -0
  76. package/tools/health.js +87 -0
  77. package/tools/help.js +3 -3
  78. package/tools/idea.js +9 -2
  79. package/tools/inbox.js +289 -105
  80. package/tools/init.js +131 -34
  81. package/tools/invite.js +15 -4
  82. package/tools/leaderboard.js +117 -0
  83. package/tools/lib/git-apply.js +206 -0
  84. package/tools/lib/git-bundle.js +407 -0
  85. package/tools/migrate.js +3 -3
  86. package/tools/multiplayer-game.js +1 -1
  87. package/tools/onboarding.js +7 -7
  88. package/tools/open.js +143 -12
  89. package/tools/party-game.js +1 -1
  90. package/tools/plan.js +225 -0
  91. package/tools/proof-of-work.js +144 -0
  92. package/tools/reply.js +166 -0
  93. package/tools/report.js +1 -1
  94. package/tools/request.js +17 -3
  95. package/tools/schedule.js +367 -0
  96. package/tools/search-messages.js +123 -0
  97. package/tools/session.js +467 -0
  98. package/tools/session_price.js +128 -0
  99. package/tools/settings.js +90 -2
  100. package/tools/ship.js +30 -7
  101. package/tools/smart-check.js +201 -0
  102. package/tools/start.js +147 -12
  103. package/tools/status.js +53 -6
  104. package/tools/streak.js +147 -0
  105. package/tools/stuck.js +297 -0
  106. package/tools/subscribe.js +148 -0
  107. package/tools/subscriptions.js +134 -0
  108. package/tools/suggest-tags.js +6 -8
  109. package/tools/tag-suggestions.js +1 -1
  110. package/tools/tip.js +150 -77
  111. package/tools/token.js +4 -4
  112. package/tools/update.js +1 -1
  113. package/tools/wallet.js +221 -79
  114. package/tools/watch.js +157 -0
  115. package/tools/who.js +30 -1
  116. package/tools/withdraw.js +145 -0
  117. package/tools/work-summary.js +96 -0
  118. package/version.json +10 -8
  119. package/LICENSE +0 -21
  120. package/store/sqlite.js +0 -347
  121. /package/tools/{auto-suggest-connections.js → _deprecated/auto-suggest-connections.js} +0 -0
  122. /package/tools/{away.js → _deprecated/away.js} +0 -0
  123. /package/tools/{back.js → _deprecated/back.js} +0 -0
  124. /package/tools/{bootstrap-skills.js → _deprecated/bootstrap-skills.js} +0 -0
  125. /package/tools/{bridge-dashboard.js → _deprecated/bridge-dashboard.js} +0 -0
  126. /package/tools/{bridge-health.js → _deprecated/bridge-health.js} +0 -0
  127. /package/tools/{bridge-live.js → _deprecated/bridge-live.js} +0 -0
  128. /package/tools/{bridges.js → _deprecated/bridges.js} +0 -0
  129. /package/tools/{colorguess.js → _deprecated/colorguess.js} +0 -0
  130. /package/tools/{discover-insights.js → _deprecated/discover-insights.js} +0 -0
  131. /package/tools/{discover-momentum.js → _deprecated/discover-momentum.js} +0 -0
  132. /package/tools/{discovery-analytics.js → _deprecated/discovery-analytics.js} +0 -0
  133. /package/tools/{discovery-auto-suggest.js → _deprecated/discovery-auto-suggest.js} +0 -0
  134. /package/tools/{discovery-bootstrap.js → _deprecated/discovery-bootstrap.js} +0 -0
  135. /package/tools/{discovery-daily.js → _deprecated/discovery-daily.js} +0 -0
  136. /package/tools/{discovery-dashboard.js → _deprecated/discovery-dashboard.js} +0 -0
  137. /package/tools/{discovery-digest.js → _deprecated/discovery-digest.js} +0 -0
  138. /package/tools/{discovery-hub.js → _deprecated/discovery-hub.js} +0 -0
  139. /package/tools/{discovery-insights.js → _deprecated/discovery-insights.js} +0 -0
  140. /package/tools/{discovery-momentum.js → _deprecated/discovery-momentum.js} +0 -0
  141. /package/tools/{discovery-monitor.js → _deprecated/discovery-monitor.js} +0 -0
  142. /package/tools/{discovery-proactive.js → _deprecated/discovery-proactive.js} +0 -0
  143. /package/tools/{draw.js → _deprecated/draw.js} +0 -0
  144. /package/tools/{farcaster.js → _deprecated/farcaster.js} +0 -0
  145. /package/tools/{forget.js → _deprecated/forget.js} +0 -0
  146. /package/tools/{games-catalog.js → _deprecated/games-catalog.js} +0 -0
  147. /package/tools/{games.js → _deprecated/games.js} +0 -0
  148. /package/tools/{guessnumber.js → _deprecated/guessnumber.js} +0 -0
  149. /package/tools/{hangman.js → _deprecated/hangman.js} +0 -0
  150. /package/tools/{multiplayer-tictactoe.js → _deprecated/multiplayer-tictactoe.js} +0 -0
  151. /package/tools/{mute.js → _deprecated/mute.js} +0 -0
  152. /package/tools/{recall.js → _deprecated/recall.js} +0 -0
  153. /package/tools/{remember.js → _deprecated/remember.js} +0 -0
  154. /package/tools/{riddle.js → _deprecated/riddle.js} +0 -0
  155. /package/tools/{run-bootstrap.js → _deprecated/run-bootstrap.js} +0 -0
  156. /package/tools/{skills-analytics.js → _deprecated/skills-analytics.js} +0 -0
  157. /package/tools/{skills-bootstrap.js → _deprecated/skills-bootstrap.js} +0 -0
  158. /package/tools/{skills-dashboard.js → _deprecated/skills-dashboard.js} +0 -0
  159. /package/tools/{skills-exchange.js → _deprecated/skills-exchange.js} +0 -0
  160. /package/tools/{skills.js → _deprecated/skills.js} +0 -0
  161. /package/tools/{smart-intro.js → _deprecated/smart-intro.js} +0 -0
  162. /package/tools/{storybuilder.js → _deprecated/storybuilder.js} +0 -0
  163. /package/tools/{telegram-bot.js → _deprecated/telegram-bot.js} +0 -0
  164. /package/tools/{telegram-setup.js → _deprecated/telegram-setup.js} +0 -0
  165. /package/tools/{tictactoe.js → _deprecated/tictactoe.js} +0 -0
  166. /package/tools/{twentyquestions.js → _deprecated/twentyquestions.js} +0 -0
  167. /package/tools/{wordassociation.js → _deprecated/wordassociation.js} +0 -0
package/games/snake.js ADDED
@@ -0,0 +1,406 @@
1
+ /**
2
+ * Snake Game implementation for /vibe
3
+ * Classic arcade action! Control the snake, eat food, grow longer, avoid walls and yourself.
4
+ * Simple controls, endless fun, and high score tracking.
5
+ */
6
+
7
+ // Game configuration
8
+ const BOARD_WIDTH = 15;
9
+ const BOARD_HEIGHT = 12;
10
+ const INITIAL_SNAKE_LENGTH = 3;
11
+
12
+ // Direction constants
13
+ const DIRECTIONS = {
14
+ 'UP': 'UP',
15
+ 'DOWN': 'DOWN',
16
+ 'LEFT': 'LEFT',
17
+ 'RIGHT': 'RIGHT'
18
+ };
19
+
20
+ // Opposite directions (to prevent instant death by going backwards)
21
+ const OPPOSITE_DIRECTIONS = {
22
+ 'UP': 'DOWN',
23
+ 'DOWN': 'UP',
24
+ 'LEFT': 'RIGHT',
25
+ 'RIGHT': 'LEFT'
26
+ };
27
+
28
+ // Visual representation
29
+ const SYMBOLS = {
30
+ empty: '⬜',
31
+ snake: '🟩', // Snake body
32
+ head: '🟢', // Snake head (brighter green)
33
+ food: '🍎', // Food
34
+ wall: '⬛' // Walls (if we add them later)
35
+ };
36
+
37
+ // Create initial snake game state
38
+ function createInitialSnakeState(playerHandle) {
39
+ // Start snake in the middle of the board
40
+ const centerX = Math.floor(BOARD_WIDTH / 2);
41
+ const centerY = Math.floor(BOARD_HEIGHT / 2);
42
+
43
+ const initialSnake = [];
44
+ for (let i = 0; i < INITIAL_SNAKE_LENGTH; i++) {
45
+ initialSnake.push({ x: centerX - i, y: centerY });
46
+ }
47
+
48
+ return {
49
+ player: playerHandle,
50
+ snake: initialSnake,
51
+ direction: 'RIGHT',
52
+ food: generateRandomFood(initialSnake),
53
+ score: 0,
54
+ gameOver: false,
55
+ moves: 0,
56
+ speed: 1, // Game speed level (1-5)
57
+ createdAt: new Date().toISOString(),
58
+ lastMove: new Date().toISOString(),
59
+ highScore: 0, // Track personal best
60
+ reason: null // Game over reason
61
+ };
62
+ }
63
+
64
+ // Generate random food position that doesn't overlap with snake
65
+ function generateRandomFood(snake) {
66
+ let attempts = 0;
67
+ const maxAttempts = 100;
68
+
69
+ while (attempts < maxAttempts) {
70
+ const x = Math.floor(Math.random() * BOARD_WIDTH);
71
+ const y = Math.floor(Math.random() * BOARD_HEIGHT);
72
+
73
+ // Check if this position is occupied by snake
74
+ const occupied = snake.some(segment => segment.x === x && segment.y === y);
75
+
76
+ if (!occupied) {
77
+ return { x, y };
78
+ }
79
+
80
+ attempts++;
81
+ }
82
+
83
+ // Fallback if we can't find a spot (board is almost full)
84
+ for (let y = 0; y < BOARD_HEIGHT; y++) {
85
+ for (let x = 0; x < BOARD_WIDTH; x++) {
86
+ const occupied = snake.some(segment => segment.x === x && segment.y === y);
87
+ if (!occupied) {
88
+ return { x, y };
89
+ }
90
+ }
91
+ }
92
+
93
+ // If board is completely full (shouldn't happen with our board size)
94
+ return { x: 0, y: 0 };
95
+ }
96
+
97
+ // Change snake direction
98
+ function changeDirection(gameState, newDirection, playerHandle) {
99
+ const { player, direction, gameOver } = gameState;
100
+
101
+ if (playerHandle !== player) {
102
+ return { error: 'Not your game!' };
103
+ }
104
+
105
+ if (gameOver) {
106
+ return { error: 'Game is over! Start a new game to play again.' };
107
+ }
108
+
109
+ // Validate direction
110
+ if (!DIRECTIONS[newDirection.toUpperCase()]) {
111
+ return { error: 'Invalid direction. Use: up, down, left, right' };
112
+ }
113
+
114
+ const normalizedDirection = newDirection.toUpperCase();
115
+
116
+ // Prevent going in opposite direction (instant death)
117
+ if (OPPOSITE_DIRECTIONS[direction] === normalizedDirection) {
118
+ return { error: 'Cannot reverse direction!' };
119
+ }
120
+
121
+ return {
122
+ success: true,
123
+ gameState: {
124
+ ...gameState,
125
+ direction: normalizedDirection,
126
+ lastMove: new Date().toISOString()
127
+ }
128
+ };
129
+ }
130
+
131
+ // Move the snake one step
132
+ function moveSnake(gameState) {
133
+ const { snake, direction, food, score, moves, speed } = gameState;
134
+
135
+ if (gameState.gameOver) {
136
+ return { success: true, gameState }; // Already over, no change
137
+ }
138
+
139
+ // Calculate new head position
140
+ const head = snake[0];
141
+ let newX = head.x;
142
+ let newY = head.y;
143
+
144
+ switch (direction) {
145
+ case 'UP':
146
+ newY -= 1;
147
+ break;
148
+ case 'DOWN':
149
+ newY += 1;
150
+ break;
151
+ case 'LEFT':
152
+ newX -= 1;
153
+ break;
154
+ case 'RIGHT':
155
+ newX += 1;
156
+ break;
157
+ }
158
+
159
+ // Check wall collision
160
+ if (newX < 0 || newX >= BOARD_WIDTH || newY < 0 || newY >= BOARD_HEIGHT) {
161
+ return {
162
+ success: true,
163
+ gameState: {
164
+ ...gameState,
165
+ gameOver: true,
166
+ reason: 'Hit the wall!',
167
+ highScore: Math.max(gameState.highScore || 0, score)
168
+ }
169
+ };
170
+ }
171
+
172
+ // Check self collision
173
+ const selfCollision = snake.some(segment => segment.x === newX && segment.y === newY);
174
+ if (selfCollision) {
175
+ return {
176
+ success: true,
177
+ gameState: {
178
+ ...gameState,
179
+ gameOver: true,
180
+ reason: 'Bit yourself!',
181
+ highScore: Math.max(gameState.highScore || 0, score)
182
+ }
183
+ };
184
+ }
185
+
186
+ // Create new head
187
+ const newHead = { x: newX, y: newY };
188
+ const newSnake = [newHead, ...snake];
189
+
190
+ // Check if food was eaten
191
+ const ateFood = newX === food.x && newY === food.y;
192
+
193
+ let finalSnake;
194
+ let newScore = score;
195
+ let newFood = food;
196
+ let newSpeed = speed;
197
+
198
+ if (ateFood) {
199
+ // Keep tail (snake grows)
200
+ finalSnake = newSnake;
201
+ newScore = score + 10;
202
+ newFood = generateRandomFood(newSnake);
203
+
204
+ // Increase speed every 50 points (max speed 5)
205
+ newSpeed = Math.min(5, Math.floor(newScore / 50) + 1);
206
+ } else {
207
+ // Remove tail (snake moves)
208
+ finalSnake = newSnake.slice(0, -1);
209
+ }
210
+
211
+ return {
212
+ success: true,
213
+ gameState: {
214
+ ...gameState,
215
+ snake: finalSnake,
216
+ food: newFood,
217
+ score: newScore,
218
+ moves: moves + 1,
219
+ speed: newSpeed,
220
+ lastMove: new Date().toISOString(),
221
+ highScore: Math.max(gameState.highScore || 0, newScore)
222
+ }
223
+ };
224
+ }
225
+
226
+ // Auto-move the snake (for continuous play)
227
+ function autoMove(gameState) {
228
+ if (gameState.gameOver) {
229
+ return { success: true, gameState };
230
+ }
231
+
232
+ return moveSnake(gameState);
233
+ }
234
+
235
+ // Format snake game for display
236
+ function formatSnakeDisplay(gameState) {
237
+ const { snake, food, score, gameOver, moves, speed, reason, highScore, player } = gameState;
238
+
239
+ let display = `🐍 **Snake Game** - @${player}\n\n`;
240
+
241
+ if (gameOver) {
242
+ display += `💀 **Game Over!** ${reason}\n`;
243
+ display += `**Final Score:** ${score} points\n`;
244
+ if (highScore > score) {
245
+ display += `**High Score:** ${highScore} points\n`;
246
+ } else {
247
+ display += `🎉 **New High Score!** ${score} points\n`;
248
+ }
249
+ display += '\n';
250
+ } else {
251
+ display += `**Score:** ${score} | **Speed:** ${speed} | **Length:** ${snake.length}\n`;
252
+ if (highScore > 0) {
253
+ display += `**High Score:** ${highScore} points\n`;
254
+ }
255
+ display += '\n';
256
+ }
257
+
258
+ // Draw the game board
259
+ display += '```\n';
260
+
261
+ // Create empty board
262
+ const board = Array(BOARD_HEIGHT).fill(null).map(() => Array(BOARD_WIDTH).fill(SYMBOLS.empty));
263
+
264
+ // Place snake body
265
+ for (let i = 1; i < snake.length; i++) {
266
+ const segment = snake[i];
267
+ if (segment.x >= 0 && segment.x < BOARD_WIDTH && segment.y >= 0 && segment.y < BOARD_HEIGHT) {
268
+ board[segment.y][segment.x] = SYMBOLS.snake;
269
+ }
270
+ }
271
+
272
+ // Place snake head (on top of body if needed)
273
+ const head = snake[0];
274
+ if (head.x >= 0 && head.x < BOARD_WIDTH && head.y >= 0 && head.y < BOARD_HEIGHT) {
275
+ board[head.y][head.x] = SYMBOLS.head;
276
+ }
277
+
278
+ // Place food
279
+ if (food.x >= 0 && food.x < BOARD_WIDTH && food.y >= 0 && food.y < BOARD_HEIGHT) {
280
+ board[food.y][food.x] = SYMBOLS.food;
281
+ }
282
+
283
+ // Add border for clarity
284
+ display += '┌' + '─'.repeat(BOARD_WIDTH * 2) + '┐\n';
285
+
286
+ // Draw board rows
287
+ for (let y = 0; y < BOARD_HEIGHT; y++) {
288
+ display += '│';
289
+ for (let x = 0; x < BOARD_WIDTH; x++) {
290
+ display += board[y][x];
291
+ if (x < BOARD_WIDTH - 1) display += '';
292
+ }
293
+ display += '│\n';
294
+ }
295
+
296
+ display += '└' + '─'.repeat(BOARD_WIDTH * 2) + '┘\n';
297
+ display += '```\n\n';
298
+
299
+ if (!gameOver) {
300
+ display += '**Controls:**\n';
301
+ display += '• `w` or `up` - Move up\n';
302
+ display += '• `s` or `down` - Move down\n';
303
+ display += '• `a` or `left` - Move left\n';
304
+ display += '• `d` or `right` - Move right\n\n';
305
+
306
+ display += '💡 **Tip:** Eat the 🍎 to grow and score points!\n';
307
+
308
+ // Show game stats
309
+ const totalCells = BOARD_WIDTH * BOARD_HEIGHT;
310
+ const coverage = Math.round((snake.length / totalCells) * 100);
311
+ display += `**Board Coverage:** ${coverage}%\n`;
312
+ } else {
313
+ display += 'Start a new game to play again! 🎮\n';
314
+ }
315
+
316
+ return display;
317
+ }
318
+
319
+ // Get game statistics
320
+ function getSnakeStats(gameState) {
321
+ const { snake, score, moves, speed } = gameState;
322
+
323
+ const totalCells = BOARD_WIDTH * BOARD_HEIGHT;
324
+ const coverage = (snake.length / totalCells) * 100;
325
+
326
+ return {
327
+ score,
328
+ snakeLength: snake.length,
329
+ moves,
330
+ speed,
331
+ boardCoverage: Math.round(coverage * 100) / 100,
332
+ efficiency: moves > 0 ? Math.round((score / moves) * 100) / 100 : 0
333
+ };
334
+ }
335
+
336
+ // Check if game is won (snake fills entire board - nearly impossible!)
337
+ function checkWin(gameState) {
338
+ const totalCells = BOARD_WIDTH * BOARD_HEIGHT;
339
+ return gameState.snake.length >= totalCells - 1; // -1 for food
340
+ }
341
+
342
+ // Get direction from various input formats
343
+ function parseDirection(input) {
344
+ const normalized = input.toLowerCase().trim();
345
+
346
+ const directionMap = {
347
+ 'w': 'UP',
348
+ 'up': 'UP',
349
+ 'u': 'UP',
350
+ 's': 'DOWN',
351
+ 'down': 'DOWN',
352
+ 'd': 'RIGHT',
353
+ 'a': 'LEFT',
354
+ 'left': 'LEFT',
355
+ 'right': 'RIGHT',
356
+ 'l': 'LEFT',
357
+ 'r': 'RIGHT'
358
+ };
359
+
360
+ return directionMap[normalized] || null;
361
+ }
362
+
363
+ // Generate tips based on game state
364
+ function getGameTips(gameState) {
365
+ const { snake, score, moves, speed } = gameState;
366
+
367
+ const tips = [];
368
+
369
+ if (snake.length < 5) {
370
+ tips.push('🎯 Focus on eating food to grow your snake!');
371
+ }
372
+
373
+ if (score > 0 && moves > score * 2) {
374
+ tips.push('⚡ Try to be more efficient - plan your path to the food!');
375
+ }
376
+
377
+ if (speed >= 3) {
378
+ tips.push('🏃 You\'re getting fast! Be careful with turns.');
379
+ }
380
+
381
+ if (snake.length > 10) {
382
+ tips.push('🐍 Getting long! Watch out for your own tail.');
383
+ }
384
+
385
+ const coverage = (snake.length / (BOARD_WIDTH * BOARD_HEIGHT)) * 100;
386
+ if (coverage > 30) {
387
+ tips.push('📈 Great coverage! Space is getting tight.');
388
+ }
389
+
390
+ return tips;
391
+ }
392
+
393
+ module.exports = {
394
+ createInitialSnakeState,
395
+ changeDirection,
396
+ moveSnake,
397
+ autoMove,
398
+ formatSnakeDisplay,
399
+ getSnakeStats,
400
+ checkWin,
401
+ parseDirection,
402
+ getGameTips,
403
+ DIRECTIONS,
404
+ BOARD_WIDTH,
405
+ BOARD_HEIGHT
406
+ };