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,267 +0,0 @@
1
- /**
2
- * vibe discovery-bootstrap — Seed discovery system with sample profiles
3
- *
4
- * Creates realistic user profiles to populate the discovery system
5
- * for testing and demonstration of workshop-buddy and skills-exchange features.
6
- */
7
-
8
- const config = require('../config');
9
- const userProfiles = require('../store/profiles');
10
- const store = require('../store');
11
- const { requireInit } = require('./_shared');
12
-
13
- const definition = {
14
- name: 'vibe_discovery_bootstrap',
15
- description: 'Bootstrap the discovery system with sample profiles for testing.',
16
- inputSchema: {
17
- type: 'object',
18
- properties: {
19
- count: {
20
- type: 'number',
21
- default: 10,
22
- description: 'Number of sample profiles to create'
23
- },
24
- clear: {
25
- type: 'boolean',
26
- default: false,
27
- description: 'Clear existing profiles first'
28
- }
29
- }
30
- }
31
- };
32
-
33
- // Sample profiles with complementary skills
34
- const sampleProfiles = [
35
- {
36
- handle: 'alex_frontend',
37
- building: 'React dashboard for startup analytics',
38
- interests: ['startups', 'design-systems', 'data-visualization'],
39
- tags: ['frontend', 'react', 'typescript', 'css'],
40
- mock: true
41
- },
42
- {
43
- handle: 'sam_backend',
44
- building: 'Scalable API infrastructure for fintech',
45
- interests: ['fintech', 'distributed-systems', 'security'],
46
- tags: ['backend', 'python', 'postgres', 'docker'],
47
- mock: true
48
- },
49
- {
50
- handle: 'jordan_design',
51
- building: 'Design system for healthcare apps',
52
- interests: ['healthcare', 'accessibility', 'user-research'],
53
- tags: ['ui', 'ux', 'figma', 'design-systems'],
54
- mock: true
55
- },
56
- {
57
- handle: 'casey_ai',
58
- building: 'AI-powered content generation tool',
59
- interests: ['ai', 'content', 'automation'],
60
- tags: ['ai', 'python', 'machine-learning', 'nlp'],
61
- mock: true
62
- },
63
- {
64
- handle: 'taylor_product',
65
- building: 'B2B SaaS for project management',
66
- interests: ['product-management', 'b2b', 'user-research'],
67
- tags: ['product', 'strategy', 'user-research', 'analytics'],
68
- mock: true
69
- },
70
- {
71
- handle: 'riley_mobile',
72
- building: 'React Native app for fitness tracking',
73
- interests: ['fitness', 'mobile', 'health'],
74
- tags: ['mobile', 'react-native', 'ios', 'android'],
75
- mock: true
76
- },
77
- {
78
- handle: 'morgan_devops',
79
- building: 'Kubernetes deployment automation',
80
- interests: ['infrastructure', 'automation', 'monitoring'],
81
- tags: ['devops', 'kubernetes', 'aws', 'monitoring'],
82
- mock: true
83
- },
84
- {
85
- handle: 'avery_data',
86
- building: 'ML pipeline for e-commerce recommendations',
87
- interests: ['data-science', 'e-commerce', 'recommendation-systems'],
88
- tags: ['data', 'python', 'spark', 'machine-learning'],
89
- mock: true
90
- },
91
- {
92
- handle: 'quinn_marketing',
93
- building: 'Growth strategy for developer tools',
94
- interests: ['developer-marketing', 'growth', 'content'],
95
- tags: ['marketing', 'growth', 'content', 'developer-relations'],
96
- mock: true
97
- },
98
- {
99
- handle: 'sage_security',
100
- building: 'Security audit tools for web apps',
101
- interests: ['cybersecurity', 'web-security', 'penetration-testing'],
102
- tags: ['security', 'penetration-testing', 'web-security', 'python'],
103
- mock: true
104
- }
105
- ];
106
-
107
- // Sample skill exchanges
108
- const sampleSkillExchanges = [
109
- {
110
- handle: 'alex_frontend',
111
- type: 'offer',
112
- skill: 'React development',
113
- details: '5+ years building complex frontend apps',
114
- category: 'technical'
115
- },
116
- {
117
- handle: 'alex_frontend',
118
- type: 'request',
119
- skill: 'backend architecture',
120
- details: 'Learning how to build scalable APIs',
121
- category: 'technical'
122
- },
123
- {
124
- handle: 'jordan_design',
125
- type: 'offer',
126
- skill: 'UI/UX design',
127
- details: 'Can help with user research and interface design',
128
- category: 'design'
129
- },
130
- {
131
- handle: 'casey_ai',
132
- type: 'request',
133
- skill: 'product strategy',
134
- details: 'Need help positioning AI tools for market',
135
- category: 'business'
136
- },
137
- {
138
- handle: 'taylor_product',
139
- type: 'offer',
140
- skill: 'product strategy',
141
- details: 'B2B product experience, market positioning',
142
- category: 'business'
143
- },
144
- {
145
- handle: 'riley_mobile',
146
- type: 'request',
147
- skill: 'UI design',
148
- details: 'App needs better visual design',
149
- category: 'design'
150
- }
151
- ];
152
-
153
- async function createSampleProfiles(count = 10, clearFirst = false) {
154
- const results = {
155
- created: 0,
156
- exchanges: 0,
157
- errors: []
158
- };
159
-
160
- try {
161
- // Clear existing profiles if requested
162
- if (clearFirst) {
163
- // Note: This would require implementing a clear function in profiles.js
164
- console.log('Clearing existing profiles...');
165
- }
166
-
167
- // Create profiles
168
- const profilesToCreate = sampleProfiles.slice(0, count);
169
-
170
- for (const profile of profilesToCreate) {
171
- try {
172
- const now = Date.now();
173
- const lastSeen = now - Math.random() * 24 * 60 * 60 * 1000; // Within last 24h
174
-
175
- await userProfiles.updateProfile(profile.handle, {
176
- building: profile.building,
177
- interests: profile.interests,
178
- tags: profile.tags,
179
- lastSeen: lastSeen,
180
- firstSeen: lastSeen - Math.random() * 7 * 24 * 60 * 60 * 1000, // Within last week
181
- mock: true
182
- });
183
-
184
- results.created++;
185
- } catch (error) {
186
- results.errors.push(`Failed to create ${profile.handle}: ${error.message}`);
187
- }
188
- }
189
-
190
- // Create skill exchange posts
191
- for (const exchange of sampleSkillExchanges.slice(0, count / 2)) {
192
- try {
193
- const post = {
194
- id: Date.now() + Math.random(),
195
- handle: exchange.handle,
196
- type: exchange.type,
197
- skill: exchange.skill,
198
- details: exchange.details,
199
- category: exchange.category,
200
- timestamp: Date.now() - Math.random() * 12 * 60 * 60 * 1000, // Within last 12h
201
- status: 'active',
202
- mock: true
203
- };
204
-
205
- await store.appendSkillExchange(post);
206
- results.exchanges++;
207
- } catch (error) {
208
- results.errors.push(`Failed to create skill exchange: ${error.message}`);
209
- }
210
- }
211
-
212
- } catch (error) {
213
- results.errors.push(`Bootstrap error: ${error.message}`);
214
- }
215
-
216
- return results;
217
- }
218
-
219
- async function handler(args) {
220
- const initCheck = requireInit();
221
- if (initCheck) return initCheck;
222
-
223
- const count = args.count || 10;
224
- const clearFirst = args.clear || false;
225
-
226
- try {
227
- const results = await createSampleProfiles(count, clearFirst);
228
-
229
- let display = `## Discovery System Bootstrapped! 🚀\n\n`;
230
-
231
- display += `**Created:**\n`;
232
- display += `• ${results.created} sample user profiles\n`;
233
- display += `• ${results.exchanges} skill exchange posts\n\n`;
234
-
235
- if (results.errors.length > 0) {
236
- display += `**Errors:**\n`;
237
- for (const error of results.errors) {
238
- display += `• ${error}\n`;
239
- }
240
- display += `\n`;
241
- }
242
-
243
- display += `**Now try:**\n`;
244
- display += `• \`workshop-buddy find\` — Find your ideal workshop partner\n`;
245
- display += `• \`skills-exchange browse\` — Browse the skill marketplace\n`;
246
- display += `• \`discover suggest\` — Get personalized recommendations\n`;
247
- display += `• \`discover interests\` — Browse by interest categories\n\n`;
248
-
249
- display += `**Sample profiles include:**\n`;
250
- display += `• Frontend + Backend developers (complementary skills)\n`;
251
- display += `• Designers seeking engineering help\n`;
252
- display += `• AI engineers needing product guidance\n`;
253
- display += `• Mobile developers wanting UI expertise\n`;
254
- display += `• DevOps + Security specialists\n\n`;
255
-
256
- display += `_These are mock profiles for testing. Real users will have richer, authentic profiles._`;
257
-
258
- return { display };
259
-
260
- } catch (error) {
261
- return {
262
- display: `## Bootstrap Error\n\n${error.message}\n\nTry: \`discovery-bootstrap --count 5\``
263
- };
264
- }
265
- }
266
-
267
- module.exports = { definition, handler };
@@ -1,375 +0,0 @@
1
- /**
2
- * Discovery Daily — Daily discovery routine and community health check
3
- *
4
- * Automated daily tasks:
5
- * - Welcome new users with connection suggestions
6
- * - Identify high-value connection opportunities
7
- * - Generate community insights
8
- * - Clean up old data
9
- * - Update trending interests/tags
10
- */
11
-
12
- const config = require('../config');
13
- const userProfiles = require('../store/profiles');
14
- const discoveryMonitor = require('./discovery-monitor');
15
- const { suggest_connection, dm_user } = require('./_actions');
16
- const { formatTimeAgo, requireInit } = require('./_shared');
17
-
18
- const definition = {
19
- name: 'vibe_discovery_daily',
20
- description: 'Run daily discovery routines and community health checks.',
21
- inputSchema: {
22
- type: 'object',
23
- properties: {
24
- action: {
25
- type: 'string',
26
- enum: ['full', 'welcome', 'insights', 'cleanup'],
27
- description: 'Which daily routine to run'
28
- }
29
- }
30
- }
31
- };
32
-
33
- // Full daily routine
34
- async function runFullDaily() {
35
- const results = {
36
- welcomesSent: 0,
37
- connectionsSuggested: 0,
38
- insights: {},
39
- cleanedProfiles: 0,
40
- errors: []
41
- };
42
-
43
- try {
44
- // 1. Welcome new users
45
- const welcomeResults = await welcomeNewUsers();
46
- results.welcomesSent = welcomeResults.welcomesSent;
47
- results.connectionsSuggested += welcomeResults.connectionsSuggested;
48
-
49
- // 2. Find high-value connections
50
- const opportunityResults = await findTodaysOpportunities();
51
- results.connectionsSuggested += opportunityResults.suggested;
52
-
53
- // 3. Generate insights
54
- results.insights = await generateDailyInsights();
55
-
56
- // 4. Cleanup old data
57
- results.cleanedProfiles = await userProfiles.cleanupOldProfiles(30);
58
-
59
- return results;
60
- } catch (error) {
61
- results.errors.push(error.message);
62
- return results;
63
- }
64
- }
65
-
66
- // Welcome new users with connection suggestions
67
- async function welcomeNewUsers() {
68
- const newUsers = await discoveryMonitor.getRecentUsers(24);
69
- let welcomesSent = 0;
70
- let connectionsSuggested = 0;
71
-
72
- for (const user of newUsers) {
73
- try {
74
- // Get welcome connections for this user
75
- const welcomeConnections = await discoveryMonitor.getWelcomeConnections(user.handle);
76
-
77
- if (welcomeConnections.length > 0) {
78
- // Send welcome message with suggestions
79
- const welcomeMsg = createWelcomeMessage(user, welcomeConnections);
80
- await dm_user(user.handle, welcomeMsg);
81
- welcomesSent++;
82
-
83
- // Make connection suggestions (max 2 per new user)
84
- for (const connection of welcomeConnections.slice(0, 2)) {
85
- await suggest_connection(user.handle, connection.handle, connection.reason);
86
- connectionsSuggested++;
87
- }
88
- } else {
89
- // Send basic welcome if no specific connections found
90
- const basicWelcome = createBasicWelcome(user);
91
- await dm_user(user.handle, basicWelcome);
92
- welcomesSent++;
93
- }
94
- } catch (error) {
95
- console.warn(`Failed to welcome ${user.handle}:`, error.message);
96
- }
97
- }
98
-
99
- return { welcomesSent, connectionsSuggested };
100
- }
101
-
102
- // Create personalized welcome message
103
- function createWelcomeMessage(user, connections) {
104
- let msg = `Welcome to /vibe, @${user.handle}! 🎉\n\n`;
105
-
106
- if (user.building) {
107
- msg += `I see you're building ${user.building} — that's exciting!\n\n`;
108
- }
109
-
110
- if (connections.length > 0) {
111
- msg += `I found some people you should definitely meet:\n\n`;
112
-
113
- for (const conn of connections.slice(0, 2)) {
114
- msg += `**@${conn.handle}** — ${conn.reason}\n`;
115
- if (conn.building) {
116
- msg += `Building: ${conn.building}\n`;
117
- }
118
- msg += `\n`;
119
- }
120
-
121
- msg += `Type \`message @handle\` to reach out, or \`discover suggest\` to see more recommendations.\n\n`;
122
- }
123
-
124
- msg += `**Getting started:**\n`;
125
- msg += `• Share what you're building: \`update building "your project"\`\n`;
126
- msg += `• Add interests: \`update interests "ai, startups, music"\`\n`;
127
- msg += `• Tag your skills: \`update tags "frontend, react, python"\`\n\n`;
128
- msg += `The more you share, the better connections I can suggest!\n\n`;
129
- msg += `Happy building! 🚀`;
130
-
131
- return msg;
132
- }
133
-
134
- // Create basic welcome for users without specific connections
135
- function createBasicWelcome(user) {
136
- let msg = `Welcome to /vibe, @${user.handle}! 🎉\n\n`;
137
-
138
- msg += `You're joining a community of builders and makers. Here's how to get connected:\n\n`;
139
-
140
- msg += `**Set up your profile:**\n`;
141
- msg += `• \`update building "what you're working on"\`\n`;
142
- msg += `• \`update interests "ai, startups, design"\`\n`;
143
- msg += `• \`update tags "frontend, python, entrepreneur"\`\n\n`;
144
-
145
- msg += `**Find your people:**\n`;
146
- msg += `• \`discover suggest\` — Get personalized recommendations\n`;
147
- msg += `• \`discover search "ai"\` — Find people by interest\n`;
148
- msg += `• \`who\` — See who's online now\n\n`;
149
-
150
- msg += `**Share your work:**\n`;
151
- msg += `• \`ship "what you completed"\` — Celebrate your progress\n`;
152
- msg += `• Join the daily builds in \`/vibe\` channel\n\n`;
153
-
154
- msg += `Looking forward to seeing what you build! 🚀`;
155
-
156
- return msg;
157
- }
158
-
159
- // Find high-value connection opportunities for today
160
- async function findTodaysOpportunities() {
161
- const opportunities = await discoveryMonitor.monitorHighValueConnections();
162
- let suggested = 0;
163
-
164
- for (const opp of opportunities) {
165
- try {
166
- // Suggest the connection to both users
167
- await suggest_connection(opp.user1, opp.user2, opp.reason);
168
- suggested++;
169
-
170
- // Optional: Send a DM to highlight the opportunity
171
- if (opp.urgency === 'both-online') {
172
- const msg = `Perfect timing! @${opp.user2} is online now and ${opp.reason.toLowerCase()}. ` +
173
- `Might be a great time to connect! 🎯`;
174
- await dm_user(opp.user1, msg);
175
- }
176
- } catch (error) {
177
- console.warn(`Failed to suggest ${opp.user1} -> ${opp.user2}:`, error.message);
178
- }
179
- }
180
-
181
- return { suggested };
182
- }
183
-
184
- // Generate daily community insights
185
- async function generateDailyInsights() {
186
- const stats = await discoveryMonitor.getConnectionStats();
187
- const trendingInterests = await userProfiles.getTrendingInterests();
188
- const trendingTags = await userProfiles.getTrendingTags();
189
-
190
- const insights = {
191
- growth: {
192
- newUsers: stats.newUsersToday,
193
- activeUsers: stats.activeUsersToday,
194
- totalUsers: stats.totalUsers,
195
- connectionsMade: stats.connectionsMadeToday
196
- },
197
- engagement: {
198
- usersWithConnections: stats.usersWithConnections,
199
- avgConnectionsPerUser: stats.avgConnectionsPerUser.toFixed(1),
200
- connectionRate: ((stats.usersWithConnections / stats.totalUsers) * 100).toFixed(1)
201
- },
202
- trends: {
203
- topInterests: trendingInterests.slice(0, 5),
204
- topTags: trendingTags.slice(0, 8)
205
- },
206
- health: calculateCommunityHealth(stats)
207
- };
208
-
209
- return insights;
210
- }
211
-
212
- // Calculate community health score
213
- function calculateCommunityHealth(stats) {
214
- let score = 0;
215
- const factors = [];
216
-
217
- // Growth factor (30 points max)
218
- if (stats.newUsersToday > 0) {
219
- score += Math.min(stats.newUsersToday * 5, 30);
220
- factors.push(`${stats.newUsersToday} new users today`);
221
- }
222
-
223
- // Activity factor (25 points max)
224
- const activityRate = stats.totalUsers > 0 ? stats.activeUsersToday / stats.totalUsers : 0;
225
- score += activityRate * 25;
226
- if (activityRate > 0.3) factors.push('High daily activity');
227
-
228
- // Connection factor (25 points max)
229
- const connectionRate = stats.totalUsers > 0 ? stats.usersWithConnections / stats.totalUsers : 0;
230
- score += connectionRate * 25;
231
- if (connectionRate > 0.5) factors.push('Good connection rate');
232
-
233
- // Engagement factor (20 points max)
234
- if (stats.connectionsMadeToday > 0) {
235
- score += Math.min(stats.connectionsMadeToday * 4, 20);
236
- factors.push(`${stats.connectionsMadeToday} connections made today`);
237
- }
238
-
239
- let level = 'Needs attention';
240
- if (score >= 80) level = 'Thriving';
241
- else if (score >= 60) level = 'Healthy';
242
- else if (score >= 40) level = 'Growing';
243
-
244
- return {
245
- score: Math.round(score),
246
- level,
247
- factors
248
- };
249
- }
250
-
251
- async function handler(args) {
252
- const initCheck = requireInit();
253
- if (initCheck) return initCheck;
254
-
255
- const action = args.action || 'full';
256
- let display = '';
257
-
258
- try {
259
- switch (action) {
260
- case 'full': {
261
- display = `## Running Daily Discovery Routine...\n\n`;
262
- const results = await runFullDaily();
263
-
264
- display += `**Community Activity:**\n`;
265
- display += `• New users welcomed: ${results.welcomesSent}\n`;
266
- display += `• Connections suggested: ${results.connectionsSuggested}\n`;
267
- if (results.cleanedProfiles > 0) {
268
- display += `• Inactive profiles cleaned: ${results.cleanedProfiles}\n`;
269
- }
270
- display += `\n`;
271
-
272
- if (results.insights.growth) {
273
- display += `**Growth Today:**\n`;
274
- display += `• New users: ${results.insights.growth.newUsers}\n`;
275
- display += `• Active users: ${results.insights.growth.activeUsers}/${results.insights.growth.totalUsers}\n`;
276
- display += `• New connections: ${results.insights.growth.connectionsMade}\n`;
277
- display += `\n`;
278
- }
279
-
280
- if (results.insights.health) {
281
- display += `**Community Health: ${results.insights.health.level}** (${results.insights.health.score}/100)\n`;
282
- if (results.insights.health.factors.length > 0) {
283
- display += `${results.insights.health.factors.join(' • ')}\n`;
284
- }
285
- display += `\n`;
286
- }
287
-
288
- if (results.insights.trends?.topInterests?.length > 0) {
289
- display += `**Trending Interests:**\n`;
290
- for (const item of results.insights.trends.topInterests) {
291
- display += `• ${item.interest} (${item.count})\n`;
292
- }
293
- display += `\n`;
294
- }
295
-
296
- if (results.errors.length > 0) {
297
- display += `**Errors:**\n`;
298
- for (const error of results.errors) {
299
- display += `• ${error}\n`;
300
- }
301
- }
302
-
303
- break;
304
- }
305
-
306
- case 'welcome': {
307
- const results = await welcomeNewUsers();
308
- display = `## Welcome Routine Complete\n\n`;
309
- display += `• Users welcomed: ${results.welcomesSent}\n`;
310
- display += `• Connection suggestions made: ${results.connectionsSuggested}\n`;
311
- break;
312
- }
313
-
314
- case 'insights': {
315
- const insights = await generateDailyInsights();
316
- display = `## Daily Community Insights\n\n`;
317
-
318
- display += `**Growth:**\n`;
319
- display += `• Total users: ${insights.growth.totalUsers}\n`;
320
- display += `• New today: ${insights.growth.newUsers}\n`;
321
- display += `• Active today: ${insights.growth.activeUsers}\n`;
322
- display += `• Connections made: ${insights.growth.connectionsMade}\n\n`;
323
-
324
- display += `**Health: ${insights.health.level}** (${insights.health.score}/100)\n`;
325
- if (insights.health.factors.length > 0) {
326
- display += `${insights.health.factors.join(' • ')}\n`;
327
- }
328
- display += `\n`;
329
-
330
- if (insights.trends.topInterests.length > 0) {
331
- display += `**Top Interests:**\n`;
332
- for (const item of insights.trends.topInterests) {
333
- display += `• ${item.interest} (${item.count})\n`;
334
- }
335
- }
336
-
337
- break;
338
- }
339
-
340
- case 'cleanup': {
341
- const cleaned = await userProfiles.cleanupOldProfiles(30);
342
- display = `## Cleanup Complete\n\n`;
343
- display += `Removed ${cleaned} inactive profiles (30+ days old)\n`;
344
- break;
345
- }
346
-
347
- default:
348
- display = `## Discovery Daily Commands
349
-
350
- **\`daily full\`** — Run complete daily routine
351
- **\`daily welcome\`** — Welcome new users only
352
- **\`daily insights\`** — Generate community insights
353
- **\`daily cleanup\`** — Clean up old profiles
354
-
355
- **Automated daily tasks:**
356
- • Welcome new users with connection suggestions
357
- • Find high-value connection opportunities
358
- • Generate community health insights
359
- • Clean up inactive profiles`;
360
- }
361
- } catch (error) {
362
- display = `## Daily Routine Error
363
-
364
- ${error.message}
365
-
366
- Try running individual routines:
367
- • \`daily welcome\` — Welcome new users
368
- • \`daily insights\` — Community insights
369
- • \`daily cleanup\` — Profile cleanup`;
370
- }
371
-
372
- return { display };
373
- }
374
-
375
- module.exports = { definition, handler };