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/open.js
CHANGED
|
@@ -8,15 +8,6 @@ const memory = require('../memory');
|
|
|
8
8
|
const patterns = require('../intelligence/patterns');
|
|
9
9
|
const { formatPayload } = require('../protocol');
|
|
10
10
|
const { requireInit, normalizeHandle } = require('./_shared');
|
|
11
|
-
const { actions, formatActions } = require('./_actions');
|
|
12
|
-
|
|
13
|
-
// Truncate message for preview (first 100 chars, clean break at word)
|
|
14
|
-
function summarizeMessage(text, maxLen = 100) {
|
|
15
|
-
if (!text || text.length <= maxLen) return text;
|
|
16
|
-
const truncated = text.slice(0, maxLen);
|
|
17
|
-
const lastSpace = truncated.lastIndexOf(' ');
|
|
18
|
-
return (lastSpace > maxLen * 0.7 ? truncated.slice(0, lastSpace) : truncated) + '...';
|
|
19
|
-
}
|
|
20
11
|
|
|
21
12
|
const definition = {
|
|
22
13
|
name: 'vibe_open',
|
|
@@ -42,7 +33,7 @@ async function handler(args) {
|
|
|
42
33
|
const them = normalizeHandle(handle);
|
|
43
34
|
|
|
44
35
|
if (them === myHandle) {
|
|
45
|
-
return { display:
|
|
36
|
+
return { display: "You can't open a thread with yourself." };
|
|
46
37
|
}
|
|
47
38
|
|
|
48
39
|
// Get thread and mark as read
|
|
@@ -55,152 +46,38 @@ async function handler(args) {
|
|
|
55
46
|
patterns.logMessageReceived(them);
|
|
56
47
|
}
|
|
57
48
|
|
|
58
|
-
// Check if they're typing
|
|
49
|
+
// Check if they're typing
|
|
59
50
|
let typingNotice = '';
|
|
60
51
|
try {
|
|
61
52
|
const typingUsers = await store.getTypingUsers(myHandle);
|
|
62
|
-
|
|
63
|
-
if (isTyping) {
|
|
53
|
+
if (typingUsers.includes(them)) {
|
|
64
54
|
typingNotice = `\n_@${them} is typing..._\n`;
|
|
65
55
|
}
|
|
66
56
|
} catch (e) {}
|
|
67
57
|
|
|
68
|
-
// Get their presence status (for "last seen" display)
|
|
69
|
-
let presenceStatus = '';
|
|
70
|
-
try {
|
|
71
|
-
const activeUsers = await store.getActiveUsers();
|
|
72
|
-
const theirPresence = activeUsers.find(u => u.handle?.toLowerCase() === them.toLowerCase());
|
|
73
|
-
|
|
74
|
-
if (theirPresence) {
|
|
75
|
-
if (theirPresence.status === 'active') {
|
|
76
|
-
presenceStatus = '🟢 online now';
|
|
77
|
-
} else if (theirPresence.status === 'away') {
|
|
78
|
-
const ago = store.formatTimeAgo(theirPresence.lastSeen);
|
|
79
|
-
presenceStatus = `☕ away · last seen ${ago}`;
|
|
80
|
-
} else {
|
|
81
|
-
const ago = store.formatTimeAgo(theirPresence.lastSeen);
|
|
82
|
-
presenceStatus = `last seen ${ago}`;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
} catch (e) {}
|
|
86
|
-
|
|
87
58
|
if (thread.length === 0) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// Fetch conversation starters to help break the ice
|
|
91
|
-
let starters = [];
|
|
92
|
-
let starterContext = {};
|
|
93
|
-
try {
|
|
94
|
-
const apiUrl = config.getApiUrl();
|
|
95
|
-
const promptsResponse = await fetch(`${apiUrl}/api/prompts?from=${myHandle}&to=${them}`, {
|
|
96
|
-
headers: { 'User-Agent': 'vibe-mcp-client' }
|
|
97
|
-
});
|
|
98
|
-
if (promptsResponse.ok) {
|
|
99
|
-
const data = await promptsResponse.json();
|
|
100
|
-
if (data.success && data.prompts) {
|
|
101
|
-
starters = data.prompts.slice(0, 3);
|
|
102
|
-
starterContext = data.context || {};
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
} catch (e) {}
|
|
106
|
-
|
|
107
|
-
// Build display with conversation starters
|
|
108
|
-
let emptyDisplay = `## @${them}${statusLine}
|
|
59
|
+
return {
|
|
60
|
+
display: `## @${them}
|
|
109
61
|
|
|
110
62
|
_No messages yet._${typingNotice}
|
|
111
|
-
`;
|
|
112
|
-
|
|
113
|
-
if (starters.length > 0) {
|
|
114
|
-
emptyDisplay += `\n**💬 Conversation starters:**\n`;
|
|
115
|
-
starters.forEach((starter, i) => {
|
|
116
|
-
emptyDisplay += `${i + 1}. "${starter}"\n`;
|
|
117
|
-
});
|
|
118
|
-
emptyDisplay += `\n_Copy one or say your own!_`;
|
|
119
|
-
} else {
|
|
120
|
-
emptyDisplay += `\nSay "message ${them} hello" to start`;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Build response with actions for quick-send
|
|
124
|
-
const response = { display: emptyDisplay };
|
|
125
|
-
|
|
126
|
-
if (starters.length > 0) {
|
|
127
|
-
response.actions = formatActions(starters.map((starter, i) => ({
|
|
128
|
-
label: `Send #${i + 1}`,
|
|
129
|
-
action: `vibe dm @${them} ${starter}`,
|
|
130
|
-
description: starter.slice(0, 40) + (starter.length > 40 ? '...' : '')
|
|
131
|
-
})));
|
|
132
|
-
response.conversationStarters = starters;
|
|
133
|
-
response.context = starterContext;
|
|
134
|
-
}
|
|
135
63
|
|
|
136
|
-
|
|
64
|
+
Say "message ${them} hello" to start`
|
|
65
|
+
};
|
|
137
66
|
}
|
|
138
67
|
|
|
139
|
-
//
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
: null;
|
|
143
|
-
|
|
144
|
-
// Build the preview summary line (what appears in collapsed view)
|
|
145
|
-
let display = '';
|
|
146
|
-
|
|
147
|
-
// Header with presence status
|
|
148
|
-
const statusSuffix = presenceStatus ? ` · _${presenceStatus}_` : '';
|
|
68
|
+
// Check if they're an agent (from first message if available)
|
|
69
|
+
const theirMessage = thread.find(m => m.from === them);
|
|
70
|
+
const agentIndicator = theirMessage?.isAgent ? ' 🤖' : '';
|
|
149
71
|
|
|
150
|
-
|
|
151
|
-
const agentBadge = latestFromThem.isAgent ? ' 🤖' : '';
|
|
152
|
-
const time = store.formatTimeAgo(latestFromThem.timestamp);
|
|
153
|
-
const preview = latestFromThem.body
|
|
154
|
-
? summarizeMessage(latestFromThem.body)
|
|
155
|
-
: (latestFromThem.payload ? '[attachment]' : '');
|
|
72
|
+
let display = `## Thread with @${them}${agentIndicator}\n\n`;
|
|
156
73
|
|
|
157
|
-
|
|
158
|
-
} else {
|
|
159
|
-
// No messages from them yet - you sent first
|
|
160
|
-
display = `💬 @${them}${statusSuffix}\n> _Waiting for reply..._\n\n`;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Thread section - sorted newest first so their latest message appears at top
|
|
164
|
-
display += `---\n📜 Thread\n\n`;
|
|
165
|
-
|
|
166
|
-
const sortedThread = [...thread].sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
|
|
167
|
-
|
|
168
|
-
// Build a map for reply lookups
|
|
169
|
-
const messageMap = {};
|
|
170
|
-
thread.forEach(m => { messageMap[m.id] = m; });
|
|
171
|
-
|
|
172
|
-
sortedThread.forEach(m => {
|
|
74
|
+
thread.forEach(m => {
|
|
173
75
|
const isMe = m.from === myHandle;
|
|
174
76
|
const agentBadge = m.isAgent && !isMe ? '🤖 ' : '';
|
|
175
77
|
const sender = isMe ? 'you' : `@${m.from}`;
|
|
176
78
|
const time = store.formatTimeAgo(m.timestamp);
|
|
177
79
|
|
|
178
|
-
|
|
179
|
-
let statusIndicator = '';
|
|
180
|
-
if (isMe) {
|
|
181
|
-
if (m.status === 'read' || m.readByThem) {
|
|
182
|
-
statusIndicator = ' ✓✓ read';
|
|
183
|
-
} else if (m.status === 'delivered' || m.delivered) {
|
|
184
|
-
statusIndicator = ' ✓✓';
|
|
185
|
-
} else {
|
|
186
|
-
statusIndicator = ' ✓';
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
display += `${agentBadge}**${sender}** — _${time}${statusIndicator}_\n`;
|
|
191
|
-
|
|
192
|
-
// Show reply context if this is a threaded reply
|
|
193
|
-
if (m.reply_to_id || m.replyToId) {
|
|
194
|
-
const replyToId = m.reply_to_id || m.replyToId;
|
|
195
|
-
const originalMsg = messageMap[replyToId];
|
|
196
|
-
if (originalMsg) {
|
|
197
|
-
const originalSender = originalMsg.from === myHandle ? 'you' : `@${originalMsg.from}`;
|
|
198
|
-
const preview = (originalMsg.body || '').substring(0, 50);
|
|
199
|
-
display += `> ↩ replying to ${originalSender}: "${preview}${preview.length >= 50 ? '...' : ''}"\n`;
|
|
200
|
-
} else {
|
|
201
|
-
display += `> ↩ _replying to earlier message_\n`;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
80
|
+
display += `${agentBadge}**${sender}** — _${time}_\n`;
|
|
204
81
|
|
|
205
82
|
// Show text if present
|
|
206
83
|
if (m.body) {
|
|
@@ -237,14 +114,6 @@ _No messages yet._${typingNotice}
|
|
|
237
114
|
response.reason = 'long_thread';
|
|
238
115
|
}
|
|
239
116
|
|
|
240
|
-
// Add smart reply actions based on their last message
|
|
241
|
-
if (latestFromThem && latestFromThem.body) {
|
|
242
|
-
response.actions = formatActions(actions.afterOpenThread(them, latestFromThem.body));
|
|
243
|
-
} else {
|
|
244
|
-
// No message from them yet - offer generic options
|
|
245
|
-
response.actions = formatActions(actions.afterOpenThread(them, ''));
|
|
246
|
-
}
|
|
247
|
-
|
|
248
117
|
return response;
|
|
249
118
|
}
|
|
250
119
|
|
package/tools/party-game.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
const config = require('../config');
|
|
8
8
|
const store = require('../store');
|
|
9
9
|
const { createGamePayload } = require('../protocol');
|
|
10
|
-
const { requireInit, normalizeHandle } = require('./_shared');
|
|
10
|
+
const { requireInit, normalizeHandle, debug } = require('./_shared');
|
|
11
11
|
|
|
12
12
|
// Import game implementations
|
|
13
13
|
const twotruths = require('../games/twotruths');
|
|
@@ -15,7 +15,7 @@ const werewolf = require('../games/werewolf');
|
|
|
15
15
|
|
|
16
16
|
// Post game results to board
|
|
17
17
|
async function postPartyGameResult(game, message) {
|
|
18
|
-
const API_URL =
|
|
18
|
+
const API_URL = config.getApiUrl();
|
|
19
19
|
|
|
20
20
|
try {
|
|
21
21
|
await fetch(`${API_URL}/api/board`, {
|
|
@@ -28,13 +28,14 @@ async function postPartyGameResult(game, message) {
|
|
|
28
28
|
})
|
|
29
29
|
});
|
|
30
30
|
} catch (e) {
|
|
31
|
-
|
|
31
|
+
debug('party-game', 'Failed to post to board:', e.message);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const definition = {
|
|
36
36
|
name: 'vibe_party_game',
|
|
37
|
-
description:
|
|
37
|
+
description:
|
|
38
|
+
'Social ice breaker and party games. Supports: twotruths (Two Truths and a Lie), werewolf (social deduction)',
|
|
38
39
|
inputSchema: {
|
|
39
40
|
type: 'object',
|
|
40
41
|
properties: {
|
|
@@ -47,11 +48,21 @@ const definition = {
|
|
|
47
48
|
type: 'string',
|
|
48
49
|
description: 'Action to take',
|
|
49
50
|
enum: [
|
|
50
|
-
'new',
|
|
51
|
+
'new',
|
|
52
|
+
'status',
|
|
53
|
+
'join',
|
|
51
54
|
// Two Truths actions
|
|
52
|
-
'statements',
|
|
55
|
+
'statements',
|
|
56
|
+
'guess',
|
|
57
|
+
'reveal',
|
|
58
|
+
'newround',
|
|
53
59
|
// Werewolf actions
|
|
54
|
-
'start',
|
|
60
|
+
'start',
|
|
61
|
+
'kill',
|
|
62
|
+
'investigate',
|
|
63
|
+
'startvote',
|
|
64
|
+
'vote',
|
|
65
|
+
'advance'
|
|
55
66
|
]
|
|
56
67
|
},
|
|
57
68
|
// Two Truths specific
|
|
@@ -123,8 +134,7 @@ function handleTwoTruths(args, myHandle, gameKey, gameState) {
|
|
|
123
134
|
gameState = twotruths.createInitialState(myHandle);
|
|
124
135
|
activeGames[gameKey] = gameState;
|
|
125
136
|
return {
|
|
126
|
-
display: twotruths.formatDisplay(gameState, myHandle) +
|
|
127
|
-
`\n\n📍 Game room: \`${gameKey}\``
|
|
137
|
+
display: twotruths.formatDisplay(gameState, myHandle) + `\n\n📍 Game room: \`${gameKey}\``
|
|
128
138
|
};
|
|
129
139
|
}
|
|
130
140
|
|
|
@@ -196,8 +206,8 @@ function handleWerewolf(args, myHandle, gameKey, gameState) {
|
|
|
196
206
|
gameState = werewolf.createInitialState(myHandle);
|
|
197
207
|
activeGames[gameKey] = gameState;
|
|
198
208
|
return {
|
|
199
|
-
display:
|
|
200
|
-
`\n\n📍 Game room: \`${gameKey}\`\nShare this to invite others!`
|
|
209
|
+
display:
|
|
210
|
+
werewolf.formatDisplay(gameState, myHandle) + `\n\n📍 Game room: \`${gameKey}\`\nShare this to invite others!`
|
|
201
211
|
};
|
|
202
212
|
}
|
|
203
213
|
|
|
@@ -247,7 +257,8 @@ function handleWerewolf(args, myHandle, gameKey, gameState) {
|
|
|
247
257
|
|
|
248
258
|
activeGames[gameKey] = result.gameState;
|
|
249
259
|
return {
|
|
250
|
-
display:
|
|
260
|
+
display:
|
|
261
|
+
`🔮 Investigation result:\n@${result.reveal.target} is... ${result.reveal.result}\n\n` +
|
|
251
262
|
werewolf.formatDisplay(result.gameState, myHandle)
|
|
252
263
|
};
|
|
253
264
|
}
|
package/tools/patterns.js
CHANGED
|
@@ -8,7 +8,8 @@ const prompts = require('../prompts');
|
|
|
8
8
|
|
|
9
9
|
const definition = {
|
|
10
10
|
name: 'vibe_patterns',
|
|
11
|
-
description:
|
|
11
|
+
description:
|
|
12
|
+
'View emerging language patterns from how people use /vibe. Shows frequent prompts and suggests new commands.',
|
|
12
13
|
inputSchema: {
|
|
13
14
|
type: 'object',
|
|
14
15
|
properties: {
|
package/tools/ping.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* vibe ping — Tap someone on the shoulder
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
const { requireInit, normalizeHandle } = require('./_shared');
|
|
5
6
|
const config = require('../config');
|
|
6
7
|
const store = require('../store');
|
|
7
8
|
|
|
@@ -25,18 +26,15 @@ const definition = {
|
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
async function handler(args) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
display: 'Run `vibe init` first to set your identity.'
|
|
31
|
-
};
|
|
32
|
-
}
|
|
29
|
+
const initCheck = requireInit();
|
|
30
|
+
if (initCheck) return initCheck;
|
|
33
31
|
|
|
34
32
|
const { handle, note } = args;
|
|
35
33
|
const myHandle = config.getHandle();
|
|
36
|
-
const them = handle
|
|
34
|
+
const them = normalizeHandle(handle);
|
|
37
35
|
|
|
38
36
|
if (them === myHandle) {
|
|
39
|
-
return { display:
|
|
37
|
+
return { display: "You can't ping yourself." };
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
// Send as a ping-type message
|
package/tools/react.js
CHANGED
|
@@ -4,50 +4,51 @@
|
|
|
4
4
|
* "react fire to stan" → sends 🔥
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
const { requireInit, normalizeHandle } = require('./_shared');
|
|
7
8
|
const config = require('../config');
|
|
8
9
|
const store = require('../store');
|
|
9
10
|
const patterns = require('../intelligence/patterns');
|
|
10
11
|
|
|
11
12
|
const REACTIONS = {
|
|
12
|
-
|
|
13
|
+
fire: '🔥',
|
|
13
14
|
'🔥': '🔥',
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
heart: '❤️',
|
|
16
|
+
love: '❤️',
|
|
16
17
|
'❤️': '❤️',
|
|
17
|
-
|
|
18
|
+
eyes: '👀',
|
|
18
19
|
'👀': '👀',
|
|
19
|
-
|
|
20
|
+
clap: '👏',
|
|
20
21
|
'👏': '👏',
|
|
21
|
-
|
|
22
|
+
rocket: '🚀',
|
|
22
23
|
'🚀': '🚀',
|
|
23
|
-
|
|
24
|
+
ship: '🚢',
|
|
24
25
|
'🚢': '🚢',
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
100: '💯',
|
|
27
|
+
hundred: '💯',
|
|
27
28
|
'💯': '💯',
|
|
28
|
-
|
|
29
|
+
thinking: '🤔',
|
|
29
30
|
'🤔': '🤔',
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
laugh: '😂',
|
|
32
|
+
lol: '😂',
|
|
32
33
|
'😂': '😂',
|
|
33
|
-
|
|
34
|
+
cool: '😎',
|
|
34
35
|
'😎': '😎',
|
|
35
|
-
|
|
36
|
+
wave: '👋',
|
|
36
37
|
'👋': '👋',
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
thumbsup: '👍',
|
|
39
|
+
yes: '👍',
|
|
39
40
|
'+1': '👍',
|
|
40
41
|
'👍': '👍',
|
|
41
|
-
|
|
42
|
+
party: '🎉',
|
|
42
43
|
'🎉': '🎉',
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
fist: '🤜',
|
|
45
|
+
bump: '🤜',
|
|
45
46
|
'🤜': '🤜',
|
|
46
|
-
|
|
47
|
+
brain: '🧠',
|
|
47
48
|
'🧠': '🧠',
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
'🤌': '🤌'
|
|
49
|
+
chef: '👨🍳',
|
|
50
|
+
chefkiss: '🤌',
|
|
51
|
+
'🤌': '🤌'
|
|
51
52
|
};
|
|
52
53
|
|
|
53
54
|
const definition = {
|
|
@@ -74,22 +75,19 @@ const definition = {
|
|
|
74
75
|
};
|
|
75
76
|
|
|
76
77
|
async function handler(args) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
display: 'Run `vibe init` first to set your identity.'
|
|
80
|
-
};
|
|
81
|
-
}
|
|
78
|
+
const initCheck = requireInit();
|
|
79
|
+
if (initCheck) return initCheck;
|
|
82
80
|
|
|
83
81
|
const { handle, reaction, note } = args;
|
|
84
82
|
const myHandle = config.getHandle();
|
|
85
|
-
const them = handle
|
|
83
|
+
const them = normalizeHandle(handle);
|
|
86
84
|
|
|
87
85
|
if (!them) {
|
|
88
86
|
return { display: 'Who should I react to? e.g., `react fire to @stan`' };
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
if (them === myHandle) {
|
|
92
|
-
return { display:
|
|
90
|
+
return { display: "You can't react to yourself." };
|
|
93
91
|
}
|
|
94
92
|
|
|
95
93
|
// Normalize reaction
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* vibe recall — Show all threads with memories
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const { requireInit, normalizeHandle } = require('./_shared');
|
|
13
13
|
const memory = require('../memory');
|
|
14
14
|
|
|
15
15
|
const definition = {
|
|
@@ -35,11 +35,8 @@ const definition = {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
async function handler(args) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
display: 'Run `vibe init` first to set your identity.'
|
|
41
|
-
};
|
|
42
|
-
}
|
|
38
|
+
const initCheck = requireInit();
|
|
39
|
+
if (initCheck) return initCheck;
|
|
43
40
|
|
|
44
41
|
let { handle, limit = 10, search } = args;
|
|
45
42
|
|
|
@@ -70,7 +67,7 @@ async function handler(args) {
|
|
|
70
67
|
}
|
|
71
68
|
|
|
72
69
|
// Clean handle
|
|
73
|
-
handle = handle
|
|
70
|
+
handle = normalizeHandle(handle);
|
|
74
71
|
|
|
75
72
|
// Get memories for this thread
|
|
76
73
|
let memories = memory.recall(handle, limit);
|
|
@@ -85,9 +82,7 @@ async function handler(args) {
|
|
|
85
82
|
// Apply search filter if provided
|
|
86
83
|
if (search) {
|
|
87
84
|
const searchLower = search.toLowerCase();
|
|
88
|
-
memories = memories.filter(m =>
|
|
89
|
-
m.observation.toLowerCase().includes(searchLower)
|
|
90
|
-
);
|
|
85
|
+
memories = memories.filter(m => m.observation.toLowerCase().includes(searchLower));
|
|
91
86
|
|
|
92
87
|
if (memories.length === 0) {
|
|
93
88
|
return {
|
package/tools/release.js
CHANGED
|
@@ -10,7 +10,7 @@ const { requireInit, success, error } = require('./_shared');
|
|
|
10
10
|
|
|
11
11
|
const definition = {
|
|
12
12
|
name: 'vibe_release',
|
|
13
|
-
description:
|
|
13
|
+
description: "Release a file reservation when you're done.",
|
|
14
14
|
inputSchema: {
|
|
15
15
|
type: 'object',
|
|
16
16
|
properties: {
|
|
@@ -55,7 +55,9 @@ vibe reservations
|
|
|
55
55
|
if (!result.success) {
|
|
56
56
|
if (result.error === 'not_found') {
|
|
57
57
|
return {
|
|
58
|
-
display: error(
|
|
58
|
+
display: error(
|
|
59
|
+
`Reservation \`${reservation_id}\` not found or already expired.\n\nUse \`vibe reservations\` to see your active reservations.`
|
|
60
|
+
)
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
63
|
if (result.error === 'not_owner') {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* vibe remember "We discussed OAuth implementation" (uses last DM thread)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
const { requireInit, normalizeHandle } = require('./_shared');
|
|
12
13
|
const config = require('../config');
|
|
13
14
|
const memory = require('../memory');
|
|
14
15
|
const store = require('../store');
|
|
@@ -33,11 +34,8 @@ const definition = {
|
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
async function handler(args) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
display: 'Run `vibe init` first to set your identity.'
|
|
39
|
-
};
|
|
40
|
-
}
|
|
37
|
+
const initCheck = requireInit();
|
|
38
|
+
if (initCheck) return initCheck;
|
|
41
39
|
|
|
42
40
|
const { observation } = args;
|
|
43
41
|
let { handle } = args;
|
|
@@ -51,7 +49,7 @@ async function handler(args) {
|
|
|
51
49
|
|
|
52
50
|
// Clean handle
|
|
53
51
|
if (handle) {
|
|
54
|
-
handle = handle
|
|
52
|
+
handle = normalizeHandle(handle);
|
|
55
53
|
} else {
|
|
56
54
|
// Try to find last active thread
|
|
57
55
|
const myHandle = config.getHandle();
|
package/tools/report.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
const config = require('../config');
|
|
10
10
|
const store = require('../store');
|
|
11
|
-
const { requireInit } = require('./_shared');
|
|
11
|
+
const { requireInit, normalizeHandle } = require('./_shared');
|
|
12
12
|
|
|
13
13
|
const definition = {
|
|
14
14
|
name: 'vibe_report',
|
|
@@ -58,7 +58,7 @@ Please specify who to report:
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// Clean handle
|
|
61
|
-
const reportedHandle = handle
|
|
61
|
+
const reportedHandle = normalizeHandle(handle);
|
|
62
62
|
|
|
63
63
|
if (reportedHandle === myHandle) {
|
|
64
64
|
return {
|
package/tools/request.js
CHANGED
|
@@ -48,9 +48,9 @@ const definition = {
|
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
const STATUS_EMOJI = {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
open: '🔓',
|
|
52
|
+
claimed: '🔨',
|
|
53
|
+
shipped: '✅'
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
async function handler(args) {
|
|
@@ -64,16 +64,9 @@ async function handler(args) {
|
|
|
64
64
|
if (args.claim) {
|
|
65
65
|
// Post a claim as a special entry
|
|
66
66
|
try {
|
|
67
|
-
// Include auth token for API authorization
|
|
68
|
-
const authToken = config.getAuthToken();
|
|
69
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
70
|
-
if (authToken) {
|
|
71
|
-
headers['Authorization'] = `Bearer ${authToken}`;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
67
|
const response = await fetch(`${apiUrl}/api/board`, {
|
|
75
68
|
method: 'POST',
|
|
76
|
-
headers,
|
|
69
|
+
headers: { 'Content-Type': 'application/json' },
|
|
77
70
|
body: JSON.stringify({
|
|
78
71
|
author: myHandle,
|
|
79
72
|
category: 'claim',
|
|
@@ -91,7 +84,6 @@ async function handler(args) {
|
|
|
91
84
|
return {
|
|
92
85
|
display: `🔨 claimed \`${args.claim}\``
|
|
93
86
|
};
|
|
94
|
-
|
|
95
87
|
} catch (error) {
|
|
96
88
|
return { display: `⚠️ Failed to claim: ${error.message}` };
|
|
97
89
|
}
|
|
@@ -110,16 +102,9 @@ async function handler(args) {
|
|
|
110
102
|
const fullContent = `${content}${bountyText}`;
|
|
111
103
|
|
|
112
104
|
try {
|
|
113
|
-
// Include auth token for API authorization
|
|
114
|
-
const authToken = config.getAuthToken();
|
|
115
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
116
|
-
if (authToken) {
|
|
117
|
-
headers['Authorization'] = `Bearer ${authToken}`;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
105
|
const response = await fetch(`${apiUrl}/api/board`, {
|
|
121
106
|
method: 'POST',
|
|
122
|
-
headers,
|
|
107
|
+
headers: { 'Content-Type': 'application/json' },
|
|
123
108
|
body: JSON.stringify({
|
|
124
109
|
author: myHandle,
|
|
125
110
|
category: 'request',
|
|
@@ -141,7 +126,6 @@ async function handler(args) {
|
|
|
141
126
|
}
|
|
142
127
|
|
|
143
128
|
return { display };
|
|
144
|
-
|
|
145
129
|
} catch (error) {
|
|
146
130
|
return { display: `⚠️ Failed to post: ${error.message}` };
|
|
147
131
|
}
|
|
@@ -155,10 +139,7 @@ async function handler(args) {
|
|
|
155
139
|
// Also get claims to show status
|
|
156
140
|
const claimsUrl = `${apiUrl}/api/board?limit=50&category=claim`;
|
|
157
141
|
|
|
158
|
-
const [requestsRes, claimsRes] = await Promise.all([
|
|
159
|
-
fetch(url),
|
|
160
|
-
fetch(claimsUrl)
|
|
161
|
-
]);
|
|
142
|
+
const [requestsRes, claimsRes] = await Promise.all([fetch(url), fetch(claimsUrl)]);
|
|
162
143
|
|
|
163
144
|
const requests = (await requestsRes.json()).entries || [];
|
|
164
145
|
const claims = (await claimsRes.json()).entries || [];
|
|
@@ -222,7 +203,6 @@ async function handler(args) {
|
|
|
222
203
|
});
|
|
223
204
|
|
|
224
205
|
return { display };
|
|
225
|
-
|
|
226
206
|
} catch (error) {
|
|
227
207
|
return { display: `⚠️ Failed to load requests: ${error.message}` };
|
|
228
208
|
}
|
package/tools/reserve.js
CHANGED
|
@@ -11,7 +11,7 @@ const { requireInit, formatDuration, warning, success } = require('./_shared');
|
|
|
11
11
|
|
|
12
12
|
const definition = {
|
|
13
13
|
name: 'vibe_reserve',
|
|
14
|
-
description:
|
|
14
|
+
description: "Reserve files you're working on. Advisory lock — warns on conflicts, doesn't block.",
|
|
15
15
|
inputSchema: {
|
|
16
16
|
type: 'object',
|
|
17
17
|
properties: {
|