slashvibe-mcp 0.3.21 → 0.3.22

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