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.
Files changed (138) hide show
  1. package/README.md +1 -1
  2. package/dist/access-YWM4BSBD.js +1 -0
  3. package/dist/activity-RTCAUMQS.js +14 -0
  4. package/dist/ai-UOYQFTAX.js +5 -0
  5. package/dist/apps-PEOBCDNU.js +14 -0
  6. package/dist/chunk-26KS6TD6.js +1 -0
  7. package/dist/chunk-3EADVHFN.js +15 -0
  8. package/dist/chunk-4LKLQOM7.js +7 -0
  9. package/dist/{chunk-PNLU5U3P.js → chunk-5IC3ZN52.js} +1 -1
  10. package/dist/{chunk-H7PDL3X5.js → chunk-AMCNAKYU.js} +1 -1
  11. package/dist/{chunk-23HJ5I2A.js → chunk-ASCNE7GS.js} +1 -1
  12. package/dist/{chunk-6OGVO7QK.js → chunk-BCTEWNN4.js} +1 -1
  13. package/dist/{chunk-W3JCQHHU.js → chunk-BK4NK34C.js} +1 -1
  14. package/dist/chunk-BWNZ6F4F.js +2 -0
  15. package/dist/chunk-DCFHBCCW.js +9 -0
  16. package/dist/{chunk-2Y5Q6A5K.js → chunk-DWTJ4OLZ.js} +1 -1
  17. package/dist/chunk-EP3IQ354.js +20 -0
  18. package/dist/{chunk-OP4DYXYI.js → chunk-EP4HRYXP.js} +1 -1
  19. package/dist/{chunk-HOUHG236.js → chunk-EQLY5I46.js} +1 -1
  20. package/dist/{chunk-YHJZMJYZ.js → chunk-F5XK23HV.js} +1 -1
  21. package/dist/{chunk-5PTNYZK6.js → chunk-FB2OC32C.js} +3 -3
  22. package/dist/chunk-FQ2A7YAP.js +57 -0
  23. package/dist/{chunk-OM2HDWVP.js → chunk-GAPQSINH.js} +1 -1
  24. package/dist/chunk-GJK6GAWO.js +1 -0
  25. package/dist/chunk-H4EZTXIK.js +1 -0
  26. package/dist/chunk-HJGZGZFE.js +32 -0
  27. package/dist/{chunk-CCWBPAKH.js → chunk-I7FNTTUY.js} +3 -3
  28. package/dist/chunk-KOBKGQ27.js +91 -0
  29. package/dist/{chunk-PS7S74DG.js → chunk-KQM6ZUX5.js} +1 -1
  30. package/dist/chunk-KVCL64LI.js +1 -0
  31. package/dist/{chunk-4JRIS6S6.js → chunk-LEEUODYR.js} +1 -1
  32. package/dist/{chunk-6PGUCTJ6.js → chunk-LI3YLKLC.js} +1 -1
  33. package/dist/chunk-MEIWV7FJ.js +20 -0
  34. package/dist/{configure-F7UZCJUG.js → chunk-MLTNW3AM.js} +2 -2
  35. package/dist/chunk-NDOEON54.js +4 -0
  36. package/dist/chunk-NW7SJPSP.js +37 -0
  37. package/dist/chunk-O64FPLGX.js +1 -0
  38. package/dist/chunk-ORGV2NNT.js +8 -0
  39. package/dist/chunk-PDPUGYJW.js +47 -0
  40. package/dist/chunk-QFTBDXLF.js +146 -0
  41. package/dist/{chunk-E3EPK27P.js → chunk-QJRZFIYC.js} +2 -2
  42. package/dist/chunk-QKHLRLK3.js +15 -0
  43. package/dist/{chunk-CZXHKPRZ.js → chunk-R2DF3ENZ.js} +1 -1
  44. package/dist/{chunk-IUOBIB5M.js → chunk-R7JOHK7Y.js} +2 -2
  45. package/dist/chunk-RL72BUT4.js +1 -0
  46. package/dist/chunk-RQBSTNL7.js +1 -0
  47. package/dist/{chunk-H6QQMY7B.js → chunk-S2G4G73L.js} +1 -1
  48. package/dist/{chunk-LXYMDZER.js → chunk-SGRGD7L4.js} +1 -1
  49. package/dist/{chunk-T2GD7RHS.js → chunk-TIYSZWP5.js} +1 -1
  50. package/dist/chunk-TUXKBLLJ.js +10 -0
  51. package/dist/chunk-U4ATZJEU.js +6 -0
  52. package/dist/chunk-V7BWZOSZ.js +26 -0
  53. package/dist/{chunk-J35DDCNU.js → chunk-VVKQJSF3.js} +1 -1
  54. package/dist/chunk-WVHJIYQ3.js +14 -0
  55. package/dist/{chunk-ZEXVHB22.js → chunk-XBD7PQN5.js} +1 -1
  56. package/dist/{chunk-N5GQLGEC.js → chunk-YAZHTVUV.js} +1 -1
  57. package/dist/configure-CAWCTPYY.js +1 -0
  58. package/dist/{create-2E5HVWYK.js → create-3ZWJQXPK.js} +2 -2
  59. package/dist/{db-HEQVTDTM.js → db-B7KO37SV.js} +1 -1
  60. package/dist/delete-CB3EPOU4.js +3 -0
  61. package/dist/deploy-5O7LV5OX.js +1 -0
  62. package/dist/dev-4JYCVVOZ.js +86 -0
  63. package/dist/{email-RLZFUFUN.js → email-SWJQXEUR.js} +1 -1
  64. package/dist/{events-2V5VRBWP.js → events-GJV2KVIU.js} +13 -13
  65. package/dist/{groups-HDG5DVFY.js → groups-NNTLSXMK.js} +1 -1
  66. package/dist/index.js +104 -95
  67. package/dist/install-UAG3CNYW.js +1 -0
  68. package/dist/{login-KHJBC64Z.js → login-QEKMLMUB.js} +1 -1
  69. package/dist/mcp-AFGVOM5D.js +1 -0
  70. package/dist/provider-622VM7UZ.js +29 -0
  71. package/dist/release-CXEX6O7F.js +1 -0
  72. package/dist/{restore-FFGYV7NO.js → restore-PGIVEA5P.js} +1 -1
  73. package/dist/secret-3LUDEDUW.js +1 -0
  74. package/dist/setup-PUD375AM.js +1 -0
  75. package/dist/{signin-AP3D4XM4.js → signin-EP5JLAT5.js} +2 -2
  76. package/dist/status-LK6DNLCI.js +5 -0
  77. package/dist/teardown-6RURRSME.js +22 -0
  78. package/dist/update-YJFTOZEV.js +1 -0
  79. package/dist/{workspace-CJC5I66L.js → workspace-VW7ZZRFP.js} +3 -3
  80. package/package.json +5 -5
  81. package/skills/build-every-app/SKILL.md +22 -13
  82. package/skills/build-every-app/patterns.md +16 -3
  83. package/skills/everyapp/SKILL.md +33 -18
  84. package/skills/everyapp/mcp.md +22 -8
  85. package/skills/everyapp/security-review.md +1 -1
  86. package/skills/everyapp/setup/README.md +18 -1
  87. package/skills/everyapp/setup/access.md +11 -7
  88. package/skills/everyapp/setup/ai-gateway.md +117 -0
  89. package/skills/everyapp/setup/ai.md +139 -0
  90. package/skills/everyapp/setup/context.md +2 -2
  91. package/skills/everyapp/setup/dataforseo.md +3 -3
  92. package/skills/everyapp/setup/email.md +1 -1
  93. package/skills/everyapp/setup/gateway.md +3 -3
  94. package/skills/everyapp/setup/google.md +8 -6
  95. package/skills/everyapp/setup/microsoft-365.md +4 -2
  96. package/skills/everyapp/setup/providers.md +27 -9
  97. package/skills/everyapp/setup/remote-mcp.md +1 -1
  98. package/skills/everyapp/setup/signin-apple.md +3 -3
  99. package/skills/everyapp/setup/signin-cloudflare.md +1 -1
  100. package/skills/everyapp/setup/signin-github.md +1 -1
  101. package/skills/everyapp/setup/signin-google.md +2 -2
  102. package/skills/everyapp/setup/signin-microsoft.md +1 -1
  103. package/skills/everyapp/setup/slack.md +2 -0
  104. package/dist/access-LGEN3ABJ.js +0 -1
  105. package/dist/activity-RSD4D66F.js +0 -12
  106. package/dist/apps-4RCFXT74.js +0 -13
  107. package/dist/chunk-AGTCKFRB.js +0 -22
  108. package/dist/chunk-BHMRY53V.js +0 -2
  109. package/dist/chunk-CB4U7H2G.js +0 -4
  110. package/dist/chunk-CZTEDWZ2.js +0 -22
  111. package/dist/chunk-EGEWRFVY.js +0 -1
  112. package/dist/chunk-ELK7QZ2M.js +0 -1
  113. package/dist/chunk-FJJSSVET.js +0 -33
  114. package/dist/chunk-GKBPYVP3.js +0 -25
  115. package/dist/chunk-IFCPALVC.js +0 -46
  116. package/dist/chunk-J455FAEN.js +0 -7
  117. package/dist/chunk-JYKRUS5C.js +0 -1
  118. package/dist/chunk-LYNBZ7RV.js +0 -57
  119. package/dist/chunk-M2QQ2UD7.js +0 -132
  120. package/dist/chunk-NFU4YFXB.js +0 -1
  121. package/dist/chunk-ONLNJXVQ.js +0 -32
  122. package/dist/chunk-RMF4YGD6.js +0 -98
  123. package/dist/chunk-TLRM3P7V.js +0 -15
  124. package/dist/chunk-WOVS3GV5.js +0 -10
  125. package/dist/chunk-ZECBN24L.js +0 -15
  126. package/dist/chunk-ZFCUH5PK.js +0 -7
  127. package/dist/delete-XCSIQIRS.js +0 -3
  128. package/dist/deploy-3QOZEZHC.js +0 -1
  129. package/dist/dev-JL3ZP5BT.js +0 -86
  130. package/dist/install-Z5FYXUYM.js +0 -1
  131. package/dist/mcp-EFDUKJ5V.js +0 -1
  132. package/dist/provider-EOI5PTFH.js +0 -13
  133. package/dist/release-74J5ZIL3.js +0 -1
  134. package/dist/secret-7FKKTLHB.js +0 -1
  135. package/dist/setup-PAKRCAFO.js +0 -1
  136. package/dist/status-RMWNHOEK.js +0 -4
  137. package/dist/teardown-E4JNKAZJ.js +0 -22
  138. package/dist/update-DWVZFNPS.js +0 -1
@@ -0,0 +1,47 @@
1
+ import{a as Pe,b as Wt,e as qt}from"./chunk-WVHJIYQ3.js";import{a as ae,b as Oe,c as Me,d as j,e as Ut,f as me,g as xt,h as Gt,j as ge,k as zt,l as Ce,p as Ft}from"./chunk-GAPQSINH.js";import{b as Bt}from"./chunk-ORGV2NNT.js";import{c as Ht}from"./chunk-KVCL64LI.js";import{a as le,c as mt}from"./chunk-LEEUODYR.js";import{b as Lt,e as ve}from"./chunk-3EADVHFN.js";import{g as yt,h as St}from"./chunk-EQLY5I46.js";import{c as Mt,e as Ct}from"./chunk-DCFHBCCW.js";import{$ as Tt,A as L,V as te,W as De,X as ne,Y as b,Z as re,_ as se,ba as kt,ca as It,da as be,ea as Dt,ga as bt,ha as de,k as ht,ka as vt,l as Et,ma as Ot,w as P,x as Ie}from"./chunk-KOBKGQ27.js";import{a as Rt,e as O,o as ee,p as V,q as At,r as _t,s as Nt,t as $t}from"./chunk-RL72BUT4.js";import{b as Le}from"./chunk-AMCNAKYU.js";import{a as q,f as gt,g as ft,i as wt}from"./chunk-I7FNTTUY.js";import{$ as ce,Aa as at,C as Ke,D as pe,Da as ot,Db as ut,Ea as Z,Fa as it,Ga as pt,Ha as ct,Hb as Q,I as Je,Ia as ke,La as lt,Oa as dt,Rc as Pt,S as he,U as Ee,W as Xe,X as Re,Y as Ze,Yc as ue,_ as W,aa as Ae,ba as J,bc as S,c as m,ca as Qe,da as _e,ea as Ne,fa as et,fc as C,ga as F,ha as M,ia as tt,ja as $e,k,ka as Te,la as nt,ra as rt,xa as X,za as st}from"./chunk-FQ2A7YAP.js";import{stripVTControlCharacters as Zn}from"node:util";import v from"chalk";function Vt(e){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new S("SECRET_NAME_INVALID",`"${e}" isn't a valid secret name`,{fix:"use letters, digits and underscores, starting with a letter, e.g. GITHUB_TOKEN"});if(F(e))throw new S("SECRET_NAME_RESERVED",`${e} is a reserved name
2
+ everyapp manages ${et}.`,{fix:"pick another name"})}function Nn(e){return e.ready?e.settings.some(n=>n.set===null&&n.names.length>0&&n.need.kind!=="optional")?null:"ready":"needs_setup"}function $n(e){return[...new Set(e.unmet.flatMap(t=>t.names))]}var jt="id, organization_id, app_slug, name, status, setup_state",Yt=e=>({id:String(e.id),organizationId:String(e.organization_id),appSlug:String(e.app_slug),name:String(e.name),status:String(e.status),setupState:e.setup_state==null?null:String(e.setup_state)});async function Kt(e,t){if(!await Ie(e))return null;let n=Nn(t.setup);if(!n)return null;let r=t.row??await Tn(e,t.appRowId);if(!r||r.status===O)return null;let s=r.setupState==="ready"||r.setupState==="needs_setup"?r.setupState:null;if(s===n)return{state:n,previous:s,event:null};let a=n==="needs_setup"?"app.needs_setup":s==="needs_setup"?"app.ready":null,o={id:r.appSlug,rowId:r.id,name:r.name},i=a?await L(e,{organizationId:r.organizationId,type:a,actor:P(t.deployer),data:a==="app.needs_setup"?{app:o,unmet:$n(t.setup)}:{app:o},appRowId:r.id,onlyIf:{sql:"changes() > 0",params:[]},now:t.now}):[];return await e.run([{sql:"UPDATE apps SET setup_state = ? WHERE id = ? AND setup_state IS ?",params:[n,r.id,s]},...i]),{state:n,previous:s,event:a}}async function Tn(e,t){let[n=[]]=await e.run([{sql:`SELECT ${jt} FROM apps WHERE id = ?`,params:[t]}]);return n[0]?Yt(n[0]):null}async function Jt(e,t,n){try{let{cf:r,db:s,deployer:a}=e;if(t.gateway.length===0&&t.appRowId===null||!await Ie(s))return;let[o=[]]=await s.run([{sql:`SELECT ${jt}, tier, manifest, secret_names FROM apps
3
+ WHERE status NOT IN ('${O}', 'pending') AND tier NOT IN ('${M}', 'dispatch')`}]),i=o.flatMap(c=>{let u=kn(c.manifest);return!u||typeof u!="object"||c.id===t.except?[]:c.id===t.appRowId||me(u).some(l=>t.gateway.includes(l))?[{row:Yt(c),manifest:u,secretNames:Rt(b(c.secret_names))}]:[]});if(i.length===0)return;let p=await ae(r);for(let c of i){let{setup:u}=j({manifest:c.manifest,appId:c.row.appSlug,gatewayNames:p,secretNames:c.secretNames});await Kt(s,{appRowId:c.row.id,setup:u,deployer:a,row:c.row})}}catch(r){n.emit({type:"progress",step:"app.setup_state",message:`Couldn't record whether the apps are set up (${C(r).split(`
4
+ `)[0]}); the Gateway records it when it next lists them`})}}function kn(e){if(typeof e!="string")return null;try{return JSON.parse(e)}catch{return null}}async function Tr(e,t,n){try{await Kt(e,t)}catch(r){n.emit({type:"progress",step:"app.setup_state",message:`Couldn't record whether the app is set up (${C(r).split(`
5
+ `)[0]}); the Gateway records it when it next lists it`})}}var Xt=new WeakMap;function H(e){let t=Xt.get(e);return t||(t=e.run([{sql:"SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ('remote_mcp_credentials', 'remote_mcp_tools')"}]).then(([n=[]])=>{let r=new Set(n.map(s=>String(s.name)));return{credentials:r.has("remote_mcp_credentials"),tools:r.has("remote_mcp_tools")}}),Xt.set(e,t)),t}function Ue(e){return{app:{id:e.appSlug,rowId:e.id,name:e.name},kind:ee(e)?"remote":"builtin"}}function In(e){return V(e)?.url??null}async function Zt(e,t,n){let[r=[]]=await e.run([{sql:`SELECT ${await ne(e)} FROM apps WHERE organization_id = ? AND app_slug = ?`,params:[t,n]}]);return r[0]?re(r[0]):null}async function Dn(e,t){let[n=[]]=await e.run([{sql:`SELECT ${await ne(e)} FROM apps WHERE organization_id = ? AND tier = ? AND status != '${O}' ORDER BY app_slug`,params:[t,M]}]);return n.map(re).filter(ee).map(r=>r.appSlug)}async function Cr(e,t){let r=(await se(e))?.organization??null,s=r?await Zt(e,r.id,t):null;if(Te(t))return{kind:"builtin",id:t,organization:r,app:s&&s.tier===M?s:null};if(s&&ee(s))return{kind:"remote",id:t,organization:r,app:s};if(s&&s.tier!==M&&s.status!==O)throw new S("PROVIDER_APP_UNKNOWN",`"${t}" is an app deployed to this Gateway, not an MCP app
6
+ ${m} delete ${t} removes a deployed app.`,{rerun:`${m} mcp list`,rerunNote:"lists the MCP apps"});let a=r?await Dn(e,r.id):[],o=/^[a-z][a-z0-9+.-]*:\/\//i.test(t);throw new S("PROVIDER_APP_UNKNOWN",[`"${t}" is not an MCP app on this Gateway`,`Built in: ${$e.join(", ")}. Added: ${a.length>0?a.join(", "):"none yet"}.`].join(`
7
+ `),o?{rerun:`${m} mcp add ${t}`,rerunNote:"adds the server at that address"}:{rerun:`${m} mcp list`,rerunNote:"lists the MCP apps"})}function Pr(e){let t=e.app?In(e.app):null;return new S("APP_NOT_FOUND",`${e.id} was removed from this Gateway
8
+ Adding it again starts fresh: nobody's access or tools are kept.`,t?{rerun:`${m} mcp add ${t} --name ${e.id}`,rerunNote:"adds it again"}:{rerun:`${m} mcp list`,rerunNote:"lists the MCP apps"})}async function Qt(e){let[t=[]]=await e.run([{sql:`SELECT tier, manifest FROM apps WHERE tier = ? AND status != '${O}'`,params:[M]}]),n=new Map;for(let r of t){let s=V({tier:String(r.tier),manifest:b(r.manifest)}),a=s?X(s.auth):null;if(!s||!a)continue;let o;try{o=new URL(s.url).origin}catch{continue}let i=n.get(a)??new Set;i.add(o),n.set(a,i)}return n}function bn(e,t,n){let{app:r}=e,s=e.grants.map(a=>({sql:`INSERT INTO user_app_access (id, user_id, app_row_id, organization_id, granted_by)
9
+ VALUES (?, ?, ?, ?, NULL) ON CONFLICT DO NOTHING`,params:[a.id,a.userId,a.appRowId,a.organizationId]}));return e.kind==="new"?[{sql:`INSERT INTO apps (id, organization_id, app_slug, name, description, hostname,
10
+ worker_name, tier, manifest, status, version_id, deployed_at, deployed_by_actor,
11
+ is_default, created_at, updated_at, scope)
12
+ VALUES (?1, ?2, ?3, ?4, ?5, NULL, NULL, ?6, ?7, ?8, NULL, ?9, ?10, 0, ?11, ?11, ?12)`,params:[r.id,r.organizationId,r.appSlug,r.name,r.description,r.tier,r.manifest,r.status,r.deployedAt,r.deployedByActor,t,r.scope]},...s]:[{sql:`UPDATE apps SET name = ?, description = ?, manifest = ?, status = ?, is_default = 0,
13
+ deployed_at = ?, deployed_by_actor = ?, updated_at = ?
14
+ WHERE id = ? AND status = '${O}'`,params:[r.name,r.description,r.manifest,r.status,r.deployedAt,r.deployedByActor,t,r.id]},...be(r,t,{secretNames:n.secretNames}),...n.remoteTools?[en(r)]:[],...s]}function en(e){return{sql:"DELETE FROM remote_mcp_tools WHERE app_row_id = ? AND organization_id = ?",params:[e.id,e.organizationId]}}function Lr(e,t){return te(async()=>{let n=t.now??Date.now(),r=t.url.trim(),s=(t.id??"").trim()||rt(r)||"",{organization:a,hasOwner:o}=await Tt(e,t.organizationName,n),[i=[],p=[],c=[]]=await e.run([{sql:`SELECT ${await ne(e)} FROM apps WHERE organization_id = ? AND app_slug = ?`,params:[a.id,s]},...kt(a.id,t.deployer.email)]),u=i[0]?re(i[0]):null,y=await Qt(e),l=b(c[0]?.id),h=At({organizationId:a.id,url:r,id:t.id,name:t.name,description:t.description,auth:t.auth,risk:t.risk,env:t.env,existingApp:E=>{if(E!==s)throw new Error(`The rules asked for "${E}", not "${s}".`);return u},secretUsedAt:E=>{let A=[...y.get(E)??[]],w=new URL(r).origin;return A.find(f=>f!==w)??A[0]??null},members:It(p),actorUserId:l,actor:t.deployer.actor,now:n}),R=await H(e),g=await L(e,{organizationId:a.id,type:"mcp_app.added",actor:P(t.deployer),data:{app:{id:h.app.appSlug,rowId:h.app.id,name:h.app.name},kind:"remote"},appRowId:h.app.id,onlyIf:{sql:"EXISTS (SELECT 1 FROM apps WHERE id = ? AND status = ? AND updated_at = ?)",params:[h.app.id,h.app.status,n]},now:n});return await e.run([...bn(h,n,{secretNames:await De(e),remoteTools:R.tools}),...g]),{plan:h,organization:a,hasOwner:o,actorGranted:l!==null&&h.grants.some(E=>E.userId===l)}})}function Ur(e,t,n,r,s=Date.now()){return te(async()=>{let a=Nt(t,n);if(!a)return{changed:!1};let o=await L(e,{organizationId:t.organizationId,type:a.status==="active"?"mcp_app.enabled":"mcp_app.disabled",actor:P(r),data:Ue(t),appRowId:t.id,onlyIf:{sql:"EXISTS (SELECT 1 FROM apps WHERE id = ? AND status = ? AND updated_at = ?)",params:[t.id,a.status,s]},now:s}),[i=[]]=await e.run([{sql:"UPDATE apps SET status = ?, updated_at = ? WHERE id = ? AND status = ? RETURNING id",params:[a.status,s,t.id,t.status]},...o]);if(i.length===0)throw new S("APP_CHANGING",`${t.appSlug} changed while this ran
15
+ Nothing was written; run it again.`,{retryable:!0});return{changed:!0}})}function xr(e,t,n,r=Date.now()){return te(async()=>{let s=$t(t);if(!t||!s)return{removed:!1};let a=await H(e);return await e.run([{sql:"UPDATE apps SET status = ?, is_default = ?, updated_at = ? WHERE id = ?",params:[s.status,s.isDefault?1:0,r,t.id]},...be(t,r,{secretNames:await De(e)}),...a.tools?[en(t)]:[],...await L(e,{organizationId:t.organizationId,type:"mcp_app.removed",actor:P(n),data:Ue(t),appRowId:t.id,now:r})]),{removed:!0}})}function xe(e){return e?{status:String(e.status),toolCount:Number(e.tool_count??0),listedAt:e.fetched_at==null?null:Number(e.fetched_at),lastError:b(e.last_error)}:null}async function Gr(e,t){let n=[t.id,t.organizationId],[r=[]]=await e.run([{sql:"SELECT status, tool_count, fetched_at, last_error FROM app_tool_catalogs WHERE app_row_id = ? AND organization_id = ?",params:n},{sql:"DELETE FROM app_tools WHERE app_row_id = ? AND organization_id = ?",params:n},{sql:"DELETE FROM app_tool_catalogs WHERE app_row_id = ? AND organization_id = ?",params:n}]);return xe(r[0])}async function vn(e){if(!(await H(e)).credentials)return new Map;let[t=[]]=await e.run([{sql:"SELECT name, origin, bound_by, bound_at FROM remote_mcp_credentials ORDER BY name"}]);return new Map(t.map(n=>[String(n.name),{origin:String(n.origin),boundBy:b(n.bound_by),boundAt:n.bound_at==null?null:Number(n.bound_at)}]))}async function zr(e){let t=await se(e),n=[],r=new Map;if(t){let[i=[],p=[]]=await e.run([{sql:`SELECT ${await ne(e)} FROM apps WHERE organization_id = ? AND tier = ? AND status != '${O}' ORDER BY app_slug`,params:[t.organization.id,M]},{sql:"SELECT app_row_id, status, tool_count, fetched_at, last_error FROM app_tool_catalogs WHERE organization_id = ?",params:[t.organization.id]}]);n.push(...i.map(re));for(let c of p)r.set(String(c.app_row_id),xe(c))}let s=new Map(n.map(i=>[i.appSlug,i])),a=$e.map(i=>{let p=s.get(i)??null;return{id:i,name:tt[i].name,kind:"builtin",app:p,remote:null,keyName:nt(i),snapshot:p?r.get(p.id)??null:null}}),o=n.filter(i=>!Te(i.appSlug)&&ee(i)).map(i=>{let p=V(i);return{id:i.appSlug,name:i.name,kind:"remote",app:i,remote:p,keyName:p?X(p.auth):null,snapshot:r.get(i.id)??null}});return[...a,...o]}function Fr(e,t,n){if(!e.app||e.app.status===O)return"not added";if(e.app.status!=="active")return"off";if(e.kind==="remote"&&!e.remote||e.keyName&&!t.includes(e.keyName))return"needs setup";if(e.kind==="remote"&&e.keyName&&e.remote){let r=n.get(e.keyName);if(r&&r.origin!==On(e.remote.url))return"needs setup"}return"on"}function On(e){try{return new URL(e).origin}catch{return""}}function Mn(e){return e==="read"?{readOnlyHint:!0}:e==="destructive"?{destructiveHint:!0}:{}}function Cn(e,t,n,r){return n.map(s=>{let a=String(s.upstream_name),o=String(s.risk_hint),i=b(s.local_name),p=st(Mn(o),t,a),c=p.source==="default"&&o==="write"?"hint":p.source,u=i?r.get(i):void 0,y=at(t,a),l=!!Number(s.listed);return{name:i?`${e}_${i}`:null,serverName:a,title:b(s.title),risk:u??p.risk,source:c,on:y&&l,problem:y?l?null:b(s.problem)??"not listed":l?"turned off; leaves the catalog at the next listing":"turned off"}})}async function Hr(e,t,n){let r=[t.app.id,t.app.organizationId],s=await H(e),a=n?X(n.auth):null,[o=[],i=[],p=[],c=[]]=await e.run([{sql:"SELECT status, tool_count, fetched_at, last_error FROM app_tool_catalogs WHERE app_row_id = ? AND organization_id = ?",params:r},{sql:"SELECT name, title, risk FROM app_tools WHERE app_row_id = ? AND organization_id = ? ORDER BY name",params:r},...s.tools&&n?[{sql:`SELECT upstream_name, local_name, title, risk_hint, listed, problem, listed_at FROM remote_mcp_tools
16
+ WHERE app_row_id = ? AND organization_id = ? ORDER BY upstream_name`,params:r}]:[{sql:"SELECT 1 WHERE 0"}],...s.credentials&&a?[{sql:"SELECT origin, bound_by, bound_at FROM remote_mcp_credentials WHERE name = ?",params:[a]}]:[{sql:"SELECT 1 WHERE 0"}]]),u=new Map(i.map(l=>[String(l.name),String(l.risk)])),y=c[0];return{snapshot:xe(o[0]),remoteTools:n?Cn(t.id,n,p,u):[],catalogTools:i.map(l=>({name:`${t.id}_${String(l.name)}`,title:b(l.title),risk:String(l.risk)})),binding:y?{origin:String(y.origin),boundBy:b(y.bound_by),boundAt:y.bound_at==null?null:Number(y.bound_at)}:null,listingKnown:s.tools}}var Pn=3;function Br(e,t,n,r,s=Date.now(),a){return te(async()=>{let o=await H(e),[i=[]]=await e.run([o.tools?{sql:`SELECT upstream_name, local_name FROM remote_mcp_tools
17
+ WHERE app_row_id = ?1 AND (upstream_name = ?2 OR local_name = ?2 OR ?3 || local_name = ?2)
18
+ ORDER BY (upstream_name = ?2) DESC, upstream_name LIMIT 1`,params:[t.app.id,n,`${t.id}_`]}:{sql:"SELECT 1 WHERE 0"}]),p=i[0],c=p?String(p.upstream_name):n,u=p?b(p.local_name):null,y={};r.risk==="annotations"?y.risk=void 0:r.risk&&(y.risk=r.risk),r.enabled!==void 0&&(y.enabled=r.enabled);let l=t.app;for(let h=1;;h+=1){let R=V(l)?.tools[c]??null,g=_t(l,{tool:{name:c,override:y}}),E=g.remote.tools[c]??null,[A=[]]=await e.run([{sql:`UPDATE apps SET manifest = ?, name = ?, description = ?, updated_at = ?
19
+ WHERE id = ? AND manifest = ? AND status != '${O}' RETURNING id`,params:[g.manifest,g.name,g.description,s,l.id,l.manifest]},...a?await L(e,{organizationId:l.organizationId,type:"mcp_app.tool_changed",actor:P(a),data:{...Ue(l),tool:c,...E?.risk?{risk:E.risk}:{},...E?.enabled!==void 0?{enabled:E.enabled}:{},...E===null?{cleared:!0}:{}},appRowId:l.id,onlyIf:{sql:"changes() > 0",params:[]},now:s}):[]]);if(A.length>0)return{serverName:c,listedName:u?`${t.id}_${u}`:null,inListing:!!p,before:R,after:E,rev:g.remote.rev};let w=await Zt(e,l.organizationId,l.appSlug);if(!w||h>=Pn)throw new S("APP_CHANGING",`${t.id} keeps changing while this writes its tool settings
20
+ Nothing was written; run it again.`,{retryable:!0});l=w}})}async function tn(e,t,n,r=Date.now()){let s={bound:[],undeclared:[],ambiguous:[]},a=t.filter(Ae);if(a.length===0||!(await H(e)).credentials)return s;let o=await Qt(e),i=await vn(e),p=[];for(let c of a){let u=[...o.get(c)??[]].sort();u.length===0?s.undeclared.push({name:c,kept:i.get(c)?.origin??null}):u.length>1?s.ambiguous.push({name:c,origins:u}):(s.bound.push({name:c,origin:u[0]}),p.push({sql:`INSERT INTO remote_mcp_credentials (name, origin, bound_by, bound_at) VALUES (?, ?, ?, ?)
21
+ ON CONFLICT(name) DO UPDATE SET origin = excluded.origin, bound_by = excluded.bound_by, bound_at = excluded.bound_at`,params:[c,u[0],n,r]}))}return p.length>0&&await e.run(p),s}async function nn(e,t){let n=t.filter(Ae);if(n.length===0||!(await H(e)).credentials)return[];let[r=[]]=await e.run([{sql:`DELETE FROM remote_mcp_credentials WHERE name IN (${n.map(()=>"?").join(", ")}) RETURNING name`,params:n}]);return r.map(s=>String(s.name))}async function rn(e){let[t=[]]=await e.run([{sql:`SELECT app_slug, tier, manifest FROM apps WHERE tier = ? AND status != '${O}' ORDER BY app_slug`,params:[M]}]),n=new Map;for(let r of t){let s=V({tier:String(r.tier),manifest:b(r.manifest)}),a=s?X(s.auth):null;a&&n.set(a,[...n.get(a)??[],String(r.app_slug)])}return n}import{text as zn}from"node:stream/consumers";var Ge=40,Ln=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|common|organizations|consumers)$/i,Un={issuer:"the issuer's https URL, which serves /.well-known/openid-configuration (no query, fragment or user:password@)",tenant:"the Directory (tenant) ID, a GUID like 72f988bf-86f1-41af-91ab-2d7cd011db47, or common, organizations or consumers",label:`the button text after "Continue with", at most ${Ge} characters`};function xn(e,t){switch(e){case"issuer":{let n;try{n=new URL(t)}catch{return`"${t}" isn't a URL.`}if(n.protocol!=="https:")return`"${t}" isn't an https URL.`;if(n.username||n.password)return"It carries a user name or password; the issuer's URL has none.";if(n.search||n.hash)return"It has a query or a fragment; the issuer's URL has neither.";let r=n.hostname.toLowerCase();return r==="localhost"||r==="127.0.0.1"?"A deployed Gateway can't reach a loopback issuer.":null}case"tenant":return Ln.test(t)?null:`"${t}" isn't a Directory (tenant) ID, common, organizations or consumers.`;case"label":return t.length<=Ge?null:`It is ${t.length} characters; the button takes ${Ge} at most.`;default:return null}}function Gn(e){return Un[e]??null}function sn(e){let t=Ze(e)?.settings.find(r=>r.name===e),n=t?Gn(t.role):null;if(!(!t||!n))return{takes:n,check:r=>xn(t.role,r)}}function pn(e){return e?"env":process.stdin.isTTY?"prompt":"stdin"}function cn(e,t){let n=pn(t);if(!(n==="prompt"||e.length<2))throw new S("SECRET_SEVERAL_NAMES",`${n==="env"?"--from-env":"A piped value"} sets one secret at a time, and you named ${e.length}`,{fix:`run it once per name, e.g. ${n==="env"?`${m} secret set ${e[0]} --from-env ${t}`:`echo "$${e[0]}" | ${m} secret set ${e[0]}`}`})}function ln(e){return e.length<2?e[0]??"":`${e.slice(0,-1).join(", ")} or ${e.at(-1)}`}function G(e,{exact:t=!1}={}){return n=>e.includes(t?n:n.toLowerCase())?null:`Not ${e.length>2?"one of ":""}${ln(e)}.`}function oe(e,t){return n=>{let r=n.split(/[\s,]+/).filter(Boolean),s=r.find(a=>!e(a));return s!==void 0?`"${s}" isn't ${t}.`:r.length>0?null:`Name ${t}.`}}var ze=["true","false","1","0","on","off","yes","no"],Fn=/^[^\s@<>]+@[^\s@<>]+\.[^\s@<>]+$/,Hn=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9-]{2,63}$/,Bn=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/,Wn=/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.cloudflareaccess\.com$/,an=/^[A-Za-z0-9._:-]{1,256}$/,qn=/^\/v1(\/[a-z0-9_-]+)+$/,Fe=3650,Vn=e=>Hn.test(e.toLowerCase().replace(/^@/,"")),jn=e=>Bn.test(e.toLowerCase().replace(/\.$/,""));function Yn(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"?t:null}catch{return null}}function dn(e){let t;try{t=new URL(e)}catch{return null}return t.username||t.password||t.search||t.hash?null:t.protocol==="https:"&&Wn.test(t.hostname.toLowerCase())?t:null}function Kn(e){let t=dn(/^[a-z]+:\/\//i.test(e)?e:`https://${e}`);return t!==null&&(t.pathname==="/"||t.pathname==="")}var Jn={EMAIL_FROM:{takes:"an address, or Name <address> (with EMAIL_FROM_NAME set, unless the name is in it)",check:e=>{let t=lt(e,"sender");return t&&Fn.test(t.address)?null:`"${e}" isn't an address or Name <address>.`}},EMAIL_FROM_NAME:{takes:"the sender's display name, e.g. Acme Support"},EMAIL_PROVIDER:{takes:`${ln(ke)}: which provider sends when both are set up`,check:G(ke)},EMAIL_PASSWORD_SIGN_IN:{takes:"true or false; false turns password sign-in off (only while Cloudflare Access sign-in is on)",check:G(ze)},MASTODON_URL:{takes:"the Mastodon instance's https origin, e.g. https://mastodon.social",check:e=>Je(Ke.mastodon,{MASTODON_URL:e})?null:`"${e}" isn't an https origin (no path).`},AI_PROXY_EXTRA_ROUTES:{takes:"/v1 paths beyond inference the AI proxy may forward, comma separated, e.g. /v1/files",check:oe(e=>qn.test(e),"a /v1/... path")},MCP_OAUTH_ENABLED:{takes:"true or false; false turns the OAuth server for MCP clients off",check:G(ze)},MCP_DCR_ENABLED:{takes:"true or false; false turns dynamic client registration off",check:G(ze)},MCP_ALLOWED_ORIGINS:{takes:"browser origins allowed to call /mcp, comma separated, e.g. http://localhost:6274",check:oe(e=>Yn(e)!==null,"an http or https URL")},MCP_AUDIT_RETENTION_DAYS:{takes:`days of MCP tool-call audit rows to keep: a whole number from 1 to ${Fe}`,check:e=>/^\d+$/.test(e)&&Number(e)>=1&&Number(e)<=Fe?null:`Not a whole number from 1 to ${Fe}.`},CLOUDFLARE_ACCESS_OIDC_ISSUER:{takes:"https://<team>.cloudflareaccess.com/cdn-cgi/access/sso/oidc/<client id>",check:e=>{let t=dn(e);return t&&/^\/cdn-cgi\/access\/sso\/oidc\/[^/]+\/?$/.test(t.pathname)?null:`"${e}" isn't an Access for SaaS issuer URL.`}},CLOUDFLARE_ACCESS_OIDC_CLIENT_ID:{takes:"the Access for SaaS application's client id"},CLOUDFLARE_ACCESS_OIDC_LABEL:{takes:`the sign-in button's label ("Continue with <label>"), at most 40 characters`},CLOUDFLARE_ACCESS_TEAM_DOMAIN:{takes:"<team>.cloudflareaccess.com",check:e=>Kn(e)?null:`"${e}" isn't <team>.cloudflareaccess.com.`},CLOUDFLARE_ACCESS_AUD:{takes:"the AUD tag of the Access application on the Gateway's host (several: comma separated)",check:oe(e=>an.test(e),"an AUD tag")},CLOUDFLARE_ACCESS_APPS_AUD:{takes:"the AUD tag of the Access application on the apps' hosts (several: comma separated)",check:oe(e=>an.test(e),"an AUD tag")},CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS:{takes:"email domains whose people join without an invitation, comma separated, e.g. example.com",check:oe(Vn,"a domain like example.com")},CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN:{takes:`everyone (anyone the outer ring admits joins); to turn it off: ${m} secret unset CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN`,check:G(["everyone"])},HOSTED_OPEN_SIGNUP:{takes:"true or false; false keeps a hosted Gateway's sign-up invite-only",check:G(["true","false"])},BROWSER_APP_INSTALLS:{takes:"on or off, in lowercase; off turns browser app installs off",check:G(["on","off"],{exact:!0})},EVENTS_ALLOW_PRIVATE_TARGETS:{takes:"true or false, in lowercase; true lets event webhooks reach http: URLs and private host names",check:G(["true","false"],{exact:!0})},DISPATCH_NAMESPACE:{takes:"the Workers for Platforms namespace third-party Workers go into (hosted Gateway only)"},THIRD_PARTY_DOMAIN:{takes:"the registrable domain third-party apps are named on (hosted Gateway only)",check:e=>jn(e)?null:`"${e}" isn't a domain like example.com.`}};function He(e){return Jn[e]??sn(e)}function Xn(e){let t=He(e);return t?[`Takes ${t.takes}`]:[]}function un(e,t){return t.trim()?He(e)?.check?.(t.trim())??null:"Enter a value."}function on(e,t){let n=t.trim(),r=un(e,n);if(r===null)return n;let s=He(e),a=n.replace(/\s+/g," ").slice(0,64);throw new S("SETTING_VALUE_INVALID",`${e} can't be "${a}"
22
+ ${r}`,{...s?{fix:`use ${s.takes}`}:{},data:{name:e}})}async function mn(e,t){let n=Qe(e),r=t.fromEnv,s=pn(r);if(s==="env"){let a=process.env[r],o=n?a?.trim():a;if(!o)throw new S("SECRET_EMPTY",`$${r} is empty or not set`,{fix:`export ${r} first, or name another variable with --from-env`});return n?on(e,o):o}if(s==="stdin"){let a=(await zn(process.stdin)).replace(/\r?\n$/,""),o=n?a.trim():a;if(o)return n?on(e,o):o}if(s==="stdin"||!q(t.json??!1))throw new S("SECRET_VALUE_REQUIRED",`Can't ask for ${e}'s value without a terminal
23
+ Or pipe it in: echo "$${e}" | ${m} secret set ${e}`,{rerun:`${m} secret set ${e} --from-env ${e}`});return n?(await gt(e,{context:Xn(e),validate:o=>un(e,o)})).trim():(await ft(`Value for ${e}`)).trim()}async function ks(e,...t){await ue(e,async n=>{cn(t,e["from-env"]),await Qn({flags:e,out:n,names:t,readValue:r=>mn(r,{fromEnv:e["from-env"],json:e.json})})})}async function Is(e,...t){await ue(e,n=>sr({flags:e,out:n,names:t}))}async function Ds(e,t){await ue(e,n=>ar({flags:e,out:n,appId:t}))}async function Qn(e){let{applied:t,gatewayHost:n}=await er(e),r=(t.gateway?.pinned??[]).map(({name:s,origin:a})=>`${s} is sent to ${a} and nowhere else.`);e.out.emit({type:"done",message:[`Set ${We(t,"on")}`,...r].join(`
24
+ `),display:[...r,v.dim(t.app?"Live now. No deploy needed.":`Live now on ${n}. No deploy needed.`)].join(`
25
+ `),data:Ve(t)})}async function er(e){let t=await Sn(e.names,e,"set");rr(t.providers,e.names,e.out);let n={};for(let s of e.names)n[s]=await e.readValue(s);return{applied:await we(t,n,e,"set"),gatewayHost:t.gatewayHost}}function tr(e){return e.mode==="oauth_client"?k([...e.token.map(t=>t.host??"the provider's origin"),...e.api]):k([...e.hosts,...e.hostSetting?[`the host ${e.hostSetting} names`]:[]])}function nr(e){return e.mode==="oauth_client"?[...e.token.flatMap(t=>t.host?[t.host]:[]),...e.api]:[...e.hosts]}function rr(e,t,n){for(let r of e){let{capability:s}=r;for(let a of pe(s).filter(o=>t.includes(o))){let o=r.addedAt?` on ${new Date(r.addedAt).toISOString().slice(0,10)}`:"",i=r.addedBy?` by ${r.addedBy}`:"";n.emit({type:"step",step:"secrets.provider",status:"ok",message:`${a} is ${s.label}'s, registered${i}${o}; the key is sent to ${tr(s)}.`,data:{name:a,provider:r.id,addedBy:r.addedBy,addedAt:r.addedAt,hosts:nr(s),...s.mode==="api_key"&&s.hostSetting?{hostSetting:s.hostSetting}:{}}})}}}async function bs(e,t,n){let r=Object.keys(t),s=Object.values(t).every(o=>o===null);for(let o of r)if(!J(o))throw new Error(`${o} isn't a Gateway setting`);let a={route:{gateway:r,app:null,undeclared:[]},cf:e.cf,db:e.db,deployer:e.deployer,accountName:e.accountName,gatewayHost:e.gatewayUrl.replace(/^https:\/\//,""),app:null,providers:[]};return we(a,t,n,s?"unset":"set")}async function vs(e,t,n,r){let s=Object.keys(n),a=await Be(s,t.manifest,e,"set"),o=fe(s,t.manifest,t.source,"set",a.names);if(o.app&&!t.app)throw new S("APP_NOT_FOUND",`${t.manifest.id} isn't deployed yet
26
+ Its own ${k(o.app.names)} can be set after its first deploy. Nothing was changed.`,{rerun:`${m} deploy`});let i={route:o,cf:e.cf,db:e.db,deployer:e.deployer,accountName:e.accountName,gatewayHost:e.gatewayUrl.replace(/^https:\/\//,""),app:o.app&&t.app?{...o.app,...t.app}:null,providers:a.providers};return await we(i,n,r,"set")}async function sr(e){let{names:t,out:n}=e,r=await Sn(t,e,"unset"),{route:s}=r,a=()=>{let p=`${k(t)} ${t.length===1?"isn't":"aren't"} set on ${pr(s).join(" or ")}. Nothing changed.`;n.emit({type:"done",message:p,display:v.dim(p),data:{removed:!1}})};if(!await ur(r)){a();return}await wt({yes:e.flags.yes,interactive:e.interactive??q(e.flags.json??!1),confirm:e.confirm,question:`Remove ${We({...s.gateway.length>0?{gateway:{names:s.gateway,versions:{}}}:{},...s.app?{app:{id:s.app.manifest.id,workerName:"",names:s.app.names,versions:{}}}:{}},"from")}?`,unattended:"Removing secrets needs confirmation, and there's no terminal to ask in",context:s.undeclared.map(p=>s.app?.source==="registry"?`${p} isn't listed in ${s.app.manifest.id}'s deployed manifest.`:`${p} isn't listed in everyapp.config.ts.`)});let o=Object.fromEntries(t.map(p=>[p,null])),i=await we(r,o,e,"unset");if(!i){a();return}n.emit({type:"done",message:`Removed ${We(i,"from")}`,display:v.dim("Live now. No deploy needed."),data:Ve(i)})}async function ar(e){let{out:t}=e,n=e.appId?null:await Le(e.cwd??process.cwd()),{cf:r,db:s,gatewayUrl:a,install:o}=await fn(e),[i,p]=await Promise.all([ae(r),Pe(s,o)]),c=[...ce,...p.rows().flatMap(N=>pe(N.capability))],u=(N,T)=>t.emit({type:"done",message:Zn(N),display:N,data:T});if(!e.appId&&!n){let N=i.filter(d=>!W(d)),T=i.filter(d=>W(d)),$=await Ot(s),I=new Set($.flatMap(d=>d.manifest?me(d.manifest,p):[])),z=o.deploymentMode==="hosted",B=c.filter(d=>z||!_e(d)).filter(d=>!i.includes(d)),U=await rn(s),x=[...B.filter(d=>I.has(d)||z&&_e(d)),...[...U.keys()].filter(d=>!i.includes(d))],je=B.filter(d=>!x.includes(d)&&!Re(d)).length,ie=[],Se=[];for(let d of $){if(!d.manifest||!Ut(d.manifest,p)||d.tier==="dispatch")continue;if(d.tier===M){let K=pt(it(d.manifest),(An,_n)=>An==="gateway"?i.includes(_n):null);if(K.ready)continue;let Rn=ct(K,{cli:m,appId:d.appSlug,provider:!0});ie.push({id:d.appSlug,setup:Rn,rows:ge(d.appSlug,K.settings)});continue}let Y=d.status==="pending"?null:await Oe(r,d.workerName).catch(K=>(Se.push({id:d.appSlug,reason:C(K).split(`
27
+ `)[0]}),null)),{report:hn,setup:En}=j({manifest:d.manifest,appId:d.appSlug,gatewayNames:i,secretNames:Y,lookup:p});ie.push({id:d.appSlug,setup:En,rows:ge(d.appSlug,hn.settings)})}let Ye=ie.flatMap(d=>d.rows);u([v.dim(`Gateway secrets \xB7 ${a.replace(/^https:\/\//,"")}`),"",...Pt(["NAME","SET BY"],[...N.map(d=>[d,"you"]),...T.map(d=>[d,v.dim("setup")]),...x.map(d=>[d,v.dim("not set")])]),...je>0?[v.dim(`${je} more can be set; see docs/capabilities.md`)]:[],v.dim(`Sign-in providers (${Object.values(Ee).map(d=>d.label).join(", ")}): ${m} signin list`),...Ye.length>0?["",...Ce(Ye)]:[],...Se.length>0?[v.dim(or(Se))]:[]].join(`
28
+ `),{gateway:{workerName:Q,names:i,settable:c,mcpCredentials:[...U].map(([d,Y])=>({name:d,apps:Y,set:i.includes(d)}))},apps:ie.map(({id:d,setup:Y})=>({id:d,setup:Y}))});return}let y=e.appId?await bt(s,e.appId):await de(s,n.id),l=e.appId?wn(y):n,h=y&&y.status!=="pending"?y.workerName:null,R=Z(l),g=[];if(h){let N=(await qe(s,h)).filter(T=>T.binding!=="").map(T=>T.name);for(let T of[h,...N]){let $=await le(r,T);g.push({workerName:T,names:$,missing:R.filter(I=>!$.includes(I))})}}let E=g[0]?g[0].names.filter(N=>!F(N)):null,{report:A,setup:w}=j({manifest:l,appId:l.id,gatewayNames:i,secretNames:E,lookup:p}),f=ge(l.id,A.settings).map(N=>!h&&N.where===l.id?{...N,status:v.dim("after first deploy")}:N);for(let N of g.slice(1)){let T=N.names.filter(I=>!F(I)),{report:$}=j({manifest:l,appId:l.id,gatewayNames:i,secretNames:T,lookup:p});f.push(...zt(l.id,N.workerName.split("--").at(-1),$.settings))}let _=`${v.green("\u2713")} set`;if(e.flags.verbose&&g[0])for(let N of g[0].names.filter(F))f.push({app:l.id,setting:N,where:l.id,status:_});let D=h?w.command?[w.command.command]:[]:[...w.command?[{command:`${m} configure`,note:"in the app's directory"}]:[],`${m} deploy`];u(f.length>0?[...Ce(f,{app:!1}),...w.unmet.length>0?["",...Ft(w.unmet)]:[],...!h&&R.length>0?["",v.dim(`${l.id} isn't deployed yet; its own secrets can be set after that.`)]:[]].join(`
29
+ `):v.dim(`${l.id} declares no secrets and needs no Gateway settings.`),{app:{id:l.id,deployed:h!==null,workerName:h,declared:R,workers:g,secretNames:E,settings:A.settings,setup:w},gateway:{workerName:Q,names:i,needed:xt(A.settings,Me(i,p)),missing:Gt(A.settings,Me(i,p)),settable:c},...f.length>0&&D.length>0?{next:D}:{}})}function or(e){return`Couldn't list ${k(e.map(n=>`${n.id}'s`))} secrets. Cloudflare said: ${e[0].reason}. They show as not recorded.`}var ir=(n=>(n.Directory="directory",n.Registry="registry",n))(ir||{});function pr(e){return[...e.gateway.length>0?["the Gateway"]:[],...e.app?[e.app.manifest.id]:[]]}function fe(e,t,n,r,s=new Set){let a=u=>J(u)||s.has(u),o=e.filter(a),i=e.filter(u=>!a(u));if(i.length===0)return{gateway:o,app:null,undeclared:[]};let p=t?Z(t):[],c=[];for(let u of i){let y=cr(u,e,t,n,r);if(y)throw y;p.includes(u)||c.push(u)}return{gateway:o,app:{manifest:t,names:i,source:n},undeclared:c}}function cr(e,t,n,r,s){let a=n?Z(n):[];if(n&&a.includes(e))return null;let o=r==="registry"&&n?` --app ${n.id}`:"",i=gn(e,[...ce,...a]);return i?new S("SECRET_NOT_DECLARED",`${e} isn't a Gateway setting${n?` or one of ${n.id}'s secrets`:""}`,{rerun:`${m} secret ${s} ${t.map(p=>p===e?i:p).join(" ")}${o}`,data:{didYouMean:i}}):Re(e)?dr(e,s):W(e)&&!n?new S("SECRET_NOT_SETTABLE",`${e} can't be changed with secret ${s}
30
+ ${e==="THIRD_PARTY_DEPLOYS"?"It's the hosted Gateway's launch gate, opened by hand.":"It's one of the Gateway's own keys, written once by setup."}`):Ne(e)?new S("SECRET_NOT_SETTABLE",`${e} only works in local development
31
+ A deployed Gateway doesn't read it.`,{fix:"set it in the Gateway's .dev.vars"}):(Vt(e),n?s==="unset"?null:new S("SECRET_NOT_DECLARED",[`${n.id} doesn't list ${e} as a secret`,r==="registry"?`Its deployed manifest (what --app ${n.id} reads) doesn't list it, and it isn't a Gateway setting either.`:W(e)?`It's one of the Gateway's own keys; listing it under secrets gives ${n.id} a secret of its own.`:"It isn't a Gateway setting either."].join(`
32
+ `),{fix:`add it to secrets in everyapp.config.ts: ${lr(n,e)}${r==="registry"?` and deploy ${n.id} again`:""}`,rerun:`${m} secret set ${e}${o}`}):new S("SECRET_NOT_DECLARED",`${e} isn't a Gateway setting, and there's no app here
33
+ An app's own secrets are ${s==="set"?"set":"removed"} from the app's directory (where everyapp.config.ts is), or from anywhere with --app <id>.
34
+ Gateway settings: ${m} secret list`,{fix:"cd into the app's directory and run this again, or add --app <id>"}))}function lr(e,t){let n=e.secrets??[],r=a=>typeof a=="string"?JSON.stringify(a):`{ ${Object.entries(a).map(([o,i])=>`${o}: ${JSON.stringify(i)}`).join(", ")} }`,s=n.every(a=>typeof a=="string")?JSON.stringify(t):`{ name: ${JSON.stringify(t)} }`;return`secrets: [${[...n.map(r),s].join(", ")}],`}function dr(e,t){let n=(/^(.+)_SIGNIN_[A-Z_]+$/.exec(e)?.[1]??e).toLowerCase();if(Xe(n)){let r=Ee[n],s=r.settings.map(a=>a.name);return new S("SECRET_NOT_SETTABLE",`${e} isn't a setting of Sign in with ${r.label}
35
+ It reads ${k(s)}.`,{rerun:`${m} signin show ${n}`,data:{provider:n,names:s}})}return new S("SECRET_NOT_SETTABLE",`${n.toUpperCase()} isn't a sign-in provider (${he.join(", ")}): ${m} signin list`,{fix:`${t} a provider's own settings, as ${m} signin show <id> names them`,data:{providers:[...he]}})}function gn(e,t){let n=r=>r.toUpperCase().replace(/_/g,"");return t.find(r=>r!==e&&n(r)===n(e))}function fn({flags:e,out:t,createCf:n}){return Ct({gateway:Mt(e.gateway),accountId:e["account-id"],interactive:q(e.json??!1),login:{json:e.json,out:t,step:"login"},createCf:n})}async function qe(e,t){return(await Lt(e,t)).filter(n=>n.kind==="worker")}function wn(e){if(!e.manifest)throw new S("MANIFEST_NOT_FOUND",`${e.appSlug}'s registry row holds no manifest
36
+ Deploying it again stores one.`,{rerun:`${m} deploy`,rerunNote:"in the app's directory"});try{return ut(e.manifest)}catch(t){throw new S("INVALID_MANIFEST",`${e.appSlug}'s deployed manifest can't be read
37
+ ${C(t)}`,{rerun:`${m} deploy`,rerunNote:"in the app's directory"})}}function yn(e,t){let n=t?Z(t):[];return e.filter(r=>!J(r)&&!n.includes(r)&&dt.test(r)&&!W(r)&&!Ne(r)&&!F(r)&&!gn(r,[...ce,...n]))}async function Be(e,t,n,r){let s=yn(e,t);if(s.length===0)return{names:new Set,providers:[]};let a=await Pe(n.db,n.install),o=Wt(a,s),i=new Set(o.flatMap(c=>pe(c.capability)).filter(c=>s.includes(c))),p=s.filter(c=>!i.has(c));if(r==="unset"&&p.length>0){let c=await ae(n.cf);for(let u of p)c.includes(u)&&i.add(u)}return{names:i,providers:o}}async function Sn(e,t,n){let r=e.every(R=>J(R)),s=t.flags.app,a,o=async()=>a??=await fn(t),i=(R,g,E,A=[])=>({route:g,cf:R.cf,db:R.db,deployer:R.deployer,accountName:R.accountName,gatewayHost:R.gatewayUrl.replace(/^https:\/\//,""),app:E,providers:A});if(r)return i(await o(),fe(e,null,"directory",n),null);if(s){let R=await o(),g=await de(R.db,s);if(!g)throw new S("APP_NOT_FOUND",`${s} isn't deployed to this Gateway
38
+ An app's secrets can be set after its first deploy. Nothing was changed.`,{rerun:`${m} status`,rerunNote:"lists its apps"});let E=wn(g),A={id:E.id,secrets:ot(E)},w=await Be(e,A,R,n),f=fe(e,A,"registry",n,w.names);return i(R,f,f.app?{...f.app,workerName:g.workerName,rowId:g.id}:null,w.providers)}let p=await Le(t.cwd??process.cwd()),c=yn(e,p).length>0?await Be(e,p,await o(),n):{names:new Set,providers:[]},u=fe(e,p,"directory",n,c.names);if(!u.app)return i(await o(),u,null,c.providers);let y=await o(),{id:l}=u.app.manifest,h=await de(y.db,l);if(!h)throw new S("APP_NOT_FOUND",`${l} isn't deployed yet
39
+ Its secrets can be set after its first deploy. Nothing was changed.`,{rerun:`${m} deploy`});return i(y,u,{...u.app,workerName:h.workerName,rowId:h.id},c.providers)}async function ur({cf:e,db:t,route:n,app:r}){let s=[...n.gateway.length>0?[{workerName:Q,names:n.gateway}]:[],...r?(await qe(t,r.workerName)).map(a=>({workerName:a.name,names:r.names})):[]];for(let{workerName:a,names:o}of s){let i=await le(e,a);if(o.some(p=>i.includes(p)))return!0}return!1}async function we(e,t,n,r){let{out:s}=n,{cf:a,db:o,route:i,app:p,deployer:c}=e,u=q(n.flags.json??!1),y=R=>Object.fromEntries(R.map(g=>[g,t[g]??null])),l=r==="unset",h=i.gateway.length>0?await St({db:o,out:s},"gateway.secrets"):null;try{let R=p?await yt({db:o,out:s},{workerName:p.workerName,appId:p.manifest.id,purpose:"app.secrets"}):null;try{let g=[],E=null;if(h){let w=await ht(o);if(E=w,!w)throw new S("GATEWAY_NOT_INSTALLED",`The Gateway${e.accountName?` in ${e.accountName}`:""} isn't fully installed`,{rerun:`${m} setup`});g.push({step:"secrets.gateway",shownAs:"the Gateway",names:i.gateway,targets:[{workerName:Q,changes:y(i.gateway),recordedVersionIds:[w.liveVersionId],record:f=>Et(o,{...w,liveVersionId:f,updatedAt:Date.now(),updatedBy:c.actor})}]})}if(p){let w=await qe(o,p.workerName),f=w.map(_=>_.versionId);g.push({step:"secrets.app",shownAs:p.manifest.id,names:p.names,targets:[{workerName:p.workerName,changes:y(p.names),recordedVersionIds:f,record:_=>ve(o,p.workerName,_)},...w.filter(_=>_.binding!=="").map(_=>({workerName:_.name,changes:y(p.names),recordedVersionIds:f,record:D=>ve(o,p.workerName,D,_.binding)}))]})}for(let w of g)for(let f of w.names)s.emit({type:"progress",step:"secrets.route",message:`${f} is ${w.step==="secrets.gateway"?"a Gateway setting":`${w.shownAs}'s secret`} \u2192 Worker ${w.targets.map(_=>_.workerName).join(", ")}`});for(let w of g)for(let f of w.targets){let _=k(Object.keys(f.changes));await Bt({cf:a,workerName:f.workerName,shownAs:w.shownAs,recordedVersionIds:f.recordedVersionIds,interactive:u,change:l?{question:`Remove ${_} from it anyway?`,effect:`Removing ${_} creates a new version from it.`}:{question:`Set ${_} on it anyway?`,effect:`Setting ${_} creates a new version from it.`}})}if(l&&!await wr(a,g,s))return null;let A={};for(let[w,f]of g.entries()){let _=f.targets.filter($=>Object.keys($.changes).length>0);if(_.length===0)continue;let D=f.names.filter($=>_.some(I=>Object.hasOwn(I.changes,$))),N=`${l?"Removed":"Set"} ${k(D)} ${l?"from":"on"} ${f.shownAs}`;s.emit({type:"step",step:f.step,status:"start",message:l?"Removing...":`Updating ${f.shownAs}...`});let T={};for(let $ of _){try{await mt(a,$.workerName,$.changes)}catch(ye){let B=Object.values(A).flatMap(x=>x.names);if(B.length===0)throw ye;let U=g.slice(w).flatMap(x=>x.names);throw new S("SECRETS_PARTIALLY_APPLIED",[`Couldn't ${l?"remove":"set"} ${k(f.names)} ${l?"from":"on"} ${f.shownAs}`,`Cloudflare said: ${C(ye).split(`
40
+ `)[0]}`,`${k(B)} ${B.length===1?"is":"are"} ${l?"removed":"set"}; only ${k(U)} ${U.length===1?"is":"are"} left.`].join(`
41
+ `),{rerun:`${m} secret ${r} ${U.join(" ")}${p&&i.app?.source==="registry"&&U.some(x=>p.names.includes(x))?` --app ${p.manifest.id}`:""}`,retryable:!0,data:{applied:Ve(A),left:U}})}let z=(await Ht(a,$.workerName))?.versionId??null;z&&await $.record(z),T[$.workerName]=z,s.emit({type:"progress",step:"secrets.version",message:`${$.workerName} is now at version ${z??"unknown"}`})}if(f.step==="secrets.gateway"){let $=await mr(o,D,l,c.actor,s).catch(I=>(s.emit({type:"progress",step:"secrets.pin",message:`Couldn't record which origin ${k(D)} ${D.length===1?"is":"are"} pinned to (${C(I).split(`
42
+ `)[0]}); the Gateway pins it on first use`}),[]));if(A.gateway={names:D,versions:T,...$.length>0?{pinned:$}:{}},!l&&e.providers.length>0&&E){let I=await qt(o,E,D);I.length>0&&(A.gateway.bound=I,s.emit({type:"progress",step:"secrets.bind",message:`Bound ${k(I)}'s key to the hosts ${I.length===1?"its row names":"their rows name"}`,data:{providers:I}}))}}else A.app={id:p.manifest.id,workerName:p.workerName,names:D,versions:T},await fr(a,o,p,s);n.announce!==!1&&await gr(o,c,{app:p?.rowId??null,names:D,removing:l,target:f.step==="secrets.gateway"?"gateway":"app"},s),s.emit({type:"step",step:f.step,status:"ok",message:N,data:{action:r,names:D,versions:T}})}return await Jt({cf:a,db:o,deployer:c},{gateway:A.gateway?.names??[],appRowId:A.app&&p?p.rowId:null,except:n.setupRecordedBy},s),A}finally{await R?.release()}}finally{await h?.release()}}async function mr(e,t,n,r,s){if(n){for(let o of await nn(e,t))s.emit({type:"progress",step:"secrets.pin",message:`${o}'s pin to its MCP server's origin is gone`});return[]}let a=await tn(e,t,r);for(let{name:o,origin:i}of a.bound)s.emit({type:"progress",step:"secrets.pin",message:`${o} is pinned to ${i}`});for(let{name:o,kept:i}of a.undeclared)s.emit({type:"warning",code:"REMOTE_MCP_SECRET_UNDECLARED",step:"secrets.gateway",message:i?`No MCP app declares ${o} now
43
+ It stays pinned to ${i}, where it was set before; the Gateway sends it nowhere else.`:`No MCP app declares ${o}
44
+ The Gateway pins it to the first MCP app that uses it.`,data:{name:o,pinnedTo:i,fix:`${m} mcp add <url> --secret ${o}`}});for(let{name:o,origins:i}of a.ambiguous)s.emit({type:"warning",code:"REMOTE_MCP_SECRET_AMBIGUOUS",step:"secrets.gateway",message:`MCP apps at ${k(i)} all declare ${o}
45
+ It isn't pinned to any of them, so the Gateway sends it to none until one is removed.`,data:{name:o,origins:i,rerun:`${m} mcp list`,rerunNote:"names the apps"}});return a.bound}async function gr(e,t,n,r){try{let s=n.app?await Dt(e,n.app):null,a=s?.organizationId??(await se(e))?.organization.id;if(!a)return;await e.run(await L(e,{organizationId:a,type:"app.settings_changed",actor:P(t),data:{app:s?{id:s.appSlug,rowId:s.id,name:s.name}:null,settings:[...n.names],action:n.removing?"unset":"set",target:n.target},appRowId:s?.id??null}))}catch(s){r.emit({type:"progress",step:"secrets.record",message:`Couldn't record the change on the event bus (${C(s).split(`
46
+ `)[0]})`})}}async function fr(e,t,n,r){try{await vt(t,n.rowId,await Oe(e,n.workerName))}catch(s){r.emit({type:"progress",step:"secrets.record",message:`Couldn't record ${n.manifest.id}'s secret names (${C(s).split(`
47
+ `)[0]}); ${m} status records them`})}}async function wr(e,t,n){let r=!1;for(let s of t.flatMap(a=>a.targets)){let a=await le(e,s.workerName);for(let o of Object.keys(s.changes)){if(a.includes(o)){r=!0;continue}delete s.changes[o],n.emit({type:"progress",step:"secrets.held",message:`${o} isn't set on ${s.workerName}`})}}return r}function We(e,t){return[...e.gateway?[`${k(e.gateway.names)} ${t} the Gateway`]:[],...e.app?[`${k(e.app.names)} ${t} ${e.app.id}`]:[]].join(", and ")}function Ve(e){return{...e.gateway?{gateway:e.gateway}:{},...e.app?{app:e.app}:{}}}export{Jt as a,Tr as b,H as c,Cr as d,Pr as e,Lr as f,Ur as g,xr as h,Gr as i,vn as j,zr as k,Fr as l,On as m,Hr as n,Br as o,tn as p,xn as q,Gn as r,Xn as s,un as t,on as u,mn as v,ks as w,Is as x,Ds as y,Qn as z,er as A,bs as B,vs as C,sr as D,ar as E,ir as F,wn as G,Ve as H};
@@ -0,0 +1,146 @@
1
+ import{a as Ue}from"./chunk-GAPQSINH.js";import{A as z,B as ue,V as $e,Y as u,_ as Z,w as W,y as ze}from"./chunk-KOBKGQ27.js";import{e as O}from"./chunk-RL72BUT4.js";import{N as De,O as ce,P as pe,Q as ye,R as ve,Ya as Ie,bc as m,c as _,cb as ke,k as K,lb as we,nb as Me,ob as Le,qb as We}from"./chunk-FQ2A7YAP.js";var Pe=.01,xe=1e6,Fe=new WeakMap;function $(e){let a=Fe.get(e);return a||(a=e.run([{sql:"PRAGMA table_info(org_app_settings)"},{sql:"PRAGMA table_info(org_settings)"}]).then(([n=[],t=[]])=>n.some(i=>i.name==="monthly_cost_cap_micros")&&t.some(i=>i.name==="default_monthly_cost_cap_micros")),Fe.set(e,a)),a}async function me(e){if(!await $(e))throw new m("GATEWAY_PREDATES_COST_CAPS",`The Gateway predates dollar caps
2
+ Its database has no monthly cap in dollars until the Gateway is updated to a release that has it.`,{rerun:`${_} update`,rerunNote:"then run this again"})}function ge(e){if(e==null)return e;let a=Math.round(e*100);if(!Number.isFinite(e)||Math.abs(e*100-a)>1e-6||e<Pe||e>xe)throw new m("INVALID_CAP",`A monthly dollar cap is from $${Pe} to $${xe.toLocaleString("en-US")} in whole cents, or off`);return a*1e4}var Y=e=>e===null?null:Math.round(e/1e4)/100;function Q(e){return["default_monthly_call_cap IS NULL",...e.cost?["default_monthly_cost_cap_micros IS NULL"]:[],...e.ai?["ai_default IS NULL"]:[]].join(" AND ")}var qe=new WeakMap;function ee(e){let a=qe.get(e);return a||(a=e.run([{sql:"PRAGMA table_info(org_settings)"}]).then(([n=[]])=>n.some(t=>t.name==="ai_default")),qe.set(e,a)),a}async function Oa(e){if(!await ee(e))throw new m("GATEWAY_PREDATES_AI_DEFAULT",`The Gateway predates the default model provider
3
+ Its database has no ai_default column until the Gateway is updated to a release that has it.`,{rerun:`${_} update`,rerunNote:"then run this again"})}async function Ge(e,a){if(!await ee(e))return null;let[n=[]]=await e.run([{sql:"SELECT ai_default FROM org_settings WHERE organization_id = ?",params:[a]}]),t=n[0]?.ai_default;return ce(typeof t=="string"?t:null)}var He=e=>e===null?null:{provider:e.provider,model:e.model??null};async function en(e,a){if(a){let l=ye(a);if(l)throw new m("AI_DEFAULT_INVALID",`${a.provider} can't be the default model provider: ${l}`,{fix:`pick one of the providers ${_} ai list shows, as <provider> or <provider>/<model>`})}await Oa(e.db);let n=e.organization.id,t=await Ge(e.db,n),i=a===null?null:pe(a),r=(t===null?null:pe(t))!==i,d=r?await z(e.db,{organizationId:n,type:"ai.default_changed",actor:W(e.operator),data:{aiDefault:He(a),previous:He(t)},now:e.now}):[];return await e.db.run([{sql:`INSERT INTO org_settings (organization_id, ai_default, updated_at, updated_by)
4
+ VALUES (?1, ?2, ?3, ?4)
5
+ ON CONFLICT (organization_id) DO UPDATE SET ai_default = ?2, updated_at = ?3, updated_by = ?4`,params:[n,i,e.now,e.operator.userId]},{sql:`DELETE FROM org_settings WHERE organization_id = ? AND ${Q({cost:await $(e.db),ai:!0})}`,params:[n]},...d]),{choice:a,was:t,changed:r}}async function an(e,a){let[n,t]=await Promise.all([Ue(e),Ge(a.db,a.organization.id)]),i=d=>n.includes(d);return{resolution:ve({choice:t,isSet:i}),names:n,aiGateway:{on:De.every(i)}}}function nn(e){let a=e.trim();if(a==="off"||a==="none")return null;let n=ce(a);if(!n)throw new m("AI_DEFAULT_INVALID",`${e} isn't a provider: write the provider's id (openrouter), or the id and a model (openrouter/anthropic/claude-haiku-5.5), or off`,{fix:`${_} ai list names the providers the default can be`});return n}var Be=`SELECT users.id AS id, users.email AS email, users.name AS name, members.role AS role
6
+ FROM members JOIN users ON users.id = members.user_id
7
+ WHERE members.organization_id = ?1 AND lower(users.email) = ?2
8
+ LIMIT 1`,J=(e,a,n)=>`EXISTS (
9
+ SELECT 1 FROM members owners JOIN users owner ON owner.id = owners.user_id
10
+ WHERE owners.organization_id = ${e} AND owners.role = 'owner' AND owners.user_id <> ${a}
11
+ AND (owner.banned IS NULL OR owner.banned = 0 OR (owner.ban_expires IS NOT NULL AND owner.ban_expires <= ${n}))
12
+ )`;async function on(e,a,n,t,i){let r=n.trim().toLowerCase(),d=Date.now(),[l=[],,s=[]]=await e.run([{sql:Be,params:[a,r]},{sql:`UPDATE members SET role = ?3
13
+ WHERE organization_id = ?1
14
+ AND user_id = (SELECT id FROM users WHERE lower(email) = ?2 LIMIT 1)
15
+ AND role <> ?3
16
+ AND NOT (
17
+ role = 'owner' AND ?3 <> 'owner'
18
+ AND NOT ${J("?1","members.user_id","?4")}
19
+ )`,params:[a,r,t,d]},{sql:Be,params:[a,r]}]),o=Ye(l[0]);if(!o)return{kind:"not_found"};if(o.role===t)return{kind:"unchanged",member:o};let c=Ye(s[0])??o;return c.role===t?(i&&await e.run(await z(e,{organizationId:a,type:"member.role_changed",actor:W(i),data:{user:{id:c.id,email:c.email,name:c.name||null},role:t,previousRole:o.role},now:d})),{kind:"changed",member:c,previousRole:o.role}):{kind:"last_owner",member:o}}function Ye(e){return e?{id:String(e.id),email:String(e.email),name:String(e.name??""),role:String(e.role)}:null}import{createHash as Da,randomBytes as Ne,randomUUID as H}from"node:crypto";var D=e=>({id:e.id,email:e.email,name:e.name||null}),X=e=>({id:e.appSlug,rowId:e.id,name:e.name}),U=50;function A(e,a){return z(e.db,{organizationId:e.organization.id,actor:W(e.operator),now:e.now,...a})}async function ya(e){let a=await Z(e);if(!a||!a.hasOwner)throw new m("WORKSPACE_NOT_CLAIMED",`The Gateway has no owner yet
20
+ The setup claim makes the workspace, named after its owner; rename it after.`,{fix:"open the Gateway in a browser and claim it, then run this again"});return a.organization}function bn(e,a,n,t=Date.now()){return $e(async()=>{let i=await ya(e),r=i.name!==a;return r&&await e.run([{sql:"UPDATE organizations SET name = ? WHERE id = ?",params:[a,i.id]},...await z(e,{organizationId:i.id,type:"organization.renamed",actor:W(n),data:{name:a,previousName:i.name},now:t})]),{organization:{...i,name:a},previousName:i.name,changed:r}})}var va=72*60*60*1e3,Ia=60*60*1e3,na=1e9,Je=60,Ve=255,Se=90,ka=19,wa=e=>Da("sha256").update(e).digest("hex"),re=e=>`((',' || replace(${e}, ' ', '') || ',') LIKE '%,owner,%')`,ta=e=>`(NOT ${re(e)} OR ${J("?2","?1","?3")})`,ae=`EXISTS (SELECT 1 FROM members m WHERE m.user_id = ?1 AND m.organization_id = ?2 AND ${ta("m.role")})`,ne=`EXISTS (SELECT 1 FROM members m WHERE m.user_id = ?1 AND m.organization_id = ?2)
21
+ AND NOT EXISTS (SELECT 1 FROM members mine WHERE mine.user_id = ?1 AND ${re("mine.role")}
22
+ AND NOT ${J("mine.organization_id","?1","?3")})`,Ma=e=>`(banned = 1 AND (ban_expires IS NULL OR ban_expires > ${e}))`;function oe(e,a){let n=[];for(let t=0;t<e.length;t+=a)n.push(e.slice(t,t+a));return n}function La(e){let a=(e??"").split(",").map(n=>n.trim());return a.includes("owner")?"owner":a.includes("admin")?"admin":a.includes("member")?"member":null}var g=e=>Number(e??0);function se(e,a){let n=Number(e.banned??0)===1,t=e.ban_expires==null?null:Number(e.ban_expires);return{id:String(e.id),name:String(e.name??""),email:String(e.email),role:String(e.role??"member"),primaryRole:La(u(e.role)),deactivated:n&&(t===null||t>a),createdAt:g(e.created_at)}}function he(e,a){let n=String(e.status),t=g(e.expires_at);return{id:String(e.id),email:String(e.email),role:String(e.role??"member"),status:n,expiresAt:t,createdAt:g(e.created_at),live:n==="pending"&&t>a}}function ia(e){return{id:String(e.id),name:String(e.name),description:u(e.description),createdAt:g(e.created_at),memberCount:g(e.member_count),appCount:g(e.app_count)}}function Re(e){return{id:String(e.id),appSlug:String(e.app_slug),name:String(e.name),description:String(e.description??""),status:String(e.status),scope:String(e.scope),tier:String(e.tier),hostname:u(e.hostname),everyone:Number(e.is_default??0)===1,manifest:u(e.manifest),secretNames:u(e.secret_names),accessCount:g(e.access_count)}}var de="u.id, u.name, u.email, m.role, u.banned, u.ban_expires, u.created_at",Te=`a.id, a.app_slug, a.name, a.description, a.status, a.scope, a.tier, a.hostname, a.is_default, a.manifest, a.secret_names,
23
+ (SELECT COUNT(DISTINCT g.user_id) FROM (
24
+ SELECT ua.user_id FROM user_app_access ua WHERE ua.app_row_id = a.id AND ua.organization_id = a.organization_id
25
+ UNION ALL
26
+ SELECT gm.user_id FROM group_app_access ga JOIN group_members gm ON gm.group_id = ga.group_id
27
+ WHERE ga.app_row_id = a.id AND ga.organization_id = a.organization_id AND gm.organization_id = a.organization_id
28
+ ) g JOIN members mm ON mm.user_id = g.user_id AND mm.organization_id = a.organization_id) AS access_count`,te=e=>({id:String(e.id),name:String(e.name),slug:String(e.slug)});async function ra(e,a){let n=a.trim(),[t=[],i=[]]=await e.run([{sql:`SELECT id, name, slug FROM organizations
29
+ WHERE id = ?1 OR slug = ?1 OR lower(name) = lower(?1)
30
+ ORDER BY created_at, id`,params:[n]},{sql:"SELECT id, name, slug FROM organizations ORDER BY created_at, id"}]),r=t.map(te),d=r.find(s=>s.id===n)??r.find(s=>s.slug===n);if(d)return d;if(r.length===1)return r[0];if(r.length>1)throw new m("ORG_AMBIGUOUS",`${r.length} organizations are named ${n}: ${K(r.map(s=>`${s.slug} (${s.id})`))}
31
+ A name isn't unique, and any owner or admin can rename their organization; a slug or id is one organization's.`,{fix:"name it by its slug or id with --org",data:{organizations:r}});let l=i.map(te);throw new m("ORGANIZATION_NOT_FOUND",`No organization named ${n} on this Gateway${l.length>0?`
32
+ The Gateway has: ${K(l.map(s=>`${s.slug} (${s.name})`))}.`:""}`,{fix:"name one by its slug, id or name with --org",data:{organizations:l}})}async function Wa(e,a){if(a.email===null)return{actor:a.actor,email:null,userId:null};let[n=[]]=await e.run([{sql:"SELECT id FROM users WHERE lower(email) = lower(?) AND email_verified = 1",params:[a.email]}]);return{actor:a.actor,email:a.email,userId:u(n[0]?.id)}}var oa=()=>new m("ORGANIZATION_NOT_FOUND",`The Gateway has no organization yet
33
+ Its owner creates the first one by claiming it.`,{rerun:`${_} setup`,rerunNote:"prints the owner link"});async function Nn(e,a){if(a!==void 0)return ra(e,a);let n=await Z(e);if(!n)throw oa();return n.organization}async function Sn(e,a,n={}){let[t,i]=await Promise.all([Z(e),Wa(e,a)]);if(n.org===void 0&&!t)throw oa();let r=n.org===void 0?t.organization:await ra(e,n.org);return{db:e,organization:r,installOrganizationId:t?.organization.id??null,operator:i,now:n.now??Date.now()}}async function G(e,a){let n=a.trim(),[t=[]]=await e.db.run([{sql:`SELECT ${de} FROM members m JOIN users u ON u.id = m.user_id
34
+ WHERE m.organization_id = ?1 AND (lower(u.email) = lower(?2) OR u.id = ?2)
35
+ ORDER BY (u.id = ?2) DESC LIMIT 1`,params:[e.organization.id,n]}]),i=t[0];if(!i)throw new m("USER_NOT_FOUND",`${n} isn't a member of ${e.organization.name}`,{rerun:`${_} workspace users`,rerunNote:"lists the members and invitations"});return se(i,e.now)}async function ie(e,a,{callable:n=!1}={}){let t=a.trim(),[i=[]]=await e.db.run([{sql:`SELECT ${Te} FROM apps a
36
+ WHERE (a.organization_id = ?1${n?" OR a.scope = 'shared'":""}) AND a.status != '${O}'
37
+ AND (a.app_slug = ?2 OR a.id = ?2)
38
+ ORDER BY (a.organization_id = ?1) DESC, (a.id = ?2) DESC LIMIT 1`,params:[e.organization.id,t]}]),r=i[0];if(!r)throw new m("APP_NOT_FOUND",`No app named ${t} in ${e.organization.name}`,{rerun:`${_} workspace apps`,rerunNote:"lists them"});return Re(r)}async function sa(e,a){let n=a.trim(),[t=[]]=await e.db.run([{sql:`${ua} AND (g.id = ?2 OR lower(g.name) = lower(?2)) ORDER BY (g.id = ?2) DESC LIMIT 1`,params:[e.organization.id,n]}]),i=t[0];if(!i)throw new m("GROUP_NOT_FOUND",`No group named ${n} in ${e.organization.name}`,{rerun:`${_} workspace groups`,rerunNote:"lists them"});return ia(i)}async function da(e,a){let n=a.trim(),[t=[]]=await e.db.run([{sql:`SELECT id, email, role, status, expires_at, created_at FROM invitations
39
+ WHERE organization_id = ?1 AND status = 'pending' AND (id = ?2 OR lower(email) = lower(?2))
40
+ ORDER BY (id = ?2) DESC, created_at DESC LIMIT 1`,params:[e.organization.id,n]}]),i=t[0];if(!i)throw new m("INVITATION_NOT_PENDING",`No pending invitation for ${n} in ${e.organization.name}
41
+ It was accepted, canceled or never made.`,{rerun:`${_} workspace users`,rerunNote:"lists the pending invitations"});return he(i,e.now)}async function hn(e){let a=e.organization.id,[n=[],t=[]]=await e.db.run([{sql:`SELECT u.email FROM members m JOIN users u ON u.id = m.user_id
42
+ WHERE m.organization_id = ?1 AND ${re("m.role")} ORDER BY m.created_at, u.email`,params:[a]},{sql:`SELECT
43
+ (SELECT COUNT(*) FROM members WHERE organization_id = ?1) AS members,
44
+ (SELECT COUNT(*) FROM members m JOIN users u ON u.id = m.user_id WHERE m.organization_id = ?1 AND ${Ma("?2")}) AS deactivated,
45
+ (SELECT COUNT(*) FROM invitations WHERE organization_id = ?1 AND status = 'pending' AND expires_at > ?2) AS invitations,
46
+ (SELECT COUNT(*) FROM groups WHERE organization_id = ?1) AS groups,
47
+ (SELECT COUNT(*) FROM apps WHERE organization_id = ?1 AND status != '${O}') AS apps`,params:[a,e.now]}]),i=t[0]??{};return{organization:e.organization,owners:n.map(r=>String(r.email)),counts:{members:g(i.members),deactivated:g(i.deactivated),invitations:g(i.invitations),groups:g(i.groups),apps:g(i.apps)}}}async function Rn(e){let[a=[],n=[]]=await e.db.run([{sql:`SELECT ${de} FROM members m JOIN users u ON u.id = m.user_id
48
+ WHERE m.organization_id = ?1 ORDER BY u.email`,params:[e.organization.id]},{sql:`SELECT id, email, role, status, expires_at, created_at FROM invitations
49
+ WHERE organization_id = ?1 AND status = 'pending' ORDER BY created_at DESC`,params:[e.organization.id]}]),t={owner:0,admin:1,member:2};return{members:a.map(i=>se(i,e.now)).sort((i,r)=>(t[i.primaryRole??"member"]??3)-(t[r.primaryRole??"member"]??3)||i.email.localeCompare(r.email)),invitations:n.map(i=>he(i,e.now))}}function la(){let e=`einv_${Ne(32).toString("base64url")}`;return{token:e,hash:wa(e)}}var Tn=(e,a)=>`${e}/accept-invitation?token=${encodeURIComponent(a)}`,Cn=(e,a)=>`${e}/reset-password?token=${encodeURIComponent(a)}`;async function On(e,a,n){let t=a.trim().toLowerCase(),i=await za(e,"invite");await Xe(e,t);let r=H(),{token:d,hash:l}=la(),s=e.now+va,[,,o=[]]=await e.db.run([{sql:`INSERT INTO invitations (id, organization_id, email, role, status, expires_at, created_at, inviter_id)
50
+ SELECT ?1, ?2, ?3, ?4, 'pending', ?5, ?6, ?7
51
+ WHERE NOT EXISTS (SELECT 1 FROM members m JOIN users u ON u.id = m.user_id WHERE m.organization_id = ?2 AND lower(u.email) = ?3)
52
+ AND NOT EXISTS (SELECT 1 FROM invitations i WHERE i.organization_id = ?2 AND lower(i.email) = ?3 AND i.status = 'pending' AND i.expires_at > ?6)`,params:[r,e.organization.id,t,n,s,e.now,i]},{sql:`INSERT INTO invitation_link_tokens (id, invitation_id, token_hash, created_at)
53
+ SELECT ?1, ?2, ?3, ?4 WHERE EXISTS (SELECT 1 FROM invitations WHERE id = ?2)`,params:[H(),r,l,e.now]},{sql:"SELECT id, email, role, status, expires_at, created_at FROM invitations WHERE id = ?",params:[r]},...await A(e,{type:"member.invited",data:{invitation:{id:r,email:t,role:n,expiresAt:new Date(s).toISOString()},emailSent:!1},onlyIf:{sql:"EXISTS (SELECT 1 FROM invitations WHERE id = ?)",params:[r]}})]),c=o[0];if(!c)throw await Xe(e,t),new m("ALREADY_INVITED",`${t} was invited meanwhile`,{retryable:!0});return{invitation:he(c,e.now),token:d}}async function za(e,a){let{operator:n}=e;if(n.userId!==null){let[i=[]]=await e.db.run([{sql:"SELECT 1 AS member FROM members WHERE user_id = ? AND organization_id = ?",params:[n.userId,e.organization.id]}]);if(i.length>0)return n.userId}let t=n.email===null?"An API token has no account on the Gateway":n.userId===null?`${n.email} has no account on this Gateway (a verified one)`:`${n.email} isn't a member of ${e.organization.name}`;throw new m("WORKSPACE_NOT_A_MEMBER",`Only a member can ${a}: an invitation records who sent it
54
+ ${t}.`,{fix:n.email===null?`log in with your Cloudflare account (${_} login), claim the Gateway (${_} setup) or get invited, or invite from Admin \u2192 Users`:`claim the Gateway (${_} setup) or get invited to ${e.organization.name}, or invite from Admin \u2192 Users`})}async function Xe(e,a){let[n=[],t=[]]=await e.db.run([{sql:"SELECT u.email FROM members m JOIN users u ON u.id = m.user_id WHERE m.organization_id = ?1 AND lower(u.email) = ?2",params:[e.organization.id,a]},{sql:"SELECT id FROM invitations WHERE organization_id = ?1 AND lower(email) = ?2 AND status = 'pending' AND expires_at > ?3",params:[e.organization.id,a,e.now]}]);if(n.length>0)throw new m("ALREADY_MEMBER",`${a} is a member of ${e.organization.name} already`,{rerun:`${_} workspace users`,rerunNote:"lists the members"});if(t.length>0)throw new m("ALREADY_INVITED",`${a} has a pending invitation to ${e.organization.name} already`,{rerun:`${_} workspace invite-link ${a}`,rerunNote:"prints a new link for it"})}async function Dn(e,a){let n=await da(e,a);if(!n.live)throw new m("INVITATION_NOT_PENDING",`The invitation for ${n.email} expired on ${new Date(n.expiresAt).toISOString()}`,{rerun:`${_} workspace invite ${n.email}`,rerunNote:"makes a new one"});let{token:t,hash:i}=la(),[r=[]]=await e.db.run([{sql:`INSERT INTO invitation_link_tokens (id, invitation_id, token_hash, created_at)
55
+ SELECT ?1, ?2, ?3, ?4 WHERE EXISTS (SELECT 1 FROM invitations WHERE id = ?2 AND status = 'pending' AND expires_at > ?4)
56
+ RETURNING id`,params:[H(),n.id,i,e.now]}]);if(r.length===0)throw new m("INVITATION_NOT_PENDING",`The invitation for ${n.email} was used or canceled meanwhile`);return{invitation:n,token:t}}async function yn(e,a){let n=await da(e,a),[t=[]]=await e.db.run([{sql:"UPDATE invitations SET status = 'canceled' WHERE id = ? AND organization_id = ? AND status = 'pending' RETURNING id",params:[n.id,e.organization.id]},...await A(e,{type:"member.invitation_cancelled",data:{invitation:{id:n.id,email:n.email,role:n.role}},onlyIf:{sql:"changes() > 0",params:[]}})]);if(t.length===0)throw new m("INVITATION_NOT_PENDING",`The invitation for ${n.email} was used or canceled meanwhile`);return{...n,status:"canceled",live:!1}}function je(e,a,n,t){let r=t.id===e.organization.id?`${a.email} is the last owner of ${t.name} who can act, so they can't be ${n}`:`${a.email} is the last owner of ${t.name} who can act, and a deactivation is account-wide: it would leave ${t.name} without one`,d=t.id===e.installOrganizationId?{rerun:`${_} workspace role <email> owner`,rerunNote:"for someone else, then this command again"}:{fix:`an owner of ${t.name} makes someone else an owner under Manage workspace \u2192 Users, then run this again`};return new m("LAST_OWNER",`${r}
57
+ Make someone else an owner of ${t.name} first, then try again.`,{...d,data:{organization:t,member:{id:a.id,email:a.email,name:a.name}}})}async function $a(e,a,n){let[t=[]]=await e.db.run([{sql:`SELECT o.id, o.name, o.slug FROM members mine JOIN organizations o ON o.id = mine.organization_id
58
+ WHERE mine.user_id = ?1 AND ${n?"1":"mine.organization_id = ?3"} AND ${re("mine.role")}
59
+ AND NOT ${J("mine.organization_id","?1","?2")}
60
+ ORDER BY (mine.organization_id = ?3) DESC, o.created_at, o.id`,params:[a,e.now,e.organization.id]}]);return t.map(te)}async function V(e,a,n,t,{afterWrite:i=!1}={}){let r=i?await G(e,a.id):a,d=await $a(e,r.id,t);if(d[0])throw je(e,r,n,d[0]);if(i)throw je(e,r,n,e.organization)}function ca(e,a,n){let t=[a.id,e.organization.id,e.now];return[{sql:`UPDATE users SET banned = 1, ban_reason = ?4, ban_expires = NULL, updated_at = ?3
61
+ WHERE id = ?1 AND ${ne} RETURNING id`,params:[...t,n]},{sql:`DELETE FROM sessions WHERE user_id = ?1 AND ${ne}`,params:t},{sql:`UPDATE user_access_tokens SET revoked_at = ?3, updated_at = ?3
62
+ WHERE user_id = ?1 AND revoked_at IS NULL AND ${ne}`,params:t},{sql:`UPDATE mcp_connections SET revoked_at = ?3, revoked_reason = 'user_deactivated'
63
+ WHERE user_id = ?1 AND revoked_at IS NULL AND ${ne}`,params:t}]}async function vn(e,a){let n=await G(e,a);await V(e,n,"deactivated",!0);let[t=[]]=await e.db.run([...ca(e,n,`Deactivated by ${e.operator.actor} (${_} workspace deactivate)`),...await pa(e,n)]);return t.length===0&&await V(e,n,"deactivated",!0,{afterWrite:!0}),{member:{...n,deactivated:!0},already:n.deactivated}}async function pa(e,a,n){return a.deactivated?[]:A(e,{type:"member.deactivated",data:{user:D(a),...n?{reason:n}:{}},onlyIf:{sql:"EXISTS (SELECT 1 FROM users WHERE id = ? AND banned = 1)",params:[a.id]}})}async function In(e,a){let n=await G(e,a);return await e.db.run([{sql:`UPDATE users SET banned = 0, ban_reason = NULL, ban_expires = NULL, updated_at = ?3
64
+ WHERE id = ?1 AND EXISTS (SELECT 1 FROM members m WHERE m.user_id = ?1 AND m.organization_id = ?2)`,params:[n.id,e.organization.id,e.now]},...n.deactivated?await A(e,{type:"member.reactivated",data:{user:D(n)},onlyIf:{sql:"changes() > 0",params:[]}}):[]]),{member:{...n,deactivated:!1},already:!n.deactivated}}async function kn(e,a,n){let t=await G(e,a);await V(e,t,"removed",!1);let[i=[]]=await e.db.run([{sql:"SELECT COUNT(*) AS n FROM members WHERE user_id = ? AND organization_id != ?",params:[t.id,e.organization.id]}]),r=g(i[0]?.n);if(r===0&&await n.accessMayLetBackIn(t)){let[o=[]]=await e.db.run([...ca(e,t,`Removed by ${e.operator.actor} (${_} workspace remove); deactivated instead, as Cloudflare Access would let them back in`),...await pa(e,t,"deleted_with_access_auto_join")]);return o.length===0&&await V(e,t,"removed",!0,{afterWrite:!0}),{member:{...t,deactivated:!0},deactivatedInstead:!0,accountDeleted:!1,otherOrganizations:r}}let d=[t.id,e.organization.id,e.now],[,,,,l=[],s=[]]=await e.db.run([{sql:`DELETE FROM user_app_access WHERE user_id = ?1 AND organization_id = ?2 AND ${ae}`,params:d},{sql:`DELETE FROM group_members WHERE user_id = ?1 AND organization_id = ?2 AND ${ae}`,params:d},{sql:`UPDATE user_access_tokens SET revoked_at = ?3, updated_at = ?3
65
+ WHERE user_id = ?1 AND organization_id = ?2 AND revoked_at IS NULL AND ${ae}`,params:d},{sql:`UPDATE mcp_connections SET revoked_at = ?3, revoked_reason = 'member_removed'
66
+ WHERE user_id = ?1 AND organization_id = ?2 AND revoked_at IS NULL AND ${ae}`,params:d},{sql:`DELETE FROM members WHERE user_id = ?1 AND organization_id = ?2 AND ${ta("role")} RETURNING id`,params:d},n.deleteAccounts?{sql:"DELETE FROM users WHERE id = ?1 AND NOT EXISTS (SELECT 1 FROM members WHERE user_id = ?1) RETURNING id",params:[t.id]}:{sql:"SELECT NULL AS id WHERE 0"},...await A(e,{type:"member.removed",data:{user:D(t),accountDeleted:n.deleteAccounts&&r===0},onlyIf:{sql:"NOT EXISTS (SELECT 1 FROM members WHERE user_id = ? AND organization_id = ?)",params:[t.id,e.organization.id]}})]);return l.length===0&&await V(e,t,"removed",!1,{afterWrite:!0}),{member:t,deactivatedInstead:!1,accountDeleted:s.length>0,otherOrganizations:r}}async function wn(e,a){let n=await G(e,a);if(n.deactivated)throw new m("PASSWORD_RESET_REQUIRES_ACTIVE_USER",`${n.email} is deactivated, and a password-reset link is only for an active account`,{rerun:`${_} workspace reactivate ${n.email}`,rerunNote:"first, if they should be back"});let[t=[]]=await e.db.run([{sql:`SELECT o.id, o.name, o.slug FROM members m JOIN organizations o ON o.id = m.organization_id
67
+ WHERE m.user_id = ?1 AND m.organization_id != ?2 ORDER BY o.created_at, o.id`,params:[n.id,e.organization.id]}]);if(t.length>0){let d=t.map(te);throw new m("USER_IN_OTHER_ORGANIZATION",`${n.email} also belongs to ${K(d.map(l=>l.name))}, and a password is account-wide
68
+ The Gateway's own rule: a password-reset link is never made for someone in another organization, since it would reach that one too.`,{fix:"they reset it themselves with Forgot password (the Gateway's email must be configured), or they are removed from the other organization first",data:{member:{id:n.id,email:n.email,name:n.name},organizations:d}})}let i=Ne(24).toString("base64url"),r=e.now+Ia;return await e.db.run([{sql:`INSERT INTO verifications (id, identifier, value, expires_at, created_at, updated_at)
69
+ VALUES (?1, ?2, ?3, ?4, ?5, ?5)`,params:[H(),`reset-password:${i}`,n.id,r,e.now]}]),{member:n,token:i,expiresAt:r}}var ua=`SELECT g.id, g.name, g.description, g.created_at,
70
+ (SELECT COUNT(*) FROM group_members gm WHERE gm.group_id = g.id) AS member_count,
71
+ (SELECT COUNT(*) FROM group_app_access ga JOIN apps a ON a.id = ga.app_row_id AND a.status != '${O}' WHERE ga.group_id = g.id) AS app_count
72
+ FROM groups g WHERE g.organization_id = ?1`;async function Mn(e){let[a=[]]=await e.db.run([{sql:`${ua} ORDER BY g.name`,params:[e.organization.id]}]);return a.map(ia)}function ma(e){let a=e.trim();if(a.length<1||a.length>Je)throw new m("GROUP_NAME_INVALID",`A group name is 1 to ${Je} characters${a?` (${a.length} given)`:""}`);return a}function ga(e){return new m("GROUP_NAME_TAKEN",`A group named "${e}" exists already in this organization`,{rerun:`${_} workspace groups`,rerunNote:"lists them"})}var Ua=()=>`grp_${Ne(8).toString("hex")}`;async function Ln(e,a){let n=ma(a.name),t=a.description?.trim()||null,i=Ua(),[r=[]]=await e.db.run([{sql:`INSERT INTO groups (id, organization_id, name, description, created_at, created_by)
73
+ SELECT ?1, ?2, ?3, ?4, ?5, ?6
74
+ WHERE NOT EXISTS (SELECT 1 FROM groups WHERE organization_id = ?2 AND lower(name) = lower(?3))
75
+ RETURNING id`,params:[i,e.organization.id,n,t,e.now,e.operator.userId]},...await A(e,{type:"group.created",data:{group:{id:i,name:n},...t?{description:t}:{}},onlyIf:{sql:"EXISTS (SELECT 1 FROM groups WHERE id = ?)",params:[i]}})]);if(r.length===0)throw ga(n);return{id:i,name:n,description:t,createdAt:e.now,memberCount:0,appCount:0}}async function Wn(e,a,n){let t=await sa(e,a),i=n.name===void 0?t.name:ma(n.name),r=n.description===void 0?t.description:n.description.trim()||null,[d=[]]=await e.db.run([{sql:`UPDATE groups SET name = ?3, description = ?4
76
+ WHERE id = ?1 AND organization_id = ?2
77
+ AND NOT EXISTS (SELECT 1 FROM groups WHERE organization_id = ?2 AND lower(name) = lower(?3) AND id != ?1)
78
+ RETURNING id`,params:[t.id,e.organization.id,i,r]},...t.name!==i||t.description!==r?await A(e,{type:"group.updated",data:{group:{id:t.id,name:i},...t.name!==i?{previousName:t.name}:{},...t.description!==r&&r?{description:r}:{}},onlyIf:{sql:"changes() > 0",params:[]}}):[]]);if(d.length===0)throw ga(i);return{...t,name:i,description:r}}async function zn(e,a){let n=await sa(e,a),t=[n.id,e.organization.id];return await e.db.run([{sql:"DELETE FROM group_app_access WHERE group_id = ?1 AND organization_id = ?2",params:t},{sql:"DELETE FROM group_members WHERE group_id = ?1 AND organization_id = ?2",params:t},{sql:"DELETE FROM groups WHERE id = ?1 AND organization_id = ?2",params:t},...await A(e,{type:"group.removed",data:{group:{id:n.id,name:n.name}},onlyIf:{sql:"NOT EXISTS (SELECT 1 FROM groups WHERE id = ?)",params:[n.id]}})]),n}async function Ke(e,a){let[n=[]]=await e.db.run([{sql:`SELECT ${de}, (gm.user_id IS NOT NULL) AS in_group
79
+ FROM members m JOIN users u ON u.id = m.user_id
80
+ LEFT JOIN group_members gm ON gm.group_id = ?2 AND gm.user_id = u.id
81
+ WHERE m.organization_id = ?1 ORDER BY u.email`,params:[e.organization.id,a.id]}]);return n.map(t=>({...se(t,e.now),inGroup:Number(t.in_group)===1}))}function Ce(e,a){let n=new Set(e);if(a.set){let r=new Set(a.set);return{add:[...r].filter(d=>!n.has(d)),remove:[...n].filter(d=>!r.has(d))}}let t=[...new Set(a.add??[])].filter(r=>!n.has(r)),i=[...new Set(a.remove??[])].filter(r=>n.has(r));return{add:t,remove:i}}async function q(e,a){let n=[];for(let t of a){let i=await G(e,t);n.some(r=>r.id===i.id)||n.push(i)}return n}async function _e(e,a){let n=[];for(let t of a){let i=await ie(e,t);n.some(r=>r.id===i.id)||n.push(i)}return n}async function $n(e,a,n){let[t,i,r]=await Promise.all([n.set?q(e,n.set):void 0,q(e,n.add??[]),q(e,n.remove??[])]),d=await Ke(e,a),l=d.filter(c=>c.inGroup).map(c=>c.id),s=Ce(l,{set:t?.map(c=>c.id),add:i.map(c=>c.id),remove:r.map(c=>c.id)}),o=new Map(d.map(c=>[c.id,c]));return await e.db.run([...oe(s.remove,Se).map(c=>({sql:`DELETE FROM group_members WHERE group_id = ? AND organization_id = ? AND user_id IN (${c.map(()=>"?").join(", ")})`,params:[a.id,e.organization.id,...c]})),...s.add.map(c=>({sql:`INSERT INTO group_members (group_id, user_id, organization_id, added_at, added_by)
82
+ SELECT ?1, ?2, ?3, ?4, ?5 WHERE EXISTS (SELECT 1 FROM members WHERE user_id = ?2 AND organization_id = ?3)
83
+ ON CONFLICT DO NOTHING`,params:[a.id,c,e.organization.id,e.now,e.operator.userId]})),...s.add.length>0||s.remove.length>0?await A(e,{type:"group.members_changed",data:{group:{id:a.id,name:a.name},added:s.add.slice(0,U).map(c=>D(o.get(c))),removed:s.remove.slice(0,U).map(c=>D(o.get(c))),addedCount:s.add.length,removedCount:s.remove.length}}):[]]),{added:s.add.map(c=>o.get(c)),removed:s.remove.map(c=>o.get(c)),members:await Ke(e,a)}}async function Ze(e,a){let[n=[]]=await e.db.run([{sql:`SELECT ${Te}, (ga.group_id IS NOT NULL) AS granted FROM apps a
84
+ LEFT JOIN group_app_access ga ON ga.group_id = ?2 AND ga.app_row_id = a.id
85
+ WHERE a.organization_id = ?1 AND a.scope != 'shared' AND a.status != '${O}' ORDER BY a.name`,params:[e.organization.id,a.id]}]);return n.map(t=>({...Re(t),granted:Number(t.granted)===1}))}function le(e){return new m("SHARED_APP_ACCESS",`${e.appSlug} is a shared app: every member of every organization can open it, so its access can't be changed`)}async function Un(e,a,n){let[t,i,r]=await Promise.all([n.set?_e(e,n.set):void 0,_e(e,n.add??[]),_e(e,n.remove??[])]);for(let o of[...t??[],...i])if(o.scope==="shared")throw le(o);let d=await Ze(e,a),l=Ce(d.filter(o=>o.granted).map(o=>o.id),{set:t?.map(o=>o.id),add:i.map(o=>o.id),remove:r.map(o=>o.id)}),s=new Map(d.map(o=>[o.id,o]));return await e.db.run([...oe(l.remove,Se).map(o=>({sql:`DELETE FROM group_app_access WHERE group_id = ? AND organization_id = ? AND app_row_id IN (${o.map(()=>"?").join(", ")})`,params:[a.id,e.organization.id,...o]})),...l.add.map(o=>({sql:`INSERT INTO group_app_access (group_id, app_row_id, organization_id, granted_at, granted_by)
86
+ SELECT ?1, ?2, ?3, ?4, ?5
87
+ WHERE EXISTS (SELECT 1 FROM apps WHERE id = ?2 AND organization_id = ?3 AND scope != 'shared' AND status != '${O}')
88
+ ON CONFLICT DO NOTHING`,params:[a.id,o,e.organization.id,e.now,e.operator.userId]})),...l.add.length>0||l.remove.length>0?await A(e,{type:"group.apps_changed",data:{group:{id:a.id,name:a.name},granted:l.add.slice(0,U).map(o=>X(s.get(o))),revoked:l.remove.slice(0,U).map(o=>X(s.get(o))),grantedCount:l.add.length,revokedCount:l.remove.length}}):[]]),{added:l.add.map(o=>s.get(o)),removed:l.remove.map(o=>s.get(o)),apps:await Ze(e,a)}}async function Pn(e){let[a=[]]=await e.db.run([{sql:`SELECT ${Te} FROM apps a WHERE a.organization_id = ?1 AND a.status != '${O}' ORDER BY a.name`,params:[e.organization.id]}]);return a.map(Re)}function Pa(e){let a=e.trim();if(a.length<1||a.length>Ve)throw new m("APP_NAME_INVALID",`An app's name is 1 to ${Ve} characters${a?` (${a.length} given)`:", not empty"}`,{fix:"give --name the name the app library should show, or leave --name off"});return a}async function xn(e,a,n){let t=await ie(e,a);if(n.name===void 0&&n.description===void 0&&n.everyone===void 0)throw new m("NOTHING_TO_SET","Nothing to set: give --name, --description or --everyone on|off");if(t.scope==="shared"&&n.everyone)throw le(t);let i=n.name===void 0?t.name:Pa(n.name),r=n.description===void 0?t.description:n.description.trim(),d=n.everyone??t.everyone,l=[],s={id:t.appSlug,rowId:t.id,name:i},o=[];if(d&&!t.everyone){let[S=[]]=await e.db.run([{sql:"SELECT u.id, u.email, u.name FROM members m JOIN users u ON u.id = m.user_id WHERE m.organization_id = ? ORDER BY u.email",params:[e.organization.id]}]);for(let f of oe(S,ka))l.push({sql:`INSERT INTO user_app_access (id, user_id, app_row_id, organization_id, granted_by) VALUES ${f.map(()=>"(?, ?, ?, ?, ?)").join(", ")} ON CONFLICT DO NOTHING RETURNING id`,params:f.flatMap(y=>[H(),String(y.id),t.id,e.organization.id,e.operator.userId])});let b=S.map(f=>D({id:String(f.id),email:String(f.email),name:u(f.name)}));o.push(...await A(e,{type:"app.access_changed",data:{app:s,granted:b.slice(0,U),revoked:[],grantedCount:b.length,revokedCount:0,everyone:!0},appRowId:t.id}))}else n.everyone===!1&&t.everyone&&o.push(...await A(e,{type:"app.access_changed",data:{app:s,granted:[],revoked:[],grantedCount:0,revokedCount:0,everyone:!1},appRowId:t.id}));(i!==t.name||r!==t.description)&&o.push(...await A(e,{type:"app.renamed",data:{app:s,...i!==t.name?{previousName:t.name}:{},...r!==t.description?{description:r}:{}},appRowId:t.id}));let h=(await e.db.run([{sql:`UPDATE apps SET name = ?3, description = ?4, is_default = ?5, updated_at = ?6
89
+ WHERE id = ?1 AND organization_id = ?2 AND status != '${O}'`,params:[t.id,e.organization.id,i,r,d?1:0,e.now]},...l,...o])).slice(1,1+l.length);return{app:await ie(e,t.id),granted:h.reduce((S,b)=>S+b.length,0)}}async function Qe(e,a){if(a.scope==="shared")throw le(a);let[n=[]]=await e.db.run([{sql:`SELECT ${de},
90
+ (ua.id IS NOT NULL) AS direct,
91
+ (SELECT group_concat(g.name, char(31)) FROM group_app_access ga
92
+ JOIN group_members gm ON gm.group_id = ga.group_id AND gm.user_id = u.id
93
+ JOIN groups g ON g.id = ga.group_id
94
+ WHERE ga.app_row_id = ?2 AND ga.organization_id = ?1) AS via_groups
95
+ FROM members m JOIN users u ON u.id = m.user_id
96
+ LEFT JOIN user_app_access ua ON ua.app_row_id = ?2 AND ua.organization_id = ?1 AND ua.user_id = u.id
97
+ WHERE m.organization_id = ?1 ORDER BY u.email`,params:[e.organization.id,a.id]}]);return n.map(t=>({...se(t,e.now),direct:Number(t.direct)===1,viaGroups:u(t.via_groups)?.split("").sort()??[]}))}async function Fn(e,a,n){if(a.scope==="shared")throw le(a);let[t,i,r]=await Promise.all([n.set?q(e,n.set):void 0,q(e,n.add??[]),q(e,n.remove??[])]),d=await Qe(e,a),l=Ce(d.filter(o=>o.direct).map(o=>o.id),{set:t?.map(o=>o.id),add:i.map(o=>o.id),remove:r.map(o=>o.id)}),s=new Map(d.map(o=>[o.id,o]));return await e.db.run([...oe(l.remove,Se).map(o=>({sql:`DELETE FROM user_app_access WHERE app_row_id = ? AND organization_id = ? AND user_id IN (${o.map(()=>"?").join(", ")})`,params:[a.id,e.organization.id,...o]})),...l.add.map(o=>({sql:`INSERT INTO user_app_access (id, user_id, app_row_id, organization_id, granted_at, granted_by)
98
+ SELECT ?1, ?2, ?3, ?4, ?5, ?6 WHERE EXISTS (SELECT 1 FROM members WHERE user_id = ?2 AND organization_id = ?4)
99
+ ON CONFLICT DO NOTHING`,params:[H(),o,a.id,e.organization.id,e.now,e.operator.userId]})),...l.add.length>0||l.remove.length>0?await A(e,{type:"app.access_changed",data:{app:X(a),granted:l.add.slice(0,U).map(o=>D(s.get(o))),revoked:l.remove.slice(0,U).map(o=>D(s.get(o))),grantedCount:l.add.length,revokedCount:l.remove.length},appRowId:a.id}):[]]),{granted:l.add.map(o=>s.get(o)),revoked:l.remove.map(o=>s.get(o)),users:await Qe(e,a)}}function F(e){return e.appCap!==null?{cap:e.appCap,source:"app"}:e.unlimited?{cap:null,source:null}:e.defaultCap!==null?{cap:e.defaultCap,source:"default"}:{cap:null,source:null}}var ea=(e,a)=>e===null?a!==null:a===null||e>a,aa=new WeakMap;function _a(e){let a=aa.get(e);return a||(a=e.run([{sql:"PRAGMA table_info(org_settings)"},{sql:"PRAGMA table_info(org_app_settings)"}]).then(([n=[],t=[]])=>n.length>0&&t.some(i=>i.name==="unlimited")),aa.set(e,a)),a}async function Oe(e){if(!await _a(e))throw new m("GATEWAY_PREDATES_DEFAULT_CAPS",`The Gateway predates default caps
100
+ Its database has no workspace default cap and no no-cap override until the Gateway is updated to a release that has them.`,{rerun:`${_} update`,rerunNote:"then run this again"})}var Ea=e=>e===null||Number.isInteger(e)&&e>=1&&e<=na,fa=()=>new m("INVALID_CAP",`A monthly cap is a whole number from 1 to ${na.toLocaleString("en-US")}, or off`),k=e=>e==null?null:Number(e);function Aa(e,a){return!ea(e.calls,a.calls)&&!ea(e.cost,a.cost)?null:{cap:e.calls,previousCap:a.calls,...e.cost!==a.cost&&{costCap:Y(e.cost),previousCostCap:Y(a.cost)}}}function ba(e,a){return e.calls===a.calls&&e.cost===a.cost?null:{cap:e.calls,previousCap:a.calls,...e.cost!==a.cost&&{costCap:Y(e.cost),previousCostCap:Y(a.cost)}}}async function qn(e,a,n,t={}){let i=t.unlimited??!1,r=await ie(e,a,{callable:!0});if(n!==void 0&&!Ea(n))throw fa();let d=ge(t.costUsd);if(i&&(n!=null||d!=null))throw new m("INVALID_CAP",`An app has a cap or no cap, not both
101
+ Give a number, --usd, off, or --unlimited.`);if(!i&&n===void 0&&d===void 0)throw new m("INVALID_CAP",`Missing the cap
102
+ Give a number of calls, --usd, off, or --unlimited.`);let l=await _a(e.db);i&&await Oe(e.db),d!==void 0&&await me(e.db);let s=l&&await $(e.db),o=e.organization.id,[c=[],h=[]]=await e.db.run([{sql:`SELECT monthly_call_cap${l?", unlimited":""}${s?", monthly_cost_cap_micros":""} FROM org_app_settings WHERE organization_id = ? AND app_row_id = ?`,params:[o,r.id]},...l?[{sql:`SELECT default_monthly_call_cap AS cap${s?", default_monthly_cost_cap_micros AS cost_cap":""} FROM org_settings WHERE organization_id = ?`,params:[o]}]:[]]),S=k(c[0]?.monthly_call_cap),b=k(c[0]?.monthly_cost_cap_micros),f=Number(c[0]?.unlimited??0)===1,y=k(h[0]?.cap),w=k(h[0]?.cost_cap),T=i?null:n===void 0?S:n,v=i?null:d===void 0?b:d,R=F({appCap:S,unlimited:f,defaultCap:y}),B=F({appCap:b,unlimited:f,defaultCap:w}),I=F({appCap:T,unlimited:i,defaultCap:y}),P=F({appCap:v,unlimited:i,defaultCap:w}),p=n==null&&d==null?null:await ue(e.db,{organizationId:o,deployer:e.operator,now:e.now}),E={calls:I.cap,cost:P.cap},C={calls:R.cap,cost:B.cap},M=Aa(E,C),L=M?null:ba(E,C)??(I.source!==R.source||P.source!==B.source?{cap:I.cap,previousCap:R.cap}:null),N=M?await A(e,{type:"cap.raised",data:{app:X(r),...M,source:"app"},appRowId:r.id}):L?await A(e,{type:"cap.changed",data:{app:X(r),...L,source:"app"},appRowId:r.id}):[],j=T===null&&v===null&&!i?{sql:"DELETE FROM org_app_settings WHERE organization_id = ? AND app_row_id = ?",params:[o,r.id]}:s?{sql:`INSERT INTO org_app_settings (organization_id, app_row_id, monthly_call_cap, monthly_cost_cap_micros, unlimited, updated_at, updated_by)
103
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)
104
+ ON CONFLICT (organization_id, app_row_id) DO UPDATE SET monthly_call_cap = ?3, monthly_cost_cap_micros = ?4, unlimited = ?5, updated_at = ?6, updated_by = ?7`,params:[o,r.id,T,v,i?1:0,e.now,e.operator.userId]}:l?{sql:`INSERT INTO org_app_settings (organization_id, app_row_id, monthly_call_cap, unlimited, updated_at, updated_by)
105
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6)
106
+ ON CONFLICT (organization_id, app_row_id) DO UPDATE SET monthly_call_cap = ?3, unlimited = ?4, updated_at = ?5, updated_by = ?6`,params:[o,r.id,T,i?1:0,e.now,e.operator.userId]}:{sql:`INSERT INTO org_app_settings (organization_id, app_row_id, monthly_call_cap, updated_at, updated_by)
107
+ VALUES (?1, ?2, ?3, ?4, ?5)
108
+ ON CONFLICT (organization_id, app_row_id) DO UPDATE SET monthly_call_cap = ?3, updated_at = ?4, updated_by = ?5`,params:[o,r.id,T,e.now,e.operator.userId]},x=await e.db.run([j,...p?[p]:[],...N]),Ca=p?u(x[1]?.[0]?.id):null;return{app:r,cap:T,costCapMicros:v,unlimited:i,was:S,wasCostCapMicros:b,wasUnlimited:f,effective:I,before:R,effectiveCost:P,beforeCost:B,capAlertsId:Ca}}async function Hn(e,a,n){if(a!==void 0&&!Ea(a))throw fa();let t=ge(n);if(a===void 0&&t===void 0)throw new m("INVALID_CAP",`Missing the default
109
+ Give a number of calls, --usd, or off.`);await Oe(e.db),t!==void 0&&await me(e.db);let i=await $(e.db),r=e.organization.id,[d=[]]=await e.db.run([{sql:`SELECT default_monthly_call_cap AS cap${i?", default_monthly_cost_cap_micros AS cost_cap":""} FROM org_settings WHERE organization_id = ?`,params:[r]}]),l=k(d[0]?.cap),s=k(d[0]?.cost_cap),o=a===void 0?l:a,c=t===void 0?s:t,h=a==null&&t==null?null:await ue(e.db,{organizationId:r,deployer:e.operator,now:e.now}),S={calls:o,cost:c},b={calls:l,cost:s},f=Aa(S,b),y=f?null:ba(S,b),w=f?await A(e,{type:"cap.raised",data:{app:null,...f,source:"default"}}):y?await A(e,{type:"cap.changed",data:{app:null,...y,source:"default"}}):[],T=[i?{sql:`INSERT INTO org_settings (organization_id, default_monthly_call_cap, default_monthly_cost_cap_micros, updated_at, updated_by)
110
+ VALUES (?1, ?2, ?3, ?4, ?5)
111
+ ON CONFLICT (organization_id) DO UPDATE SET default_monthly_call_cap = ?2, default_monthly_cost_cap_micros = ?3, updated_at = ?4, updated_by = ?5`,params:[r,o,c,e.now,e.operator.userId]}:{sql:`INSERT INTO org_settings (organization_id, default_monthly_call_cap, updated_at, updated_by)
112
+ VALUES (?1, ?2, ?3, ?4)
113
+ ON CONFLICT (organization_id) DO UPDATE SET default_monthly_call_cap = ?2, updated_at = ?3, updated_by = ?4`,params:[r,o,e.now,e.operator.userId]},...a===null||t===null?[{sql:`DELETE FROM org_settings WHERE organization_id = ? AND ${Q({cost:i,ai:await ee(e.db)})}`,params:[r]}]:[]],v=await e.db.run([...T,...h?[h]:[],...w]),R=h?u(v[T.length]?.[0]?.id):null;return{cap:o,was:l,costCapMicros:c,wasCostCapMicros:s,capAlertsId:R}}var xa=/^\d{4}-(0[1-9]|1[0-2])$/;function Na(e){return`${e.getUTCFullYear()}-${String(e.getUTCMonth()+1).padStart(2,"0")}`}function Fa(e,a){let[n,t]=e.split("-").map(Number);return Na(new Date(Date.UTC(n,t-1+a,1)))}var Ee=`COALESCE(SUM(d.calls), 0) AS calls, COALESCE(SUM(d.failures), 0) AS failures,
114
+ COALESCE(SUM(d.input_tokens), 0) AS input_tokens, COALESCE(SUM(d.output_tokens), 0) AS output_tokens,
115
+ COALESCE(SUM(d.cost_micros), 0) AS cost_micros`,fe=e=>({calls:g(e.calls),failures:g(e.failures),inputTokens:g(e.input_tokens),outputTokens:g(e.output_tokens),costMicros:g(e.cost_micros)}),Ae={calls:0,failures:0,inputTokens:0,outputTokens:0,costMicros:0},be={monthlyCallCap:null,capUnlimited:!1,effectiveMonthlyCallCap:null,capSource:null,monthlyCostCapMicros:null,effectiveMonthlyCostCapMicros:null,costCapSource:null,paused:!1,pausedBy:null};async function Gn(e,a){if(!xa.test(a))throw new m("INVALID_MONTH",`--month ${a} isn't a month: use YYYY-MM`);await Oe(e.db);let n=await $(e.db),t=e.organization.id,i=`${a}-01`,r=`${Fa(a,1)}-01`,d=Date.parse(`${i}T00:00:00.000Z`),l=Date.parse(`${r}T00:00:00.000Z`),s="d.organization_id = ?1 AND d.day >= ?2 AND d.day < ?3",o="c.organization_id = ?1 AND c.decision = 'allowed' AND c.created_at >= ?2 AND c.created_at < ?3",[c=[],h=[],S=[],b=[],f=[],y=[],w=[]]=await e.db.run([{sql:`SELECT d.app_row_id, a.name, a.app_slug, ${Ee} FROM usage_daily d LEFT JOIN apps a ON a.id = d.app_row_id
116
+ WHERE ${s} GROUP BY d.app_row_id, a.name, a.app_slug`,params:[t,i,r]},{sql:`SELECT d.user_id, u.name, u.email, ${Ee} FROM usage_daily d
117
+ LEFT JOIN members m ON m.user_id = d.user_id AND m.organization_id = d.organization_id
118
+ LEFT JOIN users u ON u.id = m.user_id
119
+ WHERE ${s} GROUP BY d.user_id, u.name, u.email`,params:[t,i,r]},{sql:`SELECT d.kind, d.target, ${Ee} FROM usage_daily d WHERE ${s} GROUP BY d.kind, d.target`,params:[t,i,r]},{sql:`SELECT c.app_row_id, a.name, a.app_slug, COUNT(*) AS tool_calls FROM mcp_tool_calls c
120
+ LEFT JOIN apps a ON a.id = c.app_row_id WHERE ${o} GROUP BY c.app_row_id, a.name, a.app_slug`,params:[t,d,l]},{sql:`SELECT c.user_id, u.name, u.email, COUNT(*) AS tool_calls FROM mcp_tool_calls c
121
+ LEFT JOIN members m ON m.user_id = c.user_id AND m.organization_id = c.organization_id
122
+ LEFT JOIN users u ON u.id = m.user_id
123
+ WHERE ${o} GROUP BY c.user_id, u.name, u.email`,params:[t,d,l]},{sql:`SELECT a.id AS app_row_id, a.name, a.app_slug, s.monthly_call_cap, s.unlimited${n?", s.monthly_cost_cap_micros":""} FROM apps a
124
+ LEFT JOIN org_app_settings s ON s.app_row_id = a.id AND s.organization_id = ?1
125
+ WHERE (a.organization_id = ?1 OR a.scope = 'shared') AND a.status != '${O}'`,params:[t]},{sql:`SELECT default_monthly_call_cap AS cap${n?", default_monthly_cost_cap_micros AS cost_cap":""} FROM org_settings WHERE organization_id = ?`,params:[t]}]),T=k(w[0]?.cap),v=k(w[0]?.cost_cap),R=new Map;for(let p of c)R.set(String(p.app_row_id),{appRowId:String(p.app_row_id),appSlug:u(p.app_slug),name:u(p.name),...fe(p),toolCalls:0,...be,callable:!1});for(let p of b){let E=u(p.app_row_id);if(!E)continue;let C=R.get(E);C?C.toolCalls=g(p.tool_calls):R.set(E,{appRowId:E,appSlug:u(p.app_slug),name:u(p.name),...Ae,toolCalls:g(p.tool_calls),...be,callable:!1})}let B=a===Na(new Date(e.now));for(let p of y){let E=String(p.app_row_id),C=p.monthly_call_cap==null?null:Number(p.monthly_call_cap),M=Number(p.unlimited??0)===1,L=F({appCap:C,unlimited:M,defaultCap:T}),N=R.get(E)??{appRowId:E,appSlug:u(p.app_slug),name:u(p.name),...Ae,toolCalls:0,...be,callable:!0};N.callable=!0,N.monthlyCallCap=C,N.capUnlimited=M,N.effectiveMonthlyCallCap=L.cap,N.capSource=L.source;let j=k(p.monthly_cost_cap_micros),x=F({appCap:j,unlimited:M,defaultCap:v});N.monthlyCostCapMicros=j,N.effectiveMonthlyCostCapMicros=x.cap,N.costCapSource=x.source,N.pausedBy=B?L.cap!==null&&N.calls>=L.cap?"calls":x.cap!==null&&N.costMicros>=x.cap?"cost":null:null,N.paused=N.pausedBy!==null,R.set(E,N)}let I=new Map;for(let p of h)I.set(String(p.user_id),{userId:String(p.user_id),name:u(p.name),email:u(p.email),...fe(p),toolCalls:0});for(let p of f){let E=String(p.user_id),C=I.get(E);C?C.toolCalls=g(p.tool_calls):I.set(E,{userId:E,name:u(p.name),email:u(p.email),...Ae,toolCalls:g(p.tool_calls)})}let P=(p,E)=>E.calls-p.calls||E.toolCalls-p.toolCalls;return{month:a,defaultMonthlyCallCap:T,defaultMonthlyCostCapMicros:v,byApp:[...R.values()].sort((p,E)=>P(p,E)||(p.name??p.appRowId).localeCompare(E.name??E.appRowId)),byMember:[...I.values()].sort(P),byTarget:S.map(p=>({kind:String(p.kind),target:String(p.target),...fe(p)})).sort((p,E)=>E.calls-p.calls)}}var qa=200;async function Bn(e,a){let n=Math.min(Math.max(1,Math.trunc(a.limit??50)||1),qa),t=["c.organization_id = ?"],i=[e.organization.id];a.before&&(t.push("(c.created_at < ? OR (c.created_at = ? AND c.id < ?))"),i.push(a.before.createdAt,a.before.createdAt,a.before.id));for(let[s,o]of[["c.app_row_id",a.appRowId],["c.user_id",a.userId],["c.decision",a.decision],["c.risk",a.risk]])o!==void 0&&(t.push(`${s} = ?`),i.push(o));a.since!==void 0&&(t.push("c.created_at >= ?"),i.push(a.since)),i.push(n+1);let[r=[]]=await e.db.run([{sql:`SELECT c.id, c.created_at, c.user_id, u.name AS user_name, u.email AS user_email,
126
+ c.credential_kind, c.client_name, c.client_info, c.app_row_id, c.app_slug, a.name AS app_name, a.status AS app_status,
127
+ c.tool_name, c.via, c.risk, c.decision, c.reason, c.outcome, c.duration_ms, c.result_bytes
128
+ FROM mcp_tool_calls c
129
+ LEFT JOIN apps a ON a.id = c.app_row_id
130
+ LEFT JOIN members m ON m.user_id = c.user_id AND m.organization_id = c.organization_id
131
+ LEFT JOIN users u ON u.id = m.user_id
132
+ WHERE ${t.join(" AND ")}
133
+ ORDER BY c.created_at DESC, c.id DESC LIMIT ?`,params:i}]),d=r.slice(0,n),l=d.at(-1);return{calls:d.map(s=>{let o=u(s.app_row_id),c=u(s.app_status);return{id:String(s.id),createdAt:g(s.created_at),user:{id:String(s.user_id),name:u(s.user_name),email:u(s.user_email)},credential:{kind:String(s.credential_kind),clientName:u(s.client_name),clientInfo:u(s.client_info)},app:{rowId:o,slug:u(s.app_slug),name:u(s.app_name),removed:o!==null&&(c===null||c===O)},tool:{name:String(s.tool_name),risk:u(s.risk),via:u(s.via)},decision:s.decision==="allowed"?"allowed":"blocked",reason:u(s.reason),outcome:String(s.outcome),durationMs:s.duration_ms==null?null:Number(s.duration_ms),resultBytes:s.result_bytes==null?null:Number(s.result_bytes)}}),nextBefore:r.length>n&&l?{createdAt:g(l.created_at),id:String(l.id)}:null}}var Ha=/^(\*|[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*(\.\*)?)$/,Ga=80;async function Yn(e,a){await ze(e.db);let n=Math.min(Math.max(1,Math.trunc(a.limit??50)||1),ke),t=["e.organization_id = ?"],i=[e.organization.id];if(a.before&&(t.push("(e.time < ? OR (e.time = ? AND e.id < ?))"),i.push(a.before.time,a.before.time,a.before.id)),a.actorId!==void 0&&(t.push("e.actor_id = ?"),i.push(a.actorId)),a.type===void 0)t.push("e.type <> 'ping' AND e.type NOT LIKE 'tool.%'");else{let s=a.type.trim();if(s.length===0||s.length>Ga||!Ha.test(s))throw new m("INVALID_EVENT_TYPE",`--type is an event type (member.joined), a prefix (member.*, app.crm.*) or *${s?` (not ${s})`:""}`);let o=We(s);o?.op==="eq"?(t.push("e.type = ?"),i.push(o.value)):o&&(t.push("substr(e.type, 1, ?) = ?"),i.push(o.value.length,o.value))}a.since!==void 0&&(t.push("e.time >= ?"),i.push(a.since)),i.push(n+1);let[r=[]]=await e.db.run([{sql:`SELECT e.id, e.time, e.type, e.actor, e.actor_kind, e.actor_id, e.data, u.email AS user_email, u.name AS user_name
134
+ FROM events e
135
+ LEFT JOIN users u ON e.actor_kind = 'user' AND u.id = e.actor_id
136
+ WHERE ${t.join(" AND ")}
137
+ ORDER BY e.time DESC, e.id DESC LIMIT ?`,params:i}]),d=r.slice(0,n),l=d.at(-1);return{events:d.map(s=>{let o=we(s.actor),c=u(s.actor_kind)??o.kind,h=u(s.actor_id)??o.id,S=c==="user"?{kind:c,id:h,email:u(s.user_email)??o.email,name:u(s.user_name)??o.name}:{kind:c,id:h,email:o.email,name:o.name},b={};try{b=JSON.parse(String(s.data))}catch{b={}}let f=String(s.type);return{id:String(s.id),time:g(s.time),type:f,label:Me(f),actor:S,subject:Le(f,b),appEvent:Ie(f)}}),nextBefore:r.length>n&&l?{time:g(l.time),id:String(l.id)}:null}}var Sa=`SELECT t.id, t.user_id, u.email, t.name, t.token_prefix, t.app_row_id, a.app_slug, a.name AS app_name,
138
+ t.scopes, t.created_at, t.expires_at, t.last_used_at, t.revoked_at
139
+ FROM user_access_tokens t JOIN users u ON u.id = t.user_id
140
+ LEFT JOIN apps a ON a.id = t.app_row_id AND a.organization_id = t.organization_id
141
+ WHERE t.organization_id = ?1`;function ha(e,a){let n=e.revoked_at==null?null:Number(e.revoked_at),t=g(e.expires_at),i=[];try{let r=JSON.parse(String(e.scopes??"[]"));i=Array.isArray(r)?r.map(String):[]}catch{i=[]}return{id:String(e.id),user:{id:String(e.user_id),email:String(e.email)},name:String(e.name),prefix:String(e.token_prefix),app:{rowId:u(e.app_row_id),slug:u(e.app_slug),name:u(e.app_name)},scopes:i,createdAt:g(e.created_at),expiresAt:t,lastUsedAt:e.last_used_at==null?null:Number(e.last_used_at),revokedAt:n,active:n===null&&t>a}}async function Jn(e,a){let[n=[]]=await e.db.run([{sql:`${Sa}${a?" AND t.user_id = ?2":""} ORDER BY t.created_at DESC`,params:a?[e.organization.id,a]:[e.organization.id]}]);return n.map(t=>ha(t,e.now))}async function Vn(e,a){let[n=[]]=await e.db.run([{sql:`${Sa} AND t.id = ?2`,params:[e.organization.id,a.trim()]}]),t=n[0];if(!t)throw new m("TOKEN_NOT_FOUND",`No personal access token ${a.trim()} in ${e.organization.name}`,{rerun:`${_} workspace tokens`,rerunNote:"lists them by id"});let i=ha(t,e.now);return i.revokedAt!==null?{token:i,already:!0}:(await e.db.run([{sql:"UPDATE user_access_tokens SET revoked_at = ?3, updated_at = ?3 WHERE id = ?1 AND organization_id = ?2 AND revoked_at IS NULL",params:[i.id,e.organization.id,e.now]},...await A(e,{type:"token.revoked",data:{id:i.id,name:i.name,user:D({...i.user,name:null})},onlyIf:{sql:"changes() > 0",params:[]}})]),{token:{...i,revokedAt:e.now,active:!1},already:!1})}var Ra=`SELECT c.id, c.user_id, u.email, c.client_name, c.client_domain, c.redirect_host, c.app_scope, c.access,
142
+ c.created_at, c.last_used_at, c.revoked_at, c.revoked_reason,
143
+ (SELECT group_concat(a.app_slug, char(31)) FROM mcp_connection_apps ca JOIN apps a ON a.id = ca.app_row_id WHERE ca.connection_id = c.id) AS app_slugs
144
+ FROM mcp_connections c JOIN users u ON u.id = c.user_id
145
+ WHERE c.organization_id = ?1`;function Ta(e){return{id:String(e.id),user:{id:String(e.user_id),email:String(e.email)},clientName:String(e.client_name),clientDomain:u(e.client_domain),redirectHost:String(e.redirect_host),apps:e.app_scope==="all"?"all":u(e.app_slugs)?.split("").sort()??[],access:e.access==="write"?"write":"read",createdAt:g(e.created_at),lastUsedAt:e.last_used_at==null?null:Number(e.last_used_at),revokedAt:e.revoked_at==null?null:Number(e.revoked_at),revokedReason:u(e.revoked_reason)}}async function Xn(e,a){let[n=[]]=await e.db.run([{sql:`${Ra} AND c.revoked_at IS NULL${a?" AND c.user_id = ?2":""} ORDER BY c.created_at DESC`,params:a?[e.organization.id,a]:[e.organization.id]}]);return n.map(Ta)}async function jn(e,a){let[n=[]]=await e.db.run([{sql:`${Ra} AND c.id = ?2`,params:[e.organization.id,a.trim()]}]),t=n[0];if(!t)throw new m("CONNECTION_NOT_FOUND",`No AI connection ${a.trim()} in ${e.organization.name}`,{rerun:`${_} workspace connections`,rerunNote:"lists them by id"});let i=Ta(t);return i.revokedAt!==null?{connection:i,already:!0}:(await e.db.run([{sql:`UPDATE mcp_connections SET revoked_at = ?3, revoked_by = ?4, revoked_reason = 'user'
146
+ WHERE id = ?1 AND organization_id = ?2 AND revoked_at IS NULL`,params:[i.id,e.organization.id,e.now,e.operator.userId]},...await A(e,{type:"connection.revoked",data:{connection:{id:i.id,clientName:i.clientName},user:D({...i.user,name:null}),reason:"operator"},onlyIf:{sql:"changes() > 0",params:[]}})]),{connection:{...i,revokedAt:e.now,revokedReason:"user"},already:!1})}export{Pe as a,xe as b,en as c,an as d,nn as e,on as f,bn as g,na as h,Nn as i,Sn as j,G as k,ie as l,sa as m,hn as n,Rn as o,Tn as p,Cn as q,On as r,Dn as s,yn as t,vn as u,In as v,kn as w,wn as x,Mn as y,Ln as z,Wn as A,zn as B,Ke as C,$n as D,Ze as E,Un as F,Pn as G,Pa as H,xn as I,Qe as J,Fn as K,qn as L,Hn as M,xa as N,Na as O,Gn as P,qa as Q,Bn as R,Ha as S,Ga as T,Yn as U,Jn as V,Vn as W,Xn as X,jn as Y};
@@ -4,7 +4,7 @@ var s=`CREATE TABLE IF NOT EXISTS _everyapp_access (
4
4
  gateway_aud TEXT NOT NULL,
5
5
  apps_aud TEXT NOT NULL,
6
6
  written_at INTEGER NOT NULL
7
- )`;async function r(t){let[a=[]]=await t.run([{sql:"SELECT name FROM sqlite_master WHERE type = 'table' AND name = '_everyapp_access'"}]);if(a.length===0)return null;let[n=[]]=await t.run([{sql:"SELECT team_domain, gateway_aud, apps_aud, written_at FROM _everyapp_access WHERE id = 'access'"}]),e=n[0];return e?{teamDomain:String(e.team_domain),gatewayAud:String(e.gateway_aud),appsAud:String(e.apps_aud),writtenAt:Number(e.written_at)}:null}async function o(t,a,n=[]){await t.run([{sql:s},{sql:`INSERT INTO _everyapp_access (id, team_domain, gateway_aud, apps_aud, written_at)
7
+ )`;async function c(t){let[a=[]]=await t.run([{sql:"SELECT name FROM sqlite_master WHERE type = 'table' AND name = '_everyapp_access'"}]);if(a.length===0)return null;let[n=[]]=await t.run([{sql:"SELECT team_domain, gateway_aud, apps_aud, written_at FROM _everyapp_access WHERE id = 'access'"}]),e=n[0];return e?{teamDomain:String(e.team_domain),gatewayAud:String(e.gateway_aud),appsAud:String(e.apps_aud),writtenAt:Number(e.written_at)}:null}async function o(t,a,n=[]){await t.run([{sql:s},{sql:`INSERT INTO _everyapp_access (id, team_domain, gateway_aud, apps_aud, written_at)
8
8
  VALUES ('access', ?1, ?2, ?3, ?4)
9
9
  ON CONFLICT(id) DO UPDATE SET team_domain = excluded.team_domain,
10
- gateway_aud = excluded.gateway_aud, apps_aud = excluded.apps_aud, written_at = excluded.written_at`,params:[a.teamDomain,a.gatewayAud,a.appsAud,a.writtenAt]},...n])}async function d(t,a=[]){await t.run([{sql:s},{sql:"DELETE FROM _everyapp_access WHERE id = 'access'"},...a])}function u(t,a){return t.teamDomain===a.teamDomain&&t.gatewayAud===a.gatewayAud&&t.appsAud===a.appsAud}var i=["CLOUDFLARE_ACCESS_TEAM_DOMAIN","CLOUDFLARE_ACCESS_APPS_AUD","CLOUDFLARE_ACCESS_AUD"];function c(t){return i.every(a=>t.includes(a))}function p(t,a){return{on:c(t),teamDomain:a?.teamDomain??null}}export{r as a,o as b,d as c,u as d,i as e,p as f};
10
+ gateway_aud = excluded.gateway_aud, apps_aud = excluded.apps_aud, written_at = excluded.written_at`,params:[a.teamDomain,a.gatewayAud,a.appsAud,a.writtenAt]},...n])}async function d(t,a=[]){await t.run([{sql:s},{sql:"DELETE FROM _everyapp_access WHERE id = 'access'"},...a])}function u(t,a){return t.teamDomain===a.teamDomain&&t.gatewayAud===a.gatewayAud&&t.appsAud===a.appsAud}var i=["CLOUDFLARE_ACCESS_TEAM_DOMAIN","CLOUDFLARE_ACCESS_APPS_AUD","CLOUDFLARE_ACCESS_AUD"];function r(t){return i.every(a=>t.includes(a))}function p(t,a){return{on:r(t),teamDomain:a?.teamDomain??null}}export{c as a,o as b,d as c,u as d,i as e,p as f};
@@ -0,0 +1,15 @@
1
+ import{c as U,e as q}from"./chunk-EQLY5I46.js";import{Dc as f,Ec as w,Jc as F,Lc as Y,bc as b,c as B,f as M,fc as x,gc as H,hc as h,k as A}from"./chunk-FQ2A7YAP.js";import{z as o}from"zod";var D={perPage:100,maxPages:20};async function d(t){try{return await t}catch(e){throw P(e)}}var I=o.looseObject({name:o.string().nullish(),auth_domain:o.string(),session_duration:o.string().nullish(),allow_authenticate_via_warp:o.boolean().nullish(),deny_unmatched_requests:o.boolean().nullish(),deny_unmatched_requests_exempted_zone_names:o.array(o.string()).nullish(),warp_auth_non_browser_401:o.boolean().nullish(),mfa_config:o.unknown().nullish()});async function se(t){try{return await f(t,{plane:"account",args:["zero-trust","organization","get"]},I)}catch(e){if(h(e,"not_found")||e instanceof H&&/not[_ ]found/i.test(e.message))return null;throw P(e)}}async function Ee(t){try{return await se(t)}catch(e){if(h(e,"access_not_enabled"))return null;throw e}}function $e(t,e){return d(f(t,{plane:"account",files:{"body.json":e},args:n=>["zero-trust","organization","create","--body",`@${n["body.json"]}`]},I))}function ve(t,e,n){let s={name:e.name??e.auth_domain,auth_domain:e.auth_domain,allow_authenticate_via_warp:e.allow_authenticate_via_warp??!1,deny_unmatched_requests:e.deny_unmatched_requests??!1,deny_unmatched_requests_exempted_zone_names:e.deny_unmatched_requests_exempted_zone_names??[],warp_auth_non_browser_401:e.warp_auth_non_browser_401??!1,...e.mfa_config?{mfa_config:e.mfa_config}:{},session_duration:n};return d(f(t,{plane:"account",files:{"body.json":s},args:i=>["zero-trust","organization","update","--body",`@${i["body.json"]}`]},I))}var E=o.looseObject({id:o.string(),type:o.string(),name:o.string().nullish(),config:o.looseObject({restrict_to_account_members:o.boolean().nullish()}).nullish()});function Te(t){return d(w(t,["zero-trust","identity-providers","list"],o.array(E),D))}function ke(t){return d(f(t,{plane:"account",files:{"body.json":{name:"One-time PIN",type:"onetimepin",config:{}}},args:e=>["zero-trust","identity-providers","create","--body",`@${e["body.json"]}`]},E))}function Le(t){return d(f(t,{plane:"account",files:{"body.json":{name:"Cloudflare",type:"cloudflare",config:{restrict_to_account_members:!0}}},args:e=>["zero-trust","identity-providers","create","--body",`@${e["body.json"]}`]},E))}var $=o.looseObject({id:o.string(),name:o.string(),decision:o.string(),include:o.array(o.record(o.string(),o.unknown())).nullish(),exclude:o.array(o.record(o.string(),o.unknown())).nullish(),require:o.array(o.record(o.string(),o.unknown())).nullish(),reusable:o.boolean().nullish()});function Ne(t){return d(w(t,["zero-trust","access","policies","list"],o.array($),D))}function ze(t,e){return d(f(t,{plane:"account",files:{"body.json":{...e,exclude:[],require:[]}},args:n=>["zero-trust","access","policies","create","--body",`@${n["body.json"]}`]},$))}async function je(t,e){try{return await t.run({plane:"account",mode:"json",args:["zero-trust","access","policies","delete",e,"--force"]}),!0}catch(n){if(h(n,"not_found"))return!1;throw P(n)}}var oe=new Set(["id","uid","created_at","updated_at","app_count","reusable"]);function Be(t,e,n){let s={};for(let[i,r]of Object.entries(e))oe.has(i)||(s[i]=r);return s.include=n,s.exclude=e.exclude??[],s.require=e.require??[],d(f(t,{plane:"account",files:{"body.json":s},args:i=>["zero-trust","access","policies","update",e.id,"--body",`@${i["body.json"]}`]},$))}var ie=o.looseObject({path_pattern:o.string(),behavior:o.string()}),re=o.looseObject({type:o.string().nullish(),uri:o.string().nullish(),overrides:o.array(ie).nullish()}),ae=o.looseObject({id:o.string(),name:o.string().nullish(),precedence:o.number().nullish(),reusable:o.boolean().nullish()}),v=o.looseObject({id:o.string(),aud:o.string(),name:o.string().nullish(),type:o.string(),created_at:o.string().nullish(),destinations:o.array(re).nullish(),policies:o.array(ae).nullish(),session_duration:o.string().nullish(),http_only_cookie_attribute:o.boolean().nullish(),enable_binding_cookie:o.boolean().nullish(),allowed_idps:o.array(o.string()).nullish(),auto_redirect_to_identity:o.boolean().nullish(),app_launcher_visible:o.boolean().nullish(),oauth_configuration:o.looseObject({enabled:o.boolean().nullish()}).nullish()});function T(t){return d(w(t,["zero-trust","access","applications","list"],o.array(v),D))}function Me(t,e){return d(f(t,{plane:"account",files:{"body.json":e},args:n=>["zero-trust","access","applications","create","--body",`@${n["body.json"]}`]},v))}var ce=new Set(["id","uid","aud","created_at","updated_at","domain","self_hosted_domains","policies","scim_config"]);function G(t,e){let n={};for(let[s,i]of Object.entries(t))ce.has(s)||(n[s]=i);return n.policies=[...t.policies??[]].sort((s,i)=>(s.precedence??0)-(i.precedence??0)).map(s=>s.id),{...n,...e}}function W(t,e,n){return d(f(t,{plane:"account",files:{"body.json":n},args:s=>["zero-trust","access","applications","update",e,"--body",`@${s["body.json"]}`]},v))}async function He(t,e){try{return await t.run({plane:"account",mode:"json",args:["zero-trust","access","applications","delete",e,"--force"]}),!0}catch(n){if(h(n,"not_found"))return!1;throw P(n)}}var le="https://dash.cloudflare.com/profile/api-tokens";function P(t){return h(t,"auth")?new b("ACCESS_PERMISSION_MISSING",`This Cloudflare login can't manage Access
2
+ ${t.message.split(`
3
+ `)[0]}`,{fix:"use a login or token with Access: Apps and Policies (edit) and Access: Organizations, Identity Providers, and Groups (edit)",data:{url:le}}):t}var Z=["/mcp","/mcp/*"],Q="/health",ee="/api/auth/callback/apple",ue=[...Z,"/oauth/token","/oauth/register","/.well-known/*",Q,ee],pe=512;function de(t){if(!t.startsWith("/"))return null;let e=t.split("/").map((s,i)=>{if(i===0)return s;let r=s.replace(/\*{2,}/g,"*");return/^:[A-Za-z_][A-Za-z0-9_]*$/.test(r)?"*":r});if(e.some(s=>(s.match(/\*/g)??[]).length>1))return null;let n=e.join("/");return n.length>pe?null:n}var te=t=>t.map(e=>({path_pattern:e,behavior:"public"})),fe=t=>t.publicPaths.length>0||t.mcp;function ge(t,{managedOAuth:e}){let n=t.mcp&&!e?[...Z]:[],s=[];for(let i of t.publicPaths){let r=de(i);if(r===null){s.push({appId:t.appId,path:i,reason:"not_expressible"});continue}if(!n.includes(r)){if(n.length>=25){s.push({appId:t.appId,path:i,reason:"too_many"});continue}n.push(r)}}return{destination:{type:"public",uri:t.hostname.toLowerCase(),overrides:te(n)},dropped:s}}function me(t,e){return{type:"public",uri:t.toLowerCase(),overrides:te(e?[Q,ee]:ue)}}var O=t=>`*.${t.toLowerCase()}`;function ne(t,e){let n=t.toLowerCase(),s=`.${e.toLowerCase()}`;return n.endsWith(s)&&!n.slice(0,-s.length).includes(".")&&n.length>s.length}function k(t,e,{managedOAuth:n=!1}={}){let s=[{type:"public",uri:O(t),overrides:[]}],i=[],r=[];for(let a of[...e].sort((l,u)=>l.hostname.localeCompare(u.hostname))){if(!fe(a))continue;if(!ne(a.hostname,t)){r.push(a.appId);continue}let l=ge(a,{managedOAuth:n});i.push(...l.dropped),l.destination.overrides.length!==0&&s.push(l.destination)}return{destinations:s,dropped:i,outsideBase:r}}function he(t,e){let n=y(t);return!n||n.includes("/")?!1:n===e.gatewayHost.toLowerCase()||n===O(e.appBaseDomain)||ne(n,e.appBaseDomain)}function L(t,e){let n=[],s=[];for(let i of t)(he(i.uri,e)?n:s).push(i);return{owned:n,foreign:s}}var y=t=>(t??"").toLowerCase().replace(/\/+$/,"");function K(t){return t.map(e=>({type:e.type??"public",uri:y(e.uri),overrides:[...e.overrides??[]].map(n=>`${n.behavior}:${n.path_pattern}`).sort()})).sort((e,n)=>e.uri.localeCompare(n.uri))}function S(t,e){return JSON.stringify(K(t))===JSON.stringify(K(e))}function J(t,e){return t.type==="self_hosted"&&(t.destinations??[]).some(n=>(n.type??"public")==="public"&&y(n.uri)===y(e))}function N(t,{gatewayHost:e,appBaseDomain:n}){return{gateway:t.find(s=>J(s,e))??null,apps:t.find(s=>J(s,O(n)))??null}}var z=t=>t?.oauth_configuration?.enabled===!0,qe=t=>t.paths.length>0||t.signIn.length>0||t.missing.length>0;function Fe({scope:t,found:e,surfaces:n,providerIds:s}){let i=t.gatewayHost.toLowerCase(),r=O(t.appBaseDomain),a=z(e.gateway),l=k(t.appBaseDomain,n,{managedOAuth:a}),u=e.gateway!==null&&e.gateway.id===e.apps?.id,g=p=>L(p.destinations??[],t).owned,c={paths:[],signIn:[],missing:[]};if(e.gateway){let p=g(e.gateway).filter(m=>y(m.uri)===i);S(p,[me(i,a)])||c.paths.push(i),X(e.gateway,s)||c.signIn.push(i)}else c.missing.push(i);if(e.apps){let p=g(e.apps).filter(m=>!u||y(m.uri)!==i);S(p,l.destinations)||c.paths.push(r),!u&&!X(e.apps,s)&&c.signIn.push(r)}else c.missing.push(r);return c}var Ye=t=>({email:{email:t.toLowerCase()}}),Ge=t=>({email_domain:{domain:t.toLowerCase()}});function V(t){return JSON.stringify(t,(e,n)=>typeof n=="string"?n.toLowerCase():n)}function We(t,e){let n=new Set(t.map(V)),s=[];for(let i of e){let r=V(i);n.has(r)||(n.add(r),s.push(i))}return{include:[...t,...s],added:s}}function Ke(t){return t.flatMap(e=>{let n=e.email?.email;return typeof n=="string"?[n]:[]})}function Je(t){return t.flatMap(e=>{let n=e.email_domain?.domain;return typeof n=="string"?[n]:[]})}var _="cloudflare",R="onetimepin",Ve=["oidc","saml"];function Xe(t){return{cloudflare:!t.some(e=>e.type===_),pin:!t.some(e=>e.type===R)}}function Ze(t){return t.filter(e=>e.type===_&&e.config?.restrict_to_account_members!==!0)}function Qe(t){let e=[...t.some(n=>n.type===_)?["a Cloudflare account"]:[],...t.filter(n=>n.type!==_&&n.type!==R).map(n=>n.name??n.type),...t.some(n=>n.type===R)?["a one-time PIN"]:[]];return e.length<=1?e[0]??"no sign-in method":`${e.slice(0,-1).join(", ")} or ${e.at(-1)}`}function et(t){return t.filter(e=>e.type===R||e.type===_&&e.config?.restrict_to_account_members===!0)}function ye(t,e){let n=[...t??[]];for(let s of e)n.includes(s)||n.push(s);return n}function Ae(t,e){let n=ye(t?.allowed_idps,e);return{allowedIdps:n,autoRedirect:n.length===1}}function X(t,e){let n=Ae(t,e),s=t.allowed_idps??[];return s.length===n.allowedIdps.length&&n.allowedIdps.every(i=>s.includes(i))&&(t.auto_redirect_to_identity??!1)===n.autoRedirect}function tt(t){let e=t.trim();if(!/^(\d+(?:\.\d+)?(?:ns|us|µs|ms|s|m|h))+$/.test(e))return null;let n={ns:1e-9,us:1e-6,\u00B5s:1e-6,ms:.001,s:1,m:60,h:3600},s=0;for(let[,i,r]of e.matchAll(/(\d+(?:\.\d+)?)(ns|us|µs|ms|s|m|h)/g))s+=Number(i)*n[r];return s}var _e=["binding","active","disabled"],be=6e4;async function we(t){let[e=[]]=await t.run([{sql:`SELECT app_slug, hostname, manifest FROM apps
4
+ WHERE status IN (${_e.map(n=>`'${n}'`).join(", ")}) AND hostname IS NOT NULL
5
+ ORDER BY hostname`}]);return e.map(n=>({appId:String(n.app_slug),hostname:String(n.hostname),publicPaths:F(n.manifest).map(s=>s.path),mcp:Y(n.manifest)!==null}))}function Pe({publicRoutes:t,mcp:e}){return t&&e?"public routes and /mcp":e?"/mcp":"public routes"}var j=t=>({gatewayHost:t.gatewayHost.toLowerCase(),appBaseDomain:t.appBaseDomain.toLowerCase()});async function Se({cf:t,db:e,install:n,out:s}){let i=j(n),r=await U({db:e,id:q,purpose:"access.sync",out:s,step:"gateway.lease",waitMs:be});try{let a=N(await T(t),i);return a.apps?(await r.check(),await Re({cf:t,db:e,install:n,application:a.apps,gateway:a.gateway})):null}finally{await r.release()}}async function Re({cf:t,db:e,install:n,application:s,gateway:i}){let r=j(n),a=k(r.appBaseDomain,await we(e),{managedOAuth:z(i)}),l=s.destinations??[],{foreign:u}=L(l,r),g=i?.id===s.id?l.filter(C=>(C.uri??"").toLowerCase().replace(/\/+$/,"")===r.gatewayHost):[],c=[...u,...g,...a.destinations],p={dropped:a.dropped,outsideBase:a.outsideBase,foreign:u.length>0?[{application:s.name??s.id,uris:u.map(C=>C.uri??"(private)")}]:[]};return S(l,c)?{application:s,changed:!1,...p}:{application:await W(t,s.id,G(s,{destinations:c})),changed:!0,...p}}function Oe(t,e){let n=e.dropped.filter(r=>r.reason==="not_expressible"),s=e.dropped.filter(r=>r.reason==="too_many"),i=r=>r===1?"A public route stays":`${r} public routes stay`;n.length>0&&t.emit({type:"warning",code:"ACCESS_ROUTE_NOT_EXPRESSIBLE",step:"access.routes",message:`${i(n.length)} behind Access: ${A(n.map(r=>`${r.appId} ${r.path}`))}
6
+ Access path patterns take one * per segment, so these have no equivalent. People signed in to Access still reach them.`,data:{routes:n}}),s.length>0&&t.emit({type:"warning",code:"ACCESS_TOO_MANY_PUBLIC_ROUTES",step:"access.routes",message:`${i(s.length)} behind Access: ${A(s.map(r=>`${r.appId} ${r.path}`))}
7
+ Access lets through at most 25 paths per host (two of them for /mcp where the manifest sets mcp). Merge routes under one prefix, or keep these behind the login.`,data:{routes:s}}),e.outsideBase.length>0&&t.emit({type:"warning",code:"ACCESS_APP_OUTSIDE_BASE",step:"access.routes",message:`${A(e.outsideBase)} ${e.outsideBase.length===1?"isn't":"aren't"} under the apps' domain, so Access isn't set up for ${e.outsideBase.length===1?"it":"them"}.`,data:{apps:e.outsideBase}});for(let{application:r,uris:a}of e.foreign)t.emit({type:"warning",code:"ACCESS_FOREIGN_DESTINATION",step:"access.routes",message:`The Access application "${r}" also covers ${A(a)}
8
+ ${M(a.length,"That destination").replace(/^1 That destination/,"That destination").replace(/^(\d+) That destinations?/,"Those $1 destinations")} ${a.length===1?"isn't":"aren't"} EveryApp's and ${a.length===1?"stays":"stay"} as ${a.length===1?"it is":"they are"}. access off won't delete this application.`,data:{application:r,uris:a}})}async function pt(t,{appId:e,surface:n,removing:s=!1}){let{cf:i,install:r,out:a}=t,l=`${B} access on`,u=Pe(n),g;try{g=await T(i)}catch(c){let p=c instanceof b&&c.code==="ACCESS_PERMISSION_MISSING";if(p&&!n.publicRoutes&&!n.mcp)return;let m=s?`If the Gateway is behind Access, ${e}'s host stays listed there until it is updated.`:`If the Gateway is behind Access, ${e}'s ${u} need a login there until it is updated.`;a.emit({type:"warning",code:"ACCESS_NOT_CHECKED",step:"app.access",message:p?`This Cloudflare login can't read Cloudflare Access, so ${e} wasn't checked against it
9
+ ${m}`:`Couldn't check Cloudflare Access for ${e}
10
+ ${x(c).split(`
11
+ `)[0]}
12
+ ${m}`,data:{appId:e,rerun:l,rerunNote:p?"with a login that can manage Access, if the Gateway is behind it":"if the Gateway is behind Access"}});return}if(N(g,j(r)).apps)try{let c=await Se(t);if(!c)return;Oe(a,c);let p=s?c.changed?`Cloudflare Access no longer lets ${e}'s ${u} through.`:`Cloudflare Access had nothing of ${e}'s to take back.`:c.changed?`Cloudflare Access lets ${e}'s ${u} through.`:`Cloudflare Access already matched ${e}'s ${u}.`;a.emit({type:"step",step:"app.access",status:c.changed?"ok":"skip",message:p,data:{appId:e,applicationId:c.application.id,changed:c.changed,removed:s}})}catch(c){a.emit({type:"warning",code:"ACCESS_SYNC_FAILED",step:"app.access",message:`Couldn't update Cloudflare Access for ${e}'s ${u}
13
+ ${x(c).split(`
14
+ `)[0]}
15
+ ${s?`${e}'s host stays listed there until it is updated.`:"Until it is updated, they need an Access login."}`,data:{appId:e,rerun:l}})}}export{se as a,Ee as b,$e as c,ve as d,Te as e,ke as f,Le as g,Ne as h,ze as i,je as j,Be as k,T as l,Me as m,G as n,W as o,He as p,Z as q,me as r,k as s,L as t,S as u,N as v,z as w,qe as x,Fe as y,Ye as z,Ge as A,We as B,Ke as C,Je as D,_ as E,R as F,Ve as G,Xe as H,Ze as I,Qe as J,et as K,Ae as L,X as M,tt as N,we as O,j as P,Oe as Q,pt as R};
@@ -1,2 +1,2 @@
1
- import{i as d}from"./chunk-ONLNJXVQ.js";import{e as g,f as c}from"./chunk-H7PDL3X5.js";import{a as m,e as y}from"./chunk-JYKRUS5C.js";import{Wb as a,bc as l,pb as p}from"./chunk-LYNBZ7RV.js";import e from"node:path";var u=".cloudflare/state",A=6e5;async function L(i,t){let r=t.resources?.d1??[];if(r.length===0)return{status:"skipped",reason:"no_d1"};let o=g(r,t.migrations),n=c(t);return await a(e.resolve(i,n))?{status:"found",binding:o,dir:n}:{status:"skipped",reason:"no_migrations_dir"}}async function b({cwd:i,manifest:t,cf:r,onApply:o}){let n=await L(i,t);return n.status==="skipped"?n:(o?.(),{status:"applied",...await R({cwd:i,manifest:t,cf:r,...n})})}async function R({cwd:i,manifest:t,cf:r,binding:o,dir:n}){let s=d(p(t.id),o);return{applied:(await l(r,{plane:"project",cwd:i,local:!0,timeoutMs:A,env:f(i),args:["d1","migrations","apply",s,"--local","--persist-to",u,"--dir",n]},m)).map(M=>M.name),database:s}}async function k({cwd:i,manifest:t,cf:r}){let o=g(t.resources?.d1??[],t.migrations);return(await l(r,{plane:"project",cwd:i,local:!0,env:f(i),args:["d1","migrations","list",d(p(t.id),o),"--local","--persist-to",u,"--dir",c(t)]},y)).map(s=>s.Name)}function f(i){let t=e.join(i,".everyapp","registry");return{CLOUDFLARE_REGISTRY_PATH:t,MINIFLARE_REGISTRY_PATH:t}}async function I(i){let t=await a(e.join(i,".wrangler","state")),r=await a(e.join(i,u));return!t||r?null:`Local data now lives in .cloudflare/state
1
+ import{j as d}from"./chunk-HJGZGZFE.js";import{e as g,f as c}from"./chunk-AMCNAKYU.js";import{a as m,e as y}from"./chunk-RQBSTNL7.js";import{Dc as l,Gb as p,wc as a}from"./chunk-FQ2A7YAP.js";import e from"node:path";var u=".cloudflare/state",A=6e5;async function L(i,t){let r=t.resources?.d1??[];if(r.length===0)return{status:"skipped",reason:"no_d1"};let o=g(r,t.migrations),n=c(t);return await a(e.resolve(i,n))?{status:"found",binding:o,dir:n}:{status:"skipped",reason:"no_migrations_dir"}}async function b({cwd:i,manifest:t,cf:r,onApply:o}){let n=await L(i,t);return n.status==="skipped"?n:(o?.(),{status:"applied",...await R({cwd:i,manifest:t,cf:r,...n})})}async function R({cwd:i,manifest:t,cf:r,binding:o,dir:n}){let s=d(p(t.id),o);return{applied:(await l(r,{plane:"project",cwd:i,local:!0,timeoutMs:A,env:f(i),args:["d1","migrations","apply",s,"--local","--persist-to",u,"--dir",n]},m)).map(M=>M.name),database:s}}async function k({cwd:i,manifest:t,cf:r}){let o=g(t.resources?.d1??[],t.migrations);return(await l(r,{plane:"project",cwd:i,local:!0,env:f(i),args:["d1","migrations","list",d(p(t.id),o),"--local","--persist-to",u,"--dir",c(t)]},y)).map(s=>s.Name)}function f(i){let t=e.join(i,".everyapp","registry");return{CLOUDFLARE_REGISTRY_PATH:t,MINIFLARE_REGISTRY_PATH:t}}async function I(i){let t=await a(e.join(i,".wrangler","state")),r=await a(e.join(i,u));return!t||r?null:`Local data now lives in .cloudflare/state
2
2
  Rows in the old .wrangler/state database weren't copied over.`}export{L as a,b,R as c,k as d,f as e,I as f};
@@ -1,4 +1,4 @@
1
- import{B as Ie,c as ve,d as O,e as ke,f as Ae,g as K,h as Ee,i as Re,j as P,k as Oe,l as W,m as H,n as Me,o as Te,p as Pe,v as _e}from"./chunk-IFCPALVC.js";import{a as S}from"./chunk-4JRIS6S6.js";import{B as de,W as le,X as pe,Y as me,Z as ue,_ as fe,aa as ge,ca as he,da as we,ea as ye,qa as $e,sa as be,y as ce}from"./chunk-RMF4YGD6.js";import{e as ae,m as se,n as re,p as ie}from"./chunk-NFU4YFXB.js";import{a as V,b as oe}from"./chunk-CCWBPAKH.js";import{Bb as R,b as Q,c as f,da as Z,f as z,ga as ee,ka as te,ma as ne,oc as j,pc as G,qb as I,sa as D,wa as B,wc as k}from"./chunk-LYNBZ7RV.js";import{stripVTControlCharacters as Ge}from"node:util";import w from"chalk";function We(e,t,a){let{app:n}=e;if(e.kind==="existing")return[{sql:"UPDATE apps SET name = ?, description = ?, manifest = ?, status = ?, updated_at = ? WHERE id = ?",params:[n.name,n.description,n.manifest,n.status,t,n.id]}];let o=e.grants.map(s=>({sql:`INSERT INTO user_app_access (id, user_id, app_row_id, organization_id, granted_by)
1
+ import{B as Ie,c as ve,d as O,e as ke,f as Ae,g as K,h as Ee,i as Re,j as P,k as Oe,l as W,m as H,n as Me,o as Te,p as Pe,v as _e}from"./chunk-PDPUGYJW.js";import{a as S}from"./chunk-LEEUODYR.js";import{c as $e,e as be}from"./chunk-DCFHBCCW.js";import{$ as ge,A as de,V as le,W as pe,X as me,Y as ue,Z as fe,ba as he,ca as we,da as ye,w as ce}from"./chunk-KOBKGQ27.js";import{e as ae,m as se,n as re,p as ie}from"./chunk-RL72BUT4.js";import{a as V,b as oe}from"./chunk-I7FNTTUY.js";import{Ba as B,Hb as I,Qc as j,Rc as G,Yc as k,b as Q,bc as R,c as f,f as z,ia as Z,la as ee,pa as te,ra as ne,xa as D}from"./chunk-FQ2A7YAP.js";import{stripVTControlCharacters as Ge}from"node:util";import w from"chalk";function We(e,t,a){let{app:n}=e;if(e.kind==="existing")return[{sql:"UPDATE apps SET name = ?, description = ?, manifest = ?, status = ?, updated_at = ? WHERE id = ?",params:[n.name,n.description,n.manifest,n.status,t,n.id]}];let o=e.grants.map(s=>({sql:`INSERT INTO user_app_access (id, user_id, app_row_id, organization_id, granted_by)
2
2
  VALUES (?, ?, ?, ?, NULL) ON CONFLICT DO NOTHING`,params:[s.id,s.userId,s.appRowId,s.organizationId]}));return e.kind==="new"?[{sql:`INSERT INTO apps (id, organization_id, app_slug, name, description, hostname,
3
3
  worker_name, tier, manifest, status, version_id, deployed_at, deployed_by_actor,
4
4
  is_default, created_at, updated_at, scope)
@@ -26,5 +26,5 @@ ${i}'s tools ${o.kind==="builtin"?'answer "not set up"':"stay out of /mcp"} unti
26
26
  `)),display:[w.bold(x[0]),...j(y),...T?["",...h]:[],...d&&!T?["",w.dim(`No tools listed yet: the Gateway lists them on the next request to ${g.url}.`)]:[]].join(`
27
27
  `),data:{id:t,name:s,kind:o.kind,status:m,on:d?.status==="active",...i?{url:i.url,auth:q(i.auth),supported:i.auth.kind!=="oauth",risk:i.risk,rev:i.rev,overrides:i.tools}:{},addedBy:d?.deployedByActor??null,addedAt:d?.deployedAt?new Date(d.deployedAt).toISOString():null,key:r,snapshot:ze(u?.snapshot??null),tools:u?i?u.remoteTools:u.catalogTools.map($=>({...$,source:"registry",on:!0})):[],mcp:g,...r&&d&&(!r.set||r.boundOrigin&&!r.bound)?{next:[{command:`${f} secret set ${r.name}`,note:`${s}'s ${o.kind==="builtin"?"key":"credential"}`}]}:m==="not added"?{next:[{command:`${f} mcp on ${t}`,note:`offer ${s}`}]}:{}}})}async function ut(e,t){let{out:a}=e,n=await E(e),o=await O(n.db,t);o.kind==="remote"&&F(o);let s=_(o),c=o.app&&o.app.status!=="deleted"?o.app:null;if(!c){let i=`${s} isn't on, so it has no tools to list again`;M(a,[`${i}.`,"Nothing changed."],{id:t,name:s,kind:o.kind,refreshed:!1},[]);return}a.emit({type:"step",step:"mcp.refresh",status:"start",message:`Dropping ${s}'s tools snapshot...`});let l=await Re(n.db,c);a.emit({type:"step",step:"mcp.refresh",status:"ok",message:`Dropped ${s}'s tools snapshot`,data:{id:t}});let p=[l?`Dropped ${s}'s tools snapshot (${Fe(l)}).`:`${s} had no tools snapshot to drop.`,c.status==="active"?`The Gateway lists its tools again on the next request to ${n.gatewayUrl}/mcp, or within the hour.`:`It's off: the Gateway lists its tools again once it's on (${f} mcp on ${t}).`];M(a,p,{id:t,name:s,kind:o.kind,refreshed:!0,dropped:ze(l)})}async function ft(e,t,a){let{out:n,flags:o}=e;if(o.on&&o.off)throw new R("MCP_TOOL_CHANGE_INVALID","--on and --off say opposite things; give one",{fix:"drop one of them"});if(!o.risk&&!o.on&&!o.off)throw new R("MCP_TOOL_CHANGE_INVALID",`Nothing to change about ${a}
28
28
  Give --risk read|write|destructive|annotations, --on or --off.`,{rerun:`${f} mcp show ${t}`,rerunNote:"lists its tools with their risks"});let s=await E(e),c=await O(s.db,t);if(c.kind==="builtin")throw new R("MCP_APP_BUILTIN",`${_(c)} is the Gateway's built-in MCP app
29
- Its tools and their risks are the Gateway's own, and can't be changed here. ${f} mcp off ${t} stops serving it.`);let l=F(c);n.emit({type:"step",step:"mcp.tool",status:"start",message:`Changing ${a} on ${t}...`});let p=await Te(s.db,{...c,app:l},a,{...o.risk?{risk:o.risk}:{},...o.on?{enabled:!0}:o.off?{enabled:!1}:{}},e.now?.());n.emit({type:"step",step:"mcp.tool",status:"ok",message:`Changed ${p.serverName} on ${t}`,data:{id:t}}),p.inListing||n.emit({type:"warning",code:"REMOTE_MCP_TOOL_NOT_LISTED",step:"mcp.tool",message:`${a} isn't in ${t}'s last tool listing
29
+ Its tools and their risks are the Gateway's own, and can't be changed here. ${f} mcp off ${t} stops serving it.`);let l=F(c);n.emit({type:"step",step:"mcp.tool",status:"start",message:`Changing ${a} on ${t}...`});let p=await Te(s.db,{...c,app:l},a,{...o.risk?{risk:o.risk}:{},...o.on?{enabled:!0}:o.off?{enabled:!1}:{}},e.now?.(),s.deployer);n.emit({type:"step",step:"mcp.tool",status:"ok",message:`Changed ${p.serverName} on ${t}`,data:{id:t}}),p.inListing||n.emit({type:"warning",code:"REMOTE_MCP_TOOL_NOT_LISTED",step:"mcp.tool",message:`${a} isn't in ${t}'s last tool listing
30
30
  The override is kept under the server's name ${p.serverName} and applies once the server lists a tool by that name.`,data:{rerun:`${f} mcp show ${t}`,rerunNote:"lists its tools by both names"}});let i=p.after??{},d=i.risk?`risk ${i.risk} (your override)`:"risk from the app's default and the server's hints",m=i.enabled===!1?"left out of the catalog":"listed",r=[`${p.serverName}${p.listedName?` (${p.listedName})`:""} on ${t}: ${d}, ${m}.`,`The Gateway lists ${t}'s tools again on first use (revision ${p.rev}).`];M(n,r,{id:t,tool:{serverName:p.serverName,name:p.listedName,inListing:p.inListing},before:p.before,override:p.after,rev:p.rev})}export{zt as a,Bt as b,Vt as c,jt as d,Kt as e,Wt as f,Ht as g,Yt as h,rt as i,it as j,ct as k,dt as l,lt as m,mt as n,ut as o,ft as p};
@@ -0,0 +1 @@
1
+ import{B as S,Bb as X,Cb as Y,Db as M,Ib as v,Kb as T,Lb as q,Mb as Q,Nb as Z,Ob as k,Pb as ee,Wb as b,ha as u,ia as L,ja as B,ka as E,ma as N,oa as w,pa as K,qa as V,ra as G,sa as F,ta as H,ua as J,va as W,wa as j,ya as O}from"./chunk-FQ2A7YAP.js";function de(e){if(!e)return null;try{let t=JSON.parse(e);return Array.isArray(t)&&t.every(r=>typeof r=="string")?t:null}catch{return null}}function le(e){return JSON.stringify([...new Set(e)].sort())}var D=class extends Error{constructor(r,n){super(`App "${r}" can't be routed: ${n}`);this.appId=r;this.name="UnroutableAppError"}};var U=class{byHostname=new Map;byAppId=new Map;byOrgApp=new Map;constructor(t=[]){for(let r of t)this.add(r)}add(t){this.byHostname.set(t.hostname.toLowerCase(),t),this.byAppId.set(t.appId,t),this.byOrgApp.set(te(t.organizationId,t.appId),t)}async findByHostname(t){return this.byHostname.get(t.toLowerCase())??null}async hasAnyActiveApp(){return Array.from(this.byAppId.values()).some(t=>t.status==="active")}async findByAppId(t){return this.byAppId.get(t)??null}async findByOrgApp(t,r){return this.byOrgApp.get(te(t,r))??null}};function te(e,t){return JSON.stringify([e,t])}var p="deleted",o=class extends Error{status;code;constructor({status:t,code:r,message:n}){super(n),this.name="RegistrationError",this.status=t,this.code=r}},ce=/^(?=.{1,63}$)[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/,ge=50;function ne(e){return e.toLowerCase().replace(/[^a-z0-9]/g,"").slice(0,b)||"org"}function ue(e){let t=ne(e);return Array.from({length:ge},(r,n)=>{let s=n===0?"":String(n+1);return`${t.slice(0,b-s.length)}${s}`})}function re(e,t){let r=e.trim().toLowerCase();if(!ce.test(r))throw new o({status:400,code:"INVALID_APP_HOSTNAME",message:`${t} must form a valid DNS label of at most 63 characters; received "${r}".`});return r}function se(e){let{appSlug:t,orgKey:r}=e;if(X(t))throw new o({status:400,code:"RESERVED_APP_ID",message:`The app id "${t}" is reserved for the platform.`});if(t.includes(T))throw new o({status:400,code:"INVALID_APP_ID",message:`App id "${t}" can't contain "${T}": it separates an app's Worker name from its resources' names. Choose another id.`});let n=e.existingApp?.workerName??q({appId:t,orgKey:r}),s=e.appBaseDomain.trim().toLowerCase().replace(/\.$/,""),i=e.existingApp?.hostname??`${e.isInstallOrganization?re(t,"The app id"):re(`${t}-${r}`,"The app id and organization key")}.${s}`;if(!Q({appId:t,orgKey:r,workerName:n}))throw new o({status:400,code:"INVALID_WORKER_NAME",message:n.length>v?`App id "${t}" is too long: its Worker name "${n}" would exceed ${v} characters.`:`App id "${t}" can't be registered: its Worker would be "${n}", which is reserved for the gateway or isn't the app's own.`});return{workerName:n,hostname:i}}function oe(e,t){let r;try{r=M(e)}catch(n){throw new o({status:400,code:"INVALID_MANIFEST",message:n instanceof Y?n.message:"Invalid manifest"})}if(r.id!==t)throw new o({status:400,code:"INVALID_MANIFEST",message:`manifest.id "${r.id}" does not match appId "${t}"`});return r}function C(e){if(!e)return null;try{return M(JSON.parse(e))}catch{return null}}function ie(e,t){let r=(n,s=Z)=>Object.fromEntries((n??[]).map(i=>[i,s(e,i)]));return{d1:r(t?.resources?.d1),kv:r(t?.resources?.kv),r2:r(t?.resources?.r2,ee)}}function me(e){return e.workerName?ie(e.workerName,C(e.manifest)):{d1:{},kv:{},r2:{}}}var Ae={d1:"D1 database",kv:"KV namespace",r2:"R2 bucket"},fe=/^[a-z0-9][a-z0-9-]*[a-z0-9]$/;function Re(e){for(let[t,r]of Object.entries(e)){let n=new Map;for(let[s,i]of Object.entries(r)){let a=n.get(i);if(a!==void 0)throw new o({status:400,code:"RESOURCE_NAME_CONFLICT",message:`Bindings ${a} and ${s} would share the ${Ae[t]} "${i}". Rename one of them in everyapp.config.ts.`});if(t==="r2"&&(i.length>k||!fe.test(i)))throw new o({status:400,code:"INVALID_MANIFEST",message:`resources.r2: ${s} would be the R2 bucket "${i}", which Cloudflare refuses (at most ${k} lowercase letters, digits and hyphens, starting and ending with a letter or digit). Rename the binding in everyapp.config.ts.`});n.set(i,s)}}}function Ie(e){return(e??"").split(",").some(t=>["owner","admin"].includes(t.trim()))}function ye(e,t,r,n){if(t==="shared")return{isDefault:!1,grants:[]};let s=r.access==="everyone";return{isDefault:s,grants:e.members.filter(i=>s||i.id===e.deployerUserId||Ie(i.role)).map(i=>({id:crypto.randomUUID(),organizationId:e.organizationId,userId:i.id,appRowId:n,grantedBy:null}))}}function we(e){let{existingApp:t}=e,r=e.scope??(t?.scope==="shared"?"shared":"org");if(t&&(t.organizationId!==e.organizationId||t.appSlug!==e.appSlug))throw new Error("existingApp is another organization's or app's row.");if(r==="shared"&&!e.isInstallOrganization)throw new o({status:403,code:"SHARED_APP_NOT_PLATFORM",message:`Only the platform organization registers shared apps; "${e.appSlug}" can't be shared from another organization.`});if(t&&t.scope!==r)throw new o({status:409,code:"APP_SCOPE_MISMATCH",message:t.scope==="shared"?`App "${e.appSlug}" is a shared app, not this organization's own. Deploy it without asking for another scope, or give the organization's own app an id of its own.`:`App "${e.appSlug}" is this organization's own app, not a shared one. Shared apps need an app id of their own.`});let n=e.tier??"service_binding";if(n==="dispatch"&&r==="shared")throw new o({status:400,code:"APP_TIER_MISMATCH",message:`A shared app is reached over a service binding; "${e.appSlug}" can't be deployed through the hosted deploy API.`});if(t&&t.tier!==n)throw new o({status:409,code:"APP_TIER_MISMATCH",message:t.tier===u?`"${e.appSlug}" is the Gateway's MCP app of that name${t.status===p?" (turned off)":""}; give this app an id of its own.`:t.tier==="dispatch"?`App "${e.appSlug}" is deployed through the hosted deploy API; deploy it the same way, or give this app an id of its own.`:`App "${e.appSlug}" is reached over a service binding, not deployed through the hosted deploy API; give the third-party app an id of its own.`});let s=se(e),i=oe(e.manifest,e.appSlug),{workerName:a,hostname:d}=s;for(let[A,_,pe]of[[e.hostnameOwner,"hostname",d],[e.workerNameOwner,"workerName",a]])if(A&&A[_]!==pe)throw new Error(`The ${_} owner passed holds another ${_}.`);let m=A=>A!==null&&(A.organizationId!==e.organizationId||A.appSlug!==e.appSlug);if(m(e.hostnameOwner))throw new o({status:409,code:"HOSTNAME_TAKEN",message:`The hostname "${d}" is already registered to another app on this gateway.`});if(m(e.workerNameOwner))throw new o({status:409,code:"WORKER_NAME_TAKEN",message:`The worker name "${a}" is already registered to another app on this gateway. Choose a different app id.`});let f=ie(a,i);Re(f);let y={organizationId:e.organizationId,name:e.name,description:e.description,hostname:d,workerName:a},l={previousManifest:C(t?.manifest??null),versionId:t?.versionId??null,resources:f};if(t&&t.status!==p)return{kind:"existing",app:{...t,...y},grants:[],...l};let R=t?.id??crypto.randomUUID(),{isDefault:c,grants:h}=ye(e,r,i,R),g={...y,manifest:JSON.stringify(i),status:"pending",isDefault:c};return t?{kind:"revived",app:{...t,...g},grants:h,...l}:{kind:"new",app:{id:R,appSlug:e.appSlug,tier:n,scope:r,versionId:null,deployedAt:null,deployedByActor:null,...g},grants:h,...l}}function he(e){if(e.status===p)throw new o({status:404,code:"APP_NOT_FOUND",message:`No app "${e.appSlug}" is registered for this organization.`});if(!e.workerName||!e.hostname&&e.tier!=="dispatch")throw new o({status:409,code:"APP_NOT_REGISTERED",message:`App "${e.appSlug}" has no Worker or hostname yet; deploy it again.`})}function Ee(e,{versionId:t,manifest:r,actor:n,now:s=Date.now()}){return he(e),{manifest:JSON.stringify(oe(r,e.appSlug)),versionId:t,deployedAt:s,deployedByActor:n,status:e.status==="pending"?"binding":e.status}}function P(e){return e.status===p?null:{status:p,isDefault:!1,emailSenders:null,emailInbound:null,secretNames:null}}function Me(e){return(e??"").split(",").some(t=>["owner","admin"].includes(t.trim()))}function I(e,t){throw new o({status:400,code:e,message:t})}function Pe(e,t){let r=t&&typeof t=="object"&&!Array.isArray(t)?t:{kind:t??"none"},n=r.kind,s=(n==="bearer"||n==="header"||n==="basic")&&r.secret===void 0?{...r,secret:K(e)}:r,i=H(s);return i.ok||I("REMOTE_MCP_INVALID",i.problem),i.auth}function $(e){if(e.tier!==u||!e.manifest)return!1;try{return j(JSON.parse(e.manifest))}catch{return!1}}function x(e){return e.tier===u}function z(e){if(e.tier!==u||!e.manifest)return null;try{return W(JSON.parse(e.manifest))}catch{return null}}function _e(e,t,r){if(r&&(r.organizationId!==e||r.appSlug!==t))throw new Error("existingApp is another organization's or app's row.")}function Se(e,t){if($(t))return;let r=t.tier===u?"the Gateway's built-in MCP app":`an app deployed to this Gateway${t.status===p?" (deleted, its names still its organization's)":""}`;throw new o({status:409,code:"APP_TIER_MISMATCH",message:`"${e}" is ${r}; a remote MCP server can't take its id.`})}function Ne(e){let t=e.url.trim(),r=F(t,e.env);r&&I("REMOTE_MCP_URL_REFUSED",r);let n=(e.id??"").trim()||G(t);n||I("REMOTE_MCP_INVALID","no app id could be read from the URL's host; give one with --name");let s=V(n);s&&I("REMOTE_MCP_INVALID",s);let i=e.sharedApp?.(n);if(i&&i.status!==p)throw new o({status:409,code:"APP_TIER_MISMATCH",message:`"${n}" is a shared app every organization sees; a remote MCP server can't take its id.`});let a=e.existingApp(n);_e(e.organizationId,n,a);let d=(e.risk??"annotations").trim();w.includes(d)||I("REMOTE_MCP_INVALID",`risk must be one of ${w.join(", ")}`);let m=Pe(n,e.auth);if("secret"in m&&e.secretUsedAt){let g=e.secretUsedAt(m.secret),A=new URL(t).origin;if(g&&g!==A)throw new o({status:409,code:"REMOTE_MCP_SECRET_TAKEN",message:`${m.secret} is the credential of an MCP app at ${g}; a server at ${A} takes another name (--secret <NAME>_MCP_TOKEN).`})}let f=a?z(a)?.rev??0:0,y={url:t,auth:m,risk:d,tools:{},rev:f+1},l=O({id:n,name:e.name,description:e.description,remote:y});if(a&&((E(n)||!$(a))&&Se(n,a),a.status!==p))throw new o({status:409,code:"REMOTE_MCP_EXISTS",message:`"${n}" is an MCP app on this Gateway already (${a.status==="active"?"on":"off"}); remove it first, or change it in place.`});let R=a?.id??crypto.randomUUID(),c={id:R,organizationId:e.organizationId,appSlug:n,name:l.name,description:l.description,hostname:null,workerName:null,tier:u,scope:"org",manifest:JSON.stringify(l),status:"active",versionId:null,deployedAt:e.now,deployedByActor:e.actor,isDefault:!1},h=e.members.filter(g=>g.id===e.actorUserId||Me(g.role)).map(g=>({id:crypto.randomUUID(),organizationId:e.organizationId,userId:g.id,appRowId:R,grantedBy:null}));return{kind:a?"revived":"new",id:n,app:c,grants:h,remote:y}}function Oe(e,t){let r=z(e);if(!r)throw new o({status:404,code:"APP_NOT_FOUND",message:`"${e.appSlug}" is not a remote MCP app.`});if(e.status===p)throw new o({status:404,code:"APP_NOT_FOUND",message:`"${e.appSlug}" was removed.`});let n=r.risk;t.risk!==void 0&&(w.includes(t.risk)||I("REMOTE_MCP_INVALID",`risk must be one of ${w.join(", ")}`),n=t.risk);let s={...r.tools};if(t.tools&&(s={...t.tools}),t.tool){let{name:l,override:R}=t.tool;if(l.trim()||I("REMOTE_MCP_INVALID","name the tool"),R===null)delete s[l];else{let c={...s[l],...R};c.risk===void 0&&delete c.risk,(c.enabled===void 0||c.enabled===!0)&&delete c.enabled,Object.keys(c).length===0?delete s[l]:s[l]=c}}let i=S({risk:n,tools:s})!==S({risk:r.risk,tools:r.tools}),a={...r,risk:n,tools:s,rev:i?r.rev+1:r.rev},d=J(a);d.ok||I("REMOTE_MCP_INVALID",d.problem);let m=JSON.parse(e.manifest??"{}"),f=O({id:e.appSlug,name:t.name===void 0?e.name:t.name,description:t.description===void 0?e.description:t.description,remote:a}),y={...m,...f};return{manifest:JSON.stringify(y),name:f.name,description:f.description,remote:a}}function ve(e,t){if(!x(e))throw new o({status:409,code:"APP_TIER_MISMATCH",message:`"${e.appSlug}" is an app deployed to this Gateway, not an MCP app.`});if(e.status===p)throw new o({status:404,code:"APP_NOT_FOUND",message:`"${e.appSlug}" was removed; add it again.`});return e.status===t?null:{status:t}}function Te(e){return!e||!x(e)?null:P(e)}function ke(e){return(e??"").split(",").some(t=>["owner","admin"].includes(t.trim()))}function ae(e){if(E(e))return e;throw new o({status:400,code:"PROVIDER_APP_UNKNOWN",message:`"${e}" is not an MCP app. The Gateway offers: ${B.join(", ")}.`})}function be(e,t){if(t.tier!==u)throw new o({status:409,code:"APP_TIER_MISMATCH",message:`"${e}" is an app deployed to this Gateway${t.status===p?" (deleted, its names still its organization's)":""}, not the MCP app; the MCP app can't take its id.`})}function De(e){let t=ae(e.id),{existingApp:r}=e;if(r&&(r.organizationId!==e.organizationId||r.appSlug!==t))throw new Error("existingApp is another organization's or app's row.");let n=L[t];if(r&&be(t,r),r&&r.status!==p)return{kind:"existing",app:{...r,name:n.name,description:n.description,manifest:JSON.stringify(N(t)),status:"active"},grants:[]};let s=r?.id??crypto.randomUUID(),i={id:s,organizationId:e.organizationId,appSlug:t,name:n.name,description:n.description,hostname:null,workerName:null,tier:u,scope:"org",manifest:JSON.stringify(N(t)),status:"active",versionId:null,deployedAt:e.now,deployedByActor:e.actor,isDefault:!1},a=e.members.filter(d=>d.id===e.actorUserId||ke(d.role)).map(d=>({id:crypto.randomUUID(),organizationId:e.organizationId,userId:d.id,appRowId:s,grantedBy:null}));return{kind:r?"revived":"new",app:i,grants:a}}export{de as a,le as b,D as c,U as d,p as e,o as f,ue as g,se as h,me as i,we as j,Ee as k,P as l,ae as m,De as n,$ as o,z as p,Ne as q,Oe as r,ve as s,Te as t};
@@ -0,0 +1 @@
1
+ import{z as t}from"zod";var h=t.array(t.looseObject({name:t.string(),status:t.string()})),b=t.looseObject({authenticated:t.boolean(),authSource:t.string().nullish(),tokenValid:t.boolean().nullish(),email:t.string().nullish(),accounts:t.array(t.looseObject({id:t.string(),name:t.string().nullish()})).nullish()}),n=t.looseObject({uuid:t.string(),name:t.string()}),m=t.array(n),d=t.array(t.looseObject({Name:t.string()})),r=t.looseObject({duration:t.number().nullish(),changes:t.number().nullish()}).nullish(),x=t.array(t.looseObject({results:t.array(t.record(t.string(),t.unknown())).nullish(),success:t.boolean().nullish(),meta:r})),f=t.looseObject({bookmark:t.string()}),j=t.looseObject({previous_bookmark:t.string().nullish()}),o=t.looseObject({id:t.string(),title:t.string()}),k=t.array(o),s=t.looseObject({id:t.string().nullish(),created_on:t.string().nullish(),versions:t.array(t.looseObject({version_id:t.string(),percentage:t.number()}))}),S=t.union([t.looseObject({deployments:t.array(s)}),t.array(s)]).transform(e=>Array.isArray(e)?e:e.deployments),L=t.array(t.looseObject({id:t.string().nullish(),name:t.string(),references:t.looseObject({domains:t.array(t.looseObject({id:t.string().nullish(),hostname:t.string(),zone_id:t.string().nullish(),zone_name:t.string().nullish()})).nullish()}).nullish()})),z=t.looseObject({buckets:t.array(t.looseObject({name:t.string()})).nullish()}).transform(e=>e.buckets??[]),_=t.union([t.looseObject({result:t.array(t.looseObject({name:t.string()}))}),t.array(t.looseObject({name:t.string()}))]).transform(e=>Array.isArray(e)?e:e.result),D=t.array(t.looseObject({id:t.string(),name:t.string(),status:t.string().nullish()})),w=t.array(t.looseObject({id:t.string(),name:t.string(),type:t.string(),content:t.string().nullish()})),C=t.array(t.looseObject({id:t.string(),type:t.string().nullish(),hosts:t.array(t.string()).nullish(),status:t.string().nullish()})),i=t.looseObject({name:t.string(),script_name:t.string().nullish(),class_name:t.string().nullish(),instances:t.record(t.string(),t.number()).nullish()}),W=t.array(i),A=t.array(t.looseObject({results:t.looseObject({columns:t.array(t.string()).nullish(),rows:t.array(t.array(t.unknown())).nullish()}).nullish(),meta:r})),u=t.looseObject({id:t.string(),name:t.string(),origin:t.looseObject({host:t.string().nullish(),port:t.number().nullish(),database:t.string().nullish(),user:t.string().nullish(),scheme:t.string().nullish()}).nullish(),caching:t.looseObject({disabled:t.boolean().nullish()}).nullish()}),Q=t.array(u),l=t.looseObject({queue_id:t.string(),queue_name:t.string(),consumers:t.array(t.looseObject({consumer_id:t.string().nullish(),script:t.string().nullish(),type:t.string().nullish()})).nullish()}),v=t.array(l),a=t.looseObject({consumer_id:t.string(),script:t.string().nullish(),type:t.string().nullish(),dead_letter_queue:t.string().nullish(),settings:t.record(t.string(),t.unknown()).nullish()}),V=t.array(a),c=t.looseObject({name:t.string(),config:t.looseObject({dimensions:t.number().nullish(),metric:t.string().nullish(),preset:t.string().nullish()}).nullish(),created_on:t.string().nullish()}),G=t.array(c),p=t.looseObject({id:t.string(),collect_logs:t.boolean().nullish(),cache_ttl:t.number().nullish(),authentication:t.boolean().nullish()}),H=t.array(p),g=t.looseObject({id:t.string(),name:t.string()}),I=t.array(g),O=t.looseObject({id:t.string(),name:t.string(),store_id:t.string().nullish(),status:t.string().nullish(),scopes:t.array(t.string()).nullish()}),R=t.array(O);export{h as a,b,n as c,m as d,d as e,x as f,f as g,j as h,o as i,k as j,S as k,L as l,z as m,_ as n,D as o,w as p,C as q,i as r,W as s,A as t,u,Q as v,l as w,v as x,c as y,G as z,p as A,H as B,I as C,R as D};
@@ -1,4 +1,4 @@
1
- import{a as ue,d as fe,f as we,h as G,j as ge,k as he,p as ve,q as be}from"./chunk-6OGVO7QK.js";import{a as ke,c as De,d as M}from"./chunk-N5GQLGEC.js";import{b as ye,c as T}from"./chunk-W3JCQHHU.js";import{b as C,c as P,e as ie,f as le}from"./chunk-ZFCUH5PK.js";import{b as ce}from"./chunk-23HJ5I2A.js";import{a as pe,c as de,e as me}from"./chunk-6PGUCTJ6.js";import{h as Q}from"./chunk-HOUHG236.js";import{V as se,d as ee,f as te,g as ae,h as re,i as oe,k as ne,l as _}from"./chunk-RMF4YGD6.js";import{a as X}from"./chunk-T2GD7RHS.js";import{Bb as h,Eb as F,Fb as V,Gb as K,Hb as Y,Qb as Z,Xb as A,Zb as q,_b as J,c as R,d as S,f as O,qb as D,vb as j}from"./chunk-LYNBZ7RV.js";import{execFile as x}from"node:child_process";import y from"node:fs/promises";import k from"node:path";import{promisify as L}from"node:util";var N=["apps/every-app-gateway","packages/sdk","packages/perimeter","packages/toolbus","pnpm-workspace.yaml","pnpm-lock.yaml"],_e=3;function gt({out:e,verbose:t}){let a=ce();return{describe:()=>Me(a),open:()=>Le({root:a,out:e,verbose:t})}}function Ge(e){return k.join(e,"node_modules",".cache","everyapp")}async function W(e){let t;try{({stdout:t}=await L(x)("git",["ls-files","-z","--cached","--others","--exclude-standard","--",...N],{cwd:e,maxBuffer:64*1024*1024}))}catch{return null}let a=[...new Set(t.split("\0").filter(Boolean))];return a.length>0?we(e,a):null}async function Re(e){try{let{stdout:t}=await L(x)("git",["log","-1","--format=%ct","--",...N],{cwd:e}),a=Number.parseInt(t.trim(),10);return Number.isFinite(a)?a*1e3:null}catch{return null}}async function Te(e,t){let a=r=>L(x)("git",r,{cwd:e}),o=()=>a(["diff","--quiet",`gateway-v${t}`,"HEAD","--",...N]).then(()=>!1,()=>!0);try{let[r,l]=await Promise.all([a(["rev-parse","--short","HEAD"]),a(["status","--porcelain","--",...N])]),n=l.stdout.trim()!=="";return!n&&!await o()?null:{hash:r.stdout.trim(),uncommittedChanges:n}}catch{return null}}async function Me(e){let t=k.join(e,"apps","every-app-gateway"),a=async c=>JSON.parse(await y.readFile(k.join(t,c),"utf8")),[o,r,l,n]=await Promise.all([W(e),Re(e),a("drizzle/meta/_journal.json"),a("package.json")]),s=String(n.version??"unknown"),i=await Te(e,s);return{treeSha256:o,origin:{kind:"checkout"},...i?{commit:i}:{},version:s,order:{schema:ge(l.entries??[]),committedAt:r??Date.now()}}}async function We({root:e,out:t,build:a,keep:o=_e}){let[r,l]=await Promise.all([W(e),Re(e)]),n=Ge(e),s=r?k.join(n,`${r}.tar.gz`):null,i={origin:{kind:"checkout"},treeSha256:r,committedAt:l};if(s&&await A(s))try{let m=await G(s,i),d=new Date;return await y.utimes(s,d,d),t.emit({type:"step",step:"gateway.release",status:"ok",message:`Using the Gateway ${m.manifest.version} built from this checkout before (${r.slice(0,12)}).`,data:{cached:!0,treeSha256:r,release:m.manifest.version}}),m}catch{await y.rm(s,{force:!0})}let c=await a();s&&await W(e)===r&&await xe(c,s,o);let p=await G(c,{origin:{kind:"checkout"},treeSha256:s&&await A(s)?r:null,committedAt:l});return t.emit({type:"step",step:"gateway.release",status:"ok",message:`Built the Gateway ${p.manifest.version} from this checkout.`,data:{cached:!1,treeSha256:p.source.treeSha256,release:p.manifest.version}}),p}async function xe(e,t,a){let o=k.dirname(t);await y.mkdir(o,{recursive:!0});let r=`${t}.${process.pid}.partial`;await y.copyFile(e,r),await y.rename(r,t);let l=await Promise.all((await y.readdir(o)).filter(n=>n.endsWith(".tar.gz")).map(async n=>({file:k.join(o,n),usedAt:(await y.stat(k.join(o,n))).mtimeMs})));for(let{file:n}of l.sort((s,i)=>i.usedAt-s.usedAt).slice(a))n!==t&&await y.rm(n,{force:!0})}function Le({root:e,out:t,verbose:a}){return We({root:e,out:t,build:()=>ze(e,t,a??!1)})}async function ze(e,t,a,o=process.env){let r=k.join(e,"apps","every-app-gateway");t.emit({type:"step",step:"gateway.release",status:"start",message:"Building the Gateway from this checkout (usually 1\u20132m)",data:{dir:r}});let l=(n,s)=>J("pnpm",n,{cwd:s,env:{...o,NODE_OPTIONS:Z(o.NODE_OPTIONS)},echo:a,what:"Building the Gateway",code:"GATEWAY_BUILD_FAILED",fix:"fix the build error above, then run this again",logName:"gateway-build"});return await l(["--filter","@every-app/sdk","build"],e),await l(["run","build:release"],r),k.join(r,ue)}var Be=`SELECT apps.app_slug, apps.worker_name, apps.hostname, apps.status,
1
+ import{a as ue,d as fe,f as we,h as G,j as ge,k as he,p as ve,q as be}from"./chunk-BCTEWNN4.js";import{a as ke,c as De,d as M}from"./chunk-YAZHTVUV.js";import{b as ye,c as T}from"./chunk-BK4NK34C.js";import{a as ie,b as le}from"./chunk-ORGV2NNT.js";import{b as C,c as P}from"./chunk-KVCL64LI.js";import{b as ce}from"./chunk-ASCNE7GS.js";import{a as pe,c as de,e as me}from"./chunk-LI3YLKLC.js";import{h as Q}from"./chunk-EQLY5I46.js";import{U as se,d as ee,f as te,g as ae,h as re,i as oe,k as ne,l as _}from"./chunk-KOBKGQ27.js";import{a as X}from"./chunk-TIYSZWP5.js";import{Ac as J,Hb as D,Mb as j,bc as h,c as R,d as S,ec as F,f as O,fc as V,gc as K,hc as Y,qc as Z,xc as A,zc as q}from"./chunk-FQ2A7YAP.js";import{execFile as x}from"node:child_process";import y from"node:fs/promises";import k from"node:path";import{promisify as L}from"node:util";var N=["apps/every-app-gateway","packages/sdk","packages/perimeter","packages/toolbus","pnpm-workspace.yaml","pnpm-lock.yaml"],_e=3;function gt({out:e,verbose:t}){let a=ce();return{describe:()=>Me(a),open:()=>Le({root:a,out:e,verbose:t})}}function Ge(e){return k.join(e,"node_modules",".cache","everyapp")}async function W(e){let t;try{({stdout:t}=await L(x)("git",["ls-files","-z","--cached","--others","--exclude-standard","--",...N],{cwd:e,maxBuffer:64*1024*1024}))}catch{return null}let a=[...new Set(t.split("\0").filter(Boolean))];return a.length>0?we(e,a):null}async function Re(e){try{let{stdout:t}=await L(x)("git",["log","-1","--format=%ct","--",...N],{cwd:e}),a=Number.parseInt(t.trim(),10);return Number.isFinite(a)?a*1e3:null}catch{return null}}async function Te(e,t){let a=r=>L(x)("git",r,{cwd:e}),o=()=>a(["diff","--quiet",`gateway-v${t}`,"HEAD","--",...N]).then(()=>!1,()=>!0);try{let[r,l]=await Promise.all([a(["rev-parse","--short","HEAD"]),a(["status","--porcelain","--",...N])]),n=l.stdout.trim()!=="";return!n&&!await o()?null:{hash:r.stdout.trim(),uncommittedChanges:n}}catch{return null}}async function Me(e){let t=k.join(e,"apps","every-app-gateway"),a=async c=>JSON.parse(await y.readFile(k.join(t,c),"utf8")),[o,r,l,n]=await Promise.all([W(e),Re(e),a("drizzle/meta/_journal.json"),a("package.json")]),s=String(n.version??"unknown"),i=await Te(e,s);return{treeSha256:o,origin:{kind:"checkout"},...i?{commit:i}:{},version:s,order:{schema:ge(l.entries??[]),committedAt:r??Date.now()}}}async function We({root:e,out:t,build:a,keep:o=_e}){let[r,l]=await Promise.all([W(e),Re(e)]),n=Ge(e),s=r?k.join(n,`${r}.tar.gz`):null,i={origin:{kind:"checkout"},treeSha256:r,committedAt:l};if(s&&await A(s))try{let m=await G(s,i),d=new Date;return await y.utimes(s,d,d),t.emit({type:"step",step:"gateway.release",status:"ok",message:`Using the Gateway ${m.manifest.version} built from this checkout before (${r.slice(0,12)}).`,data:{cached:!0,treeSha256:r,release:m.manifest.version}}),m}catch{await y.rm(s,{force:!0})}let c=await a();s&&await W(e)===r&&await xe(c,s,o);let p=await G(c,{origin:{kind:"checkout"},treeSha256:s&&await A(s)?r:null,committedAt:l});return t.emit({type:"step",step:"gateway.release",status:"ok",message:`Built the Gateway ${p.manifest.version} from this checkout.`,data:{cached:!1,treeSha256:p.source.treeSha256,release:p.manifest.version}}),p}async function xe(e,t,a){let o=k.dirname(t);await y.mkdir(o,{recursive:!0});let r=`${t}.${process.pid}.partial`;await y.copyFile(e,r),await y.rename(r,t);let l=await Promise.all((await y.readdir(o)).filter(n=>n.endsWith(".tar.gz")).map(async n=>({file:k.join(o,n),usedAt:(await y.stat(k.join(o,n))).mtimeMs})));for(let{file:n}of l.sort((s,i)=>i.usedAt-s.usedAt).slice(a))n!==t&&await y.rm(n,{force:!0})}function Le({root:e,out:t,verbose:a}){return We({root:e,out:t,build:()=>ze(e,t,a??!1)})}async function ze(e,t,a,o=process.env){let r=k.join(e,"apps","every-app-gateway");t.emit({type:"step",step:"gateway.release",status:"start",message:"Building the Gateway from this checkout (usually 1\u20132m)",data:{dir:r}});let l=(n,s)=>J("pnpm",n,{cwd:s,env:{...o,NODE_OPTIONS:Z(o.NODE_OPTIONS)},echo:a,what:"Building the Gateway",code:"GATEWAY_BUILD_FAILED",fix:"fix the build error above, then run this again",logName:"gateway-build"});return await l(["--filter","@every-app/sdk","build"],e),await l(["run","build:release"],r),k.join(r,ue)}var Be=`SELECT apps.app_slug, apps.worker_name, apps.hostname, apps.status,
2
2
  organization_keys.org_key
3
3
  FROM apps LEFT JOIN organization_keys
4
4
  ON organization_keys.organization_id = apps.organization_id
@@ -1 +1 @@
1
- import{f as i}from"./chunk-CZXHKPRZ.js";async function o(a,e){let t=await i(a);t&&e.emit({type:"warning",code:"LEGACY_LOCAL_STATE",message:t})}function p(a,e,t){a.emit({type:"step",step:e,status:"ok",message:t.applied.length>0?`Applied ${t.applied.join(", ")}.`:"The local database is up to date.",data:{database:t.database,applied:t.applied}})}export{o as a,p as b};
1
+ import{f as i}from"./chunk-R2DF3ENZ.js";async function o(a,e){let t=await i(a);t&&e.emit({type:"warning",code:"LEGACY_LOCAL_STATE",message:t})}function p(a,e,t){a.emit({type:"step",step:e,status:"ok",message:t.applied.length>0?`Applied ${t.applied.join(", ")}.`:"The local database is up to date.",data:{database:t.database,applied:t.applied}})}export{o as a,p as b};