@revealui/mcp 0.0.1-pre.0 → 0.1.0

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 (270) hide show
  1. package/.env.example +9 -0
  2. package/MCP_MAINTENANCE.md +265 -0
  3. package/README.md +260 -0
  4. package/__tests__/crdt.integration.test.ts +156 -0
  5. package/configs/README.md +77 -0
  6. package/configs/claude-template.json +54 -0
  7. package/dist/packages/core/src/database/ssl-config.d.ts +9 -0
  8. package/dist/packages/core/src/database/ssl-config.d.ts.map +1 -0
  9. package/dist/packages/core/src/database/ssl-config.js +8 -0
  10. package/dist/packages/core/src/database/ssl-config.js.map +1 -0
  11. package/dist/packages/core/src/features.d.ts +86 -0
  12. package/dist/packages/core/src/features.d.ts.map +1 -0
  13. package/dist/packages/core/src/features.js +93 -0
  14. package/dist/packages/core/src/features.js.map +1 -0
  15. package/dist/packages/core/src/license.d.ts +75 -0
  16. package/dist/packages/core/src/license.d.ts.map +1 -0
  17. package/dist/packages/core/src/license.js +174 -0
  18. package/dist/packages/core/src/license.js.map +1 -0
  19. package/dist/packages/core/src/monitoring/alerts.d.ts +118 -0
  20. package/dist/packages/core/src/monitoring/alerts.d.ts.map +1 -0
  21. package/dist/packages/core/src/monitoring/alerts.js +325 -0
  22. package/dist/packages/core/src/monitoring/alerts.js.map +1 -0
  23. package/dist/packages/core/src/monitoring/cleanup-manager.d.ts +71 -0
  24. package/dist/packages/core/src/monitoring/cleanup-manager.d.ts.map +1 -0
  25. package/dist/packages/core/src/monitoring/cleanup-manager.js +227 -0
  26. package/dist/packages/core/src/monitoring/cleanup-manager.js.map +1 -0
  27. package/dist/packages/core/src/monitoring/health-monitor.d.ts +22 -0
  28. package/dist/packages/core/src/monitoring/health-monitor.d.ts.map +1 -0
  29. package/dist/packages/core/src/monitoring/health-monitor.js +143 -0
  30. package/dist/packages/core/src/monitoring/health-monitor.js.map +1 -0
  31. package/dist/packages/core/src/monitoring/index.d.ts +14 -0
  32. package/dist/packages/core/src/monitoring/index.d.ts.map +1 -0
  33. package/dist/packages/core/src/monitoring/index.js +18 -0
  34. package/dist/packages/core/src/monitoring/index.js.map +1 -0
  35. package/dist/packages/core/src/monitoring/process-registry.d.ts +97 -0
  36. package/dist/packages/core/src/monitoring/process-registry.d.ts.map +1 -0
  37. package/dist/packages/core/src/monitoring/process-registry.js +223 -0
  38. package/dist/packages/core/src/monitoring/process-registry.js.map +1 -0
  39. package/dist/packages/core/src/monitoring/types.d.ts +231 -0
  40. package/dist/packages/core/src/monitoring/types.d.ts.map +1 -0
  41. package/dist/packages/core/src/monitoring/types.js +43 -0
  42. package/dist/packages/core/src/monitoring/types.js.map +1 -0
  43. package/dist/packages/core/src/monitoring/zombie-detector.d.ts +81 -0
  44. package/dist/packages/core/src/monitoring/zombie-detector.d.ts.map +1 -0
  45. package/dist/packages/core/src/monitoring/zombie-detector.js +232 -0
  46. package/dist/packages/core/src/monitoring/zombie-detector.js.map +1 -0
  47. package/dist/packages/core/src/observability/logger.d.ts +47 -0
  48. package/dist/packages/core/src/observability/logger.d.ts.map +1 -0
  49. package/dist/packages/core/src/observability/logger.js +141 -0
  50. package/dist/packages/core/src/observability/logger.js.map +1 -0
  51. package/dist/packages/core/src/utils/logger-server.d.ts +32 -0
  52. package/dist/packages/core/src/utils/logger-server.d.ts.map +1 -0
  53. package/dist/packages/core/src/utils/logger-server.js +69 -0
  54. package/dist/packages/core/src/utils/logger-server.js.map +1 -0
  55. package/dist/packages/core/src/utils/request-context.d.ts +143 -0
  56. package/dist/packages/core/src/utils/request-context.d.ts.map +1 -0
  57. package/dist/packages/core/src/utils/request-context.js +169 -0
  58. package/dist/packages/core/src/utils/request-context.js.map +1 -0
  59. package/dist/packages/dev/src/code-validator/index.d.ts +20 -0
  60. package/dist/packages/dev/src/code-validator/index.d.ts.map +1 -0
  61. package/dist/packages/dev/src/code-validator/index.js +20 -0
  62. package/dist/packages/dev/src/code-validator/index.js.map +1 -0
  63. package/dist/packages/dev/src/code-validator/types.d.ts +67 -0
  64. package/dist/packages/dev/src/code-validator/types.d.ts.map +1 -0
  65. package/dist/packages/dev/src/code-validator/types.js +7 -0
  66. package/dist/packages/dev/src/code-validator/types.js.map +1 -0
  67. package/dist/packages/dev/src/code-validator/validator.d.ts +48 -0
  68. package/dist/packages/dev/src/code-validator/validator.d.ts.map +1 -0
  69. package/dist/packages/dev/src/code-validator/validator.js +176 -0
  70. package/dist/packages/dev/src/code-validator/validator.js.map +1 -0
  71. package/dist/packages/mcp/src/adapters/db.d.ts +46 -0
  72. package/dist/packages/mcp/src/adapters/db.d.ts.map +1 -0
  73. package/dist/packages/mcp/src/adapters/db.js +127 -0
  74. package/dist/packages/mcp/src/adapters/db.js.map +1 -0
  75. package/dist/packages/mcp/src/config/index.d.ts +11 -0
  76. package/dist/packages/mcp/src/config/index.d.ts.map +1 -0
  77. package/dist/packages/mcp/src/config/index.js +18 -0
  78. package/dist/packages/mcp/src/config/index.js.map +1 -0
  79. package/dist/packages/mcp/src/contracts.d.ts +131 -0
  80. package/dist/packages/mcp/src/contracts.d.ts.map +1 -0
  81. package/dist/packages/mcp/src/contracts.js +153 -0
  82. package/dist/packages/mcp/src/contracts.js.map +1 -0
  83. package/dist/packages/mcp/src/hypervisor.d.ts +132 -0
  84. package/dist/packages/mcp/src/hypervisor.d.ts.map +1 -0
  85. package/dist/packages/mcp/src/hypervisor.js +359 -0
  86. package/dist/packages/mcp/src/hypervisor.js.map +1 -0
  87. package/dist/packages/mcp/src/index.d.ts +25 -0
  88. package/dist/packages/mcp/src/index.d.ts.map +1 -0
  89. package/dist/packages/mcp/src/index.js +41 -0
  90. package/dist/packages/mcp/src/index.js.map +1 -0
  91. package/dist/packages/mcp/src/servers/adapter.d.ts +199 -0
  92. package/dist/packages/mcp/src/servers/adapter.d.ts.map +1 -0
  93. package/dist/packages/mcp/src/servers/adapter.js +487 -0
  94. package/dist/packages/mcp/src/servers/adapter.js.map +1 -0
  95. package/dist/packages/mcp/src/servers/code-validator.d.ts +24 -0
  96. package/dist/packages/mcp/src/servers/code-validator.d.ts.map +1 -0
  97. package/dist/packages/mcp/src/servers/code-validator.js +156 -0
  98. package/dist/packages/mcp/src/servers/code-validator.js.map +1 -0
  99. package/dist/packages/mcp/src/servers/neon.d.ts +11 -0
  100. package/dist/packages/mcp/src/servers/neon.d.ts.map +1 -0
  101. package/dist/packages/mcp/src/servers/neon.js +90 -0
  102. package/dist/packages/mcp/src/servers/neon.js.map +1 -0
  103. package/dist/packages/mcp/src/servers/next-devtools.d.ts +11 -0
  104. package/dist/packages/mcp/src/servers/next-devtools.d.ts.map +1 -0
  105. package/dist/packages/mcp/src/servers/next-devtools.js +215 -0
  106. package/dist/packages/mcp/src/servers/next-devtools.js.map +1 -0
  107. package/dist/packages/mcp/src/servers/playwright.d.ts +11 -0
  108. package/dist/packages/mcp/src/servers/playwright.d.ts.map +1 -0
  109. package/dist/packages/mcp/src/servers/playwright.js +68 -0
  110. package/dist/packages/mcp/src/servers/playwright.js.map +1 -0
  111. package/dist/packages/mcp/src/servers/stripe.d.ts +11 -0
  112. package/dist/packages/mcp/src/servers/stripe.d.ts.map +1 -0
  113. package/dist/packages/mcp/src/servers/stripe.js +86 -0
  114. package/dist/packages/mcp/src/servers/stripe.js.map +1 -0
  115. package/dist/packages/mcp/src/servers/supabase.d.ts +11 -0
  116. package/dist/packages/mcp/src/servers/supabase.d.ts.map +1 -0
  117. package/dist/packages/mcp/src/servers/supabase.js +144 -0
  118. package/dist/packages/mcp/src/servers/supabase.js.map +1 -0
  119. package/dist/packages/mcp/src/servers/vercel.d.ts +11 -0
  120. package/dist/packages/mcp/src/servers/vercel.d.ts.map +1 -0
  121. package/dist/packages/mcp/src/servers/vercel.js +87 -0
  122. package/dist/packages/mcp/src/servers/vercel.js.map +1 -0
  123. package/dist/packages/mcp/src/servers/vultr-test.d.ts +3 -0
  124. package/dist/packages/mcp/src/servers/vultr-test.d.ts.map +1 -0
  125. package/dist/packages/mcp/src/servers/vultr-test.js +82 -0
  126. package/dist/packages/mcp/src/servers/vultr-test.js.map +1 -0
  127. package/dist/scripts/lib/analyzers/console-analyzer.d.ts +188 -0
  128. package/dist/scripts/lib/analyzers/console-analyzer.d.ts.map +1 -0
  129. package/dist/scripts/lib/analyzers/console-analyzer.js +432 -0
  130. package/dist/scripts/lib/analyzers/console-analyzer.js.map +1 -0
  131. package/dist/scripts/lib/analyzers/index.d.ts +11 -0
  132. package/dist/scripts/lib/analyzers/index.d.ts.map +1 -0
  133. package/dist/scripts/lib/analyzers/index.js +11 -0
  134. package/dist/scripts/lib/analyzers/index.js.map +1 -0
  135. package/dist/scripts/lib/args.d.ts +104 -0
  136. package/dist/scripts/lib/args.d.ts.map +1 -0
  137. package/dist/scripts/lib/args.js +304 -0
  138. package/dist/scripts/lib/args.js.map +1 -0
  139. package/dist/scripts/lib/cache.d.ts +185 -0
  140. package/dist/scripts/lib/cache.d.ts.map +1 -0
  141. package/dist/scripts/lib/cache.js +390 -0
  142. package/dist/scripts/lib/cache.js.map +1 -0
  143. package/dist/scripts/lib/cli/dispatch.d.ts +116 -0
  144. package/dist/scripts/lib/cli/dispatch.d.ts.map +1 -0
  145. package/dist/scripts/lib/cli/dispatch.js +206 -0
  146. package/dist/scripts/lib/cli/dispatch.js.map +1 -0
  147. package/dist/scripts/lib/cli/index.d.ts +10 -0
  148. package/dist/scripts/lib/cli/index.d.ts.map +1 -0
  149. package/dist/scripts/lib/cli/index.js +10 -0
  150. package/dist/scripts/lib/cli/index.js.map +1 -0
  151. package/dist/scripts/lib/database/ssl-config.d.ts +26 -0
  152. package/dist/scripts/lib/database/ssl-config.d.ts.map +1 -0
  153. package/dist/scripts/lib/database/ssl-config.js +47 -0
  154. package/dist/scripts/lib/database/ssl-config.js.map +1 -0
  155. package/dist/scripts/lib/errors.d.ts +218 -0
  156. package/dist/scripts/lib/errors.d.ts.map +1 -0
  157. package/dist/scripts/lib/errors.js +543 -0
  158. package/dist/scripts/lib/errors.js.map +1 -0
  159. package/dist/scripts/lib/exec.d.ts +107 -0
  160. package/dist/scripts/lib/exec.d.ts.map +1 -0
  161. package/dist/scripts/lib/exec.js +232 -0
  162. package/dist/scripts/lib/exec.js.map +1 -0
  163. package/dist/scripts/lib/index.d.ts +50 -0
  164. package/dist/scripts/lib/index.d.ts.map +1 -0
  165. package/dist/scripts/lib/index.js +65 -0
  166. package/dist/scripts/lib/index.js.map +1 -0
  167. package/dist/scripts/lib/logger.d.ts +50 -0
  168. package/dist/scripts/lib/logger.d.ts.map +1 -0
  169. package/dist/scripts/lib/logger.js +159 -0
  170. package/dist/scripts/lib/logger.js.map +1 -0
  171. package/dist/scripts/lib/output.d.ts +149 -0
  172. package/dist/scripts/lib/output.d.ts.map +1 -0
  173. package/dist/scripts/lib/output.js +263 -0
  174. package/dist/scripts/lib/output.js.map +1 -0
  175. package/dist/scripts/lib/parallel.d.ts +164 -0
  176. package/dist/scripts/lib/parallel.d.ts.map +1 -0
  177. package/dist/scripts/lib/parallel.js +355 -0
  178. package/dist/scripts/lib/parallel.js.map +1 -0
  179. package/dist/scripts/lib/paths.d.ts +92 -0
  180. package/dist/scripts/lib/paths.d.ts.map +1 -0
  181. package/dist/scripts/lib/paths.js +171 -0
  182. package/dist/scripts/lib/paths.js.map +1 -0
  183. package/dist/scripts/lib/state/adapters/memory.d.ts +42 -0
  184. package/dist/scripts/lib/state/adapters/memory.d.ts.map +1 -0
  185. package/dist/scripts/lib/state/adapters/memory.js +110 -0
  186. package/dist/scripts/lib/state/adapters/memory.js.map +1 -0
  187. package/dist/scripts/lib/state/adapters/pglite.d.ts +46 -0
  188. package/dist/scripts/lib/state/adapters/pglite.d.ts.map +1 -0
  189. package/dist/scripts/lib/state/adapters/pglite.js +256 -0
  190. package/dist/scripts/lib/state/adapters/pglite.js.map +1 -0
  191. package/dist/scripts/lib/state/index.d.ts +16 -0
  192. package/dist/scripts/lib/state/index.d.ts.map +1 -0
  193. package/dist/scripts/lib/state/index.js +16 -0
  194. package/dist/scripts/lib/state/index.js.map +1 -0
  195. package/dist/scripts/lib/state/types.d.ts +111 -0
  196. package/dist/scripts/lib/state/types.d.ts.map +1 -0
  197. package/dist/scripts/lib/state/types.js +8 -0
  198. package/dist/scripts/lib/state/types.js.map +1 -0
  199. package/dist/scripts/lib/state/workflow-state.d.ts +110 -0
  200. package/dist/scripts/lib/state/workflow-state.d.ts.map +1 -0
  201. package/dist/scripts/lib/state/workflow-state.js +331 -0
  202. package/dist/scripts/lib/state/workflow-state.js.map +1 -0
  203. package/dist/scripts/lib/telemetry.d.ts +194 -0
  204. package/dist/scripts/lib/telemetry.d.ts.map +1 -0
  205. package/dist/scripts/lib/telemetry.js +394 -0
  206. package/dist/scripts/lib/telemetry.js.map +1 -0
  207. package/dist/scripts/lib/utils.d.ts +270 -0
  208. package/dist/scripts/lib/utils.d.ts.map +1 -0
  209. package/dist/scripts/lib/utils.js +473 -0
  210. package/dist/scripts/lib/utils.js.map +1 -0
  211. package/dist/scripts/lib/validation/database.d.ts +83 -0
  212. package/dist/scripts/lib/validation/database.d.ts.map +1 -0
  213. package/dist/scripts/lib/validation/database.js +199 -0
  214. package/dist/scripts/lib/validation/database.js.map +1 -0
  215. package/dist/scripts/lib/validation/env.d.ts +80 -0
  216. package/dist/scripts/lib/validation/env.d.ts.map +1 -0
  217. package/dist/scripts/lib/validation/env.js +246 -0
  218. package/dist/scripts/lib/validation/env.js.map +1 -0
  219. package/dist/scripts/lib/validation/index.d.ts +16 -0
  220. package/dist/scripts/lib/validation/index.d.ts.map +1 -0
  221. package/dist/scripts/lib/validation/index.js +16 -0
  222. package/dist/scripts/lib/validation/index.js.map +1 -0
  223. package/dist/scripts/lib/validation/post-execution.d.ts +74 -0
  224. package/dist/scripts/lib/validation/post-execution.d.ts.map +1 -0
  225. package/dist/scripts/lib/validation/post-execution.js +110 -0
  226. package/dist/scripts/lib/validation/post-execution.js.map +1 -0
  227. package/dist/scripts/lib/validation/pre-execution.d.ts +165 -0
  228. package/dist/scripts/lib/validation/pre-execution.d.ts.map +1 -0
  229. package/dist/scripts/lib/validation/pre-execution.js +466 -0
  230. package/dist/scripts/lib/validation/pre-execution.js.map +1 -0
  231. package/dist/scripts/lib/validators/documentation-validator.d.ts +242 -0
  232. package/dist/scripts/lib/validators/documentation-validator.d.ts.map +1 -0
  233. package/dist/scripts/lib/validators/documentation-validator.js +584 -0
  234. package/dist/scripts/lib/validators/documentation-validator.js.map +1 -0
  235. package/dist/scripts/lib/validators/index.d.ts +11 -0
  236. package/dist/scripts/lib/validators/index.d.ts.map +1 -0
  237. package/dist/scripts/lib/validators/index.js +11 -0
  238. package/dist/scripts/lib/validators/index.js.map +1 -0
  239. package/docker-compose.yml +46 -0
  240. package/docs/INDEX.md +88 -0
  241. package/docs/README.md +774 -0
  242. package/docs/SETUP.md +264 -0
  243. package/docs/servers/code-validator.md +586 -0
  244. package/eslint.config.js +7 -0
  245. package/migrations/0001_add_crdt_columns.sql +8 -0
  246. package/migrations/0001_rollback.sql +6 -0
  247. package/migrations/005_performance_indexes.sql +190 -0
  248. package/migrations/backfill_crdt_meta.js +45 -0
  249. package/package.json +21 -85
  250. package/src/__tests__/hypervisor.test.ts +212 -0
  251. package/src/adapters/db.ts +180 -0
  252. package/src/config/config.json +49 -0
  253. package/src/config/index.ts +30 -0
  254. package/src/contracts.ts +221 -0
  255. package/src/hypervisor.ts +464 -0
  256. package/src/index.ts +87 -0
  257. package/src/servers/adapter.ts +643 -0
  258. package/src/servers/code-validator.ts +188 -0
  259. package/src/servers/neon.ts +103 -0
  260. package/src/servers/next-devtools.ts +230 -0
  261. package/src/servers/playwright.ts +77 -0
  262. package/src/servers/stripe.ts +99 -0
  263. package/src/servers/supabase.ts +161 -0
  264. package/src/servers/vercel.ts +100 -0
  265. package/src/servers/vultr-test.ts +97 -0
  266. package/tsconfig.json +12 -0
  267. package/vitest.config.ts +22 -0
  268. package/LICENSE +0 -202
  269. package/dist/index.js +0 -10990
  270. package/dist/index.js.map +0 -1
@@ -0,0 +1,190 @@
1
+ -- Performance Indexes Migration
2
+ -- Adds strategic indexes to improve query performance
3
+
4
+ -- ============================================================================
5
+ -- USER INDEXES
6
+ -- ============================================================================
7
+
8
+ -- Email lookup (used in authentication)
9
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_users_email
10
+ ON users(email);
11
+
12
+ -- Created at for sorting recent users
13
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_users_created_at
14
+ ON users(created_at DESC);
15
+
16
+ -- Email verification status
17
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_users_email_verified
18
+ ON users(email_verified_at)
19
+ WHERE email_verified_at IS NOT NULL;
20
+
21
+ -- ============================================================================
22
+ -- POST INDEXES
23
+ -- ============================================================================
24
+
25
+ -- Slug lookup (used in public URLs)
26
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_slug
27
+ ON posts(slug);
28
+
29
+ -- Published posts sorted by date
30
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_published_at
31
+ ON posts(published_at DESC)
32
+ WHERE published_at IS NOT NULL;
33
+
34
+ -- Author foreign key
35
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_author_id
36
+ ON posts(author_id);
37
+
38
+ -- Status filtering
39
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_status
40
+ ON posts(status);
41
+
42
+ -- Composite index for author's posts by status
43
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_author_status
44
+ ON posts(author_id, status);
45
+
46
+ -- Composite index for published posts list
47
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_published_status
48
+ ON posts(published_at DESC, status)
49
+ WHERE status = 'published';
50
+
51
+ -- Full text search on title and content
52
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_search
53
+ ON posts USING gin(to_tsvector('english', coalesce(title, '') || ' ' || coalesce(content, '')));
54
+
55
+ -- ============================================================================
56
+ -- SESSION INDEXES
57
+ -- ============================================================================
58
+
59
+ -- Token lookup (used in authentication)
60
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sessions_token
61
+ ON sessions(token);
62
+
63
+ -- User sessions lookup
64
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sessions_user_id
65
+ ON sessions(user_id);
66
+
67
+ -- Expiration cleanup
68
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sessions_expires_at
69
+ ON sessions(expires_at);
70
+
71
+ -- Active sessions by user
72
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sessions_user_active
73
+ ON sessions(user_id, expires_at)
74
+ WHERE expires_at > NOW();
75
+
76
+ -- ============================================================================
77
+ -- COMMENT INDEXES (if comments table exists)
78
+ -- ============================================================================
79
+
80
+ -- Post comments lookup
81
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_comments_post_id
82
+ ON comments(post_id)
83
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'comments');
84
+
85
+ -- Author comments lookup
86
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_comments_author_id
87
+ ON comments(author_id)
88
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'comments');
89
+
90
+ -- Approved comments
91
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_comments_approved
92
+ ON comments(approved_at, created_at DESC)
93
+ WHERE approved_at IS NOT NULL
94
+ AND EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'comments');
95
+
96
+ -- ============================================================================
97
+ -- CATEGORY/TAG INDEXES (if exists)
98
+ -- ============================================================================
99
+
100
+ -- Category slug lookup
101
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_categories_slug
102
+ ON categories(slug)
103
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'categories');
104
+
105
+ -- Tag slug lookup
106
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tags_slug
107
+ ON tags(slug)
108
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'tags');
109
+
110
+ -- Post-Tag junction table
111
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_post_tags_post_id
112
+ ON post_tags(post_id)
113
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'post_tags');
114
+
115
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_post_tags_tag_id
116
+ ON post_tags(tag_id)
117
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'post_tags');
118
+
119
+ -- ============================================================================
120
+ -- MEDIA/ASSETS INDEXES (if exists)
121
+ -- ============================================================================
122
+
123
+ -- Media type lookup
124
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_media_type
125
+ ON media(type)
126
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'media');
127
+
128
+ -- Media owner lookup
129
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_media_user_id
130
+ ON media(user_id)
131
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'media');
132
+
133
+ -- ============================================================================
134
+ -- ANALYTICS/METRICS INDEXES (if exists)
135
+ -- ============================================================================
136
+
137
+ -- Page views by date range
138
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_analytics_created_at
139
+ ON analytics(created_at DESC)
140
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'analytics');
141
+
142
+ -- Page views by resource
143
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_analytics_resource
144
+ ON analytics(resource_type, resource_id)
145
+ WHERE EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'analytics');
146
+
147
+ -- ============================================================================
148
+ -- VERIFICATION
149
+ -- ============================================================================
150
+
151
+ -- View all indexes
152
+ -- SELECT
153
+ -- schemaname,
154
+ -- tablename,
155
+ -- indexname,
156
+ -- indexdef
157
+ -- FROM pg_indexes
158
+ -- WHERE schemaname = 'public'
159
+ -- ORDER BY tablename, indexname;
160
+
161
+ -- Check index usage
162
+ -- SELECT
163
+ -- schemaname,
164
+ -- tablename,
165
+ -- indexname,
166
+ -- idx_scan as index_scans,
167
+ -- idx_tup_read as tuples_read,
168
+ -- idx_tup_fetch as tuples_fetched
169
+ -- FROM pg_stat_user_indexes
170
+ -- ORDER BY idx_scan DESC;
171
+
172
+ -- Find unused indexes
173
+ -- SELECT
174
+ -- schemaname,
175
+ -- tablename,
176
+ -- indexname,
177
+ -- idx_scan
178
+ -- FROM pg_stat_user_indexes
179
+ -- WHERE idx_scan = 0
180
+ -- AND indexname NOT LIKE 'pg_toast%'
181
+ -- ORDER BY tablename, indexname;
182
+
183
+ -- Check index sizes
184
+ -- SELECT
185
+ -- schemaname,
186
+ -- tablename,
187
+ -- indexname,
188
+ -- pg_size_pretty(pg_relation_size(indexrelid)) as index_size
189
+ -- FROM pg_stat_user_indexes
190
+ -- ORDER BY pg_relation_size(indexrelid) DESC;
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ Backfill script to populate `_electric_meta` columns where NULL.
4
+ Usage: ELECTRIC_DATABASE_URL=postgres://... node backfill_crdt_meta.js
5
+ */
6
+
7
+ const { Client } = require('pg')
8
+ const { logger } = require('@revealui/core/observability/logger')
9
+
10
+ async function main() {
11
+ const url = process.env.ELECTRIC_DATABASE_URL || process.env.DATABASE_URL
12
+ if (!url) {
13
+ logger.error(
14
+ 'Set ELECTRIC_DATABASE_URL or DATABASE_URL before running.',
15
+ new Error('Missing database URL'),
16
+ )
17
+ process.exit(1)
18
+ }
19
+
20
+ const client = new Client({ connectionString: url })
21
+ await client.connect()
22
+
23
+ try {
24
+ logger.info('Backfilling documents._electric_meta where null...')
25
+ await client.query(
26
+ "UPDATE documents SET _electric_meta = '{}'::jsonb WHERE _electric_meta IS NULL",
27
+ )
28
+
29
+ logger.info('Backfilling subscription_state._electric_meta where null...')
30
+ await client.query(
31
+ "UPDATE subscription_state SET _electric_meta = '{}'::jsonb WHERE _electric_meta IS NULL",
32
+ )
33
+
34
+ logger.info('Backfill complete.')
35
+ } catch (err) {
36
+ logger.error('Backfill failed', err instanceof Error ? err : new Error(String(err)))
37
+ process.exitCode = 1
38
+ } finally {
39
+ await client.end()
40
+ }
41
+ }
42
+
43
+ if (require.main === module) {
44
+ main()
45
+ }
package/package.json CHANGED
@@ -1,96 +1,32 @@
1
1
  {
2
2
  "name": "@revealui/mcp",
3
- "version": "0.0.1-pre.0",
4
- "description": "Reveal MCP - Unified Model Context Protocol implementation for multi-agent systems and PayloadCMS integration",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./dist/index.d.ts",
12
- "import": "./dist/index.js"
13
- },
14
- "./server": {
15
- "types": "./dist/server/index.d.ts",
16
- "import": "./dist/server/index.js"
17
- },
18
- "./agents": {
19
- "types": "./dist/agents/index.d.ts",
20
- "import": "./dist/agents/index.js"
21
- },
22
- "./tools": {
23
- "types": "./dist/tools/index.d.ts",
24
- "import": "./dist/tools/index.js"
25
- },
26
- "./analytics": {
27
- "types": "./dist/analytics/index.d.ts",
28
- "import": "./dist/analytics/index.js"
29
- },
30
- "./analytics/server": {
31
- "types": "./dist/analytics/server.d.ts",
32
- "import": "./dist/analytics/server.js"
33
- },
34
- "./bridge/PayloadMCPService": {
35
- "types": "./dist/bridge/PayloadMCPService.d.ts",
36
- "import": "./dist/bridge/PayloadMCPService.js"
37
- }
38
- },
39
- "files": [
40
- "dist",
41
- "README.md",
42
- "LICENSE",
43
- "CHANGELOG.md"
44
- ],
45
- "keywords": [
46
- "mcp",
47
- "model-context-protocol",
48
- "multi-agent",
49
- "payloadcms",
50
- "ai",
51
- "agents",
52
- "tools",
53
- "reveal"
54
- ],
55
- "license": "MIT",
56
- "publishable": true,
57
- "author": "RevealUI Team",
58
- "repository": {
59
- "type": "git",
60
- "url": "https://github.com/RevealUIStudio/reveal.git",
61
- "directory": "packages/mcp"
62
- },
63
- "bugs": {
64
- "url": "https://github.com/RevealUIStudio/reveal/issues"
65
- },
66
- "homepage": "https://revealui.com",
67
- "publishConfig": {
68
- "access": "public"
69
- },
3
+ "version": "0.1.0",
4
+ "license": "SEE LICENSE IN ../../LICENSE.commercial",
70
5
  "dependencies": {
71
- "@revealui/core": "^0.0.1-pre.0",
72
- "@libsql/client": "^0.15.15",
73
- "@revealui/infrastructure": "0.0.1-pre.0"
6
+ "@modelcontextprotocol/sdk": "^1.26.0",
7
+ "dotenv": "^17.2.4",
8
+ "@revealui/config": "0.2.0",
9
+ "@revealui/contracts": "1.0.0",
10
+ "@revealui/scripts": "0.1.0",
11
+ "@revealui/core": "0.2.0"
74
12
  },
75
13
  "devDependencies": {
76
- "@types/node": "^22.10.5",
77
- "@types/react": "^19.2.2",
14
+ "@electric-sql/pglite": "^0.3.15",
15
+ "pg": "^8.18.0",
78
16
  "typescript": "^5.9.3",
79
- "vitest": "^4.0.14",
80
- "rimraf": "^6.1.2",
81
- "tsup": "^8.3.5"
82
- },
83
- "peerDependencies": {
84
- "payload": ">=3.60.0 <4",
85
- "react": "^19.0.0"
17
+ "vitest": "^4.0.18"
86
18
  },
87
- "engines": {
88
- "node": ">=22.0.0"
19
+ "type": "module",
20
+ "publishConfig": {
21
+ "registry": "https://registry.npmjs.org",
22
+ "access": "public"
89
23
  },
90
24
  "scripts": {
91
- "build": "pnpm exec tsup",
92
- "clean": "rm -rf dist .tsbuildinfo",
93
- "typecheck": "tsc -p tsconfig.json --noEmit",
94
- "test": "vitest run"
25
+ "build": "tsc",
26
+ "clean": "rm -rf dist",
27
+ "dev": "tsc --watch",
28
+ "lint": "biome check .",
29
+ "test": "vitest run",
30
+ "typecheck": "tsc --noEmit"
95
31
  }
96
32
  }
@@ -0,0 +1,212 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { MCPHypervisor, type MCPServerConfig } from '../hypervisor.js'
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // Mocks
6
+ // ---------------------------------------------------------------------------
7
+
8
+ vi.mock('@revealui/core/monitoring', () => ({
9
+ registerCleanupHandler: vi.fn(),
10
+ }))
11
+
12
+ vi.mock('@revealui/core/observability/logger', () => ({
13
+ logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
14
+ }))
15
+
16
+ // Mock child_process.spawn
17
+ const mockProcess = {
18
+ pid: 12345,
19
+ exitCode: null as number | null,
20
+ stdin: { write: vi.fn() },
21
+ stdout: { on: vi.fn() },
22
+ stderr: { on: vi.fn() },
23
+ on: vi.fn(),
24
+ kill: vi.fn(),
25
+ }
26
+
27
+ vi.mock('node:child_process', () => ({
28
+ spawn: vi.fn(() => mockProcess),
29
+ }))
30
+
31
+ // ---------------------------------------------------------------------------
32
+ // Helpers
33
+ // ---------------------------------------------------------------------------
34
+
35
+ const testConfig: MCPServerConfig = {
36
+ name: 'test-server',
37
+ command: 'node',
38
+ args: ['test-mcp-server.js'],
39
+ }
40
+
41
+ // ---------------------------------------------------------------------------
42
+ // Tests
43
+ // ---------------------------------------------------------------------------
44
+
45
+ describe('MCPHypervisor', () => {
46
+ beforeEach(() => {
47
+ MCPHypervisor._resetForTests()
48
+ mockProcess.exitCode = null
49
+ mockProcess.stdin.write.mockClear()
50
+ mockProcess.stdout.on.mockClear()
51
+ mockProcess.stderr.on.mockClear()
52
+ mockProcess.on.mockClear()
53
+ mockProcess.kill.mockClear()
54
+ })
55
+
56
+ afterEach(() => {
57
+ MCPHypervisor._resetForTests()
58
+ vi.clearAllMocks()
59
+ })
60
+
61
+ describe('getInstance()', () => {
62
+ it('returns a singleton', () => {
63
+ const a = MCPHypervisor.getInstance()
64
+ const b = MCPHypervisor.getInstance()
65
+ expect(a).toBe(b)
66
+ })
67
+ })
68
+
69
+ describe('registerServer()', () => {
70
+ it('registers a server config', () => {
71
+ const hv = MCPHypervisor.getInstance()
72
+ hv.registerServer(testConfig)
73
+
74
+ const status = hv.getStatus()
75
+ expect(status['test-server']).toMatchObject({
76
+ healthy: false,
77
+ toolCount: 0,
78
+ pid: null,
79
+ })
80
+ })
81
+
82
+ it('ignores duplicate registrations', () => {
83
+ const hv = MCPHypervisor.getInstance()
84
+ hv.registerServer(testConfig)
85
+ hv.registerServer(testConfig) // duplicate — no throw
86
+
87
+ const status = hv.getStatus()
88
+ expect(Object.keys(status)).toHaveLength(1)
89
+ })
90
+ })
91
+
92
+ describe('getAllTools()', () => {
93
+ it('returns empty array when no servers are healthy', () => {
94
+ const hv = MCPHypervisor.getInstance()
95
+ hv.registerServer(testConfig)
96
+
97
+ expect(hv.getAllTools()).toHaveLength(0)
98
+ })
99
+
100
+ it('returns namespaced tools from healthy servers', () => {
101
+ const hv = MCPHypervisor.getInstance()
102
+ hv.registerServer(testConfig)
103
+
104
+ // Directly inject tools into the server entry via internal state
105
+ // (bypasses spawn for unit testing)
106
+ // Access private state via type cast — for testing only
107
+ const servers = (
108
+ hv as unknown as { servers: Map<string, { healthy: boolean; tools: unknown[] }> }
109
+ ).servers
110
+ const entry = servers.get('test-server')!
111
+ entry.healthy = true
112
+ entry.tools = [
113
+ {
114
+ name: 'create_payment',
115
+ description: 'Create a payment',
116
+ inputSchema: { type: 'object' as const, properties: {}, required: [] },
117
+ },
118
+ {
119
+ name: 'list_payments',
120
+ description: 'List payments',
121
+ inputSchema: { type: 'object' as const, properties: {}, required: [] },
122
+ },
123
+ ]
124
+
125
+ const tools = hv.getAllTools()
126
+
127
+ expect(tools).toHaveLength(2)
128
+ expect(tools[0]?.namespacedName).toBe('@@mcp_test-server_create_payment')
129
+ expect(tools[1]?.namespacedName).toBe('@@mcp_test-server_list_payments')
130
+ expect(tools[0]?.serverName).toBe('test-server')
131
+ })
132
+
133
+ it('skips unhealthy servers', () => {
134
+ const hv = MCPHypervisor.getInstance()
135
+ hv.registerServer(testConfig)
136
+
137
+ const servers = (
138
+ hv as unknown as { servers: Map<string, { healthy: boolean; tools: unknown[] }> }
139
+ ).servers
140
+ const entry = servers.get('test-server')!
141
+ entry.healthy = false
142
+ entry.tools = [
143
+ { name: 'some_tool', description: '', inputSchema: { type: 'object' as const } },
144
+ ]
145
+
146
+ expect(hv.getAllTools()).toHaveLength(0)
147
+ })
148
+
149
+ it('namespaces tools from multiple healthy servers', () => {
150
+ const hv = MCPHypervisor.getInstance()
151
+ hv.registerServer({ name: 'stripe', command: 'node', args: [] })
152
+ hv.registerServer({ name: 'vercel', command: 'node', args: [] })
153
+
154
+ const servers = (
155
+ hv as unknown as { servers: Map<string, { healthy: boolean; tools: unknown[] }> }
156
+ ).servers
157
+
158
+ const stripe = servers.get('stripe')!
159
+ stripe.healthy = true
160
+ stripe.tools = [{ name: 'charge', description: '', inputSchema: { type: 'object' as const } }]
161
+
162
+ const vercel = servers.get('vercel')!
163
+ vercel.healthy = true
164
+ vercel.tools = [{ name: 'deploy', description: '', inputSchema: { type: 'object' as const } }]
165
+
166
+ const tools = hv.getAllTools()
167
+ const names = tools.map((t) => t.namespacedName)
168
+
169
+ expect(names).toContain('@@mcp_stripe_charge')
170
+ expect(names).toContain('@@mcp_vercel_deploy')
171
+ })
172
+ })
173
+
174
+ describe('pingServer()', () => {
175
+ it('returns false for unknown server', async () => {
176
+ const hv = MCPHypervisor.getInstance()
177
+ const result = await hv.pingServer('nonexistent')
178
+ expect(result).toBe(false)
179
+ })
180
+
181
+ it('returns false when process is not running', async () => {
182
+ const hv = MCPHypervisor.getInstance()
183
+ hv.registerServer(testConfig)
184
+
185
+ const result = await hv.pingServer('test-server')
186
+ expect(result).toBe(false)
187
+ })
188
+ })
189
+
190
+ describe('getStatus()', () => {
191
+ it('reflects registered servers', () => {
192
+ const hv = MCPHypervisor.getInstance()
193
+ hv.registerServer({ name: 'alpha', command: 'node', args: [] })
194
+ hv.registerServer({ name: 'beta', command: 'node', args: [] })
195
+
196
+ const status = hv.getStatus()
197
+ expect(Object.keys(status)).toHaveLength(2)
198
+ expect(status['alpha']?.healthy).toBe(false)
199
+ expect(status['beta']?.healthy).toBe(false)
200
+ })
201
+ })
202
+
203
+ describe('unregisterServer()', () => {
204
+ it('removes a registered server', async () => {
205
+ const hv = MCPHypervisor.getInstance()
206
+ hv.registerServer(testConfig)
207
+ await hv.unregisterServer('test-server')
208
+
209
+ expect(hv.getStatus()).not.toHaveProperty('test-server')
210
+ })
211
+ })
212
+ })