@every-app/sdk 0.2.0 → 0.3.0-rc.2

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 (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +608 -2
  3. package/dist/cloudflare/index.d.ts +22 -0
  4. package/dist/cloudflare/index.d.ts.map +1 -0
  5. package/dist/cloudflare/index.js +21 -0
  6. package/dist/cloudflare/sentinel.d.ts +69 -0
  7. package/dist/cloudflare/sentinel.d.ts.map +1 -0
  8. package/dist/cloudflare/sentinel.js +50 -0
  9. package/dist/cloudflare/worker.d.ts +592 -0
  10. package/dist/cloudflare/worker.d.ts.map +1 -0
  11. package/dist/cloudflare/worker.js +817 -0
  12. package/dist/dev/index.d.ts +8 -0
  13. package/dist/dev/index.d.ts.map +1 -0
  14. package/dist/dev/index.js +7 -0
  15. package/dist/dev/keypair.d.ts +24 -0
  16. package/dist/dev/keypair.d.ts.map +1 -0
  17. package/dist/dev/keypair.js +60 -0
  18. package/dist/internal/aiProviders.d.ts +67 -0
  19. package/dist/internal/aiProviders.d.ts.map +1 -0
  20. package/dist/internal/aiProviders.js +220 -0
  21. package/dist/internal/appSettings.d.ts +237 -0
  22. package/dist/internal/appSettings.d.ts.map +1 -0
  23. package/dist/internal/appSettings.js +374 -0
  24. package/dist/internal/capabilities.d.ts +3249 -0
  25. package/dist/internal/capabilities.d.ts.map +1 -0
  26. package/dist/internal/capabilities.js +1532 -0
  27. package/dist/internal/catalog/commerce.d.ts +394 -0
  28. package/dist/internal/catalog/commerce.d.ts.map +1 -0
  29. package/dist/internal/catalog/commerce.js +477 -0
  30. package/dist/internal/catalog/comms.d.ts +338 -0
  31. package/dist/internal/catalog/comms.d.ts.map +1 -0
  32. package/dist/internal/catalog/comms.js +477 -0
  33. package/dist/internal/catalog/index.d.ts +1899 -0
  34. package/dist/internal/catalog/index.d.ts.map +1 -0
  35. package/dist/internal/catalog/index.js +19 -0
  36. package/dist/internal/catalog/inference.d.ts +356 -0
  37. package/dist/internal/catalog/inference.d.ts.map +1 -0
  38. package/dist/internal/catalog/inference.js +425 -0
  39. package/dist/internal/catalog/infra.d.ts +423 -0
  40. package/dist/internal/catalog/infra.d.ts.map +1 -0
  41. package/dist/internal/catalog/infra.js +543 -0
  42. package/dist/internal/catalog/search.d.ts +400 -0
  43. package/dist/internal/catalog/search.d.ts.map +1 -0
  44. package/dist/internal/catalog/search.js +463 -0
  45. package/dist/internal/devProviders.d.ts +49 -0
  46. package/dist/internal/devProviders.d.ts.map +1 -0
  47. package/dist/internal/devProviders.js +62 -0
  48. package/dist/internal/email.d.ts +280 -0
  49. package/dist/internal/email.d.ts.map +1 -0
  50. package/dist/internal/email.js +613 -0
  51. package/dist/internal/events.d.ts +182 -0
  52. package/dist/internal/events.d.ts.map +1 -0
  53. package/dist/internal/events.js +326 -0
  54. package/dist/internal/gatewaySettings.d.ts +83 -0
  55. package/dist/internal/gatewaySettings.d.ts.map +1 -0
  56. package/dist/internal/gatewaySettings.js +217 -0
  57. package/dist/internal/identity.d.ts +18 -3
  58. package/dist/internal/identity.d.ts.map +1 -1
  59. package/dist/internal/identity.js +53 -14
  60. package/dist/internal/index.d.ts +18 -1
  61. package/dist/internal/index.d.ts.map +1 -1
  62. package/dist/internal/index.js +18 -1
  63. package/dist/internal/members.d.ts +35 -0
  64. package/dist/internal/members.d.ts.map +1 -0
  65. package/dist/internal/members.js +7 -0
  66. package/dist/internal/oauthClient.d.ts +63 -0
  67. package/dist/internal/oauthClient.d.ts.map +1 -0
  68. package/dist/internal/oauthClient.js +194 -0
  69. package/dist/internal/oauthScopes.d.ts +117 -0
  70. package/dist/internal/oauthScopes.d.ts.map +1 -0
  71. package/dist/internal/oauthScopes.js +416 -0
  72. package/dist/internal/organizationName.d.ts +18 -0
  73. package/dist/internal/organizationName.d.ts.map +1 -0
  74. package/dist/internal/organizationName.js +24 -0
  75. package/dist/internal/protocol.d.ts +86 -2
  76. package/dist/internal/protocol.d.ts.map +1 -1
  77. package/dist/internal/protocol.js +112 -1
  78. package/dist/internal/providerApps.d.ts +75 -0
  79. package/dist/internal/providerApps.d.ts.map +1 -0
  80. package/dist/internal/providerApps.js +59 -0
  81. package/dist/internal/providerRegistry.d.ts +147 -0
  82. package/dist/internal/providerRegistry.d.ts.map +1 -0
  83. package/dist/internal/providerRegistry.js +266 -0
  84. package/dist/internal/providerSpec.d.ts +55 -0
  85. package/dist/internal/providerSpec.d.ts.map +1 -0
  86. package/dist/internal/providerSpec.js +758 -0
  87. package/dist/internal/remoteMcp.d.ts +188 -0
  88. package/dist/internal/remoteMcp.d.ts.map +1 -0
  89. package/dist/internal/remoteMcp.js +543 -0
  90. package/dist/internal/signInProviders.d.ts +104 -0
  91. package/dist/internal/signInProviders.d.ts.map +1 -0
  92. package/dist/internal/signInProviders.js +238 -0
  93. package/dist/internal/tools.d.ts +115 -0
  94. package/dist/internal/tools.d.ts.map +1 -0
  95. package/dist/internal/tools.js +80 -0
  96. package/dist/server/attribution.d.ts +39 -0
  97. package/dist/server/attribution.d.ts.map +1 -0
  98. package/dist/server/attribution.js +67 -0
  99. package/dist/server/authorizeUrl.d.ts +43 -0
  100. package/dist/server/authorizeUrl.d.ts.map +1 -0
  101. package/dist/server/authorizeUrl.js +110 -0
  102. package/dist/server/emit.d.ts +63 -0
  103. package/dist/server/emit.d.ts.map +1 -0
  104. package/dist/server/emit.js +101 -0
  105. package/dist/server/everyApp.d.ts +38 -12
  106. package/dist/server/everyApp.d.ts.map +1 -1
  107. package/dist/server/everyApp.js +92 -28
  108. package/dist/server/gatewayFetch.d.ts +24 -8
  109. package/dist/server/gatewayFetch.d.ts.map +1 -1
  110. package/dist/server/gatewayFetch.js +81 -36
  111. package/dist/server/index.d.ts +10 -1
  112. package/dist/server/index.d.ts.map +1 -1
  113. package/dist/server/index.js +8 -1
  114. package/dist/server/integrationFetch.d.ts +131 -0
  115. package/dist/server/integrationFetch.d.ts.map +1 -0
  116. package/dist/server/integrationFetch.js +526 -0
  117. package/dist/server/listMembers.d.ts +32 -0
  118. package/dist/server/listMembers.d.ts.map +1 -0
  119. package/dist/server/listMembers.js +74 -0
  120. package/dist/server/nodeServer.d.ts +48 -0
  121. package/dist/server/nodeServer.d.ts.map +1 -0
  122. package/dist/server/nodeServer.js +45 -0
  123. package/dist/server/sendEmail.d.ts +39 -0
  124. package/dist/server/sendEmail.d.ts.map +1 -0
  125. package/dist/server/sendEmail.js +114 -0
  126. package/dist/server/tools.d.ts +184 -0
  127. package/dist/server/tools.d.ts.map +1 -0
  128. package/dist/server/tools.js +347 -0
  129. package/dist/server/toolsEndpoint.d.ts +32 -0
  130. package/dist/server/toolsEndpoint.d.ts.map +1 -0
  131. package/dist/server/toolsEndpoint.js +231 -0
  132. package/package.json +19 -6
  133. package/dist/server/mcp.d.ts +0 -66
  134. package/dist/server/mcp.d.ts.map +0 -1
  135. package/dist/server/mcp.js +0 -147
@@ -0,0 +1,463 @@
1
+ export const SEARCH = {
2
+ firecrawl: {
3
+ mode: "api_key",
4
+ label: "Firecrawl",
5
+ description: "Scrapes, crawls, maps and searches the web, returning clean markdown or structured data.",
6
+ auth: {
7
+ kind: "bearer",
8
+ secret: "FIRECRAWL_API_KEY",
9
+ },
10
+ docs: "https://www.firecrawl.dev/app/api-keys",
11
+ api: "https://docs.firecrawl.dev/api-reference/introduction",
12
+ hosts: ["api.firecrawl.dev"],
13
+ data: "per-call",
14
+ access: ["read", "write"],
15
+ readMethods: ["GET", "POST"],
16
+ writeMethods: ["DELETE"],
17
+ accountWidePaths: [
18
+ ["team"],
19
+ ["crawl", "active"],
20
+ ["monitor"],
21
+ ["agent"],
22
+ ["interact"],
23
+ ["support", "ask"],
24
+ ],
25
+ hint: "An API key from Firecrawl's API keys page; the Gateway sends it as a bearer token. Scrape, crawl, map, search and extract are POSTs and job status is a GET; cancelling a crawl or batch (DELETE) needs write.",
26
+ secrets: [
27
+ {
28
+ name: "FIRECRAWL_API_KEY",
29
+ hint: "An API key from Firecrawl's API keys page; it starts with fc-.",
30
+ },
31
+ ],
32
+ smoke: {
33
+ method: "GET",
34
+ path: "/v2/team/credit-usage",
35
+ expect: [200],
36
+ free: true,
37
+ note: "Remaining credits; account-wide, so the Gateway refuses it for apps: run it from the person's terminal.",
38
+ },
39
+ cost: {
40
+ unit: "result",
41
+ note: "Credits: 1 per page scraped or crawled, 1 per map call, 2 per 10 search results; JSON extraction and other options add more.",
42
+ },
43
+ rate: {
44
+ note: "Per team per minute, by plan: /scrape 10 on Free, 100 Hobby, 500 Standard, 5,000 Growth; /crawl 2, 20, 100, 1,000.",
45
+ },
46
+ example: "scrape https://example.com/pricing into markdown",
47
+ verified: {
48
+ on: "2026-10-25",
49
+ how: "docs",
50
+ },
51
+ tags: ["scrape", "crawl", "search"],
52
+ },
53
+ exa: {
54
+ mode: "api_key",
55
+ label: "Exa",
56
+ description: "Web search built for AI: search results, page contents, similar links and cited answers.",
57
+ auth: {
58
+ kind: "header",
59
+ secret: "EXA_API_KEY",
60
+ header: "x-api-key",
61
+ },
62
+ docs: "https://dashboard.exa.ai/api-keys",
63
+ api: "https://exa.ai/docs/reference/search",
64
+ hosts: ["api.exa.ai"],
65
+ data: "per-call",
66
+ access: ["read"],
67
+ readMethods: ["POST"],
68
+ accountWidePaths: [["websets"], ["monitors"], ["agent"], ["batches"]],
69
+ hint: "An API key from the Exa dashboard (the free tier gives $10 of credit a month); the Gateway sends it in the x-api-key header. Search, contents, find-similar and answer are POSTs.",
70
+ secrets: [
71
+ {
72
+ name: "EXA_API_KEY",
73
+ hint: "An API key from the API keys page of the Exa dashboard.",
74
+ },
75
+ ],
76
+ smoke: {
77
+ method: "GET",
78
+ path: "/websets/v0/teams/me",
79
+ expect: [200],
80
+ free: true,
81
+ note: "Team info under the Websets API (the docs page leaves out the /websets prefix); account-wide, so run it from the person's terminal.",
82
+ },
83
+ cost: {
84
+ unit: "call",
85
+ usd: 0.007,
86
+ note: "Search $7 per 1k (auto and fast; lite $4), contents $1 per 1k pages, answer $5 per 1k; up to 10 results included.",
87
+ },
88
+ rate: {
89
+ perSecond: 10,
90
+ note: "Per team: /search and /answer 10 QPS, deep search 5, /contents 100.",
91
+ },
92
+ example: "find recent articles about solid-state batteries",
93
+ verified: {
94
+ on: "2026-10-25",
95
+ how: "docs",
96
+ },
97
+ tags: ["search"],
98
+ },
99
+ tavily: {
100
+ mode: "api_key",
101
+ label: "Tavily",
102
+ description: "Web search, page extraction, crawling and site maps for AI agents, plus research reports.",
103
+ auth: {
104
+ kind: "bearer",
105
+ secret: "TAVILY_API_KEY",
106
+ },
107
+ docs: "https://app.tavily.com",
108
+ api: "https://docs.tavily.com/documentation/api-reference/endpoint/search",
109
+ hosts: ["api.tavily.com"],
110
+ data: "per-call",
111
+ access: ["read"],
112
+ readMethods: ["GET", "POST"],
113
+ accountWidePaths: [["usage"], ["logs"], ["org-usage"]],
114
+ hint: "An API key from app.tavily.com (1,000 free credits a month); the Gateway sends it as a bearer token. Search, extract, crawl, map and research are POSTs; a research result is a GET.",
115
+ secrets: [
116
+ {
117
+ name: "TAVILY_API_KEY",
118
+ hint: "An API key from the Tavily dashboard; it starts with tvly-.",
119
+ },
120
+ ],
121
+ smoke: {
122
+ method: "GET",
123
+ path: "/usage",
124
+ expect: [200],
125
+ free: true,
126
+ note: "Key and account usage, not an endpoint that costs credits; account-wide, so run it from the person's terminal (10 calls per 10 minutes).",
127
+ },
128
+ cost: {
129
+ unit: "call",
130
+ usd: 0.008,
131
+ note: "Pay as you go $0.008 per credit: basic search 1 credit, advanced 2; extract 1 credit per 5 URLs; map 1 per 10 pages.",
132
+ },
133
+ rate: {
134
+ perMinute: 100,
135
+ note: "Development keys 100 per minute, production keys 1,000; crawl 100 and research 20 per minute for both.",
136
+ },
137
+ example: "search the web for this week's news on EU AI rules",
138
+ verified: {
139
+ on: "2026-10-25",
140
+ how: "docs",
141
+ },
142
+ tags: ["search", "scrape"],
143
+ },
144
+ // Unverified: Serper publishes no API reference; the request shape is read from its playground.
145
+ serper: {
146
+ mode: "api_key",
147
+ label: "Serper",
148
+ description: "Google search results as JSON: web, news, images, places, shopping, scholar and patents.",
149
+ auth: {
150
+ kind: "header",
151
+ secret: "SERPER_API_KEY",
152
+ header: "X-API-KEY",
153
+ },
154
+ docs: "https://serper.dev/api-keys",
155
+ api: "https://serper.dev/playground",
156
+ hosts: ["google.serper.dev", "scrape.serper.dev"],
157
+ data: "per-call",
158
+ access: ["read"],
159
+ readMethods: ["POST"],
160
+ accountWidePaths: [],
161
+ hint: 'An API key from serper.dev (2,500 free queries to start); the Gateway sends it in the X-API-KEY header. Every search is a POST to google.serper.dev/<type> (search, news, images, places, …) with a JSON body such as {"q": "…"}.',
162
+ secrets: [
163
+ {
164
+ name: "SERPER_API_KEY",
165
+ hint: "The API key on serper.dev's API keys page.",
166
+ },
167
+ ],
168
+ cost: {
169
+ unit: "call",
170
+ usd: 0.001,
171
+ note: "Prepaid credits, one per successful query: $1.00 per 1k on the 50k pack, down to $0.30 per 1k on the largest.",
172
+ },
173
+ rate: {
174
+ perSecond: 50,
175
+ note: "Starter credits 50 queries per second; Standard 100, Scale 200, Ultimate 300.",
176
+ },
177
+ example: "get the top Google results for best project management software",
178
+ verified: false,
179
+ tags: ["search", "serp"],
180
+ },
181
+ "brave-search": {
182
+ mode: "api_key",
183
+ label: "Brave Search",
184
+ description: "Brave's independent web index: web, news, images, videos, places, LLM context and answers.",
185
+ auth: {
186
+ kind: "header",
187
+ secret: "BRAVE_SEARCH_API_KEY",
188
+ header: "X-Subscription-Token",
189
+ },
190
+ docs: "https://api-dashboard.search.brave.com/app/keys",
191
+ api: "https://api-dashboard.search.brave.com/documentation",
192
+ hosts: ["api.search.brave.com"],
193
+ data: "per-call",
194
+ access: ["read"],
195
+ readMethods: ["GET", "POST"],
196
+ accountWidePaths: [],
197
+ hint: "Activate a plan (it includes $5 of free credit a month), then create a key under API Keys; the Gateway sends it in the X-Subscription-Token header. Searches are GETs (POST works too); answers are a POST to /res/v1/chat/completions.",
198
+ secrets: [
199
+ {
200
+ name: "BRAVE_SEARCH_API_KEY",
201
+ hint: "A key from the API Keys section of the Brave Search API dashboard, made after activating a plan.",
202
+ },
203
+ ],
204
+ cost: {
205
+ unit: "call",
206
+ usd: 0.005,
207
+ note: "Search $5 per 1k requests; Answers $4 per 1k plus $5 per million tokens; $5 free credit a month; only successful calls count.",
208
+ },
209
+ rate: {
210
+ perSecond: 50,
211
+ note: "Search plan 50 queries per second; Answers 2 per second.",
212
+ },
213
+ example: "search the web for the latest Cloudflare Workers release notes",
214
+ verified: {
215
+ on: "2026-10-25",
216
+ how: "docs",
217
+ },
218
+ tags: ["search"],
219
+ },
220
+ apify: {
221
+ mode: "api_key",
222
+ label: "Apify",
223
+ description: "Runs Apify Actors (ready-made scrapers and automations) and reads their datasets and stores.",
224
+ auth: {
225
+ kind: "bearer",
226
+ secret: "APIFY_API_TOKEN",
227
+ },
228
+ docs: "https://console.apify.com/settings/integrations",
229
+ api: "https://docs.apify.com/api/v2",
230
+ hosts: ["api.apify.com"],
231
+ data: "account",
232
+ access: ["read", "write"],
233
+ readMethods: ["GET", "HEAD"],
234
+ writeMethods: ["POST", "PUT", "DELETE"],
235
+ accountWidePaths: [
236
+ ["users"],
237
+ ["webhooks"],
238
+ ["webhook-dispatches"],
239
+ ["env-vars"],
240
+ ],
241
+ hint: "The API token from Apify Console, Settings > API & Integrations; the Gateway sends it as a bearer token. Reading Actors, runs and datasets needs read; starting a run is a POST, so it needs write.",
242
+ secrets: [
243
+ {
244
+ name: "APIFY_API_TOKEN",
245
+ hint: "The API token under Settings > API & Integrations in Apify Console.",
246
+ },
247
+ ],
248
+ smoke: {
249
+ method: "GET",
250
+ path: "/v2/users/me",
251
+ expect: [200],
252
+ free: true,
253
+ note: "The docs' verify call; account-wide, so the Gateway refuses it for apps: run it from the person's terminal.",
254
+ },
255
+ rate: {
256
+ perSecond: 60,
257
+ note: "60 requests per second per resource (one Actor, run, dataset or store); 250,000 requests per minute per user overall.",
258
+ },
259
+ example: "run the Google Maps scraper Actor for coffee shops in Austin and list the results",
260
+ verified: {
261
+ on: "2026-10-25",
262
+ how: "docs",
263
+ },
264
+ tags: ["scrape", "automation"],
265
+ },
266
+ deepgram: {
267
+ mode: "api_key",
268
+ label: "Deepgram",
269
+ description: "Speech to text, text to speech and text analysis.",
270
+ auth: {
271
+ kind: "bearer",
272
+ secret: "DEEPGRAM_API_KEY",
273
+ scheme: "Token",
274
+ },
275
+ docs: "https://console.deepgram.com/",
276
+ api: "https://developers.deepgram.com/reference/deepgram-api-overview",
277
+ hosts: [
278
+ "api.deepgram.com",
279
+ "api.eu.deepgram.com",
280
+ "api.au.deepgram.com",
281
+ "api.in.deepgram.com",
282
+ ],
283
+ data: "per-call",
284
+ access: ["read"],
285
+ readMethods: ["GET", "POST"],
286
+ accountWidePaths: [["projects"], ["auth", "grant"]],
287
+ hint: "An API key from the Deepgram Console; the Gateway sends it as Authorization: Token <key>, and the EU, Australia and India hosts take the same key. Transcription (/v1/listen), speech (/v1/speak) and text analysis (/v1/read) are POSTs.",
288
+ secrets: [
289
+ {
290
+ name: "DEEPGRAM_API_KEY",
291
+ hint: "A project API key created in the Deepgram Console.",
292
+ },
293
+ ],
294
+ smoke: {
295
+ method: "GET",
296
+ path: "/v1/models",
297
+ expect: [200],
298
+ free: true,
299
+ note: "Lists the public models; it needs the key and processes no audio.",
300
+ },
301
+ cost: {
302
+ unit: "call",
303
+ note: "Nova-3 pre-recorded $0.0043 per audio minute (pay as you go); Aura-2 speech $0.030 per 1k characters; $200 free credit.",
304
+ },
305
+ rate: {
306
+ note: "Concurrency per project on pay as you go: 50 pre-recorded transcriptions, 15 text-to-speech requests.",
307
+ },
308
+ example: "transcribe this podcast episode and label the speakers",
309
+ verified: {
310
+ on: "2026-10-25",
311
+ how: "docs",
312
+ },
313
+ tags: ["speech", "transcription"],
314
+ },
315
+ elevenlabs: {
316
+ mode: "api_key",
317
+ label: "ElevenLabs",
318
+ description: "Text to speech, speech to text, sound effects, music and voice changing.",
319
+ auth: {
320
+ kind: "header",
321
+ secret: "ELEVENLABS_API_KEY",
322
+ header: "xi-api-key",
323
+ },
324
+ docs: "https://elevenlabs.io/app/settings/api-keys",
325
+ api: "https://elevenlabs.io/docs/api-reference/introduction",
326
+ hosts: ["api.elevenlabs.io"],
327
+ data: "per-call",
328
+ access: ["read"],
329
+ readMethods: ["GET", "POST"],
330
+ accountWidePaths: [
331
+ ["v1", "user"],
332
+ ["v1", "usage"],
333
+ ["v1", "workspace"],
334
+ ["v1", "workspaces"],
335
+ ["v1", "service-accounts"],
336
+ ["v1", "history"],
337
+ ["v1", "single-use-token"],
338
+ ["v1", "convai"],
339
+ ["v1", "dubbing"],
340
+ ["v1", "studio"],
341
+ ["v1", "pronunciation-dictionaries"],
342
+ ["v1", "voices", "add"],
343
+ ["v1", "voices", "pvc"],
344
+ ["v1", "voices", "collections"],
345
+ ["edit"],
346
+ ["replicate-to-isolated-environment"],
347
+ ["v1", "text-to-voice"],
348
+ ["v1", "audio-native"],
349
+ ["v1", "productions"],
350
+ ["v1", "speech-engine"],
351
+ ["v1", "music", "finetunes"],
352
+ ["v1", "flows"],
353
+ ["v1", "assets"],
354
+ ["v1", "audio-isolation", "history"],
355
+ ],
356
+ hint: "An API key from ElevenLabs' API keys page; the Gateway sends it in the xi-api-key header. Speech, transcription and sound generation are POSTs; listing voices and models are GETs.",
357
+ secrets: [
358
+ {
359
+ name: "ELEVENLABS_API_KEY",
360
+ hint: "An API key from ElevenLabs' API keys page; it can be scoped to the endpoints the app uses and given a credit cap.",
361
+ },
362
+ ],
363
+ smoke: {
364
+ method: "GET",
365
+ path: "/v1/models",
366
+ expect: [200],
367
+ free: true,
368
+ note: "The first request in ElevenLabs' authentication docs; it generates nothing.",
369
+ },
370
+ example: "read this paragraph aloud in a calm narrator voice",
371
+ verified: {
372
+ on: "2026-10-25",
373
+ how: "docs",
374
+ },
375
+ tags: ["speech", "audio"],
376
+ },
377
+ // `account`, not per-call: GET /v2/transcript lists every transcript on the account and shares its segment with /v2/transcript/<id>.
378
+ assemblyai: {
379
+ mode: "api_key",
380
+ label: "AssemblyAI",
381
+ description: "Transcribes recorded audio and video, with speaker labels, redaction and subtitles.",
382
+ auth: {
383
+ kind: "header",
384
+ secret: "ASSEMBLYAI_API_KEY",
385
+ header: "Authorization",
386
+ },
387
+ docs: "https://www.assemblyai.com/dashboard/home",
388
+ api: "https://www.assemblyai.com/docs",
389
+ hosts: ["api.assemblyai.com", "api.eu.assemblyai.com"],
390
+ data: "account",
391
+ access: ["read", "write"],
392
+ readMethods: ["GET", "POST"],
393
+ writeMethods: ["DELETE"],
394
+ accountWidePaths: [],
395
+ hint: "The API key from your AssemblyAI dashboard; the Gateway sends it as the whole Authorization header, with no Bearer word. Audio is submitted with a POST to /v2/transcript and the app polls GET /v2/transcript/<id>; deleting a transcript needs write.",
396
+ secrets: [
397
+ {
398
+ name: "ASSEMBLYAI_API_KEY",
399
+ hint: "The API key on your AssemblyAI dashboard.",
400
+ },
401
+ ],
402
+ smoke: {
403
+ method: "GET",
404
+ path: "/v2/transcript?limit=1",
405
+ expect: [200],
406
+ free: true,
407
+ note: "Lists the account's latest transcript; it transcribes nothing.",
408
+ },
409
+ cost: {
410
+ unit: "call",
411
+ note: "Per hour of audio submitted: Universal-3.5 Pro $0.21, Universal-2 $0.15; the free tier covers up to 185 hours of pre-recorded audio.",
412
+ },
413
+ rate: {
414
+ perMinute: 4000,
415
+ note: "20,000 requests per 5 minutes per account; 5 transcriptions in parallel on free accounts, 200 or more on paid.",
416
+ },
417
+ example: "transcribe this sales call recording with speaker labels",
418
+ verified: {
419
+ on: "2026-10-25",
420
+ how: "docs",
421
+ },
422
+ tags: ["speech", "transcription"],
423
+ },
424
+ newsapi: {
425
+ mode: "api_key",
426
+ label: "NewsAPI",
427
+ description: "Searches news articles and live headlines from over 150,000 sources.",
428
+ auth: {
429
+ kind: "header",
430
+ secret: "NEWSAPI_API_KEY",
431
+ header: "X-Api-Key",
432
+ },
433
+ docs: "https://newsapi.org/register",
434
+ api: "https://newsapi.org/docs",
435
+ hosts: ["newsapi.org"],
436
+ data: "per-call",
437
+ access: ["read"],
438
+ readMethods: ["GET"],
439
+ accountWidePaths: [],
440
+ hint: "An API key from newsapi.org/register; the Gateway sends it in the X-Api-Key header. The free Developer plan allows 100 requests a day, delays articles by 24 hours and is for development only; production needs a paid plan.",
441
+ secrets: [
442
+ {
443
+ name: "NEWSAPI_API_KEY",
444
+ hint: "The API key NewsAPI shows after you register.",
445
+ },
446
+ ],
447
+ cost: {
448
+ unit: "call",
449
+ usd: 0.0018,
450
+ note: "Developer plan free (100 requests a day, development only); Business $449 a month for 250,000 requests, then $0.0018 each.",
451
+ },
452
+ rate: {
453
+ perDay: 100,
454
+ note: "Developer plan; Business includes 250,000 requests a month, Advanced 2,000,000.",
455
+ },
456
+ example: "find today's top business headlines in the US",
457
+ verified: {
458
+ on: "2026-10-25",
459
+ how: "docs",
460
+ },
461
+ tags: ["news"],
462
+ },
463
+ };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * A provider registered on a gateway, in local development
3
+ * (docs/design/2026-10-provider-registry.md, section 4). There is no
4
+ * gateway to ask in `everyapp dev`, so the spec comes from the app's
5
+ * directory: `everyapp provider add` (run in an app directory) and
6
+ * `everyapp provider show <id> --save` write it to
7
+ * `.everyapp/providers/<id>.json`, `everyAppWorker()` reads every such
8
+ * file when it builds the dev Worker and hands them over as one text
9
+ * binding, {@link DEV_PROVIDERS_ENV}, and `integrationFetch()`'s local
10
+ * fallback resolves an id outside the catalog from it, with the
11
+ * developer's own key from `.dev.vars` under the spec's setting names.
12
+ *
13
+ * The binding is JSON: `[{ "file": ".everyapp/providers/stripe.json",
14
+ * "spec": <the file's JSON, or its text when it isn't JSON> }]`. Each spec
15
+ * is parsed here, with the same parser `provider add` uses; one that
16
+ * doesn't parse is ignored until an app asks for its id, which then gets
17
+ * a ConfigurationError naming the file.
18
+ */
19
+ import type { ApiKeyCapability } from "./capabilities.js";
20
+ /** The dev Worker's binding holding the specs (a copy is in ../cloudflare/worker.ts, kept in step by a test). */
21
+ export declare const DEV_PROVIDERS_ENV = "EVERYAPP_DEV_PROVIDERS";
22
+ /** Where the specs live in an app, relative to its directory. */
23
+ export declare const DEV_PROVIDERS_DIR = ".everyapp/providers";
24
+ /** One file as the binding carries it. */
25
+ export interface DevProviderFile {
26
+ /** Relative to the app: `.everyapp/providers/stripe.json`. */
27
+ file: string;
28
+ /** The file's JSON, or its text when it isn't JSON. */
29
+ spec: unknown;
30
+ }
31
+ /** The file `everyapp dev` reads a registered provider's spec from. */
32
+ export declare function devProviderFile(id: string): string;
33
+ /** A registered provider resolved for local development, or why it can't be. */
34
+ export type DevProviderLookup = {
35
+ found: true;
36
+ capability: ApiKeyCapability;
37
+ file: string;
38
+ } | {
39
+ found: false;
40
+ problem: string;
41
+ };
42
+ /**
43
+ * `id`'s spec from the dev Worker's {@link DEV_PROVIDERS_ENV}: a file whose
44
+ * spec says that id, or whose name is `<id>.json`. A file that matches but
45
+ * doesn't parse (or names another id) is the problem; no file is too,
46
+ * naming the command that writes one.
47
+ */
48
+ export declare function resolveDevProvider(values: Readonly<Record<string, unknown>>, id: string): DevProviderLookup;
49
+ //# sourceMappingURL=devProviders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devProviders.d.ts","sourceRoot":"","sources":["../../src/internal/devProviders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,iHAAiH;AACjH,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,EAAE,OAAO,CAAC;CACf;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GACzB;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAuBtC;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,EAAE,EAAE,MAAM,GACT,iBAAiB,CA+BnB"}
@@ -0,0 +1,62 @@
1
+ import { describeSpecProblems, parseProviderSpec } from "./providerSpec.js";
2
+ /** The dev Worker's binding holding the specs (a copy is in ../cloudflare/worker.ts, kept in step by a test). */
3
+ export const DEV_PROVIDERS_ENV = "EVERYAPP_DEV_PROVIDERS";
4
+ /** Where the specs live in an app, relative to its directory. */
5
+ export const DEV_PROVIDERS_DIR = ".everyapp/providers";
6
+ /** The file `everyapp dev` reads a registered provider's spec from. */
7
+ export function devProviderFile(id) {
8
+ return `${DEV_PROVIDERS_DIR}/${id}.json`;
9
+ }
10
+ function isRecord(value) {
11
+ return typeof value === "object" && value !== null && !Array.isArray(value);
12
+ }
13
+ /** The files the binding carries; none when it is absent or not of its shape. */
14
+ function devProviderFiles(value) {
15
+ if (typeof value !== "string")
16
+ return [];
17
+ let parsed;
18
+ try {
19
+ parsed = JSON.parse(value);
20
+ }
21
+ catch {
22
+ return [];
23
+ }
24
+ if (!Array.isArray(parsed))
25
+ return [];
26
+ return parsed.flatMap((entry) => isRecord(entry) && typeof entry["file"] === "string"
27
+ ? [{ file: entry["file"], spec: entry["spec"] }]
28
+ : []);
29
+ }
30
+ /**
31
+ * `id`'s spec from the dev Worker's {@link DEV_PROVIDERS_ENV}: a file whose
32
+ * spec says that id, or whose name is `<id>.json`. A file that matches but
33
+ * doesn't parse (or names another id) is the problem; no file is too,
34
+ * naming the command that writes one.
35
+ */
36
+ export function resolveDevProvider(values, id) {
37
+ const files = devProviderFiles(values[DEV_PROVIDERS_ENV]);
38
+ const matching = files.filter((entry) => (isRecord(entry.spec) && entry.spec["id"] === id) ||
39
+ entry.file.split("/").at(-1) === `${id}.json`);
40
+ let problem = null;
41
+ for (const entry of matching) {
42
+ const parsed = parseProviderSpec(typeof entry.spec === "string" ? null : entry.spec);
43
+ if (!parsed.ok) {
44
+ problem ??=
45
+ typeof entry.spec === "string"
46
+ ? `${entry.file} isn't JSON`
47
+ : `${entry.file} isn't a provider spec: ${describeSpecProblems(parsed.problems)}`;
48
+ continue;
49
+ }
50
+ if (parsed.id !== id) {
51
+ problem ??= `${entry.file} is ${parsed.id}'s spec, not ${id}'s`;
52
+ continue;
53
+ }
54
+ return { found: true, capability: parsed.capability, file: entry.file };
55
+ }
56
+ return {
57
+ found: false,
58
+ problem: problem
59
+ ? `${problem}. Write it again with everyapp provider show ${id} --save in the app's directory, then start everyapp dev again.`
60
+ : `"${id}" isn't in the built-in provider catalog, and no ${devProviderFile(id)} describes it. A provider registered on the gateway (everyapp provider add) is reached through the EVERY_APP_GATEWAY binding; for everyapp dev, run everyapp provider show ${id} --save in the app's directory, then start everyapp dev again.`,
61
+ };
62
+ }