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.
Files changed (205) hide show
  1. package/README.md +1 -0
  2. package/analytics.js +107 -0
  3. package/auth-store.js +148 -0
  4. package/auto-update.js +130 -0
  5. package/bridges/bridge-monitor.js +388 -0
  6. package/bridges/discord-bot.js +431 -0
  7. package/bridges/farcaster.js +299 -0
  8. package/bridges/telegram.js +261 -0
  9. package/bridges/webhook-health.js +420 -0
  10. package/bridges/webhook-server.js +437 -0
  11. package/bridges/whatsapp.js +441 -0
  12. package/bridges/x-webhook.js +423 -0
  13. package/config.js +154 -5
  14. package/crypto.js +3 -8
  15. package/games/arcade.js +406 -0
  16. package/games/chess.js +451 -0
  17. package/games/colorguess.js +343 -0
  18. package/games/crossword-words.js +171 -0
  19. package/games/crossword.js +461 -0
  20. package/games/drawing.js +347 -0
  21. package/games/gameroulette.js +300 -0
  22. package/games/gamerouter.js +336 -0
  23. package/games/gamestatus.js +337 -0
  24. package/games/guessnumber.js +209 -0
  25. package/games/hangman.js +279 -0
  26. package/games/memory.js +338 -0
  27. package/games/multiplayer-tictactoe.js +389 -0
  28. package/games/pixelart.js +399 -0
  29. package/games/quickduel.js +354 -0
  30. package/games/riddle.js +371 -0
  31. package/games/rockpaperscissors.js +291 -0
  32. package/games/snake.js +406 -0
  33. package/games/storybuilder.js +343 -0
  34. package/games/tictactoe.js +345 -0
  35. package/games/twentyquestions.js +286 -0
  36. package/games/twotruths.js +207 -0
  37. package/games/werewolf.js +508 -0
  38. package/games/wordassociation.js +247 -0
  39. package/games/wordchain.js +135 -0
  40. package/index.js +105 -216
  41. package/intelligence/index.js +45 -0
  42. package/intelligence/infer.js +316 -0
  43. package/intelligence/interests.js +369 -0
  44. package/intelligence/patterns.js +651 -0
  45. package/intelligence/proactive.js +358 -0
  46. package/intelligence/serendipity.js +306 -0
  47. package/memory.js +166 -0
  48. package/notification-emitter.js +77 -0
  49. package/notify.js +102 -1
  50. package/package.json +21 -7
  51. package/prompts.js +1 -1
  52. package/protocol/index.js +161 -1
  53. package/setup.js +402 -0
  54. package/store/api.js +528 -82
  55. package/store/profiles.js +160 -12
  56. package/tools/_actions.js +463 -16
  57. package/tools/_deprecated/auto-suggest-connections.js +304 -0
  58. package/tools/_deprecated/bootstrap-skills.js +231 -0
  59. package/tools/_deprecated/bridge-dashboard.js +342 -0
  60. package/tools/_deprecated/bridge-health.js +400 -0
  61. package/tools/_deprecated/bridge-live.js +384 -0
  62. package/tools/_deprecated/bridges.js +383 -0
  63. package/tools/_deprecated/colorguess.js +281 -0
  64. package/tools/_deprecated/discover-insights.js +379 -0
  65. package/tools/_deprecated/discover-momentum.js +256 -0
  66. package/tools/_deprecated/discovery-analytics.js +345 -0
  67. package/tools/_deprecated/discovery-auto-suggest.js +275 -0
  68. package/tools/_deprecated/discovery-bootstrap.js +267 -0
  69. package/tools/_deprecated/discovery-daily.js +375 -0
  70. package/tools/_deprecated/discovery-dashboard.js +385 -0
  71. package/tools/_deprecated/discovery-digest.js +314 -0
  72. package/tools/_deprecated/discovery-hub.js +357 -0
  73. package/tools/_deprecated/discovery-insights.js +384 -0
  74. package/tools/_deprecated/discovery-momentum.js +281 -0
  75. package/tools/_deprecated/discovery-monitor.js +319 -0
  76. package/tools/_deprecated/discovery-proactive.js +300 -0
  77. package/tools/_deprecated/draw.js +317 -0
  78. package/tools/_deprecated/farcaster.js +307 -0
  79. package/tools/_deprecated/forget.js +119 -0
  80. package/tools/_deprecated/games-catalog.js +376 -0
  81. package/tools/_deprecated/games.js +313 -0
  82. package/tools/_deprecated/guessnumber.js +194 -0
  83. package/tools/_deprecated/hangman.js +129 -0
  84. package/tools/_deprecated/multiplayer-tictactoe.js +303 -0
  85. package/tools/_deprecated/recall.js +147 -0
  86. package/tools/_deprecated/remember.js +86 -0
  87. package/tools/_deprecated/riddle.js +240 -0
  88. package/tools/_deprecated/run-bootstrap.js +69 -0
  89. package/tools/_deprecated/skills-analytics.js +349 -0
  90. package/tools/_deprecated/skills-bootstrap.js +301 -0
  91. package/tools/_deprecated/skills-dashboard.js +268 -0
  92. package/tools/_deprecated/skills.js +380 -0
  93. package/tools/_deprecated/smart-intro.js +353 -0
  94. package/tools/_deprecated/storybuilder.js +331 -0
  95. package/tools/_deprecated/telegram-bot.js +183 -0
  96. package/tools/_deprecated/telegram-setup.js +214 -0
  97. package/tools/_deprecated/twentyquestions.js +143 -0
  98. package/tools/_discovery-enhanced.js +290 -0
  99. package/tools/_discovery.js +439 -0
  100. package/tools/_proactive-discovery.js +301 -0
  101. package/tools/_shared/index.js +64 -0
  102. package/tools/_shared.js +234 -0
  103. package/tools/_work-context.js +338 -0
  104. package/tools/_work-context.manual-test.js +199 -0
  105. package/tools/_work-context.test.js +260 -0
  106. package/tools/activity.js +220 -0
  107. package/tools/admin-inbox.js +218 -0
  108. package/tools/agent-treasury.js +288 -0
  109. package/tools/analytics.js +191 -0
  110. package/tools/approve.js +197 -0
  111. package/tools/arcade.js +173 -0
  112. package/tools/artifact-create.js +17 -11
  113. package/tools/artifact-view.js +31 -1
  114. package/tools/artifacts-price.js +47 -43
  115. package/tools/ask-expert.js +160 -0
  116. package/tools/available.js +120 -0
  117. package/tools/become-expert.js +150 -0
  118. package/tools/broadcast.js +286 -0
  119. package/tools/chat.js +202 -0
  120. package/tools/collaborative-drawing.js +286 -0
  121. package/tools/connection-status.js +178 -0
  122. package/tools/crossword.js +17 -1
  123. package/tools/discover.js +350 -34
  124. package/tools/dm.js +115 -73
  125. package/tools/drawing.js +1 -1
  126. package/tools/earnings.js +126 -0
  127. package/tools/echo.js +16 -0
  128. package/tools/feed.js +51 -7
  129. package/tools/follow.js +224 -0
  130. package/tools/friends.js +207 -0
  131. package/tools/game.js +2 -2
  132. package/tools/genesis.js +233 -0
  133. package/tools/gig-browse.js +206 -0
  134. package/tools/gig-complete.js +144 -0
  135. package/tools/handoff.js +7 -1
  136. package/tools/help.js +4 -4
  137. package/tools/idea.js +9 -2
  138. package/tools/inbox.js +334 -28
  139. package/tools/init.js +727 -36
  140. package/tools/invite.js +15 -4
  141. package/tools/l2-bridge.js +272 -0
  142. package/tools/l2-status.js +217 -0
  143. package/tools/l2.js +206 -0
  144. package/tools/migrate.js +156 -0
  145. package/tools/mint.js +377 -0
  146. package/tools/multiplayer-game.js +1 -1
  147. package/tools/notifications.js +415 -0
  148. package/tools/observe.js +200 -0
  149. package/tools/onboarding.js +147 -0
  150. package/tools/open.js +143 -12
  151. package/tools/party-game.js +2 -2
  152. package/tools/plan.js +225 -0
  153. package/tools/presence-agent.js +7 -0
  154. package/tools/proof-of-work.js +100 -104
  155. package/tools/pulse.js +218 -0
  156. package/tools/reply.js +166 -0
  157. package/tools/report.js +2 -2
  158. package/tools/reputation.js +175 -0
  159. package/tools/request.js +17 -3
  160. package/tools/schedule.js +367 -0
  161. package/tools/search-messages.js +123 -0
  162. package/tools/session.js +420 -0
  163. package/tools/session_price.js +128 -0
  164. package/tools/settings.js +126 -3
  165. package/tools/ship.js +31 -8
  166. package/tools/shipback.js +326 -0
  167. package/tools/smart-check.js +201 -0
  168. package/tools/social-processor.js +445 -0
  169. package/tools/solo-game.js +1 -1
  170. package/tools/start.js +335 -93
  171. package/tools/status.js +53 -6
  172. package/tools/stuck.js +297 -0
  173. package/tools/subscribe.js +148 -0
  174. package/tools/subscriptions.js +134 -0
  175. package/tools/suggest-tags.js +6 -8
  176. package/tools/tag-suggestions.js +257 -0
  177. package/tools/tip.js +193 -0
  178. package/tools/token.js +103 -0
  179. package/tools/update.js +1 -1
  180. package/tools/wallet.js +239 -186
  181. package/tools/watch.js +157 -0
  182. package/tools/webhook-test.js +388 -0
  183. package/tools/who.js +54 -3
  184. package/tools/withdraw.js +145 -0
  185. package/tools/work-summary.js +96 -0
  186. package/tools/workshop.js +327 -0
  187. package/tools/x-mentions.js +1 -1
  188. package/version.json +14 -3
  189. package/tools/artifacts-buy.js +0 -111
  190. package/tools/connect.js +0 -284
  191. package/tools/gigs-apply.js +0 -99
  192. package/tools/gigs-browse.js +0 -114
  193. package/tools/gigs-complete.js +0 -128
  194. package/tools/gigs-post.js +0 -140
  195. package/tools/live-off.js +0 -109
  196. package/tools/live-watch.js +0 -176
  197. package/tools/live.js +0 -128
  198. package/tools/sessions-browse.js +0 -105
  199. package/tools/whats-happening.js +0 -125
  200. /package/tools/{away.js โ†’ _deprecated/away.js} +0 -0
  201. /package/tools/{back.js โ†’ _deprecated/back.js} +0 -0
  202. /package/tools/{mute.js โ†’ _deprecated/mute.js} +0 -0
  203. /package/tools/{skills-exchange.js โ†’ _deprecated/skills-exchange.js} +0 -0
  204. /package/tools/{tictactoe.js โ†’ _deprecated/tictactoe.js} +0 -0
  205. /package/tools/{wordassociation.js โ†’ _deprecated/wordassociation.js} +0 -0
@@ -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 };
@@ -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 };
@@ -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 };