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,379 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Discovery Insights — Analytics and improvement suggestions for the discovery system
|
|
3
|
-
*
|
|
4
|
-
* Features:
|
|
5
|
-
* - Connection success tracking
|
|
6
|
-
* - Match quality analysis
|
|
7
|
-
* - Community growth insights
|
|
8
|
-
* - Recommendation algorithm tuning
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const config = require('../config');
|
|
12
|
-
const userProfiles = require('../store/profiles');
|
|
13
|
-
const { formatTimeAgo, requireInit } = require('./_shared');
|
|
14
|
-
|
|
15
|
-
const definition = {
|
|
16
|
-
name: 'vibe_discover_insights',
|
|
17
|
-
description: 'Analyze discovery patterns and suggest improvements to matchmaking.',
|
|
18
|
-
inputSchema: {
|
|
19
|
-
type: 'object',
|
|
20
|
-
properties: {
|
|
21
|
-
command: {
|
|
22
|
-
type: 'string',
|
|
23
|
-
enum: ['quality', 'growth', 'gaps', 'tune'],
|
|
24
|
-
description: 'Type of insight analysis to run'
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// Analyze connection quality patterns
|
|
31
|
-
async function analyzeConnectionQuality() {
|
|
32
|
-
const profiles = await userProfiles.getAllProfiles();
|
|
33
|
-
const analysis = {
|
|
34
|
-
totalConnections: 0,
|
|
35
|
-
avgConnectionsPerUser: 0,
|
|
36
|
-
connectionsByReason: {},
|
|
37
|
-
mostSuccessfulTags: {},
|
|
38
|
-
interestClusterSizes: {},
|
|
39
|
-
timingPatterns: {}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
let totalConnectionCount = 0;
|
|
43
|
-
|
|
44
|
-
for (const profile of profiles) {
|
|
45
|
-
if (profile.connections) {
|
|
46
|
-
totalConnectionCount += profile.connections.length;
|
|
47
|
-
|
|
48
|
-
// Analyze reasons for connections
|
|
49
|
-
for (const conn of profile.connections) {
|
|
50
|
-
const reason = conn.reason || 'unknown';
|
|
51
|
-
analysis.connectionsByReason[reason] = (analysis.connectionsByReason[reason] || 0) + 1;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Track tag success (users with more connections)
|
|
56
|
-
if (profile.tags && profile.connections) {
|
|
57
|
-
for (const tag of profile.tags) {
|
|
58
|
-
if (!analysis.mostSuccessfulTags[tag]) {
|
|
59
|
-
analysis.mostSuccessfulTags[tag] = { connections: 0, users: 0 };
|
|
60
|
-
}
|
|
61
|
-
analysis.mostSuccessfulTags[tag].connections += profile.connections.length;
|
|
62
|
-
analysis.mostSuccessfulTags[tag].users += 1;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
analysis.totalConnections = totalConnectionCount / 2; // Each connection is counted twice
|
|
68
|
-
analysis.avgConnectionsPerUser = profiles.length > 0 ? totalConnectionCount / profiles.length : 0;
|
|
69
|
-
|
|
70
|
-
// Calculate tag success rates
|
|
71
|
-
const tagSuccessRates = Object.entries(analysis.mostSuccessfulTags)
|
|
72
|
-
.map(([tag, data]) => ({
|
|
73
|
-
tag,
|
|
74
|
-
avgConnectionsPerUser: data.connections / data.users,
|
|
75
|
-
userCount: data.users
|
|
76
|
-
}))
|
|
77
|
-
.filter(item => item.userCount >= 2) // Only tags with multiple users
|
|
78
|
-
.sort((a, b) => b.avgConnectionsPerUser - a.avgConnectionsPerUser)
|
|
79
|
-
.slice(0, 10);
|
|
80
|
-
|
|
81
|
-
return { analysis, tagSuccessRates };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Analyze community growth patterns
|
|
85
|
-
async function analyzeCommunityGrowth() {
|
|
86
|
-
const profiles = await userProfiles.getAllProfiles();
|
|
87
|
-
|
|
88
|
-
if (profiles.length === 0) {
|
|
89
|
-
return {
|
|
90
|
-
growth: 'No user data available',
|
|
91
|
-
trends: [],
|
|
92
|
-
recommendations: ['Encourage users to set up profiles with vibe update commands']
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Sort by first seen date
|
|
97
|
-
const sortedProfiles = profiles
|
|
98
|
-
.filter(p => p.firstSeen)
|
|
99
|
-
.sort((a, b) => a.firstSeen - b.firstSeen);
|
|
100
|
-
|
|
101
|
-
const now = Date.now();
|
|
102
|
-
const oneWeekAgo = now - (7 * 24 * 60 * 60 * 1000);
|
|
103
|
-
const oneMonthAgo = now - (30 * 24 * 60 * 60 * 1000);
|
|
104
|
-
|
|
105
|
-
const recentUsers = sortedProfiles.filter(p => p.firstSeen > oneWeekAgo).length;
|
|
106
|
-
const monthlyUsers = sortedProfiles.filter(p => p.firstSeen > oneMonthAgo).length;
|
|
107
|
-
|
|
108
|
-
// Interest evolution
|
|
109
|
-
const interestTrends = await userProfiles.getTrendingInterests();
|
|
110
|
-
const tagTrends = await userProfiles.getTrendingTags();
|
|
111
|
-
|
|
112
|
-
// Activity patterns
|
|
113
|
-
const activeUsers = profiles.filter(p => p.lastSeen && p.lastSeen > oneWeekAgo).length;
|
|
114
|
-
const profileCompleteness = profiles.filter(p =>
|
|
115
|
-
p.building && p.interests?.length > 0 && p.tags?.length > 0
|
|
116
|
-
).length;
|
|
117
|
-
|
|
118
|
-
return {
|
|
119
|
-
totalUsers: profiles.length,
|
|
120
|
-
recentGrowth: recentUsers,
|
|
121
|
-
monthlyGrowth: monthlyUsers,
|
|
122
|
-
activeUsers,
|
|
123
|
-
profileCompleteness: `${Math.round((profileCompleteness / profiles.length) * 100)}%`,
|
|
124
|
-
topInterests: interestTrends.slice(0, 5),
|
|
125
|
-
topTags: tagTrends.slice(0, 8),
|
|
126
|
-
recommendations: generateGrowthRecommendations(profiles, recentUsers, profileCompleteness)
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Identify gaps in the community
|
|
131
|
-
async function identifyGaps() {
|
|
132
|
-
const profiles = await userProfiles.getAllProfiles();
|
|
133
|
-
|
|
134
|
-
if (profiles.length < 5) {
|
|
135
|
-
return {
|
|
136
|
-
message: 'Community too small for gap analysis',
|
|
137
|
-
recommendations: ['Focus on user acquisition and profile setup']
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const gaps = {
|
|
142
|
-
underrepresentedSkills: [],
|
|
143
|
-
missingComplementaryPairs: [],
|
|
144
|
-
isolatedUsers: [],
|
|
145
|
-
timezoneGaps: []
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
// Find isolated users (few connections)
|
|
149
|
-
gaps.isolatedUsers = profiles
|
|
150
|
-
.filter(p => !p.connections || p.connections.length < 2)
|
|
151
|
-
.map(p => ({
|
|
152
|
-
handle: p.handle,
|
|
153
|
-
building: p.building,
|
|
154
|
-
interests: p.interests || [],
|
|
155
|
-
connectionCount: p.connections?.length || 0
|
|
156
|
-
}))
|
|
157
|
-
.slice(0, 8);
|
|
158
|
-
|
|
159
|
-
// Skill gaps - common complementary pairs
|
|
160
|
-
const skillPairs = [
|
|
161
|
-
['frontend', 'backend'],
|
|
162
|
-
['design', 'engineering'],
|
|
163
|
-
['ai', 'data'],
|
|
164
|
-
['product', 'engineering'],
|
|
165
|
-
['marketing', 'engineering']
|
|
166
|
-
];
|
|
167
|
-
|
|
168
|
-
for (const [skill1, skill2] of skillPairs) {
|
|
169
|
-
const skill1Users = profiles.filter(p => p.tags?.some(t => t.toLowerCase().includes(skill1))).length;
|
|
170
|
-
const skill2Users = profiles.filter(p => p.tags?.some(t => t.toLowerCase().includes(skill2))).length;
|
|
171
|
-
|
|
172
|
-
if (Math.abs(skill1Users - skill2Users) > 3) {
|
|
173
|
-
gaps.missingComplementaryPairs.push({
|
|
174
|
-
overpopulated: skill1Users > skill2Users ? skill1 : skill2,
|
|
175
|
-
underpopulated: skill1Users > skill2Users ? skill2 : skill1,
|
|
176
|
-
ratio: `${Math.max(skill1Users, skill2Users)}:${Math.min(skill1Users, skill2Users)}`
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return gaps;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Suggest algorithm tuning
|
|
185
|
-
async function suggestTuning() {
|
|
186
|
-
const { analysis } = await analyzeConnectionQuality();
|
|
187
|
-
const suggestions = [];
|
|
188
|
-
|
|
189
|
-
if (analysis.avgConnectionsPerUser < 2) {
|
|
190
|
-
suggestions.push({
|
|
191
|
-
metric: 'Low connection rate',
|
|
192
|
-
issue: `Avg ${analysis.avgConnectionsPerUser.toFixed(1)} connections per user`,
|
|
193
|
-
suggestion: 'Lower match score threshold or improve onboarding'
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Analyze most successful connection reasons
|
|
198
|
-
const topReasons = Object.entries(analysis.connectionsByReason)
|
|
199
|
-
.sort(([,a], [,b]) => b - a)
|
|
200
|
-
.slice(0, 3);
|
|
201
|
-
|
|
202
|
-
if (topReasons.length > 0) {
|
|
203
|
-
suggestions.push({
|
|
204
|
-
metric: 'Top connection drivers',
|
|
205
|
-
issue: `Most connections from: ${topReasons.map(([r]) => r).join(', ')}`,
|
|
206
|
-
suggestion: 'Weight these factors higher in scoring algorithm'
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
suggestions.push({
|
|
211
|
-
metric: 'Algorithm recommendations',
|
|
212
|
-
issue: 'Based on current patterns',
|
|
213
|
-
suggestion: 'Consider time-based matching boost for users online simultaneously'
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
return suggestions;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Generate growth recommendations
|
|
220
|
-
function generateGrowthRecommendations(profiles, recentUsers, completeProfiles) {
|
|
221
|
-
const recommendations = [];
|
|
222
|
-
|
|
223
|
-
if (recentUsers < 2) {
|
|
224
|
-
recommendations.push('Focus on user acquisition - invite more builders');
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (completeProfiles < profiles.length * 0.5) {
|
|
228
|
-
recommendations.push('Improve onboarding - guide users through profile setup');
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if (profiles.length > 10 && recentUsers > 5) {
|
|
232
|
-
recommendations.push('Community is growing! Consider specialized interest groups');
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
recommendations.push('Encourage users to ship and announce their work');
|
|
236
|
-
recommendations.push('Host virtual coworking sessions for active builders');
|
|
237
|
-
|
|
238
|
-
return recommendations;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async function handler(args) {
|
|
242
|
-
const initCheck = requireInit();
|
|
243
|
-
if (initCheck) return initCheck;
|
|
244
|
-
|
|
245
|
-
const command = args.command || 'quality';
|
|
246
|
-
let display = '';
|
|
247
|
-
|
|
248
|
-
try {
|
|
249
|
-
switch (command) {
|
|
250
|
-
case 'quality': {
|
|
251
|
-
const { analysis, tagSuccessRates } = await analyzeConnectionQuality();
|
|
252
|
-
|
|
253
|
-
display = `## Connection Quality Analysis\n\n`;
|
|
254
|
-
display += `**Overall Stats:**\n`;
|
|
255
|
-
display += `• Total connections made: ${analysis.totalConnections}\n`;
|
|
256
|
-
display += `• Avg connections per user: ${analysis.avgConnectionsPerUser.toFixed(1)}\n\n`;
|
|
257
|
-
|
|
258
|
-
if (tagSuccessRates.length > 0) {
|
|
259
|
-
display += `**Most Connected Skills:**\n`;
|
|
260
|
-
for (const item of tagSuccessRates) {
|
|
261
|
-
display += `• ${item.tag}: ${item.avgConnectionsPerUser.toFixed(1)} avg connections (${item.userCount} users)\n`;
|
|
262
|
-
}
|
|
263
|
-
display += `\n`;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (Object.keys(analysis.connectionsByReason).length > 0) {
|
|
267
|
-
display += `**Connection Reasons:**\n`;
|
|
268
|
-
const sortedReasons = Object.entries(analysis.connectionsByReason)
|
|
269
|
-
.sort(([,a], [,b]) => b - a)
|
|
270
|
-
.slice(0, 5);
|
|
271
|
-
|
|
272
|
-
for (const [reason, count] of sortedReasons) {
|
|
273
|
-
display += `• ${reason}: ${count} connections\n`;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
break;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
case 'growth': {
|
|
281
|
-
const growth = await analyzeCommunityGrowth();
|
|
282
|
-
|
|
283
|
-
display = `## Community Growth Analysis\n\n`;
|
|
284
|
-
display += `**Community Size:**\n`;
|
|
285
|
-
display += `• Total users: ${growth.totalUsers}\n`;
|
|
286
|
-
display += `• New this week: ${growth.recentGrowth}\n`;
|
|
287
|
-
display += `• New this month: ${growth.monthlyGrowth}\n`;
|
|
288
|
-
display += `• Currently active: ${growth.activeUsers}\n`;
|
|
289
|
-
display += `• Complete profiles: ${growth.profileCompleteness}\n\n`;
|
|
290
|
-
|
|
291
|
-
if (growth.topInterests?.length > 0) {
|
|
292
|
-
display += `**Trending Interests:**\n`;
|
|
293
|
-
for (const item of growth.topInterests) {
|
|
294
|
-
display += `• ${item.interest} (${item.count} users)\n`;
|
|
295
|
-
}
|
|
296
|
-
display += `\n`;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
if (growth.topTags?.length > 0) {
|
|
300
|
-
display += `**Popular Skills:**\n`;
|
|
301
|
-
for (const item of growth.topTags) {
|
|
302
|
-
display += `• ${item.tag} (${item.count})\n`;
|
|
303
|
-
}
|
|
304
|
-
display += `\n`;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
display += `**Growth Recommendations:**\n`;
|
|
308
|
-
for (const rec of growth.recommendations) {
|
|
309
|
-
display += `• ${rec}\n`;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
case 'gaps': {
|
|
316
|
-
const gaps = await identifyGaps();
|
|
317
|
-
|
|
318
|
-
display = `## Community Gap Analysis\n\n`;
|
|
319
|
-
|
|
320
|
-
if (gaps.isolatedUsers?.length > 0) {
|
|
321
|
-
display += `**Users Needing Connections:**\n`;
|
|
322
|
-
for (const user of gaps.isolatedUsers) {
|
|
323
|
-
display += `• @${user.handle} (${user.connectionCount} connections)\n`;
|
|
324
|
-
if (user.building) display += ` Building: ${user.building}\n`;
|
|
325
|
-
}
|
|
326
|
-
display += `\n`;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (gaps.missingComplementaryPairs?.length > 0) {
|
|
330
|
-
display += `**Skill Imbalances:**\n`;
|
|
331
|
-
for (const gap of gaps.missingComplementaryPairs) {
|
|
332
|
-
display += `• Need more ${gap.underpopulated} (${gap.ratio} ratio)\n`;
|
|
333
|
-
}
|
|
334
|
-
display += `\n`;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
display += `**Suggestions:**\n`;
|
|
338
|
-
display += `• Target recruitment for underrepresented skills\n`;
|
|
339
|
-
display += `• Create interest groups for isolated users\n`;
|
|
340
|
-
display += `• Host skill-exchange sessions\n`;
|
|
341
|
-
|
|
342
|
-
break;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
case 'tune': {
|
|
346
|
-
const suggestions = await suggestTuning();
|
|
347
|
-
|
|
348
|
-
display = `## Algorithm Tuning Suggestions\n\n`;
|
|
349
|
-
|
|
350
|
-
for (const suggestion of suggestions) {
|
|
351
|
-
display += `**${suggestion.metric}**\n`;
|
|
352
|
-
display += `Issue: ${suggestion.issue}\n`;
|
|
353
|
-
display += `Recommendation: ${suggestion.suggestion}\n\n`;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
break;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
default:
|
|
360
|
-
display = `## Discovery Insights Commands
|
|
361
|
-
|
|
362
|
-
**\`insights quality\`** — Analyze connection success patterns
|
|
363
|
-
**\`insights growth\`** — Review community growth metrics
|
|
364
|
-
**\`insights gaps\`** — Identify underserved users and skills
|
|
365
|
-
**\`insights tune\`** — Get algorithm improvement suggestions`;
|
|
366
|
-
}
|
|
367
|
-
} catch (error) {
|
|
368
|
-
display = `## Insights Error
|
|
369
|
-
|
|
370
|
-
${error.message}
|
|
371
|
-
|
|
372
|
-
The discovery insights system needs user profile data to work.
|
|
373
|
-
Try: \`discover insights\` for available commands`;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
return { display };
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
module.exports = { definition, handler };
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Momentum-Enhanced Discovery Command — Find people based on shipping velocity and collaboration signals
|
|
3
|
-
*
|
|
4
|
-
* This provides users with discovery options that consider:
|
|
5
|
-
* - Recent shipping activity
|
|
6
|
-
* - Collaboration intent signals
|
|
7
|
-
* - Building momentum patterns
|
|
8
|
-
* - Project complementarity
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const config = require('../config');
|
|
12
|
-
const userProfiles = require('../store/profiles');
|
|
13
|
-
const { formatTimeAgo, requireInit } = require('./_shared');
|
|
14
|
-
const momentum = require('./discovery-momentum');
|
|
15
|
-
|
|
16
|
-
const definition = {
|
|
17
|
-
name: 'vibe_discover_momentum',
|
|
18
|
-
description: 'Find connections based on shipping patterns and collaboration signals.',
|
|
19
|
-
inputSchema: {
|
|
20
|
-
type: 'object',
|
|
21
|
-
properties: {
|
|
22
|
-
mode: {
|
|
23
|
-
type: 'string',
|
|
24
|
-
enum: ['matches', 'collaborate', 'momentum', 'opportunities'],
|
|
25
|
-
description: 'Discovery mode: matches (general), collaborate (seeking partners), momentum (activity-based), opportunities (all collaboration matches)'
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
required: []
|
|
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 mode = args.mode || 'matches';
|
|
38
|
-
|
|
39
|
-
let display = '';
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
switch (mode) {
|
|
43
|
-
case 'matches': {
|
|
44
|
-
const recommendations = await momentum.generateShippingRecommendations(myHandle);
|
|
45
|
-
|
|
46
|
-
if (recommendations.momentumMatches.length === 0) {
|
|
47
|
-
display = `## No Momentum Matches Found
|
|
48
|
-
|
|
49
|
-
_Looking for people with recent shipping activity..._
|
|
50
|
-
|
|
51
|
-
${recommendations.targetMomentum.recentShips > 0
|
|
52
|
-
? `**Your momentum:** ${recommendations.targetMomentum.score} (${recommendations.targetMomentum.recentShips} recent ships)`
|
|
53
|
-
: '**Tip:** Ship something recently to improve matching with active builders'
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
**Try:**
|
|
57
|
-
- \`discover momentum collaborate\` — Find collaboration opportunities
|
|
58
|
-
- \`discover momentum opportunities\` — See all seeking partnerships
|
|
59
|
-
- \`vibe ship "what you built"\` — Update your activity`;
|
|
60
|
-
|
|
61
|
-
} else {
|
|
62
|
-
display = `## Momentum-Based Matches\n\n`;
|
|
63
|
-
display += `**Your building momentum:** ${recommendations.targetMomentum.score}\n`;
|
|
64
|
-
display += `_${recommendations.targetMomentum.recentShips} ships this week • ${recommendations.targetMomentum.totalShips} total_\n\n`;
|
|
65
|
-
|
|
66
|
-
for (const match of recommendations.momentumMatches) {
|
|
67
|
-
display += `### @${match.handle} _(${match.score} match • ${Math.round(match.confidence * 100)}% confidence)_\n\n`;
|
|
68
|
-
display += `**Building:** ${match.building || 'Active project'}\n`;
|
|
69
|
-
|
|
70
|
-
if (match.lastShip) {
|
|
71
|
-
display += `**Latest ship:** ${match.lastShip.what}\n`;
|
|
72
|
-
display += `_${formatTimeAgo(match.lastShip.timestamp)}_\n`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
display += `**Why connect:**\n`;
|
|
76
|
-
for (const reason of match.reasons) {
|
|
77
|
-
display += `• ${reason}\n`;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
display += `**Activity:** ${match.momentum.recentShips} recent ships`;
|
|
81
|
-
if (match.momentum.seekingCollaboration) {
|
|
82
|
-
display += ` • 🤝 **Seeking collaboration**`;
|
|
83
|
-
}
|
|
84
|
-
display += '\n\n';
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
display += `**Quick actions:**\n`;
|
|
88
|
-
display += `- \`message @handle\` to connect\n`;
|
|
89
|
-
display += `- \`discover momentum collaborate\` for partnership opportunities`;
|
|
90
|
-
}
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
case 'collaborate': {
|
|
95
|
-
const recommendations = await momentum.generateShippingRecommendations(myHandle);
|
|
96
|
-
const collabOpps = recommendations.collaborationOpportunities;
|
|
97
|
-
|
|
98
|
-
if (collabOpps.length === 0) {
|
|
99
|
-
const myMomentum = recommendations.targetMomentum;
|
|
100
|
-
|
|
101
|
-
display = `## No Direct Collaboration Matches
|
|
102
|
-
|
|
103
|
-
${myMomentum.seekingCollaboration
|
|
104
|
-
? '**You\'re seeking collaboration** — here are active builders:'
|
|
105
|
-
: '**Tip:** Signal collaboration intent in your ships with phrases like "looking for help" or "seeking feedback"'
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
**Alternative matches:**`;
|
|
109
|
-
|
|
110
|
-
const topMatches = recommendations.momentumMatches.slice(0, 2);
|
|
111
|
-
for (const match of topMatches) {
|
|
112
|
-
display += `\n\n**@${match.handle}** _(${match.score} match)_`;
|
|
113
|
-
display += `\nBuilding: ${match.building}`;
|
|
114
|
-
display += `\nActive: ${match.momentum.recentShips} recent ships`;
|
|
115
|
-
if (match.reasons.length > 0) {
|
|
116
|
-
display += `\nWhy: ${match.reasons[0]}`;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (topMatches.length === 0) {
|
|
121
|
-
display += `\n\n_No matches found. Try shipping something or updating your profile._`;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
} else {
|
|
125
|
-
display = `## Collaboration Opportunities\n\n`;
|
|
126
|
-
|
|
127
|
-
for (const opp of collabOpps) {
|
|
128
|
-
const isSeeker = opp.seeker === myHandle;
|
|
129
|
-
const partnerHandle = isSeeker ? opp.builder : opp.seeker;
|
|
130
|
-
const partnerProject = isSeeker ? opp.builderProject : opp.seekerProject;
|
|
131
|
-
|
|
132
|
-
display += `### @${partnerHandle} _(${opp.score} match)_\n`;
|
|
133
|
-
display += `**Their project:** ${partnerProject}\n`;
|
|
134
|
-
display += `**Match reasons:**\n`;
|
|
135
|
-
for (const reason of opp.reasons) {
|
|
136
|
-
display += `• ${reason}\n`;
|
|
137
|
-
}
|
|
138
|
-
display += '\n';
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
display += `**Next steps:**\n`;
|
|
142
|
-
display += `- Reach out with \`message @handle\`\n`;
|
|
143
|
-
display += `- Reference their recent ship to show genuine interest\n`;
|
|
144
|
-
display += `- Be specific about how you could collaborate`;
|
|
145
|
-
}
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
case 'momentum': {
|
|
150
|
-
const myProfile = await userProfiles.getProfile(myHandle);
|
|
151
|
-
const myMomentum = momentum.analyzeShippingMomentum(myProfile);
|
|
152
|
-
|
|
153
|
-
display = `## Your Building Momentum\n\n`;
|
|
154
|
-
display += `**Momentum Score:** ${myMomentum.score}\n`;
|
|
155
|
-
display += `**Recent ships:** ${myMomentum.recentShips} (past week)\n`;
|
|
156
|
-
display += `**Total ships:** ${myMomentum.totalShips}\n`;
|
|
157
|
-
|
|
158
|
-
if (myMomentum.seekingCollaboration) {
|
|
159
|
-
display += `**Status:** 🤝 Seeking collaboration\n`;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (myMomentum.projectTypes.length > 0) {
|
|
163
|
-
display += `**Project types:** ${myMomentum.projectTypes.join(', ')}\n`;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
display += '\n';
|
|
167
|
-
|
|
168
|
-
// Momentum insights
|
|
169
|
-
if (myMomentum.score >= 50) {
|
|
170
|
-
display += `🚀 **High momentum!** Great time to find collaboration partners.\n\n`;
|
|
171
|
-
} else if (myMomentum.score >= 25) {
|
|
172
|
-
display += `⚡ **Good momentum.** Consider shipping more to increase visibility.\n\n`;
|
|
173
|
-
} else {
|
|
174
|
-
display += `📈 **Building momentum.** Ship something recent to improve matching.\n\n`;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Show recent ships
|
|
178
|
-
if (myProfile.ships && myProfile.ships.length > 0) {
|
|
179
|
-
display += `**Recent ships:**\n`;
|
|
180
|
-
for (const ship of myProfile.ships.slice(0, 3)) {
|
|
181
|
-
display += `• ${ship.what} _(${formatTimeAgo(ship.timestamp)})_\n`;
|
|
182
|
-
}
|
|
183
|
-
} else {
|
|
184
|
-
display += `**No ships recorded.** Use \`vibe ship "what you built"\` to get started.`;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
display += `\n\n**Improve your momentum:**\n`;
|
|
188
|
-
display += `- Ship regularly (\`vibe ship\`)\n`;
|
|
189
|
-
display += `- Signal collaboration intent ("seeking feedback", "looking for help")\n`;
|
|
190
|
-
display += `- Update your profile with current project (\`vibe update building\`)`;
|
|
191
|
-
break;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
case 'opportunities': {
|
|
195
|
-
const opportunities = await momentum.findCollaborationOpportunities();
|
|
196
|
-
|
|
197
|
-
if (opportunities.opportunities.length === 0) {
|
|
198
|
-
display = `## No Collaboration Opportunities Found
|
|
199
|
-
|
|
200
|
-
**Current activity:**
|
|
201
|
-
- ${opportunities.totalSeekers} people seeking collaboration
|
|
202
|
-
- ${opportunities.totalActiveBuilders} active builders
|
|
203
|
-
|
|
204
|
-
_Not enough overlap for quality matches yet._
|
|
205
|
-
|
|
206
|
-
**Help grow the community:**
|
|
207
|
-
- Ship with collaboration signals ("looking for", "need help")
|
|
208
|
-
- Update your profile and interests
|
|
209
|
-
- Connect with \`discover momentum matches\``;
|
|
210
|
-
|
|
211
|
-
} else {
|
|
212
|
-
display = `## All Collaboration Opportunities\n\n`;
|
|
213
|
-
display += `**Found ${opportunities.opportunities.length} potential matches**\n`;
|
|
214
|
-
display += `_${opportunities.totalSeekers} seeking • ${opportunities.totalActiveBuilders} building_\n\n`;
|
|
215
|
-
|
|
216
|
-
for (const opp of opportunities.opportunities) {
|
|
217
|
-
display += `**@${opp.seeker} 🤝 @${opp.builder}** _(${opp.score} match)_\n`;
|
|
218
|
-
display += `Seeker: ${opp.seekerProject || 'Seeking collaboration'}\n`;
|
|
219
|
-
display += `Builder: ${opp.builderProject || 'Active project'}\n`;
|
|
220
|
-
display += `Match: ${opp.reasons[0] || 'Good fit'}\n\n`;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
display += `**As a community member, you could:**\n`;
|
|
224
|
-
display += `- Suggest these connections to the people involved\n`;
|
|
225
|
-
display += `- Join \`discover momentum collaborate\` to find your own matches`;
|
|
226
|
-
}
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
default:
|
|
231
|
-
display = `## Momentum Discovery Commands
|
|
232
|
-
|
|
233
|
-
**\`discover momentum matches\`** — Find matches based on shipping patterns
|
|
234
|
-
**\`discover momentum collaborate\`** — Find collaboration opportunities
|
|
235
|
-
**\`discover momentum momentum\`** — Analyze your building momentum
|
|
236
|
-
**\`discover momentum opportunities\`** — See all collaboration matches
|
|
237
|
-
|
|
238
|
-
**Key features:**
|
|
239
|
-
- Matches based on recent shipping activity
|
|
240
|
-
- Detects collaboration intent in ships
|
|
241
|
-
- Considers project complementarity
|
|
242
|
-
- Analyzes building momentum patterns`;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
} catch (error) {
|
|
246
|
-
display = `## Momentum Discovery Error
|
|
247
|
-
|
|
248
|
-
${error.message}
|
|
249
|
-
|
|
250
|
-
Try: \`discover momentum\` for available commands`;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return { display };
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
module.exports = { definition, handler };
|