@nordsym/apiclaw 1.7.3 → 1.7.5
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/convex/_generated/api.d.ts +115 -0
- package/convex/_generated/api.js +23 -0
- package/convex/_generated/dataModel.d.ts +60 -0
- package/convex/_generated/server.d.ts +143 -0
- package/convex/_generated/server.js +93 -0
- package/convex/adminActivate.d.ts +3 -0
- package/convex/adminActivate.d.ts.map +1 -0
- package/convex/adminActivate.js +47 -0
- package/convex/adminActivate.js.map +1 -0
- package/convex/adminActivate.ts +54 -0
- package/convex/adminStats.d.ts +3 -0
- package/convex/adminStats.d.ts.map +1 -0
- package/convex/adminStats.js +42 -0
- package/convex/adminStats.js.map +1 -0
- package/convex/adminStats.ts +44 -0
- package/convex/agents.d.ts +76 -0
- package/convex/agents.d.ts.map +1 -0
- package/convex/agents.js +699 -0
- package/convex/agents.js.map +1 -0
- package/convex/agents.ts +814 -0
- package/convex/analytics.d.ts +5 -0
- package/convex/analytics.d.ts.map +1 -0
- package/convex/analytics.js +166 -0
- package/convex/analytics.js.map +1 -0
- package/convex/analytics.ts +186 -0
- package/convex/billing.d.ts +88 -0
- package/convex/billing.d.ts.map +1 -0
- package/convex/billing.js +655 -0
- package/convex/billing.js.map +1 -0
- package/convex/billing.ts +791 -0
- package/convex/capabilities.d.ts +9 -0
- package/convex/capabilities.d.ts.map +1 -0
- package/convex/capabilities.js +145 -0
- package/convex/capabilities.js.map +1 -0
- package/convex/capabilities.ts +157 -0
- package/convex/chains.d.ts +68 -0
- package/convex/chains.d.ts.map +1 -0
- package/convex/chains.js +1105 -0
- package/convex/chains.js.map +1 -0
- package/convex/chains.ts +1318 -0
- package/convex/credits.d.ts +25 -0
- package/convex/credits.d.ts.map +1 -0
- package/convex/credits.js +186 -0
- package/convex/credits.js.map +1 -0
- package/convex/credits.ts +211 -0
- package/convex/crons.d.ts +3 -0
- package/convex/crons.d.ts.map +1 -0
- package/convex/crons.js +17 -0
- package/convex/crons.js.map +1 -0
- package/convex/crons.ts +28 -0
- package/convex/directCall.d.ts +72 -0
- package/convex/directCall.d.ts.map +1 -0
- package/convex/directCall.js +627 -0
- package/convex/directCall.js.map +1 -0
- package/convex/directCall.ts +678 -0
- package/convex/earnProgress.d.ts +58 -0
- package/convex/earnProgress.d.ts.map +1 -0
- package/convex/earnProgress.js +649 -0
- package/convex/earnProgress.js.map +1 -0
- package/convex/earnProgress.ts +753 -0
- package/convex/email.d.ts +14 -0
- package/convex/email.d.ts.map +1 -0
- package/convex/email.js +300 -0
- package/convex/email.js.map +1 -0
- package/convex/email.ts +329 -0
- package/convex/feedback.d.ts +7 -0
- package/convex/feedback.d.ts.map +1 -0
- package/convex/feedback.js +227 -0
- package/convex/feedback.js.map +1 -0
- package/convex/feedback.ts +265 -0
- package/convex/http.d.ts +3 -0
- package/convex/http.d.ts.map +1 -0
- package/convex/http.js +1405 -0
- package/convex/http.js.map +1 -0
- package/convex/http.ts +1577 -0
- package/convex/inbound.d.ts +2 -0
- package/convex/inbound.d.ts.map +1 -0
- package/convex/inbound.js +32 -0
- package/convex/inbound.js.map +1 -0
- package/convex/inbound.ts +32 -0
- package/convex/logs.d.ts +48 -0
- package/convex/logs.d.ts.map +1 -0
- package/convex/logs.js +592 -0
- package/convex/logs.js.map +1 -0
- package/convex/logs.ts +662 -0
- package/convex/mou.d.ts +6 -0
- package/convex/mou.d.ts.map +1 -0
- package/convex/mou.js +82 -0
- package/convex/mou.js.map +1 -0
- package/convex/mou.ts +91 -0
- package/convex/providerKeys.d.ts +31 -0
- package/convex/providerKeys.d.ts.map +1 -0
- package/convex/providerKeys.js +257 -0
- package/convex/providerKeys.js.map +1 -0
- package/convex/providerKeys.ts +289 -0
- package/convex/providers.d.ts +32 -0
- package/convex/providers.d.ts.map +1 -0
- package/convex/providers.js +814 -0
- package/convex/providers.js.map +1 -0
- package/convex/providers.ts +909 -0
- package/convex/purchases.d.ts +7 -0
- package/convex/purchases.d.ts.map +1 -0
- package/convex/purchases.js +157 -0
- package/convex/purchases.js.map +1 -0
- package/convex/purchases.ts +183 -0
- package/convex/ratelimit.d.ts +4 -0
- package/convex/ratelimit.d.ts.map +1 -0
- package/convex/ratelimit.js +91 -0
- package/convex/ratelimit.js.map +1 -0
- package/convex/ratelimit.ts +104 -0
- package/convex/schema.ts +805 -0
- package/convex/searchLogs.d.ts +4 -0
- package/convex/searchLogs.d.ts.map +1 -0
- package/convex/searchLogs.js +129 -0
- package/convex/searchLogs.js.map +1 -0
- package/convex/searchLogs.ts +146 -0
- package/convex/seedAPILayerAPIs.d.ts +7 -0
- package/convex/seedAPILayerAPIs.d.ts.map +1 -0
- package/convex/seedAPILayerAPIs.js +177 -0
- package/convex/seedAPILayerAPIs.js.map +1 -0
- package/convex/seedAPILayerAPIs.ts +191 -0
- package/convex/seedDirectCallConfigs.d.ts +2 -0
- package/convex/seedDirectCallConfigs.d.ts.map +1 -0
- package/convex/seedDirectCallConfigs.js +324 -0
- package/convex/seedDirectCallConfigs.js.map +1 -0
- package/convex/seedDirectCallConfigs.ts +336 -0
- package/convex/seedPratham.d.ts +6 -0
- package/convex/seedPratham.d.ts.map +1 -0
- package/convex/seedPratham.js +150 -0
- package/convex/seedPratham.js.map +1 -0
- package/convex/seedPratham.ts +161 -0
- package/convex/spendAlerts.d.ts +36 -0
- package/convex/spendAlerts.d.ts.map +1 -0
- package/convex/spendAlerts.js +380 -0
- package/convex/spendAlerts.js.map +1 -0
- package/convex/spendAlerts.ts +442 -0
- package/convex/stripeActions.d.ts +19 -0
- package/convex/stripeActions.d.ts.map +1 -0
- package/convex/stripeActions.js +411 -0
- package/convex/stripeActions.js.map +1 -0
- package/convex/stripeActions.ts +512 -0
- package/convex/teams.d.ts +21 -0
- package/convex/teams.d.ts.map +1 -0
- package/convex/teams.js +215 -0
- package/convex/teams.js.map +1 -0
- package/convex/teams.ts +243 -0
- package/convex/telemetry.d.ts +4 -0
- package/convex/telemetry.d.ts.map +1 -0
- package/convex/telemetry.js +74 -0
- package/convex/telemetry.js.map +1 -0
- package/convex/telemetry.ts +81 -0
- package/convex/tsconfig.json +25 -0
- package/convex/updateAPIStatus.d.ts +6 -0
- package/convex/updateAPIStatus.d.ts.map +1 -0
- package/convex/updateAPIStatus.js +40 -0
- package/convex/updateAPIStatus.js.map +1 -0
- package/convex/updateAPIStatus.ts +45 -0
- package/convex/usage.d.ts +27 -0
- package/convex/usage.d.ts.map +1 -0
- package/convex/usage.js +229 -0
- package/convex/usage.js.map +1 -0
- package/convex/usage.ts +260 -0
- package/convex/waitlist.d.ts +4 -0
- package/convex/waitlist.d.ts.map +1 -0
- package/convex/waitlist.js +49 -0
- package/convex/waitlist.js.map +1 -0
- package/convex/waitlist.ts +55 -0
- package/convex/webhooks.d.ts +12 -0
- package/convex/webhooks.d.ts.map +1 -0
- package/convex/webhooks.js +410 -0
- package/convex/webhooks.js.map +1 -0
- package/convex/webhooks.ts +494 -0
- package/convex/workspaces.d.ts +31 -0
- package/convex/workspaces.d.ts.map +1 -0
- package/convex/workspaces.js +975 -0
- package/convex/workspaces.js.map +1 -0
- package/convex/workspaces.ts +1130 -0
- package/dist/bin.js +0 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +10 -0
- package/dist/chain-types.d.ts +0 -187
- package/dist/chain-types.d.ts.map +0 -1
- package/dist/chain-types.js +0 -33
- package/dist/chain-types.js.map +0 -1
- package/dist/registry/apis.json.bak +0 -248811
- package/dist/src/bin.js +0 -17
- package/dist/src/capability-router.js +0 -240
- package/dist/src/chainExecutor.js +0 -451
- package/dist/src/chainResolver.js +0 -518
- package/dist/src/cli/commands/doctor.js +0 -324
- package/dist/src/cli/commands/mcp-install.js +0 -255
- package/dist/src/cli/commands/restore.js +0 -259
- package/dist/src/cli/commands/setup.js +0 -205
- package/dist/src/cli/commands/uninstall.js +0 -188
- package/dist/src/cli/index.js +0 -111
- package/dist/src/cli.js +0 -302
- package/dist/src/confirmation.js +0 -240
- package/dist/src/credentials.js +0 -357
- package/dist/src/credits.js +0 -260
- package/dist/src/crypto.js +0 -66
- package/dist/src/discovery.js +0 -504
- package/dist/src/enterprise/env.js +0 -123
- package/dist/src/enterprise/script-generator.js +0 -460
- package/dist/src/execute-dynamic.js +0 -473
- package/dist/src/execute.js +0 -1727
- package/dist/src/index.js +0 -2062
- package/dist/src/metered.js +0 -80
- package/dist/src/open-apis.js +0 -276
- package/dist/src/proxy.js +0 -28
- package/dist/src/session.js +0 -86
- package/dist/src/stripe.js +0 -407
- package/dist/src/telemetry.js +0 -49
- package/dist/src/types.js +0 -2
- package/dist/src/utils/backup.js +0 -181
- package/dist/src/utils/config.js +0 -220
- package/dist/src/utils/os.js +0 -105
- package/dist/src/utils/paths.js +0 -159
package/dist/src/stripe.js
DELETED
|
@@ -1,407 +0,0 @@
|
|
|
1
|
-
// Stripe integration for APIClaw credit purchases
|
|
2
|
-
import Stripe from 'stripe';
|
|
3
|
-
import { config } from 'dotenv';
|
|
4
|
-
// Load environment quietly to avoid polluting MCP stdio output.
|
|
5
|
-
config({ path: '.env.local', quiet: true });
|
|
6
|
-
const stripeSecretKey = process.env.STRIPE_SECRET_KEY;
|
|
7
|
-
if (!stripeSecretKey) {
|
|
8
|
-
console.warn('STRIPE_SECRET_KEY not set - Stripe features disabled');
|
|
9
|
-
}
|
|
10
|
-
const stripe = stripeSecretKey ? new Stripe(stripeSecretKey) : null;
|
|
11
|
-
// Credit packages
|
|
12
|
-
export const CREDIT_PACKAGES = {
|
|
13
|
-
starter: {
|
|
14
|
-
id: 'starter',
|
|
15
|
-
name: 'Starter Pack',
|
|
16
|
-
amountUsd: 10,
|
|
17
|
-
credits: 100,
|
|
18
|
-
bonus: 0,
|
|
19
|
-
description: '$10 → 100 credits',
|
|
20
|
-
},
|
|
21
|
-
growth: {
|
|
22
|
-
id: 'growth',
|
|
23
|
-
name: 'Growth Pack',
|
|
24
|
-
amountUsd: 50,
|
|
25
|
-
credits: 550,
|
|
26
|
-
bonus: 50,
|
|
27
|
-
description: '$50 → 550 credits (10% bonus)',
|
|
28
|
-
},
|
|
29
|
-
scale: {
|
|
30
|
-
id: 'scale',
|
|
31
|
-
name: 'Scale Pack',
|
|
32
|
-
amountUsd: 100,
|
|
33
|
-
credits: 1200,
|
|
34
|
-
bonus: 200,
|
|
35
|
-
description: '$100 → 1,200 credits (20% bonus)',
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Create a Stripe Checkout Session for credit purchase
|
|
40
|
-
*/
|
|
41
|
-
export async function createCheckoutSession(agentId, packageType, successUrl, cancelUrl) {
|
|
42
|
-
if (!stripe) {
|
|
43
|
-
return { error: 'Stripe not configured' };
|
|
44
|
-
}
|
|
45
|
-
const pkg = CREDIT_PACKAGES[packageType];
|
|
46
|
-
if (!pkg) {
|
|
47
|
-
return { error: `Invalid package: ${packageType}` };
|
|
48
|
-
}
|
|
49
|
-
try {
|
|
50
|
-
const session = await stripe.checkout.sessions.create({
|
|
51
|
-
mode: 'payment',
|
|
52
|
-
payment_method_types: ['card'],
|
|
53
|
-
line_items: [
|
|
54
|
-
{
|
|
55
|
-
price_data: {
|
|
56
|
-
currency: 'usd',
|
|
57
|
-
product_data: {
|
|
58
|
-
name: `APIClaw ${pkg.name}`,
|
|
59
|
-
description: pkg.description,
|
|
60
|
-
metadata: {
|
|
61
|
-
packageType,
|
|
62
|
-
credits: pkg.credits.toString(),
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
unit_amount: pkg.amountUsd * 100, // Stripe uses cents
|
|
66
|
-
},
|
|
67
|
-
quantity: 1,
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
metadata: {
|
|
71
|
-
agentId,
|
|
72
|
-
packageType,
|
|
73
|
-
credits: pkg.credits.toString(),
|
|
74
|
-
},
|
|
75
|
-
success_url: successUrl,
|
|
76
|
-
cancel_url: cancelUrl,
|
|
77
|
-
});
|
|
78
|
-
return {
|
|
79
|
-
sessionId: session.id,
|
|
80
|
-
url: session.url,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
catch (error) {
|
|
84
|
-
console.error('Stripe checkout error:', error);
|
|
85
|
-
return {
|
|
86
|
-
error: error instanceof Error ? error.message : 'Checkout failed',
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Create a Payment Intent for programmatic payment (agent-to-agent)
|
|
92
|
-
*/
|
|
93
|
-
export async function createPaymentIntent(agentId, packageType) {
|
|
94
|
-
if (!stripe) {
|
|
95
|
-
return { error: 'Stripe not configured' };
|
|
96
|
-
}
|
|
97
|
-
const pkg = CREDIT_PACKAGES[packageType];
|
|
98
|
-
if (!pkg) {
|
|
99
|
-
return { error: `Invalid package: ${packageType}` };
|
|
100
|
-
}
|
|
101
|
-
try {
|
|
102
|
-
const paymentIntent = await stripe.paymentIntents.create({
|
|
103
|
-
amount: pkg.amountUsd * 100,
|
|
104
|
-
currency: 'usd',
|
|
105
|
-
metadata: {
|
|
106
|
-
agentId,
|
|
107
|
-
packageType,
|
|
108
|
-
credits: pkg.credits.toString(),
|
|
109
|
-
},
|
|
110
|
-
automatic_payment_methods: {
|
|
111
|
-
enabled: true,
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
return {
|
|
115
|
-
clientSecret: paymentIntent.client_secret,
|
|
116
|
-
paymentIntentId: paymentIntent.id,
|
|
117
|
-
amount: pkg.amountUsd,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
console.error('Stripe payment intent error:', error);
|
|
122
|
-
return {
|
|
123
|
-
error: error instanceof Error ? error.message : 'Payment intent failed',
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Verify Stripe webhook signature
|
|
129
|
-
*/
|
|
130
|
-
export function verifyWebhookSignature(payload, signature) {
|
|
131
|
-
if (!stripe)
|
|
132
|
-
return null;
|
|
133
|
-
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
|
|
134
|
-
if (!webhookSecret) {
|
|
135
|
-
console.error('STRIPE_WEBHOOK_SECRET not set');
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
try {
|
|
139
|
-
return stripe.webhooks.constructEvent(payload, signature, webhookSecret);
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
console.error('Webhook signature verification failed:', error);
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
export function processWebhookEvent(event) {
|
|
147
|
-
switch (event.type) {
|
|
148
|
-
case 'checkout.session.completed': {
|
|
149
|
-
const session = event.data.object;
|
|
150
|
-
if (session.payment_status !== 'paid')
|
|
151
|
-
return null;
|
|
152
|
-
const metadata = session.metadata || {};
|
|
153
|
-
const agentId = metadata.agentId;
|
|
154
|
-
const packageType = metadata.packageType;
|
|
155
|
-
const credits = parseInt(metadata.credits || '0', 10);
|
|
156
|
-
if (!agentId || !packageType || !credits) {
|
|
157
|
-
console.error('Missing metadata in checkout session:', metadata);
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
return {
|
|
161
|
-
agentId,
|
|
162
|
-
packageType,
|
|
163
|
-
credits,
|
|
164
|
-
amountUsd: (session.amount_total || 0) / 100,
|
|
165
|
-
stripeSessionId: session.id,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
case 'payment_intent.succeeded': {
|
|
169
|
-
const paymentIntent = event.data.object;
|
|
170
|
-
const metadata = paymentIntent.metadata || {};
|
|
171
|
-
const agentId = metadata.agentId;
|
|
172
|
-
const packageType = metadata.packageType;
|
|
173
|
-
const credits = parseInt(metadata.credits || '0', 10);
|
|
174
|
-
if (!agentId || !packageType || !credits) {
|
|
175
|
-
console.error('Missing metadata in payment intent:', metadata);
|
|
176
|
-
return null;
|
|
177
|
-
}
|
|
178
|
-
return {
|
|
179
|
-
agentId,
|
|
180
|
-
packageType,
|
|
181
|
-
credits,
|
|
182
|
-
amountUsd: paymentIntent.amount / 100,
|
|
183
|
-
stripePaymentIntentId: paymentIntent.id,
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
default:
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Get Stripe instance (for advanced usage)
|
|
192
|
-
*/
|
|
193
|
-
export function getStripe() {
|
|
194
|
-
return stripe;
|
|
195
|
-
}
|
|
196
|
-
// ============================================
|
|
197
|
-
// METERED BILLING (Pay-per-call)
|
|
198
|
-
// ============================================
|
|
199
|
-
// Stripe Meter configuration
|
|
200
|
-
export const METERED_BILLING = {
|
|
201
|
-
meterId: 'mtr_61UFEGojJ0b2awh1441RtJYK3aJTqS9g',
|
|
202
|
-
eventName: 'api_call',
|
|
203
|
-
priceId: 'price_1T5qNFRtJYK3aJTqzHLnUjKG', // $0.002/call, linked to meter
|
|
204
|
-
productId: 'prod_U3yHbnc4NcLofW',
|
|
205
|
-
pricePerCall: 0.002, // $0.002 per API call
|
|
206
|
-
};
|
|
207
|
-
/**
|
|
208
|
-
* Report API usage to Stripe Meter
|
|
209
|
-
* Call this after each successful API call
|
|
210
|
-
*/
|
|
211
|
-
export async function reportUsage(customerId, calls = 1, idempotencyKey) {
|
|
212
|
-
if (!stripe) {
|
|
213
|
-
return { success: false, error: 'Stripe not configured' };
|
|
214
|
-
}
|
|
215
|
-
try {
|
|
216
|
-
// Use Stripe's meter event API
|
|
217
|
-
const event = await stripe.billing.meterEvents.create({
|
|
218
|
-
event_name: METERED_BILLING.eventName,
|
|
219
|
-
payload: {
|
|
220
|
-
stripe_customer_id: customerId,
|
|
221
|
-
value: calls.toString(),
|
|
222
|
-
},
|
|
223
|
-
timestamp: Math.floor(Date.now() / 1000),
|
|
224
|
-
}, {
|
|
225
|
-
idempotencyKey: idempotencyKey || `usage_${customerId}_${Date.now()}_${Math.random()}`,
|
|
226
|
-
});
|
|
227
|
-
return { success: true, eventId: event.identifier };
|
|
228
|
-
}
|
|
229
|
-
catch (error) {
|
|
230
|
-
console.error('Failed to report usage:', error);
|
|
231
|
-
return {
|
|
232
|
-
success: false,
|
|
233
|
-
error: error instanceof Error ? error.message : 'Usage reporting failed',
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Create or get a customer in Stripe
|
|
239
|
-
*/
|
|
240
|
-
export async function getOrCreateCustomer(agentId, email) {
|
|
241
|
-
if (!stripe) {
|
|
242
|
-
return { error: 'Stripe not configured' };
|
|
243
|
-
}
|
|
244
|
-
try {
|
|
245
|
-
// Search for existing customer by agentId
|
|
246
|
-
const existing = await stripe.customers.search({
|
|
247
|
-
query: `metadata['agentId']:'${agentId}'`,
|
|
248
|
-
});
|
|
249
|
-
if (existing.data.length > 0) {
|
|
250
|
-
return { customerId: existing.data[0].id };
|
|
251
|
-
}
|
|
252
|
-
// Create new customer
|
|
253
|
-
const customer = await stripe.customers.create({
|
|
254
|
-
email: email || `${agentId}@apiclaw.local`,
|
|
255
|
-
metadata: {
|
|
256
|
-
agentId,
|
|
257
|
-
source: 'apiclaw',
|
|
258
|
-
},
|
|
259
|
-
});
|
|
260
|
-
return { customerId: customer.id };
|
|
261
|
-
}
|
|
262
|
-
catch (error) {
|
|
263
|
-
console.error('Failed to get/create customer:', error);
|
|
264
|
-
return {
|
|
265
|
-
error: error instanceof Error ? error.message : 'Customer creation failed',
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Create a metered subscription for pay-per-call billing
|
|
271
|
-
*/
|
|
272
|
-
export async function createMeteredSubscription(customerId, paymentMethodId) {
|
|
273
|
-
if (!stripe) {
|
|
274
|
-
return { error: 'Stripe not configured' };
|
|
275
|
-
}
|
|
276
|
-
try {
|
|
277
|
-
// If payment method provided, attach it
|
|
278
|
-
if (paymentMethodId) {
|
|
279
|
-
await stripe.paymentMethods.attach(paymentMethodId, {
|
|
280
|
-
customer: customerId,
|
|
281
|
-
});
|
|
282
|
-
await stripe.customers.update(customerId, {
|
|
283
|
-
invoice_settings: {
|
|
284
|
-
default_payment_method: paymentMethodId,
|
|
285
|
-
},
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
// Create subscription with metered price
|
|
289
|
-
const subscription = await stripe.subscriptions.create({
|
|
290
|
-
customer: customerId,
|
|
291
|
-
items: [
|
|
292
|
-
{
|
|
293
|
-
price: METERED_BILLING.priceId,
|
|
294
|
-
},
|
|
295
|
-
],
|
|
296
|
-
payment_behavior: 'default_incomplete',
|
|
297
|
-
payment_settings: {
|
|
298
|
-
save_default_payment_method: 'on_subscription',
|
|
299
|
-
},
|
|
300
|
-
expand: ['latest_invoice.payment_intent'],
|
|
301
|
-
});
|
|
302
|
-
return {
|
|
303
|
-
subscriptionId: subscription.id,
|
|
304
|
-
status: subscription.status,
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
catch (error) {
|
|
308
|
-
console.error('Failed to create metered subscription:', error);
|
|
309
|
-
return {
|
|
310
|
-
error: error instanceof Error ? error.message : 'Subscription creation failed',
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Create a checkout session for metered billing subscription
|
|
316
|
-
*/
|
|
317
|
-
export async function createMeteredCheckoutSession(agentId, successUrl, cancelUrl) {
|
|
318
|
-
if (!stripe) {
|
|
319
|
-
return { error: 'Stripe not configured' };
|
|
320
|
-
}
|
|
321
|
-
try {
|
|
322
|
-
const session = await stripe.checkout.sessions.create({
|
|
323
|
-
mode: 'subscription',
|
|
324
|
-
payment_method_types: ['card'],
|
|
325
|
-
line_items: [
|
|
326
|
-
{
|
|
327
|
-
price: METERED_BILLING.priceId,
|
|
328
|
-
},
|
|
329
|
-
],
|
|
330
|
-
metadata: {
|
|
331
|
-
agentId,
|
|
332
|
-
billingType: 'metered',
|
|
333
|
-
},
|
|
334
|
-
subscription_data: {
|
|
335
|
-
metadata: {
|
|
336
|
-
agentId,
|
|
337
|
-
billingType: 'metered',
|
|
338
|
-
},
|
|
339
|
-
},
|
|
340
|
-
success_url: successUrl,
|
|
341
|
-
cancel_url: cancelUrl,
|
|
342
|
-
});
|
|
343
|
-
return {
|
|
344
|
-
sessionId: session.id,
|
|
345
|
-
url: session.url,
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
catch (error) {
|
|
349
|
-
console.error('Metered checkout error:', error);
|
|
350
|
-
return {
|
|
351
|
-
error: error instanceof Error ? error.message : 'Checkout failed',
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Get usage summary for a subscription
|
|
357
|
-
*/
|
|
358
|
-
export async function getUsageSummary(subscriptionId) {
|
|
359
|
-
if (!stripe) {
|
|
360
|
-
return { error: 'Stripe not configured' };
|
|
361
|
-
}
|
|
362
|
-
try {
|
|
363
|
-
// Get subscription details - use raw API response
|
|
364
|
-
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
|
|
365
|
-
const subData = subscription;
|
|
366
|
-
// For metered billing with meters, usage is tracked via meter events
|
|
367
|
-
// The actual usage amount will show up on the invoice at period end
|
|
368
|
-
// For now, return period info and note that detailed usage is on the Stripe dashboard
|
|
369
|
-
return {
|
|
370
|
-
totalCalls: 0, // Usage tracked via meter events, visible in Stripe dashboard
|
|
371
|
-
totalCost: 0,
|
|
372
|
-
period: {
|
|
373
|
-
start: subData.current_period_start || Math.floor(Date.now() / 1000),
|
|
374
|
-
end: subData.current_period_end || Math.floor(Date.now() / 1000) + 30 * 24 * 3600,
|
|
375
|
-
},
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
catch (error) {
|
|
379
|
-
console.error('Failed to get usage summary:', error);
|
|
380
|
-
return {
|
|
381
|
-
error: error instanceof Error ? error.message : 'Usage summary failed',
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Check if a customer has an active metered subscription
|
|
387
|
-
*/
|
|
388
|
-
export async function hasActiveMeteredSubscription(customerId) {
|
|
389
|
-
if (!stripe) {
|
|
390
|
-
return { active: false };
|
|
391
|
-
}
|
|
392
|
-
try {
|
|
393
|
-
const subscriptions = await stripe.subscriptions.list({
|
|
394
|
-
customer: customerId,
|
|
395
|
-
status: 'active',
|
|
396
|
-
price: METERED_BILLING.priceId,
|
|
397
|
-
});
|
|
398
|
-
if (subscriptions.data.length > 0) {
|
|
399
|
-
return { active: true, subscriptionId: subscriptions.data[0].id };
|
|
400
|
-
}
|
|
401
|
-
return { active: false };
|
|
402
|
-
}
|
|
403
|
-
catch (error) {
|
|
404
|
-
console.error('Failed to check subscription:', error);
|
|
405
|
-
return { active: false };
|
|
406
|
-
}
|
|
407
|
-
}
|
package/dist/src/telemetry.js
DELETED
|
@@ -1,49 +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
|
-
const TELEMETRY_ENDPOINT = 'https://agile-crane-840.convex.cloud/api/mutation';
|
|
13
|
-
const isEnabled = () => {
|
|
14
|
-
return process.env.APICLAW_TELEMETRY !== 'false';
|
|
15
|
-
};
|
|
16
|
-
const getContext = () => ({
|
|
17
|
-
version: process.env.npm_package_version || 'unknown',
|
|
18
|
-
platform: process.platform,
|
|
19
|
-
nodeVersion: process.version,
|
|
20
|
-
timestamp: Date.now(),
|
|
21
|
-
});
|
|
22
|
-
export const track = async (event) => {
|
|
23
|
-
if (!isEnabled())
|
|
24
|
-
return;
|
|
25
|
-
try {
|
|
26
|
-
const payload = {
|
|
27
|
-
...event,
|
|
28
|
-
...getContext(),
|
|
29
|
-
};
|
|
30
|
-
// Fire and forget - don't block the main flow
|
|
31
|
-
fetch(TELEMETRY_ENDPOINT, {
|
|
32
|
-
method: 'POST',
|
|
33
|
-
headers: { 'Content-Type': 'application/json' },
|
|
34
|
-
body: JSON.stringify({
|
|
35
|
-
path: 'telemetry:track',
|
|
36
|
-
args: { event: payload },
|
|
37
|
-
}),
|
|
38
|
-
}).catch(() => {
|
|
39
|
-
// Silently fail - telemetry should never break the app
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
// Silently fail
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
export const trackStartup = () => track({ type: 'startup' });
|
|
47
|
-
export const trackSearch = (query, resultCount, responseTimeMs) => track({ type: 'search', query, resultCount, responseTimeMs });
|
|
48
|
-
export const trackExecute = (apiId, responseTimeMs) => track({ type: 'execute', apiId, responseTimeMs });
|
|
49
|
-
export const trackDiscovery = (resultCount) => track({ type: 'discovery', resultCount });
|
package/dist/src/types.js
DELETED
package/dist/src/utils/backup.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Backup System
|
|
3
|
-
* Handles timestamped backups of config files with automatic cleanup
|
|
4
|
-
*/
|
|
5
|
-
import { existsSync, mkdirSync, readdirSync, unlinkSync, copyFileSync } from 'fs';
|
|
6
|
-
import { dirname, basename, join } from 'path';
|
|
7
|
-
const MAX_BACKUPS = 5;
|
|
8
|
-
const BACKUP_PATTERN = /\.backup\.(\d+)\.json$/;
|
|
9
|
-
/**
|
|
10
|
-
* Generate backup filename with timestamp
|
|
11
|
-
*/
|
|
12
|
-
function generateBackupFilename(originalPath) {
|
|
13
|
-
const dir = dirname(originalPath);
|
|
14
|
-
const base = basename(originalPath, '.json');
|
|
15
|
-
const timestamp = Date.now();
|
|
16
|
-
return join(dir, `${base}.backup.${timestamp}.json`);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Create a backup of a config file
|
|
20
|
-
*/
|
|
21
|
-
export function createBackup(configPath) {
|
|
22
|
-
try {
|
|
23
|
-
// Check if original file exists
|
|
24
|
-
if (!existsSync(configPath)) {
|
|
25
|
-
return {
|
|
26
|
-
success: true,
|
|
27
|
-
backupPath: null,
|
|
28
|
-
// No backup needed if file doesn't exist
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
// Ensure backup directory exists
|
|
32
|
-
const dir = dirname(configPath);
|
|
33
|
-
if (!existsSync(dir)) {
|
|
34
|
-
mkdirSync(dir, { recursive: true });
|
|
35
|
-
}
|
|
36
|
-
// Generate backup path
|
|
37
|
-
const backupPath = generateBackupFilename(configPath);
|
|
38
|
-
// Copy file
|
|
39
|
-
copyFileSync(configPath, backupPath);
|
|
40
|
-
// Cleanup old backups
|
|
41
|
-
cleanupOldBackups(configPath);
|
|
42
|
-
return {
|
|
43
|
-
success: true,
|
|
44
|
-
backupPath,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
return {
|
|
49
|
-
success: false,
|
|
50
|
-
backupPath: null,
|
|
51
|
-
error: error instanceof Error ? error.message : 'Unknown error creating backup',
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* List all backups for a config file
|
|
57
|
-
*/
|
|
58
|
-
export function listBackups(configPath) {
|
|
59
|
-
const dir = dirname(configPath);
|
|
60
|
-
const baseName = basename(configPath, '.json');
|
|
61
|
-
if (!existsSync(dir)) {
|
|
62
|
-
return [];
|
|
63
|
-
}
|
|
64
|
-
const files = readdirSync(dir);
|
|
65
|
-
const backups = [];
|
|
66
|
-
for (const file of files) {
|
|
67
|
-
// Match backup pattern: {basename}.backup.{timestamp}.json
|
|
68
|
-
const match = file.match(new RegExp(`^${escapeRegex(baseName)}\\.backup\\.(\\d+)\\.json$`));
|
|
69
|
-
if (match) {
|
|
70
|
-
const timestamp = parseInt(match[1], 10);
|
|
71
|
-
const fullPath = join(dir, file);
|
|
72
|
-
backups.push({
|
|
73
|
-
path: fullPath,
|
|
74
|
-
timestamp,
|
|
75
|
-
date: new Date(timestamp),
|
|
76
|
-
filename: file,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
// Sort by timestamp, newest first
|
|
81
|
-
return backups.sort((a, b) => b.timestamp - a.timestamp);
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Get the most recent backup
|
|
85
|
-
*/
|
|
86
|
-
export function getLatestBackup(configPath) {
|
|
87
|
-
const backups = listBackups(configPath);
|
|
88
|
-
return backups[0] || null;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Cleanup old backups, keeping only MAX_BACKUPS most recent
|
|
92
|
-
*/
|
|
93
|
-
export function cleanupOldBackups(configPath) {
|
|
94
|
-
const backups = listBackups(configPath);
|
|
95
|
-
let deleted = 0;
|
|
96
|
-
// Keep only the first MAX_BACKUPS
|
|
97
|
-
const toDelete = backups.slice(MAX_BACKUPS);
|
|
98
|
-
for (const backup of toDelete) {
|
|
99
|
-
try {
|
|
100
|
-
unlinkSync(backup.path);
|
|
101
|
-
deleted++;
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
// Ignore deletion errors
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return deleted;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Restore from a backup
|
|
111
|
-
*/
|
|
112
|
-
export function restoreBackup(backupPath, targetPath) {
|
|
113
|
-
try {
|
|
114
|
-
if (!existsSync(backupPath)) {
|
|
115
|
-
return {
|
|
116
|
-
success: false,
|
|
117
|
-
backupPath: null,
|
|
118
|
-
error: `Backup file not found: ${backupPath}`,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
// Backup current file before restoring
|
|
122
|
-
const preRestoreBackup = createBackup(targetPath);
|
|
123
|
-
// Copy backup to target
|
|
124
|
-
copyFileSync(backupPath, targetPath);
|
|
125
|
-
return {
|
|
126
|
-
success: true,
|
|
127
|
-
backupPath: preRestoreBackup.backupPath,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
131
|
-
return {
|
|
132
|
-
success: false,
|
|
133
|
-
backupPath: null,
|
|
134
|
-
error: error instanceof Error ? error.message : 'Unknown error restoring backup',
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Restore from the most recent backup
|
|
140
|
-
*/
|
|
141
|
-
export function restoreLatestBackup(configPath) {
|
|
142
|
-
const latest = getLatestBackup(configPath);
|
|
143
|
-
if (!latest) {
|
|
144
|
-
return {
|
|
145
|
-
success: false,
|
|
146
|
-
backupPath: null,
|
|
147
|
-
error: 'No backups found',
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
return restoreBackup(latest.path, configPath);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Format backup info for display
|
|
154
|
-
*/
|
|
155
|
-
export function formatBackupInfo(backup) {
|
|
156
|
-
const date = backup.date.toLocaleString();
|
|
157
|
-
return `${backup.filename} (${date})`;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Escape regex special characters
|
|
161
|
-
*/
|
|
162
|
-
function escapeRegex(str) {
|
|
163
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Delete all backups for a config file
|
|
167
|
-
*/
|
|
168
|
-
export function deleteAllBackups(configPath) {
|
|
169
|
-
const backups = listBackups(configPath);
|
|
170
|
-
let deleted = 0;
|
|
171
|
-
for (const backup of backups) {
|
|
172
|
-
try {
|
|
173
|
-
unlinkSync(backup.path);
|
|
174
|
-
deleted++;
|
|
175
|
-
}
|
|
176
|
-
catch {
|
|
177
|
-
// Ignore deletion errors
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return deleted;
|
|
181
|
-
}
|