everyapp 0.3.0-rc.2 → 0.3.0-rc.4
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/README.md +1 -1
- package/dist/access-YWM4BSBD.js +1 -0
- package/dist/activity-RTCAUMQS.js +14 -0
- package/dist/ai-UOYQFTAX.js +5 -0
- package/dist/apps-PEOBCDNU.js +14 -0
- package/dist/chunk-26KS6TD6.js +1 -0
- package/dist/chunk-3EADVHFN.js +15 -0
- package/dist/chunk-4LKLQOM7.js +7 -0
- package/dist/{chunk-PNLU5U3P.js → chunk-5IC3ZN52.js} +1 -1
- package/dist/{chunk-H7PDL3X5.js → chunk-AMCNAKYU.js} +1 -1
- package/dist/{chunk-23HJ5I2A.js → chunk-ASCNE7GS.js} +1 -1
- package/dist/{chunk-6OGVO7QK.js → chunk-BCTEWNN4.js} +1 -1
- package/dist/{chunk-W3JCQHHU.js → chunk-BK4NK34C.js} +1 -1
- package/dist/chunk-BWNZ6F4F.js +2 -0
- package/dist/chunk-DCFHBCCW.js +9 -0
- package/dist/{chunk-2Y5Q6A5K.js → chunk-DWTJ4OLZ.js} +1 -1
- package/dist/chunk-EP3IQ354.js +20 -0
- package/dist/{chunk-OP4DYXYI.js → chunk-EP4HRYXP.js} +1 -1
- package/dist/{chunk-HOUHG236.js → chunk-EQLY5I46.js} +1 -1
- package/dist/{chunk-YHJZMJYZ.js → chunk-F5XK23HV.js} +1 -1
- package/dist/{chunk-5PTNYZK6.js → chunk-FB2OC32C.js} +3 -3
- package/dist/chunk-FQ2A7YAP.js +57 -0
- package/dist/{chunk-OM2HDWVP.js → chunk-GAPQSINH.js} +1 -1
- package/dist/chunk-GJK6GAWO.js +1 -0
- package/dist/chunk-H4EZTXIK.js +1 -0
- package/dist/chunk-HJGZGZFE.js +32 -0
- package/dist/{chunk-CCWBPAKH.js → chunk-I7FNTTUY.js} +3 -3
- package/dist/chunk-KOBKGQ27.js +91 -0
- package/dist/{chunk-PS7S74DG.js → chunk-KQM6ZUX5.js} +1 -1
- package/dist/chunk-KVCL64LI.js +1 -0
- package/dist/{chunk-4JRIS6S6.js → chunk-LEEUODYR.js} +1 -1
- package/dist/{chunk-6PGUCTJ6.js → chunk-LI3YLKLC.js} +1 -1
- package/dist/chunk-MEIWV7FJ.js +20 -0
- package/dist/{configure-F7UZCJUG.js → chunk-MLTNW3AM.js} +2 -2
- package/dist/chunk-NDOEON54.js +4 -0
- package/dist/chunk-NW7SJPSP.js +37 -0
- package/dist/chunk-O64FPLGX.js +1 -0
- package/dist/chunk-ORGV2NNT.js +8 -0
- package/dist/chunk-PDPUGYJW.js +47 -0
- package/dist/chunk-QFTBDXLF.js +146 -0
- package/dist/{chunk-E3EPK27P.js → chunk-QJRZFIYC.js} +2 -2
- package/dist/chunk-QKHLRLK3.js +15 -0
- package/dist/{chunk-CZXHKPRZ.js → chunk-R2DF3ENZ.js} +1 -1
- package/dist/{chunk-IUOBIB5M.js → chunk-R7JOHK7Y.js} +2 -2
- package/dist/chunk-RL72BUT4.js +1 -0
- package/dist/chunk-RQBSTNL7.js +1 -0
- package/dist/{chunk-H6QQMY7B.js → chunk-S2G4G73L.js} +1 -1
- package/dist/{chunk-LXYMDZER.js → chunk-SGRGD7L4.js} +1 -1
- package/dist/{chunk-T2GD7RHS.js → chunk-TIYSZWP5.js} +1 -1
- package/dist/chunk-TUXKBLLJ.js +10 -0
- package/dist/chunk-U4ATZJEU.js +6 -0
- package/dist/chunk-V7BWZOSZ.js +26 -0
- package/dist/{chunk-J35DDCNU.js → chunk-VVKQJSF3.js} +1 -1
- package/dist/chunk-WVHJIYQ3.js +14 -0
- package/dist/{chunk-ZEXVHB22.js → chunk-XBD7PQN5.js} +1 -1
- package/dist/{chunk-N5GQLGEC.js → chunk-YAZHTVUV.js} +1 -1
- package/dist/configure-CAWCTPYY.js +1 -0
- package/dist/{create-2E5HVWYK.js → create-3ZWJQXPK.js} +2 -2
- package/dist/{db-HEQVTDTM.js → db-B7KO37SV.js} +1 -1
- package/dist/delete-CB3EPOU4.js +3 -0
- package/dist/deploy-5O7LV5OX.js +1 -0
- package/dist/dev-4JYCVVOZ.js +86 -0
- package/dist/{email-RLZFUFUN.js → email-SWJQXEUR.js} +1 -1
- package/dist/{events-2V5VRBWP.js → events-GJV2KVIU.js} +13 -13
- package/dist/{groups-HDG5DVFY.js → groups-NNTLSXMK.js} +1 -1
- package/dist/index.js +104 -95
- package/dist/install-UAG3CNYW.js +1 -0
- package/dist/{login-KHJBC64Z.js → login-QEKMLMUB.js} +1 -1
- package/dist/mcp-AFGVOM5D.js +1 -0
- package/dist/provider-622VM7UZ.js +29 -0
- package/dist/release-CXEX6O7F.js +1 -0
- package/dist/{restore-FFGYV7NO.js → restore-PGIVEA5P.js} +1 -1
- package/dist/secret-3LUDEDUW.js +1 -0
- package/dist/setup-PUD375AM.js +1 -0
- package/dist/{signin-AP3D4XM4.js → signin-EP5JLAT5.js} +2 -2
- package/dist/status-LK6DNLCI.js +5 -0
- package/dist/teardown-6RURRSME.js +22 -0
- package/dist/update-YJFTOZEV.js +1 -0
- package/dist/{workspace-CJC5I66L.js → workspace-VW7ZZRFP.js} +3 -3
- package/package.json +5 -5
- package/skills/build-every-app/SKILL.md +22 -13
- package/skills/build-every-app/patterns.md +16 -3
- package/skills/everyapp/SKILL.md +33 -18
- package/skills/everyapp/mcp.md +22 -8
- package/skills/everyapp/security-review.md +1 -1
- package/skills/everyapp/setup/README.md +18 -1
- package/skills/everyapp/setup/access.md +11 -7
- package/skills/everyapp/setup/ai-gateway.md +117 -0
- package/skills/everyapp/setup/ai.md +139 -0
- package/skills/everyapp/setup/context.md +2 -2
- package/skills/everyapp/setup/dataforseo.md +3 -3
- package/skills/everyapp/setup/email.md +1 -1
- package/skills/everyapp/setup/gateway.md +3 -3
- package/skills/everyapp/setup/google.md +8 -6
- package/skills/everyapp/setup/microsoft-365.md +4 -2
- package/skills/everyapp/setup/providers.md +27 -9
- package/skills/everyapp/setup/remote-mcp.md +1 -1
- package/skills/everyapp/setup/signin-apple.md +3 -3
- package/skills/everyapp/setup/signin-cloudflare.md +1 -1
- package/skills/everyapp/setup/signin-github.md +1 -1
- package/skills/everyapp/setup/signin-google.md +2 -2
- package/skills/everyapp/setup/signin-microsoft.md +1 -1
- package/skills/everyapp/setup/slack.md +2 -0
- package/dist/access-LGEN3ABJ.js +0 -1
- package/dist/activity-RSD4D66F.js +0 -12
- package/dist/apps-4RCFXT74.js +0 -13
- package/dist/chunk-AGTCKFRB.js +0 -22
- package/dist/chunk-BHMRY53V.js +0 -2
- package/dist/chunk-CB4U7H2G.js +0 -4
- package/dist/chunk-CZTEDWZ2.js +0 -22
- package/dist/chunk-EGEWRFVY.js +0 -1
- package/dist/chunk-ELK7QZ2M.js +0 -1
- package/dist/chunk-FJJSSVET.js +0 -33
- package/dist/chunk-GKBPYVP3.js +0 -25
- package/dist/chunk-IFCPALVC.js +0 -46
- package/dist/chunk-J455FAEN.js +0 -7
- package/dist/chunk-JYKRUS5C.js +0 -1
- package/dist/chunk-LYNBZ7RV.js +0 -57
- package/dist/chunk-M2QQ2UD7.js +0 -132
- package/dist/chunk-NFU4YFXB.js +0 -1
- package/dist/chunk-ONLNJXVQ.js +0 -32
- package/dist/chunk-RMF4YGD6.js +0 -98
- package/dist/chunk-TLRM3P7V.js +0 -15
- package/dist/chunk-WOVS3GV5.js +0 -10
- package/dist/chunk-ZECBN24L.js +0 -15
- package/dist/chunk-ZFCUH5PK.js +0 -7
- package/dist/delete-XCSIQIRS.js +0 -3
- package/dist/deploy-3QOZEZHC.js +0 -1
- package/dist/dev-JL3ZP5BT.js +0 -86
- package/dist/install-Z5FYXUYM.js +0 -1
- package/dist/mcp-EFDUKJ5V.js +0 -1
- package/dist/provider-EOI5PTFH.js +0 -13
- package/dist/release-74J5ZIL3.js +0 -1
- package/dist/secret-7FKKTLHB.js +0 -1
- package/dist/setup-PAKRCAFO.js +0 -1
- package/dist/status-RMWNHOEK.js +0 -4
- package/dist/teardown-E4JNKAZJ.js +0 -22
- package/dist/update-DWVZFNPS.js +0 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var wa=Object.defineProperty;var Ea=(e,t,s)=>t in e?wa(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var ne=(e,t,s)=>(Ea(e,typeof t!="symbol"?t+"":t,s),s);var Ku="everyapp";var Hu="0.3.0";var sn={"@cloudflare/config":"0.24.1","@inquirer/prompts":"^8.7.3","@stricli/core":"^1.3.0",cf:"1.0.0-beta.14",chalk:"^5.6.2","cli-cursor":"^5.0.0",execa:"^9.6.0",jiti:"^2.6.1",undici:"^7.30.1",zod:"^4.2.0"};function ba(e=process.env){let t=e.npm_config_user_agent?.split("/")[0];return t?_a[t]??"everyapp":"everyapp"}var _a={pnpm:"pnpm everyapp",npm:"npx everyapp",yarn:"yarn everyapp"},Gt=ba();function x(e=[],{terminal:t=!1,argv:s=process.argv.slice(2)}={}){let n=t?s.filter(r=>r!=="--json"):[...s];for(let r of e)n.includes(r)||n.push(r);return[Gt,...n.map(Aa)].join(" ")}function Wu(e,t=process.argv.slice(2)){let s=[];for(let n=0;n<t.length;n++){let r=t[n];r===e?n++:r.startsWith(`${e}=`)||s.push(r)}return x([],{argv:s})}function Aa(e){return/^[\w@%+=:,./-]+$/.test(e)?e:`'${e.replace(/'/g,"'\\''")}'`}var B=(e,t)=>`${e} ${t}${e===1?"":"s"}`,Ve=e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}`,g=e=>typeof e=="string"&&e.length>0?e:void 0,Fu=e=>g(e)??null;function re(...e){return e.join(`
|
|
2
|
+
`).split(/\r?\n/).map(t=>t.trimEnd()).filter(t=>t.trim().length>0).slice(-20)}function Ut(e){return e.length<=1?e[0]??"":`${e.slice(0,-1).join(", ")} and ${e.at(-1)}`}var $=e=>Array.isArray(e)?e.map(String):[];var nn={stripe:{mode:"api_key",label:"Stripe",description:"Payments: customers, subscriptions, invoices, charges and payouts.",auth:{kind:"bearer",secret:"STRIPE_API_KEY"},docs:"https://dashboard.stripe.com/apikeys",api:"https://docs.stripe.com/api",hosts:["api.stripe.com","files.stripe.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","DELETE"],accountWidePaths:[["v1","account"],["v1","accounts"],["v2","core","accounts"],["v1","webhook_endpoints"],["v2","core","event_destinations"],["v1","apps","secrets"]],hint:"A restricted API key from the API keys page of the Stripe dashboard, with only the permissions the app needs. The Gateway sends it as a bearer token.",secrets:[{name:"STRIPE_API_KEY",hint:"A restricted key (rk_live_...) with only the permissions the app needs; a sandbox key (rk_test_... or sk_test_...) to try it."}],smoke:{method:"GET",path:"/v1/balance",expect:[200],free:!0,note:"A restricted key needs Balance read for this one."},cost:{unit:"call",note:"No per-call price; reads should average under 500 per transaction over 30 days, with at least 10,000 a month allowed."},rate:{perSecond:100,note:"Live mode, per account; sandbox 25/s; most single endpoints 25/s; Search 20/s."},example:"list my latest customers and their subscriptions",verified:{on:"2026-10-25",how:"docs"},tags:["payments","billing"]},lemonsqueezy:{mode:"api_key",label:"Lemon Squeezy",description:"Merchant of record for software: stores, products, orders, subscriptions, license keys.",auth:{kind:"bearer",secret:"LEMONSQUEEZY_API_KEY"},docs:"https://app.lemonsqueezy.com/settings/api",api:"https://docs.lemonsqueezy.com/api",hosts:["api.lemonsqueezy.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PATCH","DELETE"],accountWidePaths:[["v1","users"],["v1","webhooks"]],hint:"An API key from Settings > API in Lemon Squeezy; the Gateway sends it as a bearer token. The API is JSON:API, so the app sends Accept and Content-Type application/vnd.api+json.",secrets:[{name:"LEMONSQUEEZY_API_KEY",hint:"An API key from Settings > API; a test mode key reaches test mode store data only."}],smoke:{method:"GET",path:"/v1/users/me",expect:[200],free:!0,note:"Account-wide, so the Gateway refuses it for apps; run it from the person's terminal."},rate:{perMinute:300,note:"300 API calls per minute."},example:"list this month's orders and active subscriptions",verified:{on:"2026-10-25",how:"docs"},tags:["payments","billing"]},paddle:{mode:"api_key",label:"Paddle",description:"Paddle Billing: products, prices, customers, subscriptions and transactions.",auth:{kind:"bearer",secret:"PADDLE_API_KEY"},docs:"https://developer.paddle.com/api-reference/about/authentication/",api:"https://developer.paddle.com/api-reference/",hosts:["api.paddle.com","sandbox-api.paddle.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PATCH","DELETE"],accountWidePaths:[["account"],["settings"],["notification-settings"],["notifications"],["simulations"],["simulation-runs"],["client-tokens"],["checkout-domains"],["verifications"]],hint:"An API key from Paddle > My account > Settings > Authentication (API keys tab), with only the permissions the app needs; the Gateway sends it as a bearer token. Live and sandbox are separate hosts with separate keys.",secrets:[{name:"PADDLE_API_KEY",hint:"An API key (pdl_live_apikey_... or pdl_sdbx_apikey_...) with only the permissions the app needs; a sandbox key works on the sandbox host only."}],smoke:{method:"GET",path:"/event-types",expect:[200],free:!0,note:"Paddle's own first request: needs no permissions. Send it to sandbox-api.paddle.com with a sandbox key."},rate:{perMinute:240,note:"Per IP address; pricing previews 1,000 a minute; 20 immediate-charge updates per subscription an hour."},example:"list the active subscriptions that renew this week",verified:{on:"2026-10-25",how:"docs"},tags:["payments","billing"]},shopify:{mode:"api_key",label:"Shopify",description:"One store's Admin API (GraphQL): products, orders, customers and inventory.",auth:{kind:"header",secret:"SHOPIFY_API_TOKEN",header:"X-Shopify-Access-Token"},docs:"https://shopify.dev/docs/apps/build/authentication-authorization/legacy/admin-custom-apps",api:"https://shopify.dev/docs/api/admin-graphql",hosts:[],hostSetting:"SHOPIFY_HOST",data:"account",access:["write"],readMethods:[],writeMethods:["POST"],accountWidePaths:[["webhooks"],["storefront_access_tokens"]],hint:"An Admin API access token from a custom app created in the store's admin, sent in the X-Shopify-Access-Token header to the store's myshopify.com host. Shopify no longer lets stores create new admin custom apps, and Dev Dashboard tokens expire after 24 hours, which the Gateway can't refresh yet.",secrets:[{name:"SHOPIFY_API_TOKEN",hint:"The Admin API access token of a custom app made in the store's admin (Apps > Develop apps > the app > API credentials); it is shown once."},{name:"SHOPIFY_HOST",hint:"The store's own host, like your-store.myshopify.com."}],smoke:{method:"GET",path:"/admin/api/2026-10/shop.json",expect:[200],free:!0,note:"The legacy REST read of the store; the Gateway forwards no GET for this entry, so run it from the person's terminal."},rate:{note:"GraphQL cost points per second by plan: Standard 100, Advanced 200, Plus 1,000, enterprise 2,000."},example:"list the ten newest orders and what was in them",verified:{on:"2026-10-25",how:"docs"},tags:["ecommerce"]},plaid:{mode:"api_key",label:"Plaid",description:"Bank data: accounts, balances, transactions and identity, for the Items an app links.",auth:{kind:"header",secret:"PLAID_SECRET",header:"PLAID-SECRET"},docs:"https://dashboard.plaid.com/developers/keys",api:"https://plaid.com/docs/api/",hosts:["sandbox.plaid.com","production.plaid.com"],data:"account",access:["read"],readMethods:["POST"],accountWidePaths:[["item","webhook","update"],["item","access_token","invalidate"],["item","remove"],["webhook_verification_key"],["dashboard_user"],["transfer"],["payment_initiation"]],hint:"Plaid needs a client_id and a secret on every call, in the JSON body or in the PLAID-CLIENT-ID and PLAID-SECRET headers. The Gateway puts on one header, so the app would have to send PLAID-CLIENT-ID itself. Every endpoint is a POST.",secrets:[{name:"PLAID_SECRET",hint:"The secret for one environment (Sandbox or Production) from the Keys page of the Plaid Dashboard."}],rate:{note:"Set per endpoint and per Item: /accounts/get allows 15 a minute per Item and 15,000 a minute per client."},example:"list the last 30 days of transactions on a linked account",verified:!1,tags:["finance","banking"]},attio:{mode:"api_key",label:"Attio",description:"CRM: people, companies, deals, lists, notes and tasks in one Attio workspace.",auth:{kind:"bearer",secret:"ATTIO_API_KEY"},docs:"https://attio.com/help/reference/apps/generating-an-api-key",api:"https://docs.attio.com/rest-api/overview",hosts:["api.attio.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["v2","self"],["v2","webhooks"],["v2","workspace_members"]],hint:"An access token a workspace admin makes under Workspace settings > Developers, scoped to what the app needs; the Gateway sends it as a bearer token. Listing and searching records are POSTs, so an app that lists records needs write access.",secrets:[{name:"ATTIO_API_KEY",hint:"An access token from Workspace settings > Developers, with only the scopes the app needs."}],smoke:{method:"GET",path:"/v2/objects",expect:[200],free:!0,note:"Lists the workspace's objects; needs the object_configuration:read scope. /v2/self answers 200 even for a revoked token."},rate:{perSecond:100,note:"100 reads and 25 writes per second; listing records and entries also has score-based limits."},example:"find the companies we added this week and their open deals",verified:{on:"2026-10-25",how:"docs"},tags:["crm"]},hubspot:{mode:"api_key",label:"HubSpot",description:"CRM and marketing: contacts, companies, deals, tickets and more in one HubSpot account.",auth:{kind:"bearer",secret:"HUBSPOT_API_TOKEN"},docs:"https://developers.hubspot.com/docs/apps/legacy-apps/private-apps/overview",api:"https://developers.hubspot.com/docs/api-reference/latest/overview",hosts:["api.hubapi.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["account-info"],["settings","users"],["settings","v3","users"],["settings","teams"],["app-webhooks"],["webhooks"],["webhooks-journal"],["oauth"]],hint:"An access token from a HubSpot legacy private app (Development > Legacy apps > Create legacy app > Private), scoped to what the app needs; the Gateway sends it as a bearer token. CRM search is a POST, so an app that searches needs write access.",secrets:[{name:"HUBSPOT_API_TOKEN",hint:"The access token of a legacy private app (Development > Legacy apps > the app > Auth), with only the scopes the app needs."}],smoke:{method:"GET",path:"/account-info/2026-09/details",expect:[200],free:!0,note:"Account-wide, so the Gateway refuses it for apps; run it from the person's terminal."},rate:{perDay:25e4,note:"Private apps on Free and Starter: 100 per 10 seconds per app and 250,000 a day per account; Pro 190 and 625,000; Enterprise 190 and 1,000,000."},example:"list the deals that moved to closed won this month",verified:{on:"2026-10-25",how:"docs"},tags:["crm","marketing"]},pipedrive:{mode:"api_key",label:"Pipedrive",description:"Sales CRM: deals, persons, organizations, activities and pipelines.",auth:{kind:"header",secret:"PIPEDRIVE_API_TOKEN",header:"x-api-token"},docs:"https://app.pipedrive.com/settings/api",api:"https://developers.pipedrive.com/docs/api/v1",hosts:["api.pipedrive.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["v1","users"],["v1","webhooks"],["v1","billing"],["v1","permissionsets"],["v1","roles"],["v1","usersettings"],["v1","userconnections"],["v1","legacyteams"]],hint:"A personal API token from Settings > Personal preferences > API in Pipedrive; the Gateway sends it in the x-api-token header. If API is missing there, an admin enables it for the person's permission set.",secrets:[{name:"PIPEDRIVE_API_TOKEN",hint:"Your personal API token from Settings > Personal preferences > API; it acts as you, and each company you belong to has its own."}],smoke:{method:"GET",path:"/v1/users/me",expect:[200],free:!0,note:"Account-wide, so the Gateway refuses it for apps; run it from the person's terminal."},cost:{unit:"call",note:"Each endpoint spends API tokens from a daily company budget of 30,000 x plan multiplier (1 to 7) x seats."},rate:{note:"Per API token: 20 (Lite) to 120 (Ultimate) requests per 2 seconds; Search 10 per 2 seconds."},example:"list the open deals in my main pipeline",verified:{on:"2026-10-25",how:"docs"},tags:["crm","sales"]},airtable:{mode:"api_key",label:"Airtable",description:"Bases, tables and records in the Airtable workspaces a token can reach.",auth:{kind:"bearer",secret:"AIRTABLE_API_TOKEN"},docs:"https://airtable.com/create/tokens",api:"https://airtable.com/developers/web/api/introduction",hosts:["api.airtable.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["v0","meta","whoami"],["v0","meta","enterpriseaccounts"],["v0","meta","workspaces"],["v0","meta","groups"],["v0","bases"],["scim"],["collaborators"],["invites"],["shares"],["blockinstallations"]],hint:"A personal access token from airtable.com/create/tokens, limited to the scopes and bases the app needs; the Gateway sends it as a bearer token. Listing records by POST (listRecords) needs write access; the GET form doesn't.",secrets:[{name:"AIRTABLE_API_TOKEN",hint:"A personal access token limited to the scopes and bases the app needs."}],smoke:{method:"GET",path:"/v0/meta/whoami",expect:[200],free:!0,note:"Account-wide, so the Gateway refuses it for apps; run it from the person's terminal."},rate:{perSecond:5,note:"5 requests per second per base; 50 per second across all of one user's personal access tokens."},example:"list this week's new rows in my Leads table",verified:{on:"2026-10-25",how:"docs"},tags:["database","spreadsheet"]},notion:{mode:"api_key",label:"Notion",description:"Pages, databases and blocks that a Notion connection has been given.",auth:{kind:"bearer",secret:"NOTION_API_TOKEN"},docs:"https://app.notion.com/developers/connections",api:"https://developers.notion.com/reference/intro",hosts:["api.notion.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PATCH","DELETE"],accountWidePaths:[["v1","users"],["v1","oauth"],["admin"]],hint:"An internal connection's API token (a workspace owner creates the connection in Notion's developer portal), sent as a bearer token; it reaches only pages shared with it. The app sends the Notion-Version header itself. Search and data source queries are POSTs, so an app that queries needs write access.",secrets:[{name:"NOTION_API_TOKEN",hint:"The API token on an internal connection's Configuration tab; share the pages it should reach with the connection."}],smoke:{method:"GET",path:"/v1/users/me",expect:[200],free:!0,note:"Send Notion-Version: 2026-03-11 with it; account-wide, so run it from the person's terminal."},rate:{perMinute:180,note:"Per connection: 180 a minute, 600 on Business and Enterprise; data source queries about 3 per second."},example:"find the pages in my Projects database that are due this week",verified:{on:"2026-10-25",how:"docs"},tags:["docs","notes","database"]}};var rn={postmark:{mode:"api_key",label:"Postmark",description:"Transactional email: single, batch and templated messages from one Postmark server.",auth:{kind:"header",secret:"POSTMARK_API_TOKEN",header:"X-Postmark-Server-Token"},docs:"https://postmarkapp.com/support/article/1008-what-are-the-account-and-server-api-tokens",api:"https://postmarkapp.com/developer/api/overview",hosts:["api.postmarkapp.com"],data:"account",access:["write"],readMethods:[],writeMethods:["POST"],accountWidePaths:[["server"],["servers"],["domains"],["senders"],["webhooks"],["message-streams"],["triggers"],["data-removals"]],hint:"A Server API token from the API Tokens tab of the Postmark server the app sends from; the Gateway sends it in the X-Postmark-Server-Token header.",secrets:[{name:"POSTMARK_API_TOKEN",hint:"A Server API token from the server's API Tokens tab, never the Account API token."}],smoke:{method:"GET",path:"/server",expect:[200],free:!0,note:"Returns the server's settings; account-wide, so run it from a terminal."},example:"send a password reset email",verified:{on:"2026-10-25",how:"docs"},tags:["email","transactional"]},sendgrid:{mode:"api_key",label:"SendGrid",description:"Twilio SendGrid email: send transactional and marketing mail through the v3 Mail Send API.",auth:{kind:"bearer",secret:"SENDGRID_API_KEY"},docs:"https://app.sendgrid.com/settings/api_keys",api:"https://www.twilio.com/docs/sendgrid/api-reference",hosts:["api.sendgrid.com","api.eu.sendgrid.com"],data:"account",access:["write"],readMethods:[],writeMethods:["POST"],accountWidePaths:[["api_keys"],["scopes"],["user"],["subusers"],["teammates"],["sso"],["access_settings"],["whitelabel"],["ips"],["send_ips"],["partners"],["partner_settings"],["alerts"],["mail_settings"],["tracking_settings"],["verified_senders"],["senders"],["marketing","integrations"],["recipients","erasejob"]],hint:"An API key from Settings > API Keys in SendGrid, sent as a bearer token; Custom Access with Mail Send alone is enough to send. EU regional subusers call api.eu.sendgrid.com.",secrets:[{name:"SENDGRID_API_KEY",hint:"A Custom Access key with Mail Send only, never a Full Access key."}],smoke:{method:"GET",path:"/v3/scopes",expect:[200],free:!0,note:"Lists the key's own scopes (the docs don't say whether a Mail-Send-only key may call it); account-wide, so run it from a terminal."},rate:{note:"Each endpoint has its own limit; answers carry X-RateLimit-Limit, -Remaining and -Reset."},example:"send an order confirmation email",verified:{on:"2026-10-25",how:"docs"},tags:["email","transactional","marketing"]},twilio:{mode:"api_key",label:"Twilio",description:"SMS, MMS and voice: send text messages and place calls from your Twilio numbers.",auth:{kind:"basic",secret:"TWILIO_API_SECRET",as:"password",user:{secret:"TWILIO_API_KEY"}},docs:"https://www.twilio.com/docs/iam/api-keys/keys-in-console",api:"https://www.twilio.com/docs/usage/requests-to-twilio",hosts:["api.twilio.com"],data:"account",access:["write"],readMethods:[],writeMethods:["POST"],accountWidePaths:[["keys"],["signingkeys"],["incomingphonenumbers"],["outgoingcallerids"],["applications"],["connectapps"],["authorizedconnectapps"],["addresses"],["sip"],["usage"],["balance"]],hint:"A Standard or Restricted API key from Account settings > API keys & auth tokens in the Twilio Console, sent as HTTP Basic (the key's SID and secret); a Standard key can't reach the Accounts or Keys resources. Every path names the account, so the app puts its Account SID in it: /2010-04-01/Accounts/<Account SID>/Messages.json, with a form-encoded body.",secrets:[{name:"TWILIO_API_SECRET",hint:"The API key's secret, shown once when the key is created."},{name:"TWILIO_API_KEY",hint:"The SID of a Standard or Restricted API key, never a Main key or the Auth Token."}],example:"text a reminder to a customer's phone number",verified:{on:"2026-10-25",how:"docs"},tags:["sms","voice","messaging"]},intercom:{mode:"api_key",label:"Intercom",description:"Customer messaging: contacts, companies, conversations, tickets and help center articles.",auth:{kind:"bearer",secret:"INTERCOM_API_TOKEN"},docs:"https://app.intercom.com/a/apps/_/developer-hub",api:"https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis",hosts:["api.intercom.io","api.eu.intercom.io","api.au.intercom.io"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["me"],["admins"],["teams"],["export"],["download"],["ip_allowlist"]],hint:"The Access Token of a private app in your workspace's Developer Hub, sent as a bearer token. Searching contacts, conversations or tickets is a POST, so an app that searches asks for write.",secrets:[{name:"INTERCOM_API_TOKEN",hint:"The Access Token on your private app's Configure > Authentication page in the Developer Hub."}],smoke:{method:"GET",path:"/me",expect:[200],free:!0,note:"Returns the admin behind the token; account-wide, so run it from a terminal."},rate:{perMinute:1e4,note:"Per workspace, shared by its private apps; 25,000 a minute across all apps; counted in 10-second windows."},example:"list the latest open conversations",verified:{on:"2026-10-25",how:"docs"},tags:["support","crm","messaging"]},crisp:{mode:"api_key",label:"Crisp",description:"Customer chat: conversations, messages, people and visitors of one Crisp workspace.",auth:{kind:"basic",secret:"CRISP_API_KEY",as:"password",user:{secret:"CRISP_API_IDENTIFIER"}},docs:"https://docs.crisp.chat/guides/rest-api/authentication/website-token/",api:"https://docs.crisp.chat/references/rest-api/v1/",hosts:["api.crisp.chat"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["operators"],["operator"],["teams"],["team"],["settings"],["verify"],["audit"],["plans"],["plugins"],["plugin"],["connect"]],hint:"A website token, which the workspace owner generates under Settings > Workspace Settings > Advanced configuration > API Token. The Gateway sends the identifier and key as HTTP Basic; the app sends X-Crisp-Tier: website on every call.",secrets:[{name:"CRISP_API_KEY",hint:"The token's key, shown once when the workspace owner generates it."},{name:"CRISP_API_IDENTIFIER",hint:"The token's identifier, shown beside the key."}],rate:{perDay:1e4,note:"The website token's daily quota."},example:"list the latest chat conversations on my website",verified:{on:"2026-10-25",how:"docs"},tags:["support","chat","messaging"]},linear:{mode:"api_key",label:"Linear",description:"Issue tracking over GraphQL: issues, projects, cycles, comments and teams.",auth:{kind:"header",secret:"LINEAR_API_KEY",header:"Authorization"},docs:"https://linear.app/settings/account/security",api:"https://linear.app/developers/graphql",hosts:["api.linear.app"],data:"account",access:["write"],readMethods:[],writeMethods:["POST"],accountWidePaths:[],hint:"A personal API key from Settings > Account > Security & access; the Gateway sends it as the Authorization header with no Bearer word. Every call is a POST to /graphql, queries included, so the app asks for write.",secrets:[{name:"LINEAR_API_KEY",hint:"A personal API key, restricted to the permissions and teams the app needs."}],rate:{note:"2,500 requests and 3,000,000 complexity points an hour per API key."},example:"create an issue for this bug in the Engineering team",verified:{on:"2026-10-25",how:"docs"},tags:["issues","project-management","graphql"]},github:{mode:"api_key",label:"GitHub",description:"Code hosting: repositories, issues, pull requests, Actions and releases through the REST API.",auth:{kind:"bearer",secret:"GITHUB_API_TOKEN"},docs:"https://github.com/settings/personal-access-tokens/new",api:"https://docs.github.com/en/rest",hosts:["api.github.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["user","email"],["user","emails"],["user","public_emails"],["user","gpg_keys"],["user","ssh_signing_keys"],["user","social_accounts"],["keys"],["hooks"],["secrets"],["members"],["memberships"],["invitations"],["failed_invitations"],["collaborators"],["outside_collaborators"],["blocks"],["installations"],["personal-access-tokens"],["personal-access-token-requests"],["credential-authorizations"],["audit-log"],["billing"]],hint:"A fine-grained personal access token from Settings > Developer settings, limited to one owner, the repositories the app needs and the least permissions; sent as a bearer token. GraphQL is a POST to /graphql, so it needs write.",secrets:[{name:"GITHUB_API_TOKEN",hint:"A fine-grained personal access token limited to the repositories and permissions the app needs."}],smoke:{method:"GET",path:"/user",expect:[200],free:!0,note:"Returns the token's owner; 401 means the token is wrong."},rate:{note:"5,000 requests an hour per token; at most 100 concurrent requests and 900 points a minute across REST endpoints."},example:"list the open pull requests in my repository",verified:{on:"2026-10-25",how:"docs"},tags:["code","git","issues"]},gitlab:{mode:"api_key",label:"GitLab",description:"Code hosting on GitLab.com: projects, issues, merge requests, pipelines and releases.",auth:{kind:"header",secret:"GITLAB_API_TOKEN",header:"PRIVATE-TOKEN"},docs:"https://gitlab.com/-/user_settings/personal_access_tokens",api:"https://docs.gitlab.com/api/rest/",hosts:["gitlab.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["user"],["personal_access_tokens"],["access_tokens"],["deploy_tokens"],["deploy_keys"],["project_deploy_keys"],["hooks"],["members"],["pending_members"],["billable_members"],["invitations"],["variables"],["audit_events"]],hint:"A personal, project or group access token from GitLab.com, sent in the PRIVATE-TOKEN header; read_api is enough to read. Paths start with /api/v4. A self-managed GitLab needs its own registered provider.",secrets:[{name:"GITLAB_API_TOKEN",hint:"A personal, project or group access token with read_api, or api when the app writes."}],smoke:{method:"GET",path:"/api/v4/personal_access_tokens/self",expect:[200],free:!0,note:"Describes a personal access token itself (401 when it is wrong or revoked); account-wide, so run it from a terminal."},rate:{perMinute:2e3,note:"Authenticated API traffic per user on GitLab.com."},example:"list the open merge requests in my project",verified:{on:"2026-10-25",how:"docs"},tags:["code","git","ci"]},vercel:{mode:"api_key",label:"Vercel",description:"Frontend hosting: projects, deployments, domains and logs through the Vercel REST API.",auth:{kind:"bearer",secret:"VERCEL_API_TOKEN"},docs:"https://vercel.com/account/tokens",api:"https://vercel.com/docs/rest-api",hosts:["api.vercel.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["user"],["teams"],["members"],["organizations"],["access-groups"],["billing"],["webhooks"],["drains"],["env"],["v3","events"],["v1","events"],["v1","integrations"],["installations"],["connect"],["kms"],["api-keys"],["ai-gateway"],["token"],["tokens"],["registrar"],["transfer-request"]],hint:"An access token from your account's Tokens page, sent as a bearer token; scope it to one team or one project. A team- or project-scoped token needs no teamId parameter.",secrets:[{name:"VERCEL_API_TOKEN",hint:"An access token scoped to one team or one project, never Full Account."}],smoke:{method:"GET",path:"/v10/projects",expect:[200],free:!0,note:"Lists the projects the token can reach."},rate:{note:"Limits are per action (deployments, domains, teams), listed on Vercel's limits page."},example:"list the latest deployments of my project",verified:{on:"2026-10-25",how:"docs"},tags:["hosting","deploy","frontend"]}};var on={cloudflare:{mode:"api_key",label:"Cloudflare",description:"Cloudflare's API: zones, DNS, Workers, R2, D1, KV and the rest of an account.",auth:{kind:"bearer",secret:"CLOUDFLARE_PROVIDER_API_TOKEN"},docs:"https://dash.cloudflare.com/profile/api-tokens",api:"https://developers.cloudflare.com/api/",hosts:["api.cloudflare.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["client","v4","user"],["client","v4","memberships"],["client","v4","organizations"],["client","v4","tenants"],["members"],["tokens"],["roles"],["iam"],["subscriptions"],["payment-methods"],["pay-invoice"],["receipts"],["invoices"],["client-secret"],["billing"],["logs","audit"],["audit_logs"],["alerting","v3","destinations","webhooks"],["ai","run"],["ai","v1"]],hint:"An API token from My Profile > API Tokens with only the permissions the app needs; the Gateway sends it as a bearer token. A token on the Gateway's own account can read and change the Gateway, so keep it narrow or use another account.",secrets:[{name:"CLOUDFLARE_PROVIDER_API_TOKEN",hint:"A user or account-owned API token scoped to the zones and permissions the app needs, never a Global API Key."}],smoke:{method:"GET",path:"/client/v4/user/tokens/verify",expect:[200],free:!0,note:"For a user token; account-owned tokens use /client/v4/accounts/<id>/tokens/verify. Account-wide, so run it from the person's terminal."},rate:{note:"1,200 requests per 5 minutes per user or account token; 200 a second per IP; GraphQL by query cost, at most 320 per 5 minutes."},example:"list the DNS records for my domain",verified:{on:"2026-10-25",how:"docs"},tags:["infrastructure","dns","hosting"]},posthog:{mode:"api_key",label:"PostHog",description:"Product analytics: insights, feature flags, persons, cohorts, experiments and HogQL queries.",auth:{kind:"bearer",secret:"POSTHOG_PERSONAL_API_KEY"},docs:"https://us.posthog.com/settings/user-api-keys",api:"https://posthog.com/docs/api",hosts:["us.posthog.com","eu.posthog.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["api","users"],["api","user"],["api","organizations"],["api","billing"],["api","revoke_leaked_key"],["project_secret_api_keys"],["billing"],["activity_log"],["advanced_activity_logs"],["hog_functions"],["batch_exports"],["integrations"]],hint:"A personal API key from Settings > Personal API keys, with only the scopes the app needs; the Gateway sends it as a bearer token to us.posthog.com or eu.posthog.com. HogQL queries are POSTs, so an app that runs them asks for write.",secrets:[{name:"POSTHOG_PERSONAL_API_KEY",hint:"A personal API key (phx_...) with only the scopes the app needs, from the region the project lives in; never the project token."}],smoke:{method:"GET",host:"us.posthog.com",path:"/api/users/@me/",expect:[200],free:!0,note:"Needs the user:read scope; use eu.posthog.com for an EU project. Account-wide, so run it from the person's terminal."},rate:{perMinute:480,note:"Create, read, update and delete endpoints 480 a minute and 4,800 an hour; analytics endpoints 240 a minute; the query endpoint 2,400 an hour."},example:"list the feature flags in my project and whether each is on",verified:{on:"2026-10-25",how:"docs"},tags:["analytics","product","feature-flags"]},mixpanel:{mode:"api_key",label:"Mixpanel",description:"Product analytics: saved reports, profiles, raw event export and event import.",auth:{kind:"basic",secret:"MIXPANEL_SERVICE_ACCOUNT_SECRET",as:"password",user:{secret:"MIXPANEL_SERVICE_ACCOUNT_USERNAME"}},docs:"https://mixpanel.com/settings/org#serviceaccounts",api:"https://docs.mixpanel.com/reference/overview",hosts:["mixpanel.com","eu.mixpanel.com","in.mixpanel.com","data.mixpanel.com","data-eu.mixpanel.com","data-in.mixpanel.com","api.mixpanel.com","api-eu.mixpanel.com","api-in.mixpanel.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["api","app","me"],["api","app","organizations"],["service-accounts"],["data-retrievals"],["data-deletions"],["nessie"]],hint:"A service account from Organization Settings > Service Accounts; the Gateway sends its username and secret as HTTP Basic. Most calls also need the project_id parameter, and an EU or India project uses its own hosts.",secrets:[{name:"MIXPANEL_SERVICE_ACCOUNT_USERNAME",hint:"The service account's username, shown when it is created in Organization Settings > Service Accounts."},{name:"MIXPANEL_SERVICE_ACCOUNT_SECRET",hint:"The service account's secret, shown once when it is created; give the account the narrowest role and only the projects the app needs."}],smoke:{method:"GET",host:"mixpanel.com",path:"/api/app/me",expect:[200],free:!0,note:"Lists the organizations and projects the service account reaches. Account-wide, so run it from the person's terminal."},rate:{note:"Per project: Query API 60 queries an hour, 5 at once; Raw Data Export 60 an hour, 3 a second, 100 at once; ingestion about 2 GB a minute."},example:"pull last week's numbers from my saved Insights report",verified:{on:"2026-10-25",how:"docs"},tags:["analytics","product"]},segment:{mode:"api_key",label:"Segment",description:"Sends identify, track, page, group and alias events to a Segment source.",auth:{kind:"basic",secret:"SEGMENT_WRITE_KEY",as:"username"},docs:"https://www.twilio.com/docs/segment/connections/find-writekey",api:"https://www.twilio.com/docs/segment/connections/sources/catalog/libraries/server/http-api",hosts:["api.segment.io","events.eu1.segmentapis.com"],data:"account",access:["write"],readMethods:[],writeMethods:["POST"],accountWidePaths:[],hint:"The write key of an HTTP API source, from the source's Settings > API Keys; the Gateway sends it as the Basic username with an empty password. It only sends events; an EU workspace uses events.eu1.segmentapis.com.",secrets:[{name:"SEGMENT_WRITE_KEY",hint:"The write key of an HTTP API source, from the source's Settings > API Keys."}],rate:{perSecond:1e3,note:"Recommended ceiling per workspace; 32 KB per call, 500 KB and 2,500 events per batch."},example:"record a Signed Up event for a new user",verified:{on:"2026-10-25",how:"docs"},tags:["analytics","events","cdp"]},supabase:{mode:"api_key",label:"Supabase",description:"A Supabase project's Postgres REST API and Storage, with its secret key.",auth:{kind:"header",secret:"SUPABASE_SECRET_KEY",header:"apikey"},docs:"https://supabase.com/dashboard/project/_/settings/api-keys",api:"https://supabase.com/docs/guides/api",hosts:[],hostSetting:"SUPABASE_HOST",data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["auth","v1","admin"],["pg"]],hint:"A secret key (sb_secret_...) from Settings > API Keys and the project's host; the Gateway sends the key in the apikey header. The key bypasses Row Level Security, and RPC calls are POSTs, so they need write.",secrets:[{name:"SUPABASE_SECRET_KEY",hint:"A secret key (sb_secret_...) from Settings > API Keys, made for this Gateway alone; it bypasses Row Level Security."},{name:"SUPABASE_HOST",hint:"The project's host, <project-ref>.supabase.co, from the project URL."}],smoke:{method:"GET",path:"/rest/v1/",expect:[200],free:!0,note:"The REST API's OpenAPI root, which only a secret key may read; sent to the host in SUPABASE_HOST."},example:"list the ten newest rows in my orders table",verified:{on:"2026-10-25",how:"docs"},tags:["database","postgres","storage"]},turso:{mode:"api_key",label:"Turso",description:"Turso's Platform API: databases, groups, locations and usage for one organization.",auth:{kind:"bearer",secret:"TURSO_API_TOKEN"},docs:"https://docs.turso.tech/api-reference/authentication",api:"https://docs.turso.tech/api-reference/introduction",hosts:["api.turso.tech"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PATCH","DELETE"],accountWidePaths:[["auth"],["api-tokens"],["members"],["invites"],["invoices"],["subscription"],["plans"],["audit-logs"],["v1","user"]],hint:"An organization-scoped Platform API token (turso auth api-tokens mint <name> --org <org>); the Gateway sends it as a bearer token to api.turso.tech. It manages databases and cannot query them: that is the turso-db entry.",secrets:[{name:"TURSO_API_TOKEN",hint:"An organization-scoped or group-scoped Platform API token from turso auth api-tokens mint <name> --org <org>; never an unrestricted one."}],smoke:{method:"GET",path:"/v1/auth/validate",expect:[200],free:!0,note:"Account-wide, so run it from the person's terminal."},example:"list the databases in my Turso organization",verified:{on:"2026-10-25",how:"docs"},tags:["database","sqlite"]},"turso-db":{mode:"api_key",label:"Turso database",description:"SQL over HTTP to one Turso database: queries, dumps and migration status.",auth:{kind:"bearer",secret:"TURSO_DB_AUTH_TOKEN"},docs:"https://docs.turso.tech/sdk/authorization/tokens",api:"https://docs.turso.tech/sdk/http/reference",hosts:[],hostSetting:"TURSO_DB_HOST",data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST"],accountWidePaths:[],hint:"A database token (turso db tokens create <db>) and the database's HTTP host; the Gateway sends the token as a bearer token. Every query is a POST to /v2/pipeline, so an app that queries asks for write; a --read-only token keeps it to reads.",secrets:[{name:"TURSO_DB_AUTH_TOKEN",hint:"A database token from turso db tokens create <db>, with --read-only or fine-grained permissions when the app only reads."},{name:"TURSO_DB_HOST",hint:"The database's HTTP host, <db>-<org>.turso.io, from turso db show <db> --http-url."}],example:"count the rows in my users table",verified:{on:"2026-10-25",how:"docs"},tags:["database","sqlite","sql"]},neon:{mode:"api_key",label:"Neon",description:"Neon's management API: Postgres projects, branches, databases, roles and endpoints.",auth:{kind:"bearer",secret:"NEON_API_KEY"},docs:"https://neon.com/docs/manage/api-keys",api:"https://neon.com/docs/reference/api",hosts:["console.neon.tech"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["api","v2","auth"],["api","v2","organizations"],["users","me"],["api_keys"],["members"],["invitations"],["permissions"],["transfer_requests"],["billing"],["consumption_history"],["connection_uri"],["reveal_password"],["reset_password"],["credentials"],["realtime","secret"],["rotate_secret"],["auth","keys"],["auth","webhooks"],["oauth_providers"],["email_server"],["email_provider"],["auth","plugins"]],hint:"A project-scoped or organization API key from Settings > API keys; the Gateway sends it as a bearer token to console.neon.tech. It manages projects and branches; the database itself takes Postgres credentials, not this key.",secrets:[{name:"NEON_API_KEY",hint:"A project-scoped or organization API key from Settings > API keys; a project-scoped key reaches one project only."}],smoke:{method:"GET",path:"/api/v2/auth",expect:[200],free:!0,note:"Says which credential and identity the key is. Account-wide, so run it from the person's terminal."},rate:{perMinute:700,note:"About 11 a second, with bursts of 40 a second per route."},example:"list my Neon projects and their branches",verified:{on:"2026-10-25",how:"docs"},tags:["database","postgres"]},pinecone:{mode:"api_key",label:"Pinecone",description:"Vector database: indexes, namespaces, vectors and documents, plus hosted embedding and rerank.",auth:{kind:"header",secret:"PINECONE_API_KEY",header:"Api-Key"},docs:"https://app.pinecone.io/organizations/-/projects/-/keys",api:"https://docs.pinecone.io/reference/api/introduction",hosts:["api.pinecone.io"],hostSetting:"PINECONE_HOST",data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PATCH","DELETE"],accountWidePaths:[["admin"],["api-keys"]],hint:"An API key from the project's API keys page and the host of the index the app uses; the Gateway sends the key in the Api-Key header to api.pinecone.io and that host. Query, search, embed and rerank are POSTs, so an app that uses them asks for write.",secrets:[{name:"PINECONE_API_KEY",hint:"An API key from the project's API keys page in the Pinecone console."},{name:"PINECONE_HOST",hint:"The host of the index the app uses, <index>-<id>.svc.<env>.pinecone.io, from describe_index or the console."}],smoke:{method:"GET",host:"api.pinecone.io",path:"/indexes",expect:[200],free:!0,note:"Lists the project's indexes; the app sends X-Pinecone-Api-Version itself."},example:"list my Pinecone indexes and their dimensions",verified:{on:"2026-10-25",how:"docs"},tags:["vector","database","search"]},mapbox:{mode:"api_key",label:"Mapbox",description:"Maps and location: geocoding, directions, styles, tilesets and datasets.",auth:{kind:"query",secret:"MAPBOX_ACCESS_TOKEN",param:"access_token"},docs:"https://console.mapbox.com/account/access-tokens/",api:"https://docs.mapbox.com/api/overview/",hosts:["api.mapbox.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","PATCH","DELETE"],accountWidePaths:[["tokens"]],hint:"An access token from Access tokens in the Mapbox console, with only the scopes the app needs; the Gateway adds it to every call as the access_token parameter.",secrets:[{name:"MAPBOX_ACCESS_TOKEN",hint:"An access token with only the scopes the app needs, from Access tokens in the Mapbox console."}],rate:{note:"Per token and per API: Geocoding 1,000 a minute, Directions 300, Static Images 1,250; the Tokens API 100 a minute per account."},example:"turn a street address into map coordinates",verified:{on:"2026-10-25",how:"docs"},tags:["maps","geocoding","location"]},openweather:{mode:"api_key",label:"OpenWeather",description:"Weather data: current conditions, forecasts, One Call, history and weather map tiles.",auth:{kind:"query",secret:"OPENWEATHER_API_KEY",param:"appid"},docs:"https://home.openweathermap.org/api_keys",api:"https://openweathermap.org/api",hosts:["api.openweathermap.org","pro.openweathermap.org","history.openweathermap.org","tile.openweathermap.org","maps.openweathermap.org"],data:"per-call",access:["read"],readMethods:["GET","HEAD"],accountWidePaths:[["data","3","stations"],["data","3","measurements"]],hint:"An API key from the API keys tab of your OpenWeather account; the Gateway adds it to every call as the appid parameter. Paid products (hourly forecast, history, Weather Maps 2.0) need a plan that includes them.",secrets:[{name:"OPENWEATHER_API_KEY",hint:"An API key from the API keys tab of the OpenWeather account; a new key can take up to two hours to activate."}],smoke:{method:"GET",host:"api.openweathermap.org",path:"/data/2.5/weather?lat=51.51&lon=-0.13",expect:[200],free:!0,note:"Counts one call against the plan's quota; free within it. A bad or not yet active key answers 401."},cost:{unit:"call",note:"One Call API 3.0 includes 1,000 calls a day free, then is paid per call."},rate:{perMinute:60,note:"The Free plan answers 429 past 60 calls a minute."},example:"get the current weather in Lisbon",verified:{on:"2026-10-25",how:"docs"},tags:["weather","forecast"]}};var an={anthropic:{mode:"ai",label:"Anthropic",description:"Claude models through the Messages API.",auth:{kind:"bearer",secret:"ANTHROPIC_API_KEY"},docs:"https://platform.claude.com/settings/keys",api:"https://platform.claude.com/docs/en/api/overview",origin:"https://api.anthropic.com",inferenceRoutes:["/v1/messages","/v1/messages/count_tokens","/v1/chat/completions"],unstoredRoutes:["/v1/chat/completions"],shape:"anthropic",chat:{path:"/v1/chat/completions",model:"claude-haiku-5-5"},aig:{slug:"anthropic"},hint:"An API key from the Claude Console's API keys page; the Gateway sends it as a bearer token. Apps send the anthropic-version header themselves.",secrets:[{name:"ANTHROPIC_API_KEY",hint:"A key scoped to one workspace; the Gateway strips any anthropic-workspace-id header an app sends, so the key alone decides the workspace."}],smoke:{method:"GET",path:"/v1/models",expect:[200],free:!0,note:"Send an anthropic-version header, as every call does."},rate:{note:"Requests and tokens per minute by usage tier, on the Console's Rate limits page; token counting is free, with its own per-minute limit."},example:"summarize this support thread in three bullet points",verified:{on:"2026-10-25",how:"docs"},tags:["ai","llm"]},gemini:{mode:"ai",label:"Google Gemini",description:"Google's Gemini models through their OpenAI-compatible endpoint: chat, embeddings, images.",auth:{kind:"bearer",secret:"GEMINI_API_KEY"},docs:"https://aistudio.google.com/apikey",api:"https://ai.google.dev/gemini-api/docs/openai",origin:"https://generativelanguage.googleapis.com",inferenceRoutes:["/v1beta/openai/chat/completions","/v1beta/openai/embeddings","/v1beta/openai/images/generations"],chat:{path:"/v1beta/openai/chat/completions",model:"gemini-3.1-flash-lite"},embeddings:{path:"/v1beta/openai/embeddings",model:"gemini-embedding-001"},hint:"An API key from Google AI Studio; the Gateway sends it as a bearer token. Apps call Gemini's OpenAI-shaped paths under /v1beta/openai.",secrets:[{name:"GEMINI_API_KEY",hint:"A Google AI Studio key restricted to the Gemini API only."}],smoke:{method:"GET",path:"/v1beta/openai/models",expect:[200],free:!0},rate:{note:"Per project, not per key: requests and tokens per minute and requests per day, by tier (Free, then Tiers 1 to 3)."},example:"describe what is in this product photo",verified:{on:"2026-10-25",how:"docs"},tags:["ai","llm","embeddings","images"]},mistral:{mode:"ai",label:"Mistral AI",description:"Mistral's models: chat, code completion, embeddings, moderation, OCR, speech.",auth:{kind:"bearer",secret:"MISTRAL_API_KEY"},docs:"https://console.mistral.ai",api:"https://docs.mistral.ai/api/",origin:"https://api.mistral.ai",inferenceRoutes:["/v1/chat/completions","/v1/fim/completions","/v1/embeddings","/v1/moderations","/v1/chat/moderations","/v1/classifications","/v1/chat/classifications","/v1/ocr","/v1/audio/transcriptions","/v1/audio/speech"],chat:{path:"/v1/chat/completions",model:"mistral-small-latest"},embeddings:{path:"/v1/embeddings",model:"mistral-embed"},aig:{slug:"mistral"},hint:"An API key from API Keys in the Mistral Studio console; the Gateway sends it as a bearer token. Free mode needs no card; usage and rate limits apply.",secrets:[{name:"MISTRAL_API_KEY",hint:"A key from API Keys in the Studio console, with an expiry date."}],smoke:{method:"GET",path:"/v1/models",expect:[200],free:!0},example:"extract the text from this scanned invoice",verified:{on:"2026-10-25",how:"docs"},tags:["ai","llm","ocr","embeddings"]},groq:{mode:"ai",label:"Groq",description:"Open models on Groq through OpenAI's API shape: chat, responses, transcription, speech.",auth:{kind:"bearer",secret:"GROQ_API_KEY"},docs:"https://console.groq.com/keys",api:"https://console.groq.com/docs/api-reference",origin:"https://api.groq.com",inferenceRoutes:["/openai/v1/chat/completions","/openai/v1/responses","/openai/v1/audio/transcriptions","/openai/v1/audio/translations","/openai/v1/audio/speech"],chat:{path:"/openai/v1/chat/completions",model:"openai/gpt-oss-20b"},aig:{slug:"groq",trim:"/openai/v1"},hint:"An API key from the Groq console; the Gateway sends it as a bearer token. Apps call the OpenAI-shaped paths under /openai/v1.",secrets:[{name:"GROQ_API_KEY",hint:"A key from the API Keys page of the Groq console."}],smoke:{method:"GET",path:"/openai/v1/models",expect:[200],free:!0},rate:{note:"Requests and tokens per minute and per day, per model and plan, for the whole organization; the console Limits page shows them."},example:"transcribe this voice memo",verified:{on:"2026-10-25",how:"docs"},tags:["ai","llm","speech"]},cohere:{mode:"ai",label:"Cohere",description:"Cohere's models: chat, embeddings, reranking, classification, transcription, document parsing.",auth:{kind:"bearer",secret:"COHERE_API_KEY"},docs:"https://dashboard.cohere.com/api-keys",api:"https://docs.cohere.com/reference/about",origin:"https://api.cohere.com",inferenceRoutes:["/v2/chat","/v2/embed","/v2/rerank","/v1/classify","/v2/audio/transcriptions","/v2/parse","/v1/tokenize","/v1/detokenize"],shape:"other",hint:"An API key from the Cohere dashboard; the Gateway sends it as a bearer token. Trial keys are free and limited; production keys are paid.",secrets:[{name:"COHERE_API_KEY",hint:"A production key; a trial key is limited to 1,000 calls a month."}],smoke:{method:"GET",path:"/v1/models",expect:[200],free:!0},rate:{note:"Production: 500 calls a minute for Command A chat and most endpoints, rerank 1,000. Trial: 20 chat calls a minute, 1,000 calls a month."},example:"rerank these search results for the query refund policy",verified:{on:"2026-10-25",how:"docs"},tags:["ai","llm","embeddings","rerank"]},voyage:{mode:"api_key",label:"Voyage AI",description:"Embeddings and rerankers for search and retrieval: text, code, multimodal, contextualized chunks.",auth:{kind:"bearer",secret:"VOYAGE_API_KEY"},docs:"https://dashboard.voyageai.com/organization/api-keys",api:"https://docs.voyageai.com/reference/embeddings-api",hosts:["api.voyageai.com"],data:"per-call",access:["read"],readMethods:["POST"],accountWidePaths:[["v1","files"],["v1","batches"]],hint:"A secret key from the Voyage dashboard; the Gateway sends it as a bearer token. Apps POST to /v1/embeddings, /v1/multimodalembeddings, /v1/contextualizedembeddings and /v1/rerank.",secrets:[{name:"VOYAGE_API_KEY",hint:"A secret key from API keys in the Voyage dashboard."}],smoke:{method:"GET",path:"/v1/batches",expect:[200],free:!0,note:"Lists the organization's batches, so the Gateway refuses it for apps; run it from the person's terminal."},cost:{unit:"token",note:"voyage-4 $0.06 per million tokens; the first 200 million tokens of the voyage-4 family are free per account."},rate:{perMinute:2e3,note:"2,000 requests a minute at tier 1, doubled at tier 2, tripled at tier 3; tokens per minute vary by model."},example:"embed these product descriptions for semantic search",verified:{on:"2026-10-25",how:"docs"},tags:["embeddings","rerank","search"]},perplexity:{mode:"api_key",label:"Perplexity",description:"Web-grounded answers from the Agent API, raw web search results, and embeddings.",auth:{kind:"bearer",secret:"PERPLEXITY_API_KEY"},docs:"https://console.perplexity.ai/project/keys",api:"https://docs.perplexity.ai/api-reference/agent-post",hosts:["api.perplexity.ai"],data:"per-call",access:["read"],readMethods:["GET","POST"],accountWidePaths:[["v1","batches"],["v1","files"],["v1","skills"],["v1","analytics"],["v2","analytics"],["generate_auth_token"],["revoke_auth_token"]],hint:"An API key from the Perplexity console; the Gateway sends it as a bearer token. Apps POST to /v1/agent for researched answers and /search for result lists, and GET /v1/agent/{id} to poll a background run.",secrets:[{name:"PERPLEXITY_API_KEY",hint:"An API key from the project's API keys page in the Perplexity console."}],smoke:{method:"GET",path:"/orchestrator/v1/models",expect:[200],free:!0},cost:{unit:"token",note:"Agent API per token plus tool fees (web_search $0.0025 a call); Search API $5 per 1,000 requests."},example:"research the latest pricing changes from our three main competitors",verified:{on:"2026-10-25",how:"docs"},tags:["search","ai","research"]},jina:{mode:"api_key",label:"Jina AI",description:"Reads web pages as Markdown, searches the web, and embeds and reranks text and images.",auth:{kind:"bearer",secret:"JINA_API_KEY"},docs:"https://jina.ai/api-dashboard/key-manager",api:"https://docs.jina.ai/",hosts:["api.jina.ai","r.jina.ai","s.jina.ai"],data:"per-call",access:["read"],readMethods:["GET","POST"],accountWidePaths:[["v1","batches"],["echo"]],hint:'An API key from the Jina API dashboard; the Gateway sends it as a bearer token. Reader is r.jina.ai (POST {"url": ...}), Search is s.jina.ai, and embeddings and rerank are on api.jina.ai.',secrets:[{name:"JINA_API_KEY",hint:"A key starting jina_, from Manage API Key in the Jina API dashboard."}],smoke:{method:"GET",host:"api.jina.ai",path:"/v1/batches",expect:[200],free:!0,note:"Lists the account's batch jobs, so the Gateway refuses it for apps; run it from the person's terminal."},cost:{unit:"token",note:"Billed in tokens against the account balance; GET /v1/models lists each model's price."},rate:{note:"Reader 500 requests a minute, Search 100, embeddings and rerank 500; premium keys get ten times more."},example:"read this article as Markdown and pull out the key claims",verified:{on:"2026-10-25",how:"docs"},tags:["scrape","search","embeddings","rerank"]},replicate:{mode:"api_key",label:"Replicate",description:"Runs open-source and official models by API: images, video, audio and language.",auth:{kind:"bearer",secret:"REPLICATE_API_TOKEN"},docs:"https://replicate.com/account/api-tokens",api:"https://replicate.com/docs/reference/http",hosts:["api.replicate.com"],data:"per-call",access:["read"],readMethods:["POST"],accountWidePaths:[["v1","account"],["v1","deployments"],["v1","files"],["v1","webhooks"],["trainings"]],hint:"An API token from Replicate's API tokens page; the Gateway sends it as a bearer token. Apps POST to /v1/models/{owner}/{name}/predictions or /v1/predictions with Prefer: wait (up to 60 seconds), or pass a webhook URL for longer runs.",secrets:[{name:"REPLICATE_API_TOKEN",hint:"An API token from the API tokens page of the Replicate account."}],smoke:{method:"GET",path:"/v1/account",expect:[200],free:!0,note:"Account-wide, so the Gateway refuses it for apps; run it from the person's terminal."},rate:{perMinute:600,note:"Creating predictions 600 a minute; every other endpoint 3,000 a minute."},example:"generate a product photo of a ceramic mug on a wooden table",verified:{on:"2026-10-25",how:"docs"},tags:["ai","images","video","audio"]},huggingface:{mode:"api_key",label:"Hugging Face Inference",description:"Open models from Hugging Face's inference providers through one router: chat, embeddings, images, speech.",auth:{kind:"bearer",secret:"HUGGINGFACE_API_TOKEN"},docs:"https://huggingface.co/settings/tokens/new?ownUserPermissions=inference.serverless.write&tokenType=fineGrained",api:"https://huggingface.co/docs/inference-providers/index",hosts:["router.huggingface.co"],data:"per-call",access:["read"],readMethods:["GET","POST"],accountWidePaths:[],hint:"A fine-grained access token from Hugging Face settings with the Inference Providers permission; the Gateway sends it as a bearer token. Apps POST OpenAI-style chat to /v1/chat/completions, or other tasks under /<provider>/, such as /hf-inference/models/<model>.",secrets:[{name:"HUGGINGFACE_API_TOKEN",hint:"A fine-grained token with only the Make calls to Inference Providers permission."}],cost:{unit:"call",note:"Pay as you go at each provider's own rate with no markup; PRO accounts get $2 of compute credits a month."},example:"embed these support articles for semantic search",verified:{on:"2026-10-25",how:"docs"},tags:["ai","llm","embeddings","images"]}};var cn={firecrawl:{mode:"api_key",label:"Firecrawl",description:"Scrapes, crawls, maps and searches the web, returning clean markdown or structured data.",auth:{kind:"bearer",secret:"FIRECRAWL_API_KEY"},docs:"https://www.firecrawl.dev/app/api-keys",api:"https://docs.firecrawl.dev/api-reference/introduction",hosts:["api.firecrawl.dev"],data:"per-call",access:["read","write"],readMethods:["GET","POST"],writeMethods:["DELETE"],accountWidePaths:[["team"],["crawl","active"],["monitor"],["agent"],["interact"],["support","ask"]],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.",secrets:[{name:"FIRECRAWL_API_KEY",hint:"An API key from Firecrawl's API keys page; it starts with fc-."}],smoke:{method:"GET",path:"/v2/team/credit-usage",expect:[200],free:!0,note:"Remaining credits; account-wide, so the Gateway refuses it for apps: run it from the person's terminal."},cost:{unit:"result",note:"Credits: 1 per page scraped or crawled, 1 per map call, 2 per 10 search results; JSON extraction and other options add more."},rate:{note:"Per team per minute, by plan: /scrape 10 on Free, 100 Hobby, 500 Standard, 5,000 Growth; /crawl 2, 20, 100, 1,000."},example:"scrape https://example.com/pricing into markdown",verified:{on:"2026-10-25",how:"docs"},tags:["scrape","crawl","search"]},exa:{mode:"api_key",label:"Exa",description:"Web search built for AI: search results, page contents, similar links and cited answers.",auth:{kind:"header",secret:"EXA_API_KEY",header:"x-api-key"},docs:"https://dashboard.exa.ai/api-keys",api:"https://exa.ai/docs/reference/search",hosts:["api.exa.ai"],data:"per-call",access:["read"],readMethods:["POST"],accountWidePaths:[["websets"],["monitors"],["agent"],["batches"]],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.",secrets:[{name:"EXA_API_KEY",hint:"An API key from the API keys page of the Exa dashboard."}],smoke:{method:"GET",path:"/websets/v0/teams/me",expect:[200],free:!0,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."},cost:{unit:"call",usd:.007,note:"Search $7 per 1k (auto and fast; lite $4), contents $1 per 1k pages, answer $5 per 1k; up to 10 results included."},rate:{perSecond:10,note:"Per team: /search and /answer 10 QPS, deep search 5, /contents 100."},example:"find recent articles about solid-state batteries",verified:{on:"2026-10-25",how:"docs"},tags:["search"]},tavily:{mode:"api_key",label:"Tavily",description:"Web search, page extraction, crawling and site maps for AI agents, plus research reports.",auth:{kind:"bearer",secret:"TAVILY_API_KEY"},docs:"https://app.tavily.com",api:"https://docs.tavily.com/documentation/api-reference/endpoint/search",hosts:["api.tavily.com"],data:"per-call",access:["read"],readMethods:["GET","POST"],accountWidePaths:[["usage"],["logs"],["org-usage"]],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.",secrets:[{name:"TAVILY_API_KEY",hint:"An API key from the Tavily dashboard; it starts with tvly-."}],smoke:{method:"GET",path:"/usage",expect:[200],free:!0,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)."},cost:{unit:"call",usd:.008,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."},rate:{perMinute:100,note:"Development keys 100 per minute, production keys 1,000; crawl 100 and research 20 per minute for both."},example:"search the web for this week's news on EU AI rules",verified:{on:"2026-10-25",how:"docs"},tags:["search","scrape"]},serper:{mode:"api_key",label:"Serper",description:"Google search results as JSON: web, news, images, places, shopping, scholar and patents.",auth:{kind:"header",secret:"SERPER_API_KEY",header:"X-API-KEY"},docs:"https://serper.dev/api-keys",api:"https://serper.dev/playground",hosts:["google.serper.dev","scrape.serper.dev"],data:"per-call",access:["read"],readMethods:["POST"],accountWidePaths:[],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, \u2026) with a JSON body such as {"q": "\u2026"}.',secrets:[{name:"SERPER_API_KEY",hint:"The API key on serper.dev's API keys page."}],cost:{unit:"call",usd:.001,note:"Prepaid credits, one per successful query: $1.00 per 1k on the 50k pack, down to $0.30 per 1k on the largest."},rate:{perSecond:50,note:"Starter credits 50 queries per second; Standard 100, Scale 200, Ultimate 300."},example:"get the top Google results for best project management software",verified:!1,tags:["search","serp"]},"brave-search":{mode:"api_key",label:"Brave Search",description:"Brave's independent web index: web, news, images, videos, places, LLM context and answers.",auth:{kind:"header",secret:"BRAVE_SEARCH_API_KEY",header:"X-Subscription-Token"},docs:"https://api-dashboard.search.brave.com/app/keys",api:"https://api-dashboard.search.brave.com/documentation",hosts:["api.search.brave.com"],data:"per-call",access:["read"],readMethods:["GET","POST"],accountWidePaths:[],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.",secrets:[{name:"BRAVE_SEARCH_API_KEY",hint:"A key from the API Keys section of the Brave Search API dashboard, made after activating a plan."}],cost:{unit:"call",usd:.005,note:"Search $5 per 1k requests; Answers $4 per 1k plus $5 per million tokens; $5 free credit a month; only successful calls count."},rate:{perSecond:50,note:"Search plan 50 queries per second; Answers 2 per second."},example:"search the web for the latest Cloudflare Workers release notes",verified:{on:"2026-10-25",how:"docs"},tags:["search"]},apify:{mode:"api_key",label:"Apify",description:"Runs Apify Actors (ready-made scrapers and automations) and reads their datasets and stores.",auth:{kind:"bearer",secret:"APIFY_API_TOKEN"},docs:"https://console.apify.com/settings/integrations",api:"https://docs.apify.com/api/v2",hosts:["api.apify.com"],data:"account",access:["read","write"],readMethods:["GET","HEAD"],writeMethods:["POST","PUT","DELETE"],accountWidePaths:[["users"],["webhooks"],["webhook-dispatches"],["env-vars"]],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.",secrets:[{name:"APIFY_API_TOKEN",hint:"The API token under Settings > API & Integrations in Apify Console."}],smoke:{method:"GET",path:"/v2/users/me",expect:[200],free:!0,note:"The docs' verify call; account-wide, so the Gateway refuses it for apps: run it from the person's terminal."},rate:{perSecond:60,note:"60 requests per second per resource (one Actor, run, dataset or store); 250,000 requests per minute per user overall."},example:"run the Google Maps scraper Actor for coffee shops in Austin and list the results",verified:{on:"2026-10-25",how:"docs"},tags:["scrape","automation"]},deepgram:{mode:"api_key",label:"Deepgram",description:"Speech to text, text to speech and text analysis.",auth:{kind:"bearer",secret:"DEEPGRAM_API_KEY",scheme:"Token"},docs:"https://console.deepgram.com/",api:"https://developers.deepgram.com/reference/deepgram-api-overview",hosts:["api.deepgram.com","api.eu.deepgram.com","api.au.deepgram.com","api.in.deepgram.com"],data:"per-call",access:["read"],readMethods:["GET","POST"],accountWidePaths:[["projects"],["auth","grant"]],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.",secrets:[{name:"DEEPGRAM_API_KEY",hint:"A project API key created in the Deepgram Console."}],smoke:{method:"GET",path:"/v1/models",expect:[200],free:!0,note:"Lists the public models; it needs the key and processes no audio."},cost:{unit:"call",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."},rate:{note:"Concurrency per project on pay as you go: 50 pre-recorded transcriptions, 15 text-to-speech requests."},example:"transcribe this podcast episode and label the speakers",verified:{on:"2026-10-25",how:"docs"},tags:["speech","transcription"]},elevenlabs:{mode:"api_key",label:"ElevenLabs",description:"Text to speech, speech to text, sound effects, music and voice changing.",auth:{kind:"header",secret:"ELEVENLABS_API_KEY",header:"xi-api-key"},docs:"https://elevenlabs.io/app/settings/api-keys",api:"https://elevenlabs.io/docs/api-reference/introduction",hosts:["api.elevenlabs.io"],data:"per-call",access:["read"],readMethods:["GET","POST"],accountWidePaths:[["v1","user"],["v1","usage"],["v1","workspace"],["v1","workspaces"],["v1","service-accounts"],["v1","history"],["v1","single-use-token"],["v1","convai"],["v1","dubbing"],["v1","studio"],["v1","pronunciation-dictionaries"],["v1","voices","add"],["v1","voices","pvc"],["v1","voices","collections"],["edit"],["replicate-to-isolated-environment"],["v1","text-to-voice"],["v1","audio-native"],["v1","productions"],["v1","speech-engine"],["v1","music","finetunes"],["v1","flows"],["v1","assets"],["v1","audio-isolation","history"]],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.",secrets:[{name:"ELEVENLABS_API_KEY",hint:"An API key from ElevenLabs' API keys page; it can be scoped to the endpoints the app uses and given a credit cap."}],smoke:{method:"GET",path:"/v1/models",expect:[200],free:!0,note:"The first request in ElevenLabs' authentication docs; it generates nothing."},example:"read this paragraph aloud in a calm narrator voice",verified:{on:"2026-10-25",how:"docs"},tags:["speech","audio"]},assemblyai:{mode:"api_key",label:"AssemblyAI",description:"Transcribes recorded audio and video, with speaker labels, redaction and subtitles.",auth:{kind:"header",secret:"ASSEMBLYAI_API_KEY",header:"Authorization"},docs:"https://www.assemblyai.com/dashboard/home",api:"https://www.assemblyai.com/docs",hosts:["api.assemblyai.com","api.eu.assemblyai.com"],data:"account",access:["read","write"],readMethods:["GET","POST"],writeMethods:["DELETE"],accountWidePaths:[],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.",secrets:[{name:"ASSEMBLYAI_API_KEY",hint:"The API key on your AssemblyAI dashboard."}],smoke:{method:"GET",path:"/v2/transcript?limit=1",expect:[200],free:!0,note:"Lists the account's latest transcript; it transcribes nothing."},cost:{unit:"call",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."},rate:{perMinute:4e3,note:"20,000 requests per 5 minutes per account; 5 transcriptions in parallel on free accounts, 200 or more on paid."},example:"transcribe this sales call recording with speaker labels",verified:{on:"2026-10-25",how:"docs"},tags:["speech","transcription"]},newsapi:{mode:"api_key",label:"NewsAPI",description:"Searches news articles and live headlines from over 150,000 sources.",auth:{kind:"header",secret:"NEWSAPI_API_KEY",header:"X-Api-Key"},docs:"https://newsapi.org/register",api:"https://newsapi.org/docs",hosts:["newsapi.org"],data:"per-call",access:["read"],readMethods:["GET"],accountWidePaths:[],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.",secrets:[{name:"NEWSAPI_API_KEY",hint:"The API key NewsAPI shows after you register."}],cost:{unit:"call",usd:.0018,note:"Developer plan free (100 requests a day, development only); Business $449 a month for 250,000 requests, then $0.0018 each."},rate:{perDay:100,note:"Developer plan; Business includes 250,000 requests a month, Advanced 2,000,000."},example:"find today's top business headlines in the US",verified:{on:"2026-10-25",how:"docs"},tags:["news"]}};var dn={...nn,...rn,...on,...an,...cn};var N={openai:{mode:"ai",label:"OpenAI",description:"OpenAI's models: responses, chat, embeddings, audio, images.",auth:{kind:"bearer",secret:"OPENAI_API_KEY"},docs:"https://platform.openai.com/api-keys",api:"https://platform.openai.com/docs/api-reference",setup:"setup/openai.md",origin:"https://api.openai.com",inferenceRoutes:["/v1/responses","/v1/chat/completions","/v1/embeddings","/v1/audio/speech","/v1/audio/transcriptions","/v1/audio/translations","/v1/images/generations","/v1/images/edits","/v1/images/variations"],unstoredRoutes:["/v1/responses","/v1/chat/completions"],extraRoutes:!0,chat:{path:"/v1/chat/completions",model:"gpt-6-luna"},embeddings:{path:"/v1/embeddings",model:"text-embedding-3-small"},aig:{slug:"openai",trim:"/v1"},hint:"A secret key from the API keys page; the Gateway puts it on every call as a bearer token.",verified:{on:"2026-10-25",how:"live"}},openrouter:{mode:"ai",label:"OpenRouter",description:"One key for many models, through OpenAI's API shape.",auth:{kind:"bearer",secret:"OPENROUTER_API_KEY"},docs:"https://openrouter.ai/settings/keys",api:"https://openrouter.ai/docs",setup:"setup/openrouter.md",origin:"https://openrouter.ai",inferenceRoutes:["/api/v1/chat/completions","/api/v1/completions","/api/v1/responses","/api/v1/embeddings"],chat:{path:"/api/v1/chat/completions",model:"anthropic/claude-haiku-5.5"},embeddings:{path:"/api/v1/embeddings",model:"openai/text-embedding-3-small"},aig:{slug:"openrouter",trim:"/api"},hint:"An API key from OpenRouter's keys page; the Gateway puts it on every call as a bearer token.",cost:{unit:"token",responseField:"usage.cost",note:"The answer's usage.cost is the call's price in USD, per model."},verified:{on:"2026-10-25",how:"live"}},"workers-ai":{mode:"ai",label:"Workers AI",description:"Cloudflare's models, in the Gateway's own account.",auth:{kind:"bearer",secret:"WORKERS_AI_API_TOKEN"},docs:"https://dash.cloudflare.com/profile/api-tokens",api:"https://developers.cloudflare.com/workers-ai/",setup:"setup/workers-ai.md",origin:"https://api.cloudflare.com",alsoNeeds:["CLOUDFLARE_ACCOUNT_ID"],basePath:"/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai",inferenceRoutes:["/v1/chat/completions","/v1/embeddings","/v1/responses"],normalize:"workers-ai",chat:{path:"/v1/chat/completions",model:"@cf/meta/llama-4-scout-17b-16e-instruct"},embeddings:{path:"/v1/embeddings",model:"@cf/baai/bge-m3"},aig:{slug:"workers-ai",header:!0},hint:"A Cloudflare API token with Workers AI Read (the Workers AI page's prefilled token); the account is the Gateway's own.",verified:{on:"2026-10-25",how:"live"}},"ai-gateway":{mode:"ai",kind:"proxy",label:"Cloudflare AI Gateway",description:"Cloudflare's proxy in front of the other AI providers: logs, caching, rate limits and spend, with each provider's own key.",auth:{kind:"header",header:"cf-aig-authorization",prefix:"Bearer ",secret:"AI_GATEWAY_API_KEY"},authOptional:!0,docs:"https://dash.cloudflare.com/?to=/:account/ai/ai-gateway",api:"https://developers.cloudflare.com/ai-gateway/",setup:"setup/ai-gateway.md",origin:"https://gateway.ai.cloudflare.com",alsoNeeds:["CLOUDFLARE_ACCOUNT_ID","AI_GATEWAY_ID"],basePath:"/v1/{CLOUDFLARE_ACCOUNT_ID}/{AI_GATEWAY_ID}",inferenceRoutes:[],hint:"The gateway's id from the AI Gateway page (everyapp ai gateway on makes one named everyapp); AI_GATEWAY_API_KEY only for an authenticated gateway, sent as cf-aig-authorization.",secrets:[{name:"AI_GATEWAY_ID",hint:"The AI Gateway's id (its name in the dashboard), in the Gateway's own Cloudflare account."},{name:"AI_GATEWAY_API_KEY",hint:"An AI Gateway token with Run permission, only when the gateway is authenticated; leave unset for an open gateway."}],verified:{on:"2026-10-25",how:"docs"}},dataforseo:{mode:"api_key",label:"DataForSEO",description:"SEO data: keyword metrics, live search results, domain rankings, backlinks.",auth:{kind:"basic",secret:"DATAFORSEO_API_KEY",as:"pair"},docs:"https://app.dataforseo.com/api-access",api:"https://docs.dataforseo.com/v3/",setup:"setup/dataforseo.md",hosts:["api.dataforseo.com","sandbox.dataforseo.com"],access:["read"],readMethods:["GET","POST"],accountWidePaths:[["tasks_ready"],["tasks_fixed"],["id_list"],["errors"],["appendix","user_data"],["appendix","webhook_resend"]],hint:"The API login and password from API Access, as login:password (or that pair base64-encoded); the Gateway sends them as HTTP Basic.",secrets:[{name:"DATAFORSEO_API_KEY",hint:"login:password, or its base64; never the dashboard sign-in password."}],cost:{unit:"call",responseField:"cost",note:"A Google SERP $0.002 per 10 results; a Labs task $0.012 plus $0.00012 per item."},smoke:{method:"GET",path:"/v3/appendix/user_data",expect:[200],free:!0,note:"Account-wide, so the Gateway refuses it for apps; run it from the person's terminal."},example:"find keyword ideas for a page about running shoes",verified:{on:"2026-10-25",how:"live"}},context:{mode:"api_key",label:"Context.dev",description:"Scrapes and renders web pages, JavaScript included.",auth:{kind:"bearer",secret:"CONTEXT_API_KEY"},docs:"https://context.dev/",setup:"setup/context.md",hosts:["api.context.dev"],access:["read"],readMethods:["GET","POST"],accountWidePaths:[],hint:"An API key from the Context.dev dashboard; the Gateway puts it on every call as a bearer token.",verified:{on:"2026-10-25",how:"live"}},email:{mode:"service",label:"Email",access:["write"],routes:{send:["POST"]},settings:["EMAIL_FROM","EMAIL_FROM_NAME"],optionalSettings:["EMAIL_REST_API_TOKEN","CLOUDFLARE_ACCOUNT_ID","RESEND_API_KEY","EMAIL_PROVIDER"],setup:"setup/email.md"},members:{mode:"service",label:"Members",access:["read"],routes:{list:["GET"]},settings:[],optionalSettings:[]},linkedin:{mode:"oauth_client",label:"LinkedIn",secrets:{clientId:"LINKEDIN_CLIENT_ID",clientSecret:"LINKEDIN_CLIENT_SECRET"},token:[{host:"www.linkedin.com",path:"/oauth/v2/accessToken",methods:["POST"],inject:"form"}],access:["write"],console:"https://www.linkedin.com/developers/apps",authorize:{url:"https://www.linkedin.com/oauth/v2/authorization",scopes:["openid","profile","w_member_social","r_basicprofile","rw_organization_admin","w_organization_social","r_organization_social"]},api:["api.linkedin.com"],redirectPaths:["/integrations/social/linkedin","/integrations/social/linkedin-page"]},facebook:{mode:"oauth_client",label:"Facebook",secrets:{clientId:"FACEBOOK_APP_ID",clientSecret:"FACEBOOK_APP_SECRET"},token:[{host:"graph.facebook.com",path:/^\/v\d+\.\d+\/oauth\/access_token$/,methods:["GET","POST"],inject:"query"}],access:["write"],console:"https://developers.facebook.com/apps",authorize:{url:"https://www.facebook.com/v25.0/dialog/oauth",scopes:["pages_show_list","business_management","pages_manage_posts","pages_manage_engagement","pages_read_engagement","read_insights","instagram_basic","instagram_content_publish","instagram_manage_comments","instagram_manage_insights"]},api:["graph.facebook.com","graph.instagram.com"],redirectPaths:["/integrations/social/facebook","/integrations/social/instagram"]},instagram:{mode:"oauth_client",label:"Instagram",secrets:{clientId:"INSTAGRAM_APP_ID",clientSecret:"INSTAGRAM_APP_SECRET"},token:[{host:"api.instagram.com",path:"/oauth/access_token",methods:["POST"],inject:"form"},{host:"graph.instagram.com",path:"/access_token",methods:["GET"],inject:"query"}],access:["write"],console:"https://developers.facebook.com/apps",authorize:{url:"https://www.instagram.com/oauth/authorize",scopes:["instagram_business_basic","instagram_business_content_publish","instagram_business_manage_comments","instagram_business_manage_insights"]},api:["graph.instagram.com"],redirectPaths:["/integrations/social/instagram-standalone"]},threads:{mode:"oauth_client",label:"Threads",secrets:{clientId:"THREADS_APP_ID",clientSecret:"THREADS_APP_SECRET"},token:[{host:"graph.threads.net",path:"/oauth/access_token",methods:["GET","POST"],inject:"query"},{host:"graph.threads.net",path:"/access_token",methods:["GET"],inject:"query"}],access:["write"],console:"https://developers.facebook.com/apps",authorize:{url:"https://threads.net/oauth/authorize",scopes:["threads_basic","threads_content_publish","threads_manage_replies","threads_manage_insights"]},api:["graph.threads.net"],redirectPaths:["/integrations/social/threads"]},youtube:{mode:"oauth_client",label:"YouTube",secrets:{clientId:"YOUTUBE_CLIENT_ID",clientSecret:"YOUTUBE_CLIENT_SECRET"},token:[{host:"oauth2.googleapis.com",path:"/token",methods:["POST"],inject:"form"}],access:["write"],console:"https://console.cloud.google.com/apis/credentials",setup:"setup/google.md",authorize:{url:"https://accounts.google.com/o/oauth2/v2/auth",scopes:["https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/youtube","https://www.googleapis.com/auth/youtube.force-ssl","https://www.googleapis.com/auth/youtube.readonly","https://www.googleapis.com/auth/youtube.upload","https://www.googleapis.com/auth/youtubepartner","https://www.googleapis.com/auth/yt-analytics.readonly","https://www.googleapis.com/auth/business.manage"]},api:["www.googleapis.com","youtubeanalytics.googleapis.com","mybusinessaccountmanagement.googleapis.com","mybusinessbusinessinformation.googleapis.com","mybusiness.googleapis.com","businessprofileperformance.googleapis.com"],redirectPaths:["/integrations/social/youtube","/integrations/social/gmb"]},tiktok:{mode:"oauth_client",label:"TikTok",secrets:{clientId:"TIKTOK_CLIENT_ID",clientSecret:"TIKTOK_CLIENT_SECRET"},token:[{host:"open.tiktokapis.com",path:"/v2/oauth/token/",methods:["POST"],inject:"form",params:{clientId:"client_key"}}],access:["write"],console:"https://developers.tiktok.com/apps",authorize:{url:"https://www.tiktok.com/v2/auth/authorize/",scopes:["video.list","user.info.basic","video.publish","video.upload","user.info.profile","user.info.stats"]},api:["open.tiktokapis.com"],redirectPaths:["/integrations/social/tiktok"]},"tiktok-business":{mode:"oauth_client",label:"TikTok Business",secrets:{clientId:"TIKTOK_BUSINESS_CLIENT_ID",clientSecret:"TIKTOK_BUSINESS_CLIENT_SECRET"},token:[{host:"business-api.tiktok.com",path:"/open_api/v1.3/tt_user/oauth2/token/",methods:["POST"],inject:"json"},{host:"business-api.tiktok.com",path:"/open_api/v1.3/tt_user/oauth2/refresh_token/",methods:["POST"],inject:"json"}],access:["write"],console:"https://business-api.tiktok.com/portal/apps",authorize:{url:"https://www.tiktok.com/v2/auth/authorize/",scopes:["user.info.basic","user.info.username","user.info.stats","video.list","video.upload","video.publish"]},api:["business-api.tiktok.com"],redirectPaths:["/integrations/social/tiktok-business/"]},reddit:{mode:"oauth_client",label:"Reddit",secrets:{clientId:"REDDIT_CLIENT_ID",clientSecret:"REDDIT_CLIENT_SECRET"},token:[{host:"www.reddit.com",path:"/api/v1/access_token",methods:["POST"],inject:"basic"}],access:["write"],console:"https://www.reddit.com/prefs/apps",authorize:{url:"https://www.reddit.com/api/v1/authorize",scopes:["read","identity","submit","flair"]},api:["oauth.reddit.com"],redirectPaths:["/integrations/social/reddit"]},pinterest:{mode:"oauth_client",label:"Pinterest",secrets:{clientId:"PINTEREST_CLIENT_ID",clientSecret:"PINTEREST_CLIENT_SECRET"},token:[{host:"api.pinterest.com",path:"/v5/oauth/token",methods:["POST"],inject:"basic"}],access:["write"],console:"https://developers.pinterest.com/apps/",authorize:{url:"https://www.pinterest.com/oauth/",scopes:["boards:read","boards:write","pins:read","pins:write","user_accounts:read"]},api:["api.pinterest.com"],redirectPaths:["/integrations/social/pinterest"]},discord:{mode:"oauth_client",label:"Discord",secrets:{clientId:"DISCORD_CLIENT_ID",clientSecret:"DISCORD_CLIENT_SECRET"},token:[{host:"discord.com",path:"/api/oauth2/token",methods:["POST"],inject:"basic"}],access:["write"],console:"https://discord.com/developers/applications",authorize:{url:"https://discord.com/oauth2/authorize",scopes:["bot","identify","guilds"]},api:["discord.com"],redirectPaths:["/integrations/social/discord"],flow:{tokenUrl:"https://discord.com/api/oauth2/token",revokeUrl:"https://discord.com/api/oauth2/token/revoke",pkce:!0,scopeDialect:"space",identity:{url:"https://discord.com/api/users/@me",label:"username",id:"id"}}},slack:{mode:"oauth_client",label:"Slack",secrets:{clientId:"SLACK_CLIENT_ID",clientSecret:"SLACK_CLIENT_SECRET"},token:[{host:"slack.com",path:"/api/oauth.v2.access",methods:["POST"],inject:"form"}],access:["write"],console:"https://api.slack.com/apps",setup:"setup/slack.md",authorize:{url:"https://slack.com/oauth/v2/authorize",scopes:["channels:read","groups:read","users:read","users:read.email","chat:write","chat:write.public","chat:write.customize","channels:join","channels:manage","groups:write","channels:write.invites","groups:write.invites","im:write","files:write","channels:write"]},scopePolicy:{dialect:"slack",grantTypes:[null,"refresh_token"],requestScope:"keep",alwaysRequested:[],tolerated:[],deniedSegments:[],sets:{"channels.read":{label:"Channels (read-only)",access:"read",scopes:["channels:read","groups:read"],routes:[{host:"slack.com",paths:["/api/conversations.list","/api/conversations.info","/api/conversations.members","/api/users.conversations"],posts:[/^\/api\/conversations\.(list|info|members)$/,/^\/api\/users\.conversations$/]}]},"users.read":{label:"Members (read-only)",access:"read",scopes:["users:read"],routes:[{host:"slack.com",paths:["/api/users.list","/api/users.info","/api/users.getPresence","/api/bots.info"],posts:[/^\/api\/users\.(list|info|getPresence)$/,/^\/api\/bots\.info$/]}]},"users.email":{label:"Members' email addresses (read-only)",access:"read",scopes:["users:read.email"],routes:[{host:"slack.com",paths:["/api/users.lookupByEmail"],posts:[/^\/api\/users\.lookupByEmail$/]}]},"messages.write":{label:"Messages (post as the app)",access:"write",scopes:["chat:write","chat:write.public","chat:write.customize"],routes:[{host:"slack.com",paths:["/api/chat.scheduledMessages.list"],posts:[/^\/api\/chat\.(postMessage|postEphemeral|update|delete|scheduleMessage|deleteScheduledMessage|scheduledMessages\.list)$/]}]},"channels.join":{label:"Channels (join public ones)",access:"write",scopes:["channels:join"],routes:[{host:"slack.com",paths:[],posts:[/^\/api\/conversations\.join$/]}]},"channels.manage":{label:"Channels (create, manage and invite to; open DMs)",access:"write",scopes:["channels:manage","groups:write","channels:write.invites","groups:write.invites","im:write"],routes:[{host:"slack.com",paths:[],posts:[/^\/api\/conversations\.(create|rename|archive|unarchive|invite|open|kick|leave|setTopic|setPurpose|mark)$/]}]},"files.write":{label:"Files (upload)",access:"write",scopes:["files:write"],routes:[{host:"slack.com",paths:[],posts:[/^\/api\/files\.(getUploadURLExternal|completeUploadExternal)$/]}]},"user-channels.manage":{label:"Channels (as the installing person: read, manage, invite to)",access:"write",scopes:[],userScopes:["channels:read","channels:write","groups:read","groups:write"],routes:[{host:"slack.com",paths:["/api/conversations.list","/api/conversations.info","/api/conversations.members","/api/users.conversations"],posts:[/^\/api\/conversations\.(list|info|members|create|rename|archive|unarchive|invite|kick|leave|setTopic|setPurpose|mark)$/,/^\/api\/users\.conversations$/]}]}}},api:["slack.com"],redirectPaths:["/integrations/social/slack","/integrations/slack/callback"],flow:{tokenUrl:"https://slack.com/api/oauth.v2.access",revokeUrl:"https://slack.com/api/auth.revoke",pkce:!1,scopeDialect:"slack",identity:{url:"https://slack.com/api/auth.test",label:"team",id:"user_id"}}},mastodon:{mode:"oauth_client",label:"Mastodon",secrets:{clientId:"MASTODON_CLIENT_ID",clientSecret:"MASTODON_CLIENT_SECRET"},token:[{path:"/oauth/token",methods:["POST"],inject:"form"}],hostSetting:"MASTODON_URL",defaultOrigin:"https://mastodon.social",access:["write"],console:"/settings/applications",authorize:{url:"/oauth/authorize",scopes:["write:statuses","profile","write:media"]},api:[],redirectPaths:["/integrations/social/mastodon"]},kick:{mode:"oauth_client",label:"Kick",secrets:{clientId:"KICK_CLIENT_ID",clientSecret:"KICK_CLIENT_SECRET"},token:[{host:"id.kick.com",path:"/oauth/token",methods:["POST"],inject:"form"}],access:["write"],console:"https://kick.com/settings/developer",authorize:{url:"https://id.kick.com/oauth/authorize",scopes:["chat:write","user:read","channel:read"]},api:["api.kick.com"],redirectPaths:["/integrations/social/kick"]},twitch:{mode:"oauth_client",label:"Twitch",secrets:{clientId:"TWITCH_CLIENT_ID",clientSecret:"TWITCH_CLIENT_SECRET"},token:[{host:"id.twitch.tv",path:"/oauth2/token",methods:["POST"],inject:"form"}],access:["write"],console:"https://dev.twitch.tv/console/apps",authorize:{url:"https://id.twitch.tv/oauth2/authorize",scopes:["user:write:chat","user:read:chat","moderator:manage:announcements"]},api:["api.twitch.tv"],redirectPaths:["/integrations/social/twitch"]},tumblr:{mode:"oauth_client",label:"Tumblr",secrets:{clientId:"TUMBLR_CLIENT_ID",clientSecret:"TUMBLR_CLIENT_SECRET"},token:[{host:"api.tumblr.com",path:"/v2/oauth2/token",methods:["POST"],inject:"form"}],access:["write"],console:"https://www.tumblr.com/oauth/apps",authorize:{url:"https://www.tumblr.com/oauth2/authorize",scopes:["write","offline_access"]},api:["api.tumblr.com"],redirectPaths:["/integrations/social/tumblr"]},dribbble:{mode:"oauth_client",label:"Dribbble",secrets:{clientId:"DRIBBBLE_CLIENT_ID",clientSecret:"DRIBBBLE_CLIENT_SECRET"},token:[{host:"dribbble.com",path:"/oauth/token",methods:["POST"],inject:"query"}],access:["write"],console:"https://dribbble.com/account/applications",authorize:{url:"https://dribbble.com/oauth/authorize",scopes:["public","upload"]},api:["api.dribbble.com"],redirectPaths:["/integrations/social/dribbble"]},"google-workspace":{mode:"oauth_client",label:"Google (Gmail, Calendar, Search Console and Analytics)",secrets:{clientId:"GOOGLE_WORKSPACE_CLIENT_ID",clientSecret:"GOOGLE_WORKSPACE_CLIENT_SECRET"},token:[{host:"oauth2.googleapis.com",path:"/token",methods:["POST"],inject:"form"}],access:["write"],console:"https://console.cloud.google.com/apis/credentials",setup:"setup/google.md",authorize:{url:"https://accounts.google.com/o/oauth2/v2/auth",scopes:["openid","email","profile","https://www.googleapis.com/auth/gmail.readonly","https://www.googleapis.com/auth/calendar.readonly","https://www.googleapis.com/auth/webmasters.readonly","https://www.googleapis.com/auth/analytics.readonly"]},scopePolicy:{dialect:"google",grantTypes:["authorization_code","refresh_token"],requestScope:"drop",alwaysRequested:[],tolerated:["openid","email","profile","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],deniedSegments:["batch","measurementProtocolSecrets"],sets:{identity:{label:"Google account (who you are)",access:"read",scopes:["openid","email","profile"],routes:[{host:"openidconnect.googleapis.com",paths:["/v1/userinfo"]},{host:"www.googleapis.com",paths:["/oauth2/v2/userinfo","/oauth2/v3/userinfo","/userinfo/v2/me"]}]},"gmail.read":{label:"Gmail (read-only)",access:"read",scopes:["https://www.googleapis.com/auth/gmail.readonly"],routes:[{host:"gmail.googleapis.com",paths:["/gmail/v1/users/"],posts:[/^\/gmail\/v1\/users\/[^/]+\/(watch|stop)$/]}]},"calendar.read":{label:"Google Calendar (read-only)",access:"read",scopes:["https://www.googleapis.com/auth/calendar.readonly"],routes:[{host:"www.googleapis.com",paths:["/calendar/v3/"],posts:[/^\/calendar\/v3\/freeBusy$/,/^\/calendar\/v3\/calendars\/[^/]+\/events\/watch$/,/^\/calendar\/v3\/users\/me\/calendarList\/watch$/,/^\/calendar\/v3\/channels\/stop$/]}]},"search-console.read":{label:"Search Console (read-only)",access:"read",scopes:["https://www.googleapis.com/auth/webmasters.readonly"],routes:[{host:"www.googleapis.com",paths:["/webmasters/v3/"],posts:[/^\/webmasters\/v3\/sites\/[^/]+\/searchAnalytics\/query$/]},{host:"searchconsole.googleapis.com",paths:["/webmasters/v3/"],posts:[/^\/webmasters\/v3\/sites\/[^/]+\/searchAnalytics\/query$/,/^\/v1\/urlInspection\/index:inspect$/]}]},"analytics.read":{label:"Google Analytics (read-only)",access:"read",scopes:["https://www.googleapis.com/auth/analytics.readonly"],routes:[{host:"analyticsdata.googleapis.com",paths:["/v1beta/properties/"],posts:[/^\/v1beta\/properties\/[^/]+:(runReport|batchRunReports|runPivotReport|batchRunPivotReports|runRealtimeReport|checkCompatibility)$/]},{host:"analyticsadmin.googleapis.com",paths:["/v1beta/accountSummaries","/v1beta/accounts","/v1beta/accounts/","/v1beta/properties","/v1beta/properties/","/v1alpha/properties/"]}]}}},api:["gmail.googleapis.com","www.googleapis.com","searchconsole.googleapis.com","analyticsdata.googleapis.com","analyticsadmin.googleapis.com","openidconnect.googleapis.com"],redirectPaths:["/integrations/google/callback"],flow:{tokenUrl:"https://oauth2.googleapis.com/token",pkce:!0,scopeDialect:"google",authorizeParams:{access_type:"offline",prompt:"consent"},identity:{url:"https://openidconnect.googleapis.com/v1/userinfo",label:"email",id:"sub"}}},"microsoft-365":{mode:"oauth_client",label:"Microsoft 365 (Outlook mail and calendar)",secrets:{clientId:"MICROSOFT_365_CLIENT_ID",clientSecret:"MICROSOFT_365_CLIENT_SECRET"},token:[{host:"login.microsoftonline.com",path:"/common/oauth2/v2.0/token",methods:["POST"],inject:"form"}],access:["write"],console:"https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade",setup:"setup/microsoft-365.md",authorize:{url:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",scopes:["offline_access","User.Read","Mail.Read","Calendars.Read"]},scopePolicy:{dialect:"microsoft",grantTypes:["authorization_code","refresh_token"],requestScope:"replace",alwaysRequested:["offline_access"],tolerated:["openid","profile","email","offline_access","User.Read"],deniedSegments:["$batch","beta"],sets:{identity:{label:"Microsoft account (who you are)",access:"read",scopes:["User.Read"],routes:[{host:"graph.microsoft.com",paths:["/v1.0/me","/oidc/userinfo"]}]},"mail.read":{label:"Outlook mail (read-only)",access:"read",scopes:["Mail.Read"],routes:[{host:"graph.microsoft.com",paths:["/v1.0/me/messages","/v1.0/me/messages/","/v1.0/me/mailFolders","/v1.0/me/mailFolders/"]}]},"calendar.read":{label:"Outlook calendar (read-only)",access:"read",scopes:["Calendars.Read"],routes:[{host:"graph.microsoft.com",paths:["/v1.0/me/calendar","/v1.0/me/calendar/","/v1.0/me/calendars","/v1.0/me/calendars/","/v1.0/me/events","/v1.0/me/events/","/v1.0/me/calendarView","/v1.0/me/calendarView/"],posts:[/^\/v1\.0\/me\/calendar\/getSchedule$/]}]}}},api:["graph.microsoft.com"],redirectPaths:["/integrations/microsoft/callback"],flow:{tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",pkce:!0,scopeDialect:"microsoft",identity:{url:"https://graph.microsoft.com/v1.0/me",label:"userPrincipalName",id:"id"}}},...dn};function oe(e){let t=[e.secret];return e.kind==="basic"&&e.as==="password"&&typeof e.user=="object"&&t.push(e.user.secret),t}function L(e){switch(e.mode){case"api_key":return[...oe(e.auth),...e.hostSetting?[e.hostSetting]:[]];case"ai":return[e.auth.secret,...e.alsoNeeds??[]];case"service":return[...e.settings,...e.optionalSettings];case"oauth_client":return[e.secrets.clientId,...e.secrets.clientSecret?[e.secrets.clientSecret]:[],...e.hostSetting?[e.hostSetting]:[]]}}var j=Object.keys(N);function jt(e){return typeof e=="string"&&Object.hasOwn(N,e)}var G={get:e=>jt(e)?N[e]:void 0,ids:()=>j};function pn(e){return e.ids().filter(t=>e.get(t)?.mode!=="ai")}function ka(e,t){if(!e.hostSetting)return null;let s=t?.[e.hostSetting],n=typeof s=="string"&&s.trim()?s.trim():e.defaultOrigin;if(!n)return null;let r;try{r=new URL(/^[a-z][a-z0-9+.-]*:\/\//i.test(n)?n:`https://${n}`)}catch{return null}let o=r.pathname==="/"&&!r.search&&!r.hash&&!r.username&&!r.password;return r.protocol==="https:"&&o?r.origin:null}function al(e){return e.token.map(({host:t,path:s,methods:n})=>`${n.join("/")} https://${t??`<${e.hostSetting}>`}${Sa(s)}`).join(", ")}function Sa(e){return typeof e=="string"?e:e.source.replace(/^\^|\$$/g,"").replace(/v\\d\+\\\.\\d\+/g,"v<version>").replace(/\\(.)/g,"$1")}var va=["AI_GATEWAY_ID","CLOUDFLARE_ACCOUNT_ID"],un=["openrouter","workers-ai","openai","anthropic","groq","mistral","gemini"];var Ia=/^([a-z][a-z0-9-]{1,39})(?:\/(.{1,200}))?$/;function dl(e){if(typeof e!="string")return null;let t=Ia.exec(e.trim());if(!t)return null;let s=t[2]?.trim();return s?{provider:t[1],model:s}:{provider:t[1]}}function pl(e){return e.model?`${e.provider}/${e.model}`:e.provider}function zt(e){return e?.mode==="ai"&&e.kind!=="proxy"&&e.chat!==void 0}function _e(e){return[...e.authOptional?[]:[e.auth.secret],...e.alsoNeeds??[]]}function ln(e,t){return _e(e).every(s=>t(s))}function Ta(e){return va.every(t=>e(t))}function hn(e,t){return e.aig!==void 0&&Ta(t)}function Pa(e,t,s){return{id:e,label:t.label,settings:_e(t),configured:ln(t,s),model:t.chat.model,viaAiGateway:hn(t,s),embeddings:t.embeddings!==void 0}}function xa(e,t=G){return[...un,...t.ids().filter(n=>!un.includes(n))].flatMap(n=>{let r=t.get(n);return zt(r)?[Pa(n,r,e)]:[]})}function Ra(e,t=G){let s=t.get(e.provider);return s?s.mode!=="ai"?`${e.provider} is an API provider, not a model provider`:s.kind==="proxy"?`${s.label} fronts the model providers and serves no models of its own; set a provider, and turn the gateway on with everyapp ai gateway on`:s.chat?null:`${s.label} has no OpenAI-shaped chat route, so it can't serve the default; an app pins it by listing it under providers`:`${e.provider} isn't a provider this Gateway knows`}function mn(e){let t=e.lookup??G,{isSet:s}=e,n=xa(s,t),r=(p,u,h,w,f)=>({provider:p,label:u.label,model:w??u.chat.model,source:h,configured:ln(u,s),settings:_e(u),via:hn(u,s)?"ai-gateway":"direct",chat:u.chat,...u.embeddings?{embeddings:u.embeddings}:{},candidates:[...n.filter(l=>l.id===p),...n.filter(l=>l.id!==p)],...f?{problem:f}:{}}),o;if(e.choice){let p=t.get(e.choice.provider),u=Ra(e.choice,t);if(!u&&zt(p))return r(e.choice.provider,p,"setting",e.choice.model);o=u??void 0}let a=n.find(p=>p.configured),i=a??n[0];if(!i)throw new Error("the catalog has no AI provider with a chat route");let d=t.get(i.id);if(!zt(d))throw new Error("unreachable");return r(i.id,d,a?"order":"none",void 0,o)}function fn(e){let t=e.candidates.filter(n=>n.id!==e.provider).slice(0,3).map(n=>`${n.label} (${n.settings.join(" and ")})`),s=e.source==="setting"?`The Gateway's default model provider is ${e.label}; set ${e.settings.join(" and ")}.`:`Any one model provider's key makes the app work; ${e.label} is first in the order: set ${e.settings.join(" and ")}.`;return t.length>0?`${s} Or another: ${t.join(", ")}; pick one with everyapp ai default <provider>.`:s}var gn=["google","microsoft","github","apple","cloudflare","oidc"];function Oa(e){return`/api/auth/callback/${e}`}function ll(e,t){return`${e.replace(/\/+$/,"")}${Oa(t)}`}function Ae(e,t){return`${e.toUpperCase()}_SIGNIN_${t}`}function ae(e,t){return[{name:Ae(e,"CLIENT_ID"),role:"clientId",required:!0,plain:!0,what:t.clientId},{name:Ae(e,"CLIENT_SECRET"),role:"clientSecret",required:!0,plain:!1,what:t.clientSecret}]}var Kt=["openid","email","profile"],Ca={google:{id:"google",label:"Google",console:"https://console.cloud.google.com/apis/credentials",appNoun:"OAuth client ID (Web application)",settings:ae("google",{clientId:"The OAuth client's Client ID (ends in .apps.googleusercontent.com)",clientSecret:"The OAuth client's Client secret"}),scopes:Kt,emailClaim:"the ID token's `email`, counted as verified only when its `email_verified` is true (every Google account's own address is)",setup:"setup/signin-google.md",notes:["An OAuth consent screen still in Testing only signs in the test users listed on it; publish it for everyone else."]},microsoft:{id:"microsoft",label:"Microsoft",console:"https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade",appNoun:"App registration",settings:[...ae("microsoft",{clientId:"The app registration's Application (client) ID",clientSecret:"A client secret from Certificates & secrets (it expires; 24 months at most)"}),{name:Ae("microsoft","TENANT"),role:"tenant",required:!1,plain:!0,what:"The Directory (tenant) ID to pin sign-in to your own directory; unset means any Microsoft account (common), which then needs the xms_edov claim"}],scopes:Kt,emailClaim:"the ID token's `email`, counted as verified when MICROSOFT_SIGNIN_TENANT pins your own directory, or the token carries `xms_edov: true` (the optional claim that says the domain's owner verified it), `email_verified: true`, a matching `verified_primary_email`, or comes from a personal Microsoft account",setup:"setup/signin-microsoft.md",notes:["Without MICROSOFT_SIGNIN_TENANT, add the optional claims `email` and `xms_edov` under Token configuration, or every sign-in is refused as unverified: any tenant's admin can put any address on their users."]},github:{id:"github",label:"GitHub",console:"https://github.com/settings/developers",appNoun:"OAuth App",settings:ae("github",{clientId:"The OAuth App's Client ID",clientSecret:"A client secret generated on the OAuth App"}),scopes:["read:user","user:email"],emailClaim:"the primary address from GitHub's emails API, counted as verified only when GitHub marks it verified",setup:"setup/signin-github.md",notes:["GitHub Apps are something else: make an OAuth App (Settings \u2192 Developer settings \u2192 OAuth Apps)."]},apple:{id:"apple",label:"Apple",console:"https://developer.apple.com/account/resources/identifiers/list/serviceId",appNoun:"Services ID",settings:ae("apple",{clientId:"The Services ID's identifier (com.example.gateway)",clientSecret:"The client secret JWT you generate from your Sign in with Apple key (ES256; valid six months at most, then generate it again)"}),scopes:["email","name"],emailClaim:"the ID token's `email`, counted as verified only when its `email_verified` is true; someone who chose Hide My Email arrives as a @privaterelay.appleid.com address, which no invitation names",setup:"setup/signin-apple.md",notes:["Apple returns to the Gateway with a POST; behind the outer ring, `everyapp access on` leaves /api/auth/callback/apple public (it only redirects to the same URL as a GET, which Access then checks).","The client secret is a JWT that expires within six months: generate a new one before then or sign-in stops."]},cloudflare:{id:"cloudflare",label:"Cloudflare",console:"https://dash.cloudflare.com/?to=/:account/oauth-clients",appNoun:"OAuth client (Manage Account \u2192 OAuth clients)",settings:ae("cloudflare",{clientId:"The OAuth client's Client ID",clientSecret:"The OAuth client's Client secret"}),scopes:["user-details.read"],emailClaim:"the Cloudflare API's /user `email` (the account's sign-in address). Cloudflare reports no verified flag, so the email counts as verified on the strength of the client being private: only members of your Cloudflare account can authorize it, and they got in by accepting an invitation sent to that address",setup:"setup/signin-cloudflare.md",notes:["Keep the client private (the default): a public client lets any Cloudflare user sign in, and Cloudflare says nothing about whether their address is verified. Making a client public is permanent.","The Cloudflare account's members sign in; for everyone else use Cloudflare Access's one-time PIN (`everyapp access on`) or another provider."]},oidc:{id:"oidc",label:"SSO",console:"your identity provider's admin console",appNoun:"OpenID Connect client (web application, authorization code)",settings:[{name:Ae("oidc","ISSUER"),role:"issuer",required:!0,plain:!0,what:"The issuer URL (https://\u2026), which serves /.well-known/openid-configuration"},...ae("oidc",{clientId:"The client ID",clientSecret:"The client secret"}),{name:Ae("oidc","LABEL"),role:"label",required:!1,plain:!0,what:'The button text after "Continue with" (default "SSO")'}],scopes:Kt,emailClaim:"the ID token's `email` (else the userinfo endpoint's), counted as verified only when `email_verified` is true",setup:"setup/signin-oidc.md",notes:["Cloudflare Access has its own settings (CLOUDFLARE_ACCESS_OIDC_*, `everyapp access`): use those for Access, this for Okta, Keycloak, Auth0, Authentik, Google Workspace as an OIDC issuer and the like. For Microsoft Entra ID use the `microsoft` provider: Entra's ID tokens carry no `email_verified`, so through this entry every sign-in would be refused as unverified.","ID tokens must be signed with RS256 (every major provider's default)."]}},Ht=gn.map(e=>Ca[e]);function hl(e){return gn.includes(e)}var yn=Ht.flatMap(e=>e.settings.map(t=>t.name)),wn=Ht.flatMap(e=>e.settings.filter(t=>t.plain).map(t=>t.name)),Na=/^[A-Z][A-Z0-9_]*_SIGNIN_(CLIENT_ID|CLIENT_SECRET|ISSUER|LABEL|TENANT)$/;function qe(e){return Na.test(e)}function ml(e){for(let t of Ht)if(t.settings.some(s=>s.name===e))return t;return null}function fl(e,t){let s=e.settings.filter(o=>t(o.name)).map(o=>o.name),n=e.settings.filter(o=>o.required&&!t(o.name)).map(o=>o.name),r=n.length===0?"on":s.length===0?"off":"incomplete";return{id:e.id,status:r,missing:r==="incomplete"?n:[],set:s}}var $a=["GATEWAY_URL","APP_BASE_DOMAIN","BETTER_AUTH_SECRET","JWT_PRIVATE_KEY","JWT_PUBLIC_KEY","GATEWAY_DEPLOYMENT_MODE","CLOUDFLARE_ACCOUNT_ID","THIRD_PARTY_DEPLOYS"],En=new Set($a);function ie(e){return En.has(e)}var Da=[...new Set(j.flatMap(e=>{let t=N[e];return t.mode==="service"?[]:L(t)}))].filter(e=>!En.has(e)),La=["AI_PROXY_EXTRA_ROUTES","EMAIL_REST_API_TOKEN","RESEND_API_KEY","EMAIL_PROVIDER","EMAIL_FROM","EMAIL_FROM_NAME","MCP_OAUTH_ENABLED","MCP_DCR_ENABLED","MCP_ALLOWED_ORIGINS","MCP_AUDIT_RETENTION_DAYS","CLOUDFLARE_ACCESS_OIDC_ISSUER","CLOUDFLARE_ACCESS_OIDC_CLIENT_ID","CLOUDFLARE_ACCESS_OIDC_CLIENT_SECRET","CLOUDFLARE_ACCESS_OIDC_LABEL","CLOUDFLARE_ACCESS_TEAM_DOMAIN","CLOUDFLARE_ACCESS_AUD","CLOUDFLARE_ACCESS_APPS_AUD","CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS","CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN","EMAIL_PASSWORD_SIGN_IN","HOSTED_OPEN_SIGNUP","CF_DEPLOY_TOKEN","BROWSER_APP_INSTALLS","DISPATCH_NAMESPACE","THIRD_PARTY_DOMAIN","EVENTS_ALLOW_PRIVATE_TARGETS"],Ma=[...Da,...La,...yn],Ga=new Set(Ma),Ua=/^[A-Z][A-Z0-9_]*_MCP_TOKEN$/;function ke(e){return Ua.test(e)}function F(e){return Ga.has(e)||ke(e)}var ja=["EMAIL_FROM","EMAIL_FROM_NAME","EMAIL_PROVIDER","EMAIL_PASSWORD_SIGN_IN","MASTODON_URL","AI_PROXY_EXTRA_ROUTES","MCP_OAUTH_ENABLED","MCP_DCR_ENABLED","MCP_ALLOWED_ORIGINS","MCP_AUDIT_RETENTION_DAYS","CLOUDFLARE_ACCESS_OIDC_ISSUER","CLOUDFLARE_ACCESS_OIDC_CLIENT_ID","CLOUDFLARE_ACCESS_OIDC_LABEL","CLOUDFLARE_ACCESS_TEAM_DOMAIN","CLOUDFLARE_ACCESS_AUD","CLOUDFLARE_ACCESS_APPS_AUD","CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS","CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN","HOSTED_OPEN_SIGNUP","BROWSER_APP_INSTALLS","DISPATCH_NAMESPACE","THIRD_PARTY_DOMAIN","EVENTS_ALLOW_PRIVATE_TARGETS"],za=new Set([...ja,...wn]);function El(e){return za.has(e)}var Ka=["HOSTED_OPEN_SIGNUP","DISPATCH_NAMESPACE","THIRD_PARTY_DOMAIN"],Ha=new Set(Ka);function bl(e){return Ha.has(e)}var Wa=["MCP_ACCESS_TOKEN_TTL","DATAFORSEO_SANDBOX"];function bn(e){return Wa.includes(e)}var Ba=new Set(["GATEWAY_URL","CF_VERSION_METADATA"]),Fa=["EVERYAPP_","EVERY_APP_","APP__"],_n="GATEWAY_URL, CF_VERSION_METADATA and the EVERYAPP_*, EVERY_APP_* and APP__* names";function Je(e){let t=e.toUpperCase();return Ba.has(t)||Fa.some(s=>t.startsWith(s))}function An(e){for(let t of j){let s=N[t];if(L(s).includes(e))return{kind:s.mode==="ai"?"provider":"capability",id:t}}return null}var kl="provider",Xe={dataforseo:{id:"dataforseo",name:"DataForSEO",description:"SEO data for your agent: keyword metrics and suggestions, live Google results, domain rankings, competitors and backlinks, through the Gateway's DataForSEO key.",capability:"dataforseo",why:"Serves DataForSEO's keyword, search-result, domain and backlink data to members' AI clients.",example:"find keyword ideas for a page about running shoes"}},Sl=Object.keys(Xe).sort();function kn(e){return Object.hasOwn(Xe,e)}function vl(e){return oe(N[Xe[e].capability].auth)[0]}function Il(e){let t=Xe[e];return{id:t.id,name:t.name,description:t.description,capabilities:{[t.capability]:{access:"read",why:t.why}}}}var Se="/__everyapp/tools",Pl=`${Se}/list`,xl=`${Se}/call`,Ya=["read","write","destructive"],Rl="mcp:read",Ol="mcp:write";var Sn=/^[a-z][a-z0-9_]{0,47}$/;function vn(e){return typeof e=="string"&&Ya.includes(e)}function Cl(e){return JSON.stringify(Wt(e))}function Wt(e){if(Array.isArray(e))return e.map(Wt);if(!e||typeof e!="object")return e;let t={};for(let s of Object.keys(e).sort()){let n=e[s];n!==void 0&&(t[s]=Wt(n))}return t}var In=["none","bearer","header","basic","oauth"],Tn=["annotations","read","write"],On=/^[a-z]([a-z0-9-]*[a-z0-9])?$/,Bt=32,Va=["everyapp"],qa=64,Ja=/^[A-Za-z0-9!#$%&'*+.^_`|~-]{1,100}$/,Xa=32,Cn=2048,Za=255,Qa=1e3,Pn=500,ei=256,ti=new Set(["authorization","cookie","host","content-type","content-length","accept","connection","transfer-encoding","mcp-session-id","mcp-protocol-version","mcp-method","mcp-name"]);function si(e){return`${e.toUpperCase().replace(/-/g,"_")}_MCP_TOKEN`}function ni(e){return typeof e!="string"||!On.test(e)?"the id must be kebab-case: lowercase letters, digits and hyphens, starting with a letter":e.length>Bt?`the id must be at most ${Bt} characters`:Va.includes(e)?`"${e}" is reserved`:kn(e)?`"${e}" is the Gateway's built-in MCP app; a remote server can't take its id`:null}function Gl(e){let t;try{t=new URL(e).hostname.toLowerCase().replace(/\.$/,"")}catch{return null}if(!t||/^[\d.]+$/.test(t)||t.includes(":"))return null;let s=t.split(".").filter(i=>i.length>0);if(s.length<2)return null;let n=new Set(["co","com","net","org","gov","edu","ac"]),r=s.length-2;r>0&&n.has(s[r])&&s[r+1].length===2&&(r-=1);let a=(s[r]??"").replace(/[^a-z0-9-]/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-").slice(0,Bt).replace(/-+$/g,"");return!a||!On.test(a)||ni(a)?null:a}function xn(e,t){return e===t||e.endsWith(`.${t}`)}function ri(){let e=new Set(["api.openai.com","openrouter.ai","gateway.ai.cloudflare.com","api.cloudflare.com"]);for(let t of Object.values(N))if(t.mode==="api_key")for(let s of t.hosts)e.add(s);else if(t.mode==="oauth_client")for(let s of t.token)"host"in s&&typeof s.host=="string"&&e.add(s.host);return[...e].sort()}function Ul(e,t){if(typeof e!="string"||!e.trim())return"give the server's URL";if(e.length>Cn)return"the URL is too long";let s;try{s=new URL(e)}catch{return"the URL doesn't parse"}let n=t.gatewayUrl.trim().toLowerCase().startsWith("http://");if(s.username||s.password)return"the URL must not carry credentials; the Gateway sends the credential from its own setting";if(s.hash)return"the URL must not have a fragment";let r=s.hostname.toLowerCase().replace(/\.$/,""),o=r==="localhost"||r.endsWith(".localhost")||r==="127.0.0.1"||r==="[::1]"||r==="::1";if(s.protocol!=="https:"&&!(s.protocol==="http:"&&n&&o))return n?"the URL must be https://, or http:// on localhost while the Gateway runs locally":"the URL must be https://";if(!r)return"the URL has no host";if(!o&&(/^[\d.]+$/.test(r)||r.startsWith("[")))return"the URL must name a host, not an IP address";if(o&&!n)return"the URL must name a public host";let a="",i="";try{let d=new URL(t.gatewayUrl);a=d.hostname.toLowerCase().replace(/\.$/,""),i=d.origin.toLowerCase()}catch{a=""}if(a&&(n?s.origin.toLowerCase()===i:xn(r,a)))return"the URL is this Gateway's own address";for(let d of[t.appBaseDomain,t.thirdPartyDomain]){let p=(d??"").trim().toLowerCase().replace(/\.$/,"");if(p&&xn(r,p))return`the URL is on this Gateway's app domain (${p})`}return ri().includes(r)?`${r} is a provider this Gateway holds a key for; apps reach it through the Gateway's capabilities, not as an MCP app`:null}function ce(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function oi(e){return typeof e!="string"||!e?"give the credential's setting name":e.length>qa?"the credential's name is too long":ke(e)?null:`the credential's name must end in _MCP_TOKEN (letters, digits and underscores), like ${si("treg")}`}function ai(e){if(!ce(e)||typeof e.kind!="string")return{ok:!1,problem:"auth must name a kind"};let t=e.kind;if(!In.includes(t))return{ok:!1,problem:`auth.kind must be one of ${In.join(", ")}`};if(t==="none"||t==="oauth")return{ok:!0,auth:{kind:t}};let s=oi(e.secret);if(s)return{ok:!1,problem:`auth.secret: ${s}`};let n=e.secret;if(t==="bearer"||t==="basic")return{ok:!0,auth:{kind:t,secret:n}};let r=e.header;if(typeof r!="string"||!Ja.test(r))return{ok:!1,problem:"auth.header must be an HTTP header name"};if(ti.has(r.toLowerCase()))return{ok:!1,problem:`auth.header can't be ${r}; use kind "bearer" or "basic" for Authorization`};let o=e.prefix;return o!==void 0&&(typeof o!="string"||o.length>Xa||/[\r\n]/.test(o))?{ok:!1,problem:"auth.prefix must be a short string"}:{ok:!0,auth:{kind:"header",secret:n,header:r,...typeof o=="string"&&o?{prefix:o}:{}}}}function ii(e){if(!ce(e))return{ok:!1,problem:"remote must be an object"};let t=e.url;if(typeof t!="string"||!t||t.length>Cn)return{ok:!1,problem:"remote.url must be a URL"};let s=ai(e.auth);if(!s.ok)return s;let n=e.risk??"annotations";if(!Tn.includes(n))return{ok:!1,problem:`remote.risk must be one of ${Tn.join(", ")}`};let r={},o=e.tools??{};if(!ce(o))return{ok:!1,problem:"remote.tools must be an object"};let a=Object.entries(o);if(a.length>Pn)return{ok:!1,problem:`remote.tools has more than ${Pn} entries`};for(let[d,p]of a){if(!d||d.length>ei)return{ok:!1,problem:"remote.tools has a tool name that is empty or too long"};if(!ce(p))return{ok:!1,problem:`remote.tools.${d} must be an object`};let u={};if(p.risk!==void 0){if(!vn(p.risk))return{ok:!1,problem:`remote.tools.${d}.risk must be read, write or destructive`};u.risk=p.risk}if(p.enabled!==void 0){if(typeof p.enabled!="boolean")return{ok:!1,problem:`remote.tools.${d}.enabled must be true or false`};u.enabled=p.enabled}r[d]=u}let i=e.rev??1;return typeof i!="number"||!Number.isInteger(i)||i<1?{ok:!1,problem:"remote.rev must be a positive integer"}:{ok:!0,block:{url:t,auth:s.auth,risk:n,tools:r,rev:i}}}function Nn(e){if(!ce(e)||e.remote===void 0)return null;let t=ii(e.remote);return t.ok?t.block:null}function jl(e){return ce(e)&&e.remote!==void 0}function $n(e){return"secret"in e?e.secret:null}function ci(e,t){let s="";try{s=new URL(t).origin}catch{s=""}return`${e}'s MCP server${s?` at ${s}`:""}, served to your AI clients through this Gateway.`}function Dn(e,t){let s=e.tools[t];if(s)return s;let n=Rn(t);if(n){for(let[r,o]of Object.entries(e.tools))if(Rn(r)===n)return o}}function zl(e){let t=(e.name??"").trim().slice(0,Za)||e.id,s=(e.description??"").trim().slice(0,Qa)||ci(t,e.remote.url);return{id:e.id,name:t,description:s,remote:e.remote}}function Kl(e,t,s){let n=Dn(t,s)?.risk;return n?{risk:n,source:"override"}:t.risk==="read"||t.risk==="write"?{risk:t.risk,source:"app"}:e?.readOnlyHint===!0?{risk:"read",source:"hint"}:e?.destructiveHint===!0?{risk:"destructive",source:"hint"}:{risk:"write",source:"default"}}function Hl(e,t){return Dn(e,t)?.enabled!==!1}function Rn(e){if(typeof e!="string")return null;let t=e.trim().replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").toLowerCase().replace(/[\s./:-]+/g,"_").replace(/[^a-z0-9_]/g,"").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"");return t?(/^[0-9]/.test(t)&&(t=`t_${t}`),t=t.slice(0,48).replace(/_+$/g,""),Sn.test(t)?t:null):null}function Ln(e){switch(e.kind){case"none":return"no credential";case"bearer":return"bearer token";case"basic":return"user and password";case"header":return`header ${e.header}`;case"oauth":return"OAuth (not supported yet)"}}function di(e){return e?typeof e.anyOf=="string"&&e.anyOf.trim()?{kind:"anyOf",group:e.anyOf.trim()}:e.optional===!0?{kind:"optional"}:{kind:"required"}:{kind:"required"}}function Ft(e){if(!e||typeof e!="object")return{};let t=e;return{...typeof t.why=="string"?{why:t.why}:{},...typeof t.docs=="string"?{docs:t.docs}:{},...typeof t.optional=="boolean"?{optional:t.optional}:{},...typeof t.setup=="string"?{setup:t.setup}:{},...typeof t.anyOf=="string"?{anyOf:t.anyOf}:{}}}function Qe(e){return(e.providers??[]).flatMap(t=>typeof t=="string"?[{id:t}]:t&&typeof t=="object"&&typeof t.id=="string"?[{id:t.id,...Ft(t)}]:[])}function ql(e){return Qe(e).map(t=>t.id)}function et(e){return(e.secrets??[]).flatMap(t=>typeof t=="string"?[{name:t}]:t&&typeof t=="object"&&typeof t.name=="string"?[{name:t.name,...Ft(t)}]:[])}function Gn(e){return et(e).map(t=>t.name)}function Un(e){return _e(e).filter(t=>!ie(t))}function pi(e){let t=s=>s.filter(n=>F(n)&&!ie(n));switch(e.mode){case"api_key":return{names:[...L(e)],alsoReads:[]};case"ai":return{names:Un(e),alsoReads:[]};case"service":return{names:t(e.settings),alsoReads:t(e.optionalSettings)};case"oauth_client":{let s=[e.secrets.clientId,...e.secrets.clientSecret?[e.secrets.clientSecret]:[]],n=e.hostSetting?[e.hostSetting]:[];return e.defaultOrigin?{names:s,alsoReads:n}:{names:[...s,...n],alsoReads:[]}}}}function ui(e){switch(e.mode){case"api_key":case"ai":return e.docs;case"oauth_client":return e.console.startsWith("https://")?e.console:e.defaultOrigin?`${e.defaultOrigin}${e.console}`:void 0;case"service":return}}function Mn(e,t){if(e.mode==="service"||e.mode==="oauth_client")return{};let s=e.secrets??[],n=[...e.hint?[e.hint]:[],...s.filter(r=>r.hint&&t.includes(r.name)).map(r=>t.length>1?`${r.name}: ${r.hint}`:r.hint)];return n.length>0?{hint:n.join(" ")}:{}}function Ze(e,t,s={}){let n=t?.docs??s.docs,r=e.holder==="gateway"?s.setup:t?.setup;return{...e,need:di(t),...t?.why?{why:t.why}:{},...n?{docs:n}:{},...r?{setup:r}:{},...s.hint?{hint:s.hint}:{}}}function Jl(e,t=G,s={}){let n=[],r=e.ai?.chat;if(r===!0||r&&typeof r=="object"){let a=mn({choice:s.aiDefault??null,isSet:s.isSet??(()=>!1),lookup:t}),i=p=>p.filter(u=>!ie(u)),d=t.get(a.provider);n.push(Ze({kind:"ai-default",id:"ai-default",label:`A chat model (${a.label})`,holder:"gateway",names:i(a.settings),alsoReads:[],alternatives:a.candidates.map(p=>i(p.settings)).filter(p=>p.length>0)},r===!0?void 0:r,{...d?.mode==="ai"?{docs:d.docs}:{},setup:"setup/ai.md",hint:fn(a)}))}for(let a of Qe(e)){let i=t.get(a.id);if(i?.mode!=="ai")continue;let d=Un(i);n.push(Ze({kind:"provider",id:a.id,label:i.label,holder:"gateway",names:d,alsoReads:[]},a,{docs:i.docs,setup:i.setup,...Mn(i,d)}))}for(let[a,i]of Object.entries(e.capabilities??{})){let d=t.get(a);if(!d||d.mode==="ai")continue;let{names:p,alsoReads:u}=pi(d);n.push(Ze({kind:"capability",id:a,label:d.label,holder:"gateway",names:p,alsoReads:u},Ft(i),{docs:ui(d),setup:d.setup,...Mn(d,p)}))}e.ai?.routes?.length&&n.push({kind:"ai-routes",id:"ai-routes",label:"AI proxy routes",holder:"gateway",names:["AI_PROXY_EXTRA_ROUTES"],alsoReads:[],need:{kind:"required"},why:`Lets the app call ${e.ai.routes.join(", ")} through the AI proxy.`,setup:"setup/openai.md"});let o=Nn(e);if(o){let a=$n(o.auth);if(a){let i=typeof e.name=="string"&&e.name.trim()?e.name.trim():"the MCP server";n.push({kind:"remote-mcp",id:a,label:`${i} credential`,holder:"gateway",names:[a],alsoReads:[],need:{kind:"required"},why:`What ${i} expects: ${Ln(o.auth)}. The Gateway sends it to ${o.url} and nowhere else.`,setup:"setup/remote-mcp.md"})}}for(let a of et(e))n.push(Ze({kind:"secret",id:a.name,label:a.name,holder:"app",names:[a.name],alsoReads:[]},a));return n}function li(e,t){let s=r=>{let o=!1;for(let a of r){let i=t(e.holder,a);if(i===!1)return!1;i===null&&(o=!0)}return o?null:!0};if(!e.alternatives?.length)return s(e.names);let n=!1;for(let r of e.alternatives){let o=s(r);if(o===!0)return!0;o===null&&(n=!0)}return n?null:!1}function Xl(e,t,s={}){let n=e.map(a=>{let i=s.readiness?.(a);return{...a,set:i===void 0?li(a,t):i,blocking:!1}}),r=[];for(let a of n){if(a.need.kind!=="anyOf")continue;let i=a.need.group,d=r.find(p=>p.group===i);d||(d={group:i,members:[],met:!1},r.push(d)),d.members.push(a)}for(let a of r){a.met=a.members.some(d=>d.set===!0);let i=a.members.some(d=>d.set===null);if(!a.met&&!i)for(let d of a.members)d.blocking=!0}for(let a of n)a.need.kind==="required"&&a.set===!1&&(a.blocking=!0);let o=n.filter(a=>a.blocking);return{ready:o.length===0,settings:n,groups:r,unmet:o}}function hi(e,{cli:t,appId:s,provider:n=!1}){if(e.unmet.length===0)return null;if(!n)return{command:`${t} configure ${s}`};let r=[],o=a=>{for(let i of a.names)r.includes(i)||r.push(i)};for(let a of e.unmet)a.need.kind==="required"&&o(a);for(let a of e.groups){let i=a.members.find(d=>d.blocking);i&&o(i)}return{command:`${t} secret set ${r.join(" ")}`}}function Zl(e,t){let s=({alsoReads:n,...r})=>r;return{ready:e.ready,settings:e.settings.map(s),unmet:e.unmet.map(s),groups:e.groups.map(n=>({group:n.group,met:n.met,members:n.members.map(r=>r.id)})),command:t.withCommand===!1?null:hi(e,t)}}var eh=["cloudflare","resend"];var tt={bodyBytes:5*1024*1024,recipients:50,subjectChars:998,headers:20,headerValueBytes:2048,headerNameBytes:100,headersTotalBytes:16*1024,attachments:32,senders:20,inbound:50,inboundAddressChars:90},mi=/^(\*|[a-z0-9._+-]+)@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z][a-z0-9-]*[a-z0-9]$/,fi=/^(\*|[a-z0-9._+-]+)@([a-z0-9-]+\.)+[a-z]{2,}$/,Yt="everyapp email set";function th(e,t){let s=[],n=e==="senders"?tt.senders:tt.inbound;t.length>n&&s.push(`At most ${n} ${e==="senders"?"senders":"inbound addresses"}, not ${t.length}.`);for(let r of t)e==="inbound"&&r.length>tt.inboundAddressChars?s.push(`${r} is longer than Email Routing's ${tt.inboundAddressChars} characters.`):(e==="senders"?mi:fi).test(r)||s.push(e==="senders"?`"${r}" isn't a sender: a sender is "*@<domain>" or "<local>@<domain>", in lowercase.`:`"${r}" isn't an inbound address: an inbound address is "*@<domain>" or "<local>@<domain>", in lowercase.`);for(let r of new Set(t.filter((o,a)=>t.indexOf(o)!==a)))s.push(`${r} is listed twice.`);return s}function sh(e){return e.length===0?null:JSON.stringify(e)}function nh(e,t){let s=e?.trim();if(!s)return null;let n=/^(.*?)\s*<([^<>]+)>$/.exec(s),r=(n?.[2]??s).trim(),o=n?.[1]?.trim().replace(/^(["'])(.*)\1$/,"$2").trim(),a=t?.trim()||o;return r&&a?{address:r,name:a}:null}function rh(e){if(typeof e!="string"||!e.trim())return[];let t=e.trim();if(t.startsWith("["))try{let s=JSON.parse(t);return Array.isArray(s)?s.filter(n=>typeof n=="string"):[]}catch{return[]}return t.split(/[\s,]+/).filter(Boolean)}function ah(e){if(/[\p{Cc}\p{Cf}\u2028\u2029]/u.test(e))return null;let t=e.trim().replace(/\s+/g," ");return!t||[...t].length>64?null:t}var yi=/^[a-z][a-z0-9-]{0,31}(?:\.[a-z][a-z0-9-]{0,31})?$/,Vt=["space","comma","google","microsoft","slack"],jn=["form","basic"],wi=/^[A-Za-z0-9-]{1,64}$/,Ei=new Set(["authorization","content-type","content-length","host","cookie"]),bi=/^[A-Za-z0-9_.-]{1,64}$/,zn=/^[A-Za-z_][A-Za-z0-9_]{0,63}(?:\.[A-Za-z_][A-Za-z0-9_]{0,63}){0,3}$/,_i=/[\p{Cc}\p{Cf}]/u,Kn=20,Hn=40,Wn=20,st=50,Bn=10,Ai=["batch","$batch"],ki=["kind","authorizeUrl","tokenUrl","revokeUrl","revokeMethod","clientId","clientSecret","inject","pkce","scopeDialect","authorizeParams","tokenHeaders","identity"];function ve(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function z(e,t,s,n){if(e!==void 0){if(typeof e!="string"||e.length===0||e.length>n){s.push({path:t,message:`must be a string of 1 to ${n} characters`});return}if(_i.test(e)){s.push({path:t,message:"holds a control character"});return}return e}}function nt(e,t,s,{query:n}){if(e===void 0)return;let r=z(e,t,s,500);if(r===void 0)return;let o;try{o=new URL(r)}catch{s.push({path:t,message:"must be an https URL"});return}if(o.protocol!=="https:"||o.username||o.password||o.port||o.hash){s.push({path:t,message:"must be an https URL with no port, credentials or fragment"});return}if(!n&&o.search){s.push({path:t,message:"may not carry a query string"});return}return{url:r,host:o.hostname.toLowerCase()}}function Si(e,t,s,n){if(typeof e!="string"||!n.test(e)){s.push({path:t,message:"must name a Gateway setting: upper case letters, digits and underscores, a letter first, 3 to 64 characters (GITHUB_CLIENT_ID)"});return}return e}function Fn(e,t,s,n){if(e===void 0)return;if(!ve(e)){s.push({path:t,message:"must be an object of strings"});return}let r=Object.entries(e);if(r.length>Bn){s.push({path:t,message:`at most ${Bn} entries`});return}let o={};for(let[a,i]of r){let d=`${t}.${a}`;n(a,d);let p=z(i,d,s,200);p!==void 0&&(o[a]=p)}return o}function rt(e,t,s){if(e===void 0)return;if(!Array.isArray(e)||e.length>Hn){s.push({path:t,message:`must be a list of at most ${Hn} scopes`});return}let n=[];return e.forEach((r,o)=>{let a=z(r,`${t}.${o}`,s,200);if(a!==void 0){if(/\s/.test(a)||a.includes(",")){s.push({path:`${t}.${o}`,message:"one scope, with no space or comma"});return}n.push(a)}}),new Set(n).size!==n.length&&s.push({path:t,message:"lists a scope twice"}),n}function vi(e,t,s,n){if(e===void 0)return;if(!Array.isArray(e)||e.length>Wn){n.push({path:t,message:`must be a list of at most ${Wn} routes`});return}let r=[];return e.forEach((o,a)=>{let i=`${t}.${a}`;if(!ve(o)){n.push({path:i,message:"must be { host, paths, posts? }"});return}for(let h of Object.keys(o))["host","paths","posts"].includes(h)||n.push({path:`${i}.${h}`,message:"unknown field"});let d=z(o.host,`${i}.host`,n,253);d!==void 0&&!s.includes(d)&&n.push({path:`${i}.host`,message:"must be one of hosts"});let p=[];!Array.isArray(o.paths)||o.paths.length>st?n.push({path:`${i}.paths`,message:`must be a list of at most ${st} paths`}):o.paths.forEach((h,w)=>{let f=z(h,`${i}.paths.${w}`,n,500);if(f!==void 0){if(!f.startsWith("/")||f.includes("//")||f.includes("\\")||f.includes("%")||/(^|\/)\.\.?(\/|$)/.test(f)){n.push({path:`${i}.paths.${w}`,message:"must start with / and hold no //, backslash, percent-escape or dot segment"});return}p.push(f)}});let u=[];o.posts!==void 0&&(!Array.isArray(o.posts)||o.posts.length>st?n.push({path:`${i}.posts`,message:`must be a list of at most ${st} anchored patterns`}):o.posts.forEach((h,w)=>{let f=z(h,`${i}.posts.${w}`,n,500);if(f!==void 0){if(!f.startsWith("^")||!f.endsWith("$")){n.push({path:`${i}.posts.${w}`,message:"must be anchored: start with ^ and end with $"});return}try{u.push(new RegExp(f))}catch{n.push({path:`${i}.posts.${w}`,message:"is not a valid pattern"})}}})),d!==void 0&&r.push({host:d,paths:p,...o.posts===void 0?{}:{posts:u}})}),r}function Ii(e,t,s){if(!ve(e)){s.push({path:"scopeSets",message:'required: at least one named set, { "repo.read": { "label", "access", "scopes" } }'});return}let n=Object.entries(e);if(n.length===0||n.length>Kn){s.push({path:"scopeSets",message:`must name 1 to ${Kn} sets`});return}let r={};for(let[o,a]of n){let i=`scopeSets.${o}`;if(!yi.test(o)){s.push({path:i,message:"a set is named identity, or <area>.<access> in lowercase (repo.read)"});continue}if(!ve(a)){s.push({path:i,message:"must be { label, access, scopes }"});continue}for(let f of Object.keys(a))["label","access","scopes","userScopes","routes"].includes(f)||s.push({path:`${i}.${f}`,message:"unknown field"});let d=z(a.label,`${i}.label`,s,80);a.label===void 0&&s.push({path:`${i}.label`,message:"required"});let p=a.access;p!=="read"&&p!=="write"&&s.push({path:`${i}.access`,message:"must be read or write"});let u=rt(a.scopes,`${i}.scopes`,s);a.scopes===void 0&&s.push({path:`${i}.scopes`,message:"required"});let h=rt(a.userScopes,`${i}.userScopes`,s),w=vi(a.routes,`${i}.routes`,t,s);d===void 0||p!=="read"&&p!=="write"||u===void 0||(r[o]={label:d,access:p,scopes:u,...h===void 0?{}:{userScopes:h},routes:w??[]})}return r}function Ti(e,t,s){if(e===void 0)return;if(!ve(e)){s.push({path:"auth.identity",message:"must be { url, label, id? }"});return}for(let a of Object.keys(e))["url","label","id"].includes(a)||s.push({path:`auth.identity.${a}`,message:"unknown field"});let n=nt(e.url,"auth.identity.url",s,{query:!0});e.url===void 0?s.push({path:"auth.identity.url",message:"required"}):n&&!t.includes(n.host)&&s.push({path:"auth.identity.url",message:"must be on one of hosts (the token is sent there)"});let r=z(e.label,"auth.identity.label",s,128);r!==void 0&&!zn.test(r)&&s.push({path:"auth.identity.label",message:"must be a JSON field name, or a dotted path to a nested one"}),e.label===void 0&&s.push({path:"auth.identity.label",message:"required"});let o=z(e.id,"auth.identity.id",s,128);if(o!==void 0&&!zn.test(o)&&s.push({path:"auth.identity.id",message:"must be a JSON field name, or a dotted path to a nested one"}),!(!n||r===void 0))return{url:n.url,label:r,...o===void 0?{}:{id:o}}}function Yn(e,t,s){let n=(_,O,Ye)=>Si(_,O,Ye,/^[A-Z][A-Z0-9_]{2,63}$/),r=e.auth;for(let _ of Object.keys(r))ki.includes(_)||s.push({path:`auth.${_}`,message:"not a field of auth.kind oauth2-user"});let o=nt(r.authorizeUrl,"auth.authorizeUrl",s,{query:!0});r.authorizeUrl===void 0&&s.push({path:"auth.authorizeUrl",message:"required"});let a=nt(r.tokenUrl,"auth.tokenUrl",s,{query:!1});r.tokenUrl===void 0&&s.push({path:"auth.tokenUrl",message:"required"});let i=nt(r.revokeUrl,"auth.revokeUrl",s,{query:!1}),d=r.revokeMethod;d!==void 0&&d!=="POST"&&d!=="DELETE"&&s.push({path:"auth.revokeMethod",message:"must be POST or DELETE"}),d!==void 0&&i===void 0&&s.push({path:"auth.revokeMethod",message:"needs a revokeUrl"});let p=n(r.clientId,"auth.clientId",s),u=r.clientSecret===void 0?void 0:n(r.clientSecret,"auth.clientSecret",s);u!==void 0&&u===p&&s.push({path:"auth.clientSecret",message:"must be another setting than auth.clientId"});let h=r.inject??"form";jn.includes(h)||s.push({path:"auth.inject",message:"must be form (the client in the body) or basic (HTTP Basic)"});let w=r.pkce??!0;typeof w!="boolean"&&s.push({path:"auth.pkce",message:"must be true or false"});let f=r.scopeDialect??"space";Vt.includes(f)||s.push({path:"auth.scopeDialect",message:`must be one of ${Vt.join(", ")}`});let l=Fn(r.authorizeParams,"auth.authorizeParams",s,(_,O)=>{bi.test(_)||s.push({path:O,message:"must be a query parameter name"}),["client_id","redirect_uri","response_type","scope","state","code_challenge","code_challenge_method"].includes(_)&&s.push({path:O,message:`${_} is a parameter the Gateway sets itself`})}),A=Fn(r.tokenHeaders,"auth.tokenHeaders",s,(_,O)=>{wi.test(_)?(Ei.has(_.toLowerCase())||_.toLowerCase().startsWith("x-everyapp-"))&&s.push({path:O,message:`${_} is a header the Gateway sets itself`}):s.push({path:O,message:"must be a header name"})}),E=Ti(r.identity,t.hosts,s),b=Ii(e.scopeSets,t.hosts,s),S=rt(e.alwaysRequested,"alwaysRequested",s),U=rt(e.tolerated,"tolerated",s);if(!o||!a||p===void 0||!b||typeof w!="boolean"||!Vt.includes(f)||!jn.includes(h))return;let te=[],se=_=>{for(let O of _)te.includes(O)||te.push(O)};for(let _ of Object.values(b))se(_.scopes),se(_.userScopes??[]);se(S??[]);let He={sets:b,tolerated:U??[],alwaysRequested:S??[],dialect:f,grantTypes:["authorization_code","refresh_token"],requestScope:"keep",deniedSegments:[...Ai]},We={tokenUrl:a.url,...i===void 0?{}:{revokeUrl:i.url},...d===void 0?{}:{revokeMethod:d},pkce:w,scopeDialect:f,...l===void 0?{}:{authorizeParams:l},...A===void 0?{}:{tokenHeaders:A},...E===void 0?{}:{identity:E}},Be=new URL(a.url).pathname,Fe={mode:"oauth_client",label:t.name,secrets:{clientId:p,...u===void 0?{}:{clientSecret:u}},token:[{host:a.host,path:Be,methods:["POST"],inject:h}],access:t.access??["read"],console:t.docs,authorize:{url:o.url,scopes:te},scopePolicy:He,api:[...t.hosts],redirectPaths:[],flow:We,...t.readMethods===void 0?{}:{readMethods:t.readMethods},...t.writeMethods===void 0?{}:{writeMethods:t.writeMethods},...t.description===void 0?{}:{description:t.description},...t.reference===void 0?{}:{reference:t.reference},...t.hint===void 0?{}:{hint:t.hint},...t.example===void 0?{}:{example:t.example},...t.tags===void 0?{}:{tags:t.tags}},be=[...t.hosts];for(let _ of[o.host,a.host,i?.host])_&&!be.includes(_)&&be.push(_);return{capability:Fe,hosts:be}}function Vn(e,t){let s=t.flow,n=t.scopePolicy;if(!s||!n)return null;let r=t.token[0]?.inject??"form";return{id:e,name:t.label,...t.description===void 0?{}:{description:t.description},docs:t.console,...t.reference===void 0?{}:{api:t.reference},hosts:[...t.api],auth:{kind:"oauth2-user",authorizeUrl:t.authorize.url,tokenUrl:s.tokenUrl,...s.revokeUrl===void 0?{}:{revokeUrl:s.revokeUrl},...s.revokeMethod===void 0?{}:{revokeMethod:s.revokeMethod},clientId:t.secrets.clientId,...t.secrets.clientSecret===void 0?{}:{clientSecret:t.secrets.clientSecret},inject:r,pkce:s.pkce,scopeDialect:s.scopeDialect,...s.authorizeParams===void 0?{}:{authorizeParams:{...s.authorizeParams}},...s.tokenHeaders===void 0?{}:{tokenHeaders:{...s.tokenHeaders}},...s.identity===void 0?{}:{identity:{...s.identity}}},scopeSets:Object.fromEntries(Object.entries(n.sets).map(([o,a])=>[o,{label:a.label,access:a.access,scopes:[...a.scopes],...a.userScopes===void 0?{}:{userScopes:[...a.userScopes]},...a.routes.length===0?{}:{routes:a.routes.map(i=>({host:i.host,paths:[...i.paths],...i.posts===void 0?{}:{posts:i.posts.map(d=>d.source.replace(/\\\//g,"/"))}}))}}])),...n.alwaysRequested.length===0?{}:{alwaysRequested:[...n.alwaysRequested]},...n.tolerated.length===0?{}:{tolerated:[...n.tolerated]},access:[...t.access],...t.readMethods===void 0?{}:{readMethods:[...t.readMethods]},...t.writeMethods===void 0?{}:{writeMethods:[...t.writeMethods]},...t.hint===void 0?{}:{hint:t.hint},...t.example===void 0?{}:{example:t.example},...t.tags===void 0?{}:{tags:[...t.tags]}}}var Jt=/^[a-z][a-z0-9-]{1,39}$/,Pi=/^[A-Z][A-Z0-9_]{2,63}$/,xi=/^(?=.{1,253}$)(?!-)[a-z0-9-]{1,63}(?<!-)(?:\.(?!-)[a-z0-9-]{1,63}(?<!-))+$/,qt=["GET","HEAD","POST","PUT","PATCH","DELETE"],Ri=/^[a-z0-9_-]{1,64}$/,Oi=/^[A-Za-z0-9-]{1,64}$/,Ci=/^[A-Za-z0-9_.-]{1,64}$/,Ni=/^[A-Za-z][A-Za-z0-9-]{0,31}$/,$i=/^[A-Za-z_][A-Za-z0-9_]{0,63}(?:\.[A-Za-z_][A-Za-z0-9_]{0,63}){0,3}$/,Di=/^\d{4}-\d{2}-\d{2}$/,Li=/^[a-z][a-z0-9-]{0,31}$/,Mi=/[\p{Cc}\p{Cf}]/u,Gi=new Set(["host","cookie","content-length","content-type","transfer-encoding","connection","upgrade","te","trailer","keep-alive","proxy-authorization","proxy-authenticate","forwarded","x-forwarded-for","x-forwarded-host","x-forwarded-proto"]),Ui=20,qn=50,ji=new Set(["id","mode","name","description","docs","api","hosts","hostSetting","data","auth","secrets","access","readMethods","writeMethods","accountWidePaths","hint","smoke","cost","rate","example","verified","tags","scopeSets","alwaysRequested","tolerated"]),zi=["hostSetting","data","secrets","accountWidePaths","smoke","cost","rate","verified"],Ki=["scopeSets","alwaysRequested","tolerated"];function K(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function I(e,t,s,{max:n,min:r=1}){if(e!==void 0){if(typeof e!="string"){s.push({path:t,message:"must be a string"});return}if(e.length<r||e.length>n){s.push({path:t,message:`must be ${r} to ${n} characters`});return}if(Mi.test(e)){s.push({path:t,message:"holds a control character"});return}return e}}function Jn(e,t,s){let n=I(e,t,s,{max:500});if(n===void 0)return;let r;try{r=new URL(n)}catch{s.push({path:t,message:"must be an https URL"});return}if(r.protocol!=="https:"){s.push({path:t,message:"must be an https URL"});return}return n}function it(e,t,s,{max:n,each:r}){if(e===void 0)return;if(!Array.isArray(e)){s.push({path:t,message:"must be a list"});return}if(e.length>n){s.push({path:t,message:`at most ${n} entries`});return}let o=[];return e.forEach((a,i)=>{if(typeof a!="string"){s.push({path:`${t}.${i}`,message:"must be a string"});return}r(a,`${t}.${i}`),o.push(a)}),new Set(o).size!==o.length&&s.push({path:t,message:"lists an entry twice"}),o}function Xn(e,t,s){return it(e,t,s,{max:qt.length,each:(n,r)=>{qt.includes(n)||s.push({path:r,message:`must be one of ${qt.join(", ")}`})}})}function at(e,t,s){if(typeof e!="string"||!Pi.test(e)){s.push({path:t,message:"must name a Gateway setting: upper case letters, digits and underscores, a letter first, 3 to 64 characters (STRIPE_API_KEY)"});return}return e}function Hi(e,t){if(!K(e)){t.push({path:"auth",message:"must be an object with a kind: bearer, header, query or basic"});return}let s=e.kind,n=at(e.secret,"auth.secret",t),r=o=>{for(let a of Object.keys(e))o.includes(a)||t.push({path:`auth.${a}`,message:`not a field of auth.kind ${String(s)}`})};switch(s){case"bearer":{r(["kind","secret","scheme"]);let o=I(e.scheme,"auth.scheme",t,{max:32});return o!==void 0&&!Ni.test(o)&&t.push({path:"auth.scheme",message:"must be a token such as Bearer, Token or Api-Key"}),n?{kind:s,secret:n,...o===void 0?{}:{scheme:o}}:void 0}case"header":{r(["kind","secret","header","prefix"]);let o=I(e.header,"auth.header",t,{max:64});o!==void 0&&(Oi.test(o)?(Gi.has(o.toLowerCase())||o.toLowerCase().startsWith("x-everyapp-"))&&t.push({path:"auth.header",message:`${o} is a header the Gateway sets or strips itself`}):t.push({path:"auth.header",message:"must be a header name (letters, digits, hyphens)"}));let a=I(e.prefix,"auth.prefix",t,{max:32,min:0});return!n||o===void 0?void 0:{kind:s,secret:n,header:o,...a===void 0?{}:{prefix:a}}}case"query":{r(["kind","secret","param"]);let o=I(e.param,"auth.param",t,{max:64});return o!==void 0&&!Ci.test(o)&&t.push({path:"auth.param",message:"must be a query parameter name"}),!n||o===void 0?void 0:{kind:s,secret:n,param:o}}case"basic":{r(["kind","secret","as","user"]);let o=e.as;if(o!=="password"&&o!=="username"&&o!=="pair"){t.push({path:"auth.as",message:'must say where the key goes: "password" (beside user), "username" (with an empty password), or "pair" (the key is login:password)'});return}if(o!=="password")return e.user!==void 0&&t.push({path:"auth.user",message:`not a field of auth.as ${o}`}),n?{kind:s,secret:n,as:o}:void 0;let a=e.user,i;if(typeof a=="string"){let d=I(a,"auth.user",t,{max:128});d!==void 0&&d.includes(":")&&t.push({path:"auth.user",message:"may not hold a colon"}),i=d}else if(K(a)&&Object.keys(a).join()==="secret"){let d=at(a.secret,"auth.user.secret",t);d!==void 0&&d===n&&t.push({path:"auth.user.secret",message:"must be another setting than auth.secret"}),i=d===void 0?void 0:{secret:d}}else t.push({path:"auth.user",message:"required with as: password: a string, or { secret: NAME }"});return!n||i===void 0?void 0:{kind:s,secret:n,as:o,user:i}}default:t.push({path:"auth.kind",message:"must be bearer, header, query, basic or oauth2-user (an AI provider is a catalog entry, not a spec this gateway takes)"});return}}function Wi(e,t,s){if(e===void 0)return;if(!Array.isArray(e)){s.push({path:"secrets",message:"must be a list"});return}let n=[];return e.forEach((r,o)=>{let a=`secrets.${o}`;if(!K(r)){s.push({path:a,message:"must be an object"});return}for(let p of Object.keys(r))["name","hint"].includes(p)||s.push({path:`${a}.${p}`,message:"unknown field"});let i=at(r.name,`${a}.name`,s);i!==void 0&&!t.includes(i)&&s.push({path:`${a}.name`,message:`auth names no setting ${i}`});let d=I(r.hint,`${a}.hint`,s,{max:300});i!==void 0&&n.push({name:i,...d===void 0?{}:{hint:d}})}),new Set(n.map(r=>r.name)).size!==n.length&&s.push({path:"secrets",message:"names a setting twice"}),n}function Bi(e,t){if(e===void 0)return;if(!Array.isArray(e)){t.push({path:"accountWidePaths",message:'must be a list of segment runs: [["v1", "account"]]'});return}if(e.length>qn){t.push({path:"accountWidePaths",message:`at most ${qn} entries`});return}let s=[];return e.forEach((n,r)=>{let o=`accountWidePaths.${r}`;if(!Array.isArray(n)||n.length===0){t.push({path:o,message:"must be a non-empty list of segments"});return}let a=[];n.forEach((i,d)=>{if(typeof i!="string"||!Ri.test(i)){t.push({path:`${o}.${d}`,message:"must be a lowercase path segment (letters, digits, _ and -)"});return}a.push(i)}),a.length===n.length&&s.push(a)}),s}function Fi(e,t,s){if(e===void 0)return;if(!K(e)){s.push({path:"smoke",message:"must be an object"});return}for(let u of Object.keys(e))["method","host","path","expect","free","note"].includes(u)||s.push({path:`smoke.${u}`,message:"unknown field"});let n=e.method;n!=="GET"&&n!=="HEAD"&&n!=="POST"&&s.push({path:"smoke.method",message:"must be GET, HEAD or POST"});let r=I(e.host,"smoke.host",s,{max:253});r!==void 0&&!t.includes(r)&&s.push({path:"smoke.host",message:"must be one of hosts"});let o=I(e.path,"smoke.path",s,{max:500});o!==void 0&&(!o.startsWith("/")||o.startsWith("//"))&&s.push({path:"smoke.path",message:"must start with one /"});let a=e.expect,i=Array.isArray(a)&&a.length>0&&a.every(u=>Number.isInteger(u)&&u>=100&&u<=599)?a:void 0;i||s.push({path:"smoke.expect",message:"must list the HTTP statuses that mean the key works"});let d=e.free;typeof d!="boolean"&&s.push({path:"smoke.free",message:"must be true or false"});let p=I(e.note,"smoke.note",s,{max:200});if(!(n!=="GET"&&n!=="HEAD"&&n!=="POST"||o===void 0||!i||typeof d!="boolean"))return{method:n,...r===void 0?{}:{host:r},path:o,expect:i,free:d,...p===void 0?{}:{note:p}}}function ot(e,t,s){if(e!==void 0){if(typeof e!="number"||!Number.isFinite(e)||e<0){s.push({path:t,message:"must be a number, zero or more"});return}return e}}function Yi(e,t){if(e===void 0)return;if(!K(e)){t.push({path:"cost",message:"must be an object"});return}for(let a of Object.keys(e))["unit","usd","note","responseField"].includes(a)||t.push({path:`cost.${a}`,message:"unknown field"});let s=e.unit;s!=="call"&&s!=="result"&&s!=="token"&&t.push({path:"cost.unit",message:"must be call, result or token"});let n=ot(e.usd,"cost.usd",t),r=I(e.note,"cost.note",t,{max:200}),o=I(e.responseField,"cost.responseField",t,{max:128});if(o!==void 0&&!$i.test(o)&&t.push({path:"cost.responseField",message:"must be a JSON field name, or a dotted path to a nested one"}),!(s!=="call"&&s!=="result"&&s!=="token"))return{unit:s,...n===void 0?{}:{usd:n},...r===void 0?{}:{note:r},...o===void 0?{}:{responseField:o}}}function Vi(e,t){if(e===void 0)return;if(!K(e)){t.push({path:"rate",message:"must be an object"});return}for(let a of Object.keys(e))["perSecond","perMinute","perDay","note"].includes(a)||t.push({path:`rate.${a}`,message:"unknown field"});let s=ot(e.perSecond,"rate.perSecond",t),n=ot(e.perMinute,"rate.perMinute",t),r=ot(e.perDay,"rate.perDay",t),o=I(e.note,"rate.note",t,{max:200});return{...s===void 0?{}:{perSecond:s},...n===void 0?{}:{perMinute:n},...r===void 0?{}:{perDay:r},...o===void 0?{}:{note:o}}}function qi(e,t){if(e!==void 0){if(e===!1)return!1;if(K(e)&&typeof e.on=="string"&&Di.test(e.on)&&(e.how==="docs"||e.how==="live")&&Object.keys(e).length===2)return{on:e.on,how:e.how};t.push({path:"verified",message:'must be false, or { "on": "YYYY-MM-DD", "how": "docs" | "live" }'})}}function Zn(e,t){let s=it(e.access,"access",t,{max:2,each:(o,a)=>{o!=="read"&&o!=="write"&&t.push({path:a,message:"must be read or write"})}});s&&s.length===0&&t.push({path:"access",message:"must list read, write or both"});let n=Xn(e.readMethods,"readMethods",t);n&&n.length===0&&(!Array.isArray(s)||s.includes("read"))&&t.push({path:"readMethods",message:"must list a method unless access is write alone"});let r=Xn(e.writeMethods,"writeMethods",t);return{access:s,readMethods:n,writeMethods:r}}function Qn(e,t){return it(e,"tags",t,{max:10,each:(s,n)=>{Li.test(s)||t.push({path:n,message:"must be a lowercase word"})}})}function Ie(e){let t=[];if(!K(e))return{ok:!1,problems:[{path:"(root)",message:"must be a JSON object"}]};for(let _ of Object.keys(e))ji.has(_)||t.push({path:_,message:"unknown field"});let s=e.id;(typeof s!="string"||!Jt.test(s))&&t.push({path:"id",message:"must be lowercase letters, digits and hyphens, a letter first, 2 to 40 characters (stripe)"});let n=K(e.auth)&&e.auth.kind==="oauth2-user",r=n?"oauth_client":"api_key";e.mode!==void 0&&e.mode!==r&&t.push({path:"mode",message:n?"an oauth2-user spec's mode is oauth_client (or left out)":"this gateway registers api_key and oauth_client (auth.kind oauth2-user) providers; an AI provider is a catalog entry"});let o=I(e.name,"name",t,{max:64});e.name===void 0&&t.push({path:"name",message:"required"});let a=I(e.description,"description",t,{max:200}),i=Jn(e.docs,"docs",t);e.docs===void 0&&t.push({path:"docs",message:"required: where the person gets the key, an https URL"});let d=Jn(e.api,"api",t),p=it(e.hosts,"hosts",t,{max:Ui,each:(_,O)=>{xi.test(_)||t.push({path:O,message:"must be a bare lowercase host with a dot and no port, path or scheme (api.stripe.com)"})}});if(n){let{access:_,readMethods:O,writeMethods:Ye}=Zn(e,t),Xs=I(e.hint,"hint",t,{max:500}),Zs=I(e.example,"example",t,{max:200}),Qs=Qn(e.tags,t);for(let tn of zi)e[tn]!==void 0&&t.push({path:tn,message:"not a field of an oauth2-user spec"});(e.hosts===void 0||p&&p.length===0)&&t.push({path:"hosts",message:"required: at least one API host the token is sent to"});let en=typeof s=="string"&&o!==void 0&&i!==void 0&&p!==void 0?Yn(e,{id:s,name:o,docs:i,hosts:p,...a===void 0?{}:{description:a},...d===void 0?{}:{reference:d},..._===void 0?{}:{access:_},...O===void 0?{}:{readMethods:O},...Ye===void 0?{}:{writeMethods:Ye},...Xs===void 0?{}:{hint:Xs},...Zs===void 0?{}:{example:Zs},...Qs===void 0?{}:{tags:Qs}},t):void 0;return t.length>0||!en||typeof s!="string"?{ok:!1,problems:t}:{ok:!0,id:s,capability:en.capability}}for(let _ of Ki)e[_]!==void 0&&t.push({path:_,message:"only an oauth2-user spec has it"});let u=e.hostSetting===void 0?void 0:at(e.hostSetting,"hostSetting",t);u===void 0&&(e.hosts===void 0||p&&p.length===0)&&t.push({path:"hosts",message:"required: at least one host, or a hostSetting naming one"});let h=e.data;h!==void 0&&h!=="per-call"&&h!=="account"&&t.push({path:"data",message:"must be per-call or account"});let w=h==="per-call"||h==="account"?h:void 0,f=Hi(e.auth,t);e.auth===void 0&&t.push({path:"auth",message:"required"}),u!==void 0&&f&&oe(f).includes(u)&&t.push({path:"hostSetting",message:"must be another setting than the key"});let l=Wi(e.secrets,[...f?oe(f):[],...u===void 0?[]:[u]],t),{access:A,readMethods:E,writeMethods:b}=Zn(e,t),S=Bi(e.accountWidePaths,t),U=I(e.hint,"hint",t,{max:500}),te=Fi(e.smoke,p??[],t),se=Yi(e.cost,t),He=Vi(e.rate,t),We=I(e.example,"example",t,{max:200}),Be=qi(e.verified,t),Fe=Qn(e.tags,t);if(t.length>0||typeof s!="string"||o===void 0||i===void 0||!p&&u===void 0||!f)return{ok:!1,problems:t};let be={mode:"api_key",label:o,auth:f,docs:i,hosts:p??[],...u===void 0?{}:{hostSetting:u},...w===void 0?{}:{data:w},access:A??["read"],readMethods:E??["GET","HEAD"],accountWidePaths:S??[],...a===void 0?{}:{description:a},...d===void 0?{}:{api:d},...l===void 0?{}:{secrets:l},...b===void 0?{}:{writeMethods:b},...U===void 0?{}:{hint:U},...te===void 0?{}:{smoke:te},...se===void 0?{}:{cost:se},...He===void 0?{}:{rate:He},...We===void 0?{}:{example:We},...Be===void 0?{}:{verified:Be},...Fe===void 0?{}:{tags:Fe}};return{ok:!0,id:s,capability:be}}function Xt(e){return e.map(t=>`${t.path}: ${t.message}`).join("; ")}function lh(e,t){if(t.mode==="oauth_client"){let s=Vn(e,t);if(!s)throw new Error(`${e} is a catalog OAuth client without a Gateway-owned flow: it has no spec`);return s}return{id:e,name:t.label,...t.description===void 0?{}:{description:t.description},docs:t.docs,...t.api===void 0?{}:{api:t.api},hosts:[...t.hosts],...t.hostSetting===void 0?{}:{hostSetting:t.hostSetting},...t.data===void 0?{}:{data:t.data},auth:{...t.auth},...t.secrets===void 0?{}:{secrets:t.secrets.map(s=>({...s}))},access:[...t.access],readMethods:[...t.readMethods],...t.writeMethods===void 0?{}:{writeMethods:[...t.writeMethods]},accountWidePaths:t.accountWidePaths.map(s=>[...s]),...t.hint===void 0?{}:{hint:t.hint},...t.smoke===void 0?{}:{smoke:{...t.smoke,expect:[...t.smoke.expect]}},...t.cost===void 0?{}:{cost:{...t.cost}},...t.rate===void 0?{}:{rate:{...t.rate}},...t.example===void 0?{}:{example:t.example},...t.verified===void 0?{}:{verified:t.verified},...t.tags===void 0?{}:{tags:[...t.tags]}}}var m=(e,t,s,n=1)=>({type:t,version:n,description:s,group:e}),Qt=[m("member","member.invited","Someone was invited to the workspace"),m("member","member.joined","Someone joined the workspace"),m("member","member.role_changed","A member's role changed"),m("member","member.deactivated","A member was deactivated"),m("member","member.reactivated","A member was reactivated"),m("member","member.removed","A member was removed"),m("member","member.password_reset","A member reset their password"),m("member","member.invitation_cancelled","A pending invitation was cancelled"),m("organization","organization.renamed","The workspace was renamed"),m("app","app.installed","An app was installed on the Gateway"),m("app","app.updated","An app was redeployed"),m("app","app.live","An app went live on the Gateway"),m("app","app.removed","An app was removed from the Gateway"),m("app","app.needs_setup","An app needs a setting before it opens"),m("app","app.ready","An app has every setting it needs"),m("app","app.paused_cap","An app is paused: its monthly cap is reached"),m("app","app.tools_changed","An app's AI tools changed"),m("app","app.renamed","An app's name or description changed"),m("app","app.settings_changed","An app's settings were set or unset (names only)"),m("app","app.access_changed","Who can open an app changed"),m("app","app.email_changed","An app's email senders or inbound changed"),m("cap","cap.warning","An app is at 80% of its monthly cap"),m("cap","cap.reached","An app reached its monthly cap"),m("cap","cap.raised","An app's monthly cap, or the workspace default, was raised or removed"),m("cap","cap.changed","An app's monthly cap, or the workspace default, was set or lowered"),m("group","group.created","A group was created"),m("group","group.updated","A group was renamed or described"),m("group","group.removed","A group was removed"),m("group","group.members_changed","A group's members changed"),m("group","group.apps_changed","The apps a group opens changed"),m("tool","tool.blocked","An AI client's tool call was blocked"),m("tool","tool.error","An AI client's tool call failed"),m("connection","connection.created","An AI app was connected"),m("connection","connection.revoked","An AI app connection was revoked"),m("token","token.created","A personal access token was created"),m("token","token.revoked","A personal access token was revoked"),m("access","access.changed","Cloudflare Access was turned on or off"),m("signin_provider","signin_provider.added","A sign-in provider (Continue with Google, \u2026) was turned on"),m("signin_provider","signin_provider.removed","A sign-in provider was turned off"),m("mcp_app","mcp_app.added","An MCP app was added"),m("mcp_app","mcp_app.removed","An MCP app was removed"),m("mcp_app","mcp_app.enabled","An MCP app is being served again"),m("mcp_app","mcp_app.disabled","An MCP app stopped being served"),m("mcp_app","mcp_app.updated","An MCP app's risk default, name or description changed"),m("mcp_app","mcp_app.tool_changed","One tool of an MCP app was overridden: its risk, or on/off"),m("provider","provider.added","A provider was registered"),m("provider","provider.removed","A provider was removed"),m("provider","provider.updated","A provider's spec or OAuth client was replaced"),m("provider","provider.connected","Someone connected an account at an OAuth provider"),m("provider","provider.disconnected","An OAuth provider account was disconnected"),m("provider","provider.connection_expired","An OAuth provider refused to refresh a connection; it needs reconnecting"),m("subscription","subscription.created","An event subscription was added"),m("subscription","subscription.updated","An event subscription was changed, paused or resumed"),m("subscription","subscription.removed","An event subscription was removed"),m("subscription","subscription.redelivered","A delivery was queued again by hand"),m("ai","ai.default_changed","The default model provider changed"),m("ping","ping","A test event, sent to one subscription on request")],es=new Map(Qt.map(e=>[e.type,e]));function er(e){return es.get(e)}var de="app.";var Ji=64;function ct(e){return e.startsWith(de)&&!es.has(e)&&e.slice(de.length).includes(".")}var Xi=8*1024,mh=16*1024,tr=8;var fh=25,gh=16,yh=128,wh=30;var Eh=200,bh=2048,_h=100,Zi=[6e4,3e5,18e5,72e5,288e5,864e5],Ah=Zi.length+1;var kh="EVENTS_ALLOW_PRIVATE_TARGETS",Qi=["localhost","local","localdomain","internal","intranet","lan","corp","private","home.arpa","onion"];function Sh(e){return e.includes(".")?Qi.some(t=>e===t||e.endsWith(`.${t}`)):!0}var vh=["owners","admins"];function sr(e,t){return e==="*"?t!=="ping"&&!t.startsWith("subscription."):e.endsWith(".*")?t.startsWith(e.slice(0,-1)):e===t}function Ih(e,t){return e.some(s=>sr(s,t))}var ec=/^(\*|[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*(\.\*)?)$/;function Th(e){if(!ec.test(e)||e.length>Ji+8)return`"${e}" isn't an event type or pattern (member.joined, member.*, app.crm.*, *)`;if(e==="*"||es.has(e))return null;if(e.endsWith(".*")){let t=e.slice(0,-1);return Qt.some(s=>s.type.startsWith(t))||e.startsWith(de)?null:`"${e}" matches no event type (everyapp events types lists them)`}return ct(e)?null:`"${e}" isn't an event type (everyapp events types lists them)`}var tc=/secret|token|password|passwd|authorization|api[_-]?key|private[_-]?key|credential|cookie|session/i;function Zt(e,t){if(t>tr)return"\0depth";if(Array.isArray(e)){for(let s of e){let n=Zt(s,t+1);if(n)return n}return null}if(e&&typeof e=="object")for(let[s,n]of Object.entries(e)){if(tc.test(s))return s;let r=Zt(n,t+1);if(r)return r}return null}function Ph(e,t=Xi){if(e===null||typeof e!="object"||Array.isArray(e))return{ok:!1,code:"event_data_invalid",message:"data is a JSON object"};let s;try{s=JSON.stringify(e)}catch{return{ok:!1,code:"event_data_invalid",message:"data must serialize as JSON"}}if(s===void 0)return{ok:!1,code:"event_data_invalid",message:"data is a JSON object"};let n=new TextEncoder().encode(s).length;if(n>t)return{ok:!1,code:"event_data_too_large",message:`data is at most ${t.toLocaleString("en-US")} bytes as JSON (this is ${n.toLocaleString("en-US")})`,bytes:n};let r=Zt(JSON.parse(s),1);return r==="\0depth"?{ok:!1,code:"event_data_invalid",message:`data nests at most ${tr} levels deep`}:r?{ok:!1,code:"event_data_refused",message:`data must not carry a credential: the key "${r}" reads like one (secret, token, password, authorization, api key, private key, credential, cookie, session)`,key:r}:{ok:!0,bytes:n}}function Y(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function T(e){return typeof e=="string"&&e.length>0?e:null}function dt(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function Oh(e){let t=e;if(typeof e=="string")try{t=JSON.parse(e)}catch{t={}}let s=Y(t);return{kind:T(s.kind)??"gateway",id:T(s.id),email:T(s.email),name:T(s.name)}}function Ch(e){switch(e.kind){case"user":return e.name??e.email??e.id??"a member";case"agent":return`agent \xB7 ${e.name??e.id??"AI app"}`;case"operator":return`CLI \xB7 ${e.email??e.id??"operator"}`;case"app":return`app \xB7 ${e.id??"app"}`;case"gateway":return"Gateway";default:return e.name??e.email??e.id??e.kind}}function Nh(e){let t=er(e);if(t)return t.description;if(ct(e)){let s=e.slice(de.length);return`App event: ${s.slice(s.indexOf(".")+1)}`}return e}function pt(e){let t=Y(e),s=T(t.id)??T(t.rowId);return s?{id:s,name:T(t.name)}:void 0}function $h(e,t){let s=Y(t),n={},r=pt(s.app);if(r)e.startsWith("mcp_app.")?n.mcpApp=r:n.app=r;else if(ct(e)){let f=e.slice(de.length);n.app={id:f.slice(0,f.indexOf(".")),name:null}}let o=Y(s.user);T(o.id)&&(n.user={id:T(o.id),email:T(o.email),name:T(o.name)});let a=pt(s.group);a&&(n.group=a);let i=pt(s.provider);i&&(n.provider=i);let d=pt(s.subscription);d&&(n.subscription=d);let p=Y(s.invitation);T(p.email)&&(n.invitation={email:T(p.email),role:T(p.role)});let u=[...dt(s.settings),...dt(s.unmet),...dt(s.changed),...dt(s.names)];u.length>0&&(n.settings=[...new Set(u)]);let h=T(s.tool);h&&(n.tool=h);let w=T(Y(s.client).name)??T(Y(s.connection).clientName);return w&&(n.client=w),e.startsWith("token.")&&T(s.name)&&(n.token=T(s.name)),n}function Dh(e){let t=[],s=e.app??e.mcpApp;return s&&t.push(s.name??s.id),e.user&&t.push(e.user.name??e.user.email??e.user.id),e.invitation&&t.push(e.invitation.email),e.group&&t.push(e.group.name??e.group.id),e.provider&&t.push(e.provider.name??e.provider.id),e.subscription&&t.push(e.subscription.name??e.subscription.id),e.token&&t.push(e.token),e.tool&&t.push(e.tool),e.client&&t.push(e.client),e.settings&&t.push(e.settings.join(", ")),t.join(" \xB7 ")}function Lh(e){return e==="*"?null:e.endsWith(".*")?{op:"prefix",value:e.slice(0,-1)}:{op:"eq",value:e}}var sc=".everyapp/providers";function Uh(e){return`${sc}/${e}.json`}var V=new TextEncoder,nr=new TextDecoder,nc=new TextDecoder("utf-8",{fatal:!0}),zh=2**32;function rr(...e){let t=e.reduce((r,{length:o})=>r+o,0),s=new Uint8Array(t),n=0;for(let r of e)s.set(r,n),n+=r.length;return s}var rc=/[^\x00-\x7f]/;function ut(e){if(typeof e=="string"&&e.length>=128){if(rc.test(e))throw new TypeError("non-ASCII string encountered in encode()");return V.encode(e)}let t=new Uint8Array(e.length);for(let s=0;s<e.length;s++){let n=e.charCodeAt(s);if(n>127)throw new TypeError("non-ASCII string encountered in encode()");t[s]=n}return t}function ts(e,t=!1){if(Uint8Array.prototype.toBase64)return e.toBase64({alphabet:t?"base64url":"base64",omitPadding:t});let s=32768,n=[];for(let o=0;o<e.length;o+=s)n.push(String.fromCharCode.apply(null,e.subarray(o,o+s)));let r=btoa(n.join(""));return t?r.replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_"):r}function lt(e,t=!1){if(Uint8Array.fromBase64)return Uint8Array.fromBase64(e,{alphabet:t?"base64url":"base64"});if(t){if(e.includes("+")||e.includes("/"))throw new TypeError("Invalid base64url");e=e.replace(/-/g,"+").replace(/_/g,"/")}let s=atob(e),n=new Uint8Array(s.length);for(let r=0;r<s.length;r++)n[r]=s.charCodeAt(r);return n}var q=class extends Error{code="ERR_JOSE_GENERIC";constructor(t,s){super(t,s),this.name=this.constructor.name,Error.captureStackTrace?.(this,this.constructor)}};ne(q,"code","ERR_JOSE_GENERIC");var C=class extends q{code="ERR_JOSE_NOT_SUPPORTED"};ne(C,"code","ERR_JOSE_NOT_SUPPORTED");var D=class extends q{code="ERR_JWS_INVALID"};ne(D,"code","ERR_JWS_INVALID");var Te=class extends q{code="ERR_JWT_INVALID"};ne(Te,"code","ERR_JWT_INVALID");var ss=class extends q{[Symbol.asyncIterator]=async function*(){};code="ERR_JWKS_MULTIPLE_MATCHING_KEYS";constructor(t="multiple matching keys found in the JSON Web Key Set",s){super(t,s)}};ne(ss,"code","ERR_JWKS_MULTIPLE_MATCHING_KEYS");var oc="The input to be decoded is not correctly encoded.";function or(e){try{return lt(typeof e=="string"?e:nr.decode(e),!0)}catch(t){throw new TypeError(oc,{cause:t})}}function Pe(e){return ts(typeof e=="string"?V.encode(e):e,!0)}function xe(e){if(typeof e!="object"||e===null||Object.prototype.toString.call(e)!=="[object Object]")return!1;let t=Object.getPrototypeOf(e);return t===null||Object.getPrototypeOf(t)===null}function ar(...e){let t=new Set;for(let s of e)if(s)for(let n of Object.keys(s)){if(t.has(n))return!1;t.add(n)}return!0}function ir(e,t){if(e!==void 0)throw new TypeError(`${t} can only be called once`)}var cr={__proto__:null,b64:!0};function dr(e,t){let{crit:s}=t??{};if(Array.isArray(s)&&new Set(s).size!==s.length)throw new e('"crit" (Critical) Header Parameter MUST NOT contain duplicate values')}function pr(e,t,s,n,r){if(r.crit!==void 0&&n?.crit===void 0)throw new e('"crit" (Critical) Header Parameter MUST be integrity protected');if(!n||n.crit===void 0)return[];if(!Array.isArray(n.crit)||n.crit.length===0||n.crit.some(a=>typeof a!="string"||a.length===0))throw new e('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');let o=s===void 0?t:{__proto__:null,...s,...t};for(let a of n.crit){if(!(a in o))throw new C(`Extension Header Parameter "${a}" is not recognized`);if(!Object.hasOwn(r,a)||r[a]===void 0)throw new e(`Extension Header Parameter "${a}" is missing`);if(o[a]&&(!Object.hasOwn(n,a)||n[a]===void 0))throw new e(`Extension Header Parameter "${a}" MUST be integrity protected`)}return n.crit}function ur(e,t){if(t.includes("b64")){let s=e.b64;if(typeof s!="boolean")throw new D('The "b64" (base64url-encode payload) Header Parameter must be a boolean');return s}return!0}function ns(e,t){let s,n;try{s=JSON.stringify(t),n=JSON.parse(s)}catch(r){throw new e("JOSE Header is not valid JSON",{cause:r})}if(!xe(n))throw new e("JOSE Header is not a JSON object");return[n,s]}var ac=e=>e[Symbol.toStringTag],ic=(e,t,s)=>{let{alg:n}=e;if(t.use!==void 0){let r=s==="sign"||s==="verify"?"sig":"enc";if(t.use!==r)throw new TypeError(`Invalid key for this operation, its "use" must be "${r}" when present`)}if(t.alg!==void 0&&t.alg!==n)throw new TypeError(`Invalid key for this operation, its "alg" must be "${n}" when present`);if(Array.isArray(t.key_ops)){let r=s==="encrypt"||s==="decrypt"?e.ops?.[s==="encrypt"?0:1]:s;if(r&&!t.key_ops.includes(r))throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${r}" when present`)}};async function hr(e,t,s){let{alg:n,secret:r}=e,o=s==="decrypt"||s==="sign";if(r&&t instanceof Uint8Array)return t;let a,i;if(xe(t)){if(a=mc(t),typeof a.kty!="string")throw lr(n,t,r);if(!(r?a.kty==="oct"&&typeof a.k=="string":a.kty!=="oct"&&(o?a.kty==="AKP"&&typeof a.priv=="string"||typeof a.d=="string":a.d===void 0&&a.priv===void 0)))throw new TypeError(r?'JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present':`JSON Web Key for this operation must be a ${o?"private":"public"} JWK`);if(ic(e,a,s),a.kty==="oct")return or(a.k);if(!Object.isFrozen(t)){let{key_ops:u}=t;Array.isArray(u)&&Object.freeze(u),Object.freeze(t)}}else{if(!dc(t))throw lr(n,t,r);let u=r?"secret":o?"private":"public";if(t.type!==u&&(r||["secret","public","private"].includes(t.type)))throw new TypeError(`${ac(t)} instances must be of type "${u}" for the ${n} algorithm`);if(os(t))return t;if(i=t,i.type==="secret")return i.export()}rs||=new WeakMap;let d=t,p=rs.get(d);if(p?.[n])return p[n];if(p||rs.set(d,p={}),i&&typeof i.toCryptoKey=="function"){let u=i.type==="public",h=cc[i.asymmetricKeyDetails?.namedCurve],w=e.resolve?.({crv:h,asymmetricKeyType:i.asymmetricKeyType})??e.subtle;return p[n]=i.toCryptoKey(w,u,e.usages[u?0:1])}return a??=i.export({format:"jwk"}),a.alg=n,p[n]=await fc(e,a)}var rs,cc={__proto__:null,prime256v1:"P-256",secp384r1:"P-384",secp521r1:"P-521"};var os=e=>{if(e?.[Symbol.toStringTag]==="CryptoKey")return!0;try{return e instanceof CryptoKey}catch{return!1}},mr=e=>e?.[Symbol.toStringTag]==="KeyObject",dc=e=>os(e)||mr(e);function pc(e,t,...s){if(s.length>2){let n=s.pop();e+=`one of type ${s.join(", ")}, or ${n}.`}else s.length===2?e+=`one of type ${s[0]} or ${s[1]}.`:e+=`of type ${s[0]}.`;return t==null?e+=` Received ${t}`:typeof t=="function"&&t.name?e+=` Received function ${t.name}`:typeof t=="object"&&t!=null&&t.constructor?.name&&(e+=` Received an instance of ${t.constructor.name}`),e}function lr(e,t,s){let n=["CryptoKey","KeyObject","JSON Web Key"];return s&&n.push("Uint8Array"),new TypeError(pc(`Key for the ${e} algorithm must be `,t,...n))}var ht=(e,t="algorithm.name")=>new TypeError(`CryptoKey does not support this operation, its ${t} must be ${e}`);function uc(e,t){if(t&&!e.usages.includes(t))throw new TypeError(`CryptoKey does not support this operation, its usages must include ${t}.`)}function fr(e,t){let{modulusLength:s}=t.algorithm;if(typeof s!="number"||s<2048)throw new TypeError(`${e} requires key modulusLength to be 2048 bits or larger`)}function lc(e,t,s){let n=e.algorithm;if(n.name!==t.name)throw ht(t.name);if(t.hash&&n.hash?.name!==t.hash)throw ht(t.hash,"algorithm.hash");if(t.namedCurve&&n.namedCurve!==t.namedCurve)throw ht(t.namedCurve,"algorithm.namedCurve");if(t.length!==void 0&&n.length!==t.length)throw ht(t.length,"algorithm.length");uc(e,s)}function hc(e){return{__proto__:null,...e}}function mc(e){let t=hc(e);if(t.ext!==void 0&&typeof t.ext!="boolean")throw new TypeError('"ext" (Extractable) Parameter must be a boolean');if(t.key_ops!==void 0){let s=t.key_ops,n=Array.isArray(s)?[...s]:void 0;if(!n||n.some(r=>typeof r!="string")||new Set(n).size!==n.length)throw new TypeError('"key_ops" (Key Operations) Parameter must be an array of unique strings');t.key_ops=n}return t}function gr(e){if(e!==void 0&&typeof e!="boolean")throw new TypeError('"extractable" option must be a boolean');return e}async function fc(e,t,s){if(!e.kty.includes(t.kty))throw new C('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');let n=e.resolve?.({kty:t.kty,crv:t.crv})??e.subtle,r=!!(t.d||t.priv),o={...t,ext:s??t.ext};return o.kty!=="AKP"&&delete o.alg,delete o.use,crypto.subtle.importKey("jwk",o,n,o.ext??!r,t.key_ops??e.usages[r?1:0])}async function yr(e,t,s,n=!1){return e instanceof Uint8Array&&(e=await crypto.subtle.importKey("raw",e,t,n,[s])),lc(e,t,s),e}function Re(e){let t={__proto__:null};for(let s in e)t[s]={...e[s],alg:s};return t}var gc=[["encrypt","wrapKey"],["decrypt","unwrapKey"]],yc=[[],["deriveBits"]],gt=[[],[]];function mt(e){return{kty:["RSA"],mode:"key-encryption",subtle:{name:"RSA-OAEP",hash:`SHA-${e}`},usages:gc,ops:["wrapKey","unwrapKey"]}}function ft(e){return{kty:["EC","OKP"],mode:e,subtle:{name:"ECDH"},resolve:({kty:t,crv:s,asymmetricKeyType:n})=>{if(s==="X25519"||n==="x25519")return{name:"X25519"};if(t==="OKP")throw new C('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');return{name:"ECDH",namedCurve:s}},usages:yc,ops:[void 0,"deriveBits"]}}function pe(e,t=!1){return{kty:["oct"],mode:"key-wrapping",secret:!0,subtle:{name:t?"AES-GCM":"AES-KW",length:e},usages:gt,ops:t?["encrypt","decrypt"]:["wrapKey","unwrapKey"]}}function as(){return{kty:["oct"],mode:"key-wrapping",secret:!0,subtle:{name:"PBKDF2"},usages:gt,ops:["deriveBits","deriveBits"]}}var wr=Re({dir:{kty:["oct"],mode:"direct-encryption",secret:!0,subtle:{name:"AES-GCM"},usages:gt,ops:["encrypt","decrypt"]},"RSA-OAEP":mt(1),"RSA-OAEP-256":mt(256),"RSA-OAEP-384":mt(384),"RSA-OAEP-512":mt(512),"ECDH-ES":ft("direct-key-agreement"),"ECDH-ES+A128KW":ft("key-agreement-with-key-wrapping"),"ECDH-ES+A192KW":ft("key-agreement-with-key-wrapping"),"ECDH-ES+A256KW":ft("key-agreement-with-key-wrapping"),A128KW:pe(128),A192KW:pe(192),A256KW:pe(256),A128GCMKW:pe(128,!0),A192GCMKW:pe(192,!0),A256GCMKW:pe(256,!0),"PBES2-HS256+A128KW":as(),"PBES2-HS384+A192KW":as(),"PBES2-HS512+A256KW":as()}),wc=["encrypt","decrypt"];function ue(e,t=!1){return{kty:["oct"],secret:!0,subtle:{name:t?"AES-CBC":"AES-GCM",length:e},usages:gt,ops:wc,cekBits:e,ivBits:t?128:96,cbc:t}}var sm=Re({A128GCM:ue(128),A192GCM:ue(192),A256GCM:ue(256),"A128CBC-HS256":ue(256,!0),"A192CBC-HS384":ue(384,!0),"A256CBC-HS512":ue(512,!0)});var Oe=[["verify"],["sign"]];function is(e){let t={name:"HMAC",hash:`SHA-${e}`};return{kty:["oct"],secret:!0,subtle:t,signing:t,usages:Oe}}function le(e,t){let s={name:t?"RSA-PSS":"RSASSA-PKCS1-v1_5",hash:`SHA-${e}`};return{kty:["RSA"],subtle:s,signing:t?{...s,saltLength:t}:s,usages:Oe,minRsaBits:2048}}function cs(e,t){return{kty:["EC"],crv:e,subtle:{name:"ECDSA",namedCurve:e},signing:{name:"ECDSA",hash:`SHA-${t}`},usages:Oe}}function Er(){let e={name:"Ed25519"};return{kty:["OKP"],crv:"Ed25519",subtle:e,signing:e,usages:Oe}}function ds(e){let t={name:`ML-DSA-${e}`};return{kty:["AKP"],subtle:t,signing:t,usages:Oe}}var ps=Re({HS256:is(256),HS384:is(384),HS512:is(512),RS256:le(256),RS384:le(384),RS512:le(512),PS256:le(256,32),PS384:le(384,48),PS512:le(512,64),ES256:cs("P-256",256),ES384:cs("P-384",384),ES512:cs("P-521",512),EdDSA:Er(),Ed25519:Er(),"ML-DSA-44":ds(44),"ML-DSA-65":ds(65),"ML-DSA-87":ds(87)});function br(e){let t=typeof e=="string"?ps[e]:void 0;if(!t)throw new C(`alg ${e} is not supported either by JOSE or your javascript runtime`);return t}var yt=e=>Math.floor(e.getTime()/1e3),Ec={s:1,m:60,h:3600,d:86400,w:604800,y:31557600},bc=/^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;function us(){throw new TypeError("Invalid time period format")}function _r(e){typeof e!="string"&&us();let t=bc.exec(e);(!t||t[4]&&t[1])&&us();let s=parseFloat(t[2]),n=Math.round(s*Ec[t[3][0].toLowerCase()]);return Number.isFinite(n)||us(),t[1]==="-"||t[4]==="ago"?-n:n}function ms(e,t){if(!Number.isFinite(t))throw new TypeError(`Invalid ${e} input`);return t}function ls(e,t){if(typeof t!="string")throw new TypeError(`"${e}" claim must be a string`)}function _c(e){if(typeof e!="string"&&(!Array.isArray(e)||Array.from(e).some(t=>typeof t!="string")))throw new TypeError('"aud" claim must be a string or an array of strings')}function hs(e,t){return typeof e=="number"?ms(t,e):e instanceof Date?ms(t,yt(e)):yt(new Date)+_r(e)}var Ar;function H(e){return Ar.get(e)}function kr(e){let t=H(e);for(let s of["iat","nbf","exp"]){let n=t[s];if(typeof n=="number"&&!Number.isFinite(n))throw new TypeError(`"${s}" claim must be a finite number`)}return V.encode(JSON.stringify(t))}var wt=class{constructor(t={}){if(!xe(t))throw new TypeError("JWT Claims Set MUST be an object");(Ar||=new WeakMap).set(this,structuredClone(t))}setIssuer(t){return ls("iss",t),H(this).iss=t,this}setSubject(t){return ls("sub",t),H(this).sub=t,this}setAudience(t){return _c(t),H(this).aud=t,this}setJti(t){return ls("jti",t),H(this).jti=t,this}setNotBefore(t){return H(this).nbf=hs(t,"setNotBefore"),this}setExpirationTime(t){return H(this).exp=hs(t,"setExpirationTime"),this}setIssuedAt(t){let s=H(this);return t===void 0?s.iat=yt(new Date):typeof t=="string"?s.iat=ms("setIssuedAt",yt(new Date)+_r(t)):s.iat=hs(t,"setIssuedAt"),this}};async function Ac(e,t,s){let[n,r,o,a]=e,i="";if(r!==void 0){let b=ns(D,r);r=b[0],i=Pe(b[1])}if(o!==void 0&&(o=ns(D,o)[0]),!r&&!o)throw new D("either setProtectedHeader or setUnprotectedHeader must be called before #sign()");if(!ar(r,o))throw new D("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");let d={...r,...o};dr(D,r);let p=ur(r,pr(D,cr,a,r,d));p||s?.();let{alg:u}=d;if(typeof u!="string"||!u)throw new D('JWS "alg" (Algorithm) Header Parameter missing or invalid');let h=br(u),w="",f=n,l;if(p){let b=e[4];b?(w=b[0]??=Pe(n),f=b[1]??=ut(w)):(w=Pe(n),l=V.encode(`${i}.${w}`))}l??=rr(ut(i),ut("."),f);let A=await yr(await hr(h,t,"sign"),h.subtle,"sign");h.minRsaBits&&fr(h.alg,A);let E={signature:Pe(new Uint8Array(await crypto.subtle.sign(h.signing,A,l))),payload:w};return r&&(E.protected=i),o&&(E.header=o),[E,p]}async function Sr(e,t,s,n,r){let[o]=await Ac([e,t,void 0,s],n,r);return`${o.protected}.${o.payload}.${o.signature}`}var kc=wt,J=class extends kc{#e;setProtectedHeader(t){return ir(this.#e,"setProtectedHeader"),this.#e=t,this}async sign(t,s){return Sr(kr(this),this.#e,s?.crit,t,()=>{throw new Te("JWTs MUST NOT use unencoded payload")})}};var fs='"alg" (Algorithm)';function gs(e='JWK "alg" (Algorithm) Parameter'){throw new C(`Invalid or unsupported ${e} value`)}function vr(e,t){return(typeof e=="string"?ps[e]??wr[e]:void 0)??gs(t)}var Ce=(e,t)=>{if(e.byteLength!==t.length)return!1;for(let s=0;s<e.byteLength;s++)if(e[s]!==t[s])return!1;return!0},Sc=e=>({data:e,pos:0}),ys=e=>{let t=e.data[e.pos++];if(t===void 0)throw new Error("Unexpected end of ASN.1 input");return t},Ne=e=>{let t=ys(e);if(t&128){let s=t&127,n=0;for(let r=0;r<s;r++)n=n<<8|ys(e);return n}return t};var $e=(e,t,s)=>{if(ys(e)!==t)throw new Error(s)},Ir=(e,t)=>{if(t<0||e.pos+t>e.data.length)throw new Error("Unexpected end of ASN.1 input");let s=e.data.subarray(e.pos,e.pos+t);return e.pos+=t,s},vc=e=>{$e(e,6,"Expected algorithm OID");let t=Ne(e);return Ir(e,t)};function Ic(e,t){if($e(e,48,`Invalid ${t==="spki"?"SPKI":"PKCS#8"} structure`),Ne(e),t==="pkcs8"){$e(e,2,"Expected version field");let s=Ne(e);e.pos+=s}$e(e,48,"Expected algorithm identifier"),Ne(e)}var Tc=e=>{let t=vc(e);if(Ce(t,[43,101,110]))return"X25519";if(!Ce(t,[42,134,72,206,61,2,1]))throw new Error("Unsupported key algorithm");$e(e,6,"Expected curve OID");let s=Ne(e),n=Ir(e,s);if(Ce(n,[42,134,72,206,61,3,1,7]))return"P-256";if(Ce(n,[43,129,4,0,34]))return"P-384";if(Ce(n,[43,129,4,0,35]))return"P-521";throw new Error("Unsupported named curve")},Pc=async(e,t,s,n)=>{let r=gr(n?.extractable),o=vr(s,fs);o.secret&&gs(fs);let a=e==="spki",i;if(o.resolve)try{let d=Sc(t);Ic(d,e),i=o.resolve({crv:Tc(d)})}catch{throw new C("Invalid or unsupported key format")}else i=o.subtle;return crypto.subtle.importKey(e,t,i,r??a,o.usages[a?0:1])},xc=(e,t)=>lt(e.replace(t,"")),Tr=(e,t,s)=>{let n=xc(e,/(?:-----(?:BEGIN|END) PRIVATE KEY-----|\s)/g);return Pc("pkcs8",n,t,s)};async function ws(e,t,s){if(typeof e!="string"||e.indexOf("-----BEGIN PRIVATE KEY-----")!==0)throw new TypeError('"pkcs8" must be PKCS#8 formatted string');return Tr(e,t,s)}var De="RS256",bt="everyapp-identity",Rc="everyapp-identity-dev";var Oc="x-everyapp-identity",Cc="x-everyapp-public",Hm="x-everyapp-system";var Pr=120,Es=60;var xr="public",Nc="system";function $c(e,t){return{typ:"user",email:e.email,org_id:e.orgId,org_role:e.orgRole,chan:t.channel??"web",act:t.actor??{sub:e.sub},scopes:t.scopes??["*"],jti:t.jti,...t.toolCall?{tc:{id:t.toolCall.id,name:t.toolCall.name}}:{}}}function Dc(e){return{typ:"public",pub:!0,jti:e}}var Et=null;async function bs(e){let t=e.replace(/\\n/g,`
|
|
3
|
+
`);if(Et&&Et.pem===t)return Et.key;let s=await ws(t,De);return Et={pem:t,key:s},s}async function Wm(e,t){let s=await bs(e),n=Math.floor((t.now??Date.now())/1e3),r=t.ttlSeconds??Pr,o=crypto.randomUUID();return new J($c(t.subject,{channel:t.channel,actor:t.actor,scopes:t.scopes,toolCall:t.toolCall,jti:o})).setProtectedHeader({alg:De,kid:t.keyId??bt}).setIssuer(t.issuer).setSubject(t.subject.sub).setAudience(t.audience).setIssuedAt(n).setExpirationTime(n+r).sign(s)}async function Bm(e,t){let s=await bs(e),n=Math.floor((t.now??Date.now())/1e3),r=t.ttlSeconds??Pr;return new J(Dc(crypto.randomUUID())).setProtectedHeader({alg:De,kid:t.keyId??bt}).setIssuer(t.issuer).setSubject(xr).setAudience(t.audience).setIssuedAt(n).setExpirationTime(n+r).sign(s)}async function Fm(e,t){let s=t.ttlSeconds??Es;if(s<=0||s>Es)throw new RangeError(`system tokens live at most ${Es}s (got ${s})`);let n=await bs(e),r=Math.floor((t.now??Date.now())/1e3),o={typ:"system",purpose:t.purpose,jti:crypto.randomUUID()};return new J(o).setProtectedHeader({alg:De,kid:t.keyId??bt}).setIssuer(t.issuer).setSubject(Nc).setAudience(t.audience).setIssuedAt(r).setExpirationTime(r+s).sign(n)}function Lc(e){let{basePath:t,normalize:s}=e;return{origin:e.origin,...e.chat?{chat:e.chat}:{},...e.embeddings?{embeddings:e.embeddings}:{},keyEnv:e.auth.secret,auth:e.auth,docs:e.docs,...e.setup===void 0?{}:{setup:e.setup},...e.alsoNeeds===void 0?{}:{alsoNeeds:e.alsoNeeds},...t===void 0?{}:{basePath:n=>Mc(t,n)??""},...s==="workers-ai"?{normalizeResponse:zc}:{}}}var Rr=Object.fromEntries(j.flatMap(e=>{let t=N[e];return t.mode==="ai"&&!("kind"in t&&t.kind==="proxy")?[[e,Lc(t)]]:[]}));function qm(e){return Object.hasOwn(Rr,e)?Rr[e]:void 0}function Jm(e){return[e.keyEnv,...e.alsoNeeds??[]]}function Mc(e,t){let s=!1,n=e.replace(/\{([A-Z][A-Z0-9_]*)\}/g,(r,o)=>{let a=t[o];return typeof a!="string"||!a.trim()?(s=!0,""):encodeURIComponent(a.trim())});return s?null:n}var Gc=new Set(["/v1/chat/completions"]),Uc=["content","reasoning_content","reasoning"],jc=/"(?:content|reasoning_content|reasoning)"\s*:\s*-?\d/;function zc(e,t){if(!t.body||!Gc.has(e))return t;let s=(t.headers.get("content-type")??"").toLowerCase(),n=s.startsWith("text/event-stream")?Hc():s.startsWith("application/json")?Wc():null;if(!n)return t;let r=new Headers(t.headers);return r.delete("content-length"),new Response(t.body.pipeThrough(n),{status:t.status,statusText:t.statusText,headers:r})}function Kc(e){if(!_s(e)||!Array.isArray(e.choices))return!1;let t=!1;for(let s of e.choices)if(_s(s)){for(let n of[s.delta,s.message])if(_s(n))for(let r of Uc){let o=n[r];typeof o=="number"&&(n[r]=String(o),t=!0)}}return t}function Or(e){if(!jc.test(e))return null;let t;try{t=JSON.parse(e)}catch{return null}return Kc(t)?JSON.stringify(t):null}function Hc(){let e=new TextDecoder,t=new TextEncoder,s="",n=r=>{let o=/^(data:[ ]?)(.*?)(\r?)$/s.exec(r);if(!o)return r;let a=Or(o[2]);return a===null?r:`${o[1]}${a}${o[3]}`};return new TransformStream({transform(r,o){s+=e.decode(r,{stream:!0});let a=s.lastIndexOf(`
|
|
4
|
+
`);if(a===-1)return;let i=s.slice(0,a+1);s=s.slice(a+1),o.enqueue(t.encode(i.split(`
|
|
5
|
+
`).map(n).join(`
|
|
6
|
+
`)))},flush(r){s+=e.decode(),s&&r.enqueue(t.encode(n(s)))}})}function Wc(){let e=[];return new TransformStream({transform(t){e.push(t)},flush(t){let s=new TextDecoder,n=e.map(o=>s.decode(o,{stream:!0})).join("")+s.decode(),r=Or(n);if(r!==null){t.enqueue(new TextEncoder().encode(r));return}for(let o of e)t.enqueue(o)}})}function _s(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var ef=64*1024;var Cr={"github-oauth":{id:"github-oauth",name:"GitHub",description:"Repositories, issues, pull requests and the person's profile.",docs:"https://github.com/settings/developers",api:"https://docs.github.com/rest",hosts:["api.github.com"],auth:{kind:"oauth2-user",authorizeUrl:"https://github.com/login/oauth/authorize",tokenUrl:"https://github.com/login/oauth/access_token",revokeUrl:"https://api.github.com/applications/{client_id}/grant",revokeMethod:"DELETE",clientId:"GITHUB_OAUTH_CLIENT_ID",clientSecret:"GITHUB_OAUTH_CLIENT_SECRET",inject:"form",pkce:!0,scopeDialect:"comma",tokenHeaders:{Accept:"application/json"},identity:{url:"https://api.github.com/user",label:"login",id:"id"}},scopeSets:{identity:{label:"GitHub account (who you are)",access:"read",scopes:["read:user","user:email"]},"repo.read":{label:"Repositories (read, private ones included)",access:"read",scopes:["repo"]},"repo.write":{label:"Repositories (read and write)",access:"write",scopes:["repo"]},"org.read":{label:"Organizations and teams (read)",access:"read",scopes:["read:org"]}},access:["read","write"],hint:"Register an OAuth App (not a GitHub App) and paste its client id and secret. GitHub's `repo` scope is read and write; a read set with it still lets the Gateway refuse writes."},"notion-oauth":{id:"notion-oauth",name:"Notion",description:"Pages and databases the person shares with the integration.",docs:"https://www.notion.so/my-integrations",api:"https://developers.notion.com/reference",hosts:["api.notion.com"],auth:{kind:"oauth2-user",authorizeUrl:"https://api.notion.com/v1/oauth/authorize",tokenUrl:"https://api.notion.com/v1/oauth/token",clientId:"NOTION_OAUTH_CLIENT_ID",clientSecret:"NOTION_OAUTH_CLIENT_SECRET",inject:"basic",pkce:!1,scopeDialect:"space",authorizeParams:{owner:"user"}},scopeSets:{"workspace.read":{label:"Shared pages and databases (read)",access:"read",scopes:[],routes:[{host:"api.notion.com",paths:["/v1/users","/v1/users/","/v1/pages/","/v1/databases/","/v1/blocks/","/v1/comments"],posts:["^/v1/search$","^/v1/databases/[^/]+/query$"]}]},"workspace.write":{label:"Shared pages and databases (read and write)",access:"write",scopes:[]}},access:["read","write"],hint:"Notion has no scopes: the person picks the pages to share on Notion's consent screen. Make the integration public to get a client id and secret. Apps send `Notion-Version` on every call."},"linear-oauth":{id:"linear-oauth",name:"Linear",description:"Issues, projects and teams, over Linear's GraphQL API.",docs:"https://linear.app/settings/api/applications",api:"https://developers.linear.app/docs/oauth/authentication",hosts:["api.linear.app"],auth:{kind:"oauth2-user",authorizeUrl:"https://linear.app/oauth/authorize",tokenUrl:"https://api.linear.app/oauth/token",revokeUrl:"https://api.linear.app/oauth/revoke",clientId:"LINEAR_OAUTH_CLIENT_ID",clientSecret:"LINEAR_OAUTH_CLIENT_SECRET",inject:"form",pkce:!1,scopeDialect:"comma"},scopeSets:{"workspace.write":{label:"Issues, projects and teams (read and write)",access:"write",scopes:["read","write"]}},access:["write"],readMethods:[],writeMethods:["POST"],hint:`Linear's API is GraphQL over POST, so every call needs access: "write"; a token's scopes decide what a query may change.`},"gitlab-oauth":{id:"gitlab-oauth",name:"GitLab",description:"Projects, merge requests and issues on gitlab.com.",docs:"https://gitlab.com/-/user_settings/applications",api:"https://docs.gitlab.com/api/rest/",hosts:["gitlab.com"],auth:{kind:"oauth2-user",authorizeUrl:"https://gitlab.com/oauth/authorize",tokenUrl:"https://gitlab.com/oauth/token",revokeUrl:"https://gitlab.com/oauth/revoke",clientId:"GITLAB_OAUTH_CLIENT_ID",clientSecret:"GITLAB_OAUTH_CLIENT_SECRET",inject:"form",pkce:!0,scopeDialect:"space",identity:{url:"https://gitlab.com/api/v4/user",label:"username",id:"id"}},scopeSets:{identity:{label:"GitLab account (who you are)",access:"read",scopes:["read_user"]},"api.read":{label:"Projects, issues and merge requests (read)",access:"read",scopes:["read_api"]},"api.write":{label:"Projects, issues and merge requests (read and write)",access:"write",scopes:["api"]}},access:["read","write"],hint:"A self-managed GitLab needs a custom provider with its own host in place of gitlab.com."},atlassian:{id:"atlassian",name:"Atlassian (Jira and Confluence)",description:"Jira issues and Confluence pages on the sites the person grants.",docs:"https://developer.atlassian.com/console/myapps/",api:"https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/",hosts:["api.atlassian.com"],auth:{kind:"oauth2-user",authorizeUrl:"https://auth.atlassian.com/authorize",tokenUrl:"https://auth.atlassian.com/oauth/token",clientId:"ATLASSIAN_CLIENT_ID",clientSecret:"ATLASSIAN_CLIENT_SECRET",inject:"form",pkce:!1,scopeDialect:"space",authorizeParams:{audience:"api.atlassian.com",prompt:"consent"},identity:{url:"https://api.atlassian.com/me",label:"email",id:"account_id"}},scopeSets:{identity:{label:"Atlassian account (who you are)",access:"read",scopes:["read:me"]},"jira.read":{label:"Jira issues and projects (read)",access:"read",scopes:["read:jira-work","read:jira-user"]},"jira.write":{label:"Jira issues (read and write)",access:"write",scopes:["read:jira-work","write:jira-work"]},"confluence.read":{label:"Confluence pages (read)",access:"read",scopes:["read:confluence-content.all","read:confluence-space.summary"]}},alwaysRequested:["offline_access"],access:["read","write"],hint:"Calls go to api.atlassian.com/ex/jira/<cloud id>/\u2026 ; the cloud id comes from /oauth/token/accessible-resources."},"hubspot-oauth":{id:"hubspot-oauth",name:"HubSpot",description:"CRM contacts, companies and deals.",docs:"https://developers.hubspot.com/",api:"https://developers.hubspot.com/docs/reference/api",hosts:["api.hubapi.com"],auth:{kind:"oauth2-user",authorizeUrl:"https://app.hubspot.com/oauth/authorize",tokenUrl:"https://api.hubapi.com/oauth/v1/token",clientId:"HUBSPOT_OAUTH_CLIENT_ID",clientSecret:"HUBSPOT_OAUTH_CLIENT_SECRET",inject:"form",pkce:!1,scopeDialect:"space"},scopeSets:{"contacts.read":{label:"Contacts (read)",access:"read",scopes:["crm.objects.contacts.read"]},"contacts.write":{label:"Contacts (read and write)",access:"write",scopes:["crm.objects.contacts.read","crm.objects.contacts.write"]},"companies.read":{label:"Companies (read)",access:"read",scopes:["crm.objects.companies.read"]},"deals.read":{label:"Deals (read)",access:"read",scopes:["crm.objects.deals.read"]}},access:["read","write"],hint:"The app's scopes in HubSpot's developer console must match the sets apps declare, or HubSpot refuses the authorize URL."},zoom:{id:"zoom",name:"Zoom",description:"The person's meetings and recordings.",docs:"https://marketplace.zoom.us/develop/create",api:"https://developers.zoom.us/docs/api/",hosts:["api.zoom.us"],auth:{kind:"oauth2-user",authorizeUrl:"https://zoom.us/oauth/authorize",tokenUrl:"https://zoom.us/oauth/token",revokeUrl:"https://zoom.us/oauth/revoke",clientId:"ZOOM_CLIENT_ID",clientSecret:"ZOOM_CLIENT_SECRET",inject:"basic",pkce:!0,scopeDialect:"space",identity:{url:"https://api.zoom.us/v2/users/me",label:"email",id:"id"}},scopeSets:{identity:{label:"Zoom account (who you are)",access:"read",scopes:["user:read:user"]},"meetings.read":{label:"Meetings (read)",access:"read",scopes:["meeting:read:meeting","meeting:read:list_meetings"]},"meetings.write":{label:"Meetings (read, create and change)",access:"write",scopes:["meeting:read:meeting","meeting:write:meeting","meeting:update:meeting"]},"recordings.read":{label:"Cloud recordings (read)",access:"read",scopes:["cloud_recording:read:list_user_recordings"]}},access:["read","write"],hint:"A General app with user-managed OAuth; Zoom's granular scope names are the ones listed here."},dropbox:{id:"dropbox",name:"Dropbox",description:"Files and folders in the person's Dropbox.",docs:"https://www.dropbox.com/developers/apps",api:"https://www.dropbox.com/developers/documentation/http/documentation",hosts:["api.dropboxapi.com","content.dropboxapi.com"],auth:{kind:"oauth2-user",authorizeUrl:"https://www.dropbox.com/oauth2/authorize",tokenUrl:"https://api.dropboxapi.com/oauth2/token",revokeUrl:"https://api.dropboxapi.com/2/auth/token/revoke",clientId:"DROPBOX_OAUTH_CLIENT_ID",clientSecret:"DROPBOX_OAUTH_CLIENT_SECRET",inject:"form",pkce:!0,scopeDialect:"space",authorizeParams:{token_access_type:"offline"}},scopeSets:{identity:{label:"Dropbox account (who you are)",access:"read",scopes:["account_info.read"],routes:[{host:"api.dropboxapi.com",paths:[],posts:["^/2/users/get_current_account$","^/2/users/get_space_usage$"]}]},"files.read":{label:"Files and folders (read)",access:"read",scopes:["files.metadata.read","files.content.read"],routes:[{host:"api.dropboxapi.com",paths:[],posts:["^/2/files/list_folder$","^/2/files/list_folder/continue$","^/2/files/get_metadata$","^/2/files/search_v2$","^/2/files/search/continue_v2$","^/2/files/get_temporary_link$","^/2/files/list_revisions$"]},{host:"content.dropboxapi.com",paths:[],posts:["^/2/files/download$","^/2/files/get_thumbnail_v2$","^/2/files/export$"]}]},"files.write":{label:"Files and folders (read and write)",access:"write",scopes:["files.metadata.read","files.content.read","files.metadata.write","files.content.write"]}},access:["read","write"],hint:'Dropbox\'s API is POST throughout: a read set unlocks its listed read calls, anything else needs access: "write". `token_access_type=offline` is what yields a refresh token.'},spotify:{id:"spotify",name:"Spotify",description:"The person's library, playlists and listening.",docs:"https://developer.spotify.com/dashboard",api:"https://developer.spotify.com/documentation/web-api",hosts:["api.spotify.com"],auth:{kind:"oauth2-user",authorizeUrl:"https://accounts.spotify.com/authorize",tokenUrl:"https://accounts.spotify.com/api/token",clientId:"SPOTIFY_CLIENT_ID",clientSecret:"SPOTIFY_CLIENT_SECRET",inject:"basic",pkce:!0,scopeDialect:"space",identity:{url:"https://api.spotify.com/v1/me",label:"display_name",id:"id"}},scopeSets:{identity:{label:"Spotify account (who you are)",access:"read",scopes:["user-read-email","user-read-private"]},"library.read":{label:"Saved tracks and albums (read)",access:"read",scopes:["user-library-read"]},"playlists.read":{label:"Playlists (read)",access:"read",scopes:["playlist-read-private","playlist-read-collaborative"]},"playlists.write":{label:"Playlists (read and change)",access:"write",scopes:["playlist-read-private","playlist-modify-private","playlist-modify-public"]}},access:["read","write"]},"x-oauth":{id:"x-oauth",name:"X (OAuth 2)",description:"Posts and the person's profile on X, over the v2 API.",docs:"https://developer.x.com/en/portal/dashboard",api:"https://docs.x.com/x-api",hosts:["api.x.com"],auth:{kind:"oauth2-user",authorizeUrl:"https://x.com/i/oauth2/authorize",tokenUrl:"https://api.x.com/2/oauth2/token",revokeUrl:"https://api.x.com/2/oauth2/revoke",clientId:"X_OAUTH_CLIENT_ID",clientSecret:"X_OAUTH_CLIENT_SECRET",inject:"basic",pkce:!0,scopeDialect:"space",identity:{url:"https://api.x.com/2/users/me",label:"data.username",id:"data.id"}},scopeSets:{identity:{label:"X account (who you are)",access:"read",scopes:["users.read","tweet.read"]},"posts.read":{label:"Posts and timelines (read)",access:"read",scopes:["tweet.read","users.read"]},"posts.write":{label:"Posts (read and publish)",access:"write",scopes:["tweet.read","users.read","tweet.write"]}},alwaysRequested:["offline.access"],access:["read","write"],hint:"OAuth 2 with PKCE on X's v2 API; X's OAuth 1.0a (the v1.1 media upload) stays an app secret."}};function rf(){return Object.keys(Cr)}function of(e){let t=Cr[e];if(!t)return null;let s=Ie(t);if(!s.ok)throw new Error(`preset ${e} doesn't parse: ${JSON.stringify(s.problems)}`);return s.capability}function Nr(e){return e?.mode==="oauth_client"&&e.flow!==void 0}function Bc(e){if(e.mode==="oauth_client")return JSON.stringify({kind:"oauth2-user",authorizeUrl:e.authorize.url,tokenUrl:e.flow?.tokenUrl??null,revokeUrl:e.flow?.revokeUrl??null,inject:e.token[0]?.inject??"form",clientId:e.secrets.clientId,clientSecret:e.secrets.clientSecret??null,hosts:[...e.api].sort()});let t=Object.fromEntries(Object.entries(e.auth).sort(([s],[n])=>s<n?-1:s>n?1:0).map(([s,n])=>[s,typeof n=="object"&&n!==null?Object.fromEntries(Object.entries(n).sort(([r],[o])=>r<o?-1:r>o?1:0)):n]));return JSON.stringify({auth:t,hostSetting:e.hostSetting??null,hosts:[...e.hosts].sort()})}var Fc=new Set(["everyapp"]),Yc=/^\d{1,3}(\.\d{1,3}){3}$/,Vc=[".localhost",".local",".internal",".arpa"];function qc(e){return`${e.toUpperCase().replace(/-/g,"_")}_`}function Jc(e){return Yc.test(e)?`${e} is an IP address, not a host name`:e==="localhost"||Vc.some(t=>e.endsWith(t))?`${e} is not a public host`:null}function As(e){let t=e?.trim().toLowerCase().replace(/\.$/,"");if(!t)return null;if(!t.includes("/"))return t;try{return new URL(t).hostname.toLowerCase()}catch{return null}}function lf(e,t){let s=As(t.gatewayHost);if(s&&e===s)return`${e} is this gateway's own host`;let n=As(t.appBaseDomain);if(n&&(e===n||e.endsWith(`.${n}`)))return`${e} is under this gateway's app domain ${n}`;let r=As(t.thirdPartyDomain);return r&&(e===r||e.endsWith(`.${r}`))?`${e} is under this gateway's third-party domain ${r}`:null}function Xc(e,t,s){let n=qc(e);return t.startsWith(n)?ie(t)?`${t} is one of the Gateway's own keys`:bn(t)?`${t} is a local-development setting`:Je(t)?`${t} is a name everyapp sets itself`:qe(t)?`${t} is a sign-in provider's setting name (every <ID>_SIGNIN_<FIELD> name is the Gateway's, set with \`everyapp signin add\`)`:F(t)?`${t} is a Gateway setting another provider or the Gateway reads`:s(t)?`${t} is another registered provider's`:null:`${t} doesn't start with ${n}: a provider's settings carry its own id`}function Zc(e,t,s){if(Fc.has(e)||j.includes(e))return{id:e,code:"PROVIDER_BUILTIN",message:`${e} is a built-in provider; a registered one can't take its id`};for(let n of L(t)){let r=Xc(e,n,o=>s.rowSettings.has(o));if(r)return{id:e,code:"PROVIDER_SECRET_TAKEN",message:r}}for(let n of Qc(t)){let r=Jc(n)??s.refuseHost?.(n);if(r)return{id:e,code:"PROVIDER_HOST_REFUSED",message:r}}return null}function Qc(e){if(e.mode==="api_key")return[...e.hosts];let t=[...e.api],s=[e.authorize.url,e.flow?.tokenUrl,e.flow?.revokeUrl,e.flow?.identity?.url];for(let n of s)if(n)try{let r=new URL(n).hostname.toLowerCase();t.includes(r)||t.push(r)}catch{}return t}function ed(e,t){let s=e.spec;if(typeof s=="string")try{s=JSON.parse(s)}catch{return{ok:!1,refusal:{id:e.id,code:"PROVIDER_SPEC_INVALID",message:"the stored spec isn't JSON"}}}let n=Ie(s);if(!n.ok)return{ok:!1,refusal:{id:e.id,code:"PROVIDER_SPEC_INVALID",message:Xt(n.problems)}};if(n.id!==e.id||!Jt.test(e.id))return{ok:!1,refusal:{id:e.id,code:"PROVIDER_SPEC_INVALID",message:`the row is ${e.id} but its spec says ${n.id}`}};let r=Zc(n.id,n.capability,t);return r?{ok:!1,refusal:r}:{ok:!0,capability:n.capability}}function td(e=[],t={}){let s=new Map(j.map(p=>[p,N[p]])),n=new Map,r=[],o=new Set;for(let p of e){if(n.has(p.id)){r.push({id:p.id,code:"PROVIDER_SPEC_INVALID",message:"listed twice"});continue}let u=ed(p,{rowSettings:o,...t.refuseHost?{refuseHost:t.refuseHost}:{}});if(!u.ok){r.push(u.refusal);continue}n.set(p.id,{id:p.id,capability:u.capability,bound:p.boundTo===Bc(u.capability),addedBy:p.addedBy??null,addedAt:p.addedAt??null});for(let h of L(u.capability))o.add(h)}let a=new Map([...s,...[...n.values()].map(p=>[p.id,p.capability])]),i,d;return{get:p=>a.get(p),ids:()=>[...a.keys()],entries:()=>[...a.entries()],sourceOf:p=>s.has(p)?"catalog":n.has(p)?"row":void 0,settingNames:()=>(i??=new Set([...a.values()].flatMap(p=>L(p))),i),bound:p=>s.has(p)||(n.get(p)?.bound??!1),unboundSettings:()=>(d??=new Set([...n.values()].filter(p=>!p.bound).flatMap(p=>L(p.capability))),d),rows:()=>[...n.values()],rejected:r}}var hf=td();import{z as c}from"zod";var $r=/[\x00-\x1f\x7f]/,sd=/%2f|%5c/i;function ks(e){if(typeof e!="string"||e.length===0)return{canonical:"/",ambiguous:!0,reason:"empty path"};if(!e.startsWith("/"))return{canonical:"/",ambiguous:!0,reason:"non-absolute path"};if($r.test(e))return{canonical:"/",ambiguous:!0,reason:"control characters"};if(e.includes("\\"))return{canonical:"/",ambiguous:!0,reason:"backslash"};if(sd.test(e))return{canonical:"/",ambiguous:!0,reason:"encoded path separator"};let t;try{t=decodeURIComponent(e)}catch{return{canonical:"/",ambiguous:!0,reason:"invalid percent-encoding"}}if(t.includes("%"))return{canonical:"/",ambiguous:!0,reason:"double-encoded"};if($r.test(t)||t.includes("\\"))return{canonical:"/",ambiguous:!0,reason:"decoded to unsafe characters"};let s=[],n=!1;for(let o of t.split("/"))if(!(o===""||o===".")){if(o===".."){if(s.length===0)return{canonical:"/",ambiguous:!0,reason:"path traversal above root"};s.pop(),n=!0;continue}s.push(o)}let r="/"+s.join("/");return n&&/%2e/i.test(e)?{canonical:r,ambiguous:!0,reason:"encoded traversal"}:{canonical:r,ambiguous:!1}}function nd(e){return e===X||e.startsWith(X+"/")}function ag(e){return Dr(ks(e).canonical)||Dr(Mr(e))}function Dr(e){let t=e.toLowerCase();return t===Se||t.startsWith(`${Se}/`)}var rd=["oauth-protected-resource","oauth-authorization-server","openid-configuration"],od=rd.flatMap(e=>[`/.well-known/${e}`,`/mcp/.well-known/${e}`]);function ig(e){return Lr(ks(e).canonical)||Lr(Mr(e))}function Lr(e){let t=e.toLowerCase();return od.some(s=>t===s||t.startsWith(`${s}/`))}function Mr(e){let t=e;for(let n=0;n<3;n+=1){let r;try{r=decodeURIComponent(t)}catch{break}if(r===t)break;t=r}let s=[];for(let n of t.replace(/\\/g,"/").split("/"))if(!(n===""||n===".")){if(n===".."){s.pop();continue}s.push(n)}return"/"+s.join("/")}function ad(e){let t="^",s=0;for(;s<e.length;){let n=e[s];if(n==="*")e[s+1]==="*"?(t+=".*",s+=2):(t+="[^/]*",s+=1);else if(n===":"&&e[s-1]==="/"){let r=e.slice(s+1).match(/^[A-Za-z_][A-Za-z0-9_]*/)?.[0],o=r?e[s+1+r.length]:void 0;r&&(o===void 0||o==="/")?(t+="[^/]+",s+=1+r.length):(t+="\\:",s+=1)}else t+=n.replace(/[.+?^${}()|[\]\\]/g,"\\$&"),s+=1}return t+="$",new RegExp(t)}function Gr(e,t,s){if(!e||e.length===0)return{public:!1,reason:"no public routes declared"};let{canonical:n,ambiguous:r,reason:o}=ks(s);if(r)return{public:!1,reason:`ambiguous path: ${o}`};if(nd(n))return{public:!1,reason:"internal namespace is never public"};let a=t.toUpperCase();for(let i of e)if((i.methods??["GET"]).map(p=>p.toUpperCase()).includes(a)&&ad(i.path).test(n))return{public:!0,route:i,reason:`matched ${i.path}`};return{public:!1,reason:"no matching public route"}}var Wr=c.object({path:c.string(),methods:c.array(c.string()).optional()}),_t=c.object({name:c.string(),className:c.string(),worker:c.string().optional()}),Br=c.object({name:c.string(),worker:c.string().optional(),caching:c.enum(["off","default"]).optional()}),Fr=c.object({worker:c.string().optional(),maxBatchSize:c.number().optional(),maxBatchTimeout:c.number().optional(),maxRetries:c.number().optional(),maxConcurrency:c.number().nullable().optional(),retryDelay:c.number().optional(),visibilityTimeoutMs:c.number().optional(),deadLetterQueue:c.string().optional()}),Yr=c.object({name:c.string(),consumer:c.union([c.literal(!0),Fr]).optional()}),id=["cosine","euclidean","dot-product"],cd=["@cf/baai/bge-small-en-v1.5","@cf/baai/bge-base-en-v1.5","@cf/baai/bge-large-en-v1.5","openai/text-embedding-ada-002","cohere/embed-multilingual-v2.0"],he={min:32,max:1536},Vr=c.object({name:c.string(),dimensions:c.number().optional(),metric:c.string().optional(),preset:c.string().optional()}),qr=c.object({name:c.string(),collectLogs:c.boolean().optional(),cacheTtl:c.number().int().min(0).optional()}),Jr=c.object({name:c.string(),allowedSenderAddresses:c.array(c.string()).optional(),destinationAddress:c.string().optional(),allowedDestinationAddresses:c.array(c.string()).optional()}),Xr=c.object({name:c.string()}),Ss=128,Zr=c.object({name:c.string(),dataset:c.string().optional()}),Qr=c.object({d1:c.array(c.string()).optional(),kv:c.array(c.string()).optional(),durableObjects:c.array(_t).optional(),workflows:c.array(_t).optional(),hyperdrive:c.array(Br).optional(),r2:c.array(c.string()).optional(),queues:c.array(Yr).optional(),ai:c.array(c.string()).optional(),browser:c.array(c.string()).optional(),images:c.array(c.string()).optional(),vectorize:c.array(Vr).optional(),aiGateway:c.array(qr).optional(),sendEmail:c.array(Jr).optional(),secretsStore:c.array(Xr).optional(),analyticsEngine:c.array(Zr).optional()}).passthrough(),dd=c.string().regex(/^\d{4}-\d{2}-\d{2}$/,"must be YYYY-MM-DD"),pd=/^[a-z0-9][a-z0-9:_-]{0,63}$/,Ps={when:({value:e})=>typeof e=="object"&&e!==null&&!Array.isArray(e)},eo=c.record(c.string(),c.string().min(1).max(200)).superRefine((e,t)=>{for(let s of Object.keys(e))s==="*"||s.startsWith("provider:")?t.addIssue({code:c.ZodIssueCode.custom,path:[s],message:"reserved scope id"}):pd.test(s)||t.addIssue({code:c.ZodIssueCode.custom,path:[s],message:"invalid scope id"})},Ps),ud=eo,ld=c.object({engine:c.enum(["drizzle","d1-sql","prisma"]),dialect:c.enum(["sqlite","postgresql"]).optional(),dir:c.string().optional(),config:c.string().min(1).optional(),binding:c.string().min(1).optional()}).strict().superRefine((e,t)=>{if(e.engine==="prisma"&&e.dialect!=="postgresql"&&t.addIssue({code:c.ZodIssueCode.custom,path:["engine"],message:'Prisma migrations run on Postgres (dialect "postgresql"); D1 takes the generated SQL through "d1-sql"'}),e.dialect==="postgresql"&&(e.engine==="d1-sql"&&t.addIssue({code:c.ZodIssueCode.custom,path:["engine"],message:'Postgres migrations run on the "drizzle" or "prisma" engine'}),e.binding!==void 0&&t.addIssue({code:c.ZodIssueCode.custom,path:["binding"],message:"binding names a D1 database; Postgres migrations have none"})),e.config!==void 0&&!Hr(e.config)&&t.addIssue({code:c.ZodIssueCode.custom,path:["config"],message:"config must be a relative path without .. segments"}),e.engine==="d1-sql"&&!e.dir?.trim()){t.addIssue({code:c.ZodIssueCode.custom,path:["dir"],message:'dir is required when migrations.engine is "d1-sql"'});return}e.dir&&!Hr(e.dir)&&t.addIssue({code:c.ZodIssueCode.custom,path:["dir"],message:"dir must be a relative path without .. segments"})}),hd=c.union([c.literal(!1),c.string().min(1)]),to=/^[a-z][a-z0-9-]*$/,so="provider must start with a lowercase letter and contain only lowercase letters, digits, and hyphens",St=c.string().regex(to,so);function no(e,t){return to.test(e)?!1:(t.addIssue({code:c.ZodIssueCode.custom,path:[e],message:so}),!0)}var md=c.string().url().refine(e=>e.startsWith("https://"),"must be an https URL"),vt={why:c.string().min(1).max(200).optional(),docs:md.optional(),optional:c.boolean().optional(),anyOf:c.string().trim().min(1).max(40).optional()},fd=c.object({id:St}).passthrough(),gd=c.object({id:St,...vt}).strict(),ro=(e,t)=>{let s=new Set;e.forEach((n,r)=>{let o=typeof n=="string"?n:n.id;s.has(o)&&t.addIssue({code:c.ZodIssueCode.custom,path:[r],message:"duplicate provider"}),s.add(o)})},yd=c.array(c.union([St,fd])).superRefine(ro),wd=c.array(c.union([St,gd])).superRefine(ro),Ur=c.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/,"a secret's name is an identifier").max(64),At=c.object({scopes:c.array(c.string()).optional().catch(void 0),access:c.enum(["read","write"]),...vt}),Ed=At.passthrough();function bd(e,t=G){let s=t.get(e);if(!s||s.mode==="ai")throw new Error(`capabilityEntrySchema: ${e} is not a capability`);let n=Nr(s)&&!s.access.includes("read")?["read",...s.access]:s.access,r=c.enum(["read","write"]).refine(p=>n.includes(p),`${s.label} offers ${n.join(" or ")} access`),o="scopePolicy"in s?s.scopePolicy:void 0;if(!o){let p=c.undefined({error:`${s.label} takes no scopes; list it as { access: ..., why }`}).optional();return At.extend({access:r,scopes:p}).strict()}let a=Object.keys(o.sets),i=`${s.label} needs scopes: one or more of ${a.join(", ")}`,d=c.array(c.enum(a,{error:`unknown scope set (${s.label} offers: ${a.join(", ")})`}),{error:i}).min(1,i).refine(p=>new Set(p).size===p.length,"a scope set is listed twice");return At.extend({access:r,scopes:d}).strict()}var _d=c.record(c.string(),Ed).superRefine((e,t)=>{for(let s of Object.keys(e))no(s,t)},Ps),Ad=At.extend({scopes:c.array(c.string().regex(/^[a-z][a-z0-9-]{0,31}(?:\.[a-z][a-z0-9-]{0,31})?$/,"a scope set is named identity, or <area>.<access> (repo.read)"),{error:"scopes lists the scope sets of a registered OAuth provider (the gateway's registry names them); an API-key provider takes none"}).min(1,"scopes lists at least one set, or is left out").refine(e=>new Set(e).size===e.length,"a scope set is listed twice").optional()}).strict();function oo(e,t){return c.record(c.string(),c.unknown()).superRefine((s,n)=>{for(let[r,o]of Object.entries(s)){if(no(r,n))continue;let a=e.get(r);if(a?.mode==="ai"){n.addIssue({code:c.ZodIssueCode.custom,path:[r],message:`${r} is an AI provider: list it under providers, not capabilities`});continue}if(!a){if(t==="refuse"){n.addIssue({code:c.ZodIssueCode.custom,path:[r],message:`unknown capability (the gateway offers: ${pn(e).join(", ")})`});continue}let d=Ad.safeParse(o);if(d.success)continue;for(let p of d.error.issues)n.addIssue({...p,path:[r,...p.path]});continue}if(r==="email"&&o!==null&&typeof o=="object"&&"senders"in o){n.addIssue({code:c.ZodIssueCode.custom,path:[r,"senders"],message:`senders moved out of the manifest: set them with \`${Yt} --sender <pattern>\` in the app's directory after its first deploy`});continue}let i=bd(r,e).safeParse(o);if(!i.success)for(let d of i.error.issues)n.addIssue({...d,path:[r,...d.path]})}},Ps).transform(s=>s)}var kd=oo(G,"refuse"),Sd=`inbound is true (the Worker exports an email() handler) or left out; the addresses moved out of the manifest: set them with \`${Yt} --inbound <address>\` in the app's directory after its first deploy`,vd=c.object({inbound:c.boolean().optional().catch(void 0)}).passthrough(),Id=c.object({inbound:c.boolean({error:Sd}).optional()}).strict(),Td="email.inbound: apps in a dispatch namespace don't receive mail",kt=c.object({cpuMs:c.number().int().min(1).max(3e5).optional()}).passthrough(),ao=c.object({provider:c.enum(["d1","postgres"]),region:c.string().regex(/^[a-z0-9]+:[a-z0-9-]+$/,'region must be a cloud region such as "aws:us-east-1"').optional()}).passthrough(),Pd=c.string().regex(/^[a-z]([a-z0-9]|-(?!-))*[a-z0-9]$|^[a-z]$/,"helper Worker names are kebab-case (lowercase letters, digits, single hyphens)").max(20),io=c.object({name:Pd,binding:c.string().optional(),limits:kt.optional()}),xd=c.enum(["everyone","admins"]),co=c.string().regex(/^\/v1(\/[a-z0-9_-]+)+$/,'must be an OpenAI API path such as "/v1/files"'),po=c.object({...vt}),Rd=po.strict(),Od=c.object({models:c.array(c.string().min(1).max(200)).optional(),routes:c.array(co).optional(),chat:c.union([c.boolean(),po]).optional()}).passthrough(),Cd=c.object({models:c.array(c.string().min(1).max(200)).optional(),routes:c.array(co).optional(),chat:c.union([c.boolean(),Rd]).optional()}).strict(),Nd=`mcp is { by: "gateway" | "app", why: "..." }: "gateway" serves the app's defineTools() at <app-host>/mcp, "app" leaves the path to the app's own MCP server; left out, the Gateway's own /mcp is the one connector`,$d=/^[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}]*$/u,uo=c.object({by:c.enum(["gateway","app"]),why:c.string().min(1,"say why the app needs /mcp on its own host").max(200).regex($d,"why is plain text: no control characters")},{error:e=>e.code==="invalid_type"?Nd:void 0}).passthrough(),lo=c.object({id:c.string().min(1).regex(/^[a-z]([a-z0-9-]*[a-z0-9])?$/,"id must be kebab-case (lowercase, digits, hyphens)"),name:c.string().min(1).optional(),description:c.string().optional(),icon:c.string().regex(/^(\/[A-Za-z0-9_~-][A-Za-z0-9._~-]*)*\/[A-Za-z0-9_~-][A-Za-z0-9._~-]*\.svg$/,'icon must be the path of an SVG the app serves, such as "/everyapp-icon.svg"').optional(),main:c.string().optional(),compatibilityDate:dd.optional(),resources:Qr.optional(),workers:c.array(io.passthrough()).optional(),database:ao.optional(),limits:kt.optional(),public:c.array(Wr).optional(),providers:yd.optional(),capabilities:_d.optional(),secrets:c.array(c.union([Ur,c.object({name:Ur}).passthrough()])).max(100).optional(),scopes:eo.optional(),ai:Od.optional(),email:vd.optional(),access:xd.optional(),serverFnGuard:c.boolean().optional(),serverFnBase:c.string().regex(/^(\/[A-Za-z0-9_~-][A-Za-z0-9._~-]*)+\/?$/,'must be a path such as "/app/_serverFn"').optional(),build:c.string().min(1).optional(),dev:c.string().min(1).optional(),devPort:c.number().int().positive().optional(),install:hd.optional(),migrations:ld.optional(),mcp:uo.optional()}).passthrough(),Dd=Wr.strict(),R=c.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/,"binding names must be JavaScript identifiers"),Ld=R.refine(e=>!e.endsWith("_"),"a queue's binding can't end with _ (its queue's name would end with a hyphen, which Cloudflare refuses)"),Md=c.string().regex(/^[A-Za-z][A-Za-z0-9]*(?:_[A-Za-z0-9]+)*$/,"an AI Gateway's binding is letters and digits joined by single underscores (it ends the gateway's id, which takes single hyphens only)"),Gd=c.string().regex(/^setup\/[a-z0-9][a-z0-9-]*\.md$/,'must be a guide in the everyapp skill, such as "setup/main-secret.md"'),Ud=c.object({name:R,...vt,setup:Gd.optional()}).strict();function jd(e,t){if(!e)return null;for(let s of e.ids()){if(jt(s))continue;let n=e.get(s);if(n&&L(n).includes(t))return{kind:"capability",id:s}}return null}function ho(e){return c.array(c.union([R,Ud])).superRefine((t,s)=>{let n=new Set;t.forEach((r,o)=>{let a=typeof r=="string"?r:r.name,i=w=>s.addIssue({code:c.ZodIssueCode.custom,path:[o],message:w});if(n.has(a)&&i(`duplicate secret ${a}`),n.add(a),Je(a)){i(`${a} is set by everyapp itself (${_n})`);return}let d=a.toUpperCase();if(qe(d)){i(`${a} is a sign-in provider's setting name (every <ID>_SIGNIN_<FIELD> name is the Gateway's, set with \`everyapp signin add\`); give the app's secret another name`);return}let p=F(d)?null:jd(e,d);if(!F(d)&&!p)return;if(ke(d)){i(`${a} is a remote MCP app's credential name (every name ending in _MCP_TOKEN is the Gateway's, set with \`everyapp secret set\`); give the app's secret another name`);return}let u=p??An(d),h=u?`list \`${u.id}\` under ${u.kind==="provider"?"providers":"capabilities"} instead`:"give the app's secret another name";i(`${a} is a Gateway setting, which \`everyapp secret set ${d}\` sets on the Gateway for every app; ${h}`)})})}var zd=ho(),Kd=Vr.extend({name:R,dimensions:c.number().int("a Vectorize index's dimensions are a whole number").min(he.min,`a Vectorize index has ${he.min} to ${he.max} dimensions`).max(he.max,`a Vectorize index has ${he.min} to ${he.max} dimensions`).optional(),metric:c.enum(id).optional(),preset:c.enum(cd).optional()}).strict().superRefine((e,t)=>{let s=e.dimensions!==void 0||e.metric!==void 0;e.preset!==void 0&&s?t.addIssue({code:"custom",message:`${e.name}: a preset sets the index's dimensions and metric itself; give either preset, or dimensions and metric`}):e.preset===void 0&&(e.dimensions===void 0||e.metric===void 0)&&t.addIssue({code:"custom",message:`${e.name} needs dimensions and metric (e.g. 768 and "cosine"), or a preset (e.g. "@cf/baai/bge-base-en-v1.5")`})}),Hd=/^[A-Za-z0-9.!#$%&'+/=?^_`{|}~-]+@[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?)+$/,vs=c.string().max(254,"an email address is at most 254 characters").regex(Hd,"must be an email address such as noreply@example.com, not a pattern"),Wd=c.array(vs).min(1,"list at least one address, or leave the list out"),jr="list the addresses the binding may send as: without allowedSenderAddresses it could send as any address on the account's Email Sending domains, the Gateway's own sender included",Bd=Jr.extend({name:R,allowedSenderAddresses:c.array(vs,{error:e=>e.input===void 0?jr:void 0}).min(1,jr),destinationAddress:vs.optional(),allowedDestinationAddresses:Wd.optional()}).strict().refine(e=>e.destinationAddress===void 0||e.allowedDestinationAddresses===void 0,{message:"destinationAddress and allowedDestinationAddresses can't both be set: one destination, or a list of them",path:["allowedDestinationAddresses"]}),Fd=Qr.extend({d1:c.array(R).optional(),kv:c.array(R).optional(),r2:c.array(R).optional(),ai:c.array(R).optional(),browser:c.array(R).optional(),images:c.array(R).optional(),analyticsEngine:c.array(Zr.extend({name:R.max(63,`Analytics Engine binding names are at most 63 characters, so the dataset named after the Worker fits Cloudflare's ${Ss}`),dataset:c.string().regex(new RegExp(`^[A-Za-z0-9_-]{1,${Ss}}$`),`dataset names are letters, digits, dashes and underscores, at most ${Ss} characters (Cloudflare's rule)`).optional()}).strict()).optional(),durableObjects:c.array(_t.strict()).optional(),workflows:c.array(_t.extend({name:R}).strict()).optional(),hyperdrive:c.array(Br.extend({name:R}).strict()).optional(),queues:c.array(Yr.extend({name:Ld,consumer:c.union([c.literal(!0),Fr.extend({maxBatchSize:c.number().int().positive().optional(),maxBatchTimeout:c.number().nonnegative().optional(),maxRetries:c.number().int().nonnegative().optional(),maxConcurrency:c.number().int().positive().nullable().optional(),retryDelay:c.number().int().nonnegative().optional(),visibilityTimeoutMs:c.number().int().nonnegative().optional()}).strict()]).optional()}).strict()).optional(),vectorize:c.array(Kd).optional(),aiGateway:c.array(qr.extend({name:Md}).strict()).optional(),sendEmail:c.array(Bd).optional(),secretsStore:c.array(Xr.extend({name:R}).strict()).optional()}).strict();function mo(e={}){let t=e.capabilities===void 0&&(e.unknownCapabilities??"refuse")==="refuse"?kd:oo(e.capabilities??G,e.unknownCapabilities??"refuse");return lo.extend({resources:Fd.optional(),providers:wd.optional(),workers:c.array(io.extend({binding:R.optional(),limits:kt.strict().optional()}).strict()).optional(),public:c.array(Dd).optional(),scopes:ud.optional(),ai:Cd.optional(),capabilities:t.optional(),secrets:(e.capabilities?ho(e.capabilities):zd).optional(),email:Id.optional(),database:ao.strict().optional(),limits:kt.strict().optional(),mcp:uo.strict().optional()}).strict()}var lg=mo(),X="/__everyapp",Yd=["everyapp"];function Vd(e){return Yd.includes(e)}var k=class extends Error{constructor(t){super(t),this.name="ManifestError"}};function fo(e){return e.map(t=>`${t.path.map(String).join(".")||"(root)"}: ${t.message}`).join("; ")}function hg(e){let t=lo.safeParse(e);if(!t.success)throw new k(`Invalid manifest: ${fo(t.error.issues)}`);let s=t.data;for(let n of s.public??[])yo(n.path);return s}function mg(e,t={}){let s=mo(t).safeParse(e);if(!s.success)throw new k(`Invalid everyapp.config: ${fo(s.error.issues)}`);let n=s.data,r=ep(n),o=Gn(n).find(a=>r.has(a));if(o)throw new k(`Invalid everyapp.config: secrets: ${o} is one of the app's bindings; pick another name for the secret`);if(Vd(n.id))throw new k(`Invalid everyapp.config: id "${n.id}" is reserved for the platform.`);for(let a of n.public??[]){yo(a.path);let i=a.path==="/mcp"||a.path.startsWith("/mcp/");if(i||(a.methods??["GET"]).some(p=>Gr([a],p,"/mcp").public))throw new k(`Invalid everyapp.config: public: ${a.path} can't be public${i?"":" (it covers /mcp)"}; an app that runs its own MCP server sets mcp: { by: "app", why: "..." }`)}return Xd(n),Zd(n),Qd(n),qd(n),Jd(n),n}function qd(e){let t=Is({appId:e.id,orgKey:"k".repeat(op)});for(let{name:s}of e.resources?.aiGateway??[]){let n=Kr(t,s);if(n.length>Ts)throw new k(`Invalid everyapp.config: resources.aiGateway: ${s} would make an AI Gateway id of up to ${n.length} characters (${Kr(Is({appId:e.id,orgKey:"<orgKey>"}),s)}), longer than Cloudflare's ${Ts}; shorten the binding name.`)}}function Jd(e){let t=[...Qe(e).map(n=>({path:`providers: ${n.id}`,need:n})),...Object.entries(e.capabilities??{}).map(([n,r])=>({path:`capabilities.${n}`,need:r})),...et(e).map(n=>({path:`secrets: ${n.name}`,need:n}))],s=new Map;for(let{path:n,need:r}of t){let o=r.anyOf?.trim();if(r.optional===!0&&o)throw new k(`Invalid everyapp.config: ${n} is both optional and in the any-of group "${o}"; a group's member is optional by itself, so drop one of them.`);o&&s.set(o,[...s.get(o)??[],n])}for(let[n,r]of s)if(r.length<2)throw new k(`Invalid everyapp.config: the any-of group "${n}" has one member (${r[0]}); an any-of group needs two or more. Drop anyOf, or mark it optional.`)}function Xd(e){let t=new Set;for(let{name:n}of e.workers??[]){if(t.has(n))throw new k(`Invalid everyapp.config: workers lists "${n}" twice.`);t.add(n)}let s=e.resources;for(let n of[...s?.durableObjects??[],...s?.workflows??[]])if(n.worker!==void 0&&!t.has(n.worker))throw new k(`Invalid everyapp.config: ${n.name} is defined by Worker "${n.worker}", which workers doesn't declare.`);for(let n of s?.hyperdrive??[])if(n.worker!==void 0&&!t.has(n.worker))throw new k(`Invalid everyapp.config: Hyperdrive ${n.name} is bound by Worker "${n.worker}", which workers doesn't declare.`)}function Zd(e){let t=e.resources?.queues??[],s=new Set((e.workers??[]).map(({name:r})=>r)),n=new Set(t.map(({name:r})=>r));for(let r of t){if(r.consumer===void 0||r.consumer===!0)continue;let{worker:o,deadLetterQueue:a}=r.consumer;if(o!==void 0&&!s.has(o))throw new k(`Invalid everyapp.config: Queue ${r.name} is consumed by Worker "${o}", which workers doesn't declare.`);if(a!==void 0){if(a===r.name)throw new k(`Invalid everyapp.config: Queue ${r.name} can't be its own dead-letter queue; name another of resources.queues.`);if(!n.has(a))throw new k(`Invalid everyapp.config: Queue ${r.name}'s deadLetterQueue "${a}" isn't one of resources.queues; declare it there and name its binding.`)}}}function Qd(e){if(e.migrations?.dialect==="postgresql"&&e.database?.provider!=="postgres")throw new k('Invalid everyapp.config: Postgres migrations (migrations.dialect "postgresql") need database: { provider: "postgres" }.');let t=new Set;for(let s of[...e.resources?.d1??[],...e.resources?.kv??[],...e.resources?.r2??[],...(e.resources?.hyperdrive??[]).map(n=>n.name),...(e.resources?.queues??[]).map(n=>n.name),...e.resources?.ai??[],...e.resources?.browser??[],...e.resources?.images??[],...(e.resources?.vectorize??[]).map(n=>n.name),...(e.resources?.aiGateway??[]).map(n=>n.name),...(e.resources?.sendEmail??[]).map(n=>n.name),...(e.resources?.secretsStore??[]).map(n=>n.name),...(e.resources?.analyticsEngine??[]).map(n=>n.name)]){if(t.has(s))throw new k(`Invalid everyapp.config: the binding ${s} is declared twice in resources.`);t.add(s)}}function ep(e){return new Set([...e.resources?.d1??[],...e.resources?.kv??[],...e.resources?.r2??[],...(e.resources?.durableObjects??[]).map(t=>t.name),...(e.resources?.workflows??[]).map(t=>t.name),...(e.resources?.hyperdrive??[]).map(t=>t.name),...(e.resources?.queues??[]).map(t=>t.name),...e.resources?.ai??[],...e.resources?.browser??[],...e.resources?.images??[],...(e.resources?.vectorize??[]).map(t=>t.name),...(e.resources?.aiGateway??[]).map(t=>t.name),...(e.resources?.sendEmail??[]).map(t=>t.name),...(e.resources?.secretsStore??[]).map(t=>t.name),...(e.resources?.analyticsEngine??[]).map(t=>t.name),...(e.workers??[]).flatMap(t=>t.binding?[t.binding]:[]),...e.database?["DATABASE_PROVIDER"]:[],"ASSETS"])}function fg(e,t){if(t==="service_binding")return[];if(t!=="dispatch")return[`apps on tier "${t}" can't be deployed`];let s=[];return e.resources?.hyperdrive?.length&&s.push("resources.hyperdrive: Hyperdrive isn't available to apps in a dispatch namespace (an account holds at most 25 configs)"),e.resources?.r2?.length&&s.push("resources.r2: R2 buckets aren't available to apps in a dispatch namespace yet"),e.resources?.queues?.length&&s.push("resources.queues: Queues aren't available to apps in a dispatch namespace yet"),e.resources?.ai?.length&&s.push("resources.ai: the Workers AI binding isn't available to apps in a dispatch namespace (it bills the platform's account); list the workers-ai provider instead"),e.resources?.browser?.length&&s.push("resources.browser: Browser Rendering isn't available to apps in a dispatch namespace (it bills the platform's account)"),e.resources?.images?.length&&s.push("resources.images: the Images binding isn't available to apps in a dispatch namespace (it bills the platform's account)"),e.resources?.vectorize?.length&&s.push("resources.vectorize: Vectorize indexes aren't available to apps in a dispatch namespace yet"),e.resources?.aiGateway?.length&&s.push("resources.aiGateway: AI Gateways aren't available to apps in a dispatch namespace yet"),e.resources?.sendEmail?.length&&s.push("resources.sendEmail: Email sending bindings aren't available to apps in a dispatch namespace (they send through the Gateway's email capability)"),e.resources?.secretsStore?.length&&s.push("resources.secretsStore: Secrets Store secrets aren't available to apps in a dispatch namespace (the store is the platform account's)"),e.resources?.analyticsEngine?.length&&s.push("resources.analyticsEngine: Analytics Engine datasets aren't available to apps in a dispatch namespace (their names are account-wide and their writes bill the platform's account)"),e.email?.inbound===!0&&s.push(Td),e.secrets?.length&&s.push("secrets: third-party apps can't have secrets of their own yet"),s}function gg(e){return e.startsWith("every-")?e:`every-${e}`}var zr="every-app-gateway",tp=63;function sp(e){let t=e.toLowerCase();return t===zr||t.startsWith(`${zr}-`)}var go="--";function Is({appId:e,orgKey:t}){if(!t)throw new Error("An org-scoped Worker name needs an org key.");return`every-${t}-${e}`}function yg(e){return sp(e.workerName)||e.workerName.length>tp||!e.orgKey||e.appId.includes(go)?!1:e.workerName===Is(e)}function wg(e,t){return t==="DB"||t==="KV"?e:me(e,t)}var Eg=63;function bg(e,t){return t==="R2"?e:me(e,t)}var np=63,rp=/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;function _g(e,t){return me(e,t)}function Ag(e){return e.length<=np&&rp.test(e)}var kg=64;function Sg(e,t){return me(e,t)}var Ts=64,op=12,ap=/^[a-z0-9]+(?:-[a-z0-9]+)*$/;function vg(e){return e.length<=Ts&&ap.test(e)}function Kr(e,t){return`${e}-${t.toLowerCase().replaceAll("_","-")}`}function Ig(e,t){return me(e,t)}function Tg(e,t){return me(e,t)}function me(e,t){let s=t.toLowerCase().replaceAll("_","-");return`${e}${go}${s}`}function yo(e){if(!e.startsWith("/"))throw new k(`Public route path must be absolute (start with "/"): ${JSON.stringify(e)}`);if(e==="/*"||e==="/**"||e==="*"||e==="/")throw new k(`Public route "${e}" exposes the entire app. A catch-all public route is not allowed.`);if(e.includes("%"))throw new k(`Public route "${e}" must not contain percent-encoding; declare the decoded path.`);if(e.includes("\\"))throw new k(`Public route "${e}" must not contain backslashes.`);let t=e.split("/");if(t.some(n=>n==="."||n===".."))throw new k(`Public route "${e}" must not contain "." or ".." segments.`);for(let n of t)if(n.startsWith(":")&&!/^:[A-Za-z_][A-Za-z0-9_]*$/.test(n))throw new k(`Public route "${e}" has an invalid named segment "${n}".`);let s="/"+(t[1]??"");if(e===X||e.startsWith(X+"/")||s===X)throw new k(`Public route "${e}" targets the reserved ${X} namespace, which can never be public.`)}function Hr(e){return!e.trim()||e.startsWith("/")||/^[A-Za-z]:[\\/]/.test(e)?!1:!e.split(/[\\/]+/).some(t=>t==="..")}var ip="APP__";function xg(e){return`${ip}${e}`}var Rg=Object.freeze({manifest:"manifest",stamp:"stamp",worker:"worker",modulePrefix:"module:",assetPrefix:"asset:",migrationPrefix:"migration:"});var cp={DNS_RECORD_CONFLICT:"--force-dns",DNS_UNREADABLE:"--force-dns",CAA_BLOCKS_ISSUANCE:"--force-dns",DURABLE_OBJECT_REMOVED:"--allow-delete-durable-object-data",WORKFLOW_REMOVED:"--allow-delete-workflows",EMAIL_ROUTING_DISABLED:"--enable-email-routing",CONFIRMATION_REQUIRED:"--yes"},P=class extends Error{code;retryable;fix;rerun;rerunNote;authorize;data;constructor(t,s,n={}){super(s),this.name="EveryAppError",this.code=t,this.retryable=n.retryable??!1,this.fix=n.fix;let r=cp[t];this.rerun=n.rerun??(r?x([r]):this.retryable?x():void 0),this.rerunNote=n.rerunNote,this.authorize=n.authorize??r!==void 0,this.data=n.data}},It=class extends Error{action;url;rerun;rerunNote;data;constructor(t,s,n,r={}){super(s),this.name="ActionRequiredError",this.action=t,this.url=n,this.rerun=r.rerun===void 0?x():r.rerun,this.rerunNote=r.rerunNote,this.data=r.data}},wo=class extends P{constructor(t="Cancelled. Nothing changed."){super("CANCELLED",t),this.name="CancelledError"}},xs=new WeakMap;function Lg(e,t){return t&&typeof e=="object"&&e!==null&&(xs.has(e)||xs.set(e,t)),e}function Eo(e){return typeof e=="object"&&e!==null?xs.get(e):void 0}function Mg(e){return e instanceof Error?e.message:String(e)}var W=class extends Error{kind;apiCodes;exitCode;stderr;stdout;constructor(t,s){super(t.message),this.name="CfError",this.kind=t.kind,this.apiCodes=t.apiCodes,this.exitCode=s.exitCode,this.stderr=s.stderr,this.stdout=s.stdout??""}};function Le(e,t){return e instanceof W&&e.kind===t}function jg(e){return Le(e,"r2_not_enabled")||Le(e,"access_not_enabled")}var fe=class extends Error{constructor(t,s,n){super(`\`${t}\` did not finish within ${Math.round(s/1e3)}s`+(n?` (last output: ${n})`:"")),this.name="CfTimeoutError"}},Z=class extends Error{constructor(t,s){super(`Unexpected output from \`${t}\`: ${s}`),this.name="CfOutputError"}},dp=/Aborting the upload operation because of conflicts/,pp=[["d1_id_rejected",e=>/Expected a D1 database ID/.test(e)],["subdomain_missing",e=>/workers\.dev subdomain|\/workers\/onboarding/.test(e)],["email_unverified",(e,t)=>t.includes(10034)],["r2_not_enabled",(e,t)=>t.includes(10042)],["access_not_enabled",e=>/access\.api\.error\.not_enabled/.test(e)],["queue_consumer_worker",(e,t)=>t.includes(10064)],["queue_in_use",(e,t)=>t.includes(11005)],["free_plan",e=>/Workers Paid|paid plan/i.test(e)],["auth",(e,t)=>t.includes(1e4)||t.includes(9109)||/No authentication token found|Not logged in|cf auth login/.test(e)],["already_exists",(e,t)=>t.includes(7502)||t.includes(10014)||t.includes(11009)||/\bvectorize\.index\.duplicate_name\b/.test(e)||/\balready exists\b/i.test(e)],["not_found",(e,t)=>t.includes(10007)||t.includes(10009)||t.includes(7404)||t.includes(10200)||t.includes(11e3)||/\bvectorize\.index\.(not_found|deleted)\b/.test(e)||/\bnot found\b|does not exist/i.test(e)]];function bo(e,t){return/^Aborted\.$/m.test(t)?new W({message:`\`${e}\` asked for a confirmation no one could give, and did nothing (it printed "Aborted.").`,apiCodes:[],kind:"aborted"},{exitCode:0,stderr:t}):null}function _o(e,t=""){let s=up(e)??hp(t,e),n=[...s.matchAll(/\[(?:code: )?(\d{4,})\]/g)].map(o=>Number(o[1])),r=dp.test(`${t}
|
|
7
|
+
${e}`)?"strict_conflict":pp.find(([,o])=>o(s,n))?.[0]??"unknown";return{message:s,apiCodes:n,kind:r}}function up(e){let t=e.split(/\r?\n/),s=t.findIndex(o=>/^┌\s*(API)?Error/.test(o.trim()));if(s<0)return;let n=[];for(let o of t.slice(s+1)){let a=o.trim();if(a.startsWith("\u2514"))break;n.push(a.replace(/^│ ?/,""))}let r=lp(n);return r.length>0?r:void 0}function lp(e){let t=[],s="";for(let n of e)n.trim().length===0?(s&&t.push(s),t.push(""),s=""):/^\s/.test(n)||/^\d+\./.test(n.trim())?(s&&t.push(s),s=n.trimEnd()):s=s?`${s} ${n.trim()}`:n.trim();return s&&t.push(s),t.join(`
|
|
8
|
+
`).replace(/\n{3,}/g,`
|
|
9
|
+
|
|
10
|
+
`).trim()}function hp(...e){return re(...e).join(`
|
|
11
|
+
`)||"cf failed without an error message"}var Rs=new Set;function Ao(e){return Rs.add(e),()=>Rs.delete(e)}function Tt(){for(let e of Rs)e()}function ko(){return!!process.stdout.isTTY&&process.env.TERM!=="dumb"&&!process.env.CI}function Kg(e,t=process.env,s=!!process.stdout.isTTY){return!e&&!t.NO_COLOR&&s&&t.TERM!=="dumb"}import{AsyncLocalStorage as yp}from"node:async_hooks";import mp from"chalk";import{spawn as fp}from"node:child_process";import{once as So}from"node:events";var Q=process.platform!=="win32",gp=1e3;function vo({command:e,args:t,cwd:s,env:n,shell:r=!1,hold:o}){let a=fp(e,t,{cwd:s,shell:r,env:o&&mp.level>0?{...n,FORCE_COLOR:"1"}:n,stdio:["ignore",o?"pipe":"inherit",o?"pipe":"inherit"],detached:Q}),i=o?[]:null,d=o?Promise.race([Promise.all([So(a.stdout,"end"),So(a.stderr,"end")]),new Promise(u=>setTimeout(u,1e3).unref())]):Promise.resolve();if(o)for(let[u,h]of[[a.stdout,process.stdout],[a.stderr,process.stderr]])u.on("data",w=>{i?i.push({to:h,chunk:w}):h.write(w)});return{exited:new Promise((u,h)=>{a.once("error",h),a.once("exit",(w,f)=>{d.then(()=>u({code:w,signal:f}))})}),stop:u=>xt(a,Q,u),releaseOutput:u=>{let h=i??[];if(i=null,u)for(let{to:w,chunk:f}of h)w.write(f)}}}function xt(e,t,s="SIGTERM"){e.pid!==void 0&&(Pt(e,t,s),s!=="SIGKILL"&&setTimeout(()=>Pt(e,t,"SIGKILL"),gp).unref())}function Pt(e,t,s){let n=e.pid;if(n!==void 0)try{t?process.kill(-n,s):e.kill(s)}catch{}}var wp=3e3,Ep=1e4,bp=["SIGINT","SIGTERM"],ge=new Set,Ct=new Set,ee=new Set,Io=new WeakSet,Ro=new yp,To=!1,Me=!1,Rt;function Oo(e,t){let s={child:e,group:t,exited:new Promise(n=>{e.exitCode!==null||e.signalCode!==null?n():e.once("close",()=>n())})};return Me&&!Ro.getStore()&&Ot(s,"SIGKILL"),ge.add(s),Nt(),()=>{ge.delete(s),Nt()}}function Zg(){return Me}function Qg(e){return Rt=e,()=>{Rt===e&&(Rt=void 0)}}function Co(e){return ee.add(e),Nt(),()=>{ee.delete(e),Nt()}}function Ns(e){return Ct.add(e),()=>Ct.delete(e)}function _p(){let e=[...new Set([...ee].flatMap(n=>n.label?[n.label]:[]))],t=[...ge.size>0&&!e.some(n=>n.startsWith("stopping "))?["stopping cf"]:[],...e];if(t.length===0)return"Stopping";let s=t.length===1?t[0]:`${t.slice(0,-1).join(", ")} and ${t.at(-1)}`;return Ve(s)}function Ap(e){for(let t of[...e].reverse()){let s=t.closing?.();if(s!==void 0)return s}return"Stopped."}function Po(e,t){Ct.size===0&&process.stderr.write(t);for(let s of Ct)e(s)}function Nt(){let e=ge.size>0||ee.size>0;if(!(e===To||Me)){To=e;for(let t of bp)e?process.on(t,xo):process.off(t,xo)}}function xo(e){kp(e)}async function kp(e,{exit:t=s=>process.exit(s)}={}){let s=e==="SIGTERM"?143:130;if(Me){if(e==="SIGTERM")return;for(let d of ge)Ot(d,"SIGKILL");Os(),t(s);return}Me=!0,Tt();let n=Rt,r=n===void 0?_p():n?`Stopping ${n}`:"";r&&Po(d=>d.stopping(r),`
|
|
12
|
+
${r} (Ctrl+C again to quit at once)...
|
|
13
|
+
`);let o=[...ee],a=[...ge];for(let d of a)Ot(d,e);let i=Promise.all(a.map(d=>d.exited));if(!await Cs(i,wp)){for(let d of a)Ot(d,"SIGKILL");await Cs(i,1e3)}if(Os(),await Cs(Sp(),Ep),Os(),n===void 0){let d=Ap(o);Po(p=>p.stopped(d),d?`${d}
|
|
14
|
+
`:"")}t(s)}async function Sp(){for(let e of[...ee].reverse())e.async&&await Ro.run(!0,()=>e.async()).catch(()=>{})}function Os(){for(let e of[...ee])if(!Io.has(e)){Io.add(e);try{e.sync?.()}catch{}}}function Ot({child:e,group:t},s){Pt(e,t,s)}async function Cs(e,t){let s,n=new Promise(r=>{s=setTimeout(()=>r(!1),t)});try{return await Promise.race([e.then(()=>!0),n])}finally{clearTimeout(s)}}var ye="22.18.0",$s="--dns-result-order=ipv4first";function No(e){let t=(e??"").trim();return t.split(/\s+/).includes($s)?t:t?`${t} ${$s}`:$s}function Ds(e){return vp(e,ye)>=0}function ny(e=process.versions){return e.bun?new P("UNSUPPORTED_RUNTIME",`everyapp runs on Node.js, not Bun
|
|
15
|
+
The Cloudflare CLI can't load cloudflare.config.ts under Bun.`,{rerun:x(),rerunNote:`with Node.js ${ye} or newer`}):Ds(e.node)?null:new P("UNSUPPORTED_RUNTIME",`everyapp needs Node.js ${ye} or newer; this is ${e.node}
|
|
16
|
+
The Cloudflare CLI loads cloudflare.config.ts with Node's built-in TypeScript support.`,{fix:"install Node 22 or 24, then run the command again"})}function vp(e,t){let s=o=>o.replace(/^v/,"").split(/[.-]/).slice(0,3).map(a=>Number.parseInt(a,10)||0),[n,r]=[s(e),s(t)];for(let o=0;o<3;o+=1){let a=(n[o]??0)-(r[o]??0);if(a!==0)return a}return 0}import Tp from"node:path";import{fileURLToPath as Pp}from"node:url";import $o from"node:fs/promises";import Ge from"node:path";async function Do(e,t,s){let n=Ge.resolve(e);try{let r=await Ip(n,t),o=JSON.parse(await $o.readFile(r,"utf-8")),a=typeof o.bin=="string"?o.bin:o.bin?.[s];if(!a)throw new Error(`Package does not declare the "${s}" binary.`);return{version:o.version??"unknown",binPath:Ge.resolve(Ge.dirname(r),a)}}catch(r){throw new Error(`Could not resolve the project-local "${s}" binary from project root "${n}". Install the project's declared ${t} dependency and try again. (If the install skipped devDependencies, include them; Yarn Plug'n'Play projects are not supported \u2014 use nodeLinker: node-modules.)`,{cause:r})}}async function Ip(e,t){let s=e;for(;;){let n=Ge.join(s,"node_modules",...t.split("/"),"package.json");try{return await $o.realpath(n)}catch{}let r=Ge.dirname(s);if(r===s)break;s=r}throw new Error(`${t} is not installed under ${e} or any directory above it.`)}var xp=sn.cf;function Rp(){return Lo(Tp.dirname(Pp(import.meta.url)),"cli")}async function Lo(e,t){let{binPath:s,version:n}=await Do(e,"cf","cf");return{path:s,version:n,source:t}}var Op="EVERYAPP_CF_BINARY";async function Mo(e){let t=process.env[Op];if(t)return{path:t,version:xp,source:"cli"};if(e)try{return await Lo(e,"project")}catch{}return Rp()}import Ue from"node:fs/promises";import Go from"node:path";async function Cp(e,t,s={}){let n=s.exclude||[];await Ue.mkdir(t,{recursive:!0});let r=await Ue.readdir(e,{withFileTypes:!0});for(let o of r){let a=Go.join(e,o.name),i=Go.join(t,o.name);n.some(d=>o.name===d)||(o.isDirectory()?await Cp(a,i,s):await Ue.copyFile(a,i))}}async function fy(e){try{return(await Ue.stat(e)).isDirectory()}catch{return!1}}async function gy(e){try{return await Ue.access(e),!0}catch{return!1}}function we(e){return e?.code==="ENOENT"}import jo from"node:fs/promises";import $t from"node:path";import{execa as jp}from"execa";import Np from"node:fs";import Uo from"node:fs/promises";import $p from"node:os";import Ls from"node:path";import Dp from"chalk";import{execa as Lp}from"execa";async function Ms(e,t,s){let n=[e,...t].join(" "),r=await Gp(s.logName??n),o=Np.createWriteStream(r,{flags:"a",mode:384}),a=`$ ${n}
|
|
17
|
+
# in ${s.cwd??process.cwd()}
|
|
18
|
+
|
|
19
|
+
`;o.write(a);let i=s.echo?Mp(n):null,d=f=>{o.write(f),i?.write(f)},p=Lp(e,[...t],{cwd:s.cwd,env:s.env,shell:s.shell,stdin:"ignore",stdout:"pipe",stderr:"pipe",buffer:!1,reject:!1});p.stdout?.on("data",d),p.stderr?.on("data",d);let u=await p;if(i?.end(),await new Promise(f=>o.end(f)),!u.failed)return;let h=await Up(r,a.length),w=u.exitCode!==void 0?`${u.command} exited with code ${u.exitCode}`:u.signal?`${u.command} was stopped by ${u.signal}`:u.shortMessage;throw new P(s.code??"COMMAND_FAILED",[`${s.what} failed`,`${w}.${h.length>0?" Its last lines:":""}`,...h.map(f=>` ${f}`),`Full log: ${r}`].join(`
|
|
20
|
+
`),{...s.fix?{fix:s.fix}:{},data:{command:n,exitCode:u.exitCode??null,tail:h,log:r}})}function Mp(e){let t=n=>process.stderr.write(`${Dp.dim(` ${n}`)}
|
|
21
|
+
`);t(`$ ${e}`);let s="";return{write:n=>{let r=`${s}${n.toString("utf8")}`.split(/\r?\n/);s=r.pop()??"";for(let o of r)t(o)},end:()=>{s&&t(s),s=""}}}async function Gp(e){let t=Ls.join($p.tmpdir(),"everyapp");await Uo.mkdir(t,{recursive:!0,mode:448});let s=e.split(/\s+/).slice(0,2).map(r=>Ls.basename(r).replace(/[^\w.-]+/g,"")).filter(Boolean).join("-")||"command",n=new Date().toISOString().replace(/[:.]/g,"-");return Ls.join(t,`${s}-${n}-${process.pid}.log`)}async function Up(e,t){return re((await Uo.readFile(e,"utf8").catch(()=>"")).slice(t))}async function zp(){try{return await jp("pnpm",["--version"],{stdio:"pipe"}),!0}catch{return!1}}async function Cy({cwd:e,description:t,install:s,verbose:n=!1}){if(s===!1)return;let r=t.replace(/\.+$/,"");if(typeof s=="string"){await Ms(s,[],{cwd:e,shell:!0,echo:n,what:r,code:"INSTALL_FAILED"});return}let o=await Us(e),{command:a,args:i}=await Hp(o);await Ms(a,i,{cwd:e,echo:n,what:`${r} with ${o}`,code:"INSTALL_FAILED"})}async function Us(e){let t=await Kp(e);return t||(await Gs($t.join(e,"pnpm-lock.yaml"))?"pnpm":await Gs($t.join(e,"yarn.lock"))?"yarn":await Gs($t.join(e,"package-lock.json"))?"npm":"pnpm")}async function Kp(e){let t=$t.join(e,"package.json");try{let n=JSON.parse(await jo.readFile(t,"utf-8")).packageManager;return typeof n!="string"?null:n.startsWith("pnpm")?"pnpm":n.startsWith("yarn")?"yarn":n.startsWith("npm")?"npm":null}catch(s){if(we(s))return null;throw s}}async function Hp(e){return e==="yarn"?{command:"yarn",args:["install"]}:e==="npm"?{command:"npm",args:["install"]}:await zp()?{command:"pnpm",args:["install"]}:{command:"npx",args:["pnpm","install"]}}async function Gs(e){try{return await jo.access(e),!0}catch(t){if(we(t))return!1;throw t}}import{spawn as nu}from"node:child_process";import ru from"node:fs/promises";import Dt from"node:path";import{createHash as Wp}from"node:crypto";import v from"node:fs/promises";import{rmSync as Bp}from"node:fs";import js from"node:os";import M from"node:path";var Fp="cloudflare.config.ts",ze=448,Ko=18;async function Ho(){return Ks("neutral")}var Wo="files-";async function Yp(e){let t=await Ks("tmp");return await qp(t),v.mkdtemp(M.join(t,`${e}${process.pid}-`))}async function Bo(e){let t=await Yp(e),s=Co({sync:()=>Bp(t,{recursive:!0,force:!0})});return{dir:t,cleanup:async()=>{await v.rm(t,{recursive:!0,force:!0}),s()}}}var Vp=24*60*6e4;async function qp(e){let t=Date.now()-Vp;for(let s of await v.readdir(e).catch(()=>[])){let n=Number(/-(\d+)-[^-]+$/.exec(s)?.[1]);if(n&&Jp(n))continue;let r=M.join(e,s),o=await Vo(r).catch(()=>null);o&&o.ctimeMs<t&&await v.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}function Jp(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}async function Fo(){if(process.platform==="win32")return M.dirname(process.execPath);let e=await Ks("bin"),t=M.join(e,Wp("sha256").update(process.execPath).digest("hex").slice(0,16));await zs(t);let s=M.join(t,"node");if(await v.readlink(s).catch(()=>null)!==process.execPath){await v.rm(s,{force:!0});try{await v.symlink(process.execPath,s)}catch(n){if(n.code!=="EEXIST")throw n}}return t}async function Ks(e){await Xp();let t=M.join(js.homedir(),".everyapp");await Zp(t);let s=M.join(t,"cf");await zs(s);let n=M.join(s,e);return await zs(n),await Qp(n),n}async function Xp(){let e=Number(process.env.SUDO_UID);if(process.getuid?.()!==0||!Number.isInteger(e)||e===0)return;if((await v.stat(js.homedir()).catch(()=>null))?.uid===e)throw new P("UNSAFE_CF_DIRECTORY",`everyapp is running as root (sudo) with your HOME
|
|
22
|
+
It would leave ~/.everyapp in ${js.homedir()} to root.`,{fix:"run it without sudo"})}async function Zp(e){let t;try{t=await v.stat(e)}catch(n){if(!we(n))throw n;await v.mkdir(e,{recursive:!0,mode:ze});return}if(!t.isDirectory())throw je(e,"isn't a directory");let s=Yo(t);if(s){if(t.uid!==process.getuid?.()||!(t.mode&Ko))throw je(e,s);for(let n of await v.readdir(e))if((await v.lstat(M.join(e,n))).uid!==t.uid)throw je(e,`${s}, and ${n} in it belongs to another user`);await v.chmod(e,ze)}}async function zs(e){try{let t=await Vo(e);if(t&&zo(t))return;t&&await v.rm(e,{recursive:!0,force:!0});try{await v.mkdir(e,{mode:ze})}catch(n){if(n.code!=="EEXIST")throw n}if((await v.lstat(e)).isDirectory()&&await v.chmod(e,ze),!zo(await v.lstat(e)))throw je(e,"can't be made a private directory")}catch(t){throw t instanceof P?t:je(e,`can't be made a private directory (${t.message}; was everyapp run with sudo?)`)}}function zo(e){if(!e.isDirectory())return!1;let t=process.getuid?.();return t===void 0?!0:e.uid===t&&(e.mode&511)===ze}function Yo(e,{uid:t=process.getuid?.(),parent:s=!1}={}){return t===void 0?null:e.uid===t||e.uid===0||s&&t===0?e.mode&Ko?"is writable by other users":null:"is owned by another user"}async function Qp(e){for(let t=await v.realpath(e);;t=M.dirname(t)){let s=Yo(await v.lstat(t),{parent:!0});if(s)throw new P("UNSAFE_CF_DIRECTORY",`${t} ${s}, so everyapp won't run cf below it
|
|
23
|
+
cf runs any cloudflare.config.ts it finds in a parent of its working directory (here ${e}).`,{fix:`make it writable only by you (chmod go-w "${t}"), or run everyapp with a HOME that is`});let n=M.join(t,Fp);if(await eu(n))throw new P("UNSAFE_CF_DIRECTORY",`cf would run ${n} in every command everyapp starts
|
|
24
|
+
cf loads a cloudflare.config.ts from any parent of its working directory (here ${e}).`,{fix:"move that file into a project directory",rerun:x()});if(M.dirname(t)===t)return}}function je(e,t){return new P("UNSAFE_CF_DIRECTORY",`${e} ${t}
|
|
25
|
+
everyapp runs cf and keeps the files it hands to cf (secrets among them) there, so only you may be able to write to it.`,{fix:"fix or remove it",rerun:x()})}async function Vo(e){try{return await v.lstat(e)}catch(t){if(we(t))return null;throw t}}async function eu(e){try{return(await v.stat(e)).isFile()}catch{return!1}}import{execa as tu}from"execa";var su=6e4;function Hs(e){return e[0]==="build"||e[0]==="dev"}async function Ws(e,t){let s=["node","-p","process.versions.node"],n,r;try{n=await Us(e);let o=n==="yarn"?s:n==="npm"?["exec","--",...s]:["exec",...s],{stdout:a}=await tu(n,o,{cwd:e,env:t,extendEnv:!1,stdin:"ignore",timeout:su});r=a.trim().split(`
|
|
26
|
+
`).at(-1)?.trim()??""}catch{return}if(!(!/^\d+\.\d+\.\d+$/.test(r)||Ds(r)))throw new P("NODE_TOO_OLD",`${n} runs this project's tools on Node.js ${r}; cf needs ${ye} or newer
|
|
27
|
+
everyapp runs on ${process.versions.node}, but something pins this project's (a Volta \`volta.node\` in package.json, pnpm's use-node-version). cf needs ${ye} or newer to load cloudflare.config.ts.`,{fix:"raise the pin (`volta pin node@22`, for Volta)",rerun:x()})}var ou=12e4,au=2e3;function cw(e={}){let t=e.resolveBinary??Mo,s=e.env??process.env,n=e.watchdogIdleMs??au,r;async function o(a,i,d={}){let p={...s,CF_DELEGATION:"1",...i==="interactive"?{}:{NO_COLOR:"1"},...i==="json"?{CF_QUIET:"1"}:{},...e.accountId?{CLOUDFLARE_ACCOUNT_ID:e.accountId}:{},...a==="project"?{NODE_OPTIONS:No(s.NODE_OPTIONS)}:{},...d};return r??=Fo(),uu(p,await r)}return{async run(a){let i=await cu(a),d=await t(a.plane==="project"&&!a.cliCf?i:void 0),p=a.files?await du(a.files):null;try{let u=typeof a.args=="function"?a.args(p?.paths??{}):[...a.args],h=await o(a.plane,a.mode,a.env);return a.plane==="project"&&Hs(u)&&await Ws(i,h),await pu({binary:d,args:u,cwd:i,env:h,onOutput:a.onOutput,mode:a.mode,timeoutMs:a.timeoutMs??(a.mode==="interactive"?void 0:ou),watchdogIdleMs:a.local?n:void 0})}finally{await p?.remove()}},async start(a){let i=await t(a.cwd),d=await o("project","interactive",a.env);return Hs(a.args)&&await Ws(a.cwd,d),vo({command:process.execPath,args:[i.path,...a.args],cwd:a.cwd,env:d,hold:a.holdOutput??!1})}}}async function iu(e,t,s){let n=await e.run({...t,mode:"json"}),r=qo(t.args),o;try{o=JSON.parse(n.stdout)}catch{throw new Z(r,"stdout is not JSON")}let a=s.safeParse(o);if(!a.success)throw new Z(r,a.error.message);return a.data}async function dw(e,t,s,{perPage:n,maxPages:r}){let o=[];for(let a=1;a<=r;a+=1){let i=await iu(e,{plane:"account",args:[...t,"--per-page",String(n),"--page",String(a)]},s);if(o.push(...i),i.length<n)break}return o}async function cu(e){if(e.plane==="project"){if(!e.cwd)throw new Error("project-plane cf calls need a cwd");return e.cwd}return Ho()}async function du(e){let{dir:t,cleanup:s}=await Bo(Wo),n={};try{for(let[r,o]of Object.entries(e)){let a=Dt.join(t,Dt.basename(r));await ru.writeFile(a,typeof o=="string"?o:JSON.stringify(o),{mode:384}),n[r]=a}}catch(r){throw await s(),r}return{paths:n,remove:s}}function pu(e){let t=qo(e.args),s=e.mode==="interactive";return s&&Tt(),new Promise((n,r)=>{let o=nu(process.execPath,[e.binary.path,...e.args],{cwd:e.cwd,env:e.env,stdio:s?"inherit":["ignore","pipe","pipe"],detached:!s&&Q}),a=Oo(o,!s&&Q),i="",d="",p=!1,u,h=A=>{p||(p=!0,a(),clearTimeout(f),clearTimeout(u),A())},w=e.timeoutMs,f=w===void 0?void 0:setTimeout(()=>{xt(o,!s&&Q),h(()=>r(new fe(t,w,re(d).at(-1)?.trim())))},w),l=()=>{e.watchdogIdleMs===void 0||p||!u&&!lu(i)||(clearTimeout(u),u=setTimeout(()=>{xt(o,Q),h(()=>n({stdout:i,stderr:d,stoppedByWatchdog:!0}))},e.watchdogIdleMs))};for(let[A,E]of[[o.stdout,b=>i+=b],[o.stderr,b=>d+=b]])A?.on("data",b=>{E(b.toString()),e.onOutput?.(b.toString()),l()});o.once("error",A=>h(()=>r(A))),o.once("close",A=>{h(()=>{if(A===0){let b=bo(t,d);b?r(b):n({stdout:i,stderr:d,stoppedByWatchdog:!1});return}let E=s?{message:`\`${t}\` exited with code ${A}`,apiCodes:[],kind:"unknown"}:_o(d,i);r(new W(E,{exitCode:A,stderr:d,stdout:i}))})})})}function uu(e,t){let s=Object.keys(e).find(r=>r.toUpperCase()==="PATH")??"PATH",n=(e[s]??"").split(Dt.delimiter).filter(r=>r&&r!==t);return{...e,[s]:[t,...n].join(Dt.delimiter)}}function lu(e){let t=e.trim();if(!t)return!1;try{return JSON.parse(t),!0}catch{return!1}}function qo(e){return typeof e=="function"?"cf":["cf",...e].join(" ")}function Jo(e){let t=Math.max(0,Math.round(e/1e3));return t<60?`${t}s`:t<3600?`${Math.round(t/60)}m`:`${Math.round(t/3600)}h`}function Lt(e){let t=e/1e3;if(t<10)return`${t.toFixed(1)}s`;if(t<60)return`${Math.round(t)}s`;let s=Math.round(t);return`${Math.floor(s/60)}m ${s%60}s`}function uw(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${String(t%60).padStart(2,"0")}s`}import hu from"node:fs";var Xo="EVERYAPP_EVENT_LOG",Bs;function Fs(){let e=process.env[Xo];return e?(Bs?.path!==e&&(Bs={path:e,log:mu(e)}),Bs.log):null}function mu(e){let t=!1;return{append(s){if(!t)try{let n=`${JSON.stringify({...s,pid:process.pid})}
|
|
28
|
+
`;hu.appendFileSync(e,n,{mode:384})}catch(n){t=!0;let r=n instanceof Error?n.message:String(n);process.stderr.write(`everyapp: can't write ${Xo}=${e} (${r}); not logging
|
|
29
|
+
`)}}}}function mw({argv:e,json:t}){Fs()?.append({type:"invocation",ts:new Date().toISOString(),argv:[...e],cwd:process.cwd(),json:t,isatty:{stdin:!!process.stdin.isTTY,stdout:!!process.stdout.isTTY,stderr:!!process.stderr.isTTY},ci:!!process.env.CI})}function Zo(e,t){Fs()?.append({v:1,ts:t.toISOString(),...e})}function fw(e,t){Fs()?.append({type:"exit",ts:new Date().toISOString(),code:(e%256+256)%256,ms:t})}import{stripVTControlCharacters as fu}from"node:util";import Qo from"chalk";var Ys=e=>fu(e).length,gu=(e,t)=>e+" ".repeat(t-Ys(e));function ea(e){let t=Math.max(...e.map(s=>s.label.length));return e.map(s=>`${Qo.dim(s.label.padEnd(t))} ${s.value}`)}function Ew(e,t){let s=e.map((r,o)=>Math.max(Ys(r),...t.map(a=>Ys(a[o]??"")))),n=r=>r.map((o,a)=>a===r.length-1?o:gu(o,s[a])).join(" ");return[Qo.dim(n(e)),...t.map(n)]}import y from"chalk";import na from"cli-cursor";function _w(e){return(e?.public??[]).map(t=>sa(t.path,t.methods))}function Aw(e){if(typeof e!="string")return[];try{let s=JSON.parse(e)?.public;return Array.isArray(s)?s.flatMap(n=>{let r=n?.path;if(typeof r!="string")return[];let o=n.methods;return[sa(r,Array.isArray(o)?o.filter(a=>typeof a=="string"):void 0)]}):[]}catch{return[]}}function kw(e){return e?.mcp?{by:e.mcp.by,why:e.mcp.why}:null}function Sw(e){if(typeof e!="string")return null;try{let s=JSON.parse(e)?.mcp;if(!s||typeof s!="object")return null;let{by:n,why:r}=s;return n!=="gateway"&&n!=="app"||typeof r!="string"?null:{by:n,why:r}}catch{return null}}var vw=e=>`MCP /mcp (${e.by})`;function ta(e,t=6){return{shown:e.slice(0,t).map(s=>`${s.methods.join("/")} ${s.path}`).join(", "),more:Math.max(0,e.length-t)}}function sa(e,t){return{path:e,methods:(t??["GET"]).map(s=>s.toUpperCase())}}function ua(e=s=>process.stdout.write(s),t=()=>new Date){let s=ha(n=>{let r=n.type==="done"?{...n,display:void 0}:n;e(`${JSON.stringify({v:1,ts:t().toISOString(),...r})}
|
|
30
|
+
`)},!1,()=>t().getTime());return Ns({stopping:n=>s.emit({type:"progress",step:"interrupt",message:n}),stopped:()=>{}}),s}function la(e={}){let t=e.verbose??!1,s=e.terminal??!1,n=e.now??Date.now,r=n(),o=e.writeProblem??(l=>void process.stderr.write(l)),a=new Js(e.write??(l=>void process.stdout.write(l)),s,e.columns??(()=>process.stdout.columns??80),n);s&&Ao(()=>a.handOver()),Ns({stopping:l=>a.interrupt(`${l} (Ctrl+C again to quit at once)`),stopped:l=>{a.finish(),l&&o(`${y.dim(l)}
|
|
31
|
+
`)}});let i=l=>a.aside(()=>o(`${l.join(`
|
|
32
|
+
`)}
|
|
33
|
+
`)),d=new Map,p=new Set,u=[],h=0,w=0,f=(l,A)=>{for(let E of l)if("line"in E)a.lines(E.line);else if("fact"in E)u.splice(E.lead?w++:u.length,0,E.fact);else if("done"in E){let b=E.detail??(A!==void 0&&A>=1e3?Lt(A):"");a.lines([wu(E.done,b),...(E.notes??[]).map(S=>y.dim(` ${S}`))].join(`
|
|
34
|
+
`))}};return ha(l=>{switch(l.type){case"step":{for(let S of p)S!==l.step&&(a.drop(S),p.delete(S),d.delete(S));let A=Eu[l.step]?.(l,S=>d.has(S)),E=A?[A].flat():[];if(l.status==="start"){d.set(l.step,n());let S=E.find(U=>"spin"in U);E.length===0&&t&&!s&&l.message&&a.lines(y.dim(l.message)),f(E),a.spin(l.step,S?S.spin:E.length>0?"":l.message??"");return}let b=d.get(l.step);d.delete(l.step),p.delete(l.step),a.stopSpinning(l.step),E.length>0?f(E,b===void 0?void 0:n()-b):t&&l.message&&a.lines(y.dim(l.message));return}case"progress":ku.has(l.step)?a.lines(y.dim(l.message)):Au[l.step]?.(l.data??{})?(d.has(l.step)||d.set(l.step,n()),s?a.spin(l.step,l.message):p.has(l.step)||a.lines(l.message),p.add(l.step)):t&&a.lines(y.dim(l.message));return;case"warning":{if(bu.has(l.code)&&!t)return;h+=1,i([...ca(y.yellow("!"),l.message),...qs(l.data,{url:!0})]);return}case"action_required":{let[A="",...E]=l.message.split(`
|
|
35
|
+
`),b=[`${y.cyan("\u2192")} ${A}`,...l.data?.url?[` ${y.cyan(l.data.url)}`]:[],...l.data?.code?[` Code: ${y.bold(l.data.code)}`]:[],...E.map(S=>y.dim(` ${S}`))];if(l.data?.waiting){let S=l.step??l.action;a.lines(b.join(`
|
|
36
|
+
`)),d.set(S,n());let U=g(l.data.waitingFor);a.spin(S,U?`Waiting for ${U}`:"Waiting");return}a.finish(),o(`${[...b,...vu(l.data?.choices),...qs(l.data)].join(`
|
|
37
|
+
`)}
|
|
38
|
+
`);return}case"error":{if(a.finish(),l.code==="CANCELLED"){o(`${y.dim(l.message)}
|
|
39
|
+
`);return}let A=t?g(l.data?.stack):void 0;o(`${[...ca(y.red("\u2717"),l.message),...qs(l.data,{url:!0}),...A?A.split(`
|
|
40
|
+
`).filter(E=>/^\s+at /.test(E)).map(E=>y.dim(` ${E.trim()}`)):[],...t?[y.dim(` Error code: ${l.code}`)]:[]].join(`
|
|
41
|
+
`)}
|
|
42
|
+
`);return}case"done":{a.finish();let A=n()-r,E=[...u,...Iu(l.data?.facts)],b=Ou(l.data?.next),S=[...l.display!==void 0?l.display?[l.display]:[]:l.message?[y.green(l.message)]:[],...E.length>0?["",...ea(E)]:[],...A>=1e4&&l.display===void 0?[y.dim(`Done in ${Lt(A)}${h>0?` with ${B(h,"warning")}`:""}`)]:[],...b.length>0?["","Next:",...Cu(b)]:[]];S.length>0&&a.lines(S.join(`
|
|
43
|
+
`));return}}},t,n)}function zw(e,t){return{emit(s){if(s.type!=="done"){e.emit(s);return}e.emit({type:"step",step:t,status:"ok",...s.message?{message:s.message}:{},...s.data?{data:s.data}:{}})},get exitCode(){return e.exitCode},get verbose(){return e.verbose}}}function wu(e,t){return`${e} ${y.green("\u2713")}${t?` ${y.dim(t)}`:""}`}function ra(e,t){return s=>s.status==="ok"?{done:e,detail:t}:null}function oa(e,t){return s=>s.status==="start"?{spin:e}:s.status==="ok"?{done:t}:null}function Ee(e){return e.status==="start"?{spin:e.message??""}:e.status==="ok"&&e.message?{done:e.message}:null}var Eu={"setup.account":e=>{if(e.status!=="ok")return null;let t=e.data??{};if(t.gateway===!0)return null;let s=g(t.email);return{line:`Setting up EveryApp in ${g(t.name)??g(t.id)}${s?y.dim(` (${s})`):""}`}},"setup.gateway":e=>{let t=e.data??{},s=g(t.releaseName),n=g(t.account),r=n?`${n}'s Gateway`:"the Gateway";if(e.status==="start"){let o=g(t.gatewayUrl)?.replace(/^https:\/\//,"");switch(t.change){case"install":{let a=Tu(t.expectedMinutes);return{line:`Installing the Gateway at ${o} (${s})${a?y.dim(` (usually ${a.min}\u2013${a.max} minutes, then the owner link)`):""}`}}case"resume":return{line:`Resuming the Gateway install at ${o} (${s})`};case"upgrade":return{line:`Upgrading ${r} to ${s}`};case"repair":return{line:`Repairing ${r} (${s})`};case"redeploy":return{line:`Redeploying ${r} (${s})`};default:return null}}if(e.status==="ok"&&t.repaired===!0){let o=$(t.added);if(o.length>0)return{done:`Gateway now routes ${o.join(", ")}`};let a=Number(t.apps??0),i=Number(t.was??a);return{done:`Gateway routes ${B(a,"app")}`,detail:i!==a?`was ${i}`:""}}return e.status!=="skip"?null:t.upToDate===!0?{done:`${Ve(r)} is up to date with ${s}`,detail:""}:e.message?{line:e.message}:null},"setup.owner":e=>{let t=g(e.data?.email);return t?e.status==="skip"?{done:`Owner account is ${t}`,detail:""}:e.status==="ok"?{done:`Owner account created for ${t}`}:null:null},"gateway.migrations":(e,t)=>{let s=t("setup.gateway"),n=t("gateway.upgrade");if(e.status==="start")return s?null:{spin:""};if(!s&&!n&&$(e.data?.applied).length===0)return null;let r=ia(e,s||n?"Database":"Gateway database");return n?Vs(r):r},"gateway.deploy":(e,t)=>e.status==="start"?{spin:t("setup.gateway")?"Uploading...":t("app.bind")||t("app.delete")?"":"Updating the Gateway..."}:e.status!=="ok"?null:t("gateway.upgrade")?Vs({done:"Uploaded"}):t("setup.gateway")?{done:"Uploaded"}:null,"gateway.reconcile":e=>e.status==="skip"&&e.message?{line:e.message}:null,"app.deploy":e=>{if(e.status!=="ok")return null;let t=e.data??{},s=g(t.version),n=g(t.organizationName),r=g(t.origin);return{line:[`Deploying ${g(t.appId)}${s?` ${s}`:""} to ${g(t.gatewayHost)}${n?y.dim(` (${n})`):""}`,...r?[y.dim(` From ${r}`)]:[]].join(`
|
|
44
|
+
`)}},"app.register":e=>{let t=e.data??{};if(e.status!=="ok")return null;let s=Pu(t.publicRoutes),n=xu(t.mcp),r=[...s.length>0?[{fact:{label:"Public",value:Ru(s)}}]:[],...n?[{fact:{label:"MCP",value:`Serves /mcp on its own host (${n.by}): ${n.why}`}}]:[]];if(t.firstDeploy!==!0)return r.length>0?r:null;let o=g(t.organizationName),a=y.dim(`\xB7 change it at ${g(t.gatewayUrl)}/admin/apps`),i=t.scope==="shared"?`Members of every organization ${y.dim("(shared app)")}`:t.defaultAccess===!0?`Everyone${o?` in ${o}`:""} ${a}`:t.deployerAccess===!1?`Private to owners and admins ${a}`:`Private to you, owners and admins ${a}`,d=t.hasOwner===!1?`
|
|
45
|
+
${y.dim(`The Gateway has no owner yet; its first owner gets the app (${Gt} setup).`)}`:"";return[{fact:{label:"Who can open",value:`${i}${d}`}},...r]},"app.hyperdrive":e=>e.status==="ok"?{done:"Connected to Postgres through Hyperdrive",notes:e.data?.caching==="off"?['Query caching is off; caching: "default" in everyapp.config.ts turns it on.']:[]}:null,"app.install":ra("Installed dependencies"),"app.build":e=>e.status==="start"?{spin:"Building..."}:e.status!=="ok"?null:{done:e.data?.release===!0?"Release checked":"Built"},"app.schema":e=>e.status==="start"?{spin:"Checking the schema..."}:e.status==="skip"&&e.message?{line:y.dim(e.message)}:e.status==="ok"?{done:"Schema matches the migrations"}:null,"app.migrations":e=>e.status==="start"?{spin:e.data?.dialect==="postgresql"?"Migrating the Postgres database...":"Migrating the database..."}:e.status==="ok"&&e.data?.applied===void 0?{done:"Database migrated"}:ia(e,"Database"),"app.helper":e=>{let t=g(e.data?.name);return e.status==="start"?{spin:`Uploading ${t}...`}:e.status==="ok"?{done:`Uploaded helper Worker ${t}`}:null},"app.upload":e=>e.status==="start"?{spin:"Uploading..."}:e.status==="ok"?{done:"Uploaded"}:null,"app.release":e=>{if(e.status!=="ok")return null;let t=e.data??{};return[{done:`Packed ${g(t.appId)} ${g(t.version)}`},{fact:{label:"Release",value:g(t.shown)??""}},{fact:{label:"SHA-256",value:g(t.sha256)??""}}]},"app.workflows":e=>e.status==="ok"?{done:`Deleted the Workflow ${g(e.data?.binding)}`}:null,"app.lease":aa,"gateway.lease":aa,"gateway.release":(e,t)=>{if(e.status!=="ok")return null;let s=e.data??{};if(s.downloaded===!0)return{done:`Downloaded Gateway ${g(s.release)}`};let n=g(s.origin?.path);return n?{done:`Loaded Gateway ${g(s.release)} from ${n}`,detail:""}:s.cached!==!1?null:t("gateway.upgrade")?Vs({done:"Built"}):{done:"Built from this checkout"}},"app.email":e=>{let t=e.data??{};if(e.status==="start")return{spin:t.removing===!0?"Removing mail routes...":"Routing mail..."};if(e.status!=="ok")return null;let s=$(t.addresses),n=g(t.replyHint);return[...$(t.enabled).map(r=>({done:`Email Routing turned on for ${r}`})),s.length?{done:`Mail to ${s.join(", ")} routed`,...n?{notes:[n]}:{}}:{done:"Mail routes removed"}]},"app.access":e=>e.status==="ok"?{done:e.data?.removed===!0?`Cloudflare Access no longer lets ${g(e.data?.appId)}'s public routes through`:`Cloudflare Access lets ${g(e.data?.appId)}'s public routes through`}:null,"gateway.access":e=>e.status==="ok"?{done:"Cloudflare Access brought in step with this Gateway"}:null,"app.bind":e=>e.status==="start"?{spin:`Adding ${g(e.data?.appId)} to the Gateway...`}:e.status==="ok"?{done:"Added to the Gateway"}:null,"gateway.upgrade":e=>e.status==="start"?{line:y.bold(`Gateway ${g(e.data?.from)} \u2192 ${g(e.data?.to)}`)}:null,"app.live":e=>{let t=e.data??{},s=g(t.url)??`https://${g(t.hostname)}`;if(e.status==="skip")return Su(t,s);if(e.status!=="ok")return null;let n={fact:{label:"Live",value:y.cyan(s)},lead:!0},r=g(t.waited);return r?[{done:r==="certificate"?"Certificate issued":"Live"},n]:n},"app.delete":e=>{let t=g(e.data?.appId);return e.status==="start"?{spin:`Removing ${t} from the Gateway...`}:e.status!=="ok"?null:e.data?.alreadyDeleted===!0?{line:`${t} was already removed from the Gateway`}:{done:`Removed ${t} from the Gateway`}},"app.certificate":e=>e.status==="ok"?{done:`Removed ${g(e.data?.hostname)}'s certificate`}:null,"app.purge":e=>{let t=g(e.data?.appId);if(e.status==="start")return{spin:`Deleting ${t}'s Worker and data...`};if(e.status!=="ok")return null;let s=$(e.data?.kinds);return s.length>0?{done:`Deleted ${t}'s ${Ut(s)}`}:{line:y.dim(`Nothing of ${t}'s was left to delete in Cloudflare`)}},"create.copy":e=>{let t=e.data??{};return e.status==="start"?[{line:`Creating ${g(t.appId)} in ${g(t.shown)}`},...t.elsewhere===!0?[{line:y.dim("New apps go in the checkout's apps/ folder, wherever you run create.")}]:[]]:e.status==="ok"?{done:"Copied the starter template"}:null},"secrets.gateway":(e,t)=>t("access.update")||t("access.off")?null:Ee(e),"setup.access":e=>{if(e.status!=="ok")return null;let t=e.data??{},s=Array.isArray(t.signInMethods)?t.signInMethods.map(o=>o.type):[],n=[...s.includes("cloudflare")?["a Cloudflare account"]:[],...s.includes("onetimepin")?["a one-time PIN"]:[]],r=$(t.signIn?.pending);return{done:"Cloudflare Access on",detail:n.length>0?`sign-in with ${n.join(" or ")}`:void 0,notes:r.length>0?[`${Ut(r)} ${r.length===1?"signs":"sign"} in once with ${r.length===1?"their":"their own"} password; Access asks them to sign in first.`]:[]}},"secrets.app":Ee,"secrets.provider":e=>e.status==="ok"&&e.message?{line:e.message}:null,"provider.add":e=>e.status==="start"?{spin:e.message??"Registering..."}:null,"provider.remove":e=>e.status==="start"?{spin:e.message??"Removing..."}:null,"provider.alias":e=>e.status==="ok"&&e.message?{line:y.dim(e.message)}:null,"events.deliver":Ee,"create.skill":Ee,"create.install":oa("Installing dependencies...","Installed dependencies"),"create.types":oa("Generating types...","Generated types"),"create.git":e=>e.status==="start"?{spin:"Starting a git repository..."}:e.status==="ok"?{done:"Started a git repository",detail:"first commit: Starter template"}:null,"create.done":e=>e.status==="ok"?{line:""}:null,"dev.types":ra("Worker types generated",".cloudflare/types"),"dev.migrations":e=>{if(e.status==="skip")return e.data?.reason==="flag"?{line:y.dim("Skipped local migrations (--skip-migrations)")}:null;if(e.status!=="ok")return null;let t=$(e.data?.applied);return{done:t.length?`${B(t.length,"local migration")} applied`:"Local database up to date"}},"dev.app":e=>e.status==="ok"?[{done:`${g(e.data?.appId)??"The app"} is running locally`},...e.message?[{line:e.message}]:[]]:null,"dev.stop":e=>{let t=g(e.data?.appId)??"the app";return e.data?.started===!0?{done:`${t} stopped`}:{line:y.dim(`Stopped before ${t} started.`)}},"migrations.local":e=>{if(e.status==="start")return{spin:"Setting up the local database..."};if(e.status==="skip"&&e.message)return{line:e.message};if(e.status!=="ok")return null;let t=$(e.data?.applied);return{done:"Set up the local database",...t.length?{detail:B(t.length,"migration")}:{}}},"cloudflare.login":e=>{let t=e.data??{},s=g(t.email),n=s?` as ${s}`:t.token===!0?" with CLOUDFLARE_API_TOKEN":"";return e.status==="skip"?{line:`Already logged in to Cloudflare${n}`}:e.status==="ok"?{done:`Logged in to Cloudflare${n}`}:null},"db.migrate":e=>{if(e.status==="start")return{spin:"Applying migrations to the local database..."};if(e.status==="skip"&&e.message)return{line:y.dim(e.message)};if(e.status!=="ok")return null;let t=$(e.data?.applied);return t.length?{done:`${B(t.length,"migration")} applied to the local database`,detail:"",notes:t}:{done:"Local database up to date",detail:""}},"db.query":e=>e.status==="start"?{spin:`Querying the ${g(e.data?.database)} database...`}:null,"teardown.check":Ee,"teardown.inventory":e=>e.status==="start"?{spin:e.message??""}:null,"teardown.plan":e=>e.status==="ok"?{done:e.message??"",notes:$(e.data?.lines)}:null,"teardown.delete":Ee,"db.restore":e=>{if(e.status==="start")return{spin:"Restoring..."};if(e.status!=="ok")return null;let t=e.data??{},s=g(t.appId);return{done:`Restored ${s?`${s}'s`:"the Gateway's"} database`,detail:`before ${$(t.migrations).join(", ")}`}}},bu=new Set(["CUSTOM_DOMAIN_OWNER_UNCHECKED"]);function aa(e){return e.status==="ok"?{done:`Other ${g(e.data?.waitedFor)??"run"} finished`}:null}var Ke=()=>!0,_u=e=>e.host===void 0,Au={"app.release":Ke,"app.lease":Ke,"gateway.lease":Ke,"db.lease":Ke,"app.live":Ke,"gateway.tls":_u},ku=new Set(["dev.mcp","dev.session"]);function ia(e,t){if(e.status!=="ok")return null;let s=e.data??{},n=$(s.applied);if(n.length===0)return{done:`${t} up to date`};if(s.fresh===!0)return{done:`${t} created`,detail:B(n.length,"migration")};let r=g(s.restoreCommand);return{done:`${t} migrated`,detail:n.join(", "),notes:r?[`Restore point saved. To undo: ${r}`]:[]}}function Vs(e){return!e||!("done"in e)?e:{...e,done:` ${e.done}`,...e.notes?{notes:e.notes.map(t=>` ${t}`)}:{}}}function Su(e,t){if(e.reason==="outside-base")return[{fact:{label:"Live",value:y.yellow("Not routed")},lead:!0}];let s=e.reason==="certificate"?"Goes live on its first visit, once its certificate comes (a few minutes)":e.reason==="first-visit"?"Goes live on its first visit":void 0;return[{fact:{label:"URL",value:y.cyan(t)},lead:!0},...s?[{fact:{label:"Status",value:s},lead:!0}]:[]]}function ca(e,t){let[s="",...n]=t.split(`
|
|
46
|
+
`);return[`${e} ${s}`,...n.map(r=>y.dim(` ${r}`))]}function qs(e,{url:t=!1}={}){let s=g(e?.didYouMean),n=g(e?.usage),r=g(e?.fix),o=t?g(e?.url):void 0,a=g(e?.rerun)??g(e?.help),i=g(e?.rerunNote);return[...s?[` Did you mean ${y.bold(s)}?`]:[],...n?[y.dim(` Usage: ${n}`)]:[],...r?[` Fix: ${r}`]:[],...o?[` ${y.cyan(o)}`]:[],...a?[` ${e?.authorize===!0?"To go ahead anyway":"Run"}: ${y.bold(a)}${i?` ${y.dim(i)}`:""}`]:[]]}function vu(e){if(!Array.isArray(e))return[];let t=e.map(n=>n),s=Math.max(...t.map(n=>n.rerun.length));return t.map(n=>` ${y.bold(n.rerun.padEnd(s))}${n.label?` ${y.dim(n.label)}`:""}`)}function Iu(e){return Array.isArray(e)?e.map(t=>({label:t.label,value:`${/^https?:\/\//.test(t.value)?y.cyan(t.value):t.value}${t.note?` ${y.dim(t.note)}`:""}`})):[]}function Tu(e){if(typeof e!="object"||e===null)return;let{min:t,max:s}=e;return typeof t=="number"&&typeof s=="number"?{min:t,max:s}:void 0}function Pu(e){return Array.isArray(e)?e.map(t=>t):[]}function xu(e){if(!e||typeof e!="object")return null;let{by:t,why:s}=e;return(t==="gateway"||t==="app")&&typeof s=="string"?{by:t,why:s}:null}function Ru(e){let{shown:t,more:s}=ta(e);return`Open to the internet without sign-in: ${t}${s>0?y.dim(` \u2026 and ${s} more (everyapp.config.ts public)`):""}`}function Ou(e){return Array.isArray(e)?e.map(t=>typeof t=="string"?{command:t}:t):[]}function Cu(e){let t=n=>n.command??n.url??"",s=Math.max(...e.map(n=>t(n).length));return e.map(n=>n.note?` ${t(n).padEnd(s)} ${y.dim(n.note)}`:` ${t(n)}`)}var da=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Nu=80,pa=3e4,Js=class{constructor(t,s,n,r){this.write=t;this.terminal=s;this.columns=n;this.now=r}steps=[];frame=0;timer;drawn=!1;lines(t){this.erase(),this.write(`${t}
|
|
47
|
+
`),this.draw()}spin(t,s){let n=this.steps.find(r=>r.step===t);if(n?n.label=s:this.steps.push({step:t,label:s,since:this.now()}),!this.terminal){this.keepAlive();return}this.timer||(na.hide(process.stdout),this.timer=setInterval(()=>{this.frame=(this.frame+1)%da.length,this.draw()},Nu),this.timer.unref()),this.draw()}stopSpinning(t){let s=this.steps.findIndex(n=>n.step===t);s<0||(this.steps=this.steps.slice(0,s),this.settle())}drop(t){this.steps=this.steps.filter(s=>s.step!==t),this.settle()}aside(t){this.terminal&&this.erase(),t(),this.draw()}handOver(){this.steps=[],this.stopTimer(),this.erase()}finish(){this.handOver()}interrupt(t){this.handOver(),this.terminal?this.spin("interrupt",t):this.write(`${y.dim(t)}
|
|
48
|
+
`)}settle(){this.steps.length===0&&this.stopTimer(),this.draw()}stopTimer(){this.timer&&(clearInterval(this.timer),this.timer=void 0,this.terminal&&na.show(process.stdout))}keepAlive(){this.timer||(this.timer=setInterval(()=>{let t=this.steps.findLast(r=>r.label);if(!t)return;let s=this.now()-t.since;if(s<pa)return;let n=t.label.replace(/\.{3}$|…$/,"");this.write(`${y.dim(`still ${n.charAt(0).toLowerCase()}${n.slice(1)} \xB7 ${Jo(s)}`)}
|
|
49
|
+
`)},pa),this.timer.unref())}erase(){this.drawn&&(this.write("\r\x1B[2K"),this.drawn=!1)}draw(){if(!this.terminal)return;let t=this.steps.findLast(o=>o.label)??this.steps.at(-1);if(!t){this.erase();return}let s=this.now()-t.since,n=`${t.label?`${t.label} `:""}${s>=5e3?`\xB7 ${Lt(s)} `:""}${da[this.frame]}`,r=Math.max(this.columns()-1,10);this.write(`\r\x1B[2K${y.dim(n.length>r?`\u2026${n.slice(n.length-r+1)}`:n)}`),this.drawn=!0}};function ha(e,t,s){let n=s(),r=new Set,o=!1,a=!1,i=!1;return{emit(d){let p=d;if(p.type==="warning"){let u=`${p.code}
|
|
50
|
+
${p.message}`;if(r.has(u))return;r.add(u)}else p.type==="done"&&(p={...p,data:{...p.data,durationMs:s()-n}});p.type==="error"?o=!0:p.type==="action_required"?p.data?.waiting?i=!0:a=!0:p.type==="done"&&(i=!1),e(p),Zo(p.type==="done"?{...p,display:void 0}:p,new Date(s()))},get exitCode(){return o?1:a||i?2:0},verbose:t}}var ma;function fa(e){ma=e,process.exitCode=e}function Hw(){return ma}var $u="https://dash.cloudflare.com/?to=/:account/workers/plans",Du="https://dash.cloudflare.com/profile",Lu=new Set(["ECONNREFUSED","ECONNRESET","ENOTFOUND","EAI_AGAIN","ETIMEDOUT","UND_ERR_CONNECT_TIMEOUT","UND_ERR_SOCKET"]);function ya(e,t,s){let n=Eo(t),r=h=>n?`${h}
|
|
51
|
+
The database stays migrated. To roll it back: ${n.restoreCommand}`:h,o=n?{rollbackCommand:n.rollbackCommand}:{},a=s?{step:s}:{},i=(h,w,f)=>e.emit({type:"action_required",action:h,message:r(w),...a,data:{...f,...o}}),d=(h,w,f,l)=>e.emit({type:"error",code:h,message:r(w),retryable:f,...a,data:{...l,...o}});if(t instanceof It){i(t.action,t.message,{...t.data,...t.url?{url:t.url}:{},...t.rerun?{rerun:t.rerun}:{},...t.rerunNote?{rerunNote:t.rerunNote}:{}});return}if(Le(t,"free_plan")){i("upgrade_workers_paid",`Cloudflare refused, for the Free plan: ${t.message}
|
|
52
|
+
EveryApp needs Workers Paid ($5 a month, then usage). Subscribe, then run this command again.`,{url:$u,rerun:x()});return}if(t instanceof P){d(t.code,t.message,t.retryable,{...t.data,...t.fix?{fix:t.fix}:{},...t.rerun?{rerun:t.rerun}:{},...t.rerunNote?{rerunNote:t.rerunNote}:{},...t.authorize?{authorize:!0}:{}});return}let p=Mu(t);if(p){d(p.code,p.message,p.retryable,{...p.data,...p.retryable?{rerun:x()}:{}});return}let u=t instanceof Error?t:new Error(String(t));d("UNEXPECTED",`everyapp hit an unexpected error
|
|
53
|
+
${u.name}: ${u.message}
|
|
54
|
+
This is a bug in everyapp, not something you did.`,!1,{...u.stack?{stack:u.stack}:{},...e.verbose?{}:{rerun:x(["--verbose"]),rerunNote:"for a stack trace to report"}})}function Mu(e){if(!(e instanceof Error))return null;if(Le(e,"email_unverified"))return{code:"CF_EMAIL_UNVERIFIED",message:`Verify your Cloudflare account's email address first
|
|
55
|
+
Cloudflare refuses to create anything until the address on the account is verified. Open the message Cloudflare sent you, then run this command again.`,retryable:!0,data:{url:Du,cloudflare:e.message}};if(e instanceof W)return{code:`CF_${e.kind.toUpperCase()}`,message:e.message,retryable:!1};if(e instanceof fe)return{code:"CF_TIMEOUT",message:e.message,retryable:!0};if(e instanceof Z)return{code:"CF_OUTPUT",message:e.message,retryable:!1};if(e instanceof k)return{code:"INVALID_MANIFEST",message:e.message,retryable:!1};let t=ga(e)??ga(e.cause);return t&&Lu.has(t)?{code:"NETWORK_ERROR",message:`The network failed (${t})
|
|
56
|
+
${e.message}`,retryable:!0}:e instanceof TypeError&&e.message==="fetch failed"?{code:"NETWORK_ERROR",message:`The network failed
|
|
57
|
+
fetch failed`,retryable:!0}:t?{code:"SYSTEM_ERROR",message:e.message,retryable:!1}:null}function ga(e){let t=e?.code;return typeof e=="object"&&typeof t=="string"&&/^[A-Z_]+$/.test(t)?t:void 0}function Gu(e,t){return e?ua():la({verbose:t,terminal:ko()})}async function Uu(e,t){try{await t()}catch(s){ya(e,s)}fa(e.exitCode)}async function eE(e,t){let s=Gu(e.json,e.verbose);await Uu(s,()=>t(s))}export{Ku as a,Hu as b,Gt as c,x as d,Wu as e,B as f,Ve as g,g as h,Fu as i,re as j,Ut as k,$ as l,Rc as m,Oc as n,Cc as o,Hm as p,Pr as q,Wm as r,Bm as s,Fm as t,Pl as u,xl as v,Ya as w,Rl as x,Ol as y,Sn as z,vn as A,Cl as B,N as C,L as D,j as E,jt as F,G,pn as H,ka as I,al as J,Rr as K,qm as L,Jm as M,va as N,dl as O,pl as P,Ra as Q,mn as R,gn as S,ll as T,Ca as U,Ht as V,hl as W,qe as X,ml as Y,fl as Z,ie as _,Ma as $,ke as aa,F as ba,El as ca,bl as da,bn as ea,_n as fa,Je as ga,kl as ha,Xe as ia,Sl as ja,kn as ka,vl as la,Il as ma,In as na,Tn as oa,si as pa,ni as qa,Gl as ra,Ul as sa,ai as ta,ii as ua,Nn as va,jl as wa,$n as xa,zl as ya,Kl as za,Hl as Aa,Ln as Ba,ql as Ca,et as Da,Gn as Ea,Jl as Fa,Xl as Ga,Zl as Ha,eh as Ia,th as Ja,sh as Ka,nh as La,rh as Ma,ah as Na,Pi as Oa,Ie as Pa,Xt as Qa,lh as Ra,Cr as Sa,rf as Ta,of as Ua,Nr as Va,Qt as Wa,er as Xa,ct as Ya,mh as Za,fh as _a,gh as $a,yh as ab,wh as bb,Eh as cb,bh as db,_h as eb,kh as fb,Sh as gb,vh as hb,Ih as ib,Th as jb,Ph as kb,Oh as lb,Ch as mb,Nh as nb,$h as ob,Dh as pb,Lh as qb,Bc as rb,lf as sb,Zc as tb,td as ub,sc as vb,Uh as wb,ag as xb,ig as yb,Gr as zb,lo as Ab,Vd as Bb,k as Cb,hg as Db,mg as Eb,fg as Fb,gg as Gb,zr as Hb,tp as Ib,sp as Jb,go as Kb,Is as Lb,yg as Mb,wg as Nb,Eg as Ob,bg as Pb,np as Qb,_g as Rb,Ag as Sb,kg as Tb,Sg as Ub,Ts as Vb,op as Wb,vg as Xb,Kr as Yb,Ig as Zb,Tg as _b,ip as $b,xg as ac,P as bc,It as cc,wo as dc,Lg as ec,Mg as fc,W as gc,Le as hc,jg as ic,fe as jc,vo as kc,Tt as lc,Kg as mc,Zg as nc,Qg as oc,Co as pc,No as qc,ny as rc,Do as sc,xp as tc,Mo as uc,Cp as vc,fy as wc,gy as xc,we as yc,Bo as zc,Ms as Ac,Cy as Bc,cw as Cc,iu as Dc,dw as Ec,Jo as Fc,Lt as Gc,uw as Hc,_w as Ic,Aw as Jc,kw as Kc,Sw as Lc,vw as Mc,ta as Nc,mw as Oc,fw as Pc,ea as Qc,Ew as Rc,zw as Sc,wu as Tc,Hw as Uc,ya as Vc,Gu as Wc,Uu as Xc,eE as Yc};
|