@nordsym/apiclaw 2.1.0 → 2.2.1

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 (185) hide show
  1. package/README.md +15 -2
  2. package/dist/bin-http.js +0 -0
  3. package/dist/bin.bundled.js +79288 -0
  4. package/dist/funnel-client.d.ts +24 -0
  5. package/dist/funnel-client.d.ts.map +1 -0
  6. package/dist/funnel-client.js +131 -0
  7. package/dist/funnel-client.js.map +1 -0
  8. package/dist/funnel.test.d.ts +2 -0
  9. package/dist/funnel.test.d.ts.map +1 -0
  10. package/dist/funnel.test.js +145 -0
  11. package/dist/funnel.test.js.map +1 -0
  12. package/dist/gateway-client.d.ts.map +1 -1
  13. package/dist/gateway-client.js +24 -2
  14. package/dist/gateway-client.js.map +1 -1
  15. package/dist/index.bundled.js +61263 -0
  16. package/dist/index.js +161 -74
  17. package/dist/index.js.map +1 -1
  18. package/dist/postinstall.d.ts +0 -5
  19. package/dist/postinstall.d.ts.map +1 -1
  20. package/dist/postinstall.js +24 -3
  21. package/dist/postinstall.js.map +1 -1
  22. package/dist/registration-guard.d.ts +29 -0
  23. package/dist/registration-guard.d.ts.map +1 -0
  24. package/dist/registration-guard.js +87 -0
  25. package/dist/registration-guard.js.map +1 -0
  26. package/package.json +7 -2
  27. package/.claude/settings.local.json +0 -9
  28. package/.env.prod +0 -1
  29. package/apiclaw-README.md +0 -494
  30. package/convex/_generated/api.d.ts +0 -137
  31. package/convex/_generated/api.js +0 -23
  32. package/convex/_generated/dataModel.d.ts +0 -60
  33. package/convex/_generated/server.d.ts +0 -143
  34. package/convex/_generated/server.js +0 -93
  35. package/convex/adminActivate.ts +0 -53
  36. package/convex/adminStats.ts +0 -306
  37. package/convex/agents.ts +0 -939
  38. package/convex/analytics.ts +0 -187
  39. package/convex/apiKeys.ts +0 -220
  40. package/convex/backfillAnalytics.ts +0 -272
  41. package/convex/backfillSearchLogs.ts +0 -35
  42. package/convex/billing.ts +0 -834
  43. package/convex/capabilities.ts +0 -157
  44. package/convex/chains.ts +0 -1318
  45. package/convex/credits.ts +0 -211
  46. package/convex/crons.ts +0 -50
  47. package/convex/debugFilestackLogs.ts +0 -16
  48. package/convex/debugGetToken.ts +0 -18
  49. package/convex/directCall.ts +0 -713
  50. package/convex/earnProgress.ts +0 -753
  51. package/convex/email.ts +0 -329
  52. package/convex/feedback.ts +0 -265
  53. package/convex/http.ts +0 -3430
  54. package/convex/inbound.ts +0 -32
  55. package/convex/logs.ts +0 -701
  56. package/convex/migrateFilestack.ts +0 -81
  57. package/convex/migratePartnersProd.ts +0 -174
  58. package/convex/migratePratham.ts +0 -126
  59. package/convex/migrateProviderWorkspaces.ts +0 -175
  60. package/convex/mou.ts +0 -91
  61. package/convex/providerKeys.ts +0 -289
  62. package/convex/providers.ts +0 -1135
  63. package/convex/purchases.ts +0 -183
  64. package/convex/ratelimit.ts +0 -104
  65. package/convex/schema.ts +0 -869
  66. package/convex/searchLogs.ts +0 -265
  67. package/convex/seedAPILayerAPIs.ts +0 -191
  68. package/convex/seedDirectCallConfigs.ts +0 -336
  69. package/convex/seedPratham.ts +0 -149
  70. package/convex/spendAlerts.ts +0 -442
  71. package/convex/stripeActions.ts +0 -607
  72. package/convex/teams.ts +0 -243
  73. package/convex/telemetry.ts +0 -81
  74. package/convex/tsconfig.json +0 -25
  75. package/convex/updateAPIStatus.ts +0 -44
  76. package/convex/usage.ts +0 -260
  77. package/convex/usageReports.ts +0 -357
  78. package/convex/waitlist.ts +0 -55
  79. package/convex/webhooks.ts +0 -494
  80. package/convex/workspaceSettings.ts +0 -143
  81. package/convex/workspaces.ts +0 -1331
  82. package/convex.json +0 -3
  83. package/direct-test.mjs +0 -51
  84. package/email-templates/filestack-provider-outreach.html +0 -162
  85. package/email-templates/partnership-template.html +0 -116
  86. package/email-templates/pratham-draft-preview.txt +0 -57
  87. package/email-templates/pratham-partnership-draft.html +0 -141
  88. package/reports/APIClaw-Session-Report-2026-04-05.pdf +0 -0
  89. package/reports/pipeline/PIPELINE-REPORT.json +0 -153
  90. package/reports/pipeline/acquire_apisguru.json +0 -17
  91. package/reports/pipeline/capabilities.json +0 -38
  92. package/reports/pipeline/discover_azure_recursive.json +0 -1551
  93. package/reports/pipeline/discover_github.json +0 -25
  94. package/reports/pipeline/discover_github_repos.json +0 -49
  95. package/reports/pipeline/discover_swaggerhub.json +0 -24
  96. package/reports/pipeline/discover_well_known.json +0 -23
  97. package/reports/pipeline/fetch_specs.json +0 -19
  98. package/reports/pipeline/generate_providers.json +0 -14
  99. package/reports/pipeline/match_registry.json +0 -11
  100. package/reports/pipeline/parse_specs.json +0 -17
  101. package/reports/pipeline/promote_candidates.json +0 -34
  102. package/reports/pipeline/validate.json +0 -30
  103. package/reports/pipeline/validate_smoke_details.json +0 -3835
  104. package/reports/session-report-2026-04-05.html +0 -433
  105. package/seed-apis-direct.mjs +0 -106
  106. package/src/access-control.ts +0 -174
  107. package/src/adapters/base.ts +0 -364
  108. package/src/adapters/claude-desktop.ts +0 -41
  109. package/src/adapters/cline.ts +0 -88
  110. package/src/adapters/continue.ts +0 -91
  111. package/src/adapters/cursor.ts +0 -43
  112. package/src/adapters/custom.ts +0 -188
  113. package/src/adapters/detect.ts +0 -202
  114. package/src/adapters/index.ts +0 -47
  115. package/src/adapters/windsurf.ts +0 -44
  116. package/src/bin-http.ts +0 -45
  117. package/src/bin.ts +0 -34
  118. package/src/capability-router.ts +0 -331
  119. package/src/chainExecutor.ts +0 -730
  120. package/src/chainResolver.test.ts +0 -246
  121. package/src/chainResolver.ts +0 -658
  122. package/src/cli/commands/demo.ts +0 -109
  123. package/src/cli/commands/doctor.ts +0 -435
  124. package/src/cli/commands/index.ts +0 -9
  125. package/src/cli/commands/login.ts +0 -203
  126. package/src/cli/commands/mcp-install.ts +0 -373
  127. package/src/cli/commands/restore.ts +0 -333
  128. package/src/cli/commands/setup.ts +0 -297
  129. package/src/cli/commands/uninstall.ts +0 -240
  130. package/src/cli/index.ts +0 -148
  131. package/src/cli.ts +0 -370
  132. package/src/confirmation.ts +0 -296
  133. package/src/credentials.ts +0 -455
  134. package/src/credits.ts +0 -329
  135. package/src/crypto.ts +0 -75
  136. package/src/discovery.ts +0 -568
  137. package/src/enterprise/env.ts +0 -156
  138. package/src/enterprise/index.ts +0 -7
  139. package/src/enterprise/script-generator.ts +0 -481
  140. package/src/execute-dynamic.ts +0 -617
  141. package/src/execute.ts +0 -2386
  142. package/src/gateway-client.ts +0 -192
  143. package/src/hivr-whitelist.ts +0 -110
  144. package/src/http-api.ts +0 -286
  145. package/src/http-server-minimal.ts +0 -154
  146. package/src/index.ts +0 -2611
  147. package/src/intelligent-gateway.ts +0 -339
  148. package/src/mcp-analytics.ts +0 -156
  149. package/src/metered.ts +0 -149
  150. package/src/open-apis-generated.ts +0 -157
  151. package/src/open-apis.ts +0 -558
  152. package/src/postinstall.ts +0 -18
  153. package/src/product-whitelist.ts +0 -246
  154. package/src/proxy.ts +0 -36
  155. package/src/session.ts +0 -129
  156. package/src/stripe.ts +0 -497
  157. package/src/telemetry.ts +0 -71
  158. package/src/test.ts +0 -135
  159. package/src/types/convex-api.d.ts +0 -20
  160. package/src/types/convex-api.ts +0 -21
  161. package/src/types.ts +0 -109
  162. package/src/ui/colors.ts +0 -219
  163. package/src/ui/errors.ts +0 -394
  164. package/src/ui/index.ts +0 -17
  165. package/src/ui/prompts.ts +0 -390
  166. package/src/ui/spinner.ts +0 -325
  167. package/src/utils/backup.ts +0 -224
  168. package/src/utils/config.ts +0 -318
  169. package/src/utils/os.ts +0 -124
  170. package/src/utils/paths.ts +0 -203
  171. package/src/webhook.ts +0 -107
  172. package/test-10-working.cjs +0 -97
  173. package/test-14-final.cjs +0 -96
  174. package/test-actual-handlers.ts +0 -92
  175. package/test-apilayer-all-14.ts +0 -249
  176. package/test-apilayer-fixed.ts +0 -248
  177. package/test-direct-endpoints.ts +0 -174
  178. package/test-exact-endpoints.ts +0 -144
  179. package/test-final.ts +0 -83
  180. package/test-full-routing.ts +0 -100
  181. package/test-handlers-correct.ts +0 -217
  182. package/test-numverify-key.ts +0 -41
  183. package/test-via-handlers.ts +0 -92
  184. package/test-worldnews.mjs +0 -26
  185. package/tsconfig.json +0 -20
package/src/stripe.ts DELETED
@@ -1,497 +0,0 @@
1
- // Stripe integration for APIClaw credit purchases
2
- import Stripe from 'stripe';
3
- import { config } from 'dotenv';
4
-
5
- // Load environment quietly to avoid polluting MCP stdio output.
6
- config({ path: '.env.local', quiet: true });
7
-
8
- const stripeSecretKey = process.env.STRIPE_SECRET_KEY;
9
-
10
- if (!stripeSecretKey) {
11
- console.warn('STRIPE_SECRET_KEY not set - Stripe features disabled');
12
- }
13
-
14
- const stripe = stripeSecretKey ? new Stripe(stripeSecretKey) : null;
15
-
16
- // Credit packages
17
- export const CREDIT_PACKAGES = {
18
- starter: {
19
- id: 'starter',
20
- name: 'Starter Pack',
21
- amountUsd: 10,
22
- credits: 100,
23
- bonus: 0,
24
- description: '$10 → 100 credits',
25
- },
26
- growth: {
27
- id: 'growth',
28
- name: 'Growth Pack',
29
- amountUsd: 50,
30
- credits: 550,
31
- bonus: 50,
32
- description: '$50 → 550 credits (10% bonus)',
33
- },
34
- scale: {
35
- id: 'scale',
36
- name: 'Scale Pack',
37
- amountUsd: 100,
38
- credits: 1200,
39
- bonus: 200,
40
- description: '$100 → 1,200 credits (20% bonus)',
41
- },
42
- } as const;
43
-
44
- export type PackageType = keyof typeof CREDIT_PACKAGES;
45
-
46
- /**
47
- * Create a Stripe Checkout Session for credit purchase
48
- */
49
- export async function createCheckoutSession(
50
- agentId: string,
51
- packageType: PackageType,
52
- successUrl: string,
53
- cancelUrl: string
54
- ): Promise<{ sessionId: string; url: string } | { error: string }> {
55
- if (!stripe) {
56
- return { error: 'Stripe not configured' };
57
- }
58
-
59
- const pkg = CREDIT_PACKAGES[packageType];
60
- if (!pkg) {
61
- return { error: `Invalid package: ${packageType}` };
62
- }
63
-
64
- try {
65
- const session = await stripe.checkout.sessions.create({
66
- mode: 'payment',
67
- payment_method_types: ['card'],
68
- line_items: [
69
- {
70
- price_data: {
71
- currency: 'usd',
72
- product_data: {
73
- name: `APIClaw ${pkg.name}`,
74
- description: pkg.description,
75
- metadata: {
76
- packageType,
77
- credits: pkg.credits.toString(),
78
- },
79
- },
80
- unit_amount: pkg.amountUsd * 100, // Stripe uses cents
81
- },
82
- quantity: 1,
83
- },
84
- ],
85
- metadata: {
86
- agentId,
87
- packageType,
88
- credits: pkg.credits.toString(),
89
- },
90
- success_url: successUrl,
91
- cancel_url: cancelUrl,
92
- });
93
-
94
- return {
95
- sessionId: session.id,
96
- url: session.url!,
97
- };
98
- } catch (error) {
99
- console.error('Stripe checkout error:', error);
100
- return {
101
- error: error instanceof Error ? error.message : 'Checkout failed',
102
- };
103
- }
104
- }
105
-
106
- /**
107
- * Create a Payment Intent for programmatic payment (agent-to-agent)
108
- */
109
- export async function createPaymentIntent(
110
- agentId: string,
111
- packageType: PackageType
112
- ): Promise<
113
- | { clientSecret: string; paymentIntentId: string; amount: number }
114
- | { error: string }
115
- > {
116
- if (!stripe) {
117
- return { error: 'Stripe not configured' };
118
- }
119
-
120
- const pkg = CREDIT_PACKAGES[packageType];
121
- if (!pkg) {
122
- return { error: `Invalid package: ${packageType}` };
123
- }
124
-
125
- try {
126
- const paymentIntent = await stripe.paymentIntents.create({
127
- amount: pkg.amountUsd * 100,
128
- currency: 'usd',
129
- metadata: {
130
- agentId,
131
- packageType,
132
- credits: pkg.credits.toString(),
133
- },
134
- automatic_payment_methods: {
135
- enabled: true,
136
- },
137
- });
138
-
139
- return {
140
- clientSecret: paymentIntent.client_secret!,
141
- paymentIntentId: paymentIntent.id,
142
- amount: pkg.amountUsd,
143
- };
144
- } catch (error) {
145
- console.error('Stripe payment intent error:', error);
146
- return {
147
- error: error instanceof Error ? error.message : 'Payment intent failed',
148
- };
149
- }
150
- }
151
-
152
- /**
153
- * Verify Stripe webhook signature
154
- */
155
- export function verifyWebhookSignature(
156
- payload: string | Buffer,
157
- signature: string
158
- ): Stripe.Event | null {
159
- if (!stripe) return null;
160
-
161
- const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
162
- if (!webhookSecret) {
163
- console.error('STRIPE_WEBHOOK_SECRET not set');
164
- return null;
165
- }
166
-
167
- try {
168
- return stripe.webhooks.constructEvent(payload, signature, webhookSecret);
169
- } catch (error) {
170
- console.error('Webhook signature verification failed:', error);
171
- return null;
172
- }
173
- }
174
-
175
- /**
176
- * Process webhook event and return credit grant info
177
- */
178
- export interface CreditGrant {
179
- agentId: string;
180
- packageType: string;
181
- credits: number;
182
- amountUsd: number;
183
- stripeSessionId?: string;
184
- stripePaymentIntentId?: string;
185
- }
186
-
187
- export function processWebhookEvent(event: Stripe.Event): CreditGrant | null {
188
- switch (event.type) {
189
- case 'checkout.session.completed': {
190
- const session = event.data.object as Stripe.Checkout.Session;
191
- if (session.payment_status !== 'paid') return null;
192
-
193
- const metadata = session.metadata || {};
194
- const agentId = metadata.agentId;
195
- const packageType = metadata.packageType as PackageType;
196
- const credits = parseInt(metadata.credits || '0', 10);
197
-
198
- if (!agentId || !packageType || !credits) {
199
- console.error('Missing metadata in checkout session:', metadata);
200
- return null;
201
- }
202
-
203
- return {
204
- agentId,
205
- packageType,
206
- credits,
207
- amountUsd: (session.amount_total || 0) / 100,
208
- stripeSessionId: session.id,
209
- };
210
- }
211
-
212
- case 'payment_intent.succeeded': {
213
- const paymentIntent = event.data.object as Stripe.PaymentIntent;
214
- const metadata = paymentIntent.metadata || {};
215
- const agentId = metadata.agentId;
216
- const packageType = metadata.packageType as PackageType;
217
- const credits = parseInt(metadata.credits || '0', 10);
218
-
219
- if (!agentId || !packageType || !credits) {
220
- console.error('Missing metadata in payment intent:', metadata);
221
- return null;
222
- }
223
-
224
- return {
225
- agentId,
226
- packageType,
227
- credits,
228
- amountUsd: paymentIntent.amount / 100,
229
- stripePaymentIntentId: paymentIntent.id,
230
- };
231
- }
232
-
233
- default:
234
- return null;
235
- }
236
- }
237
-
238
- /**
239
- * Get Stripe instance (for advanced usage)
240
- */
241
- export function getStripe(): Stripe | null {
242
- return stripe;
243
- }
244
-
245
- // ============================================
246
- // METERED BILLING (Pay-per-call)
247
- // ============================================
248
-
249
- // Stripe Meter configuration
250
- export const METERED_BILLING = {
251
- meterId: 'mtr_61UFEGojJ0b2awh1441RtJYK3aJTqS9g',
252
- eventName: 'api_call',
253
- priceId: 'price_1TL038RtJYK3aJTqODoFAiVT', // $0.01/unit metered (cost in cents)
254
- productId: 'prod_UJdJXIL3CziTRT',
255
- pricePerUnit: 0.01, // $0.01 per unit (1 cent per unit)
256
- pricePerCall: 0.002, // Legacy: approximate average cost per call for estimates
257
- } as const;
258
-
259
- /**
260
- * Report API usage to Stripe Meter
261
- * Call this after each successful API call
262
- */
263
- export async function reportUsage(
264
- customerId: string,
265
- calls: number = 1,
266
- idempotencyKey?: string
267
- ): Promise<{ success: boolean; eventId?: string; error?: string }> {
268
- if (!stripe) {
269
- return { success: false, error: 'Stripe not configured' };
270
- }
271
-
272
- try {
273
- // Use Stripe's meter event API
274
- const event = await stripe.billing.meterEvents.create({
275
- event_name: METERED_BILLING.eventName,
276
- payload: {
277
- stripe_customer_id: customerId,
278
- value: calls.toString(),
279
- },
280
- timestamp: Math.floor(Date.now() / 1000),
281
- }, {
282
- idempotencyKey: idempotencyKey || `usage_${customerId}_${Date.now()}_${Math.random()}`,
283
- });
284
-
285
- return { success: true, eventId: event.identifier };
286
- } catch (error) {
287
- console.error('Failed to report usage:', error);
288
- return {
289
- success: false,
290
- error: error instanceof Error ? error.message : 'Usage reporting failed',
291
- };
292
- }
293
- }
294
-
295
- /**
296
- * Create or get a customer in Stripe
297
- */
298
- export async function getOrCreateCustomer(
299
- agentId: string,
300
- email?: string
301
- ): Promise<{ customerId: string } | { error: string }> {
302
- if (!stripe) {
303
- return { error: 'Stripe not configured' };
304
- }
305
-
306
- try {
307
- // Search for existing customer by agentId
308
- const existing = await stripe.customers.search({
309
- query: `metadata['agentId']:'${agentId}'`,
310
- });
311
-
312
- if (existing.data.length > 0) {
313
- return { customerId: existing.data[0].id };
314
- }
315
-
316
- // Create new customer
317
- const customer = await stripe.customers.create({
318
- email: email || `${agentId}@apiclaw.local`,
319
- metadata: {
320
- agentId,
321
- source: 'apiclaw',
322
- },
323
- });
324
-
325
- return { customerId: customer.id };
326
- } catch (error) {
327
- console.error('Failed to get/create customer:', error);
328
- return {
329
- error: error instanceof Error ? error.message : 'Customer creation failed',
330
- };
331
- }
332
- }
333
-
334
- /**
335
- * Create a metered subscription for pay-per-call billing
336
- */
337
- export async function createMeteredSubscription(
338
- customerId: string,
339
- paymentMethodId?: string
340
- ): Promise<{ subscriptionId: string; status: string } | { error: string }> {
341
- if (!stripe) {
342
- return { error: 'Stripe not configured' };
343
- }
344
-
345
- try {
346
- // If payment method provided, attach it
347
- if (paymentMethodId) {
348
- await stripe.paymentMethods.attach(paymentMethodId, {
349
- customer: customerId,
350
- });
351
- await stripe.customers.update(customerId, {
352
- invoice_settings: {
353
- default_payment_method: paymentMethodId,
354
- },
355
- });
356
- }
357
-
358
- // Create subscription with metered price
359
- const subscription = await stripe.subscriptions.create({
360
- customer: customerId,
361
- items: [
362
- {
363
- price: METERED_BILLING.priceId,
364
- },
365
- ],
366
- payment_behavior: 'default_incomplete',
367
- payment_settings: {
368
- save_default_payment_method: 'on_subscription',
369
- },
370
- expand: ['latest_invoice.payment_intent'],
371
- });
372
-
373
- return {
374
- subscriptionId: subscription.id,
375
- status: subscription.status,
376
- };
377
- } catch (error) {
378
- console.error('Failed to create metered subscription:', error);
379
- return {
380
- error: error instanceof Error ? error.message : 'Subscription creation failed',
381
- };
382
- }
383
- }
384
-
385
- /**
386
- * Create a checkout session for metered billing subscription
387
- */
388
- export async function createMeteredCheckoutSession(
389
- agentId: string,
390
- successUrl: string,
391
- cancelUrl: string
392
- ): Promise<{ sessionId: string; url: string } | { error: string }> {
393
- if (!stripe) {
394
- return { error: 'Stripe not configured' };
395
- }
396
-
397
- try {
398
- const session = await stripe.checkout.sessions.create({
399
- mode: 'subscription',
400
- payment_method_types: ['card'],
401
- line_items: [
402
- {
403
- price: METERED_BILLING.priceId,
404
- },
405
- ],
406
- metadata: {
407
- agentId,
408
- billingType: 'metered',
409
- },
410
- subscription_data: {
411
- metadata: {
412
- agentId,
413
- billingType: 'metered',
414
- },
415
- },
416
- success_url: successUrl,
417
- cancel_url: cancelUrl,
418
- });
419
-
420
- return {
421
- sessionId: session.id,
422
- url: session.url!,
423
- };
424
- } catch (error) {
425
- console.error('Metered checkout error:', error);
426
- return {
427
- error: error instanceof Error ? error.message : 'Checkout failed',
428
- };
429
- }
430
- }
431
-
432
- /**
433
- * Get usage summary for a subscription
434
- */
435
- export async function getUsageSummary(
436
- subscriptionId: string
437
- ): Promise<{ totalCalls: number; totalCost: number; period: { start: number; end: number } } | { error: string }> {
438
- if (!stripe) {
439
- return { error: 'Stripe not configured' };
440
- }
441
-
442
- try {
443
- // Get subscription details - use raw API response
444
- const subscription = await stripe.subscriptions.retrieve(subscriptionId);
445
- const subData = subscription as unknown as {
446
- current_period_start: number;
447
- current_period_end: number;
448
- status: string;
449
- };
450
-
451
- // For metered billing with meters, usage is tracked via meter events
452
- // The actual usage amount will show up on the invoice at period end
453
- // For now, return period info and note that detailed usage is on the Stripe dashboard
454
-
455
- return {
456
- totalCalls: 0, // Usage tracked via meter events, visible in Stripe dashboard
457
- totalCost: 0,
458
- period: {
459
- start: subData.current_period_start || Math.floor(Date.now() / 1000),
460
- end: subData.current_period_end || Math.floor(Date.now() / 1000) + 30 * 24 * 3600,
461
- },
462
- };
463
- } catch (error) {
464
- console.error('Failed to get usage summary:', error);
465
- return {
466
- error: error instanceof Error ? error.message : 'Usage summary failed',
467
- };
468
- }
469
- }
470
-
471
- /**
472
- * Check if a customer has an active metered subscription
473
- */
474
- export async function hasActiveMeteredSubscription(
475
- customerId: string
476
- ): Promise<{ active: boolean; subscriptionId?: string }> {
477
- if (!stripe) {
478
- return { active: false };
479
- }
480
-
481
- try {
482
- const subscriptions = await stripe.subscriptions.list({
483
- customer: customerId,
484
- status: 'active',
485
- price: METERED_BILLING.priceId,
486
- });
487
-
488
- if (subscriptions.data.length > 0) {
489
- return { active: true, subscriptionId: subscriptions.data[0].id };
490
- }
491
-
492
- return { active: false };
493
- } catch (error) {
494
- console.error('Failed to check subscription:', error);
495
- return { active: false };
496
- }
497
- }
package/src/telemetry.ts DELETED
@@ -1,71 +0,0 @@
1
- /**
2
- * APIClaw Telemetry - Anonymous usage tracking
3
- *
4
- * Tracks:
5
- * - Server starts
6
- * - Search queries (query text only, no PII)
7
- * - API executions (which APIs are popular)
8
- *
9
- * All data is anonymous. No personal information is collected.
10
- * Disable with APICLAW_TELEMETRY=false
11
- */
12
-
13
- const TELEMETRY_ENDPOINT = 'https://brilliant-puffin-712.eu-west-1.convex.cloud/api/mutation';
14
-
15
- interface TelemetryEvent {
16
- type: 'startup' | 'search' | 'execute' | 'discovery';
17
- query?: string;
18
- apiId?: string;
19
- resultCount?: number;
20
- responseTimeMs?: number;
21
- version?: string;
22
- platform?: string;
23
- nodeVersion?: string;
24
- }
25
-
26
- const isEnabled = (): boolean => {
27
- return process.env.APICLAW_TELEMETRY !== 'false';
28
- };
29
-
30
- const getContext = () => ({
31
- version: process.env.npm_package_version || 'unknown',
32
- platform: process.platform,
33
- nodeVersion: process.version,
34
- timestamp: Date.now(),
35
- });
36
-
37
- export const track = async (event: TelemetryEvent): Promise<void> => {
38
- if (!isEnabled()) return;
39
-
40
- try {
41
- const payload = {
42
- ...event,
43
- ...getContext(),
44
- };
45
-
46
- // Fire and forget - don't block the main flow
47
- fetch(TELEMETRY_ENDPOINT, {
48
- method: 'POST',
49
- headers: { 'Content-Type': 'application/json' },
50
- body: JSON.stringify({
51
- path: 'telemetry:track',
52
- args: { event: payload },
53
- }),
54
- }).catch(() => {
55
- // Silently fail - telemetry should never break the app
56
- });
57
- } catch {
58
- // Silently fail
59
- }
60
- };
61
-
62
- export const trackStartup = () => track({ type: 'startup' });
63
-
64
- export const trackSearch = (query: string, resultCount: number, responseTimeMs: number) =>
65
- track({ type: 'search', query, resultCount, responseTimeMs });
66
-
67
- export const trackExecute = (apiId: string, responseTimeMs: number) =>
68
- track({ type: 'execute', apiId, responseTimeMs });
69
-
70
- export const trackDiscovery = (resultCount: number) =>
71
- track({ type: 'discovery', resultCount });
package/src/test.ts DELETED
@@ -1,135 +0,0 @@
1
- #!/usr/bin/env npx tsx
2
- /**
3
- * APIClaw End-to-End Test
4
- * Tests the full flow: credits → purchase → real credentials
5
- */
6
-
7
- import { config } from 'dotenv';
8
- config({ path: '.env.local' });
9
-
10
- import {
11
- getAgentCredits,
12
- addCredits,
13
- purchaseAPIAccess,
14
- getBalanceSummary,
15
- getProvidersWithRealCredentials,
16
- } from './credits.js';
17
- import { hasRealCredentials } from './credentials.js';
18
- import { CREDIT_PACKAGES, createCheckoutSession, createPaymentIntent } from './stripe.js';
19
-
20
- const TEST_AGENT_ID = 'test_agent_001';
21
-
22
- function log(msg: string) {
23
- console.log(`\n${'='.repeat(60)}\n${msg}\n${'='.repeat(60)}`);
24
- }
25
-
26
- function logResult(label: string, data: unknown) {
27
- console.log(`\n[${label}]`);
28
- console.log(JSON.stringify(data, null, 2));
29
- }
30
-
31
- async function runTests() {
32
- console.log('\n🧪 APIClaw Connected Infrastructure Test\n');
33
-
34
- // Test 1: Check real credentials availability
35
- log('TEST 1: Real Credentials Check');
36
- const realCredProviders = getProvidersWithRealCredentials();
37
- console.log('Providers with real credentials:', realCredProviders);
38
- console.log('46elks real:', hasRealCredentials('46elks'));
39
- console.log('Twilio real:', hasRealCredentials('twilio'));
40
-
41
- // Test 2: Credit packages
42
- log('TEST 2: Credit Packages');
43
- logResult('Packages', CREDIT_PACKAGES);
44
-
45
- // Test 3: Add credits to agent
46
- log('TEST 3: Add Credits');
47
- const initialCredits = getAgentCredits(TEST_AGENT_ID);
48
- logResult('Initial balance', initialCredits);
49
-
50
- const afterAdd = addCredits(TEST_AGENT_ID, 50);
51
- logResult('After adding $50', afterAdd);
52
-
53
- // Test 4: Check balance summary
54
- log('TEST 4: Balance Summary');
55
- const summary = getBalanceSummary(TEST_AGENT_ID);
56
- logResult('Summary', summary);
57
-
58
- // Test 5: Purchase 46elks access
59
- log('TEST 5: Purchase 46elks Access');
60
- const purchase46elks = purchaseAPIAccess(TEST_AGENT_ID, '46elks', 10);
61
- logResult('46elks Purchase Result', purchase46elks);
62
-
63
- if (purchase46elks.success && purchase46elks.purchase) {
64
- console.log('\n🔑 CREDENTIALS RECEIVED:');
65
- console.log(' Type:', purchase46elks.purchase.credentials?.type);
66
- if (purchase46elks.purchase.credentials?.type === 'basic') {
67
- console.log(' Username:', purchase46elks.purchase.credentials?.username);
68
- console.log(' Password:', purchase46elks.purchase.credentials?.password?.slice(0, 8) + '...');
69
- }
70
- console.log(' Real credentials:', hasRealCredentials('46elks'));
71
- }
72
-
73
- // Test 6: Purchase Twilio access
74
- log('TEST 6: Purchase Twilio Access');
75
- const purchaseTwilio = purchaseAPIAccess(TEST_AGENT_ID, 'twilio', 10);
76
- logResult('Twilio Purchase Result', purchaseTwilio);
77
-
78
- if (purchaseTwilio.success && purchaseTwilio.purchase) {
79
- console.log('\n🔑 CREDENTIALS RECEIVED:');
80
- console.log(' Type:', purchaseTwilio.purchase.credentials?.type);
81
- if (purchaseTwilio.purchase.credentials?.type === 'basic') {
82
- console.log(' Account SID:', purchaseTwilio.purchase.credentials?.username);
83
- console.log(' Auth Token:', purchaseTwilio.purchase.credentials?.password?.slice(0, 8) + '...');
84
- }
85
- console.log(' Real credentials:', hasRealCredentials('twilio'));
86
- }
87
-
88
- // Test 7: Final balance
89
- log('TEST 7: Final Balance');
90
- const finalSummary = getBalanceSummary(TEST_AGENT_ID);
91
- logResult('Final Summary', {
92
- balance: finalSummary.credits.balance_usd,
93
- active_purchases: finalSummary.active_purchases.length,
94
- total_spent: finalSummary.total_spent_usd,
95
- real_credential_providers: finalSummary.real_credentials_available,
96
- });
97
-
98
- // Test 8: Stripe integration (if configured)
99
- log('TEST 8: Stripe Integration');
100
- if (process.env.STRIPE_SECRET_KEY) {
101
- console.log('Stripe is configured!');
102
-
103
- // Test creating a payment intent
104
- const paymentIntent = await createPaymentIntent('test_agent_stripe', 'starter');
105
- if ('error' in paymentIntent) {
106
- console.log('Payment Intent Error:', paymentIntent.error);
107
- } else {
108
- console.log('Payment Intent Created:');
109
- console.log(' ID:', paymentIntent.paymentIntentId);
110
- console.log(' Amount: $' + paymentIntent.amount);
111
- console.log(' Client Secret:', paymentIntent.clientSecret.slice(0, 20) + '...');
112
- }
113
- } else {
114
- console.log('Stripe not configured - skipping');
115
- }
116
-
117
- // Test 9: Insufficient balance
118
- log('TEST 9: Insufficient Balance Check');
119
- const insufficientPurchase = purchaseAPIAccess(TEST_AGENT_ID, '46elks', 1000);
120
- logResult('Should fail', insufficientPurchase);
121
-
122
- // Summary
123
- log('TEST SUMMARY');
124
- console.log(`
125
- ✅ Real credentials available for: ${realCredProviders.join(', ') || 'none'}
126
- ✅ Agent can add credits
127
- ✅ Agent can purchase API access
128
- ✅ Real 46elks/Twilio credentials returned when available
129
- ✅ Insufficient balance check works
130
- ${process.env.STRIPE_SECRET_KEY ? '✅ Stripe integration working' : '⚠️ Stripe not configured'}
131
- `);
132
- }
133
-
134
- // Run tests
135
- runTests().catch(console.error);