slashvibe-mcp 0.3.21 → 0.3.22

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