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/dm.js
CHANGED
|
@@ -8,12 +8,13 @@ const memory = require('../memory');
|
|
|
8
8
|
const userProfiles = require('../store/profiles');
|
|
9
9
|
const patterns = require('../intelligence/patterns');
|
|
10
10
|
const { trackMessage, checkBurst } = require('./summarize');
|
|
11
|
-
const { requireInit, normalizeHandle, truncate, warning,
|
|
11
|
+
const { requireInit, normalizeHandle, truncate, warning, debug } = require('./_shared');
|
|
12
12
|
const { actions, formatActions } = require('./_actions');
|
|
13
13
|
|
|
14
14
|
const definition = {
|
|
15
15
|
name: 'vibe_dm',
|
|
16
|
-
description:
|
|
16
|
+
description:
|
|
17
|
+
'Send a direct message to someone. Can include structured payload for games, handoffs, or artifact cards.',
|
|
17
18
|
inputSchema: {
|
|
18
19
|
type: 'object',
|
|
19
20
|
properties: {
|
|
@@ -27,19 +28,12 @@ const definition = {
|
|
|
27
28
|
},
|
|
28
29
|
artifact_slug: {
|
|
29
30
|
type: 'string',
|
|
30
|
-
description:
|
|
31
|
+
description:
|
|
32
|
+
'Optional artifact slug to share (e.g., "pizza-guide-abc123"). The artifact will be shown as a rich card.'
|
|
31
33
|
},
|
|
32
34
|
payload: {
|
|
33
35
|
type: 'object',
|
|
34
36
|
description: 'Optional structured data (game state, code review, handoff, etc.)'
|
|
35
|
-
},
|
|
36
|
-
reply_to: {
|
|
37
|
-
type: 'string',
|
|
38
|
-
description: 'Optional: Message ID to reply to (creates a threaded reply)'
|
|
39
|
-
},
|
|
40
|
-
tip_amount_cents: {
|
|
41
|
-
type: 'number',
|
|
42
|
-
description: 'Optional: Attach an instant USDC tip (100 = $1, 500 = $5, 1000 = $10)'
|
|
43
37
|
}
|
|
44
38
|
},
|
|
45
39
|
required: ['handle']
|
|
@@ -50,7 +44,7 @@ async function handler(args) {
|
|
|
50
44
|
const initCheck = requireInit();
|
|
51
45
|
if (initCheck) return initCheck;
|
|
52
46
|
|
|
53
|
-
const { handle, message, artifact_slug, payload
|
|
47
|
+
const { handle, message, artifact_slug, payload } = args;
|
|
54
48
|
const myHandle = config.getHandle();
|
|
55
49
|
const them = normalizeHandle(handle);
|
|
56
50
|
|
|
@@ -61,7 +55,7 @@ async function handler(args) {
|
|
|
61
55
|
}
|
|
62
56
|
|
|
63
57
|
if (them === myHandle) {
|
|
64
|
-
return { display:
|
|
58
|
+
return { display: "You can't DM yourself." };
|
|
65
59
|
}
|
|
66
60
|
|
|
67
61
|
// Handle artifact sharing
|
|
@@ -80,7 +74,7 @@ async function handler(args) {
|
|
|
80
74
|
const protocol = require('../protocol');
|
|
81
75
|
finalPayload = protocol.createArtifactPayload(artifact);
|
|
82
76
|
} catch (error) {
|
|
83
|
-
|
|
77
|
+
debug('dm', 'Failed to load artifact:', error);
|
|
84
78
|
return { display: `Failed to load artifact: ${error.message}` };
|
|
85
79
|
}
|
|
86
80
|
}
|
|
@@ -95,13 +89,7 @@ async function handler(args) {
|
|
|
95
89
|
const wasTruncated = trimmed.length > MAX_LENGTH;
|
|
96
90
|
const finalMessage = wasTruncated ? trimmed.substring(0, MAX_LENGTH) : trimmed;
|
|
97
91
|
|
|
98
|
-
|
|
99
|
-
// Non-blocking - we don't wait for this
|
|
100
|
-
store.sendTypingIndicator(myHandle, them).catch(() => {});
|
|
101
|
-
|
|
102
|
-
const result = await store.sendMessage(myHandle, them, finalMessage || null, 'dm', finalPayload, {
|
|
103
|
-
replyTo: reply_to || null,
|
|
104
|
-
});
|
|
92
|
+
const result = await store.sendMessage(myHandle, them, finalMessage || null, 'dm', finalPayload);
|
|
105
93
|
|
|
106
94
|
// Check for errors
|
|
107
95
|
if (result && result.error) {
|
|
@@ -113,6 +101,10 @@ async function handler(args) {
|
|
|
113
101
|
// Log social pattern (quietly, in background)
|
|
114
102
|
patterns.logMessageSent(them);
|
|
115
103
|
|
|
104
|
+
// Push event to subscribed agent gateways (Clawdbot, etc.)
|
|
105
|
+
const { pushToAgents } = require('../notify');
|
|
106
|
+
pushToAgents('dm', { from: myHandle, to: them, body: finalMessage }).catch(() => {});
|
|
107
|
+
|
|
116
108
|
// Record connection in profiles (if first time messaging)
|
|
117
109
|
try {
|
|
118
110
|
const hasConnected = await userProfiles.hasBeenConnected(myHandle, them);
|
|
@@ -121,7 +113,7 @@ async function handler(args) {
|
|
|
121
113
|
}
|
|
122
114
|
} catch (error) {
|
|
123
115
|
// Don't fail the message if profile update fails
|
|
124
|
-
|
|
116
|
+
debug('dm', 'Failed to update profile connection:', error);
|
|
125
117
|
}
|
|
126
118
|
|
|
127
119
|
// Track for session summary
|
|
@@ -135,58 +127,27 @@ async function handler(args) {
|
|
|
135
127
|
display += ` ${warning(`truncated to ${MAX_LENGTH} chars`)}`;
|
|
136
128
|
}
|
|
137
129
|
|
|
138
|
-
//
|
|
130
|
+
// Show message preview or payload type
|
|
131
|
+
if (finalMessage) {
|
|
132
|
+
display += `\n\n"${truncate(finalMessage, 100)}"`;
|
|
133
|
+
}
|
|
139
134
|
if (finalPayload) {
|
|
140
135
|
const payloadType = finalPayload.type || 'data';
|
|
141
136
|
if (payloadType === 'artifact') {
|
|
142
|
-
const icon =
|
|
137
|
+
const icon =
|
|
138
|
+
finalPayload.template === 'guide'
|
|
139
|
+
? '📘'
|
|
140
|
+
: finalPayload.template === 'learning'
|
|
141
|
+
? '💡'
|
|
142
|
+
: finalPayload.template === 'workspace'
|
|
143
|
+
? '🗂️'
|
|
144
|
+
: '📦';
|
|
143
145
|
display += `\n\n${icon} _Shared artifact: ${finalPayload.title}_`;
|
|
144
146
|
} else {
|
|
145
147
|
display += `\n\n📦 _Includes ${payloadType} payload_`;
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
|
|
149
|
-
// Execute attached tip if specified
|
|
150
|
-
let tipResult = null;
|
|
151
|
-
if (tip_amount_cents && tip_amount_cents > 0) {
|
|
152
|
-
const token = config.getToken();
|
|
153
|
-
if (token) {
|
|
154
|
-
try {
|
|
155
|
-
const apiUrl = config.getApiUrl();
|
|
156
|
-
// Generate idempotency key to prevent duplicate tips from retries
|
|
157
|
-
const timeBucket = Math.floor(Date.now() / 60000);
|
|
158
|
-
const tipIdempotencyKey = `dm:${myHandle}:${them}:${tip_amount_cents}:${timeBucket}`;
|
|
159
|
-
|
|
160
|
-
const tipResponse = await fetch(`${apiUrl}/api/tips/instant`, {
|
|
161
|
-
method: 'POST',
|
|
162
|
-
headers: {
|
|
163
|
-
'Content-Type': 'application/json',
|
|
164
|
-
'Authorization': `Bearer ${token}`,
|
|
165
|
-
'Idempotency-Key': tipIdempotencyKey
|
|
166
|
-
},
|
|
167
|
-
body: JSON.stringify({
|
|
168
|
-
to: them,
|
|
169
|
-
amount_cents: tip_amount_cents,
|
|
170
|
-
message: message ? `${message.substring(0, 50)}...` : null,
|
|
171
|
-
context: { type: 'dm_reply' }
|
|
172
|
-
})
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
tipResult = await tipResponse.json();
|
|
176
|
-
|
|
177
|
-
if (tipResult.success) {
|
|
178
|
-
const tipAmount = (tip_amount_cents / 100).toFixed(0);
|
|
179
|
-
display += `\n\n💸 _Tipped $${tipAmount} USDC — [view tx](${tipResult.explorer_url})_`;
|
|
180
|
-
} else {
|
|
181
|
-
display += `\n\n⚠️ _Tip failed: ${tipResult.message || 'Unknown error'}_`;
|
|
182
|
-
}
|
|
183
|
-
} catch (tipError) {
|
|
184
|
-
console.warn('[dm] Tip execution failed:', tipError.message);
|
|
185
|
-
display += `\n\n⚠️ _Tip failed: ${tipError.message}_`;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
151
|
// Burst notification (5+ messages in one thread)
|
|
191
152
|
if (burst.triggered && burst.thread === them) {
|
|
192
153
|
display += `\n\n💬 _${burst.count} messages with @${them} — say "summarize" when done_`;
|
|
@@ -214,27 +175,7 @@ async function handler(args) {
|
|
|
214
175
|
// Add guided mode actions
|
|
215
176
|
response.actions = formatActions(actions.afterDm(them));
|
|
216
177
|
|
|
217
|
-
// Fetch DM suggestions (async, non-blocking for response)
|
|
218
|
-
// This adds "You might want to message..." suggestions
|
|
219
|
-
try {
|
|
220
|
-
const suggestions = await fetchRelevantUsers(myHandle, 'dm_suggest', 3);
|
|
221
|
-
if (suggestions && suggestions.matches && suggestions.matches.length > 0) {
|
|
222
|
-
// Filter out the person we just messaged
|
|
223
|
-
const others = suggestions.matches.filter(m => m.handle !== them);
|
|
224
|
-
if (others.length > 0) {
|
|
225
|
-
response.dm_suggestions = others.map(m => ({
|
|
226
|
-
handle: m.handle,
|
|
227
|
-
building: m.building,
|
|
228
|
-
reasons: m.reasons?.slice(0, 2) || []
|
|
229
|
-
}));
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
} catch (e) {
|
|
233
|
-
// Don't fail DM if suggestions fail
|
|
234
|
-
console.log('[dm] dm_suggest fetch error:', e.message);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
178
|
return response;
|
|
238
179
|
}
|
|
239
180
|
|
|
240
|
-
module.exports = { definition, handler };
|
|
181
|
+
module.exports = { definition, handler };
|
package/tools/doctor.js
CHANGED
|
@@ -13,7 +13,7 @@ const config = require('../config');
|
|
|
13
13
|
const store = require('../store');
|
|
14
14
|
const presence = require('../presence');
|
|
15
15
|
|
|
16
|
-
const VIBE_API =
|
|
16
|
+
const VIBE_API = config.getApiUrl();
|
|
17
17
|
const VIBE_DIR = path.join(process.env.HOME, '.vibe');
|
|
18
18
|
const MCP_DIR = path.join(VIBE_DIR, 'mcp-server');
|
|
19
19
|
|
|
@@ -50,10 +50,7 @@ async function diagnoseAPI() {
|
|
|
50
50
|
return {
|
|
51
51
|
status: 'error',
|
|
52
52
|
message: `API returned HTTP ${res.status}`,
|
|
53
|
-
remediation: [
|
|
54
|
-
'Check if slashvibe.dev is up',
|
|
55
|
-
'Try: curl -s https://slashvibe.dev/api/stats'
|
|
56
|
-
]
|
|
53
|
+
remediation: ['Check if slashvibe.dev is up', 'Try: curl -s https://slashvibe.dev/api/stats']
|
|
57
54
|
};
|
|
58
55
|
} catch (e) {
|
|
59
56
|
if (e.name === 'TimeoutError') {
|
|
@@ -70,10 +67,7 @@ async function diagnoseAPI() {
|
|
|
70
67
|
return {
|
|
71
68
|
status: 'error',
|
|
72
69
|
message: `Network error: ${e.message}`,
|
|
73
|
-
remediation: [
|
|
74
|
-
'Check your internet connection',
|
|
75
|
-
'Check if VPN is blocking requests'
|
|
76
|
-
]
|
|
70
|
+
remediation: ['Check your internet connection', 'Check if VPN is blocking requests']
|
|
77
71
|
};
|
|
78
72
|
}
|
|
79
73
|
}
|
|
@@ -85,9 +79,7 @@ async function diagnoseIdentity(autoFix = false) {
|
|
|
85
79
|
return {
|
|
86
80
|
status: 'error',
|
|
87
81
|
message: 'Not initialized',
|
|
88
|
-
remediation: [
|
|
89
|
-
'Run: vibe init @yourhandle "what you\'re building"'
|
|
90
|
-
],
|
|
82
|
+
remediation: ['Run: vibe init @yourhandle "what you\'re building"'],
|
|
91
83
|
canAutoFix: false
|
|
92
84
|
};
|
|
93
85
|
}
|
|
@@ -155,9 +147,7 @@ async function diagnoseIdentity(autoFix = false) {
|
|
|
155
147
|
return {
|
|
156
148
|
status: 'error',
|
|
157
149
|
message: `Identity check failed: ${e.message}`,
|
|
158
|
-
remediation: [
|
|
159
|
-
'Run: vibe init @yourhandle "what you\'re building"'
|
|
160
|
-
]
|
|
150
|
+
remediation: ['Run: vibe init @yourhandle "what you\'re building"']
|
|
161
151
|
};
|
|
162
152
|
}
|
|
163
153
|
}
|
|
@@ -180,10 +170,7 @@ async function diagnosePresence() {
|
|
|
180
170
|
return {
|
|
181
171
|
status: 'warning',
|
|
182
172
|
message: 'Not visible to others',
|
|
183
|
-
remediation: [
|
|
184
|
-
'Heartbeat may have stopped',
|
|
185
|
-
'Run: vibe status to trigger heartbeat'
|
|
186
|
-
]
|
|
173
|
+
remediation: ['Heartbeat may have stopped', 'Run: vibe status to trigger heartbeat']
|
|
187
174
|
};
|
|
188
175
|
}
|
|
189
176
|
|
|
@@ -193,10 +180,7 @@ async function diagnosePresence() {
|
|
|
193
180
|
return {
|
|
194
181
|
status: 'warning',
|
|
195
182
|
message: `Last heartbeat ${minutesAgo}m ago`,
|
|
196
|
-
remediation: [
|
|
197
|
-
'Heartbeat may be stale',
|
|
198
|
-
'Run any vibe command to refresh'
|
|
199
|
-
]
|
|
183
|
+
remediation: ['Heartbeat may be stale', 'Run any vibe command to refresh']
|
|
200
184
|
};
|
|
201
185
|
}
|
|
202
186
|
|
|
@@ -272,10 +256,7 @@ async function diagnoseStorage() {
|
|
|
272
256
|
return {
|
|
273
257
|
status: 'error',
|
|
274
258
|
message: '~/.vibe directory missing',
|
|
275
|
-
remediation: [
|
|
276
|
-
'Run: mkdir -p ~/.vibe',
|
|
277
|
-
'Or: vibe init to auto-create'
|
|
278
|
-
],
|
|
259
|
+
remediation: ['Run: mkdir -p ~/.vibe', 'Or: vibe init to auto-create'],
|
|
279
260
|
canAutoFix: true
|
|
280
261
|
};
|
|
281
262
|
}
|
|
@@ -302,10 +283,7 @@ async function diagnoseStorage() {
|
|
|
302
283
|
return {
|
|
303
284
|
status: 'warning',
|
|
304
285
|
message: issues.join(', '),
|
|
305
|
-
remediation: [
|
|
306
|
-
'Run: vibe init to recreate session',
|
|
307
|
-
'Memory directory will be created on first use'
|
|
308
|
-
]
|
|
286
|
+
remediation: ['Run: vibe init to recreate session', 'Memory directory will be created on first use']
|
|
309
287
|
};
|
|
310
288
|
}
|
|
311
289
|
|
|
@@ -316,9 +294,7 @@ async function diagnoseStorage() {
|
|
|
316
294
|
return {
|
|
317
295
|
status: 'error',
|
|
318
296
|
message: 'session.json not readable/writable',
|
|
319
|
-
remediation: [
|
|
320
|
-
'Fix permissions: chmod 600 ~/.vibe/session.json'
|
|
321
|
-
]
|
|
297
|
+
remediation: ['Fix permissions: chmod 600 ~/.vibe/session.json']
|
|
322
298
|
};
|
|
323
299
|
}
|
|
324
300
|
|
|
@@ -351,9 +327,7 @@ async function diagnoseMessages() {
|
|
|
351
327
|
return {
|
|
352
328
|
status: 'info',
|
|
353
329
|
message: `${count} unread message${count > 1 ? 's' : ''}`,
|
|
354
|
-
remediation: [
|
|
355
|
-
'Run: vibe inbox to see messages'
|
|
356
|
-
]
|
|
330
|
+
remediation: ['Run: vibe inbox to see messages']
|
|
357
331
|
};
|
|
358
332
|
}
|
|
359
333
|
|
|
@@ -395,10 +369,7 @@ async function diagnoseInstall() {
|
|
|
395
369
|
return {
|
|
396
370
|
status: 'info',
|
|
397
371
|
message: `v${version} · ${MCP_DIR}`,
|
|
398
|
-
remediation: [
|
|
399
|
-
`Update: ${updateMethod}`,
|
|
400
|
-
'After update: restart Claude Code'
|
|
401
|
-
]
|
|
372
|
+
remediation: [`Update: ${updateMethod}`, 'After update: restart Claude Code']
|
|
402
373
|
};
|
|
403
374
|
} catch (e) {
|
|
404
375
|
return {
|
package/tools/drawing.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
|
// Drawing game implementation
|
|
13
13
|
const drawing = require('../games/drawing');
|
|
@@ -32,7 +32,7 @@ const definition = {
|
|
|
32
32
|
description: 'X coordinate (0-19) for drawing'
|
|
33
33
|
},
|
|
34
34
|
y: {
|
|
35
|
-
type: 'number',
|
|
35
|
+
type: 'number',
|
|
36
36
|
description: 'Y coordinate (0-11) for drawing'
|
|
37
37
|
},
|
|
38
38
|
x1: {
|
|
@@ -45,7 +45,8 @@ const definition = {
|
|
|
45
45
|
},
|
|
46
46
|
char: {
|
|
47
47
|
type: 'string',
|
|
48
|
-
description:
|
|
48
|
+
description:
|
|
49
|
+
'Character to draw (empty, dot, circle, square, star, heart, tree, house, sun, moon, water, mountain, person, cat, dog, car, plane, flower, umbrella, rainbow)'
|
|
49
50
|
},
|
|
50
51
|
theme: {
|
|
51
52
|
type: 'string',
|
|
@@ -65,7 +66,7 @@ async function getDrawingState(room) {
|
|
|
65
66
|
const state = await store.get(key);
|
|
66
67
|
return state ? JSON.parse(state) : null;
|
|
67
68
|
} catch (e) {
|
|
68
|
-
|
|
69
|
+
debug('drawing', 'Failed to get state:', e.message);
|
|
69
70
|
return null;
|
|
70
71
|
}
|
|
71
72
|
}
|
|
@@ -78,7 +79,7 @@ async function saveDrawingState(room, state) {
|
|
|
78
79
|
const key = `drawing:${room}`;
|
|
79
80
|
await store.set(key, JSON.stringify(state));
|
|
80
81
|
} catch (e) {
|
|
81
|
-
|
|
82
|
+
debug('drawing', 'Failed to save state:', e.message);
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -86,7 +87,7 @@ async function saveDrawingState(room, state) {
|
|
|
86
87
|
* Post drawing activity to board
|
|
87
88
|
*/
|
|
88
89
|
async function postDrawingActivity(action, room, player, details = '') {
|
|
89
|
-
const API_URL =
|
|
90
|
+
const API_URL = config.getApiUrl();
|
|
90
91
|
|
|
91
92
|
try {
|
|
92
93
|
let content;
|
|
@@ -114,7 +115,7 @@ async function postDrawingActivity(action, room, player, details = '') {
|
|
|
114
115
|
})
|
|
115
116
|
});
|
|
116
117
|
} catch (e) {
|
|
117
|
-
|
|
118
|
+
debug('drawing', 'Failed to post to board:', e.message);
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
|
|
@@ -146,7 +147,9 @@ async function handler(args) {
|
|
|
146
147
|
|
|
147
148
|
case 'join':
|
|
148
149
|
if (!drawingState) {
|
|
149
|
-
return {
|
|
150
|
+
return {
|
|
151
|
+
display: `No drawing session found in #${room}. Use \`vibe drawing --action start --room ${room}\` to create one!`
|
|
152
|
+
};
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
const joinResult = drawing.addPlayer(drawingState, myHandle);
|
|
@@ -164,7 +167,9 @@ async function handler(args) {
|
|
|
164
167
|
|
|
165
168
|
case 'draw':
|
|
166
169
|
if (!drawingState) {
|
|
167
|
-
return {
|
|
170
|
+
return {
|
|
171
|
+
display: `No drawing session found in #${room}. Use \`vibe drawing --action start --room ${room}\` to create one!`
|
|
172
|
+
};
|
|
168
173
|
}
|
|
169
174
|
|
|
170
175
|
if (x === undefined || y === undefined || !char) {
|
|
@@ -192,11 +197,16 @@ async function handler(args) {
|
|
|
192
197
|
|
|
193
198
|
case 'line':
|
|
194
199
|
if (!drawingState) {
|
|
195
|
-
return {
|
|
200
|
+
return {
|
|
201
|
+
display: `No drawing session found in #${room}. Use \`vibe drawing --action start --room ${room}\` to create one!`
|
|
202
|
+
};
|
|
196
203
|
}
|
|
197
204
|
|
|
198
205
|
if (x === undefined || y === undefined || x1 === undefined || y1 === undefined || !char) {
|
|
199
|
-
return {
|
|
206
|
+
return {
|
|
207
|
+
display:
|
|
208
|
+
'For line drawing, you need: --x [start x] --y [start y] --x1 [end x] --y1 [end y] --char [character name]'
|
|
209
|
+
};
|
|
200
210
|
}
|
|
201
211
|
|
|
202
212
|
const charName2 = char.toLowerCase();
|
|
@@ -222,10 +232,12 @@ async function handler(args) {
|
|
|
222
232
|
return { display: `No drawing session found in #${room}.` };
|
|
223
233
|
}
|
|
224
234
|
|
|
225
|
-
const clearResult = drawing.clearRegion(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
235
|
+
const clearResult = drawing.clearRegion(
|
|
236
|
+
drawingState,
|
|
237
|
+
x || 0,
|
|
238
|
+
y || 0,
|
|
239
|
+
x1 !== undefined ? x1 : drawing.CANVAS_WIDTH - 1,
|
|
240
|
+
y1 !== undefined ? y1 : drawing.CANVAS_HEIGHT - 1,
|
|
229
241
|
myHandle
|
|
230
242
|
);
|
|
231
243
|
|
|
@@ -259,14 +271,16 @@ async function handler(args) {
|
|
|
259
271
|
await postDrawingActivity('theme', room, myHandle, theme);
|
|
260
272
|
|
|
261
273
|
const tips = drawing.getDrawingTips(theme);
|
|
262
|
-
|
|
274
|
+
|
|
263
275
|
return {
|
|
264
276
|
display: `## 🎯 Set Theme in #${room}\n\n${drawing.formatDrawingDisplay(drawingState)}\n\n**Drawing tips for "${theme}":**\n${tips.map(tip => `• ${tip}`).join('\n')}`
|
|
265
277
|
};
|
|
266
278
|
|
|
267
279
|
case 'view':
|
|
268
280
|
if (!drawingState) {
|
|
269
|
-
return {
|
|
281
|
+
return {
|
|
282
|
+
display: `No drawing session found in #${room}. Use \`vibe drawing --action start --room ${room}\` to create one!`
|
|
283
|
+
};
|
|
270
284
|
}
|
|
271
285
|
|
|
272
286
|
return {
|
|
@@ -279,7 +293,7 @@ async function handler(args) {
|
|
|
279
293
|
}
|
|
280
294
|
|
|
281
295
|
const stats = drawing.getCanvasStats(drawingState);
|
|
282
|
-
|
|
296
|
+
|
|
283
297
|
let statsDisplay = `## 📊 Drawing Stats for #${room}\n\n`;
|
|
284
298
|
statsDisplay += `**Canvas:** ${stats.fillPercentage}% filled (${stats.totalDrawnCells}/${drawing.CANVAS_WIDTH * drawing.CANVAS_HEIGHT} cells)\n`;
|
|
285
299
|
statsDisplay += `**Moves:** ${stats.totalMoves} total\n`;
|
|
@@ -292,7 +306,7 @@ async function handler(args) {
|
|
|
292
306
|
if (Object.keys(stats.playerMoves).length > 0) {
|
|
293
307
|
statsDisplay += `**Artists:**\n`;
|
|
294
308
|
Object.entries(stats.playerMoves)
|
|
295
|
-
.sort(([,a], [,b]) => b - a)
|
|
309
|
+
.sort(([, a], [, b]) => b - a)
|
|
296
310
|
.forEach(([player, moves]) => {
|
|
297
311
|
statsDisplay += `• @${player}: ${moves} moves\n`;
|
|
298
312
|
});
|
|
@@ -307,4 +321,4 @@ async function handler(args) {
|
|
|
307
321
|
}
|
|
308
322
|
}
|
|
309
323
|
|
|
310
|
-
module.exports = { definition, handler };
|
|
324
|
+
module.exports = { definition, handler };
|
package/tools/echo.js
CHANGED
|
@@ -14,7 +14,7 @@ const config = require('../config');
|
|
|
14
14
|
const { formatTimeAgo, requireInit } = require('./_shared');
|
|
15
15
|
const store = require('../store');
|
|
16
16
|
|
|
17
|
-
const API_URL =
|
|
17
|
+
const API_URL = config.getApiUrl();
|
|
18
18
|
|
|
19
19
|
const definition = {
|
|
20
20
|
name: 'vibe_echo',
|
|
@@ -53,20 +53,20 @@ function isQuery(message) {
|
|
|
53
53
|
// @echo personality responses
|
|
54
54
|
const responses = {
|
|
55
55
|
received: [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
'Got it! 📝 Feedback received and shared with everyone.',
|
|
57
|
+
'Noted! 📝 Added to the feedback stream.',
|
|
58
|
+
'Heard you loud and clear! 🎧',
|
|
59
|
+
'Thanks for speaking up! 📣 Your feedback is now visible to all.'
|
|
60
60
|
],
|
|
61
61
|
receivedAnon: [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
'🔒 Stored anonymously. Thanks for helping make /vibe better!',
|
|
63
|
+
'🔒 Anonymous feedback saved. Your voice matters!',
|
|
64
|
+
'🔒 Noted anonymously. Appreciate you!'
|
|
65
65
|
],
|
|
66
66
|
empty: [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
'No feedback yet. Be the first to share! 🎤',
|
|
68
|
+
'The feedback stream is empty... for now. 🔇',
|
|
69
|
+
'Crickets. Share your thoughts to get things started! 🦗'
|
|
70
70
|
],
|
|
71
71
|
greeting: [
|
|
72
72
|
"Hey! I'm @echo, the /vibe feedback agent. 🎧",
|