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
package/tools/game.js
CHANGED
|
@@ -1,26 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vibe game —
|
|
2
|
+
* vibe game — Unified game entry point
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Routes to all game types:
|
|
5
|
+
* - Multiplayer: tictactoe, chess
|
|
6
|
+
* - Solo: hangman, rps, memory
|
|
7
|
+
* - Party: twotruths, werewolf
|
|
8
|
+
* - AI: tictactoe-ai (play vs AI)
|
|
9
|
+
* - Collaborative: drawing, crossword, wordassociation, multiplayer-tictactoe, wordchain, storybuilder
|
|
5
10
|
*/
|
|
6
11
|
|
|
7
12
|
const config = require('../config');
|
|
8
13
|
const store = require('../store');
|
|
9
14
|
const { createTicTacToePayload, createGamePayload, formatPayload } = require('../protocol');
|
|
10
|
-
const { requireInit, normalizeHandle } = require('./_shared');
|
|
15
|
+
const { requireInit, normalizeHandle, debug } = require('./_shared');
|
|
11
16
|
|
|
12
17
|
// Chess game implementation
|
|
13
18
|
const chess = require('../games/chess');
|
|
14
19
|
|
|
20
|
+
// Delegate handlers for absorbed game tools
|
|
21
|
+
const soloGameTool = require('./solo-game');
|
|
22
|
+
const partyGameTool = require('./party-game');
|
|
23
|
+
const tictactoeTool = require('./tictactoe');
|
|
24
|
+
const wordassociationTool = require('./wordassociation');
|
|
25
|
+
const multiplayerGameTool = require('./multiplayer-game');
|
|
26
|
+
const drawingTool = require('./drawing');
|
|
27
|
+
const crosswordTool = require('./crossword');
|
|
28
|
+
|
|
15
29
|
// Post game results to board and Discord
|
|
16
30
|
async function postGameResult(winner, loser, isDraw, game = 'tic-tac-toe') {
|
|
17
|
-
const API_URL =
|
|
31
|
+
const API_URL = config.getApiUrl();
|
|
18
32
|
|
|
19
33
|
// Post to board
|
|
20
34
|
try {
|
|
21
|
-
const content = isDraw
|
|
22
|
-
? `@${winner} and @${loser} tied at ${game}`
|
|
23
|
-
: `@${winner} beat @${loser} at ${game}`;
|
|
35
|
+
const content = isDraw ? `@${winner} and @${loser} tied at ${game}` : `@${winner} beat @${loser} at ${game}`;
|
|
24
36
|
|
|
25
37
|
await fetch(`${API_URL}/api/board`, {
|
|
26
38
|
method: 'POST',
|
|
@@ -32,7 +44,7 @@ async function postGameResult(winner, loser, isDraw, game = 'tic-tac-toe') {
|
|
|
32
44
|
})
|
|
33
45
|
});
|
|
34
46
|
} catch (e) {
|
|
35
|
-
|
|
47
|
+
debug('game', 'Failed to post to board:', e.message);
|
|
36
48
|
}
|
|
37
49
|
|
|
38
50
|
// Post to Discord
|
|
@@ -53,31 +65,76 @@ async function postGameResult(winner, loser, isDraw, game = 'tic-tac-toe') {
|
|
|
53
65
|
})
|
|
54
66
|
});
|
|
55
67
|
} catch (e) {
|
|
56
|
-
|
|
68
|
+
debug('game', 'Failed to post to Discord:', e.message);
|
|
57
69
|
}
|
|
58
70
|
}
|
|
59
71
|
|
|
72
|
+
// Games that delegate to absorbed tool handlers
|
|
73
|
+
const DELEGATED_GAMES = {
|
|
74
|
+
// Solo games (from solo-game.js)
|
|
75
|
+
hangman: 'solo',
|
|
76
|
+
rps: 'solo',
|
|
77
|
+
memory: 'solo',
|
|
78
|
+
// Party games (from party-game.js)
|
|
79
|
+
twotruths: 'party',
|
|
80
|
+
werewolf: 'party',
|
|
81
|
+
// AI tictactoe (from tictactoe.js)
|
|
82
|
+
'tictactoe-ai': 'tictactoe-ai',
|
|
83
|
+
// Collaborative (from multiplayer-game.js)
|
|
84
|
+
'multiplayer-tictactoe': 'multiplayer',
|
|
85
|
+
wordchain: 'multiplayer',
|
|
86
|
+
storybuilder: 'multiplayer',
|
|
87
|
+
// Standalone tools
|
|
88
|
+
wordassociation: 'wordassociation',
|
|
89
|
+
drawing: 'drawing',
|
|
90
|
+
crossword: 'crossword'
|
|
91
|
+
};
|
|
92
|
+
|
|
60
93
|
const definition = {
|
|
61
94
|
name: 'vibe_game',
|
|
62
|
-
description:
|
|
95
|
+
description:
|
|
96
|
+
'Start or play any game. Multiplayer: tictactoe, chess. Solo: hangman, rps, memory. Party: twotruths, werewolf. AI: tictactoe-ai. Collaborative: drawing, crossword, wordassociation, wordchain, storybuilder, multiplayer-tictactoe.',
|
|
63
97
|
inputSchema: {
|
|
64
98
|
type: 'object',
|
|
65
99
|
properties: {
|
|
66
100
|
handle: {
|
|
67
101
|
type: 'string',
|
|
68
|
-
description: 'Who to play with (
|
|
102
|
+
description: 'Who to play with (for multiplayer games like tictactoe, chess)'
|
|
69
103
|
},
|
|
70
104
|
game: {
|
|
71
105
|
type: 'string',
|
|
72
106
|
description: 'Game to play (default: tictactoe)',
|
|
73
|
-
enum: [
|
|
107
|
+
enum: [
|
|
108
|
+
'tictactoe',
|
|
109
|
+
'chess',
|
|
110
|
+
'hangman',
|
|
111
|
+
'rps',
|
|
112
|
+
'memory',
|
|
113
|
+
'twotruths',
|
|
114
|
+
'werewolf',
|
|
115
|
+
'tictactoe-ai',
|
|
116
|
+
'drawing',
|
|
117
|
+
'crossword',
|
|
118
|
+
'wordassociation',
|
|
119
|
+
'multiplayer-tictactoe',
|
|
120
|
+
'wordchain',
|
|
121
|
+
'storybuilder'
|
|
122
|
+
]
|
|
74
123
|
},
|
|
75
124
|
move: {
|
|
76
125
|
type: ['number', 'string'],
|
|
77
126
|
description: 'Move to make (tictactoe: 1-9, chess: algebraic notation like e4, Nf3)'
|
|
127
|
+
},
|
|
128
|
+
action: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
description: 'Action for party/collaborative games (e.g., new, join, draw, play, hint)'
|
|
131
|
+
},
|
|
132
|
+
difficulty: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
description: 'Difficulty for solo/AI games (easy, medium, hard)',
|
|
135
|
+
enum: ['easy', 'medium', 'hard']
|
|
78
136
|
}
|
|
79
|
-
}
|
|
80
|
-
required: ['handle']
|
|
137
|
+
}
|
|
81
138
|
}
|
|
82
139
|
};
|
|
83
140
|
|
|
@@ -100,9 +157,14 @@ function getGameState(thread, game) {
|
|
|
100
157
|
*/
|
|
101
158
|
function checkTicTacToeWinner(board) {
|
|
102
159
|
const lines = [
|
|
103
|
-
[0, 1, 2],
|
|
104
|
-
[
|
|
105
|
-
[
|
|
160
|
+
[0, 1, 2],
|
|
161
|
+
[3, 4, 5],
|
|
162
|
+
[6, 7, 8], // rows
|
|
163
|
+
[0, 3, 6],
|
|
164
|
+
[1, 4, 7],
|
|
165
|
+
[2, 5, 8], // cols
|
|
166
|
+
[0, 4, 8],
|
|
167
|
+
[2, 4, 6] // diagonals
|
|
106
168
|
];
|
|
107
169
|
|
|
108
170
|
for (const [a, b, c] of lines) {
|
|
@@ -120,30 +182,40 @@ function checkTicTacToeWinner(board) {
|
|
|
120
182
|
function formatChessPayload(payload) {
|
|
121
183
|
const state = payload.state || {};
|
|
122
184
|
const board = state.board || [];
|
|
123
|
-
|
|
185
|
+
|
|
124
186
|
if (!board.length) return '♟️ **Chess** (setting up...)';
|
|
125
187
|
|
|
126
188
|
const files = ' a b c d e f g h';
|
|
127
189
|
let display = '♟️ **Chess** ' + (state.moves ? `(move ${state.moves})` : '(new game)') + '\n```\n' + files + '\n';
|
|
128
|
-
|
|
190
|
+
|
|
129
191
|
for (let rank = 0; rank < 8; rank++) {
|
|
130
|
-
let row =
|
|
192
|
+
let row = 8 - rank + ' ';
|
|
131
193
|
for (let file = 0; file < 8; file++) {
|
|
132
194
|
const piece = board[rank] && board[rank][file];
|
|
133
195
|
// Use chess piece Unicode symbols
|
|
134
196
|
const pieceSymbols = {
|
|
135
|
-
|
|
136
|
-
|
|
197
|
+
K: '♔',
|
|
198
|
+
Q: '♕',
|
|
199
|
+
R: '♖',
|
|
200
|
+
B: '♗',
|
|
201
|
+
N: '♘',
|
|
202
|
+
P: '♙',
|
|
203
|
+
k: '♚',
|
|
204
|
+
q: '♛',
|
|
205
|
+
r: '♜',
|
|
206
|
+
b: '♝',
|
|
207
|
+
n: '♞',
|
|
208
|
+
p: '♟'
|
|
137
209
|
};
|
|
138
|
-
const symbol = piece ?
|
|
210
|
+
const symbol = piece ? pieceSymbols[piece] || piece : (rank + file) % 2 === 0 ? '·' : ' ';
|
|
139
211
|
row += symbol + ' ';
|
|
140
212
|
}
|
|
141
|
-
row +=
|
|
213
|
+
row += 8 - rank;
|
|
142
214
|
display += row + '\n';
|
|
143
215
|
}
|
|
144
|
-
|
|
216
|
+
|
|
145
217
|
display += files + '\n```\n';
|
|
146
|
-
|
|
218
|
+
|
|
147
219
|
if (state.winner) {
|
|
148
220
|
display += `**Winner: ${state.winner}**`;
|
|
149
221
|
} else if (state.checkmate) {
|
|
@@ -153,11 +225,11 @@ function formatChessPayload(payload) {
|
|
|
153
225
|
} else if (state.check) {
|
|
154
226
|
display += '**Check!** ';
|
|
155
227
|
}
|
|
156
|
-
|
|
228
|
+
|
|
157
229
|
if (!state.winner && !state.checkmate && !state.stalemate) {
|
|
158
230
|
display += `Turn: **${state.turn || 'white'}**`;
|
|
159
231
|
}
|
|
160
|
-
|
|
232
|
+
|
|
161
233
|
if (state.lastMove) {
|
|
162
234
|
display += `\nLast move: ${state.lastMove.notation}`;
|
|
163
235
|
}
|
|
@@ -169,13 +241,42 @@ async function handler(args) {
|
|
|
169
241
|
const initCheck = requireInit();
|
|
170
242
|
if (initCheck) return initCheck;
|
|
171
243
|
|
|
172
|
-
const { handle, move } = args;
|
|
173
244
|
const game = args.game || 'tictactoe';
|
|
245
|
+
|
|
246
|
+
// Delegate to absorbed game handlers
|
|
247
|
+
const delegateType = DELEGATED_GAMES[game];
|
|
248
|
+
if (delegateType === 'solo') {
|
|
249
|
+
return soloGameTool.handler({ ...args, game });
|
|
250
|
+
}
|
|
251
|
+
if (delegateType === 'party') {
|
|
252
|
+
return partyGameTool.handler({ ...args, game });
|
|
253
|
+
}
|
|
254
|
+
if (delegateType === 'tictactoe-ai') {
|
|
255
|
+
return tictactoeTool.handler(args);
|
|
256
|
+
}
|
|
257
|
+
if (delegateType === 'wordassociation') {
|
|
258
|
+
return wordassociationTool.handler(args);
|
|
259
|
+
}
|
|
260
|
+
if (delegateType === 'drawing') {
|
|
261
|
+
return drawingTool.handler(args);
|
|
262
|
+
}
|
|
263
|
+
if (delegateType === 'crossword') {
|
|
264
|
+
return crosswordTool.handler(args);
|
|
265
|
+
}
|
|
266
|
+
if (delegateType === 'multiplayer') {
|
|
267
|
+
return multiplayerGameTool.handler({ ...args, game });
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Original tictactoe/chess multiplayer logic
|
|
271
|
+
const { handle, move } = args;
|
|
272
|
+
if (!handle) {
|
|
273
|
+
return { display: `Game "${game}" requires a handle. Usage: vibe game --handle @someone --game ${game}` };
|
|
274
|
+
}
|
|
174
275
|
const myHandle = config.getHandle();
|
|
175
276
|
const them = normalizeHandle(handle);
|
|
176
277
|
|
|
177
278
|
if (them === myHandle) {
|
|
178
|
-
return { display:
|
|
279
|
+
return { display: "You can't play a game with yourself." };
|
|
179
280
|
}
|
|
180
281
|
|
|
181
282
|
// Get existing thread
|
|
@@ -189,8 +290,14 @@ async function handler(args) {
|
|
|
189
290
|
if (game === 'chess') {
|
|
190
291
|
const newState = chess.createInitialChessState();
|
|
191
292
|
const payload = createGamePayload('chess', newState);
|
|
192
|
-
|
|
193
|
-
await store.sendMessage(
|
|
293
|
+
|
|
294
|
+
await store.sendMessage(
|
|
295
|
+
myHandle,
|
|
296
|
+
them,
|
|
297
|
+
'Starting a new chess game! You can play white and go first.',
|
|
298
|
+
'dm',
|
|
299
|
+
payload
|
|
300
|
+
);
|
|
194
301
|
|
|
195
302
|
return {
|
|
196
303
|
display: `## New Chess Game with @${them}\n\n${formatChessPayload(payload)}\n\nUse \`vibe game @${them} --move e4\` to make moves in algebraic notation`
|
|
@@ -211,23 +318,18 @@ async function handler(args) {
|
|
|
211
318
|
// Show existing game
|
|
212
319
|
let payload;
|
|
213
320
|
let displayText;
|
|
214
|
-
|
|
321
|
+
|
|
215
322
|
if (game === 'chess') {
|
|
216
323
|
payload = createGamePayload('chess', gameState);
|
|
217
324
|
displayText = `## Chess Game with @${them}\n\n${formatChessPayload(payload)}\n`;
|
|
218
|
-
|
|
325
|
+
|
|
219
326
|
if (gameState.winner || gameState.checkmate) {
|
|
220
327
|
displayText += `\nGame over! Use \`vibe game @${them}\` with no move to start a new game.`;
|
|
221
328
|
} else {
|
|
222
329
|
displayText += `\nUse \`vibe game @${them} --move e4\` to make moves in algebraic notation`;
|
|
223
330
|
}
|
|
224
331
|
} else {
|
|
225
|
-
payload = createTicTacToePayload(
|
|
226
|
-
gameState.board,
|
|
227
|
-
gameState.turn,
|
|
228
|
-
gameState.moves,
|
|
229
|
-
gameState.winner
|
|
230
|
-
);
|
|
332
|
+
payload = createTicTacToePayload(gameState.board, gameState.turn, gameState.moves, gameState.winner);
|
|
231
333
|
displayText = `## Game with @${them}\n\n${formatPayload(payload)}\n`;
|
|
232
334
|
|
|
233
335
|
if (gameState.winner) {
|
|
@@ -281,7 +383,6 @@ async function handler(args) {
|
|
|
281
383
|
return {
|
|
282
384
|
display: `## Chess Game with @${them}\n\n${formatChessPayload(payload)}\n\n${newGameState.checkmate ? '🎉 You win!' : newGameState.stalemate ? '🤝 Stalemate!' : `Waiting for @${them}...`}`
|
|
283
385
|
};
|
|
284
|
-
|
|
285
386
|
} else {
|
|
286
387
|
// Tic-tac-toe logic
|
|
287
388
|
const position = move - 1; // Convert 1-9 to 0-8
|
|
@@ -327,12 +428,7 @@ async function handler(args) {
|
|
|
327
428
|
const nextTurn = mySymbol === 'X' ? 'O' : 'X';
|
|
328
429
|
|
|
329
430
|
// Create payload
|
|
330
|
-
const payload = createTicTacToePayload(
|
|
331
|
-
newBoard,
|
|
332
|
-
winner ? mySymbol : nextTurn,
|
|
333
|
-
newMoves,
|
|
334
|
-
winner
|
|
335
|
-
);
|
|
431
|
+
const payload = createTicTacToePayload(newBoard, winner ? mySymbol : nextTurn, newMoves, winner);
|
|
336
432
|
|
|
337
433
|
// Send message with game state
|
|
338
434
|
let message = '';
|
|
@@ -356,4 +452,4 @@ async function handler(args) {
|
|
|
356
452
|
}
|
|
357
453
|
}
|
|
358
454
|
|
|
359
|
-
module.exports = { definition, handler };
|
|
455
|
+
module.exports = { definition, handler };
|
package/tools/handoff.js
CHANGED
|
@@ -140,7 +140,7 @@ async function handler(args) {
|
|
|
140
140
|
files: context.files || [],
|
|
141
141
|
current_state: context.current_state,
|
|
142
142
|
next_step: context.next_step,
|
|
143
|
-
blockers: context.blockers || []
|
|
143
|
+
blockers: context.blockers || []
|
|
144
144
|
},
|
|
145
145
|
|
|
146
146
|
history: {
|
|
@@ -152,13 +152,7 @@ async function handler(args) {
|
|
|
152
152
|
const humanMessage = formatHandoffMessage(handoffPayload, myHandle);
|
|
153
153
|
|
|
154
154
|
// Send via existing message system with structured payload
|
|
155
|
-
await store.sendMessage(
|
|
156
|
-
myHandle,
|
|
157
|
-
them,
|
|
158
|
-
humanMessage,
|
|
159
|
-
'handoff',
|
|
160
|
-
handoffPayload
|
|
161
|
-
);
|
|
155
|
+
await store.sendMessage(myHandle, them, humanMessage, 'handoff', handoffPayload);
|
|
162
156
|
|
|
163
157
|
// Build response
|
|
164
158
|
const filesCount = context.files?.length || 0;
|
|
@@ -178,6 +172,10 @@ async function handler(args) {
|
|
|
178
172
|
|
|
179
173
|
display += `\n\n_Handoff ID: ${handoff_id}_`;
|
|
180
174
|
|
|
175
|
+
// Push handoff event to subscribed agent gateways
|
|
176
|
+
const { pushToAgents } = require('../notify');
|
|
177
|
+
pushToAgents('handoff', { from: myHandle, to: them, task, context, handoff_id }).catch(() => {});
|
|
178
|
+
|
|
181
179
|
return {
|
|
182
180
|
display,
|
|
183
181
|
hint: 'handoff_sent',
|
package/tools/help.js
CHANGED
|
@@ -197,7 +197,7 @@ Presence updates every 5 minutes. Run \`vibe who\` for fresh data.
|
|
|
197
197
|
- Post on the board with category "question"
|
|
198
198
|
|
|
199
199
|
### Report Issues
|
|
200
|
-
- GitHub: https://github.com/
|
|
200
|
+
- GitHub: https://github.com/brightseth/vibe/issues
|
|
201
201
|
- Or: \`vibe echo "your feedback"\``;
|
|
202
202
|
|
|
203
203
|
async function handler(args) {
|
|
@@ -260,10 +260,10 @@ ${isInitialized ? `You're **@${handle}**` : '⚠️ Not initialized yet — run
|
|
|
260
260
|
|
|
261
261
|
### Links
|
|
262
262
|
- Docs: https://slashvibe.dev/llms.txt
|
|
263
|
-
- Issues: https://github.com/
|
|
263
|
+
- Issues: https://github.com/brightseth/vibe/issues
|
|
264
264
|
- Feedback: \`vibe echo "message"\``;
|
|
265
265
|
|
|
266
266
|
return { display };
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
module.exports = { definition, handler };
|
|
269
|
+
module.exports = { definition, handler };
|
package/tools/idea.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
const config = require('../config');
|
|
13
13
|
const patterns = require('../intelligence/patterns');
|
|
14
|
-
const { requireInit, header, emptyState, formatTimeAgo, divider } = require('./_shared');
|
|
14
|
+
const { requireInit, normalizeHandle, header, emptyState, formatTimeAgo, divider } = require('./_shared');
|
|
15
15
|
|
|
16
16
|
const definition = {
|
|
17
17
|
name: 'vibe_idea',
|
|
@@ -25,7 +25,7 @@ const definition = {
|
|
|
25
25
|
},
|
|
26
26
|
riff_on: {
|
|
27
27
|
type: 'string',
|
|
28
|
-
description:
|
|
28
|
+
description: "Handle of person whose idea you're riffing on (e.g., @alice)"
|
|
29
29
|
},
|
|
30
30
|
tags: {
|
|
31
31
|
type: 'array',
|
|
@@ -50,7 +50,7 @@ const IDEA_STARTERS = [
|
|
|
50
50
|
'What would happen if we combined...',
|
|
51
51
|
'The intersection of X and Y could...',
|
|
52
52
|
'A tool that lets you...',
|
|
53
|
-
|
|
53
|
+
"What's missing is..."
|
|
54
54
|
];
|
|
55
55
|
|
|
56
56
|
async function handler(args) {
|
|
@@ -78,22 +78,15 @@ async function handler(args) {
|
|
|
78
78
|
|
|
79
79
|
// Add riff metadata
|
|
80
80
|
if (args.riff_on) {
|
|
81
|
-
const riffTarget = args.riff_on
|
|
81
|
+
const riffTarget = normalizeHandle(args.riff_on);
|
|
82
82
|
entry.content = `↳ riffing on @${riffTarget}: ${content}`;
|
|
83
83
|
entry.tags = [...(entry.tags || []), `riff:${riffTarget}`];
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
try {
|
|
87
|
-
// Include auth token for API authorization
|
|
88
|
-
const authToken = config.getAuthToken();
|
|
89
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
90
|
-
if (authToken) {
|
|
91
|
-
headers['Authorization'] = `Bearer ${authToken}`;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
87
|
const response = await fetch(`${apiUrl}/api/board`, {
|
|
95
88
|
method: 'POST',
|
|
96
|
-
headers,
|
|
89
|
+
headers: { 'Content-Type': 'application/json' },
|
|
97
90
|
body: JSON.stringify(entry)
|
|
98
91
|
});
|
|
99
92
|
|
|
@@ -110,9 +103,7 @@ async function handler(args) {
|
|
|
110
103
|
patterns.logIdea(content, args.tags || []);
|
|
111
104
|
}
|
|
112
105
|
|
|
113
|
-
let display = args.riff_on
|
|
114
|
-
? `↳ riff posted\n\n`
|
|
115
|
-
: `💡 posted\n\n`;
|
|
106
|
+
let display = args.riff_on ? `↳ riff posted\n\n` : `💡 posted\n\n`;
|
|
116
107
|
|
|
117
108
|
display += `"${content}"`;
|
|
118
109
|
|
|
@@ -121,7 +112,6 @@ async function handler(args) {
|
|
|
121
112
|
}
|
|
122
113
|
|
|
123
114
|
return { display };
|
|
124
|
-
|
|
125
115
|
} catch (error) {
|
|
126
116
|
return { display: `⚠️ Failed to post: ${error.message}` };
|
|
127
117
|
}
|
|
@@ -135,10 +125,7 @@ async function handler(args) {
|
|
|
135
125
|
// Also fetch riffs
|
|
136
126
|
const riffUrl = `${apiUrl}/api/board?limit=${limit}&category=riff`;
|
|
137
127
|
|
|
138
|
-
const [ideasRes, riffsRes] = await Promise.all([
|
|
139
|
-
fetch(url),
|
|
140
|
-
fetch(riffUrl)
|
|
141
|
-
]);
|
|
128
|
+
const [ideasRes, riffsRes] = await Promise.all([fetch(url), fetch(riffUrl)]);
|
|
142
129
|
|
|
143
130
|
const ideas = (await ideasRes.json()).entries || [];
|
|
144
131
|
const riffs = (await riffsRes.json()).entries || [];
|
|
@@ -150,9 +137,7 @@ async function handler(args) {
|
|
|
150
137
|
let filtered = allEntries;
|
|
151
138
|
if (args.filter_tag) {
|
|
152
139
|
const tag = args.filter_tag.toLowerCase();
|
|
153
|
-
filtered = allEntries.filter(e =>
|
|
154
|
-
e.tags && e.tags.some(t => t.toLowerCase().includes(tag))
|
|
155
|
-
);
|
|
140
|
+
filtered = allEntries.filter(e => e.tags && e.tags.some(t => t.toLowerCase().includes(tag)));
|
|
156
141
|
}
|
|
157
142
|
|
|
158
143
|
if (filtered.length === 0) {
|
|
@@ -190,9 +175,13 @@ async function handler(args) {
|
|
|
190
175
|
topLevel.slice(0, 10).forEach(entry => {
|
|
191
176
|
const emoji = entry.category === 'riff' ? '↳' : '💡';
|
|
192
177
|
const timeAgo = formatTimeAgo(entry.timestamp);
|
|
193
|
-
const tags =
|
|
194
|
-
|
|
195
|
-
|
|
178
|
+
const tags =
|
|
179
|
+
entry.tags && entry.tags.length > 0
|
|
180
|
+
? ` ${entry.tags
|
|
181
|
+
.filter(t => !t.startsWith('riff:'))
|
|
182
|
+
.map(t => `#${t}`)
|
|
183
|
+
.join(' ')}`
|
|
184
|
+
: '';
|
|
196
185
|
|
|
197
186
|
display += `${emoji} **@${entry.author}**${tags}\n`;
|
|
198
187
|
display += ` "${entry.content}"\n`;
|
|
@@ -208,7 +197,6 @@ async function handler(args) {
|
|
|
208
197
|
});
|
|
209
198
|
|
|
210
199
|
return { display };
|
|
211
|
-
|
|
212
200
|
} catch (error) {
|
|
213
201
|
return { display: `⚠️ Failed to load ideas: ${error.message}` };
|
|
214
202
|
}
|