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.
- package/LICENSE +21 -0
- package/README.md +280 -47
- package/config.js +36 -31
- package/crypto.js +1 -6
- package/discord.js +19 -19
- package/index.js +217 -207
- package/intelligence/index.js +2 -9
- package/intelligence/infer.js +10 -16
- package/intelligence/patterns.js +23 -18
- package/intelligence/proactive.js +16 -15
- package/intelligence/serendipity.js +57 -20
- package/memory.js +13 -8
- package/notify.js +39 -14
- package/package.json +27 -20
- package/presence.js +2 -2
- package/prompts.js +5 -9
- package/protocol/index.js +123 -87
- package/protocol/telegram-commands.js +36 -37
- package/store/api.js +358 -529
- package/store/local.js +9 -10
- package/store/profiles.js +48 -192
- package/store/reservations.js +2 -9
- package/store/skills.js +69 -71
- package/store/sqlite.js +355 -0
- package/tools/_actions.js +48 -387
- package/tools/_connection-queue.js +45 -56
- package/tools/_discovery-enhanced.js +52 -57
- package/tools/_discovery.js +87 -185
- package/tools/{l2-status.js → _experimental/l2-status.js} +68 -70
- package/tools/{shipback.js → _experimental/shipback.js} +4 -3
- package/tools/_proactive-discovery.js +60 -73
- package/tools/_shared/index.js +41 -64
- package/tools/admin-inbox.js +10 -15
- package/tools/agents.js +1 -1
- package/tools/artifact-create.js +13 -23
- package/tools/artifact-view.js +4 -4
- package/tools/{_deprecated/back.js → back.js} +1 -1
- package/tools/bye.js +3 -5
- package/tools/consent.js +2 -2
- package/tools/context.js +9 -10
- package/tools/crossword.js +3 -2
- package/tools/discover.js +94 -356
- package/tools/dm.js +27 -86
- package/tools/doctor.js +12 -41
- package/tools/drawing.js +34 -20
- package/tools/echo.js +11 -11
- package/tools/feed.js +30 -58
- package/tools/follow.js +64 -187
- package/tools/{_deprecated/forget.js → forget.js} +4 -7
- package/tools/game.js +144 -48
- package/tools/handoff.js +6 -8
- package/tools/help.js +3 -3
- package/tools/idea.js +15 -27
- package/tools/inbox.js +121 -293
- package/tools/init.js +54 -151
- package/tools/invite.js +8 -21
- package/tools/migrate.js +27 -24
- package/tools/multiplayer-game.js +50 -40
- package/tools/{_deprecated/mute.js → mute.js} +4 -3
- package/tools/notifications.js +58 -48
- package/tools/observe.js +12 -15
- package/tools/onboarding.js +8 -11
- package/tools/open.js +13 -144
- package/tools/party-game.js +23 -12
- package/tools/patterns.js +2 -1
- package/tools/ping.js +5 -7
- package/tools/react.js +28 -30
- package/tools/{_deprecated/recall.js → recall.js} +5 -10
- package/tools/release.js +4 -2
- package/tools/{_deprecated/remember.js → remember.js} +4 -6
- package/tools/report.js +2 -2
- package/tools/request.js +6 -26
- package/tools/reserve.js +1 -1
- package/tools/session-fork.js +97 -0
- package/tools/session-save.js +109 -0
- package/tools/settings.js +30 -99
- package/tools/ship.js +74 -56
- package/tools/{_deprecated/skills-exchange.js → skills-exchange.js} +38 -39
- package/tools/social-inbox.js +22 -28
- package/tools/social-post.js +24 -27
- package/tools/solo-game.js +54 -46
- package/tools/start.js +14 -148
- package/tools/status.js +21 -68
- package/tools/submit.js +4 -2
- package/tools/suggest-tags.js +36 -33
- package/tools/summarize.js +19 -16
- package/tools/tag-suggestions.js +72 -73
- package/tools/test.js +1 -1
- package/tools/{_deprecated/tictactoe.js → tictactoe.js} +26 -26
- package/tools/token.js +4 -4
- package/tools/update.js +1 -2
- package/tools/watch.js +132 -112
- package/tools/who.js +20 -40
- package/tools/{_deprecated/wordassociation.js → wordassociation.js} +23 -20
- package/tools/workshop-buddy.js +52 -53
- package/tools/x-mentions.js +0 -1
- package/tools/x-reply.js +0 -1
- package/twitter.js +14 -20
- package/version.json +8 -10
- package/analytics.js +0 -107
- package/auth-store.js +0 -148
- package/auto-update.js +0 -130
- package/bridges/bridge-monitor.js +0 -388
- package/bridges/discord-bot.js +0 -431
- package/bridges/farcaster.js +0 -299
- package/bridges/telegram.js +0 -261
- package/bridges/webhook-health.js +0 -420
- package/bridges/webhook-server.js +0 -437
- package/bridges/whatsapp.js +0 -441
- package/bridges/x-webhook.js +0 -423
- package/games/arcade.js +0 -406
- package/games/chess.js +0 -451
- package/games/colorguess.js +0 -343
- package/games/crossword-words.js +0 -171
- package/games/crossword.js +0 -461
- package/games/drawing.js +0 -347
- package/games/gameroulette.js +0 -300
- package/games/gamerouter.js +0 -336
- package/games/gamestatus.js +0 -337
- package/games/guessnumber.js +0 -209
- package/games/hangman.js +0 -279
- package/games/memory.js +0 -338
- package/games/multiplayer-tictactoe.js +0 -389
- package/games/pixelart.js +0 -399
- package/games/quickduel.js +0 -354
- package/games/riddle.js +0 -371
- package/games/rockpaperscissors.js +0 -291
- package/games/snake.js +0 -406
- package/games/storybuilder.js +0 -343
- package/games/tictactoe.js +0 -345
- package/games/twentyquestions.js +0 -286
- package/games/twotruths.js +0 -207
- package/games/werewolf.js +0 -508
- package/games/wordassociation.js +0 -247
- package/games/wordchain.js +0 -135
- package/intelligence/interests.js +0 -369
- package/notification-emitter.js +0 -77
- package/setup.js +0 -480
- package/smart-inbox.js +0 -276
- package/tools/_deprecated/auto-suggest-connections.js +0 -304
- package/tools/_deprecated/bootstrap-skills.js +0 -231
- package/tools/_deprecated/bridge-dashboard.js +0 -342
- package/tools/_deprecated/bridge-health.js +0 -400
- package/tools/_deprecated/bridge-live.js +0 -384
- package/tools/_deprecated/bridges.js +0 -383
- package/tools/_deprecated/colorguess.js +0 -281
- package/tools/_deprecated/discover-insights.js +0 -379
- package/tools/_deprecated/discover-momentum.js +0 -256
- package/tools/_deprecated/discovery-analytics.js +0 -345
- package/tools/_deprecated/discovery-auto-suggest.js +0 -275
- package/tools/_deprecated/discovery-bootstrap.js +0 -267
- package/tools/_deprecated/discovery-daily.js +0 -375
- package/tools/_deprecated/discovery-dashboard.js +0 -385
- package/tools/_deprecated/discovery-digest.js +0 -314
- package/tools/_deprecated/discovery-hub.js +0 -357
- package/tools/_deprecated/discovery-insights.js +0 -384
- package/tools/_deprecated/discovery-momentum.js +0 -281
- package/tools/_deprecated/discovery-monitor.js +0 -319
- package/tools/_deprecated/discovery-proactive.js +0 -300
- package/tools/_deprecated/draw.js +0 -317
- package/tools/_deprecated/farcaster.js +0 -307
- package/tools/_deprecated/games-catalog.js +0 -376
- package/tools/_deprecated/games.js +0 -313
- package/tools/_deprecated/guessnumber.js +0 -194
- package/tools/_deprecated/hangman.js +0 -129
- package/tools/_deprecated/multiplayer-tictactoe.js +0 -303
- package/tools/_deprecated/riddle.js +0 -240
- package/tools/_deprecated/run-bootstrap.js +0 -69
- package/tools/_deprecated/skills-analytics.js +0 -349
- package/tools/_deprecated/skills-bootstrap.js +0 -301
- package/tools/_deprecated/skills-dashboard.js +0 -268
- package/tools/_deprecated/skills.js +0 -380
- package/tools/_deprecated/smart-intro.js +0 -353
- package/tools/_deprecated/storybuilder.js +0 -331
- package/tools/_deprecated/telegram-bot.js +0 -183
- package/tools/_deprecated/telegram-setup.js +0 -214
- package/tools/_deprecated/twentyquestions.js +0 -143
- package/tools/_shared.js +0 -234
- package/tools/_work-context.js +0 -338
- package/tools/_work-context.manual-test.js +0 -199
- package/tools/_work-context.test.js +0 -260
- package/tools/activity.js +0 -220
- package/tools/agent-treasury.js +0 -288
- package/tools/analytics.js +0 -191
- package/tools/approve.js +0 -197
- package/tools/arcade.js +0 -173
- package/tools/artifacts-price.js +0 -107
- package/tools/ask-expert.js +0 -160
- package/tools/available.js +0 -120
- package/tools/become-expert.js +0 -150
- package/tools/broadcast.js +0 -325
- package/tools/chat.js +0 -202
- package/tools/collaborative-drawing.js +0 -286
- package/tools/connection-status.js +0 -178
- package/tools/earnings.js +0 -126
- package/tools/friends.js +0 -207
- package/tools/genesis.js +0 -233
- package/tools/gig-browse.js +0 -206
- package/tools/gig-complete.js +0 -144
- package/tools/health.js +0 -87
- package/tools/leaderboard.js +0 -117
- package/tools/lib/git-apply.js +0 -206
- package/tools/lib/git-bundle.js +0 -407
- package/tools/mint.js +0 -377
- package/tools/plan.js +0 -225
- package/tools/profile.js +0 -219
- package/tools/proof-of-work.js +0 -144
- package/tools/pulse.js +0 -218
- package/tools/reply.js +0 -166
- package/tools/reputation.js +0 -175
- package/tools/schedule.js +0 -367
- package/tools/search-messages.js +0 -123
- package/tools/session.js +0 -467
- package/tools/session_price.js +0 -128
- package/tools/smart-check.js +0 -201
- package/tools/social-processor.js +0 -445
- package/tools/streak.js +0 -147
- package/tools/stuck.js +0 -297
- package/tools/subscribe.js +0 -148
- package/tools/subscriptions.js +0 -134
- package/tools/tip.js +0 -193
- package/tools/wallet.js +0 -269
- package/tools/webhook-test.js +0 -388
- package/tools/withdraw.js +0 -145
- package/tools/work-summary.js +0 -96
- package/tools/workshop.js +0 -327
- /package/tools/{l2-bridge.js → _experimental/l2-bridge.js} +0 -0
- /package/tools/{l2.js → _experimental/l2.js} +0 -0
- /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 };
|