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
@@ -0,0 +1,20 @@
1
+ // Test the skills bootstrap functionality
2
+ const skillsBootstrap = require('./tools/skills-bootstrap.js');
3
+
4
+ async function testBootstrap() {
5
+ try {
6
+ console.log('Testing skills bootstrap...');
7
+
8
+ // Check status first
9
+ const statusResult = await skillsBootstrap.handler({ action: 'status' });
10
+ console.log('Status check:', statusResult);
11
+
12
+ // Seed the marketplace
13
+ const seedResult = await skillsBootstrap.handler({ action: 'seed' });
14
+ console.log('Seed result:', seedResult);
15
+ } catch (error) {
16
+ console.error('Bootstrap test failed:', error);
17
+ }
18
+ }
19
+
20
+ testBootstrap();
@@ -0,0 +1,385 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * V2 Postgres Integration Test Suite
4
+ *
5
+ * Tests the complete message flow:
6
+ * 1. SQLite schema validation
7
+ * 2. Message saving (optimistic UI)
8
+ * 3. thread_id extraction from V2 API
9
+ * 4. Message status updates
10
+ * 5. Thread retrieval
11
+ *
12
+ * Run: node test-v2-integration.js
13
+ */
14
+
15
+ const Database = require('better-sqlite3');
16
+ const path = require('path');
17
+ const os = require('os');
18
+ const sqlite = require('./store/sqlite');
19
+
20
+ const DB_PATH = path.join(os.homedir(), '.vibecodings', 'sessions.db');
21
+
22
+ class V2IntegrationTest {
23
+ constructor() {
24
+ this.db = new Database(DB_PATH);
25
+ this.results = {
26
+ passed: [],
27
+ failed: [],
28
+ warnings: []
29
+ };
30
+ }
31
+
32
+ log(emoji, message) {
33
+ console.log(`${emoji} ${message}`);
34
+ }
35
+
36
+ pass(test, details = '') {
37
+ this.results.passed.push({ test, details });
38
+ this.log('✅', `${test}${details ? ': ' + details : ''}`);
39
+ }
40
+
41
+ fail(test, error) {
42
+ this.results.failed.push({ test, error });
43
+ this.log('❌', `${test}: ${error}`);
44
+ }
45
+
46
+ warn(test, message) {
47
+ this.results.warnings.push({ test, message });
48
+ this.log('⚠️', `${test}: ${message}`);
49
+ }
50
+
51
+ // Test 1: Schema Validation
52
+ testSchema() {
53
+ this.log('🔍', 'Test 1: Validating SQLite schema...');
54
+
55
+ const columns = this.db.prepare('PRAGMA table_info(messages)').all();
56
+ const columnNames = columns.map(c => c.name);
57
+
58
+ const requiredColumns = [
59
+ 'local_id',
60
+ 'server_id',
61
+ 'thread_id', // V2 requirement
62
+ 'from_handle',
63
+ 'to_handle',
64
+ 'content',
65
+ 'created_at',
66
+ 'status',
67
+ 'sent_at',
68
+ 'delivered_at',
69
+ 'read_at',
70
+ 'synced_at',
71
+ 'retry_count'
72
+ ];
73
+
74
+ const missing = requiredColumns.filter(col => !columnNames.includes(col));
75
+
76
+ if (missing.length > 0) {
77
+ this.fail('Schema validation', `Missing columns: ${missing.join(', ')}`);
78
+ return false;
79
+ }
80
+
81
+ this.pass('Schema validation', `All ${requiredColumns.length} columns present`);
82
+
83
+ // Check indexes
84
+ const indexes = this.db.prepare("SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='messages'").all();
85
+ const indexNames = indexes.map(i => i.name);
86
+
87
+ if (!indexNames.includes('idx_messages_thread_id')) {
88
+ this.warn('Index check', 'idx_messages_thread_id missing');
89
+ } else {
90
+ this.pass('Index check', 'thread_id index exists');
91
+ }
92
+
93
+ return true;
94
+ }
95
+
96
+ // Test 2: Message Saving (Optimistic UI)
97
+ testMessageSaving() {
98
+ this.log('🔍', 'Test 2: Testing optimistic message save...');
99
+
100
+ const testMessage = {
101
+ from_handle: 'test_alice',
102
+ to_handle: 'test_bob',
103
+ content: 'Test message for V2 integration',
104
+ status: 'pending'
105
+ };
106
+
107
+ try {
108
+ const local_id = sqlite.saveLocalMessage(testMessage);
109
+
110
+ if (!local_id) {
111
+ this.fail('Message saving', 'No local_id returned');
112
+ return null;
113
+ }
114
+
115
+ // Verify it was saved
116
+ const saved = this.db.prepare('SELECT * FROM messages WHERE local_id = ?').get(local_id);
117
+
118
+ if (!saved) {
119
+ this.fail('Message saving', 'Message not found after save');
120
+ return null;
121
+ }
122
+
123
+ if (saved.status !== 'pending') {
124
+ this.fail('Message saving', `Expected status 'pending', got '${saved.status}'`);
125
+ return null;
126
+ }
127
+
128
+ this.pass('Message saving', `Saved with local_id: ${local_id.slice(0, 12)}...`);
129
+ return local_id;
130
+ } catch (error) {
131
+ this.fail('Message saving', error.message);
132
+ return null;
133
+ }
134
+ }
135
+
136
+ // Test 3: Status Update with thread_id
137
+ testStatusUpdate(local_id) {
138
+ if (!local_id) {
139
+ this.warn('Status update', 'Skipped (no local_id from previous test)');
140
+ return;
141
+ }
142
+
143
+ this.log('🔍', 'Test 3: Testing status update with thread_id...');
144
+
145
+ try {
146
+ // Simulate V2 API response with server_id and thread_id
147
+ const server_id = 'msg_test_' + Date.now();
148
+ const thread_id = 'thread_test_' + Date.now();
149
+
150
+ sqlite.updateMessageStatus(local_id, 'sent', server_id, thread_id);
151
+
152
+ // Verify update
153
+ const updated = this.db.prepare('SELECT * FROM messages WHERE local_id = ?').get(local_id);
154
+
155
+ if (updated.status !== 'sent') {
156
+ this.fail('Status update', `Expected status 'sent', got '${updated.status}'`);
157
+ return;
158
+ }
159
+
160
+ if (updated.server_id !== server_id) {
161
+ this.fail('Status update', `server_id mismatch`);
162
+ return;
163
+ }
164
+
165
+ if (updated.thread_id !== thread_id) {
166
+ this.fail('Status update', `thread_id not saved correctly`);
167
+ return;
168
+ }
169
+
170
+ if (!updated.sent_at) {
171
+ this.warn('Status update', 'sent_at timestamp not set');
172
+ }
173
+
174
+ this.pass('Status update', `Status: ${updated.status}, thread_id: ${thread_id.slice(0, 20)}...`);
175
+ } catch (error) {
176
+ this.fail('Status update', error.message);
177
+ }
178
+ }
179
+
180
+ // Test 4: Thread Retrieval
181
+ testThreadRetrieval() {
182
+ this.log('🔍', 'Test 4: Testing thread retrieval...');
183
+
184
+ try {
185
+ const messages = sqlite.getThreadMessages('test_alice', 'test_bob', 100);
186
+
187
+ if (!Array.isArray(messages)) {
188
+ this.fail('Thread retrieval', 'Did not return an array');
189
+ return;
190
+ }
191
+
192
+ if (messages.length === 0) {
193
+ this.warn('Thread retrieval', 'No messages found (expected from test 2)');
194
+ return;
195
+ }
196
+
197
+ const msg = messages[0];
198
+
199
+ // Check that thread_id is included
200
+ if (msg.thread_id === undefined) {
201
+ this.fail('Thread retrieval', 'Message missing thread_id field');
202
+ return;
203
+ }
204
+
205
+ this.pass('Thread retrieval', `Retrieved ${messages.length} message(s) with thread_id`);
206
+ } catch (error) {
207
+ this.fail('Thread retrieval', error.message);
208
+ }
209
+ }
210
+
211
+ // Test 5: Merge Server Messages (V2 format)
212
+ testMergeServerMessages() {
213
+ this.log('🔍', 'Test 5: Testing server message merge with V2 format...');
214
+
215
+ const v2Messages = [
216
+ {
217
+ id: 'msg_server_001',
218
+ thread_id: 'thread_xyz',
219
+ from: 'server_alice',
220
+ to: 'server_bob',
221
+ body: 'Server message 1',
222
+ created_at: new Date().toISOString()
223
+ },
224
+ {
225
+ id: 'msg_server_002',
226
+ thread_id: 'thread_xyz',
227
+ from: 'server_bob',
228
+ to: 'server_alice',
229
+ body: 'Server message 2',
230
+ created_at: new Date().toISOString()
231
+ }
232
+ ];
233
+
234
+ try {
235
+ const merged = sqlite.mergeServerMessages(v2Messages);
236
+
237
+ if (merged !== v2Messages.length) {
238
+ this.fail('Server message merge', `Expected ${v2Messages.length} merged, got ${merged}`);
239
+ return;
240
+ }
241
+
242
+ // Verify messages were saved with thread_id
243
+ const saved = this.db
244
+ .prepare(
245
+ `
246
+ SELECT * FROM messages
247
+ WHERE server_id IN ('msg_server_001', 'msg_server_002')
248
+ ORDER BY created_at
249
+ `
250
+ )
251
+ .all();
252
+
253
+ if (saved.length !== 2) {
254
+ this.fail('Server message merge', `Expected 2 messages, found ${saved.length}`);
255
+ return;
256
+ }
257
+
258
+ // Check thread_id was preserved
259
+ const threadIds = saved.map(m => m.thread_id);
260
+ if (!threadIds.every(id => id === 'thread_xyz')) {
261
+ this.fail('Server message merge', 'thread_id not preserved correctly');
262
+ return;
263
+ }
264
+
265
+ this.pass('Server message merge', `Merged ${merged} V2 messages with thread_id`);
266
+ } catch (error) {
267
+ this.fail('Server message merge', error.message);
268
+ }
269
+ }
270
+
271
+ // Test 6: Code Review - Check api.js integration
272
+ testCodeIntegration() {
273
+ this.log('🔍', 'Test 6: Code integration check...');
274
+
275
+ const apiCode = require('fs').readFileSync('./store/api.js', 'utf-8');
276
+
277
+ // Check 1: sendMessage saves to SQLite
278
+ if (!apiCode.includes('sqlite.saveLocalMessage')) {
279
+ this.fail('Code integration', 'api.js missing sqlite.saveLocalMessage call');
280
+ return;
281
+ }
282
+
283
+ // Check 2: sendMessage updates status with thread_id
284
+ if (!apiCode.includes('sqlite.updateMessageStatus')) {
285
+ this.fail('Code integration', 'api.js missing sqlite.updateMessageStatus call');
286
+ return;
287
+ }
288
+
289
+ // Check 3: thread_id extraction from V2 response
290
+ if (!apiCode.includes('thread_id')) {
291
+ this.fail('Code integration', 'api.js not extracting thread_id from response');
292
+ return;
293
+ }
294
+
295
+ // Check 4: getThread uses sqlite
296
+ if (!apiCode.includes('sqlite.getThreadMessages')) {
297
+ this.fail('Code integration', 'api.js getThread not using SQLite');
298
+ return;
299
+ }
300
+
301
+ // Check 5: getInbox uses sqlite
302
+ if (!apiCode.includes('sqlite.getInboxThreads')) {
303
+ this.warn('Code integration', 'api.js getInbox might not be using SQLite optimally');
304
+ }
305
+
306
+ this.pass('Code integration', 'All critical V2 integration points found in api.js');
307
+ }
308
+
309
+ // Cleanup test data
310
+ cleanup() {
311
+ this.log('🧹', 'Cleaning up test data...');
312
+
313
+ try {
314
+ this.db.exec(`
315
+ DELETE FROM messages
316
+ WHERE from_handle LIKE 'test_%'
317
+ OR from_handle LIKE 'server_%'
318
+ OR to_handle LIKE 'test_%'
319
+ OR to_handle LIKE 'server_%'
320
+ `);
321
+ this.pass('Cleanup', 'Test data removed');
322
+ } catch (error) {
323
+ this.warn('Cleanup', error.message);
324
+ }
325
+ }
326
+
327
+ // Run all tests
328
+ async runAll() {
329
+ console.log('\n════════════════════════════════════════════════════════');
330
+ console.log(' V2 Postgres Integration Test Suite');
331
+ console.log('════════════════════════════════════════════════════════\n');
332
+
333
+ // Run tests
334
+ const schemaOk = this.testSchema();
335
+
336
+ if (schemaOk) {
337
+ const local_id = this.testMessageSaving();
338
+ this.testStatusUpdate(local_id);
339
+ this.testThreadRetrieval();
340
+ this.testMergeServerMessages();
341
+ }
342
+
343
+ this.testCodeIntegration();
344
+ this.cleanup();
345
+
346
+ // Print summary
347
+ console.log('\n════════════════════════════════════════════════════════');
348
+ console.log(' Test Summary');
349
+ console.log('════════════════════════════════════════════════════════\n');
350
+
351
+ console.log(`✅ Passed: ${this.results.passed.length}`);
352
+ console.log(`❌ Failed: ${this.results.failed.length}`);
353
+ console.log(`⚠️ Warnings: ${this.results.warnings.length}`);
354
+
355
+ if (this.results.failed.length > 0) {
356
+ console.log('\n❌ Failed Tests:');
357
+ this.results.failed.forEach(({ test, error }) => {
358
+ console.log(` - ${test}: ${error}`);
359
+ });
360
+ }
361
+
362
+ if (this.results.warnings.length > 0) {
363
+ console.log('\n⚠️ Warnings:');
364
+ this.results.warnings.forEach(({ test, message }) => {
365
+ console.log(` - ${test}: ${message}`);
366
+ });
367
+ }
368
+
369
+ console.log('\n════════════════════════════════════════════════════════\n');
370
+
371
+ // Close database
372
+ this.db.close();
373
+
374
+ // Exit with appropriate code
375
+ process.exit(this.results.failed.length > 0 ? 1 : 0);
376
+ }
377
+ }
378
+
379
+ // Run tests
380
+ if (require.main === module) {
381
+ const test = new V2IntegrationTest();
382
+ test.runAll();
383
+ }
384
+
385
+ module.exports = V2IntegrationTest;