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/index.js
CHANGED
|
@@ -6,21 +6,80 @@
|
|
|
6
6
|
* Identity, presence, DM. That's it.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
// Handle "setup" command - redirect to setup.js
|
|
10
|
-
if (process.argv.includes('setup')) {
|
|
11
|
-
require('./setup.js');
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
9
|
const presence = require('./presence');
|
|
16
10
|
const config = require('./config');
|
|
17
11
|
const store = require('./store');
|
|
18
12
|
const prompts = require('./prompts');
|
|
19
13
|
const NotificationEmitter = require('./notification-emitter');
|
|
20
|
-
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* MCP Tool Safety Annotations
|
|
17
|
+
*
|
|
18
|
+
* Required by Anthropic's MCP Directory for Plugin/Connectors review.
|
|
19
|
+
* Each tool must declare behavioral hints:
|
|
20
|
+
* readOnlyHint — tool only reads data, never modifies state
|
|
21
|
+
* destructiveHint — tool may delete data or perform irreversible actions
|
|
22
|
+
* idempotentHint — repeated calls with same args have no additional effect
|
|
23
|
+
* openWorldHint — tool interacts with external services (API, network)
|
|
24
|
+
*
|
|
25
|
+
* Spec: https://modelcontextprotocol.io/docs/concepts/tools
|
|
26
|
+
*/
|
|
27
|
+
const TOOL_ANNOTATIONS = {
|
|
28
|
+
// ── Read-only tools ────────────────────────────────────────────
|
|
29
|
+
vibe_who: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
30
|
+
vibe_inbox: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
31
|
+
vibe_recall: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
32
|
+
vibe_help: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
33
|
+
vibe_feed: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
34
|
+
vibe_view_artifact: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
35
|
+
vibe_suggest_tags: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
36
|
+
vibe_doctor: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
37
|
+
vibe_reservations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
38
|
+
vibe_discover: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
39
|
+
|
|
40
|
+
// ── Write tools (non-destructive) ─────────────────────────────
|
|
41
|
+
vibe_start: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
42
|
+
vibe_init: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
43
|
+
vibe_ping: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
44
|
+
vibe_follow: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
45
|
+
vibe_unfollow: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
46
|
+
vibe_watch: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
47
|
+
vibe_live: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
48
|
+
vibe_react: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
49
|
+
vibe_dm: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
50
|
+
vibe_open: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
51
|
+
vibe_status: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
52
|
+
vibe_context: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
53
|
+
vibe_summarize: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
54
|
+
vibe_game: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
55
|
+
vibe_away: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
56
|
+
vibe_back: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
57
|
+
vibe_handoff: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
58
|
+
vibe_reserve: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
59
|
+
vibe_remember: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
60
|
+
vibe_report: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
61
|
+
vibe_invite: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
62
|
+
vibe_ship: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
63
|
+
vibe_session_save: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
64
|
+
vibe_session_fork: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
65
|
+
vibe_create_artifact: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
66
|
+
vibe_settings: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
67
|
+
vibe_notifications: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
68
|
+
vibe_presence_agent: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
69
|
+
|
|
70
|
+
// ── Destructive tools ─────────────────────────────────────────
|
|
71
|
+
vibe_forget: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
|
|
72
|
+
vibe_release: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
|
|
73
|
+
vibe_bye: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
|
|
74
|
+
vibe_mute: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
|
|
75
|
+
vibe_update: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true }
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Default annotations for any tool not explicitly mapped
|
|
79
|
+
const DEFAULT_ANNOTATIONS = { readOnlyHint: false, destructiveHint: false, openWorldHint: true };
|
|
21
80
|
|
|
22
81
|
// Tools that shouldn't show presence footer (would be redundant/noisy)
|
|
23
|
-
const SKIP_FOOTER_TOOLS = ['vibe_init', 'vibe_doctor', '
|
|
82
|
+
const SKIP_FOOTER_TOOLS = ['vibe_init', 'vibe_doctor', 'vibe_update', 'vibe_settings', 'vibe_notifications'];
|
|
24
83
|
|
|
25
84
|
// Infer user prompt from tool arguments (for pattern logging)
|
|
26
85
|
function inferPromptFromArgs(toolName, args) {
|
|
@@ -32,42 +91,66 @@ function inferPromptFromArgs(toolName, args) {
|
|
|
32
91
|
const reaction = args.reaction || '';
|
|
33
92
|
|
|
34
93
|
switch (action) {
|
|
35
|
-
case 'start':
|
|
36
|
-
|
|
37
|
-
case '
|
|
38
|
-
|
|
39
|
-
case '
|
|
40
|
-
|
|
41
|
-
case '
|
|
42
|
-
|
|
43
|
-
case '
|
|
44
|
-
|
|
45
|
-
case '
|
|
46
|
-
|
|
47
|
-
case '
|
|
48
|
-
|
|
49
|
-
case '
|
|
50
|
-
|
|
51
|
-
case '
|
|
52
|
-
|
|
53
|
-
case '
|
|
54
|
-
|
|
55
|
-
case '
|
|
56
|
-
|
|
57
|
-
case '
|
|
58
|
-
|
|
59
|
-
case '
|
|
60
|
-
|
|
61
|
-
case '
|
|
62
|
-
|
|
63
|
-
case '
|
|
64
|
-
|
|
65
|
-
case '
|
|
66
|
-
|
|
67
|
-
case '
|
|
68
|
-
|
|
69
|
-
case '
|
|
70
|
-
|
|
94
|
+
case 'start':
|
|
95
|
+
return 'start vibing';
|
|
96
|
+
case 'who':
|
|
97
|
+
return 'who is online';
|
|
98
|
+
case 'ping':
|
|
99
|
+
return `ping ${handle} ${note}`.trim();
|
|
100
|
+
case 'react':
|
|
101
|
+
return `react ${reaction} to ${handle}`.trim();
|
|
102
|
+
case 'dm':
|
|
103
|
+
return `message ${handle} ${message}`.trim();
|
|
104
|
+
case 'inbox':
|
|
105
|
+
return 'check inbox';
|
|
106
|
+
case 'open':
|
|
107
|
+
return `open thread with ${handle}`;
|
|
108
|
+
case 'status':
|
|
109
|
+
return `set status to ${mood}`;
|
|
110
|
+
case 'context':
|
|
111
|
+
return 'share context';
|
|
112
|
+
case 'summarize':
|
|
113
|
+
return 'summarize session';
|
|
114
|
+
case 'bye':
|
|
115
|
+
return 'end session';
|
|
116
|
+
case 'remember':
|
|
117
|
+
return `remember about ${handle}`;
|
|
118
|
+
case 'recall':
|
|
119
|
+
return `recall ${handle}`;
|
|
120
|
+
case 'forget':
|
|
121
|
+
return `forget ${handle}`;
|
|
122
|
+
case 'invite':
|
|
123
|
+
return 'generate invite';
|
|
124
|
+
case 'handoff':
|
|
125
|
+
return `handoff task to ${handle}`;
|
|
126
|
+
case 'reserve':
|
|
127
|
+
return args.paths ? `reserve ${args.paths.join(', ')}` : 'reserve files';
|
|
128
|
+
case 'release':
|
|
129
|
+
return `release ${args.reservation_id || 'reservation'}`;
|
|
130
|
+
case 'reservations':
|
|
131
|
+
return 'list reservations';
|
|
132
|
+
case 'game':
|
|
133
|
+
return `play ${args.game || 'game'} ${handle}`.trim();
|
|
134
|
+
case 'away':
|
|
135
|
+
return args.message ? `set away: "${args.message}"` : 'go away';
|
|
136
|
+
case 'back':
|
|
137
|
+
return 'come back';
|
|
138
|
+
case 'discover':
|
|
139
|
+
return `discover ${args.command || 'suggest'}`;
|
|
140
|
+
case 'suggest_tags':
|
|
141
|
+
return `suggest tags ${args.command || 'suggest'}`;
|
|
142
|
+
case 'ship':
|
|
143
|
+
return `ship ${args.type || ''} ${args.what || ''}`.trim();
|
|
144
|
+
case 'session_save':
|
|
145
|
+
return `save session "${args.title || ''}"`.trim();
|
|
146
|
+
case 'session_fork':
|
|
147
|
+
return `fork session ${args.session_id || ''}`.trim();
|
|
148
|
+
case 'create_artifact':
|
|
149
|
+
return `create ${args.template || 'artifact'}: ${args.title || 'untitled'}`;
|
|
150
|
+
case 'view_artifact':
|
|
151
|
+
return args.slug ? `view artifact ${args.slug}` : `list ${args.list || 'artifacts'}`;
|
|
152
|
+
default:
|
|
153
|
+
return `${action} ${handle}`.trim() || null;
|
|
71
154
|
}
|
|
72
155
|
}
|
|
73
156
|
|
|
@@ -99,11 +182,10 @@ async function getPresenceFooter() {
|
|
|
99
182
|
const handle = config.getHandle();
|
|
100
183
|
if (!handle) return '';
|
|
101
184
|
|
|
102
|
-
// Fetch presence
|
|
103
|
-
const [users, unreadCount
|
|
185
|
+
// Fetch presence and unread in parallel
|
|
186
|
+
const [users, unreadCount] = await Promise.all([
|
|
104
187
|
store.getActiveUsers().catch(() => []),
|
|
105
|
-
store.getUnreadCount(handle).catch(() => 0)
|
|
106
|
-
store.getLiveBroadcastCount().catch(() => 0)
|
|
188
|
+
store.getUnreadCount(handle).catch(() => 0)
|
|
107
189
|
]);
|
|
108
190
|
|
|
109
191
|
// Filter out self
|
|
@@ -126,7 +208,7 @@ async function getPresenceFooter() {
|
|
|
126
208
|
// Build the visible footer
|
|
127
209
|
let footer = '\n\n────────────────────────────────────────\n';
|
|
128
210
|
|
|
129
|
-
// Line 1: vibe · X online · Y unread
|
|
211
|
+
// Line 1: vibe · X online · Y unread
|
|
130
212
|
const parts = ['vibe'];
|
|
131
213
|
if (onlineCount > 0) {
|
|
132
214
|
parts.push(`${onlineCount} online`);
|
|
@@ -134,9 +216,6 @@ async function getPresenceFooter() {
|
|
|
134
216
|
if (unreadCount > 0) {
|
|
135
217
|
parts.push(`**${unreadCount} unread**`);
|
|
136
218
|
}
|
|
137
|
-
if (liveCount > 0) {
|
|
138
|
-
parts.push(`🔴 ${liveCount} live`);
|
|
139
|
-
}
|
|
140
219
|
footer += parts.join(' · ');
|
|
141
220
|
|
|
142
221
|
// Line 2: Activity hints (if anyone is online)
|
|
@@ -158,10 +237,8 @@ async function getPresenceFooter() {
|
|
|
158
237
|
}
|
|
159
238
|
});
|
|
160
239
|
footer += hints.join(' · ');
|
|
161
|
-
} else if (unreadCount === 0
|
|
162
|
-
footer += '\n_room is
|
|
163
|
-
} else if (unreadCount === 0 && liveCount > 0) {
|
|
164
|
-
footer += '\n_no messages · watch live broadcasts with `vibe watch`_';
|
|
240
|
+
} else if (unreadCount === 0) {
|
|
241
|
+
footer += '\n_room is quiet_';
|
|
165
242
|
}
|
|
166
243
|
|
|
167
244
|
footer += '\n────────────────────────────────────────';
|
|
@@ -174,148 +251,71 @@ async function getPresenceFooter() {
|
|
|
174
251
|
}
|
|
175
252
|
}
|
|
176
253
|
|
|
177
|
-
// Load
|
|
178
|
-
const
|
|
179
|
-
//
|
|
254
|
+
// Load all tools (~37 registered)
|
|
255
|
+
const tools = {
|
|
256
|
+
// Core — Identity & Session
|
|
180
257
|
vibe_start: require('./tools/start'),
|
|
181
|
-
// Core
|
|
182
258
|
vibe_init: require('./tools/init'),
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
vibe_who: require('./tools/who'),
|
|
186
|
-
vibe_ping: require('./tools/ping'),
|
|
187
|
-
vibe_react: require('./tools/react'),
|
|
259
|
+
vibe_bye: require('./tools/bye'),
|
|
260
|
+
// Core — Messaging
|
|
188
261
|
vibe_dm: require('./tools/dm'),
|
|
189
|
-
vibe_reply: require('./tools/reply'), // Quick reply to most recent unread
|
|
190
262
|
vibe_inbox: require('./tools/inbox'),
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
263
|
+
vibe_ping: require('./tools/ping'),
|
|
264
|
+
vibe_follow: require('./tools/follow').follow,
|
|
265
|
+
vibe_unfollow: require('./tools/follow').unfollow,
|
|
266
|
+
// Watch / Live
|
|
267
|
+
vibe_watch: require('./tools/watch').watch,
|
|
268
|
+
vibe_live: require('./tools/watch').live,
|
|
269
|
+
vibe_react: require('./tools/react'),
|
|
194
270
|
vibe_open: require('./tools/open'),
|
|
271
|
+
// Presence
|
|
272
|
+
vibe_who: require('./tools/who'),
|
|
195
273
|
vibe_status: require('./tools/status'),
|
|
274
|
+
vibe_away: require('./tools/away'),
|
|
275
|
+
vibe_back: require('./tools/back'),
|
|
276
|
+
// Creative
|
|
277
|
+
vibe_ship: require('./tools/ship'),
|
|
278
|
+
vibe_session_save: require('./tools/session-save'),
|
|
279
|
+
vibe_session_fork: require('./tools/session-fork'),
|
|
280
|
+
vibe_feed: require('./tools/feed'),
|
|
196
281
|
vibe_context: require('./tools/context'),
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
282
|
+
// Discovery
|
|
283
|
+
vibe_discover: require('./tools/discover'),
|
|
284
|
+
vibe_invite: require('./tools/invite'),
|
|
285
|
+
// Memory
|
|
286
|
+
vibe_remember: require('./tools/remember'),
|
|
287
|
+
vibe_recall: require('./tools/recall'),
|
|
288
|
+
vibe_forget: require('./tools/forget'),
|
|
289
|
+
// Games (single entry point for all 27 games)
|
|
200
290
|
vibe_game: require('./tools/game'),
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
vibe_crossword: require('./tools/crossword'),
|
|
206
|
-
// AIRC Handoff (v1) — context portability
|
|
207
|
-
vibe_handoff: require('./tools/handoff'),
|
|
208
|
-
// File reservations (advisory locks)
|
|
291
|
+
// Artifacts
|
|
292
|
+
vibe_create_artifact: require('./tools/artifact-create'),
|
|
293
|
+
vibe_view_artifact: require('./tools/artifact-view'),
|
|
294
|
+
// File Coordination
|
|
209
295
|
vibe_reserve: require('./tools/reserve'),
|
|
210
296
|
vibe_release: require('./tools/release'),
|
|
211
297
|
vibe_reservations: require('./tools/reservations'),
|
|
212
|
-
//
|
|
213
|
-
|
|
214
|
-
vibe_consent: require('./tools/consent'),
|
|
215
|
-
// Trust & Safety
|
|
298
|
+
// Infrastructure
|
|
299
|
+
vibe_handoff: require('./tools/handoff'),
|
|
216
300
|
vibe_report: require('./tools/report'),
|
|
217
|
-
// Support
|
|
218
|
-
vibe_help: require('./tools/help'),
|
|
219
|
-
vibe_agents: require('./tools/agents'),
|
|
220
|
-
// Community
|
|
221
|
-
vibe_invite: require('./tools/invite'),
|
|
222
|
-
vibe_submit: require('./tools/submit'),
|
|
223
|
-
vibe_observe: require('./tools/observe'),
|
|
224
|
-
// Creative Layer — Ideas, Requests, Ships
|
|
225
|
-
vibe_idea: require('./tools/idea'),
|
|
226
|
-
vibe_request: require('./tools/request'),
|
|
227
|
-
vibe_ship: require('./tools/ship'),
|
|
228
|
-
vibe_feed: require('./tools/feed'),
|
|
229
|
-
vibe_insights: require('./tools/insights'),
|
|
230
|
-
// Launch Analytics — Real-time metrics dashboard
|
|
231
|
-
vibe_analytics: require('./tools/analytics'),
|
|
232
|
-
// Activity Feed — Real-time community activity
|
|
233
|
-
vibe_activity: require('./tools/activity'),
|
|
234
|
-
// Artifacts — Just-in-time social objects
|
|
235
|
-
vibe_create_artifact: require('./tools/artifact-create'),
|
|
236
|
-
vibe_view_artifact: require('./tools/artifact-view'),
|
|
237
|
-
// Plans — Async approval workflow
|
|
238
|
-
vibe_plan: require('./tools/plan'),
|
|
239
|
-
vibe_approve: require('./tools/approve'),
|
|
240
|
-
// Discovery & Matchmaking
|
|
241
|
-
vibe_discover: require('./tools/discover'),
|
|
242
301
|
vibe_suggest_tags: require('./tools/suggest-tags'),
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
// Scheduling
|
|
248
|
-
vibe_schedule: require('./tools/schedule'),
|
|
249
|
-
// @echo feedback agent (by Flynn)
|
|
250
|
-
vibe_echo: require('./tools/echo'),
|
|
251
|
-
// X/Twitter bridge
|
|
252
|
-
vibe_x_mentions: require('./tools/x-mentions'),
|
|
253
|
-
vibe_x_reply: require('./tools/x-reply'),
|
|
254
|
-
// Unified social inbox (Phase 1a)
|
|
255
|
-
vibe_social_inbox: require('./tools/social-inbox'),
|
|
256
|
-
vibe_social_post: require('./tools/social-post'),
|
|
302
|
+
// Diagnostics
|
|
303
|
+
vibe_help: require('./tools/help'),
|
|
304
|
+
vibe_doctor: require('./tools/doctor'),
|
|
305
|
+
vibe_update: require('./tools/update'),
|
|
257
306
|
// Settings
|
|
258
307
|
vibe_settings: require('./tools/settings'),
|
|
259
|
-
// External notification channels
|
|
260
308
|
vibe_notifications: require('./tools/notifications'),
|
|
261
|
-
// Background presence agent (Claude Code 2.1)
|
|
262
309
|
vibe_presence_agent: require('./tools/presence-agent'),
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
// VIBE L2 tools
|
|
266
|
-
vibe_l2: require('./tools/l2'),
|
|
267
|
-
vibe_l2_status: require('./tools/l2-status'),
|
|
268
|
-
vibe_shipback: require('./tools/shipback'),
|
|
269
|
-
vibe_bridge: require('./tools/l2-bridge'),
|
|
270
|
-
// Gig Marketplace & Proof-of-Work
|
|
271
|
-
vibe_gig_browse: require('./tools/gig-browse'),
|
|
272
|
-
vibe_gig_complete: require('./tools/gig-complete'),
|
|
273
|
-
vibe_proof_of_work: require('./tools/proof-of-work'),
|
|
274
|
-
vibe_artifacts_price: require('./tools/artifacts-price'),
|
|
275
|
-
// Watch Me Code — Live broadcasting & sessions
|
|
276
|
-
vibe_broadcast: require('./tools/broadcast'),
|
|
277
|
-
vibe_watch: require('./tools/watch'),
|
|
278
|
-
vibe_session: require('./tools/session'),
|
|
279
|
-
vibe_chat: require('./tools/chat'),
|
|
280
|
-
// Help Signal — Symbiosis layer
|
|
281
|
-
vibe_stuck: require('./tools/stuck'),
|
|
282
|
-
// Availability — Signal openness to chat
|
|
283
|
-
vibe_available: require('./tools/available'),
|
|
284
|
-
// VIBE Economy — Tips, Earnings, Withdrawals, Subscriptions
|
|
285
|
-
vibe_tip: require('./tools/tip'),
|
|
286
|
-
vibe_earnings: require('./tools/earnings'),
|
|
287
|
-
vibe_withdraw: require('./tools/withdraw'),
|
|
288
|
-
vibe_session_price: require('./tools/session_price'),
|
|
289
|
-
vibe_subscribe: require('./tools/subscribe'),
|
|
290
|
-
vibe_subscriptions: require('./tools/subscriptions'),
|
|
291
|
-
// NFT Minting — Mint artifacts to VIBE L2, Base, or Ethereum
|
|
292
|
-
vibe_mint: require('./tools/mint'),
|
|
293
|
-
// Platform Status — Health, leaderboard, streaks
|
|
294
|
-
vibe_health: require('./tools/health'),
|
|
295
|
-
vibe_leaderboard: require('./tools/leaderboard'),
|
|
296
|
-
vibe_streak: require('./tools/streak')
|
|
310
|
+
vibe_mute: require('./tools/mute'),
|
|
311
|
+
vibe_summarize: require('./tools/summarize')
|
|
297
312
|
};
|
|
298
313
|
|
|
299
|
-
// Admin tools (only loaded when VIBE_ADMIN=true)
|
|
300
|
-
const adminTools = process.env.VIBE_ADMIN === 'true' ? {
|
|
301
|
-
vibe_admin_inbox: require('./tools/admin-inbox'),
|
|
302
|
-
vibe_test: require('./tools/test'),
|
|
303
|
-
vibe_doctor: require('./tools/doctor'),
|
|
304
|
-
vibe_update: require('./tools/update'),
|
|
305
|
-
vibe_patterns: require('./tools/patterns'),
|
|
306
|
-
} : {};
|
|
307
|
-
|
|
308
|
-
// Combine tools
|
|
309
|
-
const tools = { ...coreTools, ...adminTools };
|
|
310
|
-
|
|
311
314
|
/**
|
|
312
315
|
* MCP Protocol Handler
|
|
313
316
|
*/
|
|
314
317
|
class VibeMCPServer {
|
|
315
318
|
constructor() {
|
|
316
|
-
// Hydrate auth state from disk FIRST (before any tools need it)
|
|
317
|
-
authStore.hydrate();
|
|
318
|
-
|
|
319
319
|
// Initialize notification emitter
|
|
320
320
|
this.notifier = new NotificationEmitter(this);
|
|
321
321
|
|
|
@@ -364,7 +364,10 @@ class VibeMCPServer {
|
|
|
364
364
|
jsonrpc: '2.0',
|
|
365
365
|
id,
|
|
366
366
|
result: {
|
|
367
|
-
tools: Object.values(tools).map(t =>
|
|
367
|
+
tools: Object.values(tools).map(t => ({
|
|
368
|
+
...t.definition,
|
|
369
|
+
annotations: TOOL_ANNOTATIONS[t.definition.name] || DEFAULT_ANNOTATIONS
|
|
370
|
+
}))
|
|
368
371
|
}
|
|
369
372
|
};
|
|
370
373
|
|
|
@@ -396,10 +399,15 @@ class VibeMCPServer {
|
|
|
396
399
|
// Emit list_changed notification for state-changing tools
|
|
397
400
|
// This triggers Claude to refresh without reconnection
|
|
398
401
|
const stateChangingTools = [
|
|
399
|
-
'vibe_dm',
|
|
400
|
-
'
|
|
401
|
-
'
|
|
402
|
-
'
|
|
402
|
+
'vibe_dm',
|
|
403
|
+
'vibe_ping',
|
|
404
|
+
'vibe_react',
|
|
405
|
+
'vibe_remember',
|
|
406
|
+
'vibe_status',
|
|
407
|
+
'vibe_context',
|
|
408
|
+
'vibe_handoff',
|
|
409
|
+
'vibe_reserve',
|
|
410
|
+
'vibe_release'
|
|
403
411
|
];
|
|
404
412
|
if (stateChangingTools.includes(params.name)) {
|
|
405
413
|
// Debounced notification (prevents spam)
|
|
@@ -412,14 +420,32 @@ class VibeMCPServer {
|
|
|
412
420
|
footer = await getPresenceFooter();
|
|
413
421
|
}
|
|
414
422
|
|
|
423
|
+
// Build simplified hint indicator for Claude (human-readable)
|
|
424
|
+
let hintIndicator = '';
|
|
425
|
+
if (result.hint) {
|
|
426
|
+
// Simple format: <!-- vibe: hint_type @handle (count) -->
|
|
427
|
+
const hint = result.hint;
|
|
428
|
+
const handle = result.suggestion?.handle || result.for_handle || '';
|
|
429
|
+
const count = result.unread_count || '';
|
|
430
|
+
|
|
431
|
+
// Build minimal hint string
|
|
432
|
+
const hintParts = [hint];
|
|
433
|
+
if (handle) hintParts.push(`@${handle.replace('@', '')}`);
|
|
434
|
+
if (count) hintParts.push(`(${count})`);
|
|
435
|
+
|
|
436
|
+
hintIndicator = `\n\n<!-- vibe: ${hintParts.join(' ')} -->`;
|
|
437
|
+
}
|
|
438
|
+
|
|
415
439
|
return {
|
|
416
440
|
jsonrpc: '2.0',
|
|
417
441
|
id,
|
|
418
442
|
result: {
|
|
419
|
-
content: [
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
443
|
+
content: [
|
|
444
|
+
{
|
|
445
|
+
type: 'text',
|
|
446
|
+
text: (result.display || JSON.stringify(result, null, 2)) + hintIndicator + footer
|
|
447
|
+
}
|
|
448
|
+
]
|
|
423
449
|
}
|
|
424
450
|
};
|
|
425
451
|
} catch (e) {
|
|
@@ -443,7 +469,7 @@ class VibeMCPServer {
|
|
|
443
469
|
process.stdin.setEncoding('utf8');
|
|
444
470
|
let buffer = '';
|
|
445
471
|
|
|
446
|
-
process.stdin.on('data', async
|
|
472
|
+
process.stdin.on('data', async chunk => {
|
|
447
473
|
buffer += chunk;
|
|
448
474
|
const lines = buffer.split('\n');
|
|
449
475
|
buffer = lines.pop() || '';
|
|
@@ -464,42 +490,26 @@ class VibeMCPServer {
|
|
|
464
490
|
|
|
465
491
|
process.stdin.on('end', () => {
|
|
466
492
|
presence.stop();
|
|
493
|
+
// Close SQLite to flush WAL and prevent corruption
|
|
494
|
+
try {
|
|
495
|
+
require('./store/sqlite').close();
|
|
496
|
+
} catch (e) {}
|
|
467
497
|
process.exit(0);
|
|
468
498
|
});
|
|
469
499
|
|
|
470
500
|
// Welcome message
|
|
471
501
|
process.stderr.write('\n/vibe ready.\n');
|
|
472
502
|
process.stderr.write('vibe init → set identity\n');
|
|
473
|
-
process.stderr.write(
|
|
503
|
+
process.stderr.write("vibe who → see who's around\n");
|
|
474
504
|
process.stderr.write('vibe dm → send a message\n\n');
|
|
475
505
|
|
|
476
506
|
// Check for updates (non-blocking)
|
|
477
507
|
this.checkForUpdates();
|
|
478
|
-
|
|
479
|
-
// Auto-presence: if authenticated, broadcast presence on connect
|
|
480
|
-
this.autoPresence();
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
async autoPresence() {
|
|
484
|
-
try {
|
|
485
|
-
const handle = config.getHandle();
|
|
486
|
-
if (!handle) return; // Not authenticated yet
|
|
487
|
-
|
|
488
|
-
const one_liner = config.getOneLiner() || '';
|
|
489
|
-
|
|
490
|
-
// Start presence heartbeat
|
|
491
|
-
presence.start(handle, one_liner);
|
|
492
|
-
|
|
493
|
-
// Log quietly (only to stderr, not intrusive)
|
|
494
|
-
process.stderr.write(`🟢 Auto-connected as @${handle}\n`);
|
|
495
|
-
} catch (error) {
|
|
496
|
-
// Silent fail - don't block startup
|
|
497
|
-
}
|
|
498
508
|
}
|
|
499
509
|
|
|
500
510
|
async checkForUpdates() {
|
|
501
511
|
try {
|
|
502
|
-
const { checkForUpdates, formatUpdateNotification } =
|
|
512
|
+
const { checkForUpdates, formatUpdateNotification } = await import('./auto-update.js');
|
|
503
513
|
const update = await checkForUpdates();
|
|
504
514
|
|
|
505
515
|
if (update) {
|
|
@@ -514,4 +524,4 @@ class VibeMCPServer {
|
|
|
514
524
|
|
|
515
525
|
// Start
|
|
516
526
|
const server = new VibeMCPServer();
|
|
517
|
-
server.start();
|
|
527
|
+
server.start();
|
package/intelligence/index.js
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Intelligence Module — Ambient Social Awareness
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Four layers of intelligence:
|
|
5
5
|
* 1. Infer — Smart state detection from context signals
|
|
6
6
|
* 2. Serendipity — Surface meaningful coincidences
|
|
7
7
|
* 3. Proactive — Background agent for social moments
|
|
8
8
|
* 4. Patterns — Persistent behavioral memory (work, social, creative)
|
|
9
|
-
* 5. Interests — Live interest inference from context (Phase 2)
|
|
10
9
|
*/
|
|
11
10
|
|
|
12
11
|
const infer = require('./infer');
|
|
13
12
|
const serendipity = require('./serendipity');
|
|
14
13
|
const proactive = require('./proactive');
|
|
15
14
|
const patterns = require('./patterns');
|
|
16
|
-
const interests = require('./interests');
|
|
17
15
|
|
|
18
16
|
module.exports = {
|
|
19
17
|
// Inference
|
|
@@ -36,10 +34,5 @@ module.exports = {
|
|
|
36
34
|
setSessionStart: proactive.setSessionStart,
|
|
37
35
|
|
|
38
36
|
// Patterns (persistent behavioral memory)
|
|
39
|
-
patterns
|
|
40
|
-
|
|
41
|
-
// Interests (live context inference - Phase 2)
|
|
42
|
-
inferLiveInterests: interests.inferLiveInterests,
|
|
43
|
-
mergeInterests: interests.mergeInterests,
|
|
44
|
-
formatLiveInterests: interests.formatLiveInterests
|
|
37
|
+
patterns
|
|
45
38
|
};
|