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.
Files changed (235) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +280 -47
  3. package/auto-update.js +10 -15
  4. package/config.js +36 -31
  5. package/crypto.js +1 -6
  6. package/debug.js +12 -0
  7. package/discord.js +19 -19
  8. package/eslint.config.js +54 -0
  9. package/index.js +217 -207
  10. package/intelligence/index.js +2 -9
  11. package/intelligence/infer.js +10 -16
  12. package/intelligence/patterns.js +23 -18
  13. package/intelligence/proactive.js +16 -15
  14. package/intelligence/serendipity.js +57 -20
  15. package/memory.js +13 -8
  16. package/migrate-v2.js +72 -0
  17. package/notification-emitter.js +2 -2
  18. package/notify.js +39 -14
  19. package/package.json +28 -29
  20. package/post-install.js +141 -0
  21. package/presence.js +2 -2
  22. package/prompts.js +5 -9
  23. package/protocol/index.js +123 -87
  24. package/protocol/telegram-commands.js +36 -37
  25. package/store/api.js +358 -529
  26. package/store/local.js +9 -10
  27. package/store/profiles.js +48 -192
  28. package/store/reservations.js +2 -9
  29. package/store/skills.js +69 -71
  30. package/store/sqlite.js +355 -0
  31. package/test-skills-bootstrap.js +20 -0
  32. package/test-v2-integration.js +385 -0
  33. package/tools/_actions.js +48 -387
  34. package/tools/_connection-queue.js +45 -56
  35. package/tools/_discovery-enhanced.js +52 -57
  36. package/tools/_discovery.js +87 -185
  37. package/tools/{l2-status.js → _experimental/l2-status.js} +68 -70
  38. package/tools/{shipback.js → _experimental/shipback.js} +4 -3
  39. package/tools/_proactive-discovery.js +60 -73
  40. package/tools/_shared/index.js +41 -64
  41. package/tools/admin-inbox.js +10 -15
  42. package/tools/agents.js +1 -1
  43. package/tools/artifact-create.js +13 -23
  44. package/tools/artifact-view.js +4 -4
  45. package/tools/{_deprecated/back.js → back.js} +1 -1
  46. package/tools/bye.js +3 -5
  47. package/tools/consent.js +2 -2
  48. package/tools/context.js +9 -10
  49. package/tools/crossword.js +3 -2
  50. package/tools/discover.js +94 -356
  51. package/tools/dm.js +27 -86
  52. package/tools/doctor.js +12 -41
  53. package/tools/drawing.js +34 -20
  54. package/tools/echo.js +11 -11
  55. package/tools/feed.js +30 -58
  56. package/tools/follow.js +64 -187
  57. package/tools/{_deprecated/forget.js → forget.js} +4 -7
  58. package/tools/game.js +144 -48
  59. package/tools/handoff.js +6 -8
  60. package/tools/help.js +3 -3
  61. package/tools/idea.js +15 -27
  62. package/tools/inbox.js +121 -293
  63. package/tools/init.js +54 -151
  64. package/tools/invite.js +8 -21
  65. package/tools/migrate.js +27 -24
  66. package/tools/multiplayer-game.js +50 -40
  67. package/tools/{_deprecated/mute.js → mute.js} +4 -3
  68. package/tools/notifications.js +58 -48
  69. package/tools/observe.js +12 -15
  70. package/tools/onboarding.js +8 -11
  71. package/tools/open.js +13 -144
  72. package/tools/party-game.js +23 -12
  73. package/tools/patterns.js +2 -1
  74. package/tools/ping.js +5 -7
  75. package/tools/react.js +28 -30
  76. package/tools/{_deprecated/recall.js → recall.js} +5 -10
  77. package/tools/release.js +4 -2
  78. package/tools/{_deprecated/remember.js → remember.js} +4 -6
  79. package/tools/report.js +2 -2
  80. package/tools/request.js +6 -26
  81. package/tools/reserve.js +1 -1
  82. package/tools/session-fork.js +97 -0
  83. package/tools/session-save.js +109 -0
  84. package/tools/settings.js +30 -99
  85. package/tools/ship.js +74 -56
  86. package/tools/{_deprecated/skills-exchange.js → skills-exchange.js} +38 -39
  87. package/tools/social-inbox.js +22 -28
  88. package/tools/social-post.js +24 -27
  89. package/tools/solo-game.js +54 -46
  90. package/tools/start.js +14 -148
  91. package/tools/status.js +21 -68
  92. package/tools/submit.js +4 -2
  93. package/tools/suggest-tags.js +36 -33
  94. package/tools/summarize.js +19 -16
  95. package/tools/tag-suggestions.js +72 -73
  96. package/tools/test.js +1 -1
  97. package/tools/{_deprecated/tictactoe.js → tictactoe.js} +26 -26
  98. package/tools/token.js +4 -4
  99. package/tools/update.js +1 -2
  100. package/tools/watch.js +132 -112
  101. package/tools/who.js +20 -40
  102. package/tools/{_deprecated/wordassociation.js → wordassociation.js} +23 -20
  103. package/tools/workshop-buddy.js +52 -53
  104. package/tools/x-mentions.js +0 -1
  105. package/tools/x-reply.js +0 -1
  106. package/twitter.js +14 -20
  107. package/version.json +8 -10
  108. package/webhook-runner.js +132 -0
  109. package/auth-store.js +0 -148
  110. package/bridges/bridge-monitor.js +0 -388
  111. package/bridges/discord-bot.js +0 -431
  112. package/bridges/farcaster.js +0 -299
  113. package/bridges/telegram.js +0 -261
  114. package/bridges/webhook-health.js +0 -420
  115. package/bridges/webhook-server.js +0 -437
  116. package/bridges/whatsapp.js +0 -441
  117. package/bridges/x-webhook.js +0 -423
  118. package/games/arcade.js +0 -406
  119. package/games/chess.js +0 -451
  120. package/games/colorguess.js +0 -343
  121. package/games/crossword-words.js +0 -171
  122. package/games/crossword.js +0 -461
  123. package/games/drawing.js +0 -347
  124. package/games/gameroulette.js +0 -300
  125. package/games/gamerouter.js +0 -336
  126. package/games/gamestatus.js +0 -337
  127. package/games/guessnumber.js +0 -209
  128. package/games/hangman.js +0 -279
  129. package/games/memory.js +0 -338
  130. package/games/multiplayer-tictactoe.js +0 -389
  131. package/games/pixelart.js +0 -399
  132. package/games/quickduel.js +0 -354
  133. package/games/riddle.js +0 -371
  134. package/games/rockpaperscissors.js +0 -291
  135. package/games/snake.js +0 -406
  136. package/games/storybuilder.js +0 -343
  137. package/games/tictactoe.js +0 -345
  138. package/games/twentyquestions.js +0 -286
  139. package/games/twotruths.js +0 -207
  140. package/games/werewolf.js +0 -508
  141. package/games/wordassociation.js +0 -247
  142. package/games/wordchain.js +0 -135
  143. package/intelligence/interests.js +0 -369
  144. package/setup.js +0 -480
  145. package/smart-inbox.js +0 -276
  146. package/tools/_deprecated/auto-suggest-connections.js +0 -304
  147. package/tools/_deprecated/bootstrap-skills.js +0 -231
  148. package/tools/_deprecated/bridge-dashboard.js +0 -342
  149. package/tools/_deprecated/bridge-health.js +0 -400
  150. package/tools/_deprecated/bridge-live.js +0 -384
  151. package/tools/_deprecated/bridges.js +0 -383
  152. package/tools/_deprecated/colorguess.js +0 -281
  153. package/tools/_deprecated/discover-insights.js +0 -379
  154. package/tools/_deprecated/discover-momentum.js +0 -256
  155. package/tools/_deprecated/discovery-analytics.js +0 -345
  156. package/tools/_deprecated/discovery-auto-suggest.js +0 -275
  157. package/tools/_deprecated/discovery-bootstrap.js +0 -267
  158. package/tools/_deprecated/discovery-daily.js +0 -375
  159. package/tools/_deprecated/discovery-dashboard.js +0 -385
  160. package/tools/_deprecated/discovery-digest.js +0 -314
  161. package/tools/_deprecated/discovery-hub.js +0 -357
  162. package/tools/_deprecated/discovery-insights.js +0 -384
  163. package/tools/_deprecated/discovery-momentum.js +0 -281
  164. package/tools/_deprecated/discovery-monitor.js +0 -319
  165. package/tools/_deprecated/discovery-proactive.js +0 -300
  166. package/tools/_deprecated/draw.js +0 -317
  167. package/tools/_deprecated/farcaster.js +0 -307
  168. package/tools/_deprecated/games-catalog.js +0 -376
  169. package/tools/_deprecated/games.js +0 -313
  170. package/tools/_deprecated/guessnumber.js +0 -194
  171. package/tools/_deprecated/hangman.js +0 -129
  172. package/tools/_deprecated/multiplayer-tictactoe.js +0 -303
  173. package/tools/_deprecated/riddle.js +0 -240
  174. package/tools/_deprecated/run-bootstrap.js +0 -69
  175. package/tools/_deprecated/skills-analytics.js +0 -349
  176. package/tools/_deprecated/skills-bootstrap.js +0 -301
  177. package/tools/_deprecated/skills-dashboard.js +0 -268
  178. package/tools/_deprecated/skills.js +0 -380
  179. package/tools/_deprecated/smart-intro.js +0 -353
  180. package/tools/_deprecated/storybuilder.js +0 -331
  181. package/tools/_deprecated/telegram-bot.js +0 -183
  182. package/tools/_deprecated/telegram-setup.js +0 -214
  183. package/tools/_deprecated/twentyquestions.js +0 -143
  184. package/tools/_shared.js +0 -234
  185. package/tools/_work-context.js +0 -338
  186. package/tools/_work-context.manual-test.js +0 -199
  187. package/tools/_work-context.test.js +0 -260
  188. package/tools/activity.js +0 -220
  189. package/tools/agent-treasury.js +0 -288
  190. package/tools/analytics.js +0 -191
  191. package/tools/approve.js +0 -197
  192. package/tools/arcade.js +0 -173
  193. package/tools/artifacts-price.js +0 -107
  194. package/tools/ask-expert.js +0 -160
  195. package/tools/available.js +0 -120
  196. package/tools/become-expert.js +0 -150
  197. package/tools/broadcast.js +0 -325
  198. package/tools/chat.js +0 -202
  199. package/tools/collaborative-drawing.js +0 -286
  200. package/tools/connection-status.js +0 -178
  201. package/tools/earnings.js +0 -126
  202. package/tools/friends.js +0 -207
  203. package/tools/genesis.js +0 -233
  204. package/tools/gig-browse.js +0 -206
  205. package/tools/gig-complete.js +0 -144
  206. package/tools/health.js +0 -87
  207. package/tools/leaderboard.js +0 -117
  208. package/tools/lib/git-apply.js +0 -206
  209. package/tools/lib/git-bundle.js +0 -407
  210. package/tools/mint.js +0 -377
  211. package/tools/plan.js +0 -225
  212. package/tools/profile.js +0 -219
  213. package/tools/proof-of-work.js +0 -144
  214. package/tools/pulse.js +0 -218
  215. package/tools/reply.js +0 -166
  216. package/tools/reputation.js +0 -175
  217. package/tools/schedule.js +0 -367
  218. package/tools/search-messages.js +0 -123
  219. package/tools/session.js +0 -467
  220. package/tools/session_price.js +0 -128
  221. package/tools/smart-check.js +0 -201
  222. package/tools/social-processor.js +0 -445
  223. package/tools/streak.js +0 -147
  224. package/tools/stuck.js +0 -297
  225. package/tools/subscribe.js +0 -148
  226. package/tools/subscriptions.js +0 -134
  227. package/tools/tip.js +0 -193
  228. package/tools/wallet.js +0 -269
  229. package/tools/webhook-test.js +0 -388
  230. package/tools/withdraw.js +0 -145
  231. package/tools/work-summary.js +0 -96
  232. package/tools/workshop.js +0 -327
  233. /package/tools/{l2-bridge.js → _experimental/l2-bridge.js} +0 -0
  234. /package/tools/{l2.js → _experimental/l2.js} +0 -0
  235. /package/tools/{_deprecated/away.js → away.js} +0 -0
@@ -1,301 +0,0 @@
1
- /**
2
- * Skills Bootstrap — Seed the Skills Exchange with sample data
3
- *
4
- * Since the Skills Exchange marketplace is built but empty, this tool:
5
- * 1. Creates realistic seed skill offers/requests
6
- * 2. Demonstrates the full feature set
7
- * 3. Makes the marketplace feel active for new users
8
- */
9
-
10
- const store = require('../store');
11
-
12
- const definition = {
13
- name: 'vibe_skills_bootstrap',
14
- description: 'Bootstrap the Skills Exchange marketplace with seed data',
15
- inputSchema: {
16
- type: 'object',
17
- properties: {
18
- action: {
19
- type: 'string',
20
- enum: ['seed', 'status', 'clear'],
21
- description: 'Bootstrap action to perform'
22
- }
23
- }
24
- }
25
- };
26
-
27
- // Seed skill exchanges that represent a healthy marketplace
28
- const seedSkillExchanges = [
29
- // Tech Skills Offers
30
- {
31
- handle: 'alex-dev',
32
- type: 'offer',
33
- skill: 'React Development',
34
- details: 'Frontend focused, 3+ years experience. Happy to review code or pair program.',
35
- category: 'technical',
36
- timestamp: Date.now() - (2 * 24 * 60 * 60 * 1000), // 2 days ago
37
- status: 'active'
38
- },
39
- {
40
- handle: 'sarah-ai',
41
- type: 'offer',
42
- skill: 'Python & Machine Learning',
43
- details: 'ML engineer, can help with data analysis, model training, and deployment.',
44
- category: 'technical',
45
- timestamp: Date.now() - (1 * 24 * 60 * 60 * 1000), // 1 day ago
46
- status: 'active'
47
- },
48
- {
49
- handle: 'mike-backend',
50
- type: 'offer',
51
- skill: 'Node.js & API Design',
52
- details: 'Building scalable backends for 5+ years. Database design and authentication.',
53
- category: 'technical',
54
- timestamp: Date.now() - (3 * 24 * 60 * 60 * 1000), // 3 days ago
55
- status: 'active'
56
- },
57
-
58
- // Design Skills Offers
59
- {
60
- handle: 'emma-design',
61
- type: 'offer',
62
- skill: 'UI/UX Design',
63
- details: 'Product designer at YC startup. Can help with user research and prototyping.',
64
- category: 'design',
65
- timestamp: Date.now() - (4 * 60 * 60 * 1000), // 4 hours ago
66
- status: 'active'
67
- },
68
- {
69
- handle: 'david-brand',
70
- type: 'offer',
71
- skill: 'Brand Strategy & Visual Identity',
72
- details: 'Helped 10+ startups with branding. Logo design and brand guidelines.',
73
- category: 'design',
74
- timestamp: Date.now() - (6 * 60 * 60 * 1000), // 6 hours ago
75
- status: 'active'
76
- },
77
-
78
- // Business Skills Offers
79
- {
80
- handle: 'lisa-product',
81
- type: 'offer',
82
- skill: 'Product Strategy',
83
- details: 'Ex-Google PM. Product roadmaps, user research, and go-to-market strategy.',
84
- category: 'business',
85
- timestamp: Date.now() - (12 * 60 * 60 * 1000), // 12 hours ago
86
- status: 'active'
87
- },
88
- {
89
- handle: 'jason-growth',
90
- type: 'offer',
91
- skill: 'Growth Marketing',
92
- details: 'Scaled 3 startups to $1M ARR. SEO, content marketing, and paid acquisition.',
93
- category: 'business',
94
- timestamp: Date.now() - (8 * 60 * 60 * 1000), // 8 hours ago
95
- status: 'active'
96
- },
97
-
98
- // Skill Requests - People seeking help
99
- {
100
- handle: 'startup-founder',
101
- type: 'request',
102
- skill: 'Fundraising Advice',
103
- details: 'First-time founder building B2B SaaS. Need help with pitch deck and investor intros.',
104
- category: 'business',
105
- timestamp: Date.now() - (2 * 60 * 60 * 1000), // 2 hours ago
106
- status: 'active'
107
- },
108
- {
109
- handle: 'new-developer',
110
- type: 'request',
111
- skill: 'Code Review & Best Practices',
112
- details: 'Junior developer building my first production app. Need experienced eyes on my code.',
113
- category: 'technical',
114
- timestamp: Date.now() - (1 * 60 * 60 * 1000), // 1 hour ago
115
- status: 'active'
116
- },
117
- {
118
- handle: 'creative-writer',
119
- type: 'request',
120
- skill: 'Web Development',
121
- details: 'Writer launching a newsletter platform. Need help setting up basic website and signup.',
122
- category: 'technical',
123
- timestamp: Date.now() - (30 * 60 * 1000), // 30 minutes ago
124
- status: 'active'
125
- },
126
- {
127
- handle: 'small-business',
128
- type: 'request',
129
- skill: 'Logo Design',
130
- details: 'Local service business needs a professional logo. Budget-friendly options preferred.',
131
- category: 'design',
132
- timestamp: Date.now() - (45 * 60 * 1000), // 45 minutes ago
133
- status: 'active'
134
- },
135
- {
136
- handle: 'tech-lead',
137
- type: 'request',
138
- skill: 'Team Leadership & Culture',
139
- details: 'New tech lead at 15-person startup. Need advice on building engineering culture.',
140
- category: 'soft-skills',
141
- timestamp: Date.now() - (90 * 60 * 1000), // 1.5 hours ago
142
- status: 'active'
143
- }
144
- ];
145
-
146
- async function seedSkillsMarketplace() {
147
- let seeded = 0;
148
-
149
- for (const skillPost of seedSkillExchanges) {
150
- const postWithId = {
151
- id: Date.now() + Math.random(),
152
- ...skillPost
153
- };
154
-
155
- await store.appendSkillExchange(postWithId);
156
- seeded++;
157
- }
158
-
159
- return seeded;
160
- }
161
-
162
- async function getSkillsStatus() {
163
- try {
164
- const allSkills = await store.getSkillExchanges() || [];
165
- const offers = allSkills.filter(s => s.type === 'offer');
166
- const requests = allSkills.filter(s => s.type === 'request');
167
-
168
- const categories = {};
169
- allSkills.forEach(skill => {
170
- if (!categories[skill.category]) {
171
- categories[skill.category] = { offers: 0, requests: 0 };
172
- }
173
- categories[skill.category][skill.type + 's']++;
174
- });
175
-
176
- return {
177
- total: allSkills.length,
178
- offers: offers.length,
179
- requests: requests.length,
180
- categories
181
- };
182
- } catch (error) {
183
- return { total: 0, offers: 0, requests: 0, categories: {} };
184
- }
185
- }
186
-
187
- async function clearSkillsMarketplace() {
188
- // This would require a store method to clear all skill exchanges
189
- // For now, just return info about what would be cleared
190
- const status = await getSkillsStatus();
191
- return status;
192
- }
193
-
194
- async function handler(args) {
195
- const action = args.action || 'status';
196
- let display = '';
197
-
198
- try {
199
- switch (action) {
200
- case 'seed': {
201
- const currentStatus = await getSkillsStatus();
202
-
203
- if (currentStatus.total > 0) {
204
- display = `## Skills Exchange Already Has Data 📊\n\n`;
205
- display += `**Current marketplace:**\n`;
206
- display += `• ${currentStatus.total} total posts\n`;
207
- display += `• ${currentStatus.offers} skill offers\n`;
208
- display += `• ${currentStatus.requests} skill requests\n\n`;
209
-
210
- if (Object.keys(currentStatus.categories).length > 0) {
211
- display += `**By category:**\n`;
212
- for (const [category, counts] of Object.entries(currentStatus.categories)) {
213
- display += `• ${category}: ${counts.offers} offers, ${counts.requests} requests\n`;
214
- }
215
- }
216
-
217
- display += `\n**Marketplace is active! 🎉**\n`;
218
- display += `Check it out: \`skills-exchange browse\``;
219
- } else {
220
- const seeded = await seedSkillsMarketplace();
221
- display = `## Skills Exchange Bootstrapped! 🚀\n\n`;
222
- display += `**Added ${seeded} seed skill posts:**\n`;
223
- display += `• ${seedSkillExchanges.filter(s => s.type === 'offer').length} skill offers\n`;
224
- display += `• ${seedSkillExchanges.filter(s => s.type === 'request').length} skill requests\n`;
225
- display += `• Spanning ${new Set(seedSkillExchanges.map(s => s.category)).size} categories\n\n`;
226
-
227
- display += `**Sample skills now available:**\n`;
228
- display += `• React Development • Python & ML • UI/UX Design\n`;
229
- display += `• Product Strategy • Growth Marketing • Brand Strategy\n\n`;
230
-
231
- display += `**Try the marketplace:**\n`;
232
- display += `\`skills-exchange browse\` — See all available skills\n`;
233
- display += `\`skills-exchange match\` — Find skills perfect for you\n`;
234
- display += `\`skills-exchange post --type offer --skill "your expertise"\` — Add your skills`;
235
- }
236
- break;
237
- }
238
-
239
- case 'status': {
240
- const status = await getSkillsStatus();
241
- display = `## Skills Exchange Status 📈\n\n`;
242
-
243
- if (status.total === 0) {
244
- display += `**Marketplace is empty** 📭\n\n`;
245
- display += `Bootstrap with seed data:\n`;
246
- display += `\`skills-bootstrap --action seed\`\n\n`;
247
- display += `Or add your own skills:\n`;
248
- display += `\`skills-exchange post --type offer --skill "your expertise"\``;
249
- } else {
250
- display += `**Active marketplace** 🏪\n`;
251
- display += `• **${status.total} total posts**\n`;
252
- display += `• ${status.offers} skill offers available\n`;
253
- display += `• ${status.requests} people seeking help\n\n`;
254
-
255
- if (Object.keys(status.categories).length > 0) {
256
- display += `**Skills by category:**\n`;
257
- for (const [category, counts] of Object.entries(status.categories)) {
258
- display += `• **${category}:** ${counts.offers} offers, ${counts.requests} requests\n`;
259
- }
260
- display += `\n`;
261
- }
262
-
263
- display += `**Browse the marketplace:**\n`;
264
- display += `\`skills-exchange browse\` — See all skills\n`;
265
- display += `\`skills-exchange match\` — Find perfect matches for you`;
266
- }
267
- break;
268
- }
269
-
270
- case 'clear': {
271
- const status = await getSkillsStatus();
272
- display = `## Clear Skills Exchange 🧹\n\n`;
273
- display += `**Would clear:**\n`;
274
- display += `• ${status.total} skill posts\n`;
275
- display += `• ${status.offers} offers\n`;
276
- display += `• ${status.requests} requests\n\n`;
277
- display += `_Note: Clear functionality not implemented for safety._\n`;
278
- display += `_Skills naturally expire after inactivity._`;
279
- break;
280
- }
281
-
282
- default:
283
- display = `## Skills Bootstrap Commands\n\n`;
284
- display += `**\`skills-bootstrap --action seed\`** — Add sample skills to marketplace\n`;
285
- display += `**\`skills-bootstrap --action status\`** — Check marketplace health\n`;
286
- display += `**\`skills-bootstrap --action clear\`** — View clear options\n\n`;
287
- display += `**Perfect for:**\n`;
288
- display += `• Bootstrapping an empty marketplace\n`;
289
- display += `• Demonstrating skills exchange features\n`;
290
- display += `• Making the community feel active\n\n`;
291
- display += `**Then try:**\n`;
292
- display += `\`skills-exchange browse\` — Explore the marketplace`;
293
- }
294
- } catch (error) {
295
- display = `## Bootstrap Error\n\n${error.message}\n\nTry: \`skills-bootstrap\` for help`;
296
- }
297
-
298
- return { display };
299
- }
300
-
301
- module.exports = { definition, handler };
@@ -1,268 +0,0 @@
1
- /**
2
- * vibe skills-dashboard — Skills Exchange Dashboard
3
- *
4
- * A comprehensive dashboard view of the Skills Exchange marketplace:
5
- * - Live marketplace overview with stats
6
- * - Featured skill matches and opportunities
7
- * - Recent activity and trending skills
8
- * - Quick actions for posting and browsing
9
- * - Success stories and exchange highlights
10
- */
11
-
12
- const config = require('../config');
13
- const skillsStore = require('../store/skills');
14
- const userProfiles = require('../store/profiles');
15
- const { formatTimeAgo, requireInit } = require('./_shared');
16
-
17
- const definition = {
18
- name: 'vibe_skills_dashboard',
19
- description: 'Comprehensive dashboard view of the Skills Exchange marketplace.',
20
- inputSchema: {
21
- type: 'object',
22
- properties: {
23
- view: {
24
- type: 'string',
25
- enum: ['overview', 'matches', 'trending', 'recent'],
26
- description: 'Dashboard view to display'
27
- }
28
- }
29
- }
30
- };
31
-
32
- async function handler(args) {
33
- const initCheck = requireInit();
34
- if (initCheck) return initCheck;
35
-
36
- const myHandle = config.getHandle();
37
- const view = args.view || 'overview';
38
-
39
- let display = '';
40
-
41
- try {
42
- switch (view) {
43
- case 'overview': {
44
- const stats = await skillsStore.getExchangeStats();
45
- const categories = await skillsStore.getSkillsByCategory();
46
- const myMatches = await skillsStore.findSkillMatches(myHandle);
47
-
48
- display = `## 🏪 Skills Exchange Marketplace Dashboard\n\n`;
49
-
50
- // Quick stats
51
- display += `### 📊 Marketplace Stats\n`;
52
- display += `• **${stats.activeOffers}** skills offered by workshop members\n`;
53
- display += `• **${stats.activeRequests}** skills requested\n`;
54
- display += `• **${stats.totalExchanges}** successful connections made\n`;
55
- display += `• **${Object.keys(categories).length}** active categories\n\n`;
56
-
57
- // Personal matches preview
58
- if (myMatches.forMyRequests.length > 0 || myMatches.forMyOffers.length > 0) {
59
- display += `### 🎯 Your Opportunities\n`;
60
- if (myMatches.forMyRequests.length > 0) {
61
- display += `• **${myMatches.forMyRequests.length}** people can help you\n`;
62
- }
63
- if (myMatches.forMyOffers.length > 0) {
64
- display += `• **${myMatches.forMyOffers.length}** people you can help\n`;
65
- }
66
- display += `👉 \`skills matches\` for detailed matches\n\n`;
67
- } else {
68
- display += `### 🚀 Get Started\n`;
69
- display += `• \`skills offer "your-expertise"\` to share your skills\n`;
70
- display += `• \`skills request "skill-you-need"\` to find help\n`;
71
- display += `• \`skills browse\` to explore opportunities\n\n`;
72
- }
73
-
74
- // Hot categories
75
- const topCategories = Object.entries(categories)
76
- .sort(([,a], [,b]) => (b.offers.length + b.requests.length) - (a.offers.length + a.requests.length))
77
- .slice(0, 4);
78
-
79
- if (topCategories.length > 0) {
80
- display += `### 🔥 Most Active Categories\n`;
81
- for (const [category, items] of topCategories) {
82
- const total = items.offers.length + items.requests.length;
83
- display += `• **${category}**: ${items.offers.length} offers, ${items.requests.length} requests\n`;
84
- }
85
- display += `\n`;
86
- }
87
-
88
- // Top skills
89
- if (stats.topSkills.length > 0) {
90
- display += `### 📈 Trending Skills\n`;
91
- display += stats.topSkills.slice(0, 6)
92
- .map(s => `• ${s.skill} (${s.count})`)
93
- .join('\n');
94
- display += `\n\n`;
95
- }
96
-
97
- // Quick actions
98
- display += `### ⚡ Quick Actions\n`;
99
- display += `• \`skills matches\` — Find your perfect matches\n`;
100
- display += `• \`skills browse\` — Explore all categories\n`;
101
- display += `• \`skills-dashboard trending\` — See what's hot\n`;
102
- display += `• \`skills-dashboard recent\` — Latest activity\n`;
103
-
104
- break;
105
- }
106
-
107
- case 'matches': {
108
- const matches = await skillsStore.findSkillMatches(myHandle);
109
-
110
- display = `## 🎯 Your Skill Exchange Matches\n\n`;
111
-
112
- if (matches.forMyRequests.length === 0 && matches.forMyOffers.length === 0) {
113
- display += `_No active matches found._\n\n`;
114
- display += `**Improve your matches:**\n`;
115
- display += `• \`skills offer "your-expertise"\` to help others\n`;
116
- display += `• \`skills request "needed-skill"\` to find help\n`;
117
- display += `• \`profile tags "your,skills,here"\` to improve matching\n`;
118
- display += `• \`skills browse\` to see all opportunities\n`;
119
- } else {
120
- // High-priority matches first
121
- const highPriorityOffers = matches.forMyOffers
122
- .filter(m => m.theirItem.urgency === 'high')
123
- .slice(0, 3);
124
-
125
- if (highPriorityOffers.length > 0) {
126
- display += `### 🚨 Urgent Help Needed\n`;
127
- for (const match of highPriorityOffers) {
128
- display += `**@${match.theirItem.handle}** urgently needs **${match.theirItem.skill}**\n`;
129
- if (match.theirItem.context) {
130
- display += `_${match.theirItem.context}_\n`;
131
- }
132
- display += `💬 \`dm @${match.theirItem.handle} "I can help with ${match.theirItem.skill}!"\`\n\n`;
133
- }
134
- }
135
-
136
- // Best matches for user's requests
137
- if (matches.forMyRequests.length > 0) {
138
- display += `### 👥 People Who Can Help You\n`;
139
- for (const match of matches.forMyRequests.slice(0, 3)) {
140
- display += `**@${match.theirItem.handle}** offers **${match.theirItem.skill}** _(${match.theirItem.level})_\n`;
141
- if (match.theirItem.description) {
142
- display += `${match.theirItem.description}\n`;
143
- }
144
- display += `💬 \`dm @${match.theirItem.handle} "I'd love help with ${match.myItem.skill}!"\`\n\n`;
145
- }
146
- }
147
-
148
- // Other people user can help
149
- const remainingOffers = matches.forMyOffers
150
- .filter(m => m.theirItem.urgency !== 'high')
151
- .slice(0, 3);
152
-
153
- if (remainingOffers.length > 0) {
154
- display += `### 🤝 People You Can Help\n`;
155
- for (const match of remainingOffers) {
156
- display += `**@${match.theirItem.handle}** needs **${match.theirItem.skill}**\n`;
157
- if (match.theirItem.context) {
158
- display += `_${match.theirItem.context}_\n`;
159
- }
160
- display += `💬 \`dm @${match.theirItem.handle} "I can help with ${match.theirItem.skill}!"\`\n\n`;
161
- }
162
- }
163
- }
164
-
165
- break;
166
- }
167
-
168
- case 'trending': {
169
- const stats = await skillsStore.getExchangeStats();
170
- const categories = await skillsStore.getSkillsByCategory();
171
-
172
- display = `## 📈 Trending Skills & Categories\n\n`;
173
-
174
- // Most requested skills
175
- if (stats.topSkills.length > 0) {
176
- display += `### 🔥 Most Popular Skills\n`;
177
- display += stats.topSkills.slice(0, 8)
178
- .map((s, i) => `${i+1}. **${s.skill}** (${s.count} posts)`)
179
- .join('\n');
180
- display += `\n\n`;
181
- }
182
-
183
- // Growing categories
184
- const categoryActivity = Object.entries(categories)
185
- .map(([name, items]) => ({
186
- name,
187
- total: items.offers.length + items.requests.length,
188
- ratio: items.requests.length / (items.offers.length || 1)
189
- }))
190
- .sort((a, b) => b.total - a.total);
191
-
192
- if (categoryActivity.length > 0) {
193
- display += `### 🎯 Category Activity\n`;
194
- for (const cat of categoryActivity.slice(0, 6)) {
195
- const demand = cat.ratio > 1.5 ? ' 🔥 High Demand' : cat.ratio < 0.5 ? ' 💼 Supply Rich' : '';
196
- display += `• **${cat.name}**: ${cat.total} posts${demand}\n`;
197
- }
198
- display += `\n`;
199
- }
200
-
201
- // Market opportunities
202
- const highDemand = categoryActivity.filter(c => c.ratio > 2);
203
- if (highDemand.length > 0) {
204
- display += `### 🚀 Market Opportunities\n`;
205
- display += `_High demand, low supply - great categories to offer skills:_\n`;
206
- for (const cat of highDemand.slice(0, 3)) {
207
- display += `• **${cat.name}** - ${Math.round(cat.ratio)}x more requests than offers\n`;
208
- }
209
- display += `\n`;
210
- }
211
-
212
- break;
213
- }
214
-
215
- case 'recent': {
216
- const [offers, requests] = await Promise.all([
217
- skillsStore.getSkillOffers(),
218
- skillsStore.getSkillRequests()
219
- ]);
220
-
221
- // Combine and sort by recency
222
- const recentActivity = [...offers, ...requests]
223
- .sort((a, b) => b.timestamp - a.timestamp)
224
- .slice(0, 10);
225
-
226
- display = `## 🕒 Recent Marketplace Activity\n\n`;
227
-
228
- if (recentActivity.length === 0) {
229
- display += `_No recent activity._\n\n`;
230
- display += `**Be the first:**\n`;
231
- display += `• \`skills offer "your-skill"\` to share expertise\n`;
232
- display += `• \`skills request "needed-skill"\` to find help\n`;
233
- } else {
234
- for (const item of recentActivity) {
235
- const type = item.level ? '🔧 Offering' : '🙋 Requesting';
236
- const urgencyEmoji = item.urgency === 'high' ? '🚨 ' : item.urgency === 'medium' ? '⚡ ' : '';
237
- const levelText = item.level ? ` _(${item.level} level)_` : '';
238
-
239
- display += `${type}: **${item.skill}** by @${item.handle}${levelText}\n`;
240
- if (item.description || item.context) {
241
- display += `_${item.description || item.context}_\n`;
242
- }
243
- display += `${urgencyEmoji}${formatTimeAgo(item.timestamp)}\n\n`;
244
- }
245
- }
246
-
247
- break;
248
- }
249
-
250
- default:
251
- display = `## Skills Dashboard Views\n\n`;
252
- display += `**\`skills-dashboard\`** — Complete marketplace overview\n`;
253
- display += `**\`skills-dashboard matches\`** — Your personalized matches\n`;
254
- display += `**\`skills-dashboard trending\`** — Hot skills and categories\n`;
255
- display += `**\`skills-dashboard recent\`** — Latest marketplace activity\n\n`;
256
- display += `**Quick Links:**\n`;
257
- display += `• \`skills\` — Main skills exchange commands\n`;
258
- display += `• \`skills matches\` — Find connections\n`;
259
- display += `• \`skills browse\` — Explore categories\n`;
260
- }
261
- } catch (error) {
262
- display = `## Skills Dashboard Error\n\n${error.message}`;
263
- }
264
-
265
- return { display };
266
- }
267
-
268
- module.exports = { definition, handler };