slashvibe-mcp 0.3.20 → 0.3.21

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 (167) hide show
  1. package/README.md +47 -252
  2. package/analytics.js +107 -0
  3. package/auth-store.js +148 -0
  4. package/auto-update.js +130 -0
  5. package/bridges/bridge-monitor.js +388 -0
  6. package/bridges/discord-bot.js +431 -0
  7. package/bridges/farcaster.js +299 -0
  8. package/bridges/telegram.js +261 -0
  9. package/bridges/webhook-health.js +420 -0
  10. package/bridges/webhook-server.js +437 -0
  11. package/bridges/whatsapp.js +441 -0
  12. package/bridges/x-webhook.js +423 -0
  13. package/config.js +27 -15
  14. package/games/arcade.js +406 -0
  15. package/games/chess.js +451 -0
  16. package/games/colorguess.js +343 -0
  17. package/games/crossword-words.js +171 -0
  18. package/games/crossword.js +461 -0
  19. package/games/drawing.js +347 -0
  20. package/games/gameroulette.js +300 -0
  21. package/games/gamerouter.js +336 -0
  22. package/games/gamestatus.js +337 -0
  23. package/games/guessnumber.js +209 -0
  24. package/games/hangman.js +279 -0
  25. package/games/memory.js +338 -0
  26. package/games/multiplayer-tictactoe.js +389 -0
  27. package/games/pixelart.js +399 -0
  28. package/games/quickduel.js +354 -0
  29. package/games/riddle.js +371 -0
  30. package/games/rockpaperscissors.js +291 -0
  31. package/games/snake.js +406 -0
  32. package/games/storybuilder.js +343 -0
  33. package/games/tictactoe.js +345 -0
  34. package/games/twentyquestions.js +286 -0
  35. package/games/twotruths.js +207 -0
  36. package/games/werewolf.js +508 -0
  37. package/games/wordassociation.js +247 -0
  38. package/games/wordchain.js +135 -0
  39. package/index.js +116 -159
  40. package/intelligence/index.js +9 -2
  41. package/intelligence/interests.js +369 -0
  42. package/notification-emitter.js +77 -0
  43. package/notify.js +5 -1
  44. package/package.json +21 -16
  45. package/prompts.js +1 -1
  46. package/protocol/index.js +73 -0
  47. package/setup.js +480 -0
  48. package/smart-inbox.js +276 -0
  49. package/store/api.js +536 -215
  50. package/store/profiles.js +160 -12
  51. package/tools/_actions.js +362 -21
  52. package/tools/_discovery.js +119 -26
  53. package/tools/_shared/index.js +64 -0
  54. package/tools/_shared.js +234 -0
  55. package/tools/_work-context.js +338 -0
  56. package/tools/_work-context.manual-test.js +199 -0
  57. package/tools/_work-context.test.js +260 -0
  58. package/tools/activity.js +220 -0
  59. package/tools/analytics.js +191 -0
  60. package/tools/approve.js +197 -0
  61. package/tools/artifact-create.js +14 -3
  62. package/tools/artifacts-price.js +107 -0
  63. package/tools/available.js +120 -0
  64. package/tools/broadcast.js +325 -0
  65. package/tools/chat.js +202 -0
  66. package/tools/collaborative-drawing.js +1 -1
  67. package/tools/connection-status.js +178 -0
  68. package/tools/discover.js +350 -34
  69. package/tools/dm.js +80 -8
  70. package/tools/earnings.js +126 -0
  71. package/tools/feed.js +35 -4
  72. package/tools/follow.js +224 -0
  73. package/tools/friends.js +207 -0
  74. package/tools/gig-browse.js +206 -0
  75. package/tools/gig-complete.js +144 -0
  76. package/tools/health.js +87 -0
  77. package/tools/help.js +3 -3
  78. package/tools/idea.js +9 -2
  79. package/tools/inbox.js +289 -105
  80. package/tools/init.js +131 -34
  81. package/tools/invite.js +15 -4
  82. package/tools/leaderboard.js +117 -0
  83. package/tools/lib/git-apply.js +206 -0
  84. package/tools/lib/git-bundle.js +407 -0
  85. package/tools/migrate.js +3 -3
  86. package/tools/multiplayer-game.js +1 -1
  87. package/tools/onboarding.js +7 -7
  88. package/tools/open.js +143 -12
  89. package/tools/party-game.js +1 -1
  90. package/tools/plan.js +225 -0
  91. package/tools/proof-of-work.js +144 -0
  92. package/tools/reply.js +166 -0
  93. package/tools/report.js +1 -1
  94. package/tools/request.js +17 -3
  95. package/tools/schedule.js +367 -0
  96. package/tools/search-messages.js +123 -0
  97. package/tools/session.js +467 -0
  98. package/tools/session_price.js +128 -0
  99. package/tools/settings.js +90 -2
  100. package/tools/ship.js +30 -7
  101. package/tools/smart-check.js +201 -0
  102. package/tools/start.js +147 -12
  103. package/tools/status.js +53 -6
  104. package/tools/streak.js +147 -0
  105. package/tools/stuck.js +297 -0
  106. package/tools/subscribe.js +148 -0
  107. package/tools/subscriptions.js +134 -0
  108. package/tools/suggest-tags.js +6 -8
  109. package/tools/tag-suggestions.js +1 -1
  110. package/tools/tip.js +150 -77
  111. package/tools/token.js +4 -4
  112. package/tools/update.js +1 -1
  113. package/tools/wallet.js +221 -79
  114. package/tools/watch.js +157 -0
  115. package/tools/who.js +30 -1
  116. package/tools/withdraw.js +145 -0
  117. package/tools/work-summary.js +96 -0
  118. package/version.json +10 -8
  119. package/LICENSE +0 -21
  120. package/store/sqlite.js +0 -347
  121. /package/tools/{auto-suggest-connections.js → _deprecated/auto-suggest-connections.js} +0 -0
  122. /package/tools/{away.js → _deprecated/away.js} +0 -0
  123. /package/tools/{back.js → _deprecated/back.js} +0 -0
  124. /package/tools/{bootstrap-skills.js → _deprecated/bootstrap-skills.js} +0 -0
  125. /package/tools/{bridge-dashboard.js → _deprecated/bridge-dashboard.js} +0 -0
  126. /package/tools/{bridge-health.js → _deprecated/bridge-health.js} +0 -0
  127. /package/tools/{bridge-live.js → _deprecated/bridge-live.js} +0 -0
  128. /package/tools/{bridges.js → _deprecated/bridges.js} +0 -0
  129. /package/tools/{colorguess.js → _deprecated/colorguess.js} +0 -0
  130. /package/tools/{discover-insights.js → _deprecated/discover-insights.js} +0 -0
  131. /package/tools/{discover-momentum.js → _deprecated/discover-momentum.js} +0 -0
  132. /package/tools/{discovery-analytics.js → _deprecated/discovery-analytics.js} +0 -0
  133. /package/tools/{discovery-auto-suggest.js → _deprecated/discovery-auto-suggest.js} +0 -0
  134. /package/tools/{discovery-bootstrap.js → _deprecated/discovery-bootstrap.js} +0 -0
  135. /package/tools/{discovery-daily.js → _deprecated/discovery-daily.js} +0 -0
  136. /package/tools/{discovery-dashboard.js → _deprecated/discovery-dashboard.js} +0 -0
  137. /package/tools/{discovery-digest.js → _deprecated/discovery-digest.js} +0 -0
  138. /package/tools/{discovery-hub.js → _deprecated/discovery-hub.js} +0 -0
  139. /package/tools/{discovery-insights.js → _deprecated/discovery-insights.js} +0 -0
  140. /package/tools/{discovery-momentum.js → _deprecated/discovery-momentum.js} +0 -0
  141. /package/tools/{discovery-monitor.js → _deprecated/discovery-monitor.js} +0 -0
  142. /package/tools/{discovery-proactive.js → _deprecated/discovery-proactive.js} +0 -0
  143. /package/tools/{draw.js → _deprecated/draw.js} +0 -0
  144. /package/tools/{farcaster.js → _deprecated/farcaster.js} +0 -0
  145. /package/tools/{forget.js → _deprecated/forget.js} +0 -0
  146. /package/tools/{games-catalog.js → _deprecated/games-catalog.js} +0 -0
  147. /package/tools/{games.js → _deprecated/games.js} +0 -0
  148. /package/tools/{guessnumber.js → _deprecated/guessnumber.js} +0 -0
  149. /package/tools/{hangman.js → _deprecated/hangman.js} +0 -0
  150. /package/tools/{multiplayer-tictactoe.js → _deprecated/multiplayer-tictactoe.js} +0 -0
  151. /package/tools/{mute.js → _deprecated/mute.js} +0 -0
  152. /package/tools/{recall.js → _deprecated/recall.js} +0 -0
  153. /package/tools/{remember.js → _deprecated/remember.js} +0 -0
  154. /package/tools/{riddle.js → _deprecated/riddle.js} +0 -0
  155. /package/tools/{run-bootstrap.js → _deprecated/run-bootstrap.js} +0 -0
  156. /package/tools/{skills-analytics.js → _deprecated/skills-analytics.js} +0 -0
  157. /package/tools/{skills-bootstrap.js → _deprecated/skills-bootstrap.js} +0 -0
  158. /package/tools/{skills-dashboard.js → _deprecated/skills-dashboard.js} +0 -0
  159. /package/tools/{skills-exchange.js → _deprecated/skills-exchange.js} +0 -0
  160. /package/tools/{skills.js → _deprecated/skills.js} +0 -0
  161. /package/tools/{smart-intro.js → _deprecated/smart-intro.js} +0 -0
  162. /package/tools/{storybuilder.js → _deprecated/storybuilder.js} +0 -0
  163. /package/tools/{telegram-bot.js → _deprecated/telegram-bot.js} +0 -0
  164. /package/tools/{telegram-setup.js → _deprecated/telegram-setup.js} +0 -0
  165. /package/tools/{tictactoe.js → _deprecated/tictactoe.js} +0 -0
  166. /package/tools/{twentyquestions.js → _deprecated/twentyquestions.js} +0 -0
  167. /package/tools/{wordassociation.js → _deprecated/wordassociation.js} +0 -0
package/smart-inbox.js ADDED
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Smart Inbox Checking
3
+ *
4
+ * Intelligent notification checking that triggers at natural breaks:
5
+ * - After git commits
6
+ * - After test/build completion
7
+ * - After periods of activity (not idle)
8
+ * - On explicit check request
9
+ *
10
+ * Uses debouncing to avoid notification spam.
11
+ */
12
+
13
+ const config = require('./config');
14
+ const notify = require('./notify');
15
+ const store = require('./store');
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+
19
+ // State file for tracking check timing
20
+ const SMART_STATE_FILE = path.join(config.VIBE_DIR, '.smart_inbox_state.json');
21
+
22
+ // Timing constants
23
+ const MIN_CHECK_INTERVAL = 60 * 1000; // Minimum 1 minute between checks
24
+ const ACTIVITY_COOLDOWN = 5 * 60 * 1000; // 5 min after activity burst
25
+ const COMMIT_DELAY = 3 * 1000; // 3 second delay after commit (let it settle)
26
+ const TEST_DELAY = 2 * 1000; // 2 second delay after test
27
+ const BUILD_DELAY = 5 * 1000; // 5 second delay after build
28
+
29
+ // Trigger types
30
+ const TRIGGERS = {
31
+ COMMIT: 'commit',
32
+ TEST_PASS: 'test_pass',
33
+ TEST_FAIL: 'test_fail',
34
+ BUILD_COMPLETE: 'build_complete',
35
+ BUILD_FAIL: 'build_fail',
36
+ NATURAL_BREAK: 'natural_break',
37
+ EXPLICIT: 'explicit',
38
+ SESSION_START: 'session_start',
39
+ SESSION_END: 'session_end',
40
+ };
41
+
42
+ function loadState() {
43
+ try {
44
+ if (fs.existsSync(SMART_STATE_FILE)) {
45
+ return JSON.parse(fs.readFileSync(SMART_STATE_FILE, 'utf8'));
46
+ }
47
+ } catch (e) {}
48
+ return {
49
+ lastCheck: null,
50
+ lastTrigger: null,
51
+ checkCount: 0,
52
+ triggersToday: {},
53
+ activityBurst: null,
54
+ };
55
+ }
56
+
57
+ function saveState(state) {
58
+ try {
59
+ fs.writeFileSync(SMART_STATE_FILE, JSON.stringify(state, null, 2));
60
+ } catch (e) {}
61
+ }
62
+
63
+ /**
64
+ * Check if we should actually run a check based on timing
65
+ */
66
+ function shouldCheck(trigger) {
67
+ const state = loadState();
68
+ const now = Date.now();
69
+
70
+ // Always allow explicit checks
71
+ if (trigger === TRIGGERS.EXPLICIT) {
72
+ return { should: true, reason: 'explicit_request' };
73
+ }
74
+
75
+ // Check minimum interval
76
+ if (state.lastCheck && (now - state.lastCheck) < MIN_CHECK_INTERVAL) {
77
+ return { should: false, reason: 'too_soon', wait: MIN_CHECK_INTERVAL - (now - state.lastCheck) };
78
+ }
79
+
80
+ // Session events always trigger
81
+ if (trigger === TRIGGERS.SESSION_START || trigger === TRIGGERS.SESSION_END) {
82
+ return { should: true, reason: 'session_event' };
83
+ }
84
+
85
+ // For build/test/commit, we want them but with debounce
86
+ if ([TRIGGERS.COMMIT, TRIGGERS.TEST_PASS, TRIGGERS.TEST_FAIL,
87
+ TRIGGERS.BUILD_COMPLETE, TRIGGERS.BUILD_FAIL].includes(trigger)) {
88
+ // If same trigger happened in last 30 seconds, skip
89
+ if (state.lastTrigger === trigger && state.lastCheck && (now - state.lastCheck) < 30000) {
90
+ return { should: false, reason: 'debounced', wait: 30000 - (now - state.lastCheck) };
91
+ }
92
+ return { should: true, reason: 'event_trigger' };
93
+ }
94
+
95
+ // Natural breaks - check if there's been activity recently
96
+ if (trigger === TRIGGERS.NATURAL_BREAK) {
97
+ // If we haven't checked in 5+ minutes and there's been activity, good time
98
+ if (!state.lastCheck || (now - state.lastCheck) > ACTIVITY_COOLDOWN) {
99
+ return { should: true, reason: 'natural_break' };
100
+ }
101
+ return { should: false, reason: 'not_time_yet' };
102
+ }
103
+
104
+ return { should: true, reason: 'default' };
105
+ }
106
+
107
+ /**
108
+ * Perform smart inbox check
109
+ * Returns notification info if any
110
+ */
111
+ async function check(trigger = TRIGGERS.EXPLICIT, context = {}) {
112
+ const decision = shouldCheck(trigger);
113
+
114
+ if (!decision.should) {
115
+ return {
116
+ checked: false,
117
+ reason: decision.reason,
118
+ waitMs: decision.wait || 0,
119
+ };
120
+ }
121
+
122
+ const handle = config.getHandle();
123
+ if (!handle) {
124
+ return { checked: false, reason: 'not_initialized' };
125
+ }
126
+
127
+ const state = loadState();
128
+ const now = Date.now();
129
+
130
+ // Apply appropriate delay based on trigger
131
+ let delay = 0;
132
+ switch (trigger) {
133
+ case TRIGGERS.COMMIT:
134
+ delay = COMMIT_DELAY;
135
+ break;
136
+ case TRIGGERS.TEST_PASS:
137
+ case TRIGGERS.TEST_FAIL:
138
+ delay = TEST_DELAY;
139
+ break;
140
+ case TRIGGERS.BUILD_COMPLETE:
141
+ case TRIGGERS.BUILD_FAIL:
142
+ delay = BUILD_DELAY;
143
+ break;
144
+ }
145
+
146
+ if (delay > 0) {
147
+ await new Promise(r => setTimeout(r, delay));
148
+ }
149
+
150
+ // Run the actual notification check
151
+ let unreadCount = 0;
152
+ let notified = false;
153
+ let newUsers = [];
154
+ let newShips = [];
155
+
156
+ try {
157
+ // Get unread messages
158
+ const inbox = await store.getRawInbox(handle).catch(() => []);
159
+ unreadCount = inbox.length;
160
+
161
+ if (inbox.length > 0) {
162
+ notified = await notify.checkAndNotify(inbox);
163
+ }
164
+
165
+ // Get presence for online users
166
+ const users = await store.getActiveUsers().catch(() => []);
167
+ if (users.length > 0) {
168
+ newUsers = notify.checkPresence(users);
169
+ }
170
+
171
+ // Get ships from connections
172
+ try {
173
+ const localStore = require('./store/local');
174
+ const memories = localStore.getAllThreadMemories ? localStore.getAllThreadMemories() : {};
175
+ const memoryHandles = Object.keys(memories).map(h => h.toLowerCase());
176
+ if (memoryHandles.length > 0) {
177
+ newShips = await notify.checkShips(memoryHandles);
178
+ }
179
+ } catch (e) {
180
+ // Memory check is optional
181
+ }
182
+ } catch (e) {
183
+ // Silent fail
184
+ }
185
+
186
+ // Update state
187
+ state.lastCheck = now;
188
+ state.lastTrigger = trigger;
189
+ state.checkCount++;
190
+
191
+ // Track triggers by day
192
+ const today = new Date().toISOString().split('T')[0];
193
+ if (!state.triggersToday || state.triggersToday.date !== today) {
194
+ state.triggersToday = { date: today, counts: {} };
195
+ }
196
+ state.triggersToday.counts[trigger] = (state.triggersToday.counts[trigger] || 0) + 1;
197
+
198
+ saveState(state);
199
+
200
+ return {
201
+ checked: true,
202
+ trigger,
203
+ reason: decision.reason,
204
+ unreadCount,
205
+ notified,
206
+ newOnline: newUsers.map(u => u.handle),
207
+ newShips: newShips.map(s => s.author),
208
+ context,
209
+ timestamp: new Date().toISOString(),
210
+ };
211
+ }
212
+
213
+ /**
214
+ * Trigger after git commit
215
+ */
216
+ async function afterCommit(commitMessage = '', branch = '') {
217
+ return check(TRIGGERS.COMMIT, { commitMessage, branch });
218
+ }
219
+
220
+ /**
221
+ * Trigger after test completion
222
+ */
223
+ async function afterTest(passed = true, testOutput = '') {
224
+ const trigger = passed ? TRIGGERS.TEST_PASS : TRIGGERS.TEST_FAIL;
225
+ return check(trigger, { passed, testOutput: testOutput.slice(0, 200) });
226
+ }
227
+
228
+ /**
229
+ * Trigger after build completion
230
+ */
231
+ async function afterBuild(success = true, buildOutput = '') {
232
+ const trigger = success ? TRIGGERS.BUILD_COMPLETE : TRIGGERS.BUILD_FAIL;
233
+ return check(trigger, { success, buildOutput: buildOutput.slice(0, 200) });
234
+ }
235
+
236
+ /**
237
+ * Trigger on natural break (between tasks, file saves, etc.)
238
+ */
239
+ async function onNaturalBreak(activity = '') {
240
+ return check(TRIGGERS.NATURAL_BREAK, { activity });
241
+ }
242
+
243
+ /**
244
+ * Explicit check (user requested)
245
+ */
246
+ async function checkNow() {
247
+ return check(TRIGGERS.EXPLICIT);
248
+ }
249
+
250
+ /**
251
+ * Get check stats
252
+ */
253
+ function getStats() {
254
+ const state = loadState();
255
+ const now = Date.now();
256
+
257
+ return {
258
+ lastCheck: state.lastCheck ? new Date(state.lastCheck).toISOString() : null,
259
+ lastTrigger: state.lastTrigger,
260
+ checkCount: state.checkCount,
261
+ todayTriggers: state.triggersToday?.counts || {},
262
+ timeSinceLastCheck: state.lastCheck ? Math.floor((now - state.lastCheck) / 1000) : null,
263
+ };
264
+ }
265
+
266
+ module.exports = {
267
+ TRIGGERS,
268
+ check,
269
+ afterCommit,
270
+ afterTest,
271
+ afterBuild,
272
+ onNaturalBreak,
273
+ checkNow,
274
+ getStats,
275
+ shouldCheck,
276
+ };