slashvibe-mcp 0.3.21 → 0.3.23

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