@nordsym/apiclaw 1.5.13 → 1.5.14

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 (68) hide show
  1. package/dist/bin.js +1 -1
  2. package/dist/cli/index.js +7 -0
  3. package/dist/convex/adminActivate.js +46 -0
  4. package/dist/convex/adminStats.js +41 -0
  5. package/dist/convex/agents.js +498 -0
  6. package/dist/convex/analytics.js +165 -0
  7. package/dist/convex/billing.js +654 -0
  8. package/dist/convex/capabilities.js +144 -0
  9. package/dist/convex/chains.js +1041 -0
  10. package/dist/convex/credits.js +185 -0
  11. package/dist/convex/crons.js +16 -0
  12. package/dist/convex/directCall.js +626 -0
  13. package/dist/convex/earnProgress.js +648 -0
  14. package/dist/convex/email.js +299 -0
  15. package/dist/convex/feedback.js +226 -0
  16. package/dist/convex/http.js +909 -0
  17. package/dist/convex/logs.js +486 -0
  18. package/dist/convex/mou.js +81 -0
  19. package/dist/convex/providerKeys.js +256 -0
  20. package/dist/convex/providers.js +755 -0
  21. package/dist/convex/purchases.js +156 -0
  22. package/dist/convex/ratelimit.js +90 -0
  23. package/dist/convex/schema.js +709 -0
  24. package/dist/convex/searchLogs.js +128 -0
  25. package/dist/convex/spendAlerts.js +379 -0
  26. package/dist/convex/stripeActions.js +410 -0
  27. package/dist/convex/teams.js +214 -0
  28. package/dist/convex/telemetry.js +73 -0
  29. package/dist/convex/usage.js +228 -0
  30. package/dist/convex/waitlist.js +48 -0
  31. package/dist/convex/webhooks.js +409 -0
  32. package/dist/convex/workspaces.js +879 -0
  33. package/dist/src/analytics.js +129 -0
  34. package/dist/src/bin.js +17 -0
  35. package/dist/src/capability-router.js +240 -0
  36. package/dist/src/chainExecutor.js +451 -0
  37. package/dist/src/chainResolver.js +518 -0
  38. package/dist/src/cli/commands/doctor.js +324 -0
  39. package/dist/src/cli/commands/mcp-install.js +255 -0
  40. package/dist/src/cli/commands/restore.js +259 -0
  41. package/dist/src/cli/commands/setup.js +205 -0
  42. package/dist/src/cli/commands/uninstall.js +188 -0
  43. package/dist/src/cli/index.js +111 -0
  44. package/dist/src/cli.js +302 -0
  45. package/dist/src/confirmation.js +240 -0
  46. package/dist/src/credentials.js +357 -0
  47. package/dist/src/credits.js +260 -0
  48. package/dist/src/crypto.js +66 -0
  49. package/dist/src/discovery.js +504 -0
  50. package/dist/src/enterprise/env.js +123 -0
  51. package/dist/src/enterprise/script-generator.js +460 -0
  52. package/dist/src/execute-dynamic.js +473 -0
  53. package/dist/src/execute.js +1727 -0
  54. package/dist/src/index.js +2062 -0
  55. package/dist/src/metered.js +80 -0
  56. package/dist/src/open-apis.js +276 -0
  57. package/dist/src/proxy.js +28 -0
  58. package/dist/src/session.js +86 -0
  59. package/dist/src/stripe.js +407 -0
  60. package/dist/src/telemetry.js +49 -0
  61. package/dist/src/types.js +2 -0
  62. package/dist/src/utils/backup.js +181 -0
  63. package/dist/src/utils/config.js +220 -0
  64. package/dist/src/utils/os.js +105 -0
  65. package/dist/src/utils/paths.js +159 -0
  66. package/package.json +1 -1
  67. package/src/bin.ts +1 -1
  68. package/src/cli/index.ts +8 -0
@@ -0,0 +1,165 @@
1
+ import { mutation, query } from "./_generated/server";
2
+ import { v } from "convex/values";
3
+ // Log an analytics event
4
+ export const log = mutation({
5
+ args: {
6
+ event: v.string(),
7
+ provider: v.optional(v.string()),
8
+ query: v.optional(v.string()),
9
+ identifier: v.string(),
10
+ metadata: v.optional(v.any()),
11
+ },
12
+ handler: async (ctx, args) => {
13
+ return await ctx.db.insert("analytics", {
14
+ ...args,
15
+ timestamp: Date.now(),
16
+ });
17
+ },
18
+ });
19
+ // Get stats for dashboard
20
+ export const getStats = query({
21
+ args: {
22
+ hoursBack: v.optional(v.number()),
23
+ },
24
+ handler: async (ctx, args) => {
25
+ const hoursBack = args.hoursBack || 24;
26
+ const since = Date.now() - hoursBack * 3600000;
27
+ const events = await ctx.db
28
+ .query("analytics")
29
+ .withIndex("by_timestamp")
30
+ .filter((q) => q.gte(q.field("timestamp"), since))
31
+ .collect();
32
+ // Aggregate stats
33
+ const stats = {
34
+ totalEvents: events.length,
35
+ discoveries: events.filter((e) => e.event === "discovery").length,
36
+ instantCalls: events.filter((e) => e.event === "instant").length,
37
+ uniqueUsers: new Set(events.map((e) => e.identifier)).size,
38
+ byProvider: {},
39
+ topQueries: [],
40
+ hourly: [],
41
+ };
42
+ // By provider
43
+ for (const event of events.filter((e) => e.provider)) {
44
+ stats.byProvider[event.provider] = (stats.byProvider[event.provider] || 0) + 1;
45
+ }
46
+ // Top queries
47
+ const queryCounts = {};
48
+ for (const event of events.filter((e) => e.query)) {
49
+ queryCounts[event.query] = (queryCounts[event.query] || 0) + 1;
50
+ }
51
+ stats.topQueries = Object.entries(queryCounts)
52
+ .sort(([, a], [, b]) => b - a)
53
+ .slice(0, 10)
54
+ .map(([query, count]) => ({ query, count }));
55
+ // Hourly breakdown
56
+ const hourlyCounts = {};
57
+ for (const event of events) {
58
+ const hour = new Date(event.timestamp).toISOString().slice(0, 13);
59
+ hourlyCounts[hour] = (hourlyCounts[hour] || 0) + 1;
60
+ }
61
+ stats.hourly = Object.entries(hourlyCounts)
62
+ .sort(([a], [b]) => a.localeCompare(b))
63
+ .map(([hour, count]) => ({ hour, count }));
64
+ return stats;
65
+ },
66
+ });
67
+ // Get recent events for live feed
68
+ export const getRecent = query({
69
+ args: {
70
+ limit: v.optional(v.number()),
71
+ },
72
+ handler: async (ctx, args) => {
73
+ const limit = args.limit || 50;
74
+ return await ctx.db
75
+ .query("analytics")
76
+ .withIndex("by_timestamp")
77
+ .order("desc")
78
+ .take(limit);
79
+ },
80
+ });
81
+ // Get provider breakdown for Agent Analytics (workspace-specific)
82
+ export const getProviderBreakdown = query({
83
+ args: {
84
+ token: v.string(),
85
+ periodDays: v.optional(v.number()),
86
+ },
87
+ handler: async (ctx, args) => {
88
+ const periodDays = args.periodDays || 7;
89
+ const since = Date.now() - periodDays * 24 * 3600000;
90
+ // Verify session and get workspace
91
+ const session = await ctx.db
92
+ .query("agentSessions")
93
+ .withIndex("by_sessionToken", (q) => q.eq("sessionToken", args.token))
94
+ .first();
95
+ if (!session) {
96
+ return null;
97
+ }
98
+ // Get all API logs for this workspace
99
+ const logs = await ctx.db
100
+ .query("apiLogs")
101
+ .withIndex("by_workspaceId_createdAt", (q) => q.eq("workspaceId", session.workspaceId))
102
+ .filter((q) => q.gte(q.field("createdAt"), since))
103
+ .collect();
104
+ if (logs.length === 0) {
105
+ return null; // Return null so frontend knows to show empty state, not preview
106
+ }
107
+ // Aggregate stats
108
+ const totalCalls = logs.length;
109
+ const successCount = logs.filter((l) => l.status === "success").length;
110
+ const failureCount = logs.filter((l) => l.status === "error").length;
111
+ const totalLatency = logs.reduce((sum, l) => sum + (l.latencyMs || 0), 0);
112
+ const avgLatency = totalCalls > 0 ? Math.round(totalLatency / totalCalls) : 0;
113
+ // Provider breakdown
114
+ const byProvider = {};
115
+ for (const log of logs) {
116
+ if (!byProvider[log.provider]) {
117
+ byProvider[log.provider] = { count: 0, latency: 0 };
118
+ }
119
+ byProvider[log.provider].count++;
120
+ byProvider[log.provider].latency += log.latencyMs || 0;
121
+ }
122
+ // Agent breakdown (by subagentId)
123
+ const byAgent = {};
124
+ for (const log of logs) {
125
+ const agent = log.subagentId || "main";
126
+ byAgent[agent] = (byAgent[agent] || 0) + 1;
127
+ }
128
+ // Action breakdown
129
+ const byAction = {};
130
+ for (const log of logs) {
131
+ const key = `${log.provider}:${log.action}`;
132
+ byAction[key] = (byAction[key] || 0) + 1;
133
+ }
134
+ // Time series (daily)
135
+ const dailyCounts = {};
136
+ for (const log of logs) {
137
+ const day = new Date(log.createdAt).toISOString().slice(0, 10);
138
+ dailyCounts[day] = (dailyCounts[day] || 0) + 1;
139
+ }
140
+ return {
141
+ totalCalls,
142
+ successCount,
143
+ failureCount,
144
+ successRate: totalCalls > 0 ? (successCount / totalCalls) * 100 : 0,
145
+ avgLatency,
146
+ byProvider: Object.entries(byProvider).map(([name, data]) => ({
147
+ name,
148
+ count: data.count,
149
+ avgLatency: data.count > 0 ? Math.round(data.latency / data.count) : 0,
150
+ })).sort((a, b) => b.count - a.count),
151
+ byAgent: Object.entries(byAgent).map(([name, count]) => ({
152
+ name,
153
+ count,
154
+ })).sort((a, b) => b.count - a.count),
155
+ byAction: Object.entries(byAction).map(([name, count]) => ({
156
+ name,
157
+ count,
158
+ })).sort((a, b) => b.count - a.count).slice(0, 10),
159
+ timeSeries: Object.entries(dailyCounts)
160
+ .sort(([a], [b]) => a.localeCompare(b))
161
+ .map(([date, count]) => ({ date, count })),
162
+ isPreview: false,
163
+ };
164
+ },
165
+ });