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.
- package/LICENSE +21 -0
- package/README.md +280 -47
- package/auto-update.js +10 -15
- package/config.js +36 -31
- package/crypto.js +1 -6
- package/debug.js +12 -0
- package/discord.js +19 -19
- package/eslint.config.js +54 -0
- package/index.js +217 -207
- package/intelligence/index.js +2 -9
- package/intelligence/infer.js +10 -16
- package/intelligence/patterns.js +23 -18
- package/intelligence/proactive.js +16 -15
- package/intelligence/serendipity.js +57 -20
- package/memory.js +13 -8
- package/migrate-v2.js +72 -0
- package/notification-emitter.js +2 -2
- package/notify.js +39 -14
- package/package.json +28 -29
- package/post-install.js +141 -0
- package/presence.js +2 -2
- package/prompts.js +5 -9
- package/protocol/index.js +123 -87
- package/protocol/telegram-commands.js +36 -37
- package/store/api.js +358 -529
- package/store/local.js +9 -10
- package/store/profiles.js +48 -192
- package/store/reservations.js +2 -9
- package/store/skills.js +69 -71
- package/store/sqlite.js +355 -0
- package/test-skills-bootstrap.js +20 -0
- package/test-v2-integration.js +385 -0
- package/tools/_actions.js +48 -387
- package/tools/_connection-queue.js +45 -56
- package/tools/_discovery-enhanced.js +52 -57
- package/tools/_discovery.js +87 -185
- package/tools/{l2-status.js → _experimental/l2-status.js} +68 -70
- package/tools/{shipback.js → _experimental/shipback.js} +4 -3
- package/tools/_proactive-discovery.js +60 -73
- package/tools/_shared/index.js +41 -64
- package/tools/admin-inbox.js +10 -15
- package/tools/agents.js +1 -1
- package/tools/artifact-create.js +13 -23
- package/tools/artifact-view.js +4 -4
- package/tools/{_deprecated/back.js → back.js} +1 -1
- package/tools/bye.js +3 -5
- package/tools/consent.js +2 -2
- package/tools/context.js +9 -10
- package/tools/crossword.js +3 -2
- package/tools/discover.js +94 -356
- package/tools/dm.js +27 -86
- package/tools/doctor.js +12 -41
- package/tools/drawing.js +34 -20
- package/tools/echo.js +11 -11
- package/tools/feed.js +30 -58
- package/tools/follow.js +64 -187
- package/tools/{_deprecated/forget.js → forget.js} +4 -7
- package/tools/game.js +144 -48
- package/tools/handoff.js +6 -8
- package/tools/help.js +3 -3
- package/tools/idea.js +15 -27
- package/tools/inbox.js +121 -293
- package/tools/init.js +54 -151
- package/tools/invite.js +8 -21
- package/tools/migrate.js +27 -24
- package/tools/multiplayer-game.js +50 -40
- package/tools/{_deprecated/mute.js → mute.js} +4 -3
- package/tools/notifications.js +58 -48
- package/tools/observe.js +12 -15
- package/tools/onboarding.js +8 -11
- package/tools/open.js +13 -144
- package/tools/party-game.js +23 -12
- package/tools/patterns.js +2 -1
- package/tools/ping.js +5 -7
- package/tools/react.js +28 -30
- package/tools/{_deprecated/recall.js → recall.js} +5 -10
- package/tools/release.js +4 -2
- package/tools/{_deprecated/remember.js → remember.js} +4 -6
- package/tools/report.js +2 -2
- package/tools/request.js +6 -26
- package/tools/reserve.js +1 -1
- package/tools/session-fork.js +97 -0
- package/tools/session-save.js +109 -0
- package/tools/settings.js +30 -99
- package/tools/ship.js +74 -56
- package/tools/{_deprecated/skills-exchange.js → skills-exchange.js} +38 -39
- package/tools/social-inbox.js +22 -28
- package/tools/social-post.js +24 -27
- package/tools/solo-game.js +54 -46
- package/tools/start.js +14 -148
- package/tools/status.js +21 -68
- package/tools/submit.js +4 -2
- package/tools/suggest-tags.js +36 -33
- package/tools/summarize.js +19 -16
- package/tools/tag-suggestions.js +72 -73
- package/tools/test.js +1 -1
- package/tools/{_deprecated/tictactoe.js → tictactoe.js} +26 -26
- package/tools/token.js +4 -4
- package/tools/update.js +1 -2
- package/tools/watch.js +132 -112
- package/tools/who.js +20 -40
- package/tools/{_deprecated/wordassociation.js → wordassociation.js} +23 -20
- package/tools/workshop-buddy.js +52 -53
- package/tools/x-mentions.js +0 -1
- package/tools/x-reply.js +0 -1
- package/twitter.js +14 -20
- package/version.json +8 -10
- package/webhook-runner.js +132 -0
- package/auth-store.js +0 -148
- package/bridges/bridge-monitor.js +0 -388
- package/bridges/discord-bot.js +0 -431
- package/bridges/farcaster.js +0 -299
- package/bridges/telegram.js +0 -261
- package/bridges/webhook-health.js +0 -420
- package/bridges/webhook-server.js +0 -437
- package/bridges/whatsapp.js +0 -441
- package/bridges/x-webhook.js +0 -423
- package/games/arcade.js +0 -406
- package/games/chess.js +0 -451
- package/games/colorguess.js +0 -343
- package/games/crossword-words.js +0 -171
- package/games/crossword.js +0 -461
- package/games/drawing.js +0 -347
- package/games/gameroulette.js +0 -300
- package/games/gamerouter.js +0 -336
- package/games/gamestatus.js +0 -337
- package/games/guessnumber.js +0 -209
- package/games/hangman.js +0 -279
- package/games/memory.js +0 -338
- package/games/multiplayer-tictactoe.js +0 -389
- package/games/pixelart.js +0 -399
- package/games/quickduel.js +0 -354
- package/games/riddle.js +0 -371
- package/games/rockpaperscissors.js +0 -291
- package/games/snake.js +0 -406
- package/games/storybuilder.js +0 -343
- package/games/tictactoe.js +0 -345
- package/games/twentyquestions.js +0 -286
- package/games/twotruths.js +0 -207
- package/games/werewolf.js +0 -508
- package/games/wordassociation.js +0 -247
- package/games/wordchain.js +0 -135
- package/intelligence/interests.js +0 -369
- package/setup.js +0 -480
- package/smart-inbox.js +0 -276
- package/tools/_deprecated/auto-suggest-connections.js +0 -304
- package/tools/_deprecated/bootstrap-skills.js +0 -231
- package/tools/_deprecated/bridge-dashboard.js +0 -342
- package/tools/_deprecated/bridge-health.js +0 -400
- package/tools/_deprecated/bridge-live.js +0 -384
- package/tools/_deprecated/bridges.js +0 -383
- package/tools/_deprecated/colorguess.js +0 -281
- package/tools/_deprecated/discover-insights.js +0 -379
- package/tools/_deprecated/discover-momentum.js +0 -256
- package/tools/_deprecated/discovery-analytics.js +0 -345
- package/tools/_deprecated/discovery-auto-suggest.js +0 -275
- package/tools/_deprecated/discovery-bootstrap.js +0 -267
- package/tools/_deprecated/discovery-daily.js +0 -375
- package/tools/_deprecated/discovery-dashboard.js +0 -385
- package/tools/_deprecated/discovery-digest.js +0 -314
- package/tools/_deprecated/discovery-hub.js +0 -357
- package/tools/_deprecated/discovery-insights.js +0 -384
- package/tools/_deprecated/discovery-momentum.js +0 -281
- package/tools/_deprecated/discovery-monitor.js +0 -319
- package/tools/_deprecated/discovery-proactive.js +0 -300
- package/tools/_deprecated/draw.js +0 -317
- package/tools/_deprecated/farcaster.js +0 -307
- package/tools/_deprecated/games-catalog.js +0 -376
- package/tools/_deprecated/games.js +0 -313
- package/tools/_deprecated/guessnumber.js +0 -194
- package/tools/_deprecated/hangman.js +0 -129
- package/tools/_deprecated/multiplayer-tictactoe.js +0 -303
- package/tools/_deprecated/riddle.js +0 -240
- package/tools/_deprecated/run-bootstrap.js +0 -69
- package/tools/_deprecated/skills-analytics.js +0 -349
- package/tools/_deprecated/skills-bootstrap.js +0 -301
- package/tools/_deprecated/skills-dashboard.js +0 -268
- package/tools/_deprecated/skills.js +0 -380
- package/tools/_deprecated/smart-intro.js +0 -353
- package/tools/_deprecated/storybuilder.js +0 -331
- package/tools/_deprecated/telegram-bot.js +0 -183
- package/tools/_deprecated/telegram-setup.js +0 -214
- package/tools/_deprecated/twentyquestions.js +0 -143
- package/tools/_shared.js +0 -234
- package/tools/_work-context.js +0 -338
- package/tools/_work-context.manual-test.js +0 -199
- package/tools/_work-context.test.js +0 -260
- package/tools/activity.js +0 -220
- package/tools/agent-treasury.js +0 -288
- package/tools/analytics.js +0 -191
- package/tools/approve.js +0 -197
- package/tools/arcade.js +0 -173
- package/tools/artifacts-price.js +0 -107
- package/tools/ask-expert.js +0 -160
- package/tools/available.js +0 -120
- package/tools/become-expert.js +0 -150
- package/tools/broadcast.js +0 -325
- package/tools/chat.js +0 -202
- package/tools/collaborative-drawing.js +0 -286
- package/tools/connection-status.js +0 -178
- package/tools/earnings.js +0 -126
- package/tools/friends.js +0 -207
- package/tools/genesis.js +0 -233
- package/tools/gig-browse.js +0 -206
- package/tools/gig-complete.js +0 -144
- package/tools/health.js +0 -87
- package/tools/leaderboard.js +0 -117
- package/tools/lib/git-apply.js +0 -206
- package/tools/lib/git-bundle.js +0 -407
- package/tools/mint.js +0 -377
- package/tools/plan.js +0 -225
- package/tools/profile.js +0 -219
- package/tools/proof-of-work.js +0 -144
- package/tools/pulse.js +0 -218
- package/tools/reply.js +0 -166
- package/tools/reputation.js +0 -175
- package/tools/schedule.js +0 -367
- package/tools/search-messages.js +0 -123
- package/tools/session.js +0 -467
- package/tools/session_price.js +0 -128
- package/tools/smart-check.js +0 -201
- package/tools/social-processor.js +0 -445
- package/tools/streak.js +0 -147
- package/tools/stuck.js +0 -297
- package/tools/subscribe.js +0 -148
- package/tools/subscriptions.js +0 -134
- package/tools/tip.js +0 -193
- package/tools/wallet.js +0 -269
- package/tools/webhook-test.js +0 -388
- package/tools/withdraw.js +0 -145
- package/tools/work-summary.js +0 -96
- package/tools/workshop.js +0 -327
- /package/tools/{l2-bridge.js → _experimental/l2-bridge.js} +0 -0
- /package/tools/{l2.js → _experimental/l2.js} +0 -0
- /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:
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 =
|
|
81
|
-
|
|
82
|
-
|
|
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
|
package/tools/notifications.js
CHANGED
|
@@ -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:
|
|
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(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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:
|
|
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 ' +
|
|
161
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
232
|
-
'
|
|
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:
|
|
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:
|
|
287
|
+
display:
|
|
288
|
+
'## ✅ Test Notification Sent!\n\n' +
|
|
283
289
|
`Channel: **${channel.name}** (${channel.type})\n\n` +
|
|
284
|
-
'Check your ' +
|
|
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(
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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:
|
|
336
|
+
display:
|
|
337
|
+
`## ${enabled ? '✅ Notifications Enabled' : '⏸️ Notifications Paused'}\n\n` +
|
|
326
338
|
`Updated ${updated} channel(s).\n\n` +
|
|
327
339
|
(enabled
|
|
328
|
-
?
|
|
329
|
-
:
|
|
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(
|
|
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:
|
|
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:
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
daily: '🌅',
|
|
59
|
+
session_end: '🎯',
|
|
60
|
+
insight: '✨',
|
|
61
|
+
reflection: '🧠'
|
|
61
62
|
};
|
|
62
63
|
|
|
63
64
|
const TYPE_LABEL = {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
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
|
}
|
package/tools/onboarding.js
CHANGED
|
@@ -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 @
|
|
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
|
|
114
|
+
display += '→ Say **"reply to vibe"** or **"dm @vibe hi!"**\n';
|
|
117
115
|
break;
|
|
118
|
-
case '
|
|
119
|
-
display += '→ Say **"
|
|
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
|