everyapp 0.3.0-rc.2 → 0.3.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/access-YWM4BSBD.js +1 -0
- package/dist/activity-RTCAUMQS.js +14 -0
- package/dist/ai-UOYQFTAX.js +5 -0
- package/dist/apps-PEOBCDNU.js +14 -0
- package/dist/chunk-26KS6TD6.js +1 -0
- package/dist/chunk-3EADVHFN.js +15 -0
- package/dist/chunk-4LKLQOM7.js +7 -0
- package/dist/{chunk-PNLU5U3P.js → chunk-5IC3ZN52.js} +1 -1
- package/dist/{chunk-H7PDL3X5.js → chunk-AMCNAKYU.js} +1 -1
- package/dist/{chunk-23HJ5I2A.js → chunk-ASCNE7GS.js} +1 -1
- package/dist/{chunk-6OGVO7QK.js → chunk-BCTEWNN4.js} +1 -1
- package/dist/{chunk-W3JCQHHU.js → chunk-BK4NK34C.js} +1 -1
- package/dist/chunk-BWNZ6F4F.js +2 -0
- package/dist/chunk-DCFHBCCW.js +9 -0
- package/dist/{chunk-2Y5Q6A5K.js → chunk-DWTJ4OLZ.js} +1 -1
- package/dist/chunk-EP3IQ354.js +20 -0
- package/dist/{chunk-OP4DYXYI.js → chunk-EP4HRYXP.js} +1 -1
- package/dist/{chunk-HOUHG236.js → chunk-EQLY5I46.js} +1 -1
- package/dist/{chunk-YHJZMJYZ.js → chunk-F5XK23HV.js} +1 -1
- package/dist/{chunk-5PTNYZK6.js → chunk-FB2OC32C.js} +3 -3
- package/dist/chunk-FQ2A7YAP.js +57 -0
- package/dist/{chunk-OM2HDWVP.js → chunk-GAPQSINH.js} +1 -1
- package/dist/chunk-GJK6GAWO.js +1 -0
- package/dist/chunk-H4EZTXIK.js +1 -0
- package/dist/chunk-HJGZGZFE.js +32 -0
- package/dist/{chunk-CCWBPAKH.js → chunk-I7FNTTUY.js} +3 -3
- package/dist/chunk-KOBKGQ27.js +91 -0
- package/dist/{chunk-PS7S74DG.js → chunk-KQM6ZUX5.js} +1 -1
- package/dist/chunk-KVCL64LI.js +1 -0
- package/dist/{chunk-4JRIS6S6.js → chunk-LEEUODYR.js} +1 -1
- package/dist/{chunk-6PGUCTJ6.js → chunk-LI3YLKLC.js} +1 -1
- package/dist/chunk-MEIWV7FJ.js +20 -0
- package/dist/{configure-F7UZCJUG.js → chunk-MLTNW3AM.js} +2 -2
- package/dist/chunk-NDOEON54.js +4 -0
- package/dist/chunk-NW7SJPSP.js +37 -0
- package/dist/chunk-O64FPLGX.js +1 -0
- package/dist/chunk-ORGV2NNT.js +8 -0
- package/dist/chunk-PDPUGYJW.js +47 -0
- package/dist/chunk-QFTBDXLF.js +146 -0
- package/dist/{chunk-E3EPK27P.js → chunk-QJRZFIYC.js} +2 -2
- package/dist/chunk-QKHLRLK3.js +15 -0
- package/dist/{chunk-CZXHKPRZ.js → chunk-R2DF3ENZ.js} +1 -1
- package/dist/{chunk-IUOBIB5M.js → chunk-R7JOHK7Y.js} +2 -2
- package/dist/chunk-RL72BUT4.js +1 -0
- package/dist/chunk-RQBSTNL7.js +1 -0
- package/dist/{chunk-H6QQMY7B.js → chunk-S2G4G73L.js} +1 -1
- package/dist/{chunk-LXYMDZER.js → chunk-SGRGD7L4.js} +1 -1
- package/dist/{chunk-T2GD7RHS.js → chunk-TIYSZWP5.js} +1 -1
- package/dist/chunk-TUXKBLLJ.js +10 -0
- package/dist/chunk-U4ATZJEU.js +6 -0
- package/dist/chunk-V7BWZOSZ.js +26 -0
- package/dist/{chunk-J35DDCNU.js → chunk-VVKQJSF3.js} +1 -1
- package/dist/chunk-WVHJIYQ3.js +14 -0
- package/dist/{chunk-ZEXVHB22.js → chunk-XBD7PQN5.js} +1 -1
- package/dist/{chunk-N5GQLGEC.js → chunk-YAZHTVUV.js} +1 -1
- package/dist/configure-CAWCTPYY.js +1 -0
- package/dist/{create-2E5HVWYK.js → create-3ZWJQXPK.js} +2 -2
- package/dist/{db-HEQVTDTM.js → db-B7KO37SV.js} +1 -1
- package/dist/delete-CB3EPOU4.js +3 -0
- package/dist/deploy-5O7LV5OX.js +1 -0
- package/dist/dev-4JYCVVOZ.js +86 -0
- package/dist/{email-RLZFUFUN.js → email-SWJQXEUR.js} +1 -1
- package/dist/{events-2V5VRBWP.js → events-GJV2KVIU.js} +13 -13
- package/dist/{groups-HDG5DVFY.js → groups-NNTLSXMK.js} +1 -1
- package/dist/index.js +104 -95
- package/dist/install-UAG3CNYW.js +1 -0
- package/dist/{login-KHJBC64Z.js → login-QEKMLMUB.js} +1 -1
- package/dist/mcp-AFGVOM5D.js +1 -0
- package/dist/provider-622VM7UZ.js +29 -0
- package/dist/release-CXEX6O7F.js +1 -0
- package/dist/{restore-FFGYV7NO.js → restore-PGIVEA5P.js} +1 -1
- package/dist/secret-3LUDEDUW.js +1 -0
- package/dist/setup-PUD375AM.js +1 -0
- package/dist/{signin-AP3D4XM4.js → signin-EP5JLAT5.js} +2 -2
- package/dist/status-LK6DNLCI.js +5 -0
- package/dist/teardown-6RURRSME.js +22 -0
- package/dist/update-YJFTOZEV.js +1 -0
- package/dist/{workspace-CJC5I66L.js → workspace-VW7ZZRFP.js} +3 -3
- package/package.json +5 -5
- package/skills/build-every-app/SKILL.md +22 -13
- package/skills/build-every-app/patterns.md +16 -3
- package/skills/everyapp/SKILL.md +33 -18
- package/skills/everyapp/mcp.md +22 -8
- package/skills/everyapp/security-review.md +1 -1
- package/skills/everyapp/setup/README.md +18 -1
- package/skills/everyapp/setup/access.md +11 -7
- package/skills/everyapp/setup/ai-gateway.md +117 -0
- package/skills/everyapp/setup/ai.md +139 -0
- package/skills/everyapp/setup/context.md +2 -2
- package/skills/everyapp/setup/dataforseo.md +3 -3
- package/skills/everyapp/setup/email.md +1 -1
- package/skills/everyapp/setup/gateway.md +3 -3
- package/skills/everyapp/setup/google.md +8 -6
- package/skills/everyapp/setup/microsoft-365.md +4 -2
- package/skills/everyapp/setup/providers.md +27 -9
- package/skills/everyapp/setup/remote-mcp.md +1 -1
- package/skills/everyapp/setup/signin-apple.md +3 -3
- package/skills/everyapp/setup/signin-cloudflare.md +1 -1
- package/skills/everyapp/setup/signin-github.md +1 -1
- package/skills/everyapp/setup/signin-google.md +2 -2
- package/skills/everyapp/setup/signin-microsoft.md +1 -1
- package/skills/everyapp/setup/slack.md +2 -0
- package/dist/access-LGEN3ABJ.js +0 -1
- package/dist/activity-RSD4D66F.js +0 -12
- package/dist/apps-4RCFXT74.js +0 -13
- package/dist/chunk-AGTCKFRB.js +0 -22
- package/dist/chunk-BHMRY53V.js +0 -2
- package/dist/chunk-CB4U7H2G.js +0 -4
- package/dist/chunk-CZTEDWZ2.js +0 -22
- package/dist/chunk-EGEWRFVY.js +0 -1
- package/dist/chunk-ELK7QZ2M.js +0 -1
- package/dist/chunk-FJJSSVET.js +0 -33
- package/dist/chunk-GKBPYVP3.js +0 -25
- package/dist/chunk-IFCPALVC.js +0 -46
- package/dist/chunk-J455FAEN.js +0 -7
- package/dist/chunk-JYKRUS5C.js +0 -1
- package/dist/chunk-LYNBZ7RV.js +0 -57
- package/dist/chunk-M2QQ2UD7.js +0 -132
- package/dist/chunk-NFU4YFXB.js +0 -1
- package/dist/chunk-ONLNJXVQ.js +0 -32
- package/dist/chunk-RMF4YGD6.js +0 -98
- package/dist/chunk-TLRM3P7V.js +0 -15
- package/dist/chunk-WOVS3GV5.js +0 -10
- package/dist/chunk-ZECBN24L.js +0 -15
- package/dist/chunk-ZFCUH5PK.js +0 -7
- package/dist/delete-XCSIQIRS.js +0 -3
- package/dist/deploy-3QOZEZHC.js +0 -1
- package/dist/dev-JL3ZP5BT.js +0 -86
- package/dist/install-Z5FYXUYM.js +0 -1
- package/dist/mcp-EFDUKJ5V.js +0 -1
- package/dist/provider-EOI5PTFH.js +0 -13
- package/dist/release-74J5ZIL3.js +0 -1
- package/dist/secret-7FKKTLHB.js +0 -1
- package/dist/setup-PAKRCAFO.js +0 -1
- package/dist/status-RMWNHOEK.js +0 -4
- package/dist/teardown-E4JNKAZJ.js +0 -22
- package/dist/update-DWVZFNPS.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,98 +1,107 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as h,b as d,c as
|
|
3
|
-
A value never goes on the command line: it lands in the shell's history and the process list. Rotate it if it was real.`,
|
|
4
|
-
`),data:{...u?{didYouMean:[
|
|
5
|
-
Use one of: ${a.values.join(", ")}.`,data:
|
|
6
|
-
${
|
|
7
|
-
${
|
|
8
|
-
`)}}),
|
|
9
|
-
`)}}),
|
|
10
|
-
`)}}),
|
|
11
|
-
`)}});import{buildCommand as
|
|
12
|
-
`)}});import{buildCommand as
|
|
13
|
-
`)}}),
|
|
14
|
-
`)}}),
|
|
15
|
-
`)}}),
|
|
16
|
-
`)}});import{buildCommand as
|
|
17
|
-
`)}});import{buildCommand as
|
|
18
|
-
`)}});import{buildCommand as
|
|
19
|
-
`)}}),
|
|
20
|
-
`)}}),
|
|
21
|
-
`)}}),
|
|
22
|
-
`)}}),
|
|
23
|
-
`)}}),
|
|
24
|
-
`)}}),
|
|
25
|
-
`)}}),
|
|
26
|
-
`)}}),
|
|
27
|
-
`)}}),
|
|
28
|
-
`)}});import{buildCommand as
|
|
29
|
-
`)}});import{buildCommand as
|
|
30
|
-
`)}}),
|
|
31
|
-
`)}}),
|
|
32
|
-
`)}}),
|
|
33
|
-
`)}}),
|
|
34
|
-
`)}}),
|
|
35
|
-
`)}}),
|
|
36
|
-
`)}}),
|
|
37
|
-
`)}}),
|
|
38
|
-
`)}}),
|
|
39
|
-
`)}}),
|
|
40
|
-
`)}}),
|
|
41
|
-
`)}}),
|
|
42
|
-
`)}})
|
|
43
|
-
`)}}),
|
|
44
|
-
`)}}),
|
|
45
|
-
`)}}),
|
|
46
|
-
`)}})
|
|
47
|
-
`)}}),
|
|
48
|
-
`)}}),
|
|
49
|
-
`)}}),
|
|
50
|
-
`)}}),
|
|
51
|
-
`)}})
|
|
52
|
-
`)}})
|
|
53
|
-
`)}});import{buildCommand as
|
|
54
|
-
|
|
55
|
-
`)}}),
|
|
56
|
-
${
|
|
57
|
-
`)}}),
|
|
58
|
-
`)}}),
|
|
59
|
-
|
|
60
|
-
`)}})
|
|
61
|
-
|
|
62
|
-
${
|
|
63
|
-
`)}}),
|
|
64
|
-
${
|
|
65
|
-
${
|
|
66
|
-
`)}}),
|
|
67
|
-
${
|
|
68
|
-
`)}}),
|
|
2
|
+
import{a as h,b as d,c as F,d as r,e as M,f as p,g as _,h as U,i as W,j as _e}from"./chunk-FB2OC32C.js";import{i as Oe}from"./chunk-NDOEON54.js";import{H as Ge,N as Ie,Q as x,S as De,T as xe,a as te,b as ae,h as oe}from"./chunk-QFTBDXLF.js";import"./chunk-GAPQSINH.js";import"./chunk-LEEUODYR.js";import"./chunk-DCFHBCCW.js";import"./chunk-KOBKGQ27.js";import"./chunk-RL72BUT4.js";import"./chunk-TIYSZWP5.js";import"./chunk-I7FNTTUY.js";import"./chunk-RQBSTNL7.js";import{Oc as Te,Pc as Se,S as ye,Uc as $e,Vc as Re,Wc as ee,a as ge,b as Z,c as e,fb as Q,fc as Ae,hb as ke,k as we,mc as Ce,na as ve,oa as be,rc as Ee}from"./chunk-FQ2A7YAP.js";import qo from"chalk";import{run as Ho}from"@stricli/core";function je(t){return{process:t}}import b from"chalk";import{buildApplication as Fo,buildRouteMap as Mo,text_en as Uo}from"@stricli/core";import{AliasNotFoundError as Le,ArgumentParseError as Gt,EnumValidationError as It,FlagNotFoundError as Pe,InvalidNegatedFlagSyntaxError as Dt,UnexpectedFlagError as xt,UnexpectedPositionalError as Ot,UnsatisfiedFlagError as jt,UnsatisfiedPositionalError as Lt}from"@stricli/core";var Y=`
|
|
3
|
+
A value never goes on the command line: it lands in the shell's history and the process list. Rotate it if it was real.`,Fe=new Set(["secret"]);function Pt(t){for(let[o,a]of t.entries()){let n=a.startsWith("--")?a.slice(2):"",i=t[o+1];if(Fe.has(n)&&i!==void 0&&!i.startsWith("-"))return n}}function Ne(t){return{code:"VALUE_ON_COMMAND_LINE",message:`--${t} takes no value on the command line${Y}`,data:{fix:`give --${t} alone: it asks at a hidden prompt, or reads the value piped in or from --${t}-from-env <VAR>`}}}function ne(t){return t.includes("=")?`${t.split("=")[0]}=\u2026`:t}function se(t){return t.includes("=")?Y:""}function z(t,o){let a=[],n=t;for(let i of o){if(i.startsWith("-")||!("getRoutingTargetForInput"in n))break;let s=n.getRoutingTargetForInput(i);if(!s)break;a.push(i),n=s}return{path:a,target:n}}var O=t=>t.replace(/[A-Z]/g,o=>`-${o.toLowerCase()}`);function Nt(t,o){let a=o.parameters.positional,n=a?.kind==="array"?[`<${a.parameter.placeholder??"arg"}>...`]:(a?.parameters??[]).map((s,u)=>{let g=`<${s.placeholder??`arg${u+1}`}>`;return s.optional?`[${g}]`:g}),i=Object.entries(o.parameters.flags??{}).flatMap(([s,u])=>u.kind==="parsed"&&!u.optional&&u.default===void 0?[`--${O(s)} <${u.placeholder??"value"}>`]:[]);return[e,...t,...n,...i,"[flags]"].join(" ")}function re(t,o){let a;for(let n of o){let i=Ft(t.toLowerCase(),n.toLowerCase());i<=2&&(!a||i<a.distance)&&(a={candidate:n,distance:i})}return a?.candidate}function Ft(t,o){let a=Array.from({length:o.length+1},(n,i)=>i);for(let n=1;n<=t.length;n++){let i=[n];for(let s=1;s<=o.length;s++)i[s]=Math.min(a[s]+1,i[s-1]+1,a[s-1]+(t[n-1]===o[s-1]?0:1));a=i}return a[o.length]}function Me(t,o,a){let{path:n,target:i}=z(t,o),s="getAllEntries"in i?i.getAllEntries().filter(g=>!g.hidden).map(g=>g.name.original):[],u=re(a,s);return{code:"UNKNOWN_COMMAND",message:[`Unknown command ${[...n,a].join(" ")}`,...n.length>0&&s.length>0?[`${n.join(" ")} has ${we(s)}.`]:[]].join(`
|
|
4
|
+
`),data:{...u?{didYouMean:[e,...n,u].join(" ")}:{},help:[e,...n,"--help"].join(" ")}}}function Ue(t,o,a){let{path:n,target:i}=z(t,o),s="parameters"in i?i:void 0,u=n.join(" "),g={help:[e,...n,"--help"].join(" ")},A=s?{usage:Nt(n,s)}:{},y=s?.parameters.flags??{};if(a instanceof Pe||a instanceof Le){let l=`${a instanceof Le?"-":"--"}${a.input}`,f=a instanceof Pe?re(a.input,Object.keys(y).map(O)):void 0;return{code:"UNKNOWN_FLAG",message:`Unknown flag ${l}${u?` for ${u}`:""}`,data:{...f?{didYouMean:`--${f}`}:{},...g}}}if(a instanceof It){let l=re(a.input,a.values);return{code:"INVALID_VALUE",message:`--${a.externalFlagName} can't be "${a.input}"
|
|
5
|
+
Use one of: ${a.values.join(", ")}.`,data:l?{didYouMean:l}:{}}}if(a instanceof Gt){let l=a.exception instanceof Error?a.exception.message:String(a.exception),f=a.externalFlagNameOrPlaceholder,w=Object.keys(y).map(O).includes(f);return w&&Fe.has(f)?Ne(f):w&&y[Object.keys(y).find(D=>O(D)===f)]?.kind==="boolean"?{code:"INVALID_VALUE",message:`--${f} is a switch and takes no value${Y}`,data:{fix:`use --${f} or --no-${f}`}}:w?{code:"INVALID_VALUE",message:l.startsWith(`--${f}`)?`${l}, not ${a.input}`:`--${f} can't be "${a.input}"
|
|
6
|
+
${l}`,data:{}}:{code:"INVALID_VALUE",message:`"${ne(a.input)}" won't do for <${f}>
|
|
7
|
+
${l}${se(a.input)}`,data:A}}if(a instanceof Lt){let l=s?.parameters.positional;if(l?.kind==="array"){let C=l.parameter.brief;return{code:"MISSING_ARGUMENT",message:`Name at least one ${/^[A-Z]{2}/.test(C)?C:`${C.charAt(0).toLowerCase()}${C.slice(1)}`}`,data:A}}let f=s?.parameters.positional?.kind==="tuple"?s.parameters.positional.parameters.find(C=>C.placeholder===a.placeholder):void 0,w=f&&f.brief.length<=30?f.brief.replace(/^the /i,""):void 0;return{code:"MISSING_ARGUMENT",message:`Missing the ${w?/^[A-Z]{2}/.test(w)?w:`${w.charAt(0).toLowerCase()}${w.slice(1)}`:a.placeholder.replaceAll("-"," ")}`,data:A}}if(a instanceof jt){let l=a.externalFlagName,f=o.some(N=>N===`--${l}`||N.startsWith(`--${l}=`)),w=Object.keys(y).find(N=>O(N)===l),D=w?y[w]:void 0,C=D?.kind==="parsed"&&D.placeholder||"value";return{code:"MISSING_FLAG_VALUE",message:f?`--${l} needs a value`:`${u||"everyapp"} needs --${l} <${C}>`,data:{...A,...g}}}if(a instanceof Ot){let l=Pt(o);if(l)return Ne(l);let f=a.expectedCount===1?"one argument":`${a.expectedCount} arguments`;return{code:"TOO_MANY_ARGUMENTS",message:a.expectedCount===0?`${u||"everyapp"} takes no arguments (got "${ne(a.input)}")${se(a.input)}`:`${u||"everyapp"} takes ${f}, but got another: "${ne(a.input)}"${se(a.input)}`,data:A}}return a instanceof Dt?{code:"INVALID_VALUE",message:`--no-${a.externalFlagName} is a switch and takes no value${Y}`,data:{}}:a instanceof xt?{code:"REPEATED_FLAG",message:`--${a.externalFlagName} is given more than once`,data:g}:{code:"COMMAND_FAILED",message:a instanceof Error?a.message:String(a),data:g}}import{buildCommand as ie,buildRouteMap as Mt}from"@stricli/core";var pe={gateway:h,"account-id":d,json:r,verbose:p},Ut=ie({loader:async()=>{let{on:t}=await import("./access-YWM4BSBD.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{email:{kind:"parsed",parse:String,variadic:!0,optional:!0,placeholder:"address",brief:"Also let this email address past Access (repeat for several; an account still takes an invitation)"},"email-domain":{kind:"parsed",parse:String,variadic:!0,optional:!0,placeholder:"domain",brief:"Also let everyone with an email address at this domain past Access (repeat for several)"},team:{kind:"parsed",parse:String,optional:!0,placeholder:"name",brief:"Name for a new Zero Trust team when the account has none: its sign-in page is <name>.cloudflareaccess.com, for good (asked at a terminal; ignored once a team exists)"},session:{kind:"parsed",parse:String,optional:!0,placeholder:"duration",brief:"How long an Access sign-in lasts, like 720h or 24h (default 720h, the most Access allows; an existing application keeps its own unless given)"},"team-session":{kind:"parsed",parse:String,optional:!0,placeholder:"duration",brief:"Set the team's global session too (how often people sign in at the identity provider): it applies to every Access application in the account"},"write-settings":{kind:"boolean",optional:!0,brief:"Write the three Gateway settings even when they are set already (after an Access application was recreated by hand: its AUD tag changed)"},...pe}},docs:{brief:"Turn Cloudflare Access on in front of the Gateway and its apps, or bring it up to date",fullDescription:["Everyone opens the Gateway and its apps through Cloudflare Access first (a one-time PIN to","their email, or your identity provider), then lands signed in. With your Cloudflare login it","finds or creates the Zero Trust team, adds the one-time PIN when people have no other way to","sign in, keeps an allow policy with every member's and invitee's email, puts one Access","application in front of the Gateway's host and one in front of the apps' hosts (MCP, the OAuth","endpoints and each app's public routes stay reachable without a login), and gives the Gateway","the team domain and both AUD tags in one change.","","Run it again any time: after inviting someone, so Access lets them in, or after anything","changed by hand. It changes only what differs, never removes anyone from the policy, and","leaves alone what it didn't set up. Deploys keep an app's public routes in step themselves.","","Afterwards each existing member signs in once with their password through Access, which",`links the two. Then passwords can go: ${e} secret set EMAIL_PASSWORD_SIGN_IN (false).`,"","Examples:",` ${e} access on`,` ${e} access on --email-domain example.com`,` ${e} access on --team acme --json`].join(`
|
|
8
|
+
`)}}),Wt=ie({loader:async()=>{let{off:t}=await import("./access-YWM4BSBD.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{"keep-applications":{kind:"boolean",optional:!0,brief:"Keep the two Access applications: Access still asks people to sign in there, and the Gateway no longer requires it"},yes:{kind:"boolean",optional:!0,brief:"Turn Access off without asking"},...pe},aliases:{y:"yes"}},docs:{brief:"Turn Cloudflare Access off for the Gateway and its apps",fullDescription:["Removes CLOUDFLARE_ACCESS_AUD, CLOUDFLARE_ACCESS_APPS_AUD and CLOUDFLARE_ACCESS_TEAM_DOMAIN","from the Gateway in one change, so passwords sign people in again at once, then deletes the","two Access applications (one that also covers something else only loses EveryApp's hosts).","The Zero Trust team, its identity providers and the allow policy stay: other applications may","use them. Asks first.","","Example:",` ${e} access off`].join(`
|
|
9
|
+
`)}}),Yt=ie({loader:async()=>{let{show:t}=await import("./access-YWM4BSBD.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:pe},docs:{brief:"Show how Cloudflare Access fronts the Gateway, and what access on would change",fullDescription:["The Zero Trust team, who the allow policy lets in, the two Access applications and whether","their public paths match the apps' public routes, and which Access settings the Gateway has","(their values can't be read back). Nothing is changed.","","Example:",` ${e} access show`].join(`
|
|
10
|
+
`)}}),We=Mt({routes:{on:Ut,off:Wt,show:Yt},docs:{brief:"Put Cloudflare Access in front of the Gateway and its apps, or take it off"}});import{buildCommand as zt}from"@stricli/core";var Ye=zt({loader:async()=>{let{configure:t}=await import("./configure-CAWCTPYY.js");return t},parameters:{positional:{kind:"tuple",parameters:[{brief:"The app to configure (default: the app in this directory)",parse:String,placeholder:"app",optional:!0}]},flags:{"from-env":{kind:"boolean",brief:"Take each unset setting's value, optional ones too, from the environment variable of its name (DATAFORSEO_API_KEY from $DATAFORSEO_API_KEY); a set name is never replaced; stdin isn't read; the rest are asked for at a terminal",optional:!0},gateway:h,"account-id":d,json:r,verbose:p}},docs:{brief:"Set up an app: asks for each setting it needs, required ones first, then the optional ones",fullDescription:["Reads what the app's everyapp.config.ts declares (AI providers, capabilities, its own","secrets) and what is set, then asks for each required setting that isn't (hidden input,","with where to get it beside each), offers the optional ones (Enter skips them all), and","says whether the app is ready. One member of an any-of group is enough: it asks which.","Run it again any time: it shows what is set (names only, never values) and lets you","change one.","","Where they go: an AI provider's key or a capability's client is a Gateway setting, held","once for every app on the Gateway Worker; the app's own secrets go on its Worker, after","its first deploy. Changes are live at once; no deploy needed.","","For a script or a coding agent, which can't answer a prompt: pipe NAME=value lines in","(one per line; # starts a comment only at the start of a line; a value is taken as it is,","one pair of quotes around it dropped), or export the variables under the settings' own","names and add --from-env (then stdin isn't read). A value never goes on the command line.","","Examples:",` ${e} configure crm`,` ${e} configure (in the app's directory)`,` ${e} configure crm --from-env --json`,` printf 'OPENROUTER_API_KEY=%s\\n' "$OPENROUTER_API_KEY" | ${e} configure crm --json`,"",`One setting at a time, by name: ${e} secret set <NAME> [--app <id>]`].join(`
|
|
11
|
+
`)}});import{buildCommand as qt}from"@stricli/core";var ze=qt({loader:async()=>import("./create-3ZWJQXPK.js"),parameters:{positional:{kind:"tuple",parameters:[{brief:"An app name (lowercase letters, digits and dashes, e.g. my-app; asked for when missing), or the path of the folder to make, named after its last part (../my-app)",parse:String,placeholder:"name or path",optional:!0}]},flags:{yes:{kind:"boolean",brief:"Don't ask anything (a name is then required)",optional:!0},json:r,verbose:{kind:"boolean",brief:"Stream install and git output to stderr",optional:!0}},aliases:{y:"yes"}},docs:{brief:"Create a new app from the starter template",fullDescription:["A path (../my-app, ~/apps/my-app) makes the app there, named after its last part:","outside your EveryApp checkout it is its own git repository, linked to the checkout;","inside it only apps/<name> is allowed. A bare name goes in apps/<name> when run from","the checkout, in ./<name> anywhere else. Dependencies are installed and the local","database is ready, so `pnpm dev` works straight away. Then: cd into it and","`pnpm run deploy`.","","Examples:"," pnpm everyapp create ../my-app beside the checkout, its own repository"," pnpm everyapp create analytics apps/analytics, from the checkout"].join(`
|
|
12
|
+
`)}});import{buildCommand as le,buildRouteMap as Ht}from"@stricli/core";var Vt=le({loader:async()=>{let{migrate:t}=await import("./db-B7KO37SV.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{json:r,verbose:p}},docs:{brief:"Apply migrations to the local database",fullDescription:["Apply the app's migrations to the local database","","Reads migrations from migrations.dir in everyapp.config.ts (default drizzle/).",`\`${e} dev\` runs this on every start. Production migrations run only during`,`\`${e} deploy\`, after a restore point is saved.`].join(`
|
|
13
|
+
`)}}),Kt=le({loader:async()=>{let{query:t}=await import("./db-B7KO37SV.js");return t},parameters:{positional:{kind:"tuple",parameters:[{brief:"SQL to run",parse:String,placeholder:"sql",optional:!0}]},flags:{local:{kind:"boolean",brief:"Query the local database `everyapp dev` uses",optional:!0},file:{kind:"parsed",parse:String,brief:"Read the SQL from a file (- for stdin)",placeholder:"path",optional:!0},binding:{kind:"parsed",parse:String,brief:"D1 binding to query (default: the migrations binding, or the first)",placeholder:"name",optional:!0},gateway:h,"account-id":d,yes:{kind:"boolean",brief:"Run SQL that changes the production database without asking",optional:!0},json:{...M,brief:"Print one NDJSON done event, its rows in data.results, instead of a table"},verbose:{...p,brief:"Show every step"}}},docs:{brief:"Run SQL against the production database (or --local)",fullDescription:["Run SQL against the app's D1 database","","Runs against the production database unless --local is set; SQL that changes it is","confirmed first (--yes skips that). Rows print as a table; with --json they are in the","done event's data.results.","","EXAMPLES",` $ ${e} db query "select * from todos limit 5"`,` $ ${e} db query --local "select count(*) from events"`,` $ ${e} db query --file scripts/backfill.sql`].join(`
|
|
14
|
+
`)}}),Bt=le({loader:async()=>{let{restore:t}=await import("./restore-PGIVEA5P.js");return t},parameters:{positional:{kind:"tuple",parameters:[{brief:"The app (default: the one in this directory)",parse:String,placeholder:"app",optional:!0}]},flags:{gateway:{kind:"boolean",brief:"Restore the Gateway's database, from its last migrating setup or upgrade",optional:!0},"account-id":d,yes:{kind:"boolean",brief:"Restore without asking",optional:!0},json:r}},docs:{brief:"Put the production database back to before the last migrations",fullDescription:["Put the app's production database back to before its last migrations","","Each deploy that migrates a database with data saves a restore point first (Time Travel).","This restores the last one, after asking: the migrations are undone, and so is anything","written to the database since. --gateway does the same for the Gateway's database.","","EXAMPLES",` $ ${e} db restore`,` $ ${e} db restore --gateway`].join(`
|
|
15
|
+
`)}}),qe=Ht({routes:{migrate:Vt,query:Kt,restore:Bt},docs:{brief:"Migrate, query and restore an app's D1 database"}});import{buildCommand as Xt}from"@stricli/core";var He=Xt({loader:async()=>{let{deleteApp:t}=await import("./delete-CB3EPOU4.js");return t},parameters:{positional:{kind:"tuple",parameters:[{brief:"App id (default: the app in this directory)",parse:String,placeholder:"id",optional:!0}]},flags:{gateway:h,"account-id":d,purge:{kind:"boolean",brief:"Also delete the app's Worker and helper Workers, D1 databases, KV namespaces, Workflows and Email Routing routes",optional:!0},yes:{kind:"boolean",brief:"Delete without asking (with --purge too, without typing the app id)",optional:!0},json:r,verbose:p},aliases:{y:"yes"}},docs:{brief:"Remove an app from the Gateway",fullDescription:["Deletes the app in the Gateway's D1 database (its name stays reserved; deploy it again to","bring it back) and removes its Gateway binding and hostname, with a redeploy of the Gateway","from this checkout.","The app's Worker and data are kept unless --purge, which deletes them for good.","Asks first at a terminal; elsewhere it needs --yes."].join(`
|
|
16
|
+
`)}});import{buildCommand as Jt}from"@stricli/core";var Ve=Jt({loader:async()=>{let{deploy:t}=await import("./deploy-5O7LV5OX.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{gateway:h,"account-id":d,...W,"no-wait":{kind:"boolean",brief:"Don't wait for the app to go live (a new hostname's certificate included); the Gateway makes it live within a minute, or on its first visit",optional:!0},yes:{kind:"boolean",brief:"With no Gateway yet, install one at apps.<zone> without asking (never cf's questions, or the one before replacing a Worker changed outside everyapp)",optional:!0},json:r,verbose:p},aliases:{y:"yes"}},docs:{brief:"Deploy the app in this directory",fullDescription:["Deploys the app in this directory as a private Cloudflare Worker defined by cloudflare.config.ts,","with cf and your Cloudflare login (or CLOUDFLARE_API_TOKEN), in the Gateway's account:"," 1. Registers the app in the Gateway's database, which names its Worker, resources and hostname"," 2. Creates or links the D1 databases and KV namespaces in everyapp.config.ts"," 3. Installs dependencies and builds (cf build, or the manifest's build command), then checks"," the built Worker against the app policy and the drizzle migrations against the schema"," 4. Bookmarks the production D1 database, then applies its migrations"," 5. Uploads the Worker with its secrets, its helper Workers, its Workflows and the Email"," Routing rules for its inbound addresses (turning routing on for a domain asks first)"," 6. Rebinds the Gateway from this checkout when the app is new (upgrading the Gateway too"," when the checkout is newer), then waits for the app's hostname to go live","","No Gateway in any account the login sees? At a terminal it offers to install one at",`apps.<zone> (what ${e} setup does), then deploys; otherwise it stops with action_required`,"install_gateway and the setup command to run. Nothing else asks first. Install and build","output goes to a log file, never to stdout. Safe to run again: a redeploy of an app the","Gateway already serves never touches the Gateway.","",`Someone else's published app: ${e} install <url>. To publish this one: ${e} release.`,"--gateway <url> (or EVERYAPP_GATEWAY_URL) names the Gateway when your login sees several.","With --json, each step is an NDJSON event."].join(`
|
|
17
|
+
`)}});import{buildCommand as Zt}from"@stricli/core";import{numberParser as Qt}from"@stricli/core";var Ke=Zt({loader:async()=>import("./dev-4JYCVVOZ.js"),parameters:{flags:{port:{kind:"parsed",parse:Qt,brief:"Gateway port (defaults to $PORT, then 8787)",optional:!0},host:{kind:"parsed",parse:String,brief:"Address the Gateway listens on (default 127.0.0.1; 0.0.0.0 lets other machines in, each as a dev identity)",optional:!0},mode:{kind:"parsed",parse:String,brief:"stub (seeded dev user, default) | mirror (real login through a local Gateway)",optional:!0},gateway:{kind:"parsed",parse:String,brief:"mirror mode: URL of the separately-run local Gateway (default http://localhost:3000)",optional:!0},baseHost:{kind:"parsed",parse:String,brief:"mirror mode: two-label base host for cookie scope (default everyapp.localhost)",optional:!0},"skip-migrations":{kind:"boolean",brief:"Start without applying local database migrations",optional:!0}}},docs:{brief:"Run the app locally behind a dev Gateway",fullDescription:["Runs the app under `cf dev` (or the manifest's dev command) on an internal","port and a gateway-lite in front of it on $PORT (default 8787) \u2014 the REAL","perimeter: public-route policy, header strip/inject, a real RS256 identity","JWT, and a seeded dev user. Open http://<app-id>.localhost:8787 \u2014 the first","Host label selects the app, so portless per-worktree hosts work with no","configuration.","","Identities are signed with the SDK's well-known dev keypair, which the app's","development build trusts on its own: nothing is written into the app. The","key is public, so the gateway listens on 127.0.0.1 unless --host says","otherwise. Before starting, dev generates the Worker's types when",".cloudflare/types is missing and applies local D1 migrations","(cf d1 migrations apply --local) to .cloudflare/state.","","With no Gateway in local runs, the app reads its manifest's secrets and the","keys of its providers and capabilities (OPENROUTER_API_KEY, DATAFORSEO_API_KEY,","...) from .dev.vars in its directory, one NAME=value per line, gitignored. The","ready block names the ones that file is missing and the app can't run without;","until they are set, AI calls and integrations answer that they aren't set up","(email needs none: sendEmail() prints until EMAIL_FROM and a transport are set).","","Every request goes through the real perimeter (identity header, public-route","policy, CSRF). Public routes are auth-optional; to call them anonymously send","the header x-everyapp-dev-anon: 1 (curl) or set the cookie everyapp_dev_anon=1","(browser). Requests straight to the app's internal port get 401, by design.","","An app that declares crons runs one on demand with"," curl -X POST http://<app-id>.localhost:8787/__everyapp/cron -d '<schedule>'","An app that receives mail gets a curl command that delivers message.eml to its","email() handler: a raw message with From, To, Subject and Message-ID headers,","to any address. email() gets no identity.","","--mode stub (default): seeded dev user, zero setup.","--mode mirror: authenticate against a SEPARATELY-running local Gateway"," (run `pnpm dev` in apps/every-app-gateway first). Real login/launcher"," are forwarded to it. Requires a two-label base host (e.g."," everyapp.localhost) so the session cookie crosses the subdomain"," boundary; the CLI prints setup guidance if the host is unusable."," Also settable via EVERYAPP_DEV_MODE; the flag wins.","","Ctrl+C stops the app and exits with 130."].join(`
|
|
18
|
+
`)}});import{buildCommand as v,buildRouteMap as ea}from"@stricli/core";var E={org:F,gateway:h,"account-id":d,json:r,verbose:p},j={placeholder:"id",brief:"The subscription, by its sub_ id (events list names them)",parse:String},ta=v({loader:async()=>{let{add:t}=await import("./events-GJV2KVIU.js");return t},parameters:{positional:{kind:"tuple",parameters:[{placeholder:"url",brief:"The webhook's https:// URL (leave it out with --email)",parse:String,optional:!0}]},flags:{events:{kind:"parsed",parse:String,variadic:!0,optional:!0,placeholder:"types",brief:"The events to send, comma separated: types (member.joined), prefixes (cap.*, app.crm.*) or * (repeat to add more; default: every event but test pings)"},name:{kind:"parsed",parse:String,optional:!0,placeholder:"text",brief:"What to call it, like 'Slack #ops' (default: the URL's host, or Email owners and admins)"},email:{kind:"enum",values:ke,optional:!0,brief:"Mail each event to the organization's owners, or its owners and admins (admins), instead of a webhook"},secret:{kind:"boolean",optional:!0,brief:"Give the webhook's signing secret yourself, 16 to 128 characters: asked at a hidden prompt, or read piped in, never typed on the command line (default: one is made and shown once)"},"secret-from-env":{kind:"parsed",parse:String,optional:!0,placeholder:"VAR",brief:"Read the signing secret from this environment variable"},...E}},docs:{brief:"Send the organization's events to a URL (a signed POST) or by email to its owners and admins",fullDescription:["A webhook gets each event as a JSON POST, signed with the subscription's secret:","X-EveryApp-Signature: t=<seconds>,v1=<hex>, HMAC-SHA256 over <t>.<body>; the receiver checks","it (/docs/events has the code). Without --secret one is made and shown once: copy it then.","Slack's Workflow Builder, Zapier, n8n, Make and your own endpoint all take one; the body's","top-level summary is a line a person reads.","","The URL must be https:// on a public hostname: not an IP address, not a local or internal","name, not the Gateway or one of its apps. For a receiver on a private network, set",`${Q} on the Gateway with the value "true" (self-host only;`,`${e} secret set ${Q}): then http://, IP addresses and private names are let through.`,"","--email mails each event to the organization's owners (owners) or owners and admins","(admins), from the Gateway's sender (EMAIL_FROM); it takes no address. An organization has at","most 25 subscriptions. The Gateway sends each event within a minute.","","Examples:",` ${e} events add https://hooks.example.com/everyapp --events cap.*,member.*`,` ${e} events add https://hooks.zapier.com/hooks/catch/1/abc --name Zapier --secret`,` ${e} events add --email admins --events cap.*`,` ${e} events add https://n8n.example.com/webhook/x --secret-from-env N8N_SECRET --json`].join(`
|
|
19
|
+
`)}}),aa=v({loader:async()=>{let{list:t}=await import("./events-GJV2KVIU.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:E},docs:{brief:"List the organization's subscriptions: where each goes, what it takes, how its last delivery went",fullDescription:["A webhook shows its URL's host and path (never its query or secret); an email one, whom it","mails. Nothing is changed.","","Example:",` ${e} events list`].join(`
|
|
20
|
+
`)}}),oa=v({loader:async()=>{let{remove:t}=await import("./events-GJV2KVIU.js");return t},parameters:{positional:{kind:"tuple",parameters:[j]},flags:E},docs:{brief:"Remove a subscription (a built-in one is disabled instead)",fullDescription:["Nothing more is delivered to it; its delivery log stays for 30 days. The Gateway's built-in","cap alerts are disabled instead of removed, so the Gateway never makes them again.","","Example:",` ${e} events remove sub_0123456789abcdef01234567`].join(`
|
|
21
|
+
`)}}),na=v({loader:async()=>{let{enable:t}=await import("./events-GJV2KVIU.js");return t},parameters:{positional:{kind:"tuple",parameters:[j]},flags:E},docs:{brief:"Resume a subscription: new events are queued for it again",fullDescription:["What happened while it was disabled isn't sent. Safe to repeat.","","Example:",` ${e} events enable sub_0123456789abcdef01234567`].join(`
|
|
22
|
+
`)}}),sa=v({loader:async()=>{let{disable:t}=await import("./events-GJV2KVIU.js");return t},parameters:{positional:{kind:"tuple",parameters:[j]},flags:E},docs:{brief:"Pause a subscription: no new events are queued for it, and what is queued is dropped",fullDescription:["Turn the built-in cap alerts off this way. Safe to repeat; events enable resumes it.","","Example:",` ${e} events disable sub_0123456789abcdef01234567`].join(`
|
|
23
|
+
`)}}),ra=v({loader:async()=>{let{test:t}=await import("./events-GJV2KVIU.js");return t},parameters:{positional:{kind:"tuple",parameters:[j]},flags:{"no-wait":{kind:"boolean",optional:!0,brief:"Return once the test event is queued; events deliveries shows how it went"},...E}},docs:{brief:"Send a test event (ping) to one subscription and wait to see whether it was delivered",fullDescription:["Queues a ping for that subscription only, then waits up to 90 seconds while the Gateway","sends it (it sends queued events every minute), and says delivered or failed with the","receiver's status code or the error. A failed test is retried like any delivery.","","Examples:",` ${e} events test sub_0123456789abcdef01234567`,` ${e} events test sub_0123456789abcdef01234567 --no-wait --json`].join(`
|
|
24
|
+
`)}}),ia=v({loader:async()=>{let{deliveries:t}=await import("./events-GJV2KVIU.js");return t},parameters:{positional:{kind:"tuple",parameters:[{...j,brief:"Only this subscription's (default: every subscription's)",optional:!0}]},flags:{dead:{kind:"boolean",optional:!0,brief:"Only deliveries that ran out of attempts (dead), to redeliver"},limit:{kind:"parsed",parse:Oe,optional:!0,placeholder:"n",brief:"How many to show, newest first: 1 to 200 (default 20)"},...E}},docs:{brief:"List the last deliveries (30 days): the event, its subscription, attempts, status, next attempt, last error",fullDescription:["A delivery is retried after 1, 5 and 30 minutes, then 2, 8 and 24 hours; the seventh failure","is dead. Nothing is changed.","","Examples:",` ${e} events deliveries`,` ${e} events deliveries sub_0123456789abcdef01234567 --limit 50`,` ${e} events deliveries --dead`].join(`
|
|
25
|
+
`)}}),pa=v({loader:async()=>{let{redeliverDelivery:t}=await import("./events-GJV2KVIU.js");return t},parameters:{positional:{kind:"tuple",parameters:[{placeholder:"delivery",brief:"The delivery, by its dlv_ id (events deliveries names them)",parse:String}]},flags:E},docs:{brief:"Send a failing or dead delivery again: the Gateway sends it within a minute, with the full retry schedule",fullDescription:["Its attempts start over at 0. A delivered one is left alone. The receiver may get the same","event id again: receivers deduplicate on it.","","Example:",` ${e} events redeliver dlv_0123456789abcdef01234567`].join(`
|
|
26
|
+
`)}}),la=v({loader:async()=>{let{types:t}=await import("./events-GJV2KVIU.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{json:r,verbose:p}},docs:{brief:"List the event types --events takes, with their versions",fullDescription:["The catalogue this CLI knows, and how a pattern names several (member.*, app.crm.*, *). No","Gateway is needed.","","Example:",` ${e} events types`].join(`
|
|
27
|
+
`)}}),Be=ea({routes:{add:ta,list:aa,remove:oa,enable:na,disable:sa,test:ra,deliveries:ia,redeliver:pa,types:la},aliases:{ls:"list"},docs:{brief:"Send the Gateway's events to Slack, Zapier, n8n or your own endpoint (signed), or by email"}});import{buildCommand as da}from"@stricli/core";var Xe=da({loader:async()=>{let{install:t}=await import("./install-UAG3CNYW.js");return t},parameters:{positional:{kind:"tuple",parameters:[{brief:"The app release to install: a GitHub repository URL (its latest release), a release tarball's URL, or a downloaded everyapp-release.tar.gz",parse:String,placeholder:"source"}]},flags:{gateway:h,"account-id":d,...W,"no-wait":{kind:"boolean",brief:"Don't wait for the app to go live (a new hostname's certificate included); the Gateway makes it live within a minute, or on its first visit",optional:!0},yes:{kind:"boolean",brief:"With no Gateway yet, install one at apps.<zone> without asking (never cf's questions, or the one before replacing a Worker changed outside everyapp)",optional:!0},json:r,verbose:p},aliases:{y:"yes"}},docs:{brief:"Install an app someone published, from GitHub or a release file",fullDescription:[`Installs an app release on your Gateway with no checkout of the app, as ${e} deploy`,"would from the app's directory, with nothing to build: <source> is a GitHub repository URL","(the everyapp-release.tar.gz on its latest release; \u2026/releases/tag/<tag> for that one), a","tarball's HTTPS URL, or a downloaded everyapp-release.tar.gz. The release holds the app's","tenant-neutral Build Output, migrations and manifest, checked against its SHA-256. Run it",`again later to update the app. Its settings are set with ${e} configure <id>;`,".everyapp/secrets.env in this directory is the deploy's own file, read only for a Hyperdrive","app's database URL.","","A repository without a release is never built from its URL: clone it, then run pnpm",`install in it and this checkout's ${e} deploy from its directory. Postgres migrations`,"need the app's source, so their releases are refused.","","No Gateway in any account the login sees? At a terminal it offers to install one at",`apps.<zone> (what ${e} setup does, owner link included), then installs the app; otherwise`,"it stops with action_required install_gateway and the setup command to run.","--gateway <url> (or EVERYAPP_GATEWAY_URL) names the Gateway when your login sees several.","With --json, each step is an NDJSON event."].join(`
|
|
28
|
+
`)}});import{buildCommand as ca}from"@stricli/core";var Je=ca({loader:async()=>{let{login:t}=await import("./login-QEKMLMUB.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{json:r,verbose:p}},docs:{brief:"Log in to Cloudflare",fullDescription:["Log in to Cloudflare","","At a terminal, Cloudflare's own login runs (open its link and enter the code). Piped, or","with --json, the link and code are printed and the run waits for the login to be approved.","Already logged in, it says as whom. Unattended runs can set CLOUDFLARE_API_TOKEN and","CLOUDFLARE_ACCOUNT_ID instead."].join(`
|
|
29
|
+
`)}});import{buildCommand as T,buildRouteMap as ha}from"@stricli/core";var S={gateway:h,"account-id":d,json:r,verbose:p},G={placeholder:"id",brief:"The MCP app (mcp list names them): dataforseo, or the id a server was added as",parse:String},ma=T({loader:async()=>{let{add:t}=await import("./mcp-AFGVOM5D.js");return t},parameters:{positional:{kind:"tuple",parameters:[{placeholder:"url",brief:"The server's MCP address (https://, the one URL the Gateway ever sends its credential to)",parse:String}]},flags:{name:{kind:"parsed",parse:String,brief:"The app's id and tool prefix (default: from the URL's host, https://mcp.treg.to/mcp \u2192 treg)",optional:!0},auth:{kind:"enum",values:ve,brief:"How the Gateway authenticates to the server (default: none; bearer with --secret, header with --header)",optional:!0},header:{kind:"parsed",parse:String,brief:"With --auth header: the header the server reads the credential from (X-Api-Key)",optional:!0},secret:{kind:"parsed",parse:String,brief:"The Gateway setting holding the credential, ending in _MCP_TOKEN (default: <ID>_MCP_TOKEN)",optional:!0},risk:{kind:"enum",values:be,brief:"How a tool's risk is decided: from the server's hints, unknown as write (annotations, the default), or every tool read or write",optional:!0},description:{kind:"parsed",parse:String,brief:"What the app is for, as Admin \u2192 Apps and everyapp_list_apps say it (default: from the URL)",optional:!0},"from-env":{kind:"parsed",parse:String,brief:"Set the credential from this environment variable once the app is added (as secret set --from-env)",placeholder:"VAR",optional:!0},...S}},docs:{brief:"Add any remote MCP server as an MCP app: its tools reach members' AI clients through the Gateway's /mcp",fullDescription:["The Gateway serves the server's tools on its own /mcp under <id>_<tool> names, holding the","server's credential itself: every call is attributed to the member, audited, counted and","capped like an app's, and read tools are told apart from write tools (a read-only","connection sees only the read ones). You, the owners and the admins get it at once; an","admin grants others in Admin \u2192 Apps \u2192 Manage access. Nothing is deployed.","","The credential is a Gateway setting named <ID>_MCP_TOKEN (--secret picks another name","ending in _MCP_TOKEN), pinned to the URL's origin when it is set: the Gateway never sends","it anywhere else. At a terminal, add offers to set it right away (hidden input, as secret","set asks); --from-env VAR sets it from an environment variable; otherwise, afterwards:",` ${e} secret set TREG_MCP_TOKEN`,"","--auth bearer sends Authorization: Bearer <value>; header sends <header>: <value>; basic","takes user:password; none sends nothing. oauth is recorded but not served yet: the Gateway","doesn't sign in to MCP servers with OAuth this week.","","add looks at the URL once from this machine, without the credential, and says what it","found (MCP, a 401, a redirect, or nothing); that is a warning, never a refusal, since the","Gateway, not this machine, is what fetches it. The Gateway follows no redirects.","","Examples:",` ${e} mcp add https://mcp.deepwiki.com/mcp`,` ${e} mcp add https://treg.to/mcp/ --auth bearer`,` ${e} mcp add https://api.example.org/mcp --name example --auth header --header X-Api-Key --risk read`].join(`
|
|
30
|
+
`)}}),ua=T({loader:async()=>{let{remove:t}=await import("./mcp-AFGVOM5D.js");return t},parameters:{positional:{kind:"tuple",parameters:[G]},flags:S},docs:{brief:"Remove an MCP app: it leaves /mcp and the home page, and everyone's access to it goes",fullDescription:["Like deleting an app: the Gateway stops serving its tools within 30 seconds, and","everyone's access to it, the personal tokens bound to it, its tools snapshot and its","place in AI connections go with it. Adding it again starts fresh. To stop serving it",`and keep all that, turn it off instead: ${e} mcp off <id>.`,"","The Gateway setting holding its key or credential stays, and so does a credential's pin",`to its origin; ${e} secret unset <NAME> removes both.`,"","Example:",` ${e} mcp remove treg`].join(`
|
|
31
|
+
`)}}),fa=T({loader:async()=>{let{on:t}=await import("./mcp-AFGVOM5D.js");return t},parameters:{positional:{kind:"tuple",parameters:[G]},flags:S},docs:{brief:"Turn an MCP app on: its tools reach members' AI clients through the Gateway's /mcp",fullDescription:["An MCP app is a data provider (DataForSEO, built in) or any remote MCP server added with",`${e} mcp add <url>, offered as an app of the Gateway's own with no page and nothing to`,"deploy: the Gateway serves its tools on its /mcp under <id>_<tool> names, with its own key,","and counts and audits every call like an app's. It appears in Admin \u2192 Apps and under MCP","apps on the home page.","","A built-in's first on adds it: you, the owners and the admins get it at once, and an","admin grants other members with Manage access. On after off serves it again at once,","with everyone's access kept. The key is a Gateway setting the tools need (mcp list names","it):",` ${e} secret set DATAFORSEO_API_KEY`,"","Safe to repeat: an app that is on stays on, with its access.","","Examples:",` ${e} mcp on dataforseo`,` ${e} mcp on treg --json`].join(`
|
|
32
|
+
`)}}),ga=T({loader:async()=>{let{off:t}=await import("./mcp-AFGVOM5D.js");return t},parameters:{positional:{kind:"tuple",parameters:[G]},flags:S},docs:{brief:"Turn an MCP app off: its tools leave /mcp, and everyone's access is kept for on",fullDescription:["The Gateway stops serving the app's tools within 30 seconds and the home page stops","listing it. Everyone's access, the personal tokens bound to it and its tools snapshot",`are kept, so ${e} mcp on <id> serves it again at once. To remove it for good, with`,`all of that: ${e} mcp remove <id>.`,"","(Until 2026-10-25 off removed the app; that is remove now.)","","Example:",` ${e} mcp off dataforseo`].join(`
|
|
33
|
+
`)}}),wa=T({loader:async()=>{let{list:t}=await import("./mcp-AFGVOM5D.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:S},docs:{brief:"List the MCP apps: built-in and added, on or off, their tools and whether each key is set",fullDescription:["Nothing is changed. A key's value can't be read back; only whether it is set.","","Example:",` ${e} mcp list`].join(`
|
|
34
|
+
`)}}),ya=T({loader:async()=>{let{show:t}=await import("./mcp-AFGVOM5D.js");return t},parameters:{positional:{kind:"tuple",parameters:[G]},flags:S},docs:{brief:"Show an MCP app: its address, credential, status, last tool listing and every tool with its risk",fullDescription:["For a remote server: the URL, how the Gateway authenticates, the credential's name, whether","it is set and the origin it is pinned to, the risk default, when the tools were last listed","(and the error if that failed), then every tool the server listed: its name on the Gateway,","the server's own name, its risk and where that comes from (the server's hint, the app's","default, your override), and whether it is on. Nothing is changed.","","Examples:",` ${e} mcp show treg`,` ${e} mcp show dataforseo --json`].join(`
|
|
35
|
+
`)}}),va=T({loader:async()=>{let{refresh:t}=await import("./mcp-AFGVOM5D.js");return t},parameters:{positional:{kind:"tuple",parameters:[G]},flags:S},docs:{brief:"Drop an MCP app's tools snapshot, so the Gateway lists its tools again",fullDescription:["Only the snapshot goes (the Gateway's copy of the tool list); the app, its access and its","settings stay. The Gateway lists the tools again on the next request to its /mcp, or","within the hour. Use it after the server changed its tools.","","Example:",` ${e} mcp refresh treg`].join(`
|
|
36
|
+
`)}}),ba=T({loader:async()=>{let{tool:t}=await import("./mcp-AFGVOM5D.js");return t},parameters:{positional:{kind:"tuple",parameters:[G,{placeholder:"tool",brief:"The tool: the server's name for it, or its name on the Gateway (mcp show lists both)",parse:String}]},flags:{risk:{kind:"enum",values:["read","write","destructive","annotations"],brief:"The tool's risk: read, write or destructive (hidden until approvals exist); annotations drops your override",optional:!0},on:{kind:"boolean",brief:"List the tool (the default)",optional:!0},off:{kind:"boolean",brief:"Leave the tool out: it isn't listed, and a call answers Unknown tool",optional:!0},...S}},docs:{brief:"Override one tool of a remote MCP app: its risk, or whether it is listed at all",fullDescription:["A tool's risk decides who can call it: read tools every connection, write tools only","read & write ones, destructive tools nobody until approvals exist. The server's hints","decide it unless the app's --risk default or this override says otherwise. The Gateway","lists the tools again on first use. A built-in MCP app's tools are its own and can't be","changed here.","","Examples:",` ${e} mcp tool treg delete_everything --risk destructive`,` ${e} mcp tool treg treg_noisy_tool --off`,` ${e} mcp tool treg search --risk annotations`].join(`
|
|
37
|
+
`)}}),Ze=ha({routes:{add:ma,remove:ua,on:fa,off:ga,list:wa,show:ya,refresh:va,tool:ba},aliases:{ls:"list"},docs:{brief:"Offer MCP servers to members' AI clients as MCP apps, with the Gateway holding each one's key"}});import{buildCommand as $,buildRouteMap as ka}from"@stricli/core";var R={gateway:h,"account-id":d,json:r,verbose:p},q={placeholder:"id",brief:"The provider's id (provider list names them): stripe",parse:String},Aa=$({loader:async()=>{let{add:t}=await import("./provider-622VM7UZ.js");return t},parameters:{positional:{kind:"tuple",parameters:[{placeholder:"spec",brief:"The provider's spec: a JSON file, or an https URL to one (64 KiB at most); none with --oauth",parse:String,optional:!0}]},flags:{replace:{kind:"boolean",brief:"Replace the provider registered under the spec's id; its key must be set again",optional:!0},oauth:{kind:"parsed",parse:String,placeholder:"preset",brief:"An OAuth provider: a preset (provider presets names them: github-oauth), a built-in client (google-workspace), or a JSON spec file with auth.kind oauth2-user",optional:!0},"client-id":{kind:"parsed",parse:String,placeholder:"id",brief:"With --oauth: the client id from the provider's console (public); the secret comes from piped NAME=value lines or --from-env",optional:!0},"from-env":{kind:"boolean",brief:"With --oauth: take the client id and secret from the environment variables of their setting names (GITHUB_OAUTH_CLIENT_ID, GITHUB_OAUTH_CLIENT_SECRET); stdin isn't read",optional:!0},...R}},docs:{brief:"Register an API provider from its spec, or an OAuth provider from a preset (--oauth), so apps can list it under capabilities",fullDescription:["The spec says what the provider is and where its key goes: its id, name, the page the key","comes from (docs), the only hosts the key is ever sent to, and how it is sent (auth: bearer,","header, query or basic), naming the Gateway setting that holds the key (STRIPE_API_KEY for","stripe). It never holds the key itself. A URL is fetched on this machine.","","The rules a spec must pass: an id that isn't a built-in provider's, settings named after the","id that no other provider, app or the Gateway itself reads, and public hosts that aren't the","Gateway's own or its apps'. The Gateway checks them again every time it reads the row.","","Next, set the key; the Gateway sends it only to the hosts the row had when it was set:",` ${e} secret set STRIPE_API_KEY`,"","Run in an app's directory, it also writes .everyapp/providers/<id>.json, which everyapp dev","reaches the provider from with your key in .dev.vars.","","An OAuth provider (--oauth) is one people connect their own account to: the Gateway runs","the authorize flow at /connect/<id>, keeps each person's tokens and puts them on the app's","calls. A preset (provider presets) or a spec file with auth.kind oauth2-user becomes a","registered provider; a built-in client (google-workspace, slack, microsoft-365, discord)","takes its client only. The command prints the redirect URI to register at the provider's","console. The client id and secret are set in the same run from piped NAME=value lines or","--from-env (never on the command line), or afterwards:",` ${e} secret set GITHUB_OAUTH_CLIENT_ID GITHUB_OAUTH_CLIENT_SECRET`,"","Examples:",` ${e} provider add stripe.json`,` ${e} provider add https://example.com/providers/stripe.json`,` ${e} provider add stripe.json --replace`,` ${e} provider add --oauth github-oauth`,` printf 'GITHUB_OAUTH_CLIENT_SECRET=%s\\n' "$SECRET" | ${e} provider add --oauth github-oauth --client-id Iv1.abc`,` ${e} provider add --oauth ./acme.json --from-env`].join(`
|
|
38
|
+
`)}}),Ca=$({loader:async()=>{let{presets:t}=await import("./provider-622VM7UZ.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{json:r,verbose:p}},docs:{brief:"List the OAuth presets provider add --oauth takes: GitHub, Notion, Linear and more, and the built-in clients",fullDescription:["Each with its scope sets (what an app lists under scopes) and the console where its client","is made. Nothing is read from the Gateway.","","Example:",` ${e} provider presets`].join(`
|
|
39
|
+
`)}}),Ea=$({loader:async()=>{let{connections:t}=await import("./provider-622VM7UZ.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{all:{kind:"boolean",brief:"Every organization's connections (default: the Gateway's own organization's)",optional:!0},user:{kind:"parsed",parse:String,placeholder:"email",brief:"One person's connections",optional:!0},provider:{kind:"parsed",parse:String,placeholder:"id",brief:"One provider's connections",optional:!0},...R}},docs:{brief:"List the accounts people (and the organization) connected to OAuth providers on the Gateway",fullDescription:["Who connected what, with the scope sets granted, the status and when it was last used.","Never a token.","","Examples:",` ${e} provider connections`,` ${e} provider connections --provider github-oauth`,` ${e} provider connections --user ben@example.com`].join(`
|
|
40
|
+
`)}}),Ta=$({loader:async()=>{let{disconnect:t}=await import("./provider-622VM7UZ.js");return t},parameters:{positional:{kind:"tuple",parameters:[{...q,brief:"The OAuth provider's id: github-oauth"}]},flags:{user:{kind:"parsed",parse:String,placeholder:"email",brief:"This person's connection",optional:!0},organization:{kind:"boolean",brief:"The organization's own connection (the one background work uses)",optional:!0},all:{kind:"boolean",brief:"Every connection to the provider",optional:!0},...R}},docs:{brief:"Remove a person's or the organization's connection to an OAuth provider from the Gateway",fullDescription:['The Gateway drops the tokens it held; apps get "not connected" until the person connects',"again at /connect/<id>. The CLI holds no token, so the grant stays at the provider until it","is revoked there (Admin \u2192 Providers \u2192 Disconnect revokes it from the Gateway).","","Examples:",` ${e} provider disconnect github-oauth --user ben@example.com`,` ${e} provider disconnect github-oauth --organization`,` ${e} provider disconnect github-oauth --all`].join(`
|
|
41
|
+
`)}}),Sa=$({loader:async()=>{let{list:t}=await import("./provider-622VM7UZ.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:R},docs:{brief:"List the API providers the Gateway offers: built in and registered, each key's state, the apps using each",fullDescription:["Nothing is changed. A key's value can't be read back; only whether it is set, and for a","registered provider whether it was set for the hosts the row names now (bound).","","Example:",` ${e} provider list`].join(`
|
|
42
|
+
`)}}),$a=$({loader:async()=>{let{show:t}=await import("./provider-622VM7UZ.js");return t},parameters:{positional:{kind:"tuple",parameters:[q]},flags:{save:{kind:"boolean",brief:"Also write the spec to .everyapp/providers/<id>.json in this app's directory, for everyapp dev",optional:!0},...R}},docs:{brief:"Print a provider's spec: its hosts, how its key is sent, its settings, who registered it and which apps use it",fullDescription:["What an agent reads to set up and call a provider without a setup guide. With --save, in an","app's directory, the spec is written where everyapp dev reads it.","","Examples:",` ${e} provider show stripe`,` ${e} provider show stripe --save`].join(`
|
|
43
|
+
`)}}),Ra=$({loader:async()=>{let{remove:t}=await import("./provider-622VM7UZ.js");return t},parameters:{positional:{kind:"tuple",parameters:[q]},flags:{force:{kind:"boolean",brief:"Remove it even though deployed apps list it (their calls to it stop)",optional:!0},...R}},docs:{brief:"Remove a registered provider from the Gateway; its key stays set until secret unset",fullDescription:["The Gateway stops serving it within 30 seconds. A provider a deployed app lists under","capabilities is refused unless --force. The Gateway setting holding its key stays; remove",`it with ${e} secret unset <NAME>. Registering it again needs the key set again too.`,"","Example:",` ${e} provider remove stripe`].join(`
|
|
44
|
+
`)}}),Qe=t=>$({loader:async()=>{let o=await import("./provider-622VM7UZ.js");return t==="on"?o.on:o.off},parameters:{positional:{kind:"tuple",parameters:[{...q,brief:"The MCP app (mcp list names them): dataforseo"}]},flags:R},docs:{brief:`Same as ${e} mcp ${t}; this alias goes after launch week`}}),et=ka({routes:{add:Aa,list:Sa,show:$a,remove:Ra,presets:Ca,connections:Ea,disconnect:Ta,on:Qe("on"),off:Qe("off")},aliases:{ls:"list",rm:"remove"},docs:{brief:"Register API providers for apps to call with the Gateway's key, and OAuth providers people connect their accounts to",hideRoute:{on:!0,off:!0}}});import{buildCommand as L,buildRouteMap as tt}from"@stricli/core";var P={gateway:h,"account-id":d,json:r,verbose:p},_a=L({loader:async()=>(await import("./ai-UOYQFTAX.js")).show,parameters:{positional:{kind:"tuple",parameters:[]},flags:P},docs:{brief:"What the Gateway's default model provider resolves to now, and why",fullDescription:["The provider and model an app that asks for the default chat model gets (ai: { chat: true }","in its manifest, the SDK's ai()): the stored choice (ai default) if there is one, else the","first provider of the shipped order whose key is set (OpenRouter, Workers AI, OpenAI, Anthropic,","Groq, Mistral, Gemini), else what to set. Reads the Gateway's setting names, never values.","Says whether calls go through Cloudflare AI Gateway (ai gateway on).","","Example:",` ${e} ai show`].join(`
|
|
45
|
+
`)}}),Ga=L({loader:async()=>(await import("./ai-UOYQFTAX.js")).list,parameters:{positional:{kind:"tuple",parameters:[]},flags:P},docs:{brief:"Every provider the default model could be, in order, each with its key set or not",fullDescription:["The shipped order first, then any other AI provider with an OpenAI-shaped chat route; the","one the default resolves to now is marked. An API provider (Stripe) or one without such a","route (Cohere) isn't here: an app pins those under providers.","","Example:",` ${e} ai list`].join(`
|
|
46
|
+
`)}}),Ia=L({loader:async()=>(await import("./ai-UOYQFTAX.js")).setDefault,parameters:{positional:{kind:"tuple",parameters:[{placeholder:"provider[/model]|off",brief:"The provider's id (openrouter), or the id and a model (openrouter/anthropic/claude-sonnet-5.5), or off",parse:String}]},flags:P},docs:{brief:"Choose the default model provider (and model) for every app that asks for one, or off for the shipped order",fullDescription:["The same setting as Manage workspace \u2192 Usage \u2192 AI default. The provider id is everything","up to the first slash, the model everything after it (a model id may hold slashes). Without","a model, the provider's own default model is filled in. A provider whose key isn't set is","accepted with a warning naming the key; one the default can't be (an API provider, an entry","without an OpenAI-shaped chat route, AI Gateway) is refused (AI_DEFAULT_INVALID). The Gateway","reads the change within 30 seconds; a change queues ai.default_changed. Refused on a Gateway","from before the setting (GATEWAY_PREDATES_AI_DEFAULT): run update first.","","Examples:",` ${e} ai default openrouter`,` ${e} ai default openrouter/anthropic/claude-sonnet-5.5`,` ${e} ai default workers-ai --json`,` ${e} ai default off`].join(`
|
|
47
|
+
`)}}),Da=L({loader:async()=>(await import("./ai-UOYQFTAX.js")).gatewayOn,parameters:{positional:{kind:"tuple",parameters:[]},flags:{id:{kind:"parsed",parse:String,brief:"The AI Gateway's id (its name in the dashboard): lowercase letters, digits and single hyphens; everyapp by default",optional:!0,placeholder:"id"},...P}},docs:{brief:"Put Cloudflare AI Gateway in front of every model call: find or make the gateway, set AI_GATEWAY_ID",fullDescription:["Finds the AI Gateway in the Gateway's Cloudflare account (or makes it, logs on, no cache)","and records its id as the Gateway setting AI_GATEWAY_ID. From the Gateway's next request","every call to a model provider that AI Gateway fronts (OpenRouter, OpenAI, Anthropic, Groq,","Mistral, Workers AI) goes through it with the provider's own key still on the call; Gemini","and Cohere go direct. Changes no app and no key. For an authenticated gateway, set its",`token afterwards: ${e} secret set AI_GATEWAY_API_KEY.`,"","Examples:",` ${e} ai gateway on`,` ${e} ai gateway on --id acme-models`].join(`
|
|
48
|
+
`)}}),xa=L({loader:async()=>(await import("./ai-UOYQFTAX.js")).gatewayOff,parameters:{positional:{kind:"tuple",parameters:[]},flags:P},docs:{brief:"Send model calls direct again: unset AI_GATEWAY_ID (the Cloudflare resource stays)",fullDescription:["Unsets AI_GATEWAY_ID on the Gateway; every model call goes direct from its next request.",`The AI Gateway and its logs stay in the account. AI_GATEWAY_API_KEY stays until ${e} secret unset.`,"","Example:",` ${e} ai gateway off`].join(`
|
|
49
|
+
`)}}),Oa=tt({routes:{on:Da,off:xa},docs:{brief:"Cloudflare AI Gateway in front of every model call: on or off"}}),at=tt({routes:{show:_a,list:Ga,default:Ia,gateway:Oa},aliases:{ls:"list"},docs:{brief:"The default model provider apps get when they ask for one, and AI Gateway in front"}});import{buildCommand as ja}from"@stricli/core";var ot=ja({loader:async()=>{let{release:t}=await import("./release-CXEX6O7F.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{out:{kind:"parsed",parse:String,brief:"Where to write the release (default: ./everyapp-release.tar.gz)",placeholder:"file",optional:!0},json:r,verbose:p}},docs:{brief:"Pack the app in this directory as a release others can install",fullDescription:["Builds the app in this directory as a deploy would (tenant-neutral), checks its Build Output","against the app policy and its migrations against its schema, and packs the release","(default ./everyapp-release.tar.gz) without deploying it: no Gateway and no Cloudflare login,","so it runs in CI. Attach the tarball to a GitHub release of the app's repository, and",`${e} install <repository url> installs it on any Gateway.`,"With --json, each step is an NDJSON event; done carries the tarball's path and SHA-256."].join(`
|
|
50
|
+
`)}});import{buildCommand as de,buildRouteMap as La}from"@stricli/core";var nt={kind:"array",minimum:1,parameter:{brief:"Secret or Gateway setting",parse:String,placeholder:"name"}},ce={gateway:h,"account-id":d},st={kind:"parsed",parse:String,brief:"The app whose secret this is (default: the app in this directory)",placeholder:"id",optional:!0},Pa=de({loader:async()=>{let{set:t}=await import("./secret-3LUDEDUW.js");return t},parameters:{positional:nt,flags:{"from-env":{kind:"parsed",parse:String,brief:"Read the value from this environment variable",placeholder:"VAR",optional:!0},app:st,...ce,json:r,verbose:{kind:"boolean",brief:"Show which Worker each secret goes to and its new version",optional:!0}}},docs:{brief:"Set secrets on your app or your Gateway",fullDescription:["Gateway settings (AI provider keys, EMAIL_FROM, sign-in clients) go to the Gateway, from any","directory. Other names go to the app in this directory, or with --app <id> to that app from","anywhere; the app's everyapp.config.ts must list them under secrets. Values come from a","hidden prompt, --from-env or stdin, never the command line. Changes are live at once; no","deploy needed.","","Examples:",` ${e} secret set OPENAI_API_KEY`,` ${e} secret set GITHUB_TOKEN --from-env GITHUB_TOKEN`,` echo "$STRIPE_KEY" | ${e} secret set STRIPE_KEY`,` ${e} secret set MAIN_SECRET --app analytics`,"",`See what an app needs and what is set: ${e} secret list [<app>]`].join(`
|
|
51
|
+
`)}}),Na=de({loader:async()=>{let{unset:t}=await import("./secret-3LUDEDUW.js");return t},parameters:{positional:nt,flags:{yes:{kind:"boolean",brief:"Remove without asking",optional:!0},app:st,...ce,json:{kind:"boolean",brief:"Print NDJSON events on stdout (never asks)",optional:!0},verbose:{kind:"boolean",brief:"Show which Worker each secret is removed from",optional:!0}},aliases:{y:"yes"}},docs:{brief:"Remove secrets from your app or your Gateway",fullDescription:["Names go where `secret set` sends them (--app <id> names the app from anywhere). Asks before","removing; the change is live at once.","","Example:",` ${e} secret unset GITHUB_TOKEN`].join(`
|
|
52
|
+
`)}}),Fa=de({loader:async()=>{let{list:t}=await import("./secret-3LUDEDUW.js");return t},parameters:{positional:{kind:"tuple",parameters:[{brief:"An app id (default: the app in this directory; elsewhere, every app)",parse:String,placeholder:"app",optional:!0}]},flags:{...ce,json:M,verbose:{kind:"boolean",brief:"Also list the names everyapp sets itself",optional:!0}}},docs:{brief:"List what an app needs set and what is: its own secrets and the Gateway's settings",fullDescription:["For one app (the app in this directory, or <app> from anywhere): every setting its manifest","declares, where it is held (the Gateway, or the app's Worker), whether it is set, and the one",`command that opens the app when something required is missing (${e} configure <app>).`,"Elsewhere with no app named: the Gateway's names and who set them, then every app's","settings. Names only, never values."].join(`
|
|
53
|
+
`)}}),rt=La({routes:{set:Pa,unset:Na,list:Fa},docs:{brief:"Set, remove and list secrets and Gateway settings"}});import{buildCommand as Ma}from"@stricli/core";var it=Ma({loader:async()=>{let{setup:t}=await import("./setup-PUD375AM.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{domain:{kind:"parsed",parse:String,brief:"Where the Gateway lives: any hostname under one of the account's domains, e.g. apps.example.com (asked at a terminal; remembered after that)",optional:!0},"account-id":{kind:"parsed",parse:String,brief:"The Cloudflare account of the Gateway, or with none yet, the one to install it in (default: CLOUDFLARE_ACCOUNT_ID, or the only one)",optional:!0},"force-dns":U,"allow-downgrade":{kind:"boolean",brief:"Deploy this Gateway even though it is older than the live one (a deliberate rollback)",optional:!0,hidden:!0},redeploy:{kind:"boolean",brief:"Upload the Gateway even when it is up to date (after a change in the dashboard, such as a key rotation)",optional:!0,hidden:!0},"no-access":{kind:"boolean",brief:"Leave Cloudflare Access off: by default setup puts it in front of the Gateway once the owner exists (asked at a terminal; unattended when the account can). everyapp access off takes it off later",optional:!0},yes:_,json:r,verbose:{kind:"boolean",brief:"Show every step and progress line, and stream the Gateway's build output to stderr",optional:!0}},aliases:{y:"yes"}},docs:{brief:"Install or repair the Gateway",fullDescription:["One command from an empty Cloudflare account (Workers Paid) to a working Gateway and its","owner, and the one to run when something is off. Run it again any time: it picks up where it",`stopped, and does nothing once everything is there. After a git pull, ${e} update takes`,"the newer Gateway from this checkout (setup does that too, on its way).","","A fresh install takes 5 to 20 minutes, most of it waiting for you at the owner link: give it a","long timeout, or run it in the background and watch its output.",""," 1. Logs in to Cloudflare (cf auth login, or CLOUDFLARE_API_TOKEN) and finds the Gateway in"," the login's accounts; with none, picks the account to install it in"," 2. Picks where the Gateway lives (--domain, or asked): any hostname under one of the"," account's domains, apps.example.com; apps get one each below it, todo.apps.example.com"," 3. Installs the Gateway from this checkout (apps/every-app-gateway), or repairs it, and"," waits for its certificate"," 4. Opens a one-time link to create the owner account and waits up to 15 minutes for it;"," in CI there is no link, and the run ends with a warning to run setup at a terminal"," 5. Puts Cloudflare Access in front of the Gateway (asked at a terminal, Yes by default;"," with --yes or --json, done when the account can, else a warning names access on);"," --no-access leaves it off","","The flags people use: --domain, --account-id, and --yes for a script (it answers setup's own","questions; never cf's). With --json each step is an NDJSON event; a run that stops on","something only a person can do exits 2 with action_required.",`Then: ${e} create my-app, cd into it, ${e} dev, ${e} deploy.`,"More: https://everyapp.com/docs/gateway"].join(`
|
|
54
|
+
`)}});import{buildCommand as H,buildRouteMap as Ua}from"@stricli/core";var V={gateway:h,"account-id":d,json:r,verbose:p},he={placeholder:"id",brief:`The sign-in provider: ${ye.join(", ")}`,parse:String},Wa=H({loader:async()=>{let{add:t}=await import("./signin-EP5JLAT5.js");return t},parameters:{positional:{kind:"tuple",parameters:[he]},flags:{"client-id":{kind:"parsed",parse:String,brief:"The OAuth app's client id (not a secret; for apple, the Services ID)",optional:!0},"client-secret-from-env":{kind:"parsed",parse:String,brief:"Read the client secret from this environment variable (a secret never goes on the command line)",placeholder:"VAR",optional:!0},issuer:{kind:"parsed",parse:String,brief:"oidc: the issuer's https URL, which serves /.well-known/openid-configuration",placeholder:"url",optional:!0},label:{kind:"parsed",parse:String,brief:'oidc: the button text after "Continue with" (default SSO; 40 characters at most)',placeholder:"text",optional:!0},tenant:{kind:"parsed",parse:String,brief:"microsoft: the Directory (tenant) ID that pins sign-in to your own directory (recommended), or common, organizations, consumers",optional:!0},...V}},docs:{brief:'Turn a sign-in provider on: "Continue with Google" (or Microsoft, GitHub, Apple, Cloudflare, your SSO)',fullDescription:["Says where to create the OAuth app and the redirect URL to register with it","(https://<gateway>/api/auth/callback/<id>), then sets the provider's settings on the","Gateway Worker, all in one new version under your Cloudflare login, live on the next","request. At a terminal it asks for each setting: the client id shown as typed, the","client secret hidden, an optional one (microsoft's tenant, oidc's label) left as it is","when you press Enter. Unattended (--json, or no terminal) every required setting comes","from a flag: --client-id, --client-secret-from-env VAR, and for oidc --issuer. The","client secret is never taken from the command line.","","A provider says who someone is; the Gateway still decides who gets in: a member, or","someone with a pending invitation for that exact, verified email. Nobody else.","","Safe to repeat: running it again replaces the values given (a rotated secret, a new",`client). An optional setting not given stays as it is; ${e} secret unset <NAME>`,"removes one. The everyapp skill's setup/signin-<id>.md walks through each provider's","console.","","Examples:",` ${e} signin add google`,` ${e} signin add github --client-id Iv1.0123456789abcdef --client-secret-from-env GITHUB_SECRET --json`,` ${e} signin add microsoft --tenant 72f988bf-86f1-41af-91ab-2d7cd011db47`,` ${e} signin add oidc --issuer https://acme.okta.com --label Okta`].join(`
|
|
55
|
+
`)}}),Ya=H({loader:async()=>{let{list:t}=await import("./signin-EP5JLAT5.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:V},docs:{brief:"List the sign-in providers: on, needs setup (naming what is missing) or off",fullDescription:["Reads which of each provider's settings the Gateway Worker holds (names only: a value","can't be read back) and says whether the provider is on (every required setting set),","needs setup (some set, the rest named; the Gateway keeps it off rather than half","configured) or off. A value that is set but malformed also keeps a provider off; the","Gateway's log says so (signin.config_problem). Nothing is changed.","","Example:",` ${e} signin list`].join(`
|
|
56
|
+
`)}}),za=H({loader:async()=>{let{show:t}=await import("./signin-EP5JLAT5.js");return t},parameters:{positional:{kind:"tuple",parameters:[he]},flags:V},docs:{brief:"Show a sign-in provider: where to make its OAuth app, the redirect URL, its settings and whether each is set",fullDescription:["The provider's console and what the OAuth app is called there, the redirect URL to","register for this Gateway, the scopes asked for (identity only), which claim becomes","the email and when it counts as verified, every setting with what it holds and whether","it is set, the provider's caveats and its setup guide. Nothing is changed.","","Example:",` ${e} signin show apple`].join(`
|
|
57
|
+
`)}}),qa=H({loader:async()=>{let{remove:t}=await import("./signin-EP5JLAT5.js");return t},parameters:{positional:{kind:"tuple",parameters:[he]},flags:{yes:_,...V}},docs:{brief:"Turn a sign-in provider off: its settings leave the Gateway; accounts stay",fullDescription:["Asks first (--yes doesn't), then removes every setting of the provider from the Gateway","Worker in one new version: the button leaves the sign-in page on the next request.","People who signed in with it keep their accounts and sign in another way (a password","via Forgot password, another provider, Access). Delete the OAuth app at the provider","too: a client the Gateway no longer holds is still a client.","","Example:",` ${e} signin remove github`].join(`
|
|
58
|
+
`)}}),pt=Ua({routes:{add:Wa,list:Ya,show:za,remove:qa},aliases:{ls:"list"},docs:{brief:"Let people sign in with Google, Microsoft, GitHub, Apple, Cloudflare or your SSO, beside passwords"}});import{buildCommand as Ha}from"@stricli/core";var lt=Ha({loader:async()=>{let{status:t}=await import("./status-LK6DNLCI.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{"account-id":d,json:r,verbose:p}},docs:{brief:"Show the Gateway, its apps and anything to fix",fullDescription:["One screen, all of it from the Gateway's D1 database and cf, nothing asked of the Gateway:","its URL and release (and whether this checkout builds it), its owner, the apps its registry","lists and whether the live Gateway binds them, each hostname's certificate, any deploy in","progress, and what to run when something is off. With --json, the `done` event's data has","all of it, `fixes` included: the one state query an agent needs."].join(`
|
|
59
|
+
`)}});import{buildCommand as Va}from"@stricli/core";var dt=Va({loader:async()=>{let{teardown:t}=await import("./teardown-6RURRSME.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{"account-id":{kind:"parsed",parse:String,placeholder:"id",brief:"The dedicated test account to empty (required; 32 hex characters, from the dashboard URL dash.cloudflare.com/<id>/\u2026; never read from CLOUDFLARE_ACCOUNT_ID)"},confirm:{kind:"parsed",parse:String,placeholder:"id",optional:!0,brief:"The same account id again, for a run without a terminal (--json, a script); at a terminal it is typed instead"},"dry-run":{kind:"boolean",optional:!0,brief:"List what would be deleted and stop; nothing is written"},json:r,verbose:p}},docs:{brief:"Delete everything EveryApp created in a dedicated test Cloudflare account",fullDescription:["For the accounts the onboarding loop installs into, over and over: removes every Worker,","Workflow, D1 database, KV namespace, R2 bucket, Hyperdrive config, queue, Vectorize index,","AI Gateway and Secrets Store secret named every-*, the Gateway's own included, the two","Cloudflare Access applications and the allow policy, the Email Routing rules that send mail","to those Workers (a catch-all drops mail again, and routing is turned off once no rule and no","catch-all of anyone else's needs it), the certificate packs of the hostnames the Gateway","published, and the Custom Domain records (A, AAAA, CNAME) left at exactly those names. Never","the zone, the Workers Paid subscription, the workers.dev subdomain, the Zero Trust team and","its identity providers, a Secrets Store itself, any other DNS record (MX, TXT, CAA...) even","at those names, R2 buckets outside the default jurisdiction, or anything whose name doesn't","start with every- and that no app recorded.","","It is destructive and exists for dedicated test accounts only. The account must be on the","allowlist (EVERYAPP_TEST_ACCOUNTS, or one id per line in ~/.config/everyapp/test-accounts),","the run needs CLOUDFLARE_API_TOKEN scoped to that account alone (a token that sees any other","account is refused), and one account is refused by id whatever the lists say. It reads","everything first and shows what it found; then the account id is typed at the terminal, or","passed again with --confirm for a run without one. There is no --yes.","","Examples:"," EVERYAPP_TEST_ACCOUNTS=<id> everyapp teardown --account-id <id> --dry-run"," EVERYAPP_TEST_ACCOUNTS=<id> everyapp teardown --account-id <id>"," EVERYAPP_TEST_ACCOUNTS=<id> everyapp teardown --account-id <id> --confirm <id> --json"].join(`
|
|
60
|
+
`)}});import{buildCommand as Ka}from"@stricli/core";var ct=Ka({loader:async()=>{let{update:t}=await import("./update-YJFTOZEV.js");return t},parameters:{positional:{kind:"tuple",parameters:[]},flags:{"account-id":d,"force-dns":U,"allow-downgrade":{kind:"boolean",brief:"Deploy this Gateway even though it is older than the live one (a deliberate rollback)",optional:!0,hidden:!0},redeploy:{kind:"boolean",brief:"Upload the Gateway even when it is up to date (after a change in the dashboard, such as a key rotation)",optional:!0,hidden:!0},yes:_,json:r,verbose:p},aliases:{y:"yes"}},docs:{brief:"Update the Gateway to this checkout (after git pull)",fullDescription:["Deploys the Gateway built from this checkout (apps/every-app-gateway) over the one your","Cloudflare login finds, where it is, keeping its data, users and apps. It never installs a",`Gateway: with none, it stops and says to run ${e} setup.`,""," 1. Logs in to Cloudflare (cf auth login, or CLOUDFLARE_API_TOKEN) and finds the Gateway in"," the login's accounts (--account-id when there is one in more than one)"," 2. Upgrades it (migrations first, with a restore point). When it runs this checkout's"," Gateway already, binds and publishes every registered app if the live Gateway doesn't,"," and otherwise says it is up to date. A Gateway newer than this checkout is refused"," (git pull)","","The release is named by its version when this checkout's Gateway is that version's release","(the gateway-v<version> tag), and by the checkout's commit otherwise.","With --json, each step is an NDJSON event."].join(`
|
|
61
|
+
`)}});import{buildCommand as c,buildRouteMap as I}from"@stricli/core";var m={org:F,gateway:h,"account-id":d,json:r,verbose:p},ht={gateway:h,"account-id":d,json:r,verbose:p},Ba=["owner","admin","member"];function Xa(t){let o=Ba.find(a=>a===t.trim().toLowerCase());if(!o)throw new Error("Use owner, admin or member.");return o}var mt=t=>({kind:"boolean",brief:`${t} without asking (needed where nobody is at a terminal)`,optional:!0}),Ja=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;function Za(t){let o=t.trim().toLowerCase();if(!Ja.test(o))throw new Error(`${t} isn't an email address`);return o}var K={placeholder:"email",brief:"The member, by email or user id (workspace users lists them)",parse:String},me={placeholder:"app",brief:"The app, by id (crm) or row id (workspace apps lists them)",parse:String},B={placeholder:"group",brief:"The group, by name or grp_ id (workspace groups lists them)",parse:String},ut={placeholder:"email|id",brief:"The pending invitation, by invited email or id (workspace users lists them)",parse:String},ue=(t,o)=>({add:{kind:"parsed",parse:String,variadic:!0,optional:!0,placeholder:o,brief:`Add ${t} (repeat for several)`},remove:{kind:"parsed",parse:String,variadic:!0,optional:!0,placeholder:o,brief:`Remove ${t} (repeat for several)`},set:{kind:"parsed",parse:String,variadic:!0,optional:!0,placeholder:o,brief:"Replace the whole list with these (repeat for several; alone, with neither --add nor --remove)"}}),Qa=c({loader:async()=>(await import("./workspace-VW7ZZRFP.js")).show,parameters:{positional:{kind:"tuple",parameters:[]},flags:m},docs:{brief:"The organization: its owners, whether it can send mail, and how many members, invitations, groups and apps it has",fullDescription:["Nothing is changed. Email counts as configured when the Gateway settings EMAIL_FROM and a","provider key are set, which is what invitations need to be mailed from the Gateway (this","command prints links instead either way).","",`Example:
|
|
62
|
+
${e} workspace show --json`].join(`
|
|
63
|
+
`)}}),eo=c({loader:async()=>(await import("./workspace-VW7ZZRFP.js")).users,parameters:{positional:{kind:"tuple",parameters:[]},flags:m},docs:{brief:"The members with their role and state, then the pending invitations",fullDescription:["Nothing is changed. A deactivated member is listed as such; a pending invitation with when","it expires.","",`Example:
|
|
64
|
+
${e} workspace users`].join(`
|
|
65
|
+
`)}}),to=c({loader:async()=>(await import("./workspace-VW7ZZRFP.js")).invite,parameters:{positional:{kind:"tuple",parameters:[{placeholder:"email",brief:"The address to invite",parse:Za}]},flags:{role:{kind:"enum",values:["member","admin"],default:"member",brief:"The role they join with"},...m}},docs:{brief:"Invite someone by email and print the link to send them (the Gateway mails nothing from here)",fullDescription:["Makes a pending invitation (72 hours, single use, only for an account with that email) in","your name: your Cloudflare login's email must be a member of the organization. Prints","<gateway>/accept-invitation?token=einv_\u2026, which is the invitation's only secret: hand it to","the person yourself. The Gateway mails invitations only from Admin \u2192 Users.","","Examples:",` ${e} workspace invite ann@example.com`,` ${e} workspace invite ann@example.com --role admin --json`].join(`
|
|
66
|
+
`)}}),ao=c({loader:async()=>(await import("./workspace-VW7ZZRFP.js")).inviteLink,parameters:{positional:{kind:"tuple",parameters:[ut]},flags:m},docs:{brief:"Print a new link for a pending invitation (earlier links keep working until it is used)",fullDescription:["The link's token is new each time and stored only as its hash. Every link of an invitation","stops working once it is accepted, canceled or expired.","",`Example:
|
|
67
|
+
${e} workspace invite-link ann@example.com`].join(`
|
|
68
|
+
`)}}),oo=c({loader:async()=>(await import("./workspace-VW7ZZRFP.js")).uninvite,parameters:{positional:{kind:"tuple",parameters:[ut]},flags:m},docs:{brief:"Cancel a pending invitation: its links stop working",fullDescription:`Example:
|
|
69
|
+
${e} workspace uninvite ann@example.com`}}),no=c({loader:async()=>(await import("./workspace-VW7ZZRFP.js")).deactivate,parameters:{positional:{kind:"tuple",parameters:[K]},flags:m},docs:{brief:"Lock a member out everywhere: no sign-in, every session ended, their tokens and AI connections revoked",fullDescription:["The account stays, listed as deactivated, and the ban holds in every organization it belongs","to; workspace reactivate lifts it (revoked tokens and connections stay revoked). An","organization always keeps an owner who can act, and the ban is account-wide, so the last","live owner of this organization, or of any other they own, can't be deactivated","(LAST_OWNER, naming the organization): a deactivated owner doesn't count.","",`Example:
|
|
70
|
+
${e} workspace deactivate ann@example.com`].join(`
|
|
71
|
+
`)}}),so=c({loader:async()=>(await import("./workspace-VW7ZZRFP.js")).reactivate,parameters:{positional:{kind:"tuple",parameters:[K]},flags:m},docs:{brief:"Lift a deactivation: they can sign in again (revoked tokens and connections stay revoked)",fullDescription:`Example:
|
|
72
|
+
${e} workspace reactivate ann@example.com`}}),ro=c({loader:async()=>(await import("./workspace-VW7ZZRFP.js")).remove,parameters:{positional:{kind:"tuple",parameters:[K]},flags:{yes:mt("Remove"),...m},aliases:{y:"yes"}},docs:{brief:"Remove a member from the organization, and their account when it belongs to no other",fullDescription:["Deletes the membership, their app grants and places in groups, and revokes their personal","access tokens for the organization and AI connections to it, in one write. The account goes","too when it belongs to no other organization (a hosted Gateway keeps accounts). Someone","Cloudflare Access would let straight back in (the Gateway has CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS","or CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN set) is deactivated and kept listed instead, as the","Gateway's own Delete does. Owners are peers, and the organization always keeps one who can","act: the last owner who isn't deactivated can't be removed (LAST_OWNER). Asks first at a","terminal; elsewhere it needs --yes.","",`Example:
|
|
73
|
+
${e} workspace remove ann@example.com --yes --json`].join(`
|
|
74
|
+
`)}}),io=c({loader:async()=>(await import("./workspace-VW7ZZRFP.js")).resetLink,parameters:{positional:{kind:"tuple",parameters:[K]},flags:m},docs:{brief:"Print a one-hour, single-use password-reset link to hand to a member",fullDescription:["Better Auth's own reset token, consumed by the Gateway's /reset-password page: whoever opens","it sets the account's password, so hand it to the person yourself. Only for an active","account (PASSWORD_RESET_REQUIRES_ACTIVE_USER) that belongs to this organization alone","(USER_IN_OTHER_ORGANIZATION: a password is account-wide, so the Gateway's rule holds here","too). Password sign-in must be on (EMAIL_PASSWORD_SIGN_IN) for the page to take it. An","owner's too: the operator is root (the Gateway refuses that to admins and other owners),","which is the way back in for a sole owner who lost their password.","",`Example:
|
|
75
|
+
${e} workspace reset-link ann@example.com`].join(`
|
|
76
|
+
`)}}),po=c({loader:async()=>(await import("./groups-NNTLSXMK.js")).groups,parameters:{positional:{kind:"tuple",parameters:[]},flags:m},docs:{brief:"The groups, with how many members and apps each has",fullDescription:`Nothing is changed.
|
|
69
77
|
|
|
70
78
|
Example:
|
|
71
|
-
${
|
|
72
|
-
${
|
|
73
|
-
`)}}),
|
|
74
|
-
${
|
|
75
|
-
${
|
|
76
|
-
`)}}),
|
|
77
|
-
`)}}),
|
|
78
|
-
`)}}),
|
|
79
|
-
${
|
|
80
|
-
`)}}),
|
|
81
|
-
`)}}),
|
|
82
|
-
`)}});function
|
|
83
|
-
`)}}),
|
|
84
|
-
`)}});function
|
|
85
|
-
${
|
|
86
|
-
`)}});function
|
|
87
|
-
`)}}),
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
${
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
`)}}),go=c({loader:async()=>{let{
|
|
95
|
-
`)}}),
|
|
96
|
-
`)}
|
|
97
|
-
`)}function
|
|
98
|
-
`
|
|
79
|
+
${e} workspace groups`}}),ft={kind:"parsed",parse:String,optional:!0,placeholder:"text",brief:"What the group is for (empty text clears it)"},lo=c({loader:async()=>(await import("./groups-NNTLSXMK.js")).groupCreate,parameters:{positional:{kind:"tuple",parameters:[{placeholder:"name",brief:"The group's name, 1 to 60 characters, unique in the organization",parse:String}]},flags:{description:ft,...m}},docs:{brief:"Make a group: a named set of members that apps are granted to as one",fullDescription:["A member opens an app when they hold a grant to it, or belong to a group that does.","",`Example:
|
|
80
|
+
${e} workspace group create Sales --description "The sales team"`].join(`
|
|
81
|
+
`)}}),co=c({loader:async()=>(await import("./groups-NNTLSXMK.js")).groupSet,parameters:{positional:{kind:"tuple",parameters:[B]},flags:{name:{kind:"parsed",parse:String,optional:!0,placeholder:"name",brief:"A new name"},description:ft,...m}},docs:{brief:"Rename or describe a group",fullDescription:`Example:
|
|
82
|
+
${e} workspace group set Sales --name "Sales and marketing"`}}),ho=c({loader:async()=>(await import("./groups-NNTLSXMK.js")).groupDelete,parameters:{positional:{kind:"tuple",parameters:[B]},flags:{yes:mt("Delete"),...m},aliases:{y:"yes"}},docs:{brief:"Delete a group: what it granted ends with it",fullDescription:["Its members keep their direct grants and their other groups. Asks first at a terminal;","elsewhere it needs --yes.","",`Example:
|
|
83
|
+
${e} workspace group delete Sales --yes`].join(`
|
|
84
|
+
`)}}),mo=c({loader:async()=>(await import("./groups-NNTLSXMK.js")).groupMembers,parameters:{positional:{kind:"tuple",parameters:[B]},flags:{...ue("a member, by email or user id","email"),...m}},docs:{brief:"Who is in a group; --add, --remove or --set change it",fullDescription:["Without a change flag, lists every member of the organization and whether they are in the","group. Only members of the organization can be in its groups.","","Examples:",` ${e} workspace group members Sales`,` ${e} workspace group members Sales --add ann@example.com --add bob@example.com`,` ${e} workspace group members Sales --set ann@example.com`].join(`
|
|
85
|
+
`)}}),uo=c({loader:async()=>(await import("./groups-NNTLSXMK.js")).groupApps,parameters:{positional:{kind:"tuple",parameters:[B]},flags:{...ue("an app, by id","app"),...m}},docs:{brief:"Which apps a group opens; --add, --remove or --set change it",fullDescription:["Without a change flag, lists the organization's own apps and whether the group opens each.","A shared app opens for everyone already and is never granted to a group.","","Examples:",` ${e} workspace group apps Sales`,` ${e} workspace group apps Sales --add crm`].join(`
|
|
86
|
+
`)}}),fo=c({loader:async()=>(await import("./apps-PEOBCDNU.js")).apps,parameters:{positional:{kind:"tuple",parameters:[]},flags:m},docs:{brief:"Every app with who can open it, whether everyone can, its state and what it still needs set",fullDescription:["The admin's view (Admin \u2192 Apps); everyapp status has the operator's. Nothing is changed.","",`Example:
|
|
87
|
+
${e} workspace apps --json`].join(`
|
|
88
|
+
`)}}),go=c({loader:async()=>(await import("./apps-PEOBCDNU.js")).appSet,parameters:{positional:{kind:"tuple",parameters:[me]},flags:{name:{kind:"parsed",parse:Ge,optional:!0,placeholder:"name",brief:"The name the app library shows (1 to 255 characters)"},description:{kind:"parsed",parse:String,optional:!0,placeholder:"text",brief:"The description under it"},everyone:{kind:"enum",values:["on","off"],optional:!0,brief:"Available to everyone: on grants every member now and every future member on joining; off keeps existing access"},...m}},docs:{brief:"Change an app's name, description or whether everyone can open it",fullDescription:["Catalog metadata only: the next deploy sets the name and description again from","everyapp.config.ts.","","Examples:",` ${e} workspace app set crm --everyone on`,` ${e} workspace app set crm --name "Open CRM" --description "Contacts and deals"`].join(`
|
|
89
|
+
`)}}),wo=c({loader:async()=>(await import("./apps-PEOBCDNU.js")).appAccess,parameters:{positional:{kind:"tuple",parameters:[me]},flags:{...ue("a member's direct grant, by email or user id","email"),...m}},docs:{brief:"Who can open an app; --add, --remove or --set change the direct grants",fullDescription:["Without a change flag, lists every member with whether they hold a direct grant and which","groups open the app for them. A change touches direct grants only; what a group grants","stays (workspace group apps). A shared app's access can't be changed.","","Examples:",` ${e} workspace app access crm`,` ${e} workspace app access crm --add ann@example.com`,` ${e} workspace app access crm --set ann@example.com --set bob@example.com --json`].join(`
|
|
90
|
+
`)}});function gt(t){let o=t.trim().toLowerCase();if(o==="off"||o==="none")return"off";if(!/^\d+$/.test(o))throw new Error(`a cap is a whole number of calls per month, or off (not ${t})`);let a=Number(o);if(a<1||a>oe)throw new Error(`a cap is from 1 to ${oe.toLocaleString("en-US")} calls per month`);return a}function yo(t){let o=t.trim().toLowerCase().replace(/^\$/,"");if(o==="off"||o==="none")return"off";if(!/^\d+(\.\d{1,2})?$/.test(o))throw new Error(`a dollar cap is dollars with at most two decimals, or off (not ${t})`);let a=Number(o);if(a<te||a>ae)throw new Error(`a dollar cap is from $${te} to $${ae.toLocaleString("en-US")} a month`);return a}var wt=t=>({usd:{kind:"parsed",parse:yo,optional:!0,placeholder:"dollars|off",brief:t}}),vo=c({loader:async()=>(await import("./apps-PEOBCDNU.js")).appCap,parameters:{positional:{kind:"tuple",parameters:[{...me,brief:"The app, by id or row id: the organization's own, or a shared one"},{placeholder:"n|off",brief:"Provider calls per UTC month (1 to 1,000,000,000), or off for no call cap of its own (the workspace default applies); left out to keep it, and with --unlimited",parse:gt,optional:!0}]},flags:{...wt("Dollars of provider-reported cost per UTC month (0.01 to 1,000,000), or off for no dollar cap of its own; counted only where the provider reports a price (OpenRouter, DataForSEO)"),unlimited:{kind:"boolean",optional:!0,brief:"No cap at all, of either kind, even with workspace defaults (instead of a number, off or --usd)"},...m}},docs:{brief:"Cap an app's provider calls or dollars per month, lift its own caps, or exempt it from the workspace defaults",fullDescription:["An app has caps of its own (a number of calls, --usd dollars, or both), no cap whatever","the workspace defaults (--unlimited), or neither (off, and --usd off): the defaults set","with workspace cap default bind it, and without them it is uncapped. A kind left out","keeps the app's own, so --usd alone keeps the call cap; a cap of either kind ends","--unlimited, the other kind then following its default. The dollar cap counts the cost","a provider reports (OpenRouter, DataForSEO); other calls count toward the call cap","alone. Past either cap that binds it, a provider tool answers a tool error naming it and","an app's brokered call gets 429 app_monthly_cap_exceeded until the next UTC month. Binds","within seconds. --unlimited with a number, off or --usd is refused (INVALID_VALUE); on a","Gateway from before the workspace default, --unlimited is refused","(GATEWAY_PREDATES_DEFAULT_CAPS) and a number or off still work; on one from before dollar","caps, --usd is refused (GATEWAY_PREDATES_COST_CAPS).","","Examples:",` ${e} workspace app cap crm 5000`,` ${e} workspace app cap crm --usd 20`,` ${e} workspace app cap crm off --usd off`,` ${e} workspace app cap crm --unlimited`].join(`
|
|
91
|
+
`)}}),bo=c({loader:async()=>(await import("./apps-PEOBCDNU.js")).capDefault,parameters:{positional:{kind:"tuple",parameters:[{placeholder:"n|off",brief:"Provider calls per UTC month (1 to 1,000,000,000) for every app without its own call cap, or off for no default; left out to keep it",parse:gt,optional:!0}]},flags:{...wt("Dollars of provider-reported cost per UTC month (0.01 to 1,000,000) for every app without its own dollar cap, or off for no dollar default"),...m}},docs:{brief:"Set or clear the workspace default caps: what binds every app without a cap or --unlimited of its own",fullDescription:["The same setting as Manage workspace \u2192 Usage \u2192 Default monthly cap: a number of calls,","--usd dollars of provider-reported cost, or both; a kind left out is kept. An app's own","cap of that kind, or its --unlimited, stays. The dollar cap counts the cost a provider","reports (OpenRouter, DataForSEO); other calls count toward the call cap alone. The","Gateway holds every app without its own to them within 30 seconds; past either, a","provider tool answers a tool error naming the cap and an app's brokered call gets 429","app_monthly_cap_exceeded until the next UTC month. As in the Gateway, the workspace's","first cap makes the built-in Cap alerts subscription, and a default set, raised or","removed queues cap.raised (a lowered one doesn't). The default model provider in the","same row stays. Refused on a Gateway from before the workspace default","(GATEWAY_PREDATES_DEFAULT_CAPS), and --usd on one from before dollar caps","(GATEWAY_PREDATES_COST_CAPS): run update first.","","Examples:",` ${e} workspace cap default 1000`,` ${e} workspace cap default --usd 20`,` ${e} workspace cap default off --usd off --json`].join(`
|
|
92
|
+
`)}});function ko(t){let o=t.trim();if(!Ie.test(o))throw new Error(`a month is written YYYY-MM (not ${t})`);return o}var Ao=c({loader:async()=>(await import("./activity-RTCAUMQS.js")).usage,parameters:{positional:{kind:"tuple",parameters:[]},flags:{month:{kind:"parsed",parse:ko,optional:!0,placeholder:"YYYY-MM",brief:"The UTC month (default: this one)"},...m}},docs:{brief:"What the apps spent in a month: per app (with the cap that binds it), per member and per provider",fullDescription:["Provider calls, failures, tokens and provider-reported cost, counted at the Gateway after a","provider answered, and allowed MCP tool calls from the audit trail. Every callable app is","listed, with zeros in a month it made no call, its own caps (calls and dollars), the caps","that bind it and where they come from (its own, or the workspace default), whether it is","exempt (--unlimited) and whether it is paused this month and by which cap; the workspace","default caps come with it. Nothing is","changed. Refused on a Gateway from before the workspace default","(GATEWAY_PREDATES_DEFAULT_CAPS): run update first.","",`Example:
|
|
93
|
+
${e} workspace usage --month 2026-10 --json`].join(`
|
|
94
|
+
`)}});function yt(t){let o=Date.parse(t.trim());if(Number.isNaN(o))throw new Error(`a time is written like 2026-10-24 or 2026-10-24T09:00:00Z (not ${t})`);return o}function vt(t){let o=Number(t.trim());if(!Number.isInteger(o)||o<1||o>x)throw new Error(`a limit is a whole number from 1 to ${x}`);return o}function Co(t){let o=/^(\d+):(.+)$/.exec(t.trim());if(!o)throw new Error("a cursor is the previous page's nextBefore, written <createdAt>:<id>");return{createdAt:Number(o[1]),id:o[2]}}var Eo=c({loader:async()=>(await import("./activity-RTCAUMQS.js")).activity,parameters:{positional:{kind:"tuple",parameters:[]},flags:{app:{kind:"parsed",parse:String,optional:!0,placeholder:"app",brief:"Calls on this app only, by id or row id"},user:{kind:"parsed",parse:String,optional:!0,placeholder:"email",brief:"Calls by this member only, by email or user id"},decision:{kind:"enum",values:["allowed","blocked"],optional:!0,brief:"Allowed or blocked calls only"},risk:{kind:"enum",values:["read","write","destructive"],optional:!0,brief:"Tools of this risk only"},since:{kind:"parsed",parse:yt,optional:!0,placeholder:"time",brief:"Calls at or after this time (ISO 8601, UTC)"},limit:{kind:"parsed",parse:vt,optional:!0,placeholder:"n",brief:`Rows per page, 1 to ${x} (default 50)`},before:{kind:"parsed",parse:Co,optional:!0,placeholder:"cursor",brief:"The next page: the previous page's nextBefore, as <createdAt>:<id>"},...m}},docs:{brief:"The tool-call audit trail, newest first: who called which tool on which app, and what came of it",fullDescription:["Never the arguments or the result: the trail holds neither. One page at a time; --json","carries data.nextBefore for the next page. Nothing is changed.","","Examples:",` ${e} workspace activity --limit 20`,` ${e} workspace activity --app crm --decision blocked --since 2026-10-24 --json`].join(`
|
|
95
|
+
`)}}),bt={kind:"parsed",parse:String,optional:!0,placeholder:"email",brief:"One member's only, by email or user id"};function To(t){let o=t.trim();if(o.length===0||o.length>xe||!De.test(o))throw new Error(`a type filter is an event type (member.joined), a prefix (member.*, app.crm.*) or * (not ${t})`);return o}function So(t){let o=/^(\d+):(.+)$/.exec(t.trim());if(!o)throw new Error("a cursor is the previous page's nextBefore, written <time>:<id>");return{time:Number(o[1]),id:o[2]}}var $o=c({loader:async()=>(await import("./activity-RTCAUMQS.js")).audit,parameters:{positional:{kind:"tuple",parameters:[]},flags:{actor:{kind:"parsed",parse:String,optional:!0,placeholder:"who",brief:"Events this actor caused: a member by email or user id, an AI connection's or token's id, an app's id, or an operator's email"},type:{kind:"parsed",parse:To,optional:!0,placeholder:"type",brief:"One event type (member.joined), every type under a prefix (member.*, app.crm.*), or * for everything, pings and tool calls included"},since:{kind:"parsed",parse:yt,optional:!0,placeholder:"time",brief:"Events at or after this time (ISO 8601, UTC)"},limit:{kind:"parsed",parse:vt,optional:!0,placeholder:"n",brief:`Rows per page, 1 to ${x} (default 50)`},before:{kind:"parsed",parse:So,optional:!0,placeholder:"cursor",brief:"The next page: the previous page's nextBefore, as <time>:<id>"},...m}},docs:{brief:"The audit log, newest first: every event the Gateway recorded (members, apps, caps, connections, tokens, Access, MCP apps, providers, apps' own events), who did it and what it was about",fullDescription:["The same rows as Admin \u2192 Activity \u2192 Audit and everyapp_workspace_audit, kept 90 days. Each","row is when, who (a member by name, agent \xB7 <AI app>, CLI \xB7 <operator>, app \xB7 <id>, or","Gateway), what (the type in plain words) and the subject; never an event's data, a","secret or a tool's arguments. Test pings and tool calls stay out unless --type names","them (tool.*, *): workspace activity lists the calls. One page at a time; --json carries","data.nextBefore for the next page. Refused on a Gateway from before the audit log","(GATEWAY_OUTDATED): run update first. Nothing is changed.","","Examples:",` ${e} workspace audit --limit 20`,` ${e} workspace audit --actor mia@acme.com --type member.* --since 2026-10-24 --json`].join(`
|
|
96
|
+
`)}}),Ro=c({loader:async()=>(await import("./activity-RTCAUMQS.js")).tokens,parameters:{positional:{kind:"tuple",parameters:[]},flags:{user:bt,all:{kind:"boolean",optional:!0,brief:"Revoked and expired tokens too"},...m}},docs:{brief:"Every member's personal access tokens for the organization (never a token's value)",fullDescription:["Tokens are created in Admin \u2192 Tokens only: their hash is keyed by a Gateway secret the CLI","never holds. Nothing is changed.","",`Example:
|
|
97
|
+
${e} workspace tokens --user ann@example.com`].join(`
|
|
98
|
+
`)}}),_o=c({loader:async()=>(await import("./activity-RTCAUMQS.js")).tokenRevoke,parameters:{positional:{kind:"tuple",parameters:[{placeholder:"id",brief:"The token's id (workspace tokens lists them)",parse:String}]},flags:m},docs:{brief:"Revoke a personal access token: it stops working on its next request",fullDescription:`Example:
|
|
99
|
+
${e} workspace token revoke 3f2a\u2026`}}),Go=c({loader:async()=>(await import("./activity-RTCAUMQS.js")).connections,parameters:{positional:{kind:"tuple",parameters:[]},flags:{user:bt,...m}},docs:{brief:"Every member's AI connections to the organization: which AI app, which apps it may use, read or write",fullDescription:["A connection is an OAuth client (Claude, Cursor, \u2026) a member connected to the Gateway's /mcp.","Nothing is changed.","",`Example:
|
|
100
|
+
${e} workspace connections`].join(`
|
|
101
|
+
`)}}),Io=c({loader:async()=>(await import("./activity-RTCAUMQS.js")).connectionRevoke,parameters:{positional:{kind:"tuple",parameters:[{placeholder:"id",brief:"The connection's id (workspace connections lists them)",parse:String}]},flags:m},docs:{brief:"Revoke an AI connection: the client is out on its next request",fullDescription:`Example:
|
|
102
|
+
${e} workspace connection revoke mcpc_\u2026`}}),Do=I({routes:{create:lo,set:co,delete:ho,members:mo,apps:uo},docs:{brief:"Make, change or delete a group, and set its members and apps"}}),xo=I({routes:{set:go,access:wo,cap:vo},docs:{brief:"Change an app's listing, who can open it, and its monthly cap"}}),Oo=I({routes:{default:bo},docs:{brief:"The workspace default cap on every app's provider calls"}}),jo=I({routes:{revoke:_o},docs:{brief:"Revoke a personal access token"}}),Lo=I({routes:{revoke:Io},docs:{brief:"Revoke an AI connection"}}),Po=c({loader:async()=>{let{rename:t}=await import("./workspace-VW7ZZRFP.js");return t},parameters:{positional:{kind:"tuple",parameters:[{placeholder:"name",brief:"The new name: 1 to 64 characters, no line breaks (quote one with spaces)",parse:String}]},flags:ht},docs:{brief:"Rename the workspace: the name members see in the organization switcher and in invitations",fullDescription:["The workspace is the Gateway's organization: the one the setup claim made, named after","its owner. This gives it the name you want; the same rename is under Manage workspace in","the Gateway, for owners and admins. Nothing is built or deployed: the Gateway reads the","name live, and each member sees it on their next page.","","Before the Gateway is claimed there is no workspace to rename (WORKSPACE_NOT_CLAIMED):","claim it in a browser first.","","Examples:",` ${e} workspace rename 'Acme Corp'`,` ${e} workspace rename 'Acme Corp' --json`].join(`
|
|
103
|
+
`)}}),No=c({loader:async()=>{let{role:t}=await import("./workspace-VW7ZZRFP.js");return t},parameters:{positional:{kind:"tuple",parameters:[{placeholder:"email",brief:"The member's email address, as Manage workspace \u2192 Users lists it",parse:String},{placeholder:"owner|admin|member",brief:"The role to give them",parse:Xa}]},flags:ht},docs:{brief:"Set a member's role: owner, admin or member",fullDescription:["The workspace is the Gateway's own organization, the one its owner claimed. Owners are","peers: any owner can make a member or an admin an owner, and change another owner's","role, from Manage workspace \u2192 Users or with this command under the Cloudflare login.","The workspace always keeps at least one owner, so the last owner's role is never","changed (LAST_OWNER): make someone else an owner first. Deactivated owners don't","count here, so this command can't leave a workspace whose only owner is locked out","(the Gateway's own Users page needs no such rule: a deactivated owner can't act, and","only an owner acts on an owner). Only a member can be given a role; someone still","invited isn't one yet (MEMBER_NOT_FOUND). The Gateway picks up the change within 30","seconds.","","Examples:",` ${e} workspace role sam@example.com owner`,` ${e} workspace role sam@example.com member --json`].join(`
|
|
104
|
+
`)}}),kt=I({routes:{show:Qa,rename:Po,users:eo,role:No,invite:to,"invite-link":ao,uninvite:oo,deactivate:no,reactivate:so,remove:ro,"reset-link":io,groups:po,group:Do,apps:fo,app:xo,cap:Oo,usage:Ao,activity:Eo,audit:$o,tokens:Ro,token:jo,connections:Go,connection:Lo},docs:{brief:"Manage the workspace from the terminal: members, invitations, groups, app access, caps, usage, activity, the audit log, tokens and AI connections"}});var J=Mo({routes:{create:ze,dev:Ke,deploy:Ve,release:ot,db:qe,teardown:dt,login:Je,setup:it,update:ct,install:Xe,configure:Ye,status:lt,delete:He,access:We,signin:pt,secret:rt,provider:et,ai:at,mcp:Ze,email:_e,events:Be,workspace:kt},docs:{brief:"Deploy and run EveryApp apps on your own Cloudflare account."}}),X=J;var At=[["BUILD AN APP",["create","dev","deploy","release","db"]],["RUN A GATEWAY",["login","setup","update","install","configure","status","delete","access","signin","secret","provider","ai","mcp","email","events","teardown"]],["MANAGE THE WORKSPACE",["workspace"]]],Wo={secret:["secret set GITHUB_TOKEN","secret set GITHUB_TOKEN --from-env GH_TOKEN","secret set MAIN_SECRET --app analytics","secret list crm"],email:["email show","email set --sender '*@mail.example.com'","email unset inbound"],events:["events add https://hooks.example.com/everyapp --events cap.*,member.*","events add --email admins --events cap.*","events test sub_\u2026","events deliveries --dead"],access:["access on","access on --email-domain example.com","access off"],signin:["signin list","signin show google","signin add google","signin add github --client-id Iv1.0123456789abcdef --client-secret-from-env GITHUB_SECRET --json","signin remove github"],provider:["provider list","provider add stripe.json","provider add --oauth github-oauth","provider connections"],ai:["ai show","ai default openrouter","ai default openrouter/anthropic/claude-sonnet-5.5","ai gateway on"],mcp:["mcp list","mcp on dataforseo","mcp add https://treg.to/mcp/ --auth bearer","mcp show treg","mcp off treg"],db:["db migrate","db query 'select count(*) from todos'"],workspace:["workspace rename 'Acme Corp'","workspace users","workspace role sam@example.com owner","workspace role sam@example.com member","workspace invite ann@example.com --role admin","workspace app access crm --add ann@example.com","workspace group members Sales --set ann@example.com --set bob@example.com","workspace usage --month 2026-10 --json"]},Yo={email:["Invites, and apps that don't set their own senders, send as the Gateway's sender.",`Set it with: ${e} secret set EMAIL_FROM EMAIL_FROM_NAME`],events:["Each webhook is signed: X-EveryApp-Signature, HMAC-SHA256 over <t>.<body>; verify it with the snippet on /docs/events."],workspace:["Everything Admin \u2192 Users, Groups, Apps, Tokens, Usage and Activity do, from the terminal.","Acts under your Cloudflare login (the operator is root in every organization of the Gateway),","on the install organization unless --org names another by slug, id or name (a name two","organizations share is refused: give the slug). The Gateway mails nothing from here: invite","and reset-link print the link to hand over.",`Depth-two groups have their own help: ${e} workspace group --help, app, token, connection.`]},zo=t=>J.getRoutingTargetForInput(t).brief;function Ct(){let t=Math.max(...At.flatMap(([,a])=>a.map(n=>n.length))),o=(a,n)=>["",b.bold(a),...n.map(i=>` ${i.padEnd(t)} ${zo(i)}`)];return[J.brief,"",b.bold("USAGE"),` ${e} <command> [flags]`,...At.flatMap(([a,n])=>o(a,n)),"",b.bold("FLAGS")," -h, --help Show help for everyapp or a command"," -v, --version Show everyapp's version"," --no-color Print without colors (also NO_COLOR=1)","",b.bold("EXAMPLES"),` $ ${e} setup --domain apps.example.com`,` $ ${e} create todo`,` $ ${e} deploy`,` $ ${e} install https://github.com/<owner>/<repo>`,` $ ${e} configure crm`,"",`Run ${b.bold(`${e} <command> --help`)} for a command's flags.`,""].join(`
|
|
105
|
+
`)}function Et(t){let o=t.filter(l=>l!=="--help"&&l!=="-h");if(o.length!==1||t.length-o.length>1)return null;let{path:a,target:n}=z(X,o);if(a.length!==1||!("getAllEntries"in n))return null;let i=a[0],s=X.getAllEntries().find(l=>l.target===n)?.name.original??i,u=n.getAllEntries().filter(l=>!l.hidden),g=Math.max(...u.map(l=>l.name.original.length)),A=Wo[s]??[],y=Yo[s]??[];return[`${n.brief}.`,...y.length>0?["",...y]:[],"",b.bold("USAGE"),` ${e} ${i} <command> [flags]`,"",b.bold("COMMANDS"),...u.map(l=>` ${l.name.original.padEnd(g)} ${l.target.brief}`),...A.length>0?["",b.bold("EXAMPLES"),...A.map(l=>` $ ${e} ${l}`)]:[],"",`Run ${b.bold(`${e} ${i} <command> --help`)} for its flags.`,""].join(`
|
|
106
|
+
`)}function Tt(){return`${ge} ${Z}
|
|
107
|
+
`}function St({color:t,args:o,report:a}){let n=s=>(a(s),""),i=s=>n({code:"COMMAND_FAILED",message:Ae(s),data:{}});return Fo(J,{name:e,versionInfo:{currentVersion:Z},scanner:{allowArgumentEscapeSequence:!0,caseStyle:"allow-kebab-for-camel"},documentation:{caseStyle:"convert-camel-to-kebab",disableAnsiColor:!t},localization:{loadText:()=>({...Uo,exceptionWhileParsingArguments:s=>n(Ue(X,o,s)),noCommandRegisteredForInput:({input:s})=>n(Me(X,o,s)),exceptionWhileLoadingCommandFunction:i,exceptionWhileRunningCommand:i,commandErrorResult:i})}})}function Vo(t){let o=t.indexOf("--"),a=o<0?t:t.slice(0,o),n=s=>o>=0&&s>o,i=t.filter((s,u)=>s!=="--no-color"||n(u)).map((s,u)=>(s==="--help-all"||s==="-H")&&!n(u)?"--help":s);return{args:i[0]==="help"?[...i.slice(1),"--help"]:i,json:a.includes("--json"),noColor:a.includes("--no-color")}}var{args:k,json:fe,noColor:Rt}=Vo(process.argv.slice(2)),Ko=Date.now();Te({argv:process.argv.slice(2),json:fe});process.on("exit",t=>Se(t,Date.now()-Ko));var _t=Ce(Rt);_t||(qo.level=0);Rt&&(process.env.NO_COLOR="1");var Bo=k.some(t=>t==="--help"||t==="-h"),$t=Ee();if($t){let t=ee(fe);Re(t,$t),process.exitCode=t.exitCode}else if(k.length===0||k.length===1&&Bo)process.stdout.write(Ct());else if(k.length===1&&(k[0]==="--version"||k[0]==="-v"))process.stdout.write(Tt());else{let t=Et(k);t?process.stdout.write(t):await Xo()}async function Xo(){let t,o=St({color:_t,args:k,report:i=>{t??=ee(fe),t.emit({type:"error",retryable:!1,...i})}}),a={stdout:process.stdout,stderr:{write:()=>!0},env:process.env,exitCode:void 0};await Ho(o,k,je(a));let n=$e()??a.exitCode;n!==void 0&&(process.exitCode=n)}
|