slashvibe-mcp 0.2.9 โ 0.3.13
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/README.md +1 -0
- package/analytics.js +107 -0
- package/auth-store.js +148 -0
- package/auto-update.js +130 -0
- package/bridges/bridge-monitor.js +388 -0
- package/bridges/discord-bot.js +431 -0
- package/bridges/farcaster.js +299 -0
- package/bridges/telegram.js +261 -0
- package/bridges/webhook-health.js +420 -0
- package/bridges/webhook-server.js +437 -0
- package/bridges/whatsapp.js +441 -0
- package/bridges/x-webhook.js +423 -0
- package/config.js +154 -5
- package/crypto.js +3 -8
- package/games/arcade.js +406 -0
- package/games/chess.js +451 -0
- package/games/colorguess.js +343 -0
- package/games/crossword-words.js +171 -0
- package/games/crossword.js +461 -0
- package/games/drawing.js +347 -0
- package/games/gameroulette.js +300 -0
- package/games/gamerouter.js +336 -0
- package/games/gamestatus.js +337 -0
- package/games/guessnumber.js +209 -0
- package/games/hangman.js +279 -0
- package/games/memory.js +338 -0
- package/games/multiplayer-tictactoe.js +389 -0
- package/games/pixelart.js +399 -0
- package/games/quickduel.js +354 -0
- package/games/riddle.js +371 -0
- package/games/rockpaperscissors.js +291 -0
- package/games/snake.js +406 -0
- package/games/storybuilder.js +343 -0
- package/games/tictactoe.js +345 -0
- package/games/twentyquestions.js +286 -0
- package/games/twotruths.js +207 -0
- package/games/werewolf.js +508 -0
- package/games/wordassociation.js +247 -0
- package/games/wordchain.js +135 -0
- package/index.js +105 -216
- package/intelligence/index.js +45 -0
- package/intelligence/infer.js +316 -0
- package/intelligence/interests.js +369 -0
- package/intelligence/patterns.js +651 -0
- package/intelligence/proactive.js +358 -0
- package/intelligence/serendipity.js +306 -0
- package/memory.js +166 -0
- package/notification-emitter.js +77 -0
- package/notify.js +102 -1
- package/package.json +21 -7
- package/prompts.js +1 -1
- package/protocol/index.js +161 -1
- package/setup.js +402 -0
- package/store/api.js +528 -82
- package/store/profiles.js +160 -12
- package/tools/_actions.js +463 -16
- package/tools/_deprecated/auto-suggest-connections.js +304 -0
- package/tools/_deprecated/bootstrap-skills.js +231 -0
- package/tools/_deprecated/bridge-dashboard.js +342 -0
- package/tools/_deprecated/bridge-health.js +400 -0
- package/tools/_deprecated/bridge-live.js +384 -0
- package/tools/_deprecated/bridges.js +383 -0
- package/tools/_deprecated/colorguess.js +281 -0
- package/tools/_deprecated/discover-insights.js +379 -0
- package/tools/_deprecated/discover-momentum.js +256 -0
- package/tools/_deprecated/discovery-analytics.js +345 -0
- package/tools/_deprecated/discovery-auto-suggest.js +275 -0
- package/tools/_deprecated/discovery-bootstrap.js +267 -0
- package/tools/_deprecated/discovery-daily.js +375 -0
- package/tools/_deprecated/discovery-dashboard.js +385 -0
- package/tools/_deprecated/discovery-digest.js +314 -0
- package/tools/_deprecated/discovery-hub.js +357 -0
- package/tools/_deprecated/discovery-insights.js +384 -0
- package/tools/_deprecated/discovery-momentum.js +281 -0
- package/tools/_deprecated/discovery-monitor.js +319 -0
- package/tools/_deprecated/discovery-proactive.js +300 -0
- package/tools/_deprecated/draw.js +317 -0
- package/tools/_deprecated/farcaster.js +307 -0
- package/tools/_deprecated/forget.js +119 -0
- package/tools/_deprecated/games-catalog.js +376 -0
- package/tools/_deprecated/games.js +313 -0
- package/tools/_deprecated/guessnumber.js +194 -0
- package/tools/_deprecated/hangman.js +129 -0
- package/tools/_deprecated/multiplayer-tictactoe.js +303 -0
- package/tools/_deprecated/recall.js +147 -0
- package/tools/_deprecated/remember.js +86 -0
- package/tools/_deprecated/riddle.js +240 -0
- package/tools/_deprecated/run-bootstrap.js +69 -0
- package/tools/_deprecated/skills-analytics.js +349 -0
- package/tools/_deprecated/skills-bootstrap.js +301 -0
- package/tools/_deprecated/skills-dashboard.js +268 -0
- package/tools/_deprecated/skills.js +380 -0
- package/tools/_deprecated/smart-intro.js +353 -0
- package/tools/_deprecated/storybuilder.js +331 -0
- package/tools/_deprecated/telegram-bot.js +183 -0
- package/tools/_deprecated/telegram-setup.js +214 -0
- package/tools/_deprecated/twentyquestions.js +143 -0
- package/tools/_discovery-enhanced.js +290 -0
- package/tools/_discovery.js +439 -0
- package/tools/_proactive-discovery.js +301 -0
- package/tools/_shared/index.js +64 -0
- package/tools/_shared.js +234 -0
- package/tools/_work-context.js +338 -0
- package/tools/_work-context.manual-test.js +199 -0
- package/tools/_work-context.test.js +260 -0
- package/tools/activity.js +220 -0
- package/tools/admin-inbox.js +218 -0
- package/tools/agent-treasury.js +288 -0
- package/tools/analytics.js +191 -0
- package/tools/approve.js +197 -0
- package/tools/arcade.js +173 -0
- package/tools/artifact-create.js +17 -11
- package/tools/artifact-view.js +31 -1
- package/tools/artifacts-price.js +47 -43
- package/tools/ask-expert.js +160 -0
- package/tools/available.js +120 -0
- package/tools/become-expert.js +150 -0
- package/tools/broadcast.js +286 -0
- package/tools/chat.js +202 -0
- package/tools/collaborative-drawing.js +286 -0
- package/tools/connection-status.js +178 -0
- package/tools/crossword.js +17 -1
- package/tools/discover.js +350 -34
- package/tools/dm.js +115 -73
- package/tools/drawing.js +1 -1
- package/tools/earnings.js +126 -0
- package/tools/echo.js +16 -0
- package/tools/feed.js +51 -7
- package/tools/follow.js +224 -0
- package/tools/friends.js +207 -0
- package/tools/game.js +2 -2
- package/tools/genesis.js +233 -0
- package/tools/gig-browse.js +206 -0
- package/tools/gig-complete.js +144 -0
- package/tools/handoff.js +7 -1
- package/tools/help.js +4 -4
- package/tools/idea.js +9 -2
- package/tools/inbox.js +334 -28
- package/tools/init.js +727 -36
- package/tools/invite.js +15 -4
- package/tools/l2-bridge.js +272 -0
- package/tools/l2-status.js +217 -0
- package/tools/l2.js +206 -0
- package/tools/migrate.js +156 -0
- package/tools/mint.js +377 -0
- package/tools/multiplayer-game.js +1 -1
- package/tools/notifications.js +415 -0
- package/tools/observe.js +200 -0
- package/tools/onboarding.js +147 -0
- package/tools/open.js +143 -12
- package/tools/party-game.js +2 -2
- package/tools/plan.js +225 -0
- package/tools/presence-agent.js +7 -0
- package/tools/proof-of-work.js +100 -104
- package/tools/pulse.js +218 -0
- package/tools/reply.js +166 -0
- package/tools/report.js +2 -2
- package/tools/reputation.js +175 -0
- package/tools/request.js +17 -3
- package/tools/schedule.js +367 -0
- package/tools/search-messages.js +123 -0
- package/tools/session.js +420 -0
- package/tools/session_price.js +128 -0
- package/tools/settings.js +126 -3
- package/tools/ship.js +31 -8
- package/tools/shipback.js +326 -0
- package/tools/smart-check.js +201 -0
- package/tools/social-processor.js +445 -0
- package/tools/solo-game.js +1 -1
- package/tools/start.js +335 -93
- package/tools/status.js +53 -6
- package/tools/stuck.js +297 -0
- package/tools/subscribe.js +148 -0
- package/tools/subscriptions.js +134 -0
- package/tools/suggest-tags.js +6 -8
- package/tools/tag-suggestions.js +257 -0
- package/tools/tip.js +193 -0
- package/tools/token.js +103 -0
- package/tools/update.js +1 -1
- package/tools/wallet.js +239 -186
- package/tools/watch.js +157 -0
- package/tools/webhook-test.js +388 -0
- package/tools/who.js +54 -3
- package/tools/withdraw.js +145 -0
- package/tools/work-summary.js +96 -0
- package/tools/workshop.js +327 -0
- package/tools/x-mentions.js +1 -1
- package/version.json +14 -3
- package/tools/artifacts-buy.js +0 -111
- package/tools/connect.js +0 -284
- package/tools/gigs-apply.js +0 -99
- package/tools/gigs-browse.js +0 -114
- package/tools/gigs-complete.js +0 -128
- package/tools/gigs-post.js +0 -140
- package/tools/live-off.js +0 -109
- package/tools/live-watch.js +0 -176
- package/tools/live.js +0 -128
- package/tools/sessions-browse.js +0 -105
- package/tools/whats-happening.js +0 -125
- /package/tools/{away.js โ _deprecated/away.js} +0 -0
- /package/tools/{back.js โ _deprecated/back.js} +0 -0
- /package/tools/{mute.js โ _deprecated/mute.js} +0 -0
- /package/tools/{skills-exchange.js โ _deprecated/skills-exchange.js} +0 -0
- /package/tools/{tictactoe.js โ _deprecated/tictactoe.js} +0 -0
- /package/tools/{wordassociation.js โ _deprecated/wordassociation.js} +0 -0
package/tools/gigs-post.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe gigs-post โ Post a gig to get help
|
|
3
|
-
*
|
|
4
|
-
* Post a paid gig to the community. Describe what you need,
|
|
5
|
-
* set your budget, and let builders apply to help.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const config = require('../config');
|
|
9
|
-
const { requireInit } = require('./_shared');
|
|
10
|
-
|
|
11
|
-
const API_URL = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
|
|
12
|
-
|
|
13
|
-
const definition = {
|
|
14
|
-
name: 'vibe_gigs_post',
|
|
15
|
-
description: 'Post a gig to get help from the community. Specify what you need built, fixed, designed, or reviewed. Set your budget and required skills.',
|
|
16
|
-
inputSchema: {
|
|
17
|
-
type: 'object',
|
|
18
|
-
properties: {
|
|
19
|
-
title: {
|
|
20
|
-
type: 'string',
|
|
21
|
-
description: 'Short title for the gig (e.g., "Build a landing page")'
|
|
22
|
-
},
|
|
23
|
-
description: {
|
|
24
|
-
type: 'string',
|
|
25
|
-
description: 'Detailed description of what you need'
|
|
26
|
-
},
|
|
27
|
-
category: {
|
|
28
|
-
type: 'string',
|
|
29
|
-
description: 'Category: build, fix, design, review, teach, consult, other'
|
|
30
|
-
},
|
|
31
|
-
skills: {
|
|
32
|
-
type: 'string',
|
|
33
|
-
description: 'Comma-separated skills needed (e.g., "react, tailwind, typescript")'
|
|
34
|
-
},
|
|
35
|
-
budget_min: {
|
|
36
|
-
type: 'number',
|
|
37
|
-
description: 'Minimum budget in USD'
|
|
38
|
-
},
|
|
39
|
-
budget_max: {
|
|
40
|
-
type: 'number',
|
|
41
|
-
description: 'Maximum budget in USD'
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
required: ['title', 'description', 'category']
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
async function handler(args) {
|
|
49
|
-
const initCheck = requireInit();
|
|
50
|
-
if (initCheck) return initCheck;
|
|
51
|
-
|
|
52
|
-
const handle = config.getHandle();
|
|
53
|
-
if (!handle) {
|
|
54
|
-
return {
|
|
55
|
-
display: `## Post a Gig\n\n_You need to be logged in to post a gig._\n\nRun \`vibe init\` first.`
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const {
|
|
60
|
-
title,
|
|
61
|
-
description,
|
|
62
|
-
category,
|
|
63
|
-
skills,
|
|
64
|
-
budget_min,
|
|
65
|
-
budget_max
|
|
66
|
-
} = args;
|
|
67
|
-
|
|
68
|
-
// Validate required fields
|
|
69
|
-
if (!title || !description || !category) {
|
|
70
|
-
return {
|
|
71
|
-
display: `## Post a Gig\n\n_Missing required fields._\n\n**Required:**\n- title: Short title for the gig\n- description: What you need done\n- category: build, fix, design, review, teach, consult, other\n\n**Optional:**\n- skills: Comma-separated skills (e.g., "react, python")\n- budget_min / budget_max: Budget range in USD`
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const validCategories = ['build', 'fix', 'design', 'review', 'teach', 'consult', 'other'];
|
|
76
|
-
if (!validCategories.includes(category.toLowerCase())) {
|
|
77
|
-
return {
|
|
78
|
-
display: `## Post a Gig\n\n_Invalid category "${category}"._\n\nValid categories: ${validCategories.join(', ')}`
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
const gigData = {
|
|
84
|
-
poster: handle,
|
|
85
|
-
title,
|
|
86
|
-
description,
|
|
87
|
-
category: category.toLowerCase(),
|
|
88
|
-
skills_needed: skills
|
|
89
|
-
? skills.split(',').map(s => s.trim().toLowerCase())
|
|
90
|
-
: [],
|
|
91
|
-
budget: (budget_min || budget_max)
|
|
92
|
-
? {
|
|
93
|
-
min: budget_min || budget_max,
|
|
94
|
-
max: budget_max || budget_min
|
|
95
|
-
}
|
|
96
|
-
: null
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const response = await fetch(`${API_URL}/api/gigs`, {
|
|
100
|
-
method: 'POST',
|
|
101
|
-
headers: {
|
|
102
|
-
'Content-Type': 'application/json'
|
|
103
|
-
},
|
|
104
|
-
body: JSON.stringify(gigData)
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
const data = await response.json();
|
|
108
|
-
|
|
109
|
-
if (!data.success) {
|
|
110
|
-
return {
|
|
111
|
-
display: `## Post a Gig\n\n_Failed to post gig: ${data.error || 'Unknown error'}_`
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const gig = data.gig;
|
|
116
|
-
const budget = gig.budget
|
|
117
|
-
? `$${gig.budget.min}-${gig.budget.max}`
|
|
118
|
-
: 'negotiable';
|
|
119
|
-
|
|
120
|
-
let display = `## Gig Posted! โ\n\n`;
|
|
121
|
-
display += `**${gig.title}** [${gig.category}]\n`;
|
|
122
|
-
display += `Budget: ${budget}\n`;
|
|
123
|
-
if (gig.skills_needed?.length > 0) {
|
|
124
|
-
display += `Skills: ${gig.skills_needed.join(', ')}\n`;
|
|
125
|
-
}
|
|
126
|
-
display += `\n_"${gig.description}"_\n\n`;
|
|
127
|
-
display += `---\n`;
|
|
128
|
-
display += `Your gig is now visible to the community. You'll be notified when someone applies.\n\n`;
|
|
129
|
-
display += `View all gigs: "browse gigs"`;
|
|
130
|
-
|
|
131
|
-
return { display };
|
|
132
|
-
|
|
133
|
-
} catch (e) {
|
|
134
|
-
return {
|
|
135
|
-
display: `## Post a Gig\n\n_Error posting gig: ${e.message}_`
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
module.exports = { definition, handler };
|
package/tools/live-off.js
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe off โ End your live stream
|
|
3
|
-
*
|
|
4
|
-
* Stops broadcasting. Session is saved for replay.
|
|
5
|
-
* The jazz solo ends, but the recording remains.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const config = require('../config');
|
|
9
|
-
const liveState = require('../live-state');
|
|
10
|
-
const { requireInit } = require('./_shared');
|
|
11
|
-
|
|
12
|
-
const API_URL = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
|
|
13
|
-
|
|
14
|
-
const definition = {
|
|
15
|
-
name: 'vibe_off',
|
|
16
|
-
description: 'End your live stream. Session is saved for replay.',
|
|
17
|
-
inputSchema: {
|
|
18
|
-
type: 'object',
|
|
19
|
-
properties: {}
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
async function handler(args) {
|
|
24
|
-
const initCheck = requireInit();
|
|
25
|
-
if (initCheck) return initCheck;
|
|
26
|
-
|
|
27
|
-
const session = liveState.getSession();
|
|
28
|
-
|
|
29
|
-
if (!session) {
|
|
30
|
-
return {
|
|
31
|
-
display: `## Not Live
|
|
32
|
-
|
|
33
|
-
You're not currently streaming.
|
|
34
|
-
|
|
35
|
-
Say "vibe live" to start a session.`
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
// Stop broadcast via API
|
|
41
|
-
const response = await fetch(`${API_URL}/api/watch`, {
|
|
42
|
-
method: 'POST',
|
|
43
|
-
headers: { 'Content-Type': 'application/json' },
|
|
44
|
-
body: JSON.stringify({
|
|
45
|
-
action: 'stop',
|
|
46
|
-
roomId: session.roomId
|
|
47
|
-
})
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const data = await response.json();
|
|
51
|
-
|
|
52
|
-
// End local session
|
|
53
|
-
const endedSession = liveState.endSession();
|
|
54
|
-
|
|
55
|
-
// Calculate duration
|
|
56
|
-
const durationMs = Date.now() - (endedSession.startedAt || Date.now());
|
|
57
|
-
const durationMin = Math.floor(durationMs / 60000);
|
|
58
|
-
const durationSec = Math.floor((durationMs % 60000) / 1000);
|
|
59
|
-
const durationStr = durationMin > 0
|
|
60
|
-
? `${durationMin}m ${durationSec}s`
|
|
61
|
-
: `${durationSec}s`;
|
|
62
|
-
|
|
63
|
-
let display = `## Session Ended
|
|
64
|
-
|
|
65
|
-
**Duration:** ${durationStr}
|
|
66
|
-
**Tool calls:** ${endedSession.toolCallCount || 0}
|
|
67
|
-
**Peak viewers:** ${endedSession.peakViewers || 0}
|
|
68
|
-
|
|
69
|
-
`;
|
|
70
|
-
|
|
71
|
-
// If we got a replay URL from the API
|
|
72
|
-
if (data.replayUrl) {
|
|
73
|
-
display += `**Replay:** ${data.replayUrl}\n`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
display += `
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
The solo is complete. ๐ท
|
|
80
|
-
|
|
81
|
-
**What's next:**
|
|
82
|
-
โข "vibe live" โ start another session
|
|
83
|
-
โข "browse sessions" โ see what others built
|
|
84
|
-
โข "vibe" โ check what's happening`;
|
|
85
|
-
|
|
86
|
-
return {
|
|
87
|
-
display,
|
|
88
|
-
data: {
|
|
89
|
-
duration: durationMs,
|
|
90
|
-
toolCalls: endedSession.toolCallCount,
|
|
91
|
-
peakViewers: endedSession.peakViewers
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
} catch (e) {
|
|
96
|
-
// Even if API fails, clear local state
|
|
97
|
-
liveState.endSession();
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
display: `## Session Ended
|
|
101
|
-
|
|
102
|
-
_Note: API error (${e.message}), but local session cleared._
|
|
103
|
-
|
|
104
|
-
Say "vibe live" to start a new session.`
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
module.exports = { definition, handler };
|
package/tools/live-watch.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe watch โ Drop into someone's live session
|
|
3
|
-
*
|
|
4
|
-
* See who's streaming. Pick someone. Watch their flow.
|
|
5
|
-
* Jazz club energy. Drop in anytime.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const config = require('../config');
|
|
9
|
-
const { requireInit } = require('./_shared');
|
|
10
|
-
|
|
11
|
-
const API_URL = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
|
|
12
|
-
|
|
13
|
-
const definition = {
|
|
14
|
-
name: 'vibe_watch',
|
|
15
|
-
description: 'See who\'s streaming live and drop into their session. Watch how others code.',
|
|
16
|
-
inputSchema: {
|
|
17
|
-
type: 'object',
|
|
18
|
-
properties: {
|
|
19
|
-
handle: {
|
|
20
|
-
type: 'string',
|
|
21
|
-
description: 'Specific handle to watch (optional, shows all live if omitted)'
|
|
22
|
-
},
|
|
23
|
-
random: {
|
|
24
|
-
type: 'boolean',
|
|
25
|
-
description: 'Drop into a random live session'
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
function formatDuration(seconds) {
|
|
32
|
-
if (seconds < 60) return 'just started';
|
|
33
|
-
if (seconds < 3600) return Math.floor(seconds / 60) + 'm';
|
|
34
|
-
const h = Math.floor(seconds / 3600);
|
|
35
|
-
const m = Math.floor((seconds % 3600) / 60);
|
|
36
|
-
return `${h}h ${m}m`;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function handler(args) {
|
|
40
|
-
const initCheck = requireInit();
|
|
41
|
-
if (initCheck) return initCheck;
|
|
42
|
-
|
|
43
|
-
const { handle, random } = args;
|
|
44
|
-
const myHandle = config.getHandle();
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
// Get live broadcasts
|
|
48
|
-
const response = await fetch(`${API_URL}/api/live?format=json`);
|
|
49
|
-
const data = await response.json();
|
|
50
|
-
|
|
51
|
-
if (!data.success) {
|
|
52
|
-
return {
|
|
53
|
-
display: `## Live Sessions
|
|
54
|
-
|
|
55
|
-
_Error fetching live sessions._`
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const broadcasts = data.broadcasts || [];
|
|
60
|
-
|
|
61
|
-
// Filter out own session
|
|
62
|
-
const others = broadcasts.filter(b => b.handle !== myHandle);
|
|
63
|
-
|
|
64
|
-
if (others.length === 0) {
|
|
65
|
-
return {
|
|
66
|
-
display: `## Live Sessions
|
|
67
|
-
|
|
68
|
-
_No one is streaming right now._
|
|
69
|
-
|
|
70
|
-
Be the first! Say "vibe live" to start broadcasting.
|
|
71
|
-
|
|
72
|
-
**Tip:** When someone goes live, you'll see them here.`
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// If specific handle requested
|
|
77
|
-
if (handle) {
|
|
78
|
-
const target = others.find(b =>
|
|
79
|
-
b.handle.toLowerCase() === handle.toLowerCase().replace('@', '')
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
if (!target) {
|
|
83
|
-
return {
|
|
84
|
-
display: `## Live Sessions
|
|
85
|
-
|
|
86
|
-
@${handle.replace('@', '')} is not currently live.
|
|
87
|
-
|
|
88
|
-
**Currently streaming:**
|
|
89
|
-
${others.slice(0, 5).map(b => `โข @${b.handle}`).join('\n')}
|
|
90
|
-
|
|
91
|
-
Pick one to watch, or say "vibe live" to go live yourself.`
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
display: `## Watching @${target.handle}
|
|
97
|
-
|
|
98
|
-
**Duration:** ${formatDuration(target.duration)}
|
|
99
|
-
**Viewers:** ${target.viewers}
|
|
100
|
-
|
|
101
|
-
**Watch in browser:** slashvibe.dev/watch/${target.roomId}
|
|
102
|
-
|
|
103
|
-
_Drop in anytime. Leave anytime. Jazz club rules._ ๐ท`,
|
|
104
|
-
data: {
|
|
105
|
-
watching: target.handle,
|
|
106
|
-
roomId: target.roomId,
|
|
107
|
-
watchUrl: `slashvibe.dev/watch/${target.roomId}`
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Random selection
|
|
113
|
-
if (random) {
|
|
114
|
-
const target = others[Math.floor(Math.random() * others.length)];
|
|
115
|
-
return {
|
|
116
|
-
display: `## ๐ฒ Random Drop-In
|
|
117
|
-
|
|
118
|
-
Watching **@${target.handle}**
|
|
119
|
-
|
|
120
|
-
**Duration:** ${formatDuration(target.duration)}
|
|
121
|
-
**Viewers:** ${target.viewers}
|
|
122
|
-
|
|
123
|
-
**Watch:** slashvibe.dev/watch/${target.roomId}
|
|
124
|
-
|
|
125
|
-
_Surprise yourself with someone else's flow._ ๐ท`,
|
|
126
|
-
data: {
|
|
127
|
-
watching: target.handle,
|
|
128
|
-
roomId: target.roomId,
|
|
129
|
-
watchUrl: `slashvibe.dev/watch/${target.roomId}`
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Show all live sessions
|
|
135
|
-
let display = `## ๐ด Live Now
|
|
136
|
-
|
|
137
|
-
${others.length} ${others.length === 1 ? 'person' : 'people'} streaming:
|
|
138
|
-
|
|
139
|
-
`;
|
|
140
|
-
|
|
141
|
-
others.slice(0, 10).forEach(b => {
|
|
142
|
-
const duration = formatDuration(b.duration);
|
|
143
|
-
const viewers = b.viewers > 0 ? ` ยท ${b.viewers} watching` : '';
|
|
144
|
-
display += `โข **@${b.handle}** โ ${duration}${viewers}\n`;
|
|
145
|
-
display += ` slashvibe.dev/watch/${b.roomId}\n\n`;
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
if (others.length > 10) {
|
|
149
|
-
display += `_...and ${others.length - 10} more_\n\n`;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
display += `---
|
|
153
|
-
|
|
154
|
-
**Commands:**
|
|
155
|
-
โข "watch @handle" โ drop into specific session
|
|
156
|
-
โข "watch --random" โ surprise me
|
|
157
|
-
โข "vibe live" โ start your own session`;
|
|
158
|
-
|
|
159
|
-
return {
|
|
160
|
-
display,
|
|
161
|
-
data: {
|
|
162
|
-
count: others.length,
|
|
163
|
-
broadcasts: others.slice(0, 10)
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
} catch (e) {
|
|
168
|
-
return {
|
|
169
|
-
display: `## Live Sessions
|
|
170
|
-
|
|
171
|
-
_Error: ${e.message}_`
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
module.exports = { definition, handler };
|
package/tools/live.js
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe live โ Go live. Stream your coding session.
|
|
3
|
-
*
|
|
4
|
-
* "Watch me code!" โ One command, you're streaming.
|
|
5
|
-
* Block by block, your tool calls flow to watchers.
|
|
6
|
-
* Jazz solo energy. The craft made visible.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const config = require('../config');
|
|
10
|
-
const liveState = require('../live-state');
|
|
11
|
-
const { requireInit } = require('./_shared');
|
|
12
|
-
|
|
13
|
-
const API_URL = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
|
|
14
|
-
|
|
15
|
-
const definition = {
|
|
16
|
-
name: 'vibe_live',
|
|
17
|
-
description: 'Go live! Start streaming your coding session. Others can watch your tool calls flow in real-time. Jazz solo energy.',
|
|
18
|
-
inputSchema: {
|
|
19
|
-
type: 'object',
|
|
20
|
-
properties: {
|
|
21
|
-
title: {
|
|
22
|
-
type: 'string',
|
|
23
|
-
description: 'What you\'re working on (optional, shows to watchers)'
|
|
24
|
-
},
|
|
25
|
-
identity: {
|
|
26
|
-
type: 'string',
|
|
27
|
-
enum: ['anon', 'handle', 'full'],
|
|
28
|
-
description: 'How much to reveal: anon (just code), handle (default), full (with bio/pedigree)'
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
async function handler(args) {
|
|
35
|
-
const initCheck = requireInit();
|
|
36
|
-
if (initCheck) return initCheck;
|
|
37
|
-
|
|
38
|
-
const handle = config.getHandle();
|
|
39
|
-
const { title, identity = 'handle' } = args;
|
|
40
|
-
|
|
41
|
-
// Check if already live
|
|
42
|
-
const currentSession = liveState.getSession();
|
|
43
|
-
if (currentSession) {
|
|
44
|
-
return {
|
|
45
|
-
display: `## Already Live
|
|
46
|
-
|
|
47
|
-
You're already streaming!
|
|
48
|
-
|
|
49
|
-
๐ด **Room:** ${currentSession.roomId}
|
|
50
|
-
๐๏ธ **Watch:** slashvibe.dev/watch/${currentSession.roomId}
|
|
51
|
-
|
|
52
|
-
Say "vibe off" to stop streaming.`
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
// Start broadcast via API
|
|
58
|
-
const response = await fetch(`${API_URL}/api/watch`, {
|
|
59
|
-
method: 'POST',
|
|
60
|
-
headers: { 'Content-Type': 'application/json' },
|
|
61
|
-
body: JSON.stringify({
|
|
62
|
-
action: 'start',
|
|
63
|
-
handle: identity === 'anon' ? 'anonymous' : handle,
|
|
64
|
-
title: title || config.getOneLiner() || 'coding session'
|
|
65
|
-
})
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const data = await response.json();
|
|
69
|
-
|
|
70
|
-
if (!data.success) {
|
|
71
|
-
return {
|
|
72
|
-
display: `## Go Live
|
|
73
|
-
|
|
74
|
-
_Failed to start broadcast: ${data.error || 'Unknown error'}_
|
|
75
|
-
|
|
76
|
-
Try again in a moment.`
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Store session locally
|
|
81
|
-
liveState.startSession({
|
|
82
|
-
roomId: data.roomId,
|
|
83
|
-
handle: identity === 'anon' ? 'anonymous' : handle,
|
|
84
|
-
identity,
|
|
85
|
-
title: title || config.getOneLiner(),
|
|
86
|
-
startedAt: Date.now()
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
const watchUrl = `slashvibe.dev/watch/${data.roomId}`;
|
|
90
|
-
const displayHandle = identity === 'anon' ? 'anonymous' : `@${handle}`;
|
|
91
|
-
|
|
92
|
-
let display = `## ๐ด You're Live
|
|
93
|
-
|
|
94
|
-
**${displayHandle}** ${title ? `ยท ${title}` : ''}
|
|
95
|
-
|
|
96
|
-
Your tool calls are now streaming to watchers.
|
|
97
|
-
Every file read, edit, command โ they see the flow.
|
|
98
|
-
|
|
99
|
-
**Watch URL:** ${watchUrl}
|
|
100
|
-
**Viewers:** 0
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
**Commands:**
|
|
105
|
-
โข "vibe off" โ stop streaming
|
|
106
|
-
โข "vibe private" โ pause momentarily
|
|
107
|
-
|
|
108
|
-
Just keep coding. The jazz solo has begun. ๐ท`;
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
display,
|
|
112
|
-
data: {
|
|
113
|
-
roomId: data.roomId,
|
|
114
|
-
watchUrl,
|
|
115
|
-
identity
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
} catch (e) {
|
|
120
|
-
return {
|
|
121
|
-
display: `## Go Live
|
|
122
|
-
|
|
123
|
-
_Error starting broadcast: ${e.message}_`
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
module.exports = { definition, handler };
|
package/tools/sessions-browse.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe sessions-browse โ Discover what people are building
|
|
3
|
-
*
|
|
4
|
-
* Browse shared coding sessions from the community.
|
|
5
|
-
* See what problems people are solving, what tech they're using,
|
|
6
|
-
* and learn from their approaches.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const config = require('../config');
|
|
10
|
-
const { requireInit } = require('./_shared');
|
|
11
|
-
|
|
12
|
-
const API_URL = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
|
|
13
|
-
|
|
14
|
-
const definition = {
|
|
15
|
-
name: 'vibe_sessions_browse',
|
|
16
|
-
description: 'Browse shared coding sessions from the community. See what others are building, learn from their approaches, find sessions by tech stack or topic.',
|
|
17
|
-
inputSchema: {
|
|
18
|
-
type: 'object',
|
|
19
|
-
properties: {
|
|
20
|
-
filter: {
|
|
21
|
-
type: 'string',
|
|
22
|
-
description: 'Filter by: trending, recent, or a tech stack like "react", "python", "rust"'
|
|
23
|
-
},
|
|
24
|
-
limit: {
|
|
25
|
-
type: 'number',
|
|
26
|
-
description: 'Number of sessions to show (default 5)'
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
async function handler(args) {
|
|
33
|
-
const initCheck = requireInit();
|
|
34
|
-
if (initCheck) return initCheck;
|
|
35
|
-
|
|
36
|
-
const { filter = 'trending', limit = 5 } = args;
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
// Determine which endpoint to use
|
|
40
|
-
let endpoint = '/api/sessions/browse';
|
|
41
|
-
let params = `limit=${limit}`;
|
|
42
|
-
|
|
43
|
-
if (filter === 'trending') {
|
|
44
|
-
endpoint = '/api/sessions/trending';
|
|
45
|
-
params += '&period=week';
|
|
46
|
-
} else if (filter === 'recent') {
|
|
47
|
-
endpoint = '/api/sessions/browse';
|
|
48
|
-
params += '&sort=recent';
|
|
49
|
-
} else {
|
|
50
|
-
// Treat as tech stack filter
|
|
51
|
-
endpoint = '/api/sessions/search';
|
|
52
|
-
params += `&q=${encodeURIComponent(filter)}`;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const response = await fetch(`${API_URL}${endpoint}?${params}`);
|
|
56
|
-
const data = await response.json();
|
|
57
|
-
|
|
58
|
-
if (!data.success) {
|
|
59
|
-
return {
|
|
60
|
-
display: `## Sessions\n\n_Couldn't load sessions: ${data.error || 'Unknown error'}_`
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const sessions = data.sessions || [];
|
|
65
|
-
|
|
66
|
-
if (sessions.length === 0) {
|
|
67
|
-
return {
|
|
68
|
-
display: `## Sessions\n\n_No sessions found${filter !== 'trending' ? ` for "${filter}"` : ''}._\n\nBe the first to share your work! Sessions help others learn from your approach.\n\n**Share a session**: When you're done building something interesting, share it with the community.`
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
let display = `## ${filter === 'trending' ? 'Trending' : filter === 'recent' ? 'Recent' : `Sessions: ${filter}`}\n\n`;
|
|
73
|
-
|
|
74
|
-
sessions.forEach((s, i) => {
|
|
75
|
-
const title = s.title || 'Untitled Session';
|
|
76
|
-
const author = s.author_handle || s.author || 'anonymous';
|
|
77
|
-
const views = s.views || 0;
|
|
78
|
-
const techStack = (s.enrichment?.techStack || []).slice(0, 3).join(', ');
|
|
79
|
-
const duration = s.duration_seconds
|
|
80
|
-
? `${Math.floor(s.duration_seconds / 60)}m`
|
|
81
|
-
: '';
|
|
82
|
-
|
|
83
|
-
display += `**${i + 1}. ${title}**\n`;
|
|
84
|
-
display += ` by @${author}`;
|
|
85
|
-
if (duration) display += ` โข ${duration}`;
|
|
86
|
-
if (views > 0) display += ` โข ${views} views`;
|
|
87
|
-
display += '\n';
|
|
88
|
-
if (techStack) display += ` _${techStack}_\n`;
|
|
89
|
-
display += ` โ slashvibe.dev/session/${s.id}\n\n`;
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
display += `---\n`;
|
|
93
|
-
display += `View all sessions: slashvibe.dev/sessions\n`;
|
|
94
|
-
display += `Watch live: slashvibe.dev/live`;
|
|
95
|
-
|
|
96
|
-
return { display };
|
|
97
|
-
|
|
98
|
-
} catch (e) {
|
|
99
|
-
return {
|
|
100
|
-
display: `## Sessions\n\n_Error loading sessions: ${e.message}_`
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
module.exports = { definition, handler };
|