agent-relay 2.0.23 → 2.0.24

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 (168) hide show
  1. package/dist/src/cli/index.js +66 -13
  2. package/package.json +18 -52
  3. package/packages/api-types/package.json +1 -1
  4. package/packages/bridge/package.json +8 -8
  5. package/packages/cli-tester/package.json +1 -1
  6. package/packages/config/package.json +2 -2
  7. package/packages/continuity/package.json +1 -1
  8. package/packages/daemon/package.json +12 -12
  9. package/packages/hooks/package.json +4 -4
  10. package/packages/mcp/package.json +2 -2
  11. package/packages/memory/package.json +2 -2
  12. package/packages/policy/package.json +2 -2
  13. package/packages/protocol/package.json +1 -1
  14. package/packages/resiliency/package.json +1 -1
  15. package/packages/sdk/package.json +2 -2
  16. package/packages/spawner/package.json +1 -1
  17. package/packages/state/package.json +1 -1
  18. package/packages/storage/package.json +2 -2
  19. package/packages/telemetry/package.json +1 -1
  20. package/packages/trajectory/package.json +2 -2
  21. package/packages/user-directory/package.json +2 -2
  22. package/packages/utils/package.json +1 -1
  23. package/packages/wrapper/package.json +6 -6
  24. package/deploy/init-db.sql +0 -5
  25. package/deploy/scripts/setup-fly-workspaces.sh +0 -69
  26. package/deploy/scripts/setup-railway.sh +0 -75
  27. package/dist/src/cloud/index.d.ts +0 -8
  28. package/dist/src/cloud/index.js +0 -8
  29. package/packages/cloud/dist/api/admin.d.ts +0 -8
  30. package/packages/cloud/dist/api/admin.js +0 -225
  31. package/packages/cloud/dist/api/auth.d.ts +0 -20
  32. package/packages/cloud/dist/api/auth.js +0 -138
  33. package/packages/cloud/dist/api/billing.d.ts +0 -7
  34. package/packages/cloud/dist/api/billing.js +0 -564
  35. package/packages/cloud/dist/api/cli-pty-runner.d.ts +0 -53
  36. package/packages/cloud/dist/api/cli-pty-runner.js +0 -175
  37. package/packages/cloud/dist/api/codex-auth-helper.d.ts +0 -21
  38. package/packages/cloud/dist/api/codex-auth-helper.js +0 -327
  39. package/packages/cloud/dist/api/consensus.d.ts +0 -13
  40. package/packages/cloud/dist/api/consensus.js +0 -261
  41. package/packages/cloud/dist/api/coordinators.d.ts +0 -8
  42. package/packages/cloud/dist/api/coordinators.js +0 -750
  43. package/packages/cloud/dist/api/daemons.d.ts +0 -12
  44. package/packages/cloud/dist/api/daemons.js +0 -535
  45. package/packages/cloud/dist/api/email-auth.d.ts +0 -11
  46. package/packages/cloud/dist/api/email-auth.js +0 -347
  47. package/packages/cloud/dist/api/generic-webhooks.d.ts +0 -8
  48. package/packages/cloud/dist/api/generic-webhooks.js +0 -129
  49. package/packages/cloud/dist/api/git.d.ts +0 -8
  50. package/packages/cloud/dist/api/git.js +0 -269
  51. package/packages/cloud/dist/api/github-app.d.ts +0 -11
  52. package/packages/cloud/dist/api/github-app.js +0 -223
  53. package/packages/cloud/dist/api/middleware/planLimits.d.ts +0 -43
  54. package/packages/cloud/dist/api/middleware/planLimits.js +0 -202
  55. package/packages/cloud/dist/api/monitoring.d.ts +0 -11
  56. package/packages/cloud/dist/api/monitoring.js +0 -578
  57. package/packages/cloud/dist/api/nango-auth.d.ts +0 -9
  58. package/packages/cloud/dist/api/nango-auth.js +0 -741
  59. package/packages/cloud/dist/api/onboarding.d.ts +0 -15
  60. package/packages/cloud/dist/api/onboarding.js +0 -679
  61. package/packages/cloud/dist/api/policy.d.ts +0 -8
  62. package/packages/cloud/dist/api/policy.js +0 -229
  63. package/packages/cloud/dist/api/provider-env.d.ts +0 -26
  64. package/packages/cloud/dist/api/provider-env.js +0 -141
  65. package/packages/cloud/dist/api/providers.d.ts +0 -7
  66. package/packages/cloud/dist/api/providers.js +0 -574
  67. package/packages/cloud/dist/api/repos.d.ts +0 -8
  68. package/packages/cloud/dist/api/repos.js +0 -577
  69. package/packages/cloud/dist/api/sessions.d.ts +0 -11
  70. package/packages/cloud/dist/api/sessions.js +0 -302
  71. package/packages/cloud/dist/api/teams.d.ts +0 -7
  72. package/packages/cloud/dist/api/teams.js +0 -281
  73. package/packages/cloud/dist/api/test-helpers.d.ts +0 -10
  74. package/packages/cloud/dist/api/test-helpers.js +0 -745
  75. package/packages/cloud/dist/api/usage.d.ts +0 -7
  76. package/packages/cloud/dist/api/usage.js +0 -111
  77. package/packages/cloud/dist/api/webhooks.d.ts +0 -8
  78. package/packages/cloud/dist/api/webhooks.js +0 -645
  79. package/packages/cloud/dist/api/workspaces.d.ts +0 -25
  80. package/packages/cloud/dist/api/workspaces.js +0 -1799
  81. package/packages/cloud/dist/billing/index.d.ts +0 -9
  82. package/packages/cloud/dist/billing/index.js +0 -9
  83. package/packages/cloud/dist/billing/plans.d.ts +0 -39
  84. package/packages/cloud/dist/billing/plans.js +0 -245
  85. package/packages/cloud/dist/billing/service.d.ts +0 -80
  86. package/packages/cloud/dist/billing/service.js +0 -388
  87. package/packages/cloud/dist/billing/types.d.ts +0 -141
  88. package/packages/cloud/dist/billing/types.js +0 -7
  89. package/packages/cloud/dist/config.d.ts +0 -5
  90. package/packages/cloud/dist/config.js +0 -5
  91. package/packages/cloud/dist/db/bulk-ingest.d.ts +0 -89
  92. package/packages/cloud/dist/db/bulk-ingest.js +0 -268
  93. package/packages/cloud/dist/db/drizzle.d.ts +0 -290
  94. package/packages/cloud/dist/db/drizzle.js +0 -1422
  95. package/packages/cloud/dist/db/index.d.ts +0 -56
  96. package/packages/cloud/dist/db/index.js +0 -70
  97. package/packages/cloud/dist/db/schema.d.ts +0 -5117
  98. package/packages/cloud/dist/db/schema.js +0 -656
  99. package/packages/cloud/dist/index.d.ts +0 -11
  100. package/packages/cloud/dist/index.js +0 -38
  101. package/packages/cloud/dist/provisioner/index.d.ts +0 -207
  102. package/packages/cloud/dist/provisioner/index.js +0 -2118
  103. package/packages/cloud/dist/server.d.ts +0 -17
  104. package/packages/cloud/dist/server.js +0 -2055
  105. package/packages/cloud/dist/services/auto-scaler.d.ts +0 -152
  106. package/packages/cloud/dist/services/auto-scaler.js +0 -439
  107. package/packages/cloud/dist/services/capacity-manager.d.ts +0 -148
  108. package/packages/cloud/dist/services/capacity-manager.js +0 -449
  109. package/packages/cloud/dist/services/ci-agent-spawner.d.ts +0 -49
  110. package/packages/cloud/dist/services/ci-agent-spawner.js +0 -373
  111. package/packages/cloud/dist/services/cloud-message-bus.d.ts +0 -28
  112. package/packages/cloud/dist/services/cloud-message-bus.js +0 -19
  113. package/packages/cloud/dist/services/compute-enforcement.d.ts +0 -57
  114. package/packages/cloud/dist/services/compute-enforcement.js +0 -175
  115. package/packages/cloud/dist/services/coordinator.d.ts +0 -62
  116. package/packages/cloud/dist/services/coordinator.js +0 -389
  117. package/packages/cloud/dist/services/index.d.ts +0 -17
  118. package/packages/cloud/dist/services/index.js +0 -25
  119. package/packages/cloud/dist/services/intro-expiration.d.ts +0 -60
  120. package/packages/cloud/dist/services/intro-expiration.js +0 -252
  121. package/packages/cloud/dist/services/mention-handler.d.ts +0 -65
  122. package/packages/cloud/dist/services/mention-handler.js +0 -405
  123. package/packages/cloud/dist/services/nango.d.ts +0 -219
  124. package/packages/cloud/dist/services/nango.js +0 -424
  125. package/packages/cloud/dist/services/persistence.d.ts +0 -131
  126. package/packages/cloud/dist/services/persistence.js +0 -200
  127. package/packages/cloud/dist/services/planLimits.d.ts +0 -147
  128. package/packages/cloud/dist/services/planLimits.js +0 -335
  129. package/packages/cloud/dist/services/presence-registry.d.ts +0 -56
  130. package/packages/cloud/dist/services/presence-registry.js +0 -91
  131. package/packages/cloud/dist/services/scaling-orchestrator.d.ts +0 -159
  132. package/packages/cloud/dist/services/scaling-orchestrator.js +0 -502
  133. package/packages/cloud/dist/services/scaling-policy.d.ts +0 -121
  134. package/packages/cloud/dist/services/scaling-policy.js +0 -415
  135. package/packages/cloud/dist/services/ssh-security.d.ts +0 -31
  136. package/packages/cloud/dist/services/ssh-security.js +0 -63
  137. package/packages/cloud/dist/services/workspace-keepalive.d.ts +0 -76
  138. package/packages/cloud/dist/services/workspace-keepalive.js +0 -234
  139. package/packages/cloud/dist/shims/consensus.d.ts +0 -23
  140. package/packages/cloud/dist/shims/consensus.js +0 -5
  141. package/packages/cloud/dist/webhooks/index.d.ts +0 -24
  142. package/packages/cloud/dist/webhooks/index.js +0 -29
  143. package/packages/cloud/dist/webhooks/parsers/github.d.ts +0 -8
  144. package/packages/cloud/dist/webhooks/parsers/github.js +0 -234
  145. package/packages/cloud/dist/webhooks/parsers/index.d.ts +0 -23
  146. package/packages/cloud/dist/webhooks/parsers/index.js +0 -30
  147. package/packages/cloud/dist/webhooks/parsers/linear.d.ts +0 -9
  148. package/packages/cloud/dist/webhooks/parsers/linear.js +0 -258
  149. package/packages/cloud/dist/webhooks/parsers/slack.d.ts +0 -9
  150. package/packages/cloud/dist/webhooks/parsers/slack.js +0 -214
  151. package/packages/cloud/dist/webhooks/responders/github.d.ts +0 -8
  152. package/packages/cloud/dist/webhooks/responders/github.js +0 -73
  153. package/packages/cloud/dist/webhooks/responders/index.d.ts +0 -23
  154. package/packages/cloud/dist/webhooks/responders/index.js +0 -30
  155. package/packages/cloud/dist/webhooks/responders/linear.d.ts +0 -9
  156. package/packages/cloud/dist/webhooks/responders/linear.js +0 -149
  157. package/packages/cloud/dist/webhooks/responders/slack.d.ts +0 -20
  158. package/packages/cloud/dist/webhooks/responders/slack.js +0 -178
  159. package/packages/cloud/dist/webhooks/router.d.ts +0 -25
  160. package/packages/cloud/dist/webhooks/router.js +0 -504
  161. package/packages/cloud/dist/webhooks/rules-engine.d.ts +0 -24
  162. package/packages/cloud/dist/webhooks/rules-engine.js +0 -287
  163. package/packages/cloud/dist/webhooks/types.d.ts +0 -186
  164. package/packages/cloud/dist/webhooks/types.js +0 -8
  165. package/packages/cloud/package.json +0 -60
  166. package/scripts/run-migrations.js +0 -43
  167. package/scripts/setup-stripe-products.ts +0 -312
  168. package/scripts/verify-schema.js +0 -134
@@ -1,312 +0,0 @@
1
- #!/usr/bin/env npx tsx
2
- /**
3
- * Setup Stripe Products and Prices
4
- *
5
- * Creates products and prices in Stripe for all billing plans.
6
- * Run this when:
7
- * - Setting up a new Stripe account
8
- * - Migrating to a new Stripe org
9
- * - Updating pricing (creates new prices, keeps old ones for existing subscriptions)
10
- *
11
- * Usage:
12
- * STRIPE_SECRET_KEY=sk_test_xxx npx tsx scripts/setup-stripe-products.ts
13
- *
14
- * Options:
15
- * --dry-run Show what would be created without making changes
16
- * --update Update existing products (name, description, metadata)
17
- */
18
-
19
- import Stripe from 'stripe';
20
-
21
- // Plan definitions (mirrors src/cloud/billing/plans.ts)
22
- const PLANS = [
23
- {
24
- id: 'pro',
25
- name: 'Pro',
26
- description: 'For professional developers building with AI agents',
27
- priceMonthly: 6900, // $69/month
28
- priceYearly: 69000, // $690/year (2 months free)
29
- features: [
30
- 'Up to 5 workspaces',
31
- 'Up to 5 agents per workspace',
32
- '50 compute hours/month',
33
- '10 GB storage',
34
- '3 team members',
35
- 'Custom domains',
36
- 'Session persistence',
37
- 'Email support',
38
- ],
39
- },
40
- {
41
- id: 'team',
42
- name: 'Team',
43
- description: 'For growing teams with advanced needs',
44
- priceMonthly: 12900, // $129/month
45
- priceYearly: 129000, // $1290/year (2 months free)
46
- features: [
47
- 'Up to 50 workspaces',
48
- 'Up to 25 agents per workspace',
49
- '500 compute hours/month',
50
- '50 GB storage',
51
- '25 team members',
52
- 'Custom domains',
53
- 'Session persistence',
54
- 'Priority support',
55
- 'Audit logs',
56
- ],
57
- },
58
- {
59
- id: 'enterprise',
60
- name: 'Enterprise',
61
- description: 'For organizations requiring dedicated support and SLAs',
62
- priceMonthly: 49900, // $499/month
63
- priceYearly: 499000, // $4990/year
64
- features: [
65
- 'Unlimited workspaces',
66
- 'Unlimited agents',
67
- 'Unlimited compute hours',
68
- '500 GB storage',
69
- 'Unlimited team members',
70
- 'Custom domains',
71
- 'Session persistence',
72
- 'Priority support with SLA',
73
- 'SSO/SAML integration',
74
- 'Audit logs & compliance',
75
- 'Dedicated account manager',
76
- ],
77
- },
78
- ];
79
-
80
- interface CreatedResources {
81
- products: Map<string, string>; // plan id -> product id
82
- prices: Map<string, { monthly: string; yearly: string }>; // plan id -> price ids
83
- }
84
-
85
- async function main() {
86
- const args = process.argv.slice(2);
87
- const dryRun = args.includes('--dry-run');
88
- const update = args.includes('--update');
89
-
90
- const stripeKey = process.env.STRIPE_SECRET_KEY;
91
- if (!stripeKey) {
92
- console.error('Error: STRIPE_SECRET_KEY environment variable is required');
93
- console.error('Usage: STRIPE_SECRET_KEY=sk_test_xxx npx tsx scripts/setup-stripe-products.ts');
94
- process.exit(1);
95
- }
96
-
97
- const isTestMode = stripeKey.startsWith('sk_test_');
98
- console.log(`\nšŸ”‘ Using Stripe ${isTestMode ? 'TEST' : 'LIVE'} mode\n`);
99
-
100
- if (!isTestMode && !dryRun) {
101
- console.warn('āš ļø WARNING: You are about to create products in LIVE mode!');
102
- console.warn(' Run with --dry-run first to preview changes.\n');
103
- // Give user a chance to cancel
104
- await new Promise((resolve) => setTimeout(resolve, 3000));
105
- }
106
-
107
- if (dryRun) {
108
- console.log('šŸ” DRY RUN - No changes will be made\n');
109
- }
110
-
111
- const stripe = new Stripe(stripeKey);
112
- const created: CreatedResources = {
113
- products: new Map(),
114
- prices: new Map(),
115
- };
116
-
117
- // Check for existing products
118
- console.log('šŸ“¦ Checking for existing products...\n');
119
- const existingProducts = await stripe.products.list({ limit: 100, active: true });
120
- const productsByPlanId = new Map<string, Stripe.Product>();
121
-
122
- for (const product of existingProducts.data) {
123
- const planId = product.metadata?.plan_id;
124
- if (planId && PLANS.some((p) => p.id === planId)) {
125
- productsByPlanId.set(planId, product);
126
- console.log(` Found existing product for ${planId}: ${product.id}`);
127
- }
128
- }
129
-
130
- // Create or update products
131
- console.log('\nšŸ“¦ Creating/updating products...\n');
132
-
133
- for (const plan of PLANS) {
134
- const existingProduct = productsByPlanId.get(plan.id);
135
-
136
- if (existingProduct) {
137
- if (update) {
138
- console.log(` Updating product: ${plan.name} (${existingProduct.id})`);
139
- if (!dryRun) {
140
- await stripe.products.update(existingProduct.id, {
141
- name: `Agent Relay ${plan.name}`,
142
- description: plan.description,
143
- metadata: {
144
- plan_id: plan.id,
145
- features: plan.features.join('|'),
146
- },
147
- });
148
- }
149
- } else {
150
- console.log(` Skipping existing product: ${plan.name} (${existingProduct.id})`);
151
- }
152
- created.products.set(plan.id, existingProduct.id);
153
- } else {
154
- console.log(` Creating product: ${plan.name}`);
155
- if (!dryRun) {
156
- const product = await stripe.products.create({
157
- name: `Agent Relay ${plan.name}`,
158
- description: plan.description,
159
- metadata: {
160
- plan_id: plan.id,
161
- features: plan.features.join('|'),
162
- },
163
- });
164
- created.products.set(plan.id, product.id);
165
- console.log(` Created: ${product.id}`);
166
- } else {
167
- created.products.set(plan.id, `prod_${plan.id}_placeholder`);
168
- }
169
- }
170
- }
171
-
172
- // Check for existing prices
173
- console.log('\nšŸ’° Checking for existing prices...\n');
174
- const existingPrices = await stripe.prices.list({ limit: 100, active: true });
175
- const pricesByPlanId = new Map<string, { monthly?: Stripe.Price; yearly?: Stripe.Price }>();
176
-
177
- for (const price of existingPrices.data) {
178
- const planId = price.metadata?.plan_id;
179
- const interval = price.recurring?.interval;
180
- if (planId && PLANS.some((p) => p.id === planId)) {
181
- if (!pricesByPlanId.has(planId)) {
182
- pricesByPlanId.set(planId, {});
183
- }
184
- const existing = pricesByPlanId.get(planId)!;
185
- if (interval === 'month') {
186
- existing.monthly = price;
187
- console.log(` Found existing monthly price for ${planId}: ${price.id} ($${price.unit_amount! / 100})`);
188
- } else if (interval === 'year') {
189
- existing.yearly = price;
190
- console.log(` Found existing yearly price for ${planId}: ${price.id} ($${price.unit_amount! / 100})`);
191
- }
192
- }
193
- }
194
-
195
- // Create prices
196
- console.log('\nšŸ’° Creating prices...\n');
197
-
198
- for (const plan of PLANS) {
199
- const productId = created.products.get(plan.id);
200
- if (!productId) {
201
- console.error(` Error: No product ID for ${plan.id}`);
202
- continue;
203
- }
204
-
205
- const existingPlanPrices = pricesByPlanId.get(plan.id) || {};
206
- const planPrices: { monthly: string; yearly: string } = { monthly: '', yearly: '' };
207
-
208
- // Monthly price
209
- if (existingPlanPrices.monthly && existingPlanPrices.monthly.unit_amount === plan.priceMonthly) {
210
- console.log(` Skipping existing monthly price for ${plan.name}: $${plan.priceMonthly / 100}/mo`);
211
- planPrices.monthly = existingPlanPrices.monthly.id;
212
- } else {
213
- if (existingPlanPrices.monthly) {
214
- console.log(` Price changed for ${plan.name} monthly: $${existingPlanPrices.monthly.unit_amount! / 100} -> $${plan.priceMonthly / 100}`);
215
- }
216
- console.log(` Creating monthly price for ${plan.name}: $${plan.priceMonthly / 100}/mo`);
217
- if (!dryRun) {
218
- const price = await stripe.prices.create({
219
- product: productId,
220
- unit_amount: plan.priceMonthly,
221
- currency: 'usd',
222
- recurring: { interval: 'month' },
223
- metadata: {
224
- plan_id: plan.id,
225
- interval: 'month',
226
- },
227
- });
228
- planPrices.monthly = price.id;
229
- console.log(` Created: ${price.id}`);
230
-
231
- // Archive old price if it exists
232
- if (existingPlanPrices.monthly) {
233
- console.log(` Archiving old price: ${existingPlanPrices.monthly.id}`);
234
- await stripe.prices.update(existingPlanPrices.monthly.id, { active: false });
235
- }
236
- } else {
237
- planPrices.monthly = `price_${plan.id}_monthly_placeholder`;
238
- }
239
- }
240
-
241
- // Yearly price
242
- if (existingPlanPrices.yearly && existingPlanPrices.yearly.unit_amount === plan.priceYearly) {
243
- console.log(` Skipping existing yearly price for ${plan.name}: $${plan.priceYearly / 100}/yr`);
244
- planPrices.yearly = existingPlanPrices.yearly.id;
245
- } else {
246
- if (existingPlanPrices.yearly) {
247
- console.log(` Price changed for ${plan.name} yearly: $${existingPlanPrices.yearly.unit_amount! / 100} -> $${plan.priceYearly / 100}`);
248
- }
249
- console.log(` Creating yearly price for ${plan.name}: $${plan.priceYearly / 100}/yr`);
250
- if (!dryRun) {
251
- const price = await stripe.prices.create({
252
- product: productId,
253
- unit_amount: plan.priceYearly,
254
- currency: 'usd',
255
- recurring: { interval: 'year' },
256
- metadata: {
257
- plan_id: plan.id,
258
- interval: 'year',
259
- },
260
- });
261
- planPrices.yearly = price.id;
262
- console.log(` Created: ${price.id}`);
263
-
264
- // Archive old price if it exists
265
- if (existingPlanPrices.yearly) {
266
- console.log(` Archiving old price: ${existingPlanPrices.yearly.id}`);
267
- await stripe.prices.update(existingPlanPrices.yearly.id, { active: false });
268
- }
269
- } else {
270
- planPrices.yearly = `price_${plan.id}_yearly_placeholder`;
271
- }
272
- }
273
-
274
- created.prices.set(plan.id, planPrices);
275
- }
276
-
277
- // Output environment variables
278
- console.log('\n' + '='.repeat(60));
279
- console.log('šŸ“‹ Environment Variables to Set:');
280
- console.log('='.repeat(60) + '\n');
281
-
282
- const envVars: string[] = [];
283
-
284
- for (const plan of PLANS) {
285
- const prices = created.prices.get(plan.id);
286
- if (prices) {
287
- const monthlyVar = `STRIPE_${plan.id.toUpperCase()}_MONTHLY_PRICE_ID=${prices.monthly}`;
288
- const yearlyVar = `STRIPE_${plan.id.toUpperCase()}_YEARLY_PRICE_ID=${prices.yearly}`;
289
- envVars.push(monthlyVar, yearlyVar);
290
- console.log(monthlyVar);
291
- console.log(yearlyVar);
292
- console.log();
293
- }
294
- }
295
-
296
- // Output .env format
297
- console.log('='.repeat(60));
298
- console.log('šŸ“„ Copy to .env file:');
299
- console.log('='.repeat(60) + '\n');
300
- console.log(envVars.join('\n'));
301
-
302
- console.log('\nāœ… Done!\n');
303
-
304
- if (dryRun) {
305
- console.log('This was a dry run. Run without --dry-run to create resources.\n');
306
- }
307
- }
308
-
309
- main().catch((err) => {
310
- console.error('Error:', err);
311
- process.exit(1);
312
- });
@@ -1,134 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Verify database schema after migrations
4
- *
5
- * This script verifies that all expected tables exist after migrations.
6
- * It dynamically reads table definitions from the schema to avoid hardcoding.
7
- *
8
- * Usage: DATABASE_URL=postgres://... node scripts/verify-schema.js
9
- */
10
-
11
- import pg from 'pg';
12
- import * as schema from '../packages/cloud/dist/db/schema.js';
13
-
14
- const { Pool } = pg;
15
-
16
- /**
17
- * Extract table names from the schema module.
18
- * Drizzle pgTable objects store their name in Symbol.for('drizzle:Name').
19
- */
20
- function getTablesFromSchema() {
21
- const tables = [];
22
- const drizzleNameSymbol = Symbol.for('drizzle:Name');
23
-
24
- for (const [key, value] of Object.entries(schema)) {
25
- // Skip relation definitions (they end with 'Relations')
26
- if (key.endsWith('Relations')) continue;
27
-
28
- // Drizzle tables have the table name in a Symbol
29
- if (value && typeof value === 'object' && value[drizzleNameSymbol]) {
30
- tables.push(value[drizzleNameSymbol]);
31
- }
32
- }
33
- return tables;
34
- }
35
-
36
- // Dynamically get tables from schema
37
- const SCHEMA_TABLES = getTablesFromSchema();
38
- const EXPECTED_TABLES = [...SCHEMA_TABLES];
39
-
40
- // Key columns to spot-check (subset of critical columns)
41
- const EXPECTED_COLUMNS = {
42
- users: ['id', 'email', 'created_at'],
43
- workspaces: ['id', 'user_id', 'name', 'status'],
44
- linked_daemons: ['id', 'user_id', 'workspace_id', 'status'],
45
- };
46
-
47
- async function main() {
48
- console.log('Verifying database schema...\n');
49
-
50
- if (!process.env.DATABASE_URL) {
51
- console.error('ERROR: DATABASE_URL environment variable is required');
52
- process.exit(1);
53
- }
54
-
55
- console.log(`Found ${SCHEMA_TABLES.length} tables in schema.ts:`);
56
- console.log(` ${SCHEMA_TABLES.join(', ')}\n`);
57
-
58
- const pool = new Pool({ connectionString: process.env.DATABASE_URL });
59
-
60
- try {
61
- // Get all tables in the public schema
62
- const tablesResult = await pool.query(`
63
- SELECT table_name
64
- FROM information_schema.tables
65
- WHERE table_schema = 'public'
66
- ORDER BY table_name
67
- `);
68
-
69
- const existingTables = tablesResult.rows.map((r) => r.table_name);
70
- console.log('Existing tables:', existingTables.join(', '));
71
- console.log('');
72
-
73
- // Check for missing tables
74
- const missingTables = EXPECTED_TABLES.filter((t) => !existingTables.includes(t));
75
- if (missingTables.length > 0) {
76
- console.error('MISSING TABLES:', missingTables.join(', '));
77
- process.exit(1);
78
- }
79
- console.log(`All ${EXPECTED_TABLES.length} expected tables exist`);
80
-
81
- // Verify key columns
82
- console.log('\nVerifying key columns...');
83
- for (const [table, columns] of Object.entries(EXPECTED_COLUMNS)) {
84
- const columnsResult = await pool.query(
85
- `
86
- SELECT column_name
87
- FROM information_schema.columns
88
- WHERE table_schema = 'public' AND table_name = $1
89
- `,
90
- [table]
91
- );
92
-
93
- const existingColumns = columnsResult.rows.map((r) => r.column_name);
94
- const missingColumns = columns.filter((c) => !existingColumns.includes(c));
95
-
96
- if (missingColumns.length > 0) {
97
- console.error(`Table '${table}' missing columns: ${missingColumns.join(', ')}`);
98
- console.error(`Existing columns: ${existingColumns.join(', ')}`);
99
- process.exit(1);
100
- }
101
- console.log(` ${table}: OK (${columns.length} key columns verified)`);
102
- }
103
-
104
- // Check migration history (table may be in public or drizzle schema)
105
- try {
106
- // Try public schema first, then drizzle schema
107
- let migrationsResult;
108
- try {
109
- migrationsResult = await pool.query(`
110
- SELECT id, hash, created_at FROM public.__drizzle_migrations ORDER BY created_at
111
- `);
112
- } catch {
113
- migrationsResult = await pool.query(`
114
- SELECT id, hash, created_at FROM drizzle.__drizzle_migrations ORDER BY created_at
115
- `);
116
- }
117
- console.log(`\nMigration history: ${migrationsResult.rows.length} migrations applied`);
118
- for (const row of migrationsResult.rows) {
119
- console.log(` - ${row.id} (${new Date(Number(row.created_at)).toISOString()})`);
120
- }
121
- } catch {
122
- console.log('\nMigration history: (table not found, but migrations ran successfully)');
123
- }
124
-
125
- console.log('\nSchema verification passed!');
126
- } catch (error) {
127
- console.error('Schema verification failed:', error);
128
- process.exit(1);
129
- } finally {
130
- await pool.end();
131
- }
132
- }
133
-
134
- main();