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
package/tools/connect.js DELETED
@@ -1,284 +0,0 @@
1
- /**
2
- * vibe connect <platform>
3
- *
4
- * Connect external messaging platforms (Gmail, X, Farcaster, etc.)
5
- * Sets up OAuth and stores credentials securely
6
- */
7
-
8
- const config = require('../config');
9
- const router = require('../../lib/messaging/router');
10
- const credentials = require('../../lib/messaging/credentials');
11
-
12
- module.exports = {
13
- name: 'vibe_connect',
14
- description: 'Connect external messaging platforms (Gmail, X, Farcaster, WhatsApp, Telegram, Discord)',
15
-
16
- parameters: {
17
- type: 'object',
18
- properties: {
19
- platform: {
20
- type: 'string',
21
- enum: ['gmail', 'x', 'twitter', 'farcaster', 'telegram', 'discord', 'whatsapp'],
22
- description: 'Platform to connect'
23
- },
24
- action: {
25
- type: 'string',
26
- enum: ['connect', 'disconnect', 'status', 'list'],
27
- description: 'Action to perform (default: connect)'
28
- }
29
- }
30
- },
31
-
32
- handler: async (args) => {
33
- const handle = config.getHandle();
34
- if (!handle) {
35
- return {
36
- error: 'Not initialized',
37
- message: 'Run vibe init first'
38
- };
39
- }
40
-
41
- const { platform, action = 'connect' } = args;
42
-
43
- // List all platforms and their status
44
- if (action === 'list' || !platform) {
45
- // Check which platforms are configured by testing adapters
46
- const telegramBridge = require('../../mcp-server/bridges/telegram');
47
- const discordBridge = require('../../mcp-server/bridges/discord-bot');
48
- const farcasterBridge = require('../../mcp-server/bridges/farcaster');
49
- const twitterBridge = require('../../mcp-server/twitter');
50
- const smtpAdapter = router.getAdapter('gmail');
51
-
52
- const platforms = {
53
- gmail: smtpAdapter && smtpAdapter.isConfigured(),
54
- x: twitterBridge.getCredentials() !== null,
55
- farcaster: farcasterBridge.isConfigured(),
56
- telegram: telegramBridge.isConfigured(),
57
- discord: discordBridge.isConfigured(),
58
- whatsapp: false // Not yet implemented
59
- };
60
-
61
- const configured = Object.entries(platforms)
62
- .filter(([_, status]) => status)
63
- .map(([name, _]) => name);
64
-
65
- let display = `🔌 Platform Status\n\n`;
66
-
67
- // Configured platforms
68
- if (configured.length > 0) {
69
- display += `✓ Configured:\n`;
70
- for (const p of configured) {
71
- const emoji = {
72
- gmail: '📧',
73
- x: '🐦',
74
- farcaster: '🎭',
75
- telegram: '📱',
76
- discord: '🎮',
77
- whatsapp: '💬'
78
- }[p] || '●';
79
- display += ` ${emoji} ${p}\n`;
80
- }
81
- display += `\n`;
82
- }
83
-
84
- // Available platforms
85
- const available = Object.entries(platforms)
86
- .filter(([_, status]) => !status)
87
- .map(([name, _]) => name);
88
-
89
- if (available.length > 0) {
90
- display += `⚪ Available:\n`;
91
- for (const p of available) {
92
- const emoji = {
93
- gmail: '📧',
94
- x: '🐦',
95
- farcaster: '🎭',
96
- telegram: '📱',
97
- discord: '🎮',
98
- whatsapp: '💬'
99
- }[p] || '●';
100
- const desc = {
101
- gmail: 'Email anyone (OAuth or SMTP)',
102
- x: 'X/Twitter DMs and tweets',
103
- farcaster: 'Farcaster casts (via Neynar)',
104
- telegram: 'Telegram messages (bot API)',
105
- discord: 'Discord messages (bot API)',
106
- whatsapp: 'WhatsApp messages (coming soon)'
107
- }[p] || '';
108
- display += ` ${emoji} ${p} - ${desc}\n`;
109
- }
110
- }
111
-
112
- display += `\nConnect: vibe connect <platform>
113
- Test: vibe dm <recipient> "message"
114
- Status: vibe connect <platform> --action status
115
- `;
116
-
117
- return { display };
118
- }
119
-
120
- // Normalize platform name
121
- const normalizedPlatform = platform === 'twitter' ? 'x' : platform;
122
-
123
- // Disconnect platform
124
- if (action === 'disconnect') {
125
- await credentials.remove(handle, normalizedPlatform);
126
- return {
127
- success: true,
128
- display: `✓ Disconnected ${normalizedPlatform}
129
-
130
- Your credentials have been removed.
131
- Reconnect anytime: vibe connect ${normalizedPlatform}
132
- `
133
- };
134
- }
135
-
136
- // Check status
137
- if (action === 'status') {
138
- const hasAuth = await credentials.hasCredentials(handle, normalizedPlatform);
139
-
140
- if (!hasAuth) {
141
- return {
142
- display: `${normalizedPlatform} is not connected.
143
-
144
- Connect: vibe connect ${normalizedPlatform}
145
- `
146
- };
147
- }
148
-
149
- // Validate credentials still work
150
- const adapter = router.getAdapter(normalizedPlatform);
151
- const valid = await adapter.validateCredentials(handle);
152
-
153
- if (!valid) {
154
- return {
155
- display: `⚠️ ${normalizedPlatform} credentials expired
156
-
157
- Reconnect: vibe connect ${normalizedPlatform}
158
- `
159
- };
160
- }
161
-
162
- return {
163
- display: `✓ ${normalizedPlatform} is connected and active`
164
- };
165
- }
166
-
167
- // Connect platform (OAuth flow)
168
- if (action === 'connect') {
169
- try {
170
- const authUrl = await router.getAuthUrl(handle, normalizedPlatform);
171
-
172
- return {
173
- authRequired: true,
174
- platform: normalizedPlatform,
175
- authUrl,
176
- display: `🔐 Connect ${normalizedPlatform}
177
-
178
- 1. Open this URL in your browser:
179
- ${authUrl}
180
-
181
- 2. Authorize /vibe to send messages
182
-
183
- 3. You'll be redirected back
184
-
185
- Once connected, you can:
186
- vibe dm user@example.com "message" # Auto-detect Gmail
187
- vibe dm @user --platform ${normalizedPlatform} "message" # Explicit platform
188
-
189
- Need help? vibe help connect
190
- `
191
- };
192
- } catch (error) {
193
- // Check if platform is not configured (missing API keys)
194
- if (error.message.includes('not configured')) {
195
- return {
196
- error: 'Platform not configured',
197
- display: `⚠️ ${normalizedPlatform} integration not configured
198
-
199
- To enable ${normalizedPlatform}:
200
-
201
- 1. Get API credentials:
202
- ${getPlatformSetupInstructions(normalizedPlatform)}
203
-
204
- 2. Add to your environment:
205
- ${getPlatformEnvVars(normalizedPlatform)}
206
-
207
- 3. Restart /vibe: vibe reload
208
-
209
- Questions? https://slashvibe.dev/docs/messaging
210
- `
211
- };
212
- }
213
-
214
- return {
215
- error: error.message,
216
- display: `❌ Failed to connect ${normalizedPlatform}
217
-
218
- Error: ${error.message}
219
-
220
- Need help? vibe help connect
221
- `
222
- };
223
- }
224
- }
225
- }
226
- };
227
-
228
- /**
229
- * Get platform-specific setup instructions
230
- */
231
- function getPlatformSetupInstructions(platform) {
232
- const instructions = {
233
- gmail: ` - Go to: https://console.cloud.google.com
234
- - Create OAuth 2.0 credentials
235
- - Enable Gmail API`,
236
-
237
- x: ` - Go to: https://developer.twitter.com/en/portal/dashboard
238
- - Create app with OAuth 1.0a
239
- - Request elevated access for DMs`,
240
-
241
- farcaster: ` - Go to: https://neynar.com
242
- - Create account and get API key
243
- - Enable Hub API access`,
244
-
245
- whatsapp: ` - Go to: https://business.facebook.com/wa/manage/home
246
- - Create WhatsApp Business app
247
- - Get API access token`,
248
-
249
- telegram: ` - Message @BotFather on Telegram
250
- - Create new bot with /newbot
251
- - Get bot token`,
252
-
253
- discord: ` - Go to: https://discord.com/developers/applications
254
- - Create new application
255
- - Create bot and get token`
256
- };
257
-
258
- return instructions[platform] || 'See platform documentation';
259
- }
260
-
261
- /**
262
- * Get platform-specific environment variables
263
- */
264
- function getPlatformEnvVars(platform) {
265
- const envVars = {
266
- gmail: `GMAIL_CLIENT_ID=your_client_id
267
- GMAIL_CLIENT_SECRET=your_client_secret
268
- GMAIL_REDIRECT_URI=http://localhost:3000/api/oauth/gmail/callback`,
269
-
270
- x: `X_CONSUMER_KEY=your_key
271
- X_CONSUMER_SECRET=your_secret`,
272
-
273
- farcaster: `NEYNAR_API_KEY=your_api_key`,
274
-
275
- whatsapp: `WHATSAPP_TOKEN=your_token
276
- WHATSAPP_PHONE_NUMBER_ID=your_phone_id`,
277
-
278
- telegram: `TELEGRAM_BOT_TOKEN=your_bot_token`,
279
-
280
- discord: `DISCORD_BOT_TOKEN=your_bot_token`
281
- };
282
-
283
- return envVars[platform] || 'See documentation';
284
- }
@@ -1,99 +0,0 @@
1
- /**
2
- * vibe gigs-apply — Apply to help with a gig
3
- *
4
- * Express interest in a gig. Your message goes directly
5
- * to the person who posted it.
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_apply',
15
- description: 'Apply to help with a gig. Send a message to the poster explaining why you\'re a good fit.',
16
- inputSchema: {
17
- type: 'object',
18
- properties: {
19
- gig_id: {
20
- type: 'string',
21
- description: 'The gig ID to apply for'
22
- },
23
- message: {
24
- type: 'string',
25
- description: 'Your pitch - why you\'re a good fit for this gig'
26
- }
27
- },
28
- required: ['gig_id', 'message']
29
- }
30
- };
31
-
32
- async function handler(args) {
33
- const initCheck = requireInit();
34
- if (initCheck) return initCheck;
35
-
36
- const handle = config.getHandle();
37
- if (!handle) {
38
- return {
39
- display: `## Apply to Gig\n\n_You need to be logged in to apply._\n\nRun \`vibe init\` first.`
40
- };
41
- }
42
-
43
- const { gig_id, message } = args;
44
-
45
- if (!gig_id || !message) {
46
- return {
47
- display: `## Apply to Gig\n\n_Missing required fields._\n\n**Required:**\n- gig_id: The gig you want to apply for\n- message: Your pitch explaining why you're a good fit\n\n**Tip:** Browse gigs first with "browse gigs" to find one that matches your skills.`
48
- };
49
- }
50
-
51
- try {
52
- const response = await fetch(`${API_URL}/api/gigs/apply`, {
53
- method: 'POST',
54
- headers: {
55
- 'Content-Type': 'application/json'
56
- },
57
- body: JSON.stringify({
58
- gig_id,
59
- applicant: handle,
60
- message
61
- })
62
- });
63
-
64
- const data = await response.json();
65
-
66
- if (!data.success) {
67
- // Handle specific errors
68
- if (data.error?.includes('already applied')) {
69
- return {
70
- display: `## Apply to Gig\n\n_You've already applied to this gig._\n\nWait for the poster to respond, or browse other gigs.`
71
- };
72
- }
73
- if (data.error?.includes('not found')) {
74
- return {
75
- display: `## Apply to Gig\n\n_Gig not found._\n\nIt may have been filled or removed. Browse current gigs with "browse gigs".`
76
- };
77
- }
78
- return {
79
- display: `## Apply to Gig\n\n_Failed to apply: ${data.error || 'Unknown error'}_`
80
- };
81
- }
82
-
83
- let display = `## Application Sent! ✓\n\n`;
84
- display += `${data.message || 'Your application has been submitted.'}\n\n`;
85
- display += `**Your pitch:**\n_"${message}"_\n\n`;
86
- display += `---\n`;
87
- display += `The gig poster will review your application and can respond directly.\n`;
88
- display += `Check your inbox for their reply.`;
89
-
90
- return { display };
91
-
92
- } catch (e) {
93
- return {
94
- display: `## Apply to Gig\n\n_Error applying: ${e.message}_`
95
- };
96
- }
97
- }
98
-
99
- module.exports = { definition, handler };
@@ -1,114 +0,0 @@
1
- /**
2
- * vibe gigs-browse — Find paid work or get help
3
- *
4
- * Browse gigs posted by the community. Filter by your skills
5
- * to find work you can help with, or see what others need.
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_browse',
15
- description: 'Browse gigs from the community. Find paid work that matches your skills, or see what help others need. Categories: build, fix, design, review, teach, consult.',
16
- inputSchema: {
17
- type: 'object',
18
- properties: {
19
- category: {
20
- type: 'string',
21
- description: 'Filter by category: build, fix, design, review, teach, consult, or "all"'
22
- },
23
- skill: {
24
- type: 'string',
25
- description: 'Filter by skill needed (e.g., "react", "python", "rust")'
26
- }
27
- }
28
- }
29
- };
30
-
31
- async function handler(args) {
32
- const initCheck = requireInit();
33
- if (initCheck) return initCheck;
34
-
35
- const { category, skill } = args;
36
-
37
- try {
38
- let endpoint = '/api/gigs';
39
- const params = [];
40
-
41
- if (category && category !== 'all') {
42
- params.push(`category=${encodeURIComponent(category)}`);
43
- }
44
- if (skill) {
45
- params.push(`skill=${encodeURIComponent(skill)}`);
46
- }
47
-
48
- const url = params.length > 0
49
- ? `${API_URL}${endpoint}?${params.join('&')}`
50
- : `${API_URL}${endpoint}`;
51
-
52
- const response = await fetch(url);
53
- const data = await response.json();
54
-
55
- if (!data.success) {
56
- return {
57
- display: `## Gigs\n\n_Couldn't load gigs: ${data.error || 'Unknown error'}_`
58
- };
59
- }
60
-
61
- const gigs = data.gigs || [];
62
- const categories = data.categories || [];
63
-
64
- if (gigs.length === 0) {
65
- let display = `## Gigs\n\n_No open gigs`;
66
- if (category) display += ` in ${category}`;
67
- if (skill) display += ` needing ${skill}`;
68
- display += `._\n\n`;
69
- display += `**Post a gig** if you need help with something!\n`;
70
- display += `Categories: ${categories.join(', ')}`;
71
- return { display };
72
- }
73
-
74
- let display = `## Open Gigs\n\n`;
75
-
76
- gigs.forEach((g, i) => {
77
- const budget = g.budget
78
- ? `$${g.budget.min}-${g.budget.max}`
79
- : 'negotiable';
80
- const skills = (g.skills_needed || []).join(', ');
81
- const applicants = g.applicants || 0;
82
-
83
- display += `**${i + 1}. ${g.title}** [${g.category}]\n`;
84
- display += ` Posted by @${g.poster} • ${budget}\n`;
85
- if (skills) display += ` Skills: ${skills}\n`;
86
- if (g.description) {
87
- const shortDesc = g.description.length > 100
88
- ? g.description.slice(0, 100) + '...'
89
- : g.description;
90
- display += ` _"${shortDesc}"_\n`;
91
- }
92
- display += ` ${applicants} applicant${applicants !== 1 ? 's' : ''}\n\n`;
93
- });
94
-
95
- display += `---\n`;
96
- display += `**Apply**: Say "apply to gig [number]" or message the poster directly\n`;
97
- display += `**Post a gig**: Say "post a gig" to get help with your project`;
98
-
99
- // Include gig IDs for apply action
100
- const gigIds = gigs.map(g => g.id);
101
-
102
- return {
103
- display,
104
- data: { gigs: gigIds }
105
- };
106
-
107
- } catch (e) {
108
- return {
109
- display: `## Gigs\n\n_Error loading gigs: ${e.message}_`
110
- };
111
- }
112
- }
113
-
114
- module.exports = { definition, handler };
@@ -1,128 +0,0 @@
1
- /**
2
- * vibe gigs-complete — Mark a gig as done
3
- *
4
- * Completes a gig you were hired for. Links deliverables (session, artifacts)
5
- * and boosts your reputation. Part of the proof-of-work system.
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_complete',
15
- description: 'Complete a gig you were hired for. Links deliverables (session, artifacts), records poster rating, and boosts your reputation. Search triggers: "complete gig", "finish gig", "gig done", "delivered".',
16
- inputSchema: {
17
- type: 'object',
18
- properties: {
19
- gig_id: {
20
- type: 'string',
21
- description: 'The gig ID to complete (e.g., "gig_xxx")'
22
- },
23
- session_id: {
24
- type: 'string',
25
- description: 'Optional: Link to session where work was done'
26
- },
27
- artifacts: {
28
- type: 'array',
29
- items: { type: 'string' },
30
- description: 'Optional: Array of artifact IDs produced for this gig'
31
- },
32
- notes: {
33
- type: 'string',
34
- description: 'Optional: Notes about what was delivered'
35
- }
36
- },
37
- required: ['gig_id']
38
- }
39
- };
40
-
41
- async function handler(args) {
42
- const initCheck = requireInit();
43
- if (initCheck) return initCheck;
44
-
45
- const { gig_id, session_id, artifacts = [], notes } = args;
46
- const handle = config.getHandle();
47
-
48
- if (!gig_id) {
49
- return {
50
- display: '❌ Missing gig_id. Provide the ID of the gig you completed.'
51
- };
52
- }
53
-
54
- try {
55
- // First, verify the gig and that we're the hired person
56
- const gigResponse = await fetch(`${API_URL}/api/gigs?id=${encodeURIComponent(gig_id)}`);
57
- const gigData = await gigResponse.json();
58
-
59
- if (!gigData.success || !gigData.gig) {
60
- return {
61
- display: `❌ Gig not found: ${gig_id}`
62
- };
63
- }
64
-
65
- const gig = gigData.gig;
66
-
67
- if (gig.hired !== handle) {
68
- return {
69
- display: `❌ You weren't hired for this gig. Only @${gig.hired} can complete it.`
70
- };
71
- }
72
-
73
- if (gig.status === 'completed') {
74
- return {
75
- display: `✅ This gig is already completed.`
76
- };
77
- }
78
-
79
- // Complete the gig
80
- const response = await fetch(`${API_URL}/api/gigs/complete`, {
81
- method: 'POST',
82
- headers: { 'Content-Type': 'application/json' },
83
- body: JSON.stringify({
84
- gig_id,
85
- poster: gig.poster,
86
- session_id,
87
- artifacts,
88
- notes
89
- })
90
- });
91
-
92
- const data = await response.json();
93
-
94
- if (!data.success) {
95
- return {
96
- display: `❌ Failed to complete gig: ${data.error || 'Unknown error'}`
97
- };
98
- }
99
-
100
- let display = `## ✅ Gig Completed!\n\n`;
101
- display += `**${gig.title}**\n`;
102
- display += `Posted by @${gig.poster}\n\n`;
103
-
104
- if (session_id) {
105
- display += `📹 Linked session: ${session_id}\n`;
106
- }
107
- if (artifacts.length > 0) {
108
- display += `📦 Linked ${artifacts.length} artifact${artifacts.length > 1 ? 's' : ''}\n`;
109
- }
110
- if (notes) {
111
- display += `📝 Notes: ${notes}\n`;
112
- }
113
-
114
- display += `\n---\n`;
115
- display += `**Reputation boost applied!**\n`;
116
- display += `Your proven skills and gig completion count have been updated.\n`;
117
- display += `Check your proof-of-work with "show my proof of work"`;
118
-
119
- return { display };
120
-
121
- } catch (e) {
122
- return {
123
- display: `❌ Error completing gig: ${e.message}`
124
- };
125
- }
126
- }
127
-
128
- module.exports = { definition, handler };