@nordsym/apiclaw 1.5.17 → 1.5.19

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 (228) hide show
  1. package/convex/http.js.map +1 -1
  2. package/convex/http.ts +516 -0
  3. package/dist/analytics.d.ts +0 -4
  4. package/dist/analytics.d.ts.map +1 -1
  5. package/dist/analytics.js +0 -1
  6. package/dist/analytics.js.map +1 -1
  7. package/dist/bin.js +1 -1
  8. package/dist/cli/commands/mcp-install.d.ts.map +1 -1
  9. package/dist/cli/commands/mcp-install.js +8 -87
  10. package/dist/cli/commands/mcp-install.js.map +1 -1
  11. package/dist/cli/index.js +0 -7
  12. package/dist/credentials.d.ts.map +1 -1
  13. package/dist/credentials.js +38 -43
  14. package/dist/credentials.js.map +1 -1
  15. package/dist/discovery.d.ts.map +1 -1
  16. package/dist/discovery.js +82 -191
  17. package/dist/discovery.js.map +1 -1
  18. package/dist/http-api.d.ts.map +1 -1
  19. package/dist/http-api.js +33 -17
  20. package/dist/http-api.js.map +1 -1
  21. package/dist/proxy.js +1 -1
  22. package/dist/proxy.js.map +1 -1
  23. package/landing/next-env.d.ts +0 -1
  24. package/landing/src/app/api/auth/magic-link/route.ts +1 -1
  25. package/landing/src/app/auth/verify/page.tsx +0 -6
  26. package/landing/src/app/dashboard/verify/page.tsx +0 -6
  27. package/landing/src/app/join/page.tsx +0 -6
  28. package/landing/src/app/layout.tsx +2 -2
  29. package/landing/src/app/login/page.tsx +1 -1
  30. package/landing/src/app/mou/[partnerId]/page.tsx +0 -6
  31. package/landing/src/app/page.tsx +18 -39
  32. package/landing/src/app/providers/dashboard/[apiId]/actions/[actionId]/edit/page.tsx +0 -6
  33. package/landing/src/app/providers/dashboard/[apiId]/actions/new/page.tsx +0 -5
  34. package/landing/src/app/providers/dashboard/[apiId]/actions/page.tsx +0 -5
  35. package/landing/src/app/providers/dashboard/[apiId]/direct-call/page.tsx +1 -6
  36. package/landing/src/app/providers/dashboard/[apiId]/page.tsx +0 -5
  37. package/landing/src/app/providers/dashboard/[apiId]/test/page.tsx +0 -5
  38. package/landing/src/app/providers/dashboard/layout.tsx +6 -6
  39. package/landing/src/app/providers/dashboard/login/page.tsx +1 -1
  40. package/landing/src/app/providers/dashboard/page.tsx +1 -1
  41. package/landing/src/app/providers/dashboard/verify/page.tsx +0 -6
  42. package/landing/src/app/providers/layout.tsx +1 -1
  43. package/landing/src/app/upgrade/page.tsx +0 -6
  44. package/landing/src/app/workspace/page.tsx +0 -6
  45. package/landing/src/components/HeroTabs.tsx +2 -2
  46. package/landing/src/components/{Workspace.tsx → ProviderDashboard.tsx} +2 -2
  47. package/landing/src/components/VideoDemo.tsx +10 -21
  48. package/landing/src/lib/mock-data.ts +1 -1
  49. package/landing/src/lib/stats.json +1 -1
  50. package/package.json +3 -8
  51. package/src/analytics.ts +0 -5
  52. package/src/bin.ts +1 -1
  53. package/src/cli/commands/mcp-install.ts +8 -90
  54. package/src/cli/index.ts +0 -8
  55. package/src/credentials.ts +39 -44
  56. package/src/discovery.ts +82 -191
  57. package/src/http-api.ts +34 -18
  58. package/src/proxy.ts +1 -1
  59. package/APILAYER_STATUS_2026-03-24.md +0 -38
  60. package/CHANGELOG-WHITELIST-V2.md +0 -269
  61. package/HIVR-WHITELIST-STATUS.md +0 -205
  62. package/HIVR-WHITELIST.md +0 -148
  63. package/TERMINOLOGY-AUDIT.md +0 -99
  64. package/TERMINOLOGY-FIXED.md +0 -74
  65. package/VIDEO-DEMO-GUIDE.md +0 -82
  66. package/WHITELIST-ARCHITECTURE.md +0 -379
  67. package/api/discover.ts +0 -71
  68. package/api/health.ts +0 -20
  69. package/convex/adminActivate.d.ts +0 -3
  70. package/convex/adminActivate.js +0 -47
  71. package/convex/adminStats.d.ts +0 -3
  72. package/convex/adminStats.js +0 -42
  73. package/convex/agents.d.ts +0 -54
  74. package/convex/agents.js +0 -499
  75. package/convex/analytics.d.ts +0 -5
  76. package/convex/analytics.js +0 -166
  77. package/convex/billing.d.ts +0 -88
  78. package/convex/billing.js +0 -655
  79. package/convex/capabilities.d.ts +0 -9
  80. package/convex/capabilities.js +0 -145
  81. package/convex/chains.d.ts +0 -67
  82. package/convex/chains.js +0 -1042
  83. package/convex/credits.d.ts +0 -25
  84. package/convex/credits.js +0 -186
  85. package/convex/crons.d.ts +0 -3
  86. package/convex/crons.js +0 -17
  87. package/convex/directCall.d.ts +0 -72
  88. package/convex/directCall.js +0 -627
  89. package/convex/earnProgress.d.ts +0 -58
  90. package/convex/earnProgress.js +0 -649
  91. package/convex/email.d.ts +0 -14
  92. package/convex/email.js +0 -300
  93. package/convex/feedback.d.ts +0 -7
  94. package/convex/feedback.js +0 -227
  95. package/convex/http.d.ts +0 -3
  96. package/convex/http.js +0 -910
  97. package/convex/logs.d.ts +0 -38
  98. package/convex/logs.js +0 -487
  99. package/convex/mou.d.ts +0 -6
  100. package/convex/mou.js +0 -82
  101. package/convex/providerKeys.d.ts +0 -31
  102. package/convex/providerKeys.js +0 -257
  103. package/convex/providers.d.ts +0 -29
  104. package/convex/providers.js +0 -756
  105. package/convex/purchases.d.ts +0 -7
  106. package/convex/purchases.js +0 -157
  107. package/convex/ratelimit.d.ts +0 -4
  108. package/convex/ratelimit.js +0 -91
  109. package/convex/searchLogs.d.ts +0 -4
  110. package/convex/searchLogs.js +0 -129
  111. package/convex/spendAlerts.d.ts +0 -36
  112. package/convex/spendAlerts.js +0 -380
  113. package/convex/stripeActions.d.ts +0 -19
  114. package/convex/stripeActions.js +0 -411
  115. package/convex/teams.d.ts +0 -21
  116. package/convex/teams.js +0 -215
  117. package/convex/telemetry.d.ts +0 -4
  118. package/convex/telemetry.js +0 -74
  119. package/convex/usage.d.ts +0 -27
  120. package/convex/usage.js +0 -229
  121. package/convex/waitlist.d.ts +0 -4
  122. package/convex/waitlist.js +0 -49
  123. package/convex/webhooks.d.ts +0 -12
  124. package/convex/webhooks.js +0 -410
  125. package/convex/workspaces.d.ts +0 -29
  126. package/convex/workspaces.js +0 -880
  127. package/direct-test.mjs +0 -51
  128. package/dist/access-control.d.ts +0 -45
  129. package/dist/access-control.d.ts.map +0 -1
  130. package/dist/access-control.js +0 -142
  131. package/dist/access-control.js.map +0 -1
  132. package/dist/chain-types.d.ts +0 -187
  133. package/dist/chain-types.d.ts.map +0 -1
  134. package/dist/chain-types.js +0 -33
  135. package/dist/chain-types.js.map +0 -1
  136. package/dist/convex/adminActivate.js +0 -46
  137. package/dist/convex/adminStats.js +0 -41
  138. package/dist/convex/agents.js +0 -498
  139. package/dist/convex/analytics.js +0 -165
  140. package/dist/convex/billing.js +0 -654
  141. package/dist/convex/capabilities.js +0 -144
  142. package/dist/convex/chains.js +0 -1041
  143. package/dist/convex/credits.js +0 -185
  144. package/dist/convex/crons.js +0 -16
  145. package/dist/convex/directCall.js +0 -626
  146. package/dist/convex/earnProgress.js +0 -648
  147. package/dist/convex/email.js +0 -299
  148. package/dist/convex/feedback.js +0 -226
  149. package/dist/convex/http.js +0 -909
  150. package/dist/convex/logs.js +0 -486
  151. package/dist/convex/mou.js +0 -81
  152. package/dist/convex/providerKeys.js +0 -256
  153. package/dist/convex/providers.js +0 -755
  154. package/dist/convex/purchases.js +0 -156
  155. package/dist/convex/ratelimit.js +0 -90
  156. package/dist/convex/schema.js +0 -709
  157. package/dist/convex/searchLogs.js +0 -128
  158. package/dist/convex/spendAlerts.js +0 -379
  159. package/dist/convex/stripeActions.js +0 -410
  160. package/dist/convex/teams.js +0 -214
  161. package/dist/convex/telemetry.js +0 -73
  162. package/dist/convex/usage.js +0 -228
  163. package/dist/convex/waitlist.js +0 -48
  164. package/dist/convex/webhooks.js +0 -409
  165. package/dist/convex/workspaces.js +0 -879
  166. package/dist/hivr-whitelist.d.ts +0 -18
  167. package/dist/hivr-whitelist.d.ts.map +0 -1
  168. package/dist/hivr-whitelist.js +0 -95
  169. package/dist/hivr-whitelist.js.map +0 -1
  170. package/dist/http-server-minimal.d.ts +0 -7
  171. package/dist/http-server-minimal.d.ts.map +0 -1
  172. package/dist/http-server-minimal.js +0 -126
  173. package/dist/http-server-minimal.js.map +0 -1
  174. package/dist/product-whitelist.d.ts +0 -37
  175. package/dist/product-whitelist.d.ts.map +0 -1
  176. package/dist/product-whitelist.js +0 -203
  177. package/dist/product-whitelist.js.map +0 -1
  178. package/dist/src/analytics.js +0 -129
  179. package/dist/src/bin.js +0 -17
  180. package/dist/src/capability-router.js +0 -240
  181. package/dist/src/chainExecutor.js +0 -451
  182. package/dist/src/chainResolver.js +0 -518
  183. package/dist/src/cli/commands/doctor.js +0 -324
  184. package/dist/src/cli/commands/mcp-install.js +0 -255
  185. package/dist/src/cli/commands/restore.js +0 -259
  186. package/dist/src/cli/commands/setup.js +0 -205
  187. package/dist/src/cli/commands/uninstall.js +0 -188
  188. package/dist/src/cli/index.js +0 -111
  189. package/dist/src/cli.js +0 -302
  190. package/dist/src/confirmation.js +0 -240
  191. package/dist/src/credentials.js +0 -357
  192. package/dist/src/credits.js +0 -260
  193. package/dist/src/crypto.js +0 -66
  194. package/dist/src/discovery.js +0 -504
  195. package/dist/src/enterprise/env.js +0 -123
  196. package/dist/src/enterprise/script-generator.js +0 -460
  197. package/dist/src/execute-dynamic.js +0 -473
  198. package/dist/src/execute.js +0 -1727
  199. package/dist/src/index.js +0 -2062
  200. package/dist/src/metered.js +0 -80
  201. package/dist/src/open-apis.js +0 -276
  202. package/dist/src/proxy.js +0 -28
  203. package/dist/src/session.js +0 -86
  204. package/dist/src/stripe.js +0 -407
  205. package/dist/src/telemetry.js +0 -49
  206. package/dist/src/types.js +0 -2
  207. package/dist/src/utils/backup.js +0 -181
  208. package/dist/src/utils/config.js +0 -220
  209. package/dist/src/utils/os.js +0 -105
  210. package/dist/src/utils/paths.js +0 -159
  211. package/landing/pages/api/discover.ts +0 -43
  212. package/landing/pages/api/health.ts +0 -20
  213. package/scripts/test-whitelist-v2.sh +0 -128
  214. package/src/access-control.ts +0 -174
  215. package/src/hivr-whitelist.ts +0 -110
  216. package/src/http-server-minimal.ts +0 -154
  217. package/src/product-whitelist.ts +0 -246
  218. package/test-actual-handlers.ts +0 -92
  219. package/test-apilayer-all-14.ts +0 -249
  220. package/test-apilayer-fixed.ts +0 -248
  221. package/test-direct-endpoints.ts +0 -174
  222. package/test-exact-endpoints.ts +0 -144
  223. package/test-final.ts +0 -83
  224. package/test-full-routing.ts +0 -100
  225. package/test-handlers-correct.ts +0 -217
  226. package/test-numverify-key.ts +0 -41
  227. package/test-via-handlers.ts +0 -92
  228. package/test-worldnews.mjs +0 -26
@@ -1,504 +0,0 @@
1
- // Discovery engine for APIvault
2
- // MVP: Keyword matching. Future: Embeddings + semantic search
3
- import { readFileSync } from 'fs';
4
- import { fileURLToPath } from 'url';
5
- import { dirname, join } from 'path';
6
- import { openAPIs, isOpenAPI } from './open-apis.js';
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = dirname(__filename);
9
- const apisData = JSON.parse(readFileSync(join(__dirname, 'registry', 'apis.json'), 'utf-8'));
10
- const apis = apisData.apis;
11
- // Direct Call provider specs (hardcoded handlers with params)
12
- // Ordered: AI-first (models, LLM routing, audio), then infrastructure (code, web, search, email, SMS)
13
- const DIRECT_CALL_SPECS = {
14
- openrouter: {
15
- description: 'LLM routing (100+ models)',
16
- auth: 'bearer',
17
- docs: 'https://openrouter.ai/docs',
18
- actions: {
19
- chat: {
20
- desc: 'Chat completion',
21
- params: [
22
- { name: 'messages', required: true, desc: 'Array of {role, content}' },
23
- { name: 'model', required: false, desc: 'Model ID (default: claude-3-haiku)' },
24
- { name: 'max_tokens', required: false, desc: 'Max response tokens (default: 1000)' },
25
- ],
26
- },
27
- },
28
- },
29
- replicate: {
30
- description: 'Run any AI model (images, video, audio)',
31
- auth: 'bearer',
32
- docs: 'https://replicate.com/docs',
33
- actions: {
34
- run: {
35
- desc: 'Run a model',
36
- params: [
37
- { name: 'model', required: true, desc: 'Model ID (e.g., stability-ai/sdxl:...)' },
38
- { name: 'input', required: true, desc: 'Model input parameters' },
39
- ],
40
- },
41
- list_models: {
42
- desc: 'List available models',
43
- params: [],
44
- },
45
- },
46
- },
47
- elevenlabs: {
48
- description: 'Text-to-speech',
49
- auth: 'api_key',
50
- docs: 'https://elevenlabs.io/docs',
51
- actions: {
52
- text_to_speech: {
53
- desc: 'Generate audio from text',
54
- params: [
55
- { name: 'text', required: true, desc: 'Text to speak' },
56
- { name: 'voice_id', required: false, desc: 'Voice ID (default: Rachel)' },
57
- { name: 'model_id', required: false, desc: 'Model ID' },
58
- ],
59
- },
60
- },
61
- },
62
- e2b: {
63
- description: 'Code sandbox for AI agents',
64
- auth: 'api_key',
65
- docs: 'https://e2b.dev/docs',
66
- actions: {
67
- run_code: {
68
- desc: 'Execute code in sandbox',
69
- params: [
70
- { name: 'code', required: true, desc: 'Code to run' },
71
- { name: 'language', required: false, desc: 'Language (default: python)' },
72
- ],
73
- },
74
- run_shell: {
75
- desc: 'Execute shell command',
76
- params: [
77
- { name: 'command', required: true, desc: 'Shell command' },
78
- ],
79
- },
80
- },
81
- },
82
- firecrawl: {
83
- description: 'Web scraping and crawling',
84
- auth: 'bearer',
85
- docs: 'https://firecrawl.dev/docs',
86
- actions: {
87
- scrape: {
88
- desc: 'Scrape a URL',
89
- params: [
90
- { name: 'url', required: true, desc: 'URL to scrape' },
91
- { name: 'formats', required: false, desc: 'Output formats (default: ["markdown"])' },
92
- ],
93
- },
94
- crawl: {
95
- desc: 'Start a crawl job',
96
- params: [
97
- { name: 'url', required: true, desc: 'Starting URL' },
98
- { name: 'limit', required: false, desc: 'Max pages (default: 10)' },
99
- ],
100
- },
101
- map: {
102
- desc: 'Map site structure',
103
- params: [
104
- { name: 'url', required: true, desc: 'URL to map' },
105
- ],
106
- },
107
- },
108
- },
109
- github: {
110
- description: 'Code repos and developer data',
111
- auth: 'bearer',
112
- docs: 'https://docs.github.com/rest',
113
- actions: {
114
- search_repos: {
115
- desc: 'Search repositories',
116
- params: [
117
- { name: 'query', required: true, desc: 'Search query' },
118
- { name: 'sort', required: false, desc: 'Sort by (default: stars)' },
119
- { name: 'limit', required: false, desc: 'Max results (default: 10)' },
120
- ],
121
- },
122
- get_repo: {
123
- desc: 'Get repo details',
124
- params: [
125
- { name: 'owner', required: true, desc: 'Repo owner' },
126
- { name: 'repo', required: true, desc: 'Repo name' },
127
- ],
128
- },
129
- list_issues: {
130
- desc: 'List issues',
131
- params: [
132
- { name: 'owner', required: true, desc: 'Repo owner' },
133
- { name: 'repo', required: true, desc: 'Repo name' },
134
- { name: 'state', required: false, desc: 'State filter (default: open)' },
135
- ],
136
- },
137
- create_issue: {
138
- desc: 'Create issue',
139
- params: [
140
- { name: 'owner', required: true, desc: 'Repo owner' },
141
- { name: 'repo', required: true, desc: 'Repo name' },
142
- { name: 'title', required: true, desc: 'Issue title' },
143
- { name: 'body', required: false, desc: 'Issue body' },
144
- ],
145
- },
146
- get_file: {
147
- desc: 'Get file contents',
148
- params: [
149
- { name: 'owner', required: true, desc: 'Repo owner' },
150
- { name: 'repo', required: true, desc: 'Repo name' },
151
- { name: 'path', required: true, desc: 'File path' },
152
- ],
153
- },
154
- },
155
- },
156
- brave_search: {
157
- description: 'Web search API',
158
- auth: 'api_key',
159
- docs: 'https://api.search.brave.com/docs',
160
- actions: {
161
- search: {
162
- desc: 'Search the web',
163
- params: [
164
- { name: 'query', required: true, desc: 'Search query' },
165
- { name: 'count', required: false, desc: 'Number of results (default: 5)' },
166
- ],
167
- },
168
- },
169
- },
170
- resend: {
171
- description: 'Email API',
172
- auth: 'bearer',
173
- docs: 'https://resend.com/docs',
174
- actions: {
175
- send_email: {
176
- desc: 'Send email',
177
- params: [
178
- { name: 'to', required: true, desc: 'Recipient email' },
179
- { name: 'subject', required: true, desc: 'Email subject' },
180
- { name: 'html', required: false, desc: 'HTML body' },
181
- { name: 'text', required: false, desc: 'Plain text body' },
182
- { name: 'from', required: false, desc: 'Sender (default: noreply@apiclaw.nordsym.com)' },
183
- ],
184
- },
185
- },
186
- },
187
- '46elks': {
188
- description: 'Swedish SMS and voice API',
189
- auth: 'basic',
190
- docs: 'https://46elks.com/docs',
191
- actions: {
192
- send_sms: {
193
- desc: 'Send SMS message',
194
- params: [
195
- { name: 'to', required: true, desc: 'Phone number (+46...)' },
196
- { name: 'message', required: true, desc: 'SMS text (max 160 chars for 1 segment)' },
197
- { name: 'from', required: false, desc: 'Sender ID (default: APIClaw)' },
198
- ],
199
- },
200
- },
201
- },
202
- twilio: {
203
- description: 'Global SMS and voice API',
204
- auth: 'basic',
205
- docs: 'https://www.twilio.com/docs',
206
- actions: {
207
- send_sms: {
208
- desc: 'Send SMS message',
209
- params: [
210
- { name: 'to', required: true, desc: 'Phone number (E.164 format)' },
211
- { name: 'message', required: true, desc: 'SMS text' },
212
- { name: 'from', required: false, desc: 'Sender phone number' },
213
- ],
214
- },
215
- },
216
- },
217
- apilayer: {
218
- description: 'APILayer marketplace — currency, news, scraping, PDFs, verification & more',
219
- auth: 'api_key',
220
- docs: 'https://apilayer.com',
221
- actions: {
222
- exchange_rates: {
223
- desc: 'Get live or historical currency exchange rates',
224
- params: [
225
- { name: 'base', required: false, desc: 'Base currency (default: USD)' },
226
- { name: 'symbols', required: false, desc: 'Comma-separated target currencies' },
227
- { name: 'date', required: false, desc: 'Historical date YYYY-MM-DD (omit for live)' },
228
- ],
229
- },
230
- market_data: {
231
- desc: 'End-of-day stock market data',
232
- params: [
233
- { name: 'symbols', required: true, desc: 'Stock ticker(s), comma-separated e.g. AAPL,MSFT' },
234
- { name: 'date_from', required: false, desc: 'Start date YYYY-MM-DD' },
235
- { name: 'date_to', required: false, desc: 'End date YYYY-MM-DD' },
236
- ],
237
- },
238
- aviation: {
239
- desc: 'Real-time flight data and tracking',
240
- params: [
241
- { name: 'flight_iata', required: false, desc: 'IATA flight number e.g. AA100' },
242
- { name: 'dep_iata', required: false, desc: 'Departure airport IATA code' },
243
- { name: 'arr_iata', required: false, desc: 'Arrival airport IATA code' },
244
- ],
245
- },
246
- pdf_generate: {
247
- desc: 'Generate PDF from URL or HTML',
248
- params: [
249
- { name: 'document_url', required: false, desc: 'URL to convert to PDF' },
250
- { name: 'document_html', required: false, desc: 'HTML string to convert (alternative to URL)' },
251
- { name: 'page_size', required: false, desc: 'Page size: A4, Letter, etc (default: A4)' },
252
- ],
253
- },
254
- screenshot: {
255
- desc: 'Capture full-page screenshot of any URL',
256
- params: [
257
- { name: 'url', required: true, desc: 'URL to screenshot' },
258
- { name: 'viewport', required: false, desc: 'Viewport size e.g. 1440x900 (default)' },
259
- { name: 'fullpage', required: false, desc: '1 for full page, 0 for viewport only (default: 0)' },
260
- ],
261
- },
262
- verify_email: {
263
- desc: 'Validate email address format and deliverability',
264
- params: [
265
- { name: 'email', required: true, desc: 'Email address to verify' },
266
- ],
267
- },
268
- verify_number: {
269
- desc: 'Validate and lookup phone number details',
270
- params: [
271
- { name: 'number', required: true, desc: 'Phone number in E.164 format e.g. +46701234567' },
272
- ],
273
- },
274
- vat_check: {
275
- desc: 'Validate EU VAT number',
276
- params: [
277
- { name: 'vat_number', required: true, desc: 'EU VAT number e.g. SE556012345601' },
278
- ],
279
- },
280
- world_news: {
281
- desc: 'Extract and analyze news articles from a URL',
282
- params: [
283
- { name: 'url', required: true, desc: 'URL of the news article to analyze' },
284
- { name: 'analyze', required: false, desc: 'Whether to analyze the news (default: true)' },
285
- ],
286
- },
287
- finance_news: {
288
- desc: 'Latest financial and stock market news',
289
- params: [
290
- { name: 'tickers', required: false, desc: 'Stock tickers comma-separated e.g. AAPL,TSLA' },
291
- { name: 'text', required: false, desc: 'Keyword filter' },
292
- { name: 'number', required: false, desc: 'Number of results (default: 5)' },
293
- ],
294
- },
295
- scrape: {
296
- desc: 'Advanced web scraper — returns clean page content',
297
- params: [
298
- { name: 'url', required: true, desc: 'URL to scrape' },
299
- ],
300
- },
301
- image_crop: {
302
- desc: 'Smart crop an image to specified dimensions',
303
- params: [
304
- { name: 'url', required: true, desc: 'Image URL to crop' },
305
- { name: 'width', required: false, desc: 'Target width in pixels' },
306
- { name: 'height', required: false, desc: 'Target height in pixels' },
307
- ],
308
- },
309
- skills: {
310
- desc: 'Search 7000+ professional skills database',
311
- params: [
312
- { name: 'q', required: true, desc: 'Skill search query e.g. "machine learning"' },
313
- { name: 'count', required: false, desc: 'Number of results (default: 10)' },
314
- ],
315
- },
316
- form_submit: {
317
- desc: 'Submit form data to a FormAPI endpoint',
318
- params: [
319
- { name: 'endpoint', required: true, desc: 'FormAPI endpoint path' },
320
- { name: 'data', required: false, desc: 'Form data object to submit' },
321
- ],
322
- },
323
- },
324
- },
325
- };
326
- /**
327
- * Discover APIs based on a natural language query
328
- * MVP uses keyword matching; production would use embeddings
329
- */
330
- export function discoverAPIs(query, options = {}) {
331
- const { category, maxResults = 5, maxPrice, region } = options;
332
- const queryLower = query.toLowerCase();
333
- const queryWords = queryLower.split(/\s+/).filter(w => w.length > 2);
334
- const results = [];
335
- for (const api of apis) {
336
- // Category filter
337
- if (category && api.category !== category)
338
- continue;
339
- // Region filter
340
- if (region && api.regions && !api.regions.includes(region) && !api.regions.includes('global'))
341
- continue;
342
- // Calculate relevance score
343
- let score = 0;
344
- const matchReasons = [];
345
- // Check keywords
346
- for (const word of queryWords) {
347
- // Direct keyword match
348
- if (api.keywords?.some(k => k.includes(word))) {
349
- score += 10;
350
- matchReasons.push(`keyword: ${word}`);
351
- }
352
- // Capability match
353
- if (api.capabilities?.some(c => c.includes(word))) {
354
- score += 15;
355
- matchReasons.push(`capability: ${word}`);
356
- }
357
- // Name match
358
- if (api.name.toLowerCase().includes(word)) {
359
- score += 20;
360
- matchReasons.push(`name: ${word}`);
361
- }
362
- // Description match
363
- if (api.description.toLowerCase().includes(word)) {
364
- score += 5;
365
- matchReasons.push(`description: ${word}`);
366
- }
367
- // Feature match
368
- if (api.features?.some(f => f.toLowerCase().includes(word))) {
369
- score += 8;
370
- matchReasons.push(`feature: ${word}`);
371
- }
372
- }
373
- // Boost for high success rate (default to 0.8 if not set)
374
- score += (api.agent_success_rate ?? 0.8) * 10;
375
- // Boost for low latency (default to 500ms if not set)
376
- score += Math.max(0, (1000 - (api.avg_latency_ms ?? 500)) / 100);
377
- // Boost for free tier
378
- if (api.pricing?.free_tier) {
379
- score += 5;
380
- matchReasons.push('has free tier');
381
- }
382
- if (score > 0) {
383
- results.push({
384
- provider: api,
385
- relevance_score: Math.round(score * 100) / 100,
386
- match_reasons: [...new Set(matchReasons)]
387
- });
388
- }
389
- }
390
- // Sort by relevance
391
- results.sort((a, b) => b.relevance_score - a.relevance_score);
392
- return results.slice(0, maxResults);
393
- }
394
- /**
395
- * Get detailed information about a specific API
396
- * @param apiId - The API provider ID
397
- * @param options.compact - If true, returns minified spec (saves ~60% tokens)
398
- */
399
- export function getAPIDetails(apiId, options = {}) {
400
- const { compact = false } = options;
401
- // Check if it's a Direct Call provider (hardcoded handlers)
402
- const directSpec = DIRECT_CALL_SPECS[apiId];
403
- if (directSpec) {
404
- if (compact) {
405
- // Minified format: ~60% smaller
406
- return {
407
- id: apiId,
408
- type: 'direct_call',
409
- desc: directSpec.description,
410
- auth: directSpec.auth,
411
- actions: Object.fromEntries(Object.entries(directSpec.actions).map(([action, info]) => [
412
- action,
413
- {
414
- params: info.params.map(p => p.required ? p.name : `${p.name}?`),
415
- },
416
- ])),
417
- };
418
- }
419
- return {
420
- id: apiId,
421
- type: 'direct_call',
422
- name: apiId,
423
- description: directSpec.description,
424
- auth_type: directSpec.auth,
425
- docs_url: directSpec.docs,
426
- direct_call: true,
427
- actions: Object.fromEntries(Object.entries(directSpec.actions).map(([action, info]) => [
428
- action,
429
- {
430
- description: info.desc,
431
- params: info.params,
432
- },
433
- ])),
434
- };
435
- }
436
- // Check if it's an Open API (free, no auth)
437
- if (isOpenAPI(apiId)) {
438
- const openApi = openAPIs[apiId];
439
- const actions = Object.keys(openApi.actions);
440
- if (compact) {
441
- return {
442
- id: apiId,
443
- type: 'open',
444
- desc: openApi.description,
445
- auth: 'none',
446
- actions: Object.fromEntries(actions.map(a => [a, { params: [] }])),
447
- };
448
- }
449
- return {
450
- id: apiId,
451
- type: 'open',
452
- name: openApi.name,
453
- description: openApi.description,
454
- auth_type: 'none',
455
- free: true,
456
- actions: Object.fromEntries(actions.map(a => [a, { description: `Execute ${a}`, params: [] }])),
457
- };
458
- }
459
- // Fall back to registry (19,000+ APIs - basic info only)
460
- const registryApi = apis.find(api => api.id === apiId ||
461
- api.name?.toLowerCase() === apiId.toLowerCase());
462
- if (!registryApi) {
463
- return null;
464
- }
465
- if (compact) {
466
- return {
467
- id: registryApi.id || registryApi.name,
468
- type: 'registry',
469
- desc: registryApi.description?.slice(0, 80),
470
- auth: registryApi.auth_type || registryApi.auth || 'unknown',
471
- url: registryApi.base_url || registryApi.baseUrl,
472
- };
473
- }
474
- return {
475
- id: registryApi.id || registryApi.name,
476
- type: 'registry',
477
- name: registryApi.name,
478
- description: registryApi.description,
479
- category: registryApi.category,
480
- auth_type: registryApi.auth_type || registryApi.auth,
481
- base_url: registryApi.base_url || registryApi.baseUrl,
482
- docs_url: registryApi.docs_url || registryApi.docsUrl,
483
- pricing: registryApi.pricing || registryApi.pricing,
484
- note: 'Registry API - use call_api with customer_key or check docs for integration',
485
- };
486
- }
487
- /**
488
- * List all APIs in a category
489
- */
490
- export function listByCategory(category) {
491
- return apis.filter(api => api.category === category);
492
- }
493
- /**
494
- * Get all available categories
495
- */
496
- export function getCategories() {
497
- return [...new Set(apis.map(api => api.category))];
498
- }
499
- /**
500
- * Get all APIs
501
- */
502
- export function getAllAPIs() {
503
- return apis;
504
- }
@@ -1,123 +0,0 @@
1
- /**
2
- * Environment Variable Handler
3
- * Manages APIClaw environment variables for configuration
4
- */
5
- export const ENV_VARS = {
6
- WORKSPACE: 'APICLAW_WORKSPACE',
7
- API_URL: 'APICLAW_API_URL',
8
- DISABLE_TELEMETRY: 'APICLAW_DISABLE_TELEMETRY',
9
- };
10
- export const DEFAULT_API_URL = 'https://api.apiclaw.com';
11
- /**
12
- * Read APIClaw config from environment variables
13
- */
14
- export function readEnvConfig() {
15
- return {
16
- workspace: process.env[ENV_VARS.WORKSPACE] || undefined,
17
- apiUrl: process.env[ENV_VARS.API_URL] || undefined,
18
- disableTelemetry: process.env[ENV_VARS.DISABLE_TELEMETRY] === 'true' ||
19
- process.env[ENV_VARS.DISABLE_TELEMETRY] === '1',
20
- };
21
- }
22
- /**
23
- * Get API URL with fallback to default
24
- */
25
- export function getApiUrl() {
26
- return process.env[ENV_VARS.API_URL] || DEFAULT_API_URL;
27
- }
28
- /**
29
- * Check if telemetry is disabled
30
- */
31
- export function isTelemetryDisabled() {
32
- const val = process.env[ENV_VARS.DISABLE_TELEMETRY];
33
- return val === 'true' || val === '1';
34
- }
35
- /**
36
- * Get pre-configured workspace ID
37
- */
38
- export function getWorkspaceFromEnv() {
39
- return process.env[ENV_VARS.WORKSPACE];
40
- }
41
- /**
42
- * Generate env block for MCP server config
43
- */
44
- export function generateEnvBlock(config) {
45
- const env = {};
46
- if (config.workspace) {
47
- env[ENV_VARS.WORKSPACE] = config.workspace;
48
- }
49
- if (config.apiUrl && config.apiUrl !== DEFAULT_API_URL) {
50
- env[ENV_VARS.API_URL] = config.apiUrl;
51
- }
52
- if (config.disableTelemetry) {
53
- env[ENV_VARS.DISABLE_TELEMETRY] = 'true';
54
- }
55
- return env;
56
- }
57
- /**
58
- * Format env config for display
59
- */
60
- export function formatEnvConfig(config) {
61
- const lines = [];
62
- if (config.workspace) {
63
- lines.push(` Workspace: ${config.workspace}`);
64
- }
65
- if (config.apiUrl) {
66
- lines.push(` API URL: ${config.apiUrl}`);
67
- }
68
- if (config.disableTelemetry) {
69
- lines.push(` Telemetry: Disabled`);
70
- }
71
- return lines;
72
- }
73
- /**
74
- * Validate workspace ID format
75
- */
76
- export function isValidWorkspaceId(id) {
77
- // Workspace IDs should be alphanumeric with dashes/underscores
78
- return /^[a-zA-Z0-9_-]{3,64}$/.test(id);
79
- }
80
- /**
81
- * Validate API URL format
82
- */
83
- export function isValidApiUrl(url) {
84
- try {
85
- const parsed = new URL(url);
86
- return parsed.protocol === 'http:' || parsed.protocol === 'https:';
87
- }
88
- catch {
89
- return false;
90
- }
91
- }
92
- /**
93
- * Generate shell export statements
94
- */
95
- export function generateShellExports(config) {
96
- const lines = [];
97
- if (config.workspace) {
98
- lines.push(`export ${ENV_VARS.WORKSPACE}="${config.workspace}"`);
99
- }
100
- if (config.apiUrl) {
101
- lines.push(`export ${ENV_VARS.API_URL}="${config.apiUrl}"`);
102
- }
103
- if (config.disableTelemetry) {
104
- lines.push(`export ${ENV_VARS.DISABLE_TELEMETRY}="true"`);
105
- }
106
- return lines.join('\n');
107
- }
108
- /**
109
- * Generate PowerShell $env statements
110
- */
111
- export function generatePowerShellEnv(config) {
112
- const lines = [];
113
- if (config.workspace) {
114
- lines.push(`$env:${ENV_VARS.WORKSPACE} = "${config.workspace}"`);
115
- }
116
- if (config.apiUrl) {
117
- lines.push(`$env:${ENV_VARS.API_URL} = "${config.apiUrl}"`);
118
- }
119
- if (config.disableTelemetry) {
120
- lines.push(`$env:${ENV_VARS.DISABLE_TELEMETRY} = "true"`);
121
- }
122
- return lines.join('\n');
123
- }