@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.
- package/.env.example +9 -0
- package/MCP_MAINTENANCE.md +265 -0
- package/README.md +260 -0
- package/__tests__/crdt.integration.test.ts +156 -0
- package/configs/README.md +77 -0
- package/configs/claude-template.json +54 -0
- package/dist/packages/core/src/database/ssl-config.d.ts +9 -0
- package/dist/packages/core/src/database/ssl-config.d.ts.map +1 -0
- package/dist/packages/core/src/database/ssl-config.js +8 -0
- package/dist/packages/core/src/database/ssl-config.js.map +1 -0
- package/dist/packages/core/src/features.d.ts +86 -0
- package/dist/packages/core/src/features.d.ts.map +1 -0
- package/dist/packages/core/src/features.js +93 -0
- package/dist/packages/core/src/features.js.map +1 -0
- package/dist/packages/core/src/license.d.ts +75 -0
- package/dist/packages/core/src/license.d.ts.map +1 -0
- package/dist/packages/core/src/license.js +174 -0
- package/dist/packages/core/src/license.js.map +1 -0
- package/dist/packages/core/src/monitoring/alerts.d.ts +118 -0
- package/dist/packages/core/src/monitoring/alerts.d.ts.map +1 -0
- package/dist/packages/core/src/monitoring/alerts.js +325 -0
- package/dist/packages/core/src/monitoring/alerts.js.map +1 -0
- package/dist/packages/core/src/monitoring/cleanup-manager.d.ts +71 -0
- package/dist/packages/core/src/monitoring/cleanup-manager.d.ts.map +1 -0
- package/dist/packages/core/src/monitoring/cleanup-manager.js +227 -0
- package/dist/packages/core/src/monitoring/cleanup-manager.js.map +1 -0
- package/dist/packages/core/src/monitoring/health-monitor.d.ts +22 -0
- package/dist/packages/core/src/monitoring/health-monitor.d.ts.map +1 -0
- package/dist/packages/core/src/monitoring/health-monitor.js +143 -0
- package/dist/packages/core/src/monitoring/health-monitor.js.map +1 -0
- package/dist/packages/core/src/monitoring/index.d.ts +14 -0
- package/dist/packages/core/src/monitoring/index.d.ts.map +1 -0
- package/dist/packages/core/src/monitoring/index.js +18 -0
- package/dist/packages/core/src/monitoring/index.js.map +1 -0
- package/dist/packages/core/src/monitoring/process-registry.d.ts +97 -0
- package/dist/packages/core/src/monitoring/process-registry.d.ts.map +1 -0
- package/dist/packages/core/src/monitoring/process-registry.js +223 -0
- package/dist/packages/core/src/monitoring/process-registry.js.map +1 -0
- package/dist/packages/core/src/monitoring/types.d.ts +231 -0
- package/dist/packages/core/src/monitoring/types.d.ts.map +1 -0
- package/dist/packages/core/src/monitoring/types.js +43 -0
- package/dist/packages/core/src/monitoring/types.js.map +1 -0
- package/dist/packages/core/src/monitoring/zombie-detector.d.ts +81 -0
- package/dist/packages/core/src/monitoring/zombie-detector.d.ts.map +1 -0
- package/dist/packages/core/src/monitoring/zombie-detector.js +232 -0
- package/dist/packages/core/src/monitoring/zombie-detector.js.map +1 -0
- package/dist/packages/core/src/observability/logger.d.ts +47 -0
- package/dist/packages/core/src/observability/logger.d.ts.map +1 -0
- package/dist/packages/core/src/observability/logger.js +141 -0
- package/dist/packages/core/src/observability/logger.js.map +1 -0
- package/dist/packages/core/src/utils/logger-server.d.ts +32 -0
- package/dist/packages/core/src/utils/logger-server.d.ts.map +1 -0
- package/dist/packages/core/src/utils/logger-server.js +69 -0
- package/dist/packages/core/src/utils/logger-server.js.map +1 -0
- package/dist/packages/core/src/utils/request-context.d.ts +143 -0
- package/dist/packages/core/src/utils/request-context.d.ts.map +1 -0
- package/dist/packages/core/src/utils/request-context.js +169 -0
- package/dist/packages/core/src/utils/request-context.js.map +1 -0
- package/dist/packages/dev/src/code-validator/index.d.ts +20 -0
- package/dist/packages/dev/src/code-validator/index.d.ts.map +1 -0
- package/dist/packages/dev/src/code-validator/index.js +20 -0
- package/dist/packages/dev/src/code-validator/index.js.map +1 -0
- package/dist/packages/dev/src/code-validator/types.d.ts +67 -0
- package/dist/packages/dev/src/code-validator/types.d.ts.map +1 -0
- package/dist/packages/dev/src/code-validator/types.js +7 -0
- package/dist/packages/dev/src/code-validator/types.js.map +1 -0
- package/dist/packages/dev/src/code-validator/validator.d.ts +48 -0
- package/dist/packages/dev/src/code-validator/validator.d.ts.map +1 -0
- package/dist/packages/dev/src/code-validator/validator.js +176 -0
- package/dist/packages/dev/src/code-validator/validator.js.map +1 -0
- package/dist/packages/mcp/src/adapters/db.d.ts +46 -0
- package/dist/packages/mcp/src/adapters/db.d.ts.map +1 -0
- package/dist/packages/mcp/src/adapters/db.js +127 -0
- package/dist/packages/mcp/src/adapters/db.js.map +1 -0
- package/dist/packages/mcp/src/config/index.d.ts +11 -0
- package/dist/packages/mcp/src/config/index.d.ts.map +1 -0
- package/dist/packages/mcp/src/config/index.js +18 -0
- package/dist/packages/mcp/src/config/index.js.map +1 -0
- package/dist/packages/mcp/src/contracts.d.ts +131 -0
- package/dist/packages/mcp/src/contracts.d.ts.map +1 -0
- package/dist/packages/mcp/src/contracts.js +153 -0
- package/dist/packages/mcp/src/contracts.js.map +1 -0
- package/dist/packages/mcp/src/hypervisor.d.ts +132 -0
- package/dist/packages/mcp/src/hypervisor.d.ts.map +1 -0
- package/dist/packages/mcp/src/hypervisor.js +359 -0
- package/dist/packages/mcp/src/hypervisor.js.map +1 -0
- package/dist/packages/mcp/src/index.d.ts +25 -0
- package/dist/packages/mcp/src/index.d.ts.map +1 -0
- package/dist/packages/mcp/src/index.js +41 -0
- package/dist/packages/mcp/src/index.js.map +1 -0
- package/dist/packages/mcp/src/servers/adapter.d.ts +199 -0
- package/dist/packages/mcp/src/servers/adapter.d.ts.map +1 -0
- package/dist/packages/mcp/src/servers/adapter.js +487 -0
- package/dist/packages/mcp/src/servers/adapter.js.map +1 -0
- package/dist/packages/mcp/src/servers/code-validator.d.ts +24 -0
- package/dist/packages/mcp/src/servers/code-validator.d.ts.map +1 -0
- package/dist/packages/mcp/src/servers/code-validator.js +156 -0
- package/dist/packages/mcp/src/servers/code-validator.js.map +1 -0
- package/dist/packages/mcp/src/servers/neon.d.ts +11 -0
- package/dist/packages/mcp/src/servers/neon.d.ts.map +1 -0
- package/dist/packages/mcp/src/servers/neon.js +90 -0
- package/dist/packages/mcp/src/servers/neon.js.map +1 -0
- package/dist/packages/mcp/src/servers/next-devtools.d.ts +11 -0
- package/dist/packages/mcp/src/servers/next-devtools.d.ts.map +1 -0
- package/dist/packages/mcp/src/servers/next-devtools.js +215 -0
- package/dist/packages/mcp/src/servers/next-devtools.js.map +1 -0
- package/dist/packages/mcp/src/servers/playwright.d.ts +11 -0
- package/dist/packages/mcp/src/servers/playwright.d.ts.map +1 -0
- package/dist/packages/mcp/src/servers/playwright.js +68 -0
- package/dist/packages/mcp/src/servers/playwright.js.map +1 -0
- package/dist/packages/mcp/src/servers/stripe.d.ts +11 -0
- package/dist/packages/mcp/src/servers/stripe.d.ts.map +1 -0
- package/dist/packages/mcp/src/servers/stripe.js +86 -0
- package/dist/packages/mcp/src/servers/stripe.js.map +1 -0
- package/dist/packages/mcp/src/servers/supabase.d.ts +11 -0
- package/dist/packages/mcp/src/servers/supabase.d.ts.map +1 -0
- package/dist/packages/mcp/src/servers/supabase.js +144 -0
- package/dist/packages/mcp/src/servers/supabase.js.map +1 -0
- package/dist/packages/mcp/src/servers/vercel.d.ts +11 -0
- package/dist/packages/mcp/src/servers/vercel.d.ts.map +1 -0
- package/dist/packages/mcp/src/servers/vercel.js +87 -0
- package/dist/packages/mcp/src/servers/vercel.js.map +1 -0
- package/dist/packages/mcp/src/servers/vultr-test.d.ts +3 -0
- package/dist/packages/mcp/src/servers/vultr-test.d.ts.map +1 -0
- package/dist/packages/mcp/src/servers/vultr-test.js +82 -0
- package/dist/packages/mcp/src/servers/vultr-test.js.map +1 -0
- package/dist/scripts/lib/analyzers/console-analyzer.d.ts +188 -0
- package/dist/scripts/lib/analyzers/console-analyzer.d.ts.map +1 -0
- package/dist/scripts/lib/analyzers/console-analyzer.js +432 -0
- package/dist/scripts/lib/analyzers/console-analyzer.js.map +1 -0
- package/dist/scripts/lib/analyzers/index.d.ts +11 -0
- package/dist/scripts/lib/analyzers/index.d.ts.map +1 -0
- package/dist/scripts/lib/analyzers/index.js +11 -0
- package/dist/scripts/lib/analyzers/index.js.map +1 -0
- package/dist/scripts/lib/args.d.ts +104 -0
- package/dist/scripts/lib/args.d.ts.map +1 -0
- package/dist/scripts/lib/args.js +304 -0
- package/dist/scripts/lib/args.js.map +1 -0
- package/dist/scripts/lib/cache.d.ts +185 -0
- package/dist/scripts/lib/cache.d.ts.map +1 -0
- package/dist/scripts/lib/cache.js +390 -0
- package/dist/scripts/lib/cache.js.map +1 -0
- package/dist/scripts/lib/cli/dispatch.d.ts +116 -0
- package/dist/scripts/lib/cli/dispatch.d.ts.map +1 -0
- package/dist/scripts/lib/cli/dispatch.js +206 -0
- package/dist/scripts/lib/cli/dispatch.js.map +1 -0
- package/dist/scripts/lib/cli/index.d.ts +10 -0
- package/dist/scripts/lib/cli/index.d.ts.map +1 -0
- package/dist/scripts/lib/cli/index.js +10 -0
- package/dist/scripts/lib/cli/index.js.map +1 -0
- package/dist/scripts/lib/database/ssl-config.d.ts +26 -0
- package/dist/scripts/lib/database/ssl-config.d.ts.map +1 -0
- package/dist/scripts/lib/database/ssl-config.js +47 -0
- package/dist/scripts/lib/database/ssl-config.js.map +1 -0
- package/dist/scripts/lib/errors.d.ts +218 -0
- package/dist/scripts/lib/errors.d.ts.map +1 -0
- package/dist/scripts/lib/errors.js +543 -0
- package/dist/scripts/lib/errors.js.map +1 -0
- package/dist/scripts/lib/exec.d.ts +107 -0
- package/dist/scripts/lib/exec.d.ts.map +1 -0
- package/dist/scripts/lib/exec.js +232 -0
- package/dist/scripts/lib/exec.js.map +1 -0
- package/dist/scripts/lib/index.d.ts +50 -0
- package/dist/scripts/lib/index.d.ts.map +1 -0
- package/dist/scripts/lib/index.js +65 -0
- package/dist/scripts/lib/index.js.map +1 -0
- package/dist/scripts/lib/logger.d.ts +50 -0
- package/dist/scripts/lib/logger.d.ts.map +1 -0
- package/dist/scripts/lib/logger.js +159 -0
- package/dist/scripts/lib/logger.js.map +1 -0
- package/dist/scripts/lib/output.d.ts +149 -0
- package/dist/scripts/lib/output.d.ts.map +1 -0
- package/dist/scripts/lib/output.js +263 -0
- package/dist/scripts/lib/output.js.map +1 -0
- package/dist/scripts/lib/parallel.d.ts +164 -0
- package/dist/scripts/lib/parallel.d.ts.map +1 -0
- package/dist/scripts/lib/parallel.js +355 -0
- package/dist/scripts/lib/parallel.js.map +1 -0
- package/dist/scripts/lib/paths.d.ts +92 -0
- package/dist/scripts/lib/paths.d.ts.map +1 -0
- package/dist/scripts/lib/paths.js +171 -0
- package/dist/scripts/lib/paths.js.map +1 -0
- package/dist/scripts/lib/state/adapters/memory.d.ts +42 -0
- package/dist/scripts/lib/state/adapters/memory.d.ts.map +1 -0
- package/dist/scripts/lib/state/adapters/memory.js +110 -0
- package/dist/scripts/lib/state/adapters/memory.js.map +1 -0
- package/dist/scripts/lib/state/adapters/pglite.d.ts +46 -0
- package/dist/scripts/lib/state/adapters/pglite.d.ts.map +1 -0
- package/dist/scripts/lib/state/adapters/pglite.js +256 -0
- package/dist/scripts/lib/state/adapters/pglite.js.map +1 -0
- package/dist/scripts/lib/state/index.d.ts +16 -0
- package/dist/scripts/lib/state/index.d.ts.map +1 -0
- package/dist/scripts/lib/state/index.js +16 -0
- package/dist/scripts/lib/state/index.js.map +1 -0
- package/dist/scripts/lib/state/types.d.ts +111 -0
- package/dist/scripts/lib/state/types.d.ts.map +1 -0
- package/dist/scripts/lib/state/types.js +8 -0
- package/dist/scripts/lib/state/types.js.map +1 -0
- package/dist/scripts/lib/state/workflow-state.d.ts +110 -0
- package/dist/scripts/lib/state/workflow-state.d.ts.map +1 -0
- package/dist/scripts/lib/state/workflow-state.js +331 -0
- package/dist/scripts/lib/state/workflow-state.js.map +1 -0
- package/dist/scripts/lib/telemetry.d.ts +194 -0
- package/dist/scripts/lib/telemetry.d.ts.map +1 -0
- package/dist/scripts/lib/telemetry.js +394 -0
- package/dist/scripts/lib/telemetry.js.map +1 -0
- package/dist/scripts/lib/utils.d.ts +270 -0
- package/dist/scripts/lib/utils.d.ts.map +1 -0
- package/dist/scripts/lib/utils.js +473 -0
- package/dist/scripts/lib/utils.js.map +1 -0
- package/dist/scripts/lib/validation/database.d.ts +83 -0
- package/dist/scripts/lib/validation/database.d.ts.map +1 -0
- package/dist/scripts/lib/validation/database.js +199 -0
- package/dist/scripts/lib/validation/database.js.map +1 -0
- package/dist/scripts/lib/validation/env.d.ts +80 -0
- package/dist/scripts/lib/validation/env.d.ts.map +1 -0
- package/dist/scripts/lib/validation/env.js +246 -0
- package/dist/scripts/lib/validation/env.js.map +1 -0
- package/dist/scripts/lib/validation/index.d.ts +16 -0
- package/dist/scripts/lib/validation/index.d.ts.map +1 -0
- package/dist/scripts/lib/validation/index.js +16 -0
- package/dist/scripts/lib/validation/index.js.map +1 -0
- package/dist/scripts/lib/validation/post-execution.d.ts +74 -0
- package/dist/scripts/lib/validation/post-execution.d.ts.map +1 -0
- package/dist/scripts/lib/validation/post-execution.js +110 -0
- package/dist/scripts/lib/validation/post-execution.js.map +1 -0
- package/dist/scripts/lib/validation/pre-execution.d.ts +165 -0
- package/dist/scripts/lib/validation/pre-execution.d.ts.map +1 -0
- package/dist/scripts/lib/validation/pre-execution.js +466 -0
- package/dist/scripts/lib/validation/pre-execution.js.map +1 -0
- package/dist/scripts/lib/validators/documentation-validator.d.ts +242 -0
- package/dist/scripts/lib/validators/documentation-validator.d.ts.map +1 -0
- package/dist/scripts/lib/validators/documentation-validator.js +584 -0
- package/dist/scripts/lib/validators/documentation-validator.js.map +1 -0
- package/dist/scripts/lib/validators/index.d.ts +11 -0
- package/dist/scripts/lib/validators/index.d.ts.map +1 -0
- package/dist/scripts/lib/validators/index.js +11 -0
- package/dist/scripts/lib/validators/index.js.map +1 -0
- package/docker-compose.yml +46 -0
- package/docs/INDEX.md +88 -0
- package/docs/README.md +774 -0
- package/docs/SETUP.md +264 -0
- package/docs/servers/code-validator.md +586 -0
- package/eslint.config.js +7 -0
- package/migrations/0001_add_crdt_columns.sql +8 -0
- package/migrations/0001_rollback.sql +6 -0
- package/migrations/005_performance_indexes.sql +190 -0
- package/migrations/backfill_crdt_meta.js +45 -0
- package/package.json +21 -85
- package/src/__tests__/hypervisor.test.ts +212 -0
- package/src/adapters/db.ts +180 -0
- package/src/config/config.json +49 -0
- package/src/config/index.ts +30 -0
- package/src/contracts.ts +221 -0
- package/src/hypervisor.ts +464 -0
- package/src/index.ts +87 -0
- package/src/servers/adapter.ts +643 -0
- package/src/servers/code-validator.ts +188 -0
- package/src/servers/neon.ts +103 -0
- package/src/servers/next-devtools.ts +230 -0
- package/src/servers/playwright.ts +77 -0
- package/src/servers/stripe.ts +99 -0
- package/src/servers/supabase.ts +161 -0
- package/src/servers/vercel.ts +100 -0
- package/src/servers/vultr-test.ts +97 -0
- package/tsconfig.json +12 -0
- package/vitest.config.ts +22 -0
- package/LICENSE +0 -202
- package/dist/index.js +0 -10990
- 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.
|
|
4
|
-
"
|
|
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
|
-
"@
|
|
72
|
-
"
|
|
73
|
-
"@revealui/
|
|
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
|
-
"@
|
|
77
|
-
"
|
|
14
|
+
"@electric-sql/pglite": "^0.3.15",
|
|
15
|
+
"pg": "^8.18.0",
|
|
78
16
|
"typescript": "^5.9.3",
|
|
79
|
-
"vitest": "^4.0.
|
|
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
|
-
"
|
|
88
|
-
|
|
19
|
+
"type": "module",
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"registry": "https://registry.npmjs.org",
|
|
22
|
+
"access": "public"
|
|
89
23
|
},
|
|
90
24
|
"scripts": {
|
|
91
|
-
"build": "
|
|
92
|
-
"clean": "rm -rf dist
|
|
93
|
-
"
|
|
94
|
-
"
|
|
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
|
+
})
|