@codions/portta 0.0.0-develop.20261104153517.sha-5a14f37 → 0.0.0-develop.20261104154502.sha-e00843e

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/dist/cli.js CHANGED
@@ -95,16 +95,16 @@ _getCommandAndAncestors().forEach(a=>a.emit("afterAllHelp",o))}helpOption(t,n){r
95
95
  return this._helpOption=t,this._initOptionGroup(t),this}help(t){this.outputHelp(t);let n=Number(ne.exitCode??0);n===0&&t&&typeof t!="function"&&t.error&&(n=1),this._exit(n,"commander.help","(outputHelp)")}addHelpText(t,n){let r=["beforeAll","before","after","afterAll"];if(!r.includes(t))throw new Error(`Unexpected value for position to addHelpText.
96
96
  Expecting one of '${r.join("', '")}'`);let o=`${t}Help`;return this.on(o,s=>{let a;typeof n=="function"?a=n({error:s.error,command:s.command}):a=n,a&&s.write(`${a}
97
97
  `)}),this}_outputHelpIfRequested(t){let n=this._getHelpOption();n&&t.find(o=>n.is(o))&&(this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)"))}};function wv(e){return e.map(t=>{if(!t.startsWith("--inspect"))return t;let n,r="127.0.0.1",o="9229",s;return(s=t.match(/^(--inspect(-brk)?)$/))!==null?n=s[1]:(s=t.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null?(n=s[1],/^\d+$/.test(s[3])?o=s[3]:r=s[3]):(s=t.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null&&(n=s[1],r=s[3],
98
- o=s[4]),n&&o!=="0"?`${n}=${r}:${parseInt(o)+1}`:t})}i(wv,"incrementNodeInspectorPort");function Ld(){if(ne.env.NO_COLOR||ne.env.FORCE_COLOR==="0"||ne.env.FORCE_COLOR==="false")return!1;if(ne.env.FORCE_COLOR||ne.env.CLICOLOR_FORCE!==void 0)return!0}i(Ld,"useColor");Md.Command=Nd;Md.useColor=Ld});var _v=N(pt=>{var{Argument:Sv}=Ba(),{Command:zd}=vv(),{CommanderError:N1,InvalidArgumentError:xv}=Es(),{Help:L1}=$d(),{Option:kv}=jd();pt.program=new zd;pt.createCommand=e=>new zd(e);pt.createOption=(e,t)=>new kv(e,t);pt.createArgument=(e,t)=>new Sv(e,t);pt.Command=zd;pt.Option=kv;pt.Argument=Sv;pt.Help=L1;pt.CommanderError=N1;pt.InvalidArgumentError=xv;pt.InvalidOptionArgumentError=xv});var NA=N((rpe,DA)=>{DA.exports=IA;IA.sync=wq;var RA=Me("fs");function yq(e,t){var n=t.pathExt!==void 0?t.pathExt:process.env.PATHEXT;if(!n||(n=n.split(";"),n.indexOf("")!==-1))return!0;for(var r=0;r<n.length;r++){var o=n[r].toLowerCase();if(o&&e.substr(-o.length).toLowerCase()===o)return!0}return!1}i(yq,"checkPathExt");function jA(e,t,n){return!e.isSymbolicLink()&&!e.isFile()?!1:yq(t,n)}i(jA,"checkStat");function IA(e,t,n){RA.stat(e,function(r,o){n(r,r?!1:jA(o,e,t))})}i(IA,"isexe");function wq(e,t){
99
- return jA(RA.statSync(e),e,t)}i(wq,"sync")});var BA=N((spe,FA)=>{FA.exports=MA;MA.sync=vq;var LA=Me("fs");function MA(e,t,n){LA.stat(e,function(r,o){n(r,r?!1:zA(o,t))})}i(MA,"isexe");function vq(e,t){return zA(LA.statSync(e),t)}i(vq,"sync");function zA(e,t){return e.isFile()&&Sq(e,t)}i(zA,"checkStat");function Sq(e,t){var n=e.mode,r=e.uid,o=e.gid,s=t.uid!==void 0?t.uid:process.getuid&&process.getuid(),a=t.gid!==void 0?t.gid:process.getgid&&process.getgid(),c=parseInt("100",8),u=parseInt("010",8),p=parseInt("001",8),d=c|u,f=n&p||n&u&&o===a||
100
- n&c&&r===s||n&d&&s===0;return f}i(Sq,"checkMode")});var qA=N((cpe,UA)=>{var ape=Me("fs"),ol;process.platform==="win32"||global.TESTING_WINDOWS?ol=NA():ol=BA();UA.exports=bh;bh.sync=xq;function bh(e,t,n){if(typeof t=="function"&&(n=t,t={}),!n){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(r,o){bh(e,t||{},function(s,a){s?o(s):r(a)})})}ol(e,t||{},function(r,o){r&&(r.code==="EACCES"||t&&t.ignoreErrors)&&(r=null,o=!1),n(r,o)})}i(bh,"isexe");function xq(e,t){try{return ol.sync(e,t||{})}catch(n){if(t&&
101
- t.ignoreErrors||n.code==="EACCES")return!1;throw n}}i(xq,"sync")});var JA=N((upe,KA)=>{var _o=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",HA=Me("path"),kq=_o?";":":",ZA=qA(),GA=i(e=>Object.assign(new Error(`not found: ${e}`),{code:"ENOENT"}),"getNotFoundError"),WA=i((e,t)=>{let n=t.colon||kq,r=e.match(/\//)||_o&&e.match(/\\/)?[""]:[..._o?[process.cwd()]:[],...(t.path||process.env.PATH||"").split(n)],o=_o?t.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=_o?o.split(n):[""];return _o&&e.indexOf(".")!==-1&&s[0]!==
98
+ o=s[4]),n&&o!=="0"?`${n}=${r}:${parseInt(o)+1}`:t})}i(wv,"incrementNodeInspectorPort");function Ld(){if(ne.env.NO_COLOR||ne.env.FORCE_COLOR==="0"||ne.env.FORCE_COLOR==="false")return!1;if(ne.env.FORCE_COLOR||ne.env.CLICOLOR_FORCE!==void 0)return!0}i(Ld,"useColor");Md.Command=Nd;Md.useColor=Ld});var _v=N(pt=>{var{Argument:Sv}=Ba(),{Command:zd}=vv(),{CommanderError:N1,InvalidArgumentError:xv}=Es(),{Help:L1}=$d(),{Option:kv}=jd();pt.program=new zd;pt.createCommand=e=>new zd(e);pt.createOption=(e,t)=>new kv(e,t);pt.createArgument=(e,t)=>new Sv(e,t);pt.Command=zd;pt.Option=kv;pt.Argument=Sv;pt.Help=L1;pt.CommanderError=N1;pt.InvalidArgumentError=xv;pt.InvalidOptionArgumentError=xv});var NA=N((ope,DA)=>{DA.exports=IA;IA.sync=wq;var RA=Me("fs");function yq(e,t){var n=t.pathExt!==void 0?t.pathExt:process.env.PATHEXT;if(!n||(n=n.split(";"),n.indexOf("")!==-1))return!0;for(var r=0;r<n.length;r++){var o=n[r].toLowerCase();if(o&&e.substr(-o.length).toLowerCase()===o)return!0}return!1}i(yq,"checkPathExt");function jA(e,t,n){return!e.isSymbolicLink()&&!e.isFile()?!1:yq(t,n)}i(jA,"checkStat");function IA(e,t,n){RA.stat(e,function(r,o){n(r,r?!1:jA(o,e,t))})}i(IA,"isexe");function wq(e,t){
99
+ return jA(RA.statSync(e),e,t)}i(wq,"sync")});var BA=N((ipe,FA)=>{FA.exports=MA;MA.sync=vq;var LA=Me("fs");function MA(e,t,n){LA.stat(e,function(r,o){n(r,r?!1:zA(o,t))})}i(MA,"isexe");function vq(e,t){return zA(LA.statSync(e),t)}i(vq,"sync");function zA(e,t){return e.isFile()&&Sq(e,t)}i(zA,"checkStat");function Sq(e,t){var n=e.mode,r=e.uid,o=e.gid,s=t.uid!==void 0?t.uid:process.getuid&&process.getuid(),a=t.gid!==void 0?t.gid:process.getgid&&process.getgid(),c=parseInt("100",8),u=parseInt("010",8),p=parseInt("001",8),d=c|u,f=n&p||n&u&&o===a||
100
+ n&c&&r===s||n&d&&s===0;return f}i(Sq,"checkMode")});var qA=N((lpe,UA)=>{var cpe=Me("fs"),ol;process.platform==="win32"||global.TESTING_WINDOWS?ol=NA():ol=BA();UA.exports=bh;bh.sync=xq;function bh(e,t,n){if(typeof t=="function"&&(n=t,t={}),!n){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(r,o){bh(e,t||{},function(s,a){s?o(s):r(a)})})}ol(e,t||{},function(r,o){r&&(r.code==="EACCES"||t&&t.ignoreErrors)&&(r=null,o=!1),n(r,o)})}i(bh,"isexe");function xq(e,t){try{return ol.sync(e,t||{})}catch(n){if(t&&
101
+ t.ignoreErrors||n.code==="EACCES")return!1;throw n}}i(xq,"sync")});var JA=N((ppe,KA)=>{var _o=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",HA=Me("path"),kq=_o?";":":",ZA=qA(),GA=i(e=>Object.assign(new Error(`not found: ${e}`),{code:"ENOENT"}),"getNotFoundError"),WA=i((e,t)=>{let n=t.colon||kq,r=e.match(/\//)||_o&&e.match(/\\/)?[""]:[..._o?[process.cwd()]:[],...(t.path||process.env.PATH||"").split(n)],o=_o?t.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=_o?o.split(n):[""];return _o&&e.indexOf(".")!==-1&&s[0]!==
102
102
  ""&&s.unshift(""),{pathEnv:r,pathExt:s,pathExtExe:o}},"getPathInfo"),VA=i((e,t,n)=>{typeof t=="function"&&(n=t,t={}),t||(t={});let{pathEnv:r,pathExt:o,pathExtExe:s}=WA(e,t),a=[],c=i(p=>new Promise((d,f)=>{if(p===r.length)return t.all&&a.length?d(a):f(GA(e));let m=r[p],h=/^".*"$/.test(m)?m.slice(1,-1):m,b=HA.join(h,e),g=!h&&/^\.[\\\/]/.test(e)?e.slice(0,2)+b:b;d(u(g,p,0))}),"step"),u=i((p,d,f)=>new Promise((m,h)=>{if(f===o.length)return m(c(d+1));let b=o[f];ZA(p+b,{pathExt:s},(g,y)=>{if(!g&&y)if(t.
103
103
  all)a.push(p+b);else return m(p+b);return m(u(p,d,f+1))})}),"subStep");return n?c(0).then(p=>n(null,p),n):c(0)},"which"),_q=i((e,t)=>{t=t||{};let{pathEnv:n,pathExt:r,pathExtExe:o}=WA(e,t),s=[];for(let a=0;a<n.length;a++){let c=n[a],u=/^".*"$/.test(c)?c.slice(1,-1):c,p=HA.join(u,e),d=!u&&/^\.[\\\/]/.test(e)?e.slice(0,2)+p:p;for(let f=0;f<r.length;f++){let m=d+r[f];try{if(ZA.sync(m,{pathExt:o}))if(t.all)s.push(m);else return m}catch{}}}if(t.all&&s.length)return s;if(t.nothrow)return null;throw GA(
104
- e)},"whichSync");KA.exports=VA;VA.sync=_q});var XA=N((dpe,yh)=>{"use strict";var YA=i((e={})=>{let t=e.env||process.env;return(e.platform||process.platform)!=="win32"?"PATH":Object.keys(t).reverse().find(r=>r.toUpperCase()==="PATH")||"Path"},"pathKey");yh.exports=YA;yh.exports.default=YA});var n0=N((mpe,t0)=>{"use strict";var QA=Me("path"),Pq=JA(),Eq=XA();function e0(e,t){let n=e.options.env||process.env,r=process.cwd(),o=e.options.cwd!=null,s=o&&process.chdir!==void 0&&!process.chdir.disabled;if(s)try{process.chdir(e.options.cwd)}catch{}let a;try{a=Pq.sync(e.command,{path:n[Eq({env:n})],pathExt:t?QA.delimiter:void 0})}catch{}finally{s&&process.chdir(r)}return a&&(a=QA.resolve(o?e.options.cwd:"",a)),a}i(e0,"resolveCommandAttempt");function Aq(e){return e0(e)||e0(e,!0)}i(Aq,"resolv\
105
- eCommand");t0.exports=Aq});var r0=N((gpe,vh)=>{"use strict";var wh=/([()\][%!^"`<>&|;, *?])/g;function Oq(e){return e=e.replace(wh,"^$1"),e}i(Oq,"escapeCommand");function $q(e,t){return e=`${e}`,e=e.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),e=e.replace(/(?=(\\+?)?)\1$/,"$1$1"),e=`"${e}"`,e=e.replace(wh,"^$1"),t&&(e=e.replace(wh,"^$1")),e}i($q,"escapeArgument");vh.exports.command=Oq;vh.exports.argument=$q});var s0=N((ype,o0)=>{"use strict";o0.exports=/^#!(.*)/});var a0=N((wpe,i0)=>{"use strict";var Tq=s0();i0.exports=(e="")=>{let t=e.match(Tq);if(!t)return null;let[n,r]=t[0].replace(/#! ?/,"").split(" "),o=n.split("/").pop();return o==="env"?r:r?`${o} ${r}`:o}});var l0=N((vpe,c0)=>{"use strict";var Sh=Me("fs"),Cq=a0();function Rq(e){let n=Buffer.alloc(150),r;try{r=Sh.openSync(e,"r"),Sh.readSync(r,n,0,150,0),Sh.closeSync(r)}catch{}return Cq(n.toString())}i(Rq,"readShebang");c0.exports=Rq});var f0=N((xpe,d0)=>{"use strict";var jq=Me("path"),u0=n0(),p0=r0(),Iq=l0(),Dq=process.platform==="win32",Nq=/\.(?:com|exe)$/i,Lq=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function Mq(e){e.file=u0(e);let t=e.file&&Iq(e.file);return t?(e.args.unshift(e.file),e.command=t,u0(e)):e.file}i(Mq,"detectShebang");function zq(e){if(!Dq)return e;let t=Mq(e),n=!Nq.test(t);if(e.options.forceShell||n){let r=Lq.test(t);e.command=jq.normalize(e.command),e.command=p0.command(e.command),e.args=e.args.map(s=>p0.argument(
106
- s,r));let o=[e.command].concat(e.args).join(" ");e.args=["/d","/s","/c",`"${o}"`],e.command=process.env.comspec||"cmd.exe",e.options.windowsVerbatimArguments=!0}return e}i(zq,"parseNonShell");function Fq(e,t,n){t&&!Array.isArray(t)&&(n=t,t=null),t=t?t.slice(0):[],n=Object.assign({},n);let r={command:e,args:t,options:n,file:void 0,original:{command:e,args:t}};return n.shell?r:zq(r)}i(Fq,"parse");d0.exports=Fq});var g0=N((_pe,h0)=>{"use strict";var xh=process.platform==="win32";function kh(e,t){return Object.assign(new Error(`${t} ${e.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${t} ${e.command}`,path:e.command,spawnargs:e.args})}i(kh,"notFoundError");function Bq(e,t){if(!xh)return;let n=e.emit;e.emit=function(r,o){if(r==="exit"){let s=m0(o,t);if(s)return n.call(e,"error",s)}return n.apply(e,arguments)}}i(Bq,"hookChildProcess");function m0(e,t){return xh&&e===1&&!t.file?kh(t.original,"spawn"):
107
- null}i(m0,"verifyENOENT");function Uq(e,t){return xh&&e===1&&!t.file?kh(t.original,"spawnSync"):null}i(Uq,"verifyENOENTSync");h0.exports={hookChildProcess:Bq,verifyENOENT:m0,verifyENOENTSync:Uq,notFoundError:kh}});var w0=N((Epe,Po)=>{"use strict";var b0=Me("child_process"),_h=f0(),Ph=g0();function y0(e,t,n){let r=_h(e,t,n),o=b0.spawn(r.command,r.args,r.options);return Ph.hookChildProcess(o,r),o}i(y0,"spawn");function qq(e,t,n){let r=_h(e,t,n),o=b0.spawnSync(r.command,r.args,r.options);return o.error=o.error||Ph.verifyENOENTSync(o.status,r),o}i(qq,"spawnSync");Po.exports=y0;Po.exports.spawn=y0;Po.exports.sync=qq;Po.exports._parse=_h;Po.exports._enoent=Ph});var te=N(Be=>{"use strict";var Fg=Symbol.for("yaml.alias"),kC=Symbol.for("yaml.document"),ru=Symbol.for("yaml.map"),_C=Symbol.for("yaml.pair"),Bg=Symbol.for("yaml.scalar"),ou=Symbol.for("yaml.seq"),gn=Symbol.for("yaml.node.type"),aK=i(e=>!!e&&typeof e=="object"&&e[gn]===Fg,"isAlias"),cK=i(e=>!!e&&typeof e=="object"&&e[gn]===kC,"isDocument"),lK=i(e=>!!e&&typeof e=="object"&&e[gn]===ru,"isMap"),uK=i(e=>!!e&&typeof e=="object"&&e[gn]===_C,"isPair"),PC=i(e=>!!e&&typeof e=="object"&&e[gn]===Bg,"isSca\
104
+ e)},"whichSync");KA.exports=VA;VA.sync=_q});var XA=N((fpe,yh)=>{"use strict";var YA=i((e={})=>{let t=e.env||process.env;return(e.platform||process.platform)!=="win32"?"PATH":Object.keys(t).reverse().find(r=>r.toUpperCase()==="PATH")||"Path"},"pathKey");yh.exports=YA;yh.exports.default=YA});var n0=N((hpe,t0)=>{"use strict";var QA=Me("path"),Pq=JA(),Eq=XA();function e0(e,t){let n=e.options.env||process.env,r=process.cwd(),o=e.options.cwd!=null,s=o&&process.chdir!==void 0&&!process.chdir.disabled;if(s)try{process.chdir(e.options.cwd)}catch{}let a;try{a=Pq.sync(e.command,{path:n[Eq({env:n})],pathExt:t?QA.delimiter:void 0})}catch{}finally{s&&process.chdir(r)}return a&&(a=QA.resolve(o?e.options.cwd:"",a)),a}i(e0,"resolveCommandAttempt");function Aq(e){return e0(e)||e0(e,!0)}i(Aq,"resolv\
105
+ eCommand");t0.exports=Aq});var r0=N((bpe,vh)=>{"use strict";var wh=/([()\][%!^"`<>&|;, *?])/g;function Oq(e){return e=e.replace(wh,"^$1"),e}i(Oq,"escapeCommand");function $q(e,t){return e=`${e}`,e=e.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),e=e.replace(/(?=(\\+?)?)\1$/,"$1$1"),e=`"${e}"`,e=e.replace(wh,"^$1"),t&&(e=e.replace(wh,"^$1")),e}i($q,"escapeArgument");vh.exports.command=Oq;vh.exports.argument=$q});var s0=N((wpe,o0)=>{"use strict";o0.exports=/^#!(.*)/});var a0=N((vpe,i0)=>{"use strict";var Tq=s0();i0.exports=(e="")=>{let t=e.match(Tq);if(!t)return null;let[n,r]=t[0].replace(/#! ?/,"").split(" "),o=n.split("/").pop();return o==="env"?r:r?`${o} ${r}`:o}});var l0=N((Spe,c0)=>{"use strict";var Sh=Me("fs"),Cq=a0();function Rq(e){let n=Buffer.alloc(150),r;try{r=Sh.openSync(e,"r"),Sh.readSync(r,n,0,150,0),Sh.closeSync(r)}catch{}return Cq(n.toString())}i(Rq,"readShebang");c0.exports=Rq});var f0=N((kpe,d0)=>{"use strict";var jq=Me("path"),u0=n0(),p0=r0(),Iq=l0(),Dq=process.platform==="win32",Nq=/\.(?:com|exe)$/i,Lq=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function Mq(e){e.file=u0(e);let t=e.file&&Iq(e.file);return t?(e.args.unshift(e.file),e.command=t,u0(e)):e.file}i(Mq,"detectShebang");function zq(e){if(!Dq)return e;let t=Mq(e),n=!Nq.test(t);if(e.options.forceShell||n){let r=Lq.test(t);e.command=jq.normalize(e.command),e.command=p0.command(e.command),e.args=e.args.map(s=>p0.argument(
106
+ s,r));let o=[e.command].concat(e.args).join(" ");e.args=["/d","/s","/c",`"${o}"`],e.command=process.env.comspec||"cmd.exe",e.options.windowsVerbatimArguments=!0}return e}i(zq,"parseNonShell");function Fq(e,t,n){t&&!Array.isArray(t)&&(n=t,t=null),t=t?t.slice(0):[],n=Object.assign({},n);let r={command:e,args:t,options:n,file:void 0,original:{command:e,args:t}};return n.shell?r:zq(r)}i(Fq,"parse");d0.exports=Fq});var g0=N((Ppe,h0)=>{"use strict";var xh=process.platform==="win32";function kh(e,t){return Object.assign(new Error(`${t} ${e.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${t} ${e.command}`,path:e.command,spawnargs:e.args})}i(kh,"notFoundError");function Bq(e,t){if(!xh)return;let n=e.emit;e.emit=function(r,o){if(r==="exit"){let s=m0(o,t);if(s)return n.call(e,"error",s)}return n.apply(e,arguments)}}i(Bq,"hookChildProcess");function m0(e,t){return xh&&e===1&&!t.file?kh(t.original,"spawn"):
107
+ null}i(m0,"verifyENOENT");function Uq(e,t){return xh&&e===1&&!t.file?kh(t.original,"spawnSync"):null}i(Uq,"verifyENOENTSync");h0.exports={hookChildProcess:Bq,verifyENOENT:m0,verifyENOENTSync:Uq,notFoundError:kh}});var w0=N((Ape,Po)=>{"use strict";var b0=Me("child_process"),_h=f0(),Ph=g0();function y0(e,t,n){let r=_h(e,t,n),o=b0.spawn(r.command,r.args,r.options);return Ph.hookChildProcess(o,r),o}i(y0,"spawn");function qq(e,t,n){let r=_h(e,t,n),o=b0.spawnSync(r.command,r.args,r.options);return o.error=o.error||Ph.verifyENOENTSync(o.status,r),o}i(qq,"spawnSync");Po.exports=y0;Po.exports.spawn=y0;Po.exports.sync=qq;Po.exports._parse=_h;Po.exports._enoent=Ph});var te=N(Be=>{"use strict";var Fg=Symbol.for("yaml.alias"),kC=Symbol.for("yaml.document"),ru=Symbol.for("yaml.map"),_C=Symbol.for("yaml.pair"),Bg=Symbol.for("yaml.scalar"),ou=Symbol.for("yaml.seq"),gn=Symbol.for("yaml.node.type"),aK=i(e=>!!e&&typeof e=="object"&&e[gn]===Fg,"isAlias"),cK=i(e=>!!e&&typeof e=="object"&&e[gn]===kC,"isDocument"),lK=i(e=>!!e&&typeof e=="object"&&e[gn]===ru,"isMap"),uK=i(e=>!!e&&typeof e=="object"&&e[gn]===_C,"isPair"),PC=i(e=>!!e&&typeof e=="object"&&e[gn]===Bg,"isSca\
108
108
  lar"),pK=i(e=>!!e&&typeof e=="object"&&e[gn]===ou,"isSeq");function EC(e){if(e&&typeof e=="object")switch(e[gn]){case ru:case ou:return!0}return!1}i(EC,"isCollection");function dK(e){if(e&&typeof e=="object")switch(e[gn]){case Fg:case ru:case Bg:case ou:return!0}return!1}i(dK,"isNode");var fK=i(e=>(PC(e)||EC(e))&&!!e.anchor,"hasAnchor");Be.ALIAS=Fg;Be.DOC=kC;Be.MAP=ru;Be.NODE_TYPE=gn;Be.PAIR=_C;Be.SCALAR=Bg;Be.SEQ=ou;Be.hasAnchor=fK;Be.isAlias=aK;Be.isCollection=EC;Be.isDocument=cK;Be.isMap=lK;Be.
109
109
  isNode=dK;Be.isPair=uK;Be.isScalar=PC;Be.isSeq=pK});var Ei=N(Ug=>{"use strict";var Te=te(),tt=Symbol("break visit"),AC=Symbol("skip children"),Gt=Symbol("remove node");function su(e,t){let n=OC(t);Te.isDocument(e)?zo(null,e.contents,n,Object.freeze([e]))===Gt&&(e.contents=null):zo(null,e,n,Object.freeze([]))}i(su,"visit");su.BREAK=tt;su.SKIP=AC;su.REMOVE=Gt;function zo(e,t,n,r){let o=$C(e,t,n,r);if(Te.isNode(o)||Te.isPair(o))return TC(e,r,o),zo(e,o,n,r);if(typeof o!="symbol"){if(Te.isCollection(t)){r=Object.freeze(r.concat(t));for(let s=0;s<t.items.
110
110
  length;++s){let a=zo(s,t.items[s],n,r);if(typeof a=="number")s=a-1;else{if(a===tt)return tt;a===Gt&&(t.items.splice(s,1),s-=1)}}}else if(Te.isPair(t)){r=Object.freeze(r.concat(t));let s=zo("key",t.key,n,r);if(s===tt)return tt;s===Gt&&(t.key=null);let a=zo("value",t.value,n,r);if(a===tt)return tt;a===Gt&&(t.value=null)}}return o}i(zo,"visit_");async function iu(e,t){let n=OC(t);Te.isDocument(e)?await Fo(null,e.contents,n,Object.freeze([e]))===Gt&&(e.contents=null):await Fo(null,e,n,Object.freeze(
@@ -402,7 +402,7 @@ this.type==="newline"&&(yield*this.pop())}}};oI.Parser=by});var lI=N(ta=>{"use s
402
402
  Object.assign([],{empty:!0},s.streamInfo())}i(w8,"parseAllDocuments");function cI(e,t={}){let{lineCounter:n,prettyErrors:r}=aI(t),o=new iI.Parser(n?.addNewLine),s=new sI.Composer(t),a=null;for(let c of s.compose(o.parse(e),!0,e.length))if(!a)a=c;else if(a.options.logLevel!=="silent"){a.errors.push(new ea.YAMLParseError(c.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return r&&n&&(a.errors.forEach(ea.prettifyError(e,n)),a.warnings.
403
403
  forEach(ea.prettifyError(e,n))),a}i(cI,"parseDocument");function v8(e,t,n){let r;typeof t=="function"?r=t:n===void 0&&t&&typeof t=="object"&&(n=t);let o=cI(e,n);if(!o)return null;if(o.warnings.forEach(s=>g8.warn(o.options.logLevel,s)),o.errors.length>0){if(o.options.logLevel!=="silent")throw o.errors[0];o.errors=[]}return o.toJS(Object.assign({reviver:r},n))}i(v8,"parse");function S8(e,t,n){let r=null;if(typeof t=="function"||Array.isArray(t)?r=t:n===void 0&&t&&(n=t),typeof n=="string"&&(n=n.length),
404
404
  typeof n=="number"){let o=Math.round(n);n=o<1?void 0:o>8?{indent:8}:{indent:o}}if(e===void 0){let{keepUndefined:o}=n??t??{};if(!o)return}return b8.isDocument(e)&&!r?e.toString(n):new h8.Document(e,r,n).toString(n)}i(S8,"stringify");ta.parse=v8;ta.parseAllDocuments=w8;ta.parseDocument=cI;ta.stringify=S8});var vy=N(se=>{"use strict";var x8=oy(),k8=Gi(),_8=Mb(),wy=Ki(),P8=Ti(),Kn=te(),E8=Hn(),A8=Pe(),O8=Gn(),$8=Wn(),T8=Ju(),C8=my(),R8=gy(),j8=yy(),ep=lI(),uI=Ei();se.Composer=x8.Composer;se.Document=k8.Document;se.Schema=_8.Schema;se.YAMLError=wy.YAMLError;se.YAMLParseError=wy.YAMLParseError;se.YAMLWarning=wy.YAMLWarning;se.Alias=P8.Alias;se.isAlias=Kn.isAlias;se.isCollection=Kn.isCollection;se.isDocument=Kn.isDocument;se.isMap=Kn.isMap;se.isNode=Kn.isNode;se.isPair=Kn.isPair;se.isScalar=Kn.isScalar;
405
- se.isSeq=Kn.isSeq;se.Pair=E8.Pair;se.Scalar=A8.Scalar;se.YAMLMap=O8.YAMLMap;se.YAMLSeq=$8.YAMLSeq;se.CST=T8;se.Lexer=C8.Lexer;se.LineCounter=R8.LineCounter;se.Parser=j8.Parser;se.parse=ep.parse;se.parseAllDocuments=ep.parseAllDocuments;se.parseDocument=ep.parseDocument;se.stringify=ep.stringify;se.visit=uI.visit;se.visitAsync=uI.visitAsync});var Pv=za(_v(),1),{program:rne,createCommand:one,createArgument:sne,createOption:ine,CommanderError:Ev,InvalidArgumentError:ane,InvalidOptionArgumentError:cne,Command:Av,Argument:lne,Option:une,Help:pne}=Pv.default;import{randomBytes as sK}from"node:crypto";import{createHash as ez}from"node:crypto";var As=["search","train","live","preview"],Fd={search:!1,train:!1,live:!1,preview:!1},M1={search:["Googlebot","Bingbot","DuckDuckBot","YandexBot","Baiduspider","Applebot","Slurp"],train:["GPTBot","ClaudeBot","anthropic-ai","CCBot","Google-Extended","Bytespider","Meta-ExternalAgent","Amazonbot","cohere-ai","Diffbot"],live:["ChatGPT-User","OAI-SearchBot","Claude-User","Claude-Web","PerplexityBot","Perplexity-User"],preview:["Slackbot","facebookexternalhit","Twitterbot","WhatsApp","LinkedInBot","Di\
405
+ se.isSeq=Kn.isSeq;se.Pair=E8.Pair;se.Scalar=A8.Scalar;se.YAMLMap=O8.YAMLMap;se.YAMLSeq=$8.YAMLSeq;se.CST=T8;se.Lexer=C8.Lexer;se.LineCounter=R8.LineCounter;se.Parser=j8.Parser;se.parse=ep.parse;se.parseAllDocuments=ep.parseAllDocuments;se.parseDocument=ep.parseDocument;se.stringify=ep.stringify;se.visit=uI.visit;se.visitAsync=uI.visitAsync});var Pv=za(_v(),1),{program:one,createCommand:sne,createArgument:ine,createOption:ane,CommanderError:Ev,InvalidArgumentError:cne,InvalidOptionArgumentError:lne,Command:Av,Argument:une,Option:pne,Help:dne}=Pv.default;import{randomBytes as sK}from"node:crypto";import{createHash as ez}from"node:crypto";var As=["search","train","live","preview"],Fd={search:!1,train:!1,live:!1,preview:!1},M1={search:["Googlebot","Bingbot","DuckDuckBot","YandexBot","Baiduspider","Applebot","Slurp"],train:["GPTBot","ClaudeBot","anthropic-ai","CCBot","Google-Extended","Bytespider","Meta-ExternalAgent","Amazonbot","cohere-ai","Diffbot"],live:["ChatGPT-User","OAI-SearchBot","Claude-User","Claude-Web","PerplexityBot","Perplexity-User"],preview:["Slackbot","facebookexternalhit","Twitterbot","WhatsApp","LinkedInBot","Di\
406
406
  scordbot","TelegramBot"]};function Bd(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("invalid crawler policy");let t=e,n={...Fd};for(let r of Object.keys(t))if(!As.includes(r))throw new Error(`unknown crawler kind: ${r}`);for(let r of As){let o=t[r];if(o!==void 0){if(typeof o!="boolean")throw new Error(`invalid crawler policy: ${r}`);n[r]=o}}return n}i(Bd,"parseCrawlerPolicy");function z1(e){return As.every(t=>e[t])}i(z1,"allowsEveryCrawler");function F1(e){return As.every(t=>!e[t])}
407
407
  i(F1,"blocksEveryCrawler");function Ov(e){return z1(e)?null:F1(e)?`User-agent: *
408
408
  Disallow: /
@@ -428,7 +428,7 @@ function Mv(e,t){return`portta-alias-${e}-${t}`.replace(/[^a-zA-Z0-9-]/g,"-")}i(
428
428
  `)}
429
429
  `;r.push("http:"," routers:");for(let o of e){let s=Mv(o.project,o.service);r.push(` ${s}:`),r.push(` rule: ${wt(`Host(\`${o.host}\`)`)}`),r.push(` entryPoints: [${o.entryPoint}]`),t&&r.push(` middlewares: [${Os}]`),r.push(` service: ${s}`)}r.push(" services:");for(let o of e){let s=Mv(o.project,o.service);r.push(` ${s}:`," loadBalancer:"," servers:"),r.push(` - url: ${wt(`http://${o.container}:${o.port}`)}`)}return r.push(""),r.join(`
430
430
  `)}i(nz,"renderAliases");function $s(e,t,n,r){let o=i(a=>[t,...r?[r]:[]].some(c=>{let u=Ge(c,a.host);return u!==null&&(u.service!==a.service||u.project!==a.project)}),"conflicts"),s=n?e.filter(o):[];return nz(e.filter(a=>!s.includes(a)),n,s)}i($s,"renderAliasesForStore");function Wr(e){if(!e)return[];let t=e.split(`
431
- `).find(n=>n.startsWith(Wd));if(!t)return[];try{let n=JSON.parse(t.slice(Wd.length));return Array.isArray(n)?n.filter(r=>{let o=r;return typeof o?.host=="string"&&typeof o?.container=="string"}):[]}catch{return[]}}i(Wr,"parseAliases");import{createHash as rz,randomBytes as oz}from"node:crypto";import{closeSync as sz,existsSync as Rne,mkdirSync as iz,openSync as az,readFileSync as jne,renameSync as cz,writeSync as lz}from"node:fs";import{dirname as uz,join as pz}from"node:path";var dz="state/panel/applied-env.json";var fz=/(SECRET|TOKEN|AUTHKEY|PASSWORD|PASSWD|CREDENTIAL|PRIVATE_?KEY|API_?KEY|ACCESS_?KEY|_KEY)/i;function mz(e){return fz.test(e)}i(mz,"isSecretKey");function hz(e){return rz("sha256").update(e).digest("hex")}i(hz,"digest");function gz(e,t=new Date){let n={},r={};for(let[o,s]of e)mz(o)?r[o]=hz(s):n[o]=s;return{version:1,appliedAt:t.toISOString(),values:n,secrets:r}}i(gz,"snapshotOf");function qa(e,t){let n=pz(e,dz);iz(uz(n),{recursive:!0});let r=`${n}.${oz(8).toString("hex")}.tmp`,o=az(r,"wx",420);try{lz(o,`${JSON.stringify(gz(t),null,2)}
431
+ `).find(n=>n.startsWith(Wd));if(!t)return[];try{let n=JSON.parse(t.slice(Wd.length));return Array.isArray(n)?n.filter(r=>{let o=r;return typeof o?.host=="string"&&typeof o?.container=="string"}):[]}catch{return[]}}i(Wr,"parseAliases");import{createHash as rz,randomBytes as oz}from"node:crypto";import{closeSync as sz,existsSync as jne,mkdirSync as iz,openSync as az,readFileSync as Ine,renameSync as cz,writeSync as lz}from"node:fs";import{dirname as uz,join as pz}from"node:path";var dz="state/panel/applied-env.json";var fz=/(SECRET|TOKEN|AUTHKEY|PASSWORD|PASSWD|CREDENTIAL|PRIVATE_?KEY|API_?KEY|ACCESS_?KEY|_KEY)/i;function mz(e){return fz.test(e)}i(mz,"isSecretKey");function hz(e){return rz("sha256").update(e).digest("hex")}i(hz,"digest");function gz(e,t=new Date){let n={},r={};for(let[o,s]of e)mz(o)?r[o]=hz(s):n[o]=s;return{version:1,appliedAt:t.toISOString(),values:n,secrets:r}}i(gz,"snapshotOf");function qa(e,t){let n=pz(e,dz);iz(uz(n),{recursive:!0});let r=`${n}.${oz(8).toString("hex")}.tmp`,o=az(r,"wx",420);try{lz(o,`${JSON.stringify(gz(t),null,2)}
432
432
  `)}finally{sz(o)}cz(r,n)}i(qa,"writeApplied");var bz=/^[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?$/;function yz(e){let t=e.trim();if(!bz.test(t))throw new Error(`invalid Portta release version '${t||"<empty>"}'`);return t}i(yz,"assertReleaseVersion");function Se(e){let t=yz(e);return{runtime:`codions-labs/portta:${t}`,apply:`codions-labs/portta-apply:${t}`,toolbox:`codions-labs/portta-toolbox:${t}`}}i(Se,"porttaImages");var Ts="portta-apply",wz="apply";function zv(e,t,n){return["create","--name",Ts,"--label","portta.managed=true","--label",`portta.component=${wz}`,"--label",`portta.apply.spec=${t}`,"--label","traefik.enable=false","--restart","no","--network","none","--user","0:0","--security-opt","no-new-privileges:true","--workdir",e,"--env",`PORTTA_ROOT=${e}`,"--env","HOME=/tmp","--volume","/var/run/docker.sock:/var/run/docker.sock","--volume",`${e}:${e}`,Se(n).apply,"node",`${e}/bin/portta`,"up"]}i(zv,"appl\
433
433
  yCreateArguments");function Fv(e,t){return`${Se(t).apply}|${e}|${t}`}i(Fv,"applySpec");function Bv(e){return(e.PORTTA_WEB_EXPOSE??"local")==="public"?"the panel is exposed publicly: apply on the host instead":(e.PORTTA_PROFILE??"local")==="remote-public"?"the remote-public profile applies on the host only":null}i(Bv,"applyRefusal");var Uv=["auth.login","auth.logout","auth.login_failed","user.created","user.deleted","user.role_changed","user.banned","user.unbanned","user.password_set","user.password_changed","user.ownership_transferred","user.two_factor_enabled","user.two_factor_disabled","user.sessions_revoked","project_access.granted","project_access.revoked","token.created","token.revoked","project.created","project.updated","project.tagged","project_file.read","project.deleted","environment.started","environment.stopped",
434
434
  "environment.restarted","environment.rebuilt","environment.destroyed","environment.forgotten","service.restarted","container.operated","container.destroyed","access.bridge_opened","access.bridge_closed","protection.created","protection.rotated","protection.opened","protection.removed","share.created","share.revoked","gateway.applied","settings.changed","crawlers.changed","settings.discarded","database.migrated","container.console_opened","container.console_closed"];function We(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}i(We,"slug");function Vr(e,t){return(t?`${We(e)}-${We(t)}`:We(e)).slice(0,52).replace(/-$/,"")||"project"}i(Vr,"composeNamespace");function Ha(e){return["main","master","develop","development"].includes(e)?null:We(e)}i(Ha,"branchSuffix");var vz=63,Sz="--";function xz(e){let t=2166136261;for(let n=0;n<e.length;n+=1)t^=e.charCodeAt(n),t=Math.imul(t,16777619)>>>0;return t.toString(36).padStart(6,"0").slice(-6)}i(xz,"shortHash");function kz(e,t=vz){if(e.length<=t)return e;let n=xz(e),r=t-n.length-1;return`${e.slice(0,r).replace(/-+$/,"")}-${n}`}i(kz,"fitLabel");function Cs(e){let t=We(e.project),n=We(e.service),r=e.context?We(e.context):"",o=n?`${t}-${n}`:t;return kz(r?`${o}${Sz}${r}`:o)}i(Cs,"hostLabel");var Za=["local","auto","custom"];function Vd(e){return Za.includes(e)}i(Vd,"isDomainMode");var Kd=["sslip.io","nip.io"];function Jd(e){return Kd.includes(e)}i(Jd,"isAutoDomainProvider");var _z=/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/;function Pz(e){return _z.test(e)}i(Pz,"isIpv4");function Ga(e,t="sslip.io"){return Pz(e)?`${e.replace(/\./g,"-")}.${t}`:null}i(Ga,"autoDomainFor");function qv(e){let t=Vd(e.mode)?e.mode:"local",n=e.configured?.trim()||null;if(t==="custom")return n?{mode:t,domain:n,problem:null}:{mode:t,domain:"localhost",problem:"domain mode is custom and no domain is set"};if(t==="auto"){let r=e.provider&&Jd(e.provider)?e.provider:"sslip.io",o=e.publicIp?.trim()||null;if(!o)return{mode:t,domain:"localhost",problem:"domain mode is auto and no public address has been detected"};let s=Ga(o,r);return s?{mode:t,domain:s,problem:null}:{mode:t,domain:"localhost",
@@ -483,7 +483,7 @@ return null;let{Volumes:r,Containers:o}=n,s=new Map,a=i(c=>{let u=s.get(c)??{com
483
483
  r?100:c.startsWith(r)?90:c.includes(r)?80:d?60:u.includes(r)?40:20,h=m<80?d?.id??null:null,b=p.indexOf(r),g=m>=40?s.description:p.slice(Math.max(0,b-60),Math.max(0,b-60)+220);return[{order:a,score:m,hit:{slug:s.slug,title:s.title,description:s.description,audience:s.audience,section:s.section,category:s.category,url:`${s.url}${h?`#${h}`:""}`,anchor:h,excerpt:g}}]}).sort((s,a)=>a.score-s.score||s.order-a.order).slice(0,Math.min(50,Math.max(1,n.limit??10))).map(({hit:s})=>s)}i(AS,"searchDocumentat\
484
484
  ion");function OS(e,t,n){let r=e.pages.find(c=>c.slug===(e.aliases[t]??t));if(!r||!n)return r;let o=r.headings.findIndex(c=>c.id===n),s=r.headings[o];if(!s)return;let a=r.headings.slice(o+1).find(c=>c.level<=s.level);return{...r,url:`${r.url}#${n}`,markdown:r.markdown.split(`
485
485
  `).slice(s.line,a?.line).join(`
486
- `),headings:r.headings.filter(c=>c.line>=s.line&&(!a||c.line<a.line))}}i(OS,"getDocumentationPage");function $S(e,t="all"){return{identity:e.identity,groups:e.groups.filter(n=>t==="all"||n.audience===t),pages:e.pages.filter(n=>t==="all"||n.audience===t).map(({markdown:n,text:r,headings:o,...s})=>s)}}i($S,"documentationNavigation");import{randomBytes as tF}from"node:crypto";import{accessSync as Ire,chmodSync as af,constants as Dre,copyFileSync as TS,existsSync as js,mkdirSync as CS,readFileSync as RS,rmdirSync as nF,unlinkSync as rF,writeFileSync as oF}from"node:fs";import{dirname as Xa,join as Is}from"node:path";var sF=/^[A-Za-z_][A-Za-z0-9_]*$/,En=/^([ \t]*(?:export[ \t]+)?([A-Za-z_][A-Za-z0-9_]*)[ \t]*=[ \t]*)(.*)$/;function jS(e){let t=e[0]==='"'||e[0]==="'"?e[0]:"";if(t){let r=1;for(;r<e.length;r++){if(e[r]==="\\"&&(e[r+1]===t||t==='"'&&e[r+1]==="\\")){r++;continue}if(e[r]===t)break}if(r===e.length||!/^[ \t]*(?:#.*)?$/.test(e.slice(r+1)))throw new Error("invalid quoted .env value");return{value:t==="'"?e.slice(1,r).replace(/\\'/g,"'"):e.slice(1,r).replace(/\\(["\\$nrt])/g,(s,a)=>({n:`
486
+ `),headings:r.headings.filter(c=>c.line>=s.line&&(!a||c.line<a.line))}}i(OS,"getDocumentationPage");function $S(e,t="all"){return{identity:e.identity,groups:e.groups.filter(n=>t==="all"||n.audience===t),pages:e.pages.filter(n=>t==="all"||n.audience===t).map(({markdown:n,text:r,headings:o,...s})=>s)}}i($S,"documentationNavigation");import{randomBytes as tF}from"node:crypto";import{accessSync as Dre,chmodSync as af,constants as Nre,copyFileSync as TS,existsSync as js,mkdirSync as CS,readFileSync as RS,rmdirSync as nF,unlinkSync as rF,writeFileSync as oF}from"node:fs";import{dirname as Xa,join as Is}from"node:path";var sF=/^[A-Za-z_][A-Za-z0-9_]*$/,En=/^([ \t]*(?:export[ \t]+)?([A-Za-z_][A-Za-z0-9_]*)[ \t]*=[ \t]*)(.*)$/;function jS(e){let t=e[0]==='"'||e[0]==="'"?e[0]:"";if(t){let r=1;for(;r<e.length;r++){if(e[r]==="\\"&&(e[r+1]===t||t==='"'&&e[r+1]==="\\")){r++;continue}if(e[r]===t)break}if(r===e.length||!/^[ \t]*(?:#.*)?$/.test(e.slice(r+1)))throw new Error("invalid quoted .env value");return{value:t==="'"?e.slice(1,r).replace(/\\'/g,"'"):e.slice(1,r).replace(/\\(["\\$nrt])/g,(s,a)=>({n:`
487
487
  `,r:"\r",t:" "})[a]??a).replace(/\$\$/g,"$"),suffix:e.slice(r+1),quote:t}}let n=/^(.*?)([ \t]+#.*|[ \t]*)$/.exec(e);return{value:n[1],suffix:n[2],quote:""}}i(jS,"parts");function me(e){let t=new Map;for(let n of e.split(/\r?\n/)){let r=En.exec(n);if(!r)continue;let o=r[2];if(t.has(o))throw new Error(`duplicate .env key: ${o}`);t.set(o,jS(r[3]).value)}return t}i(me,"parseEnv");function cf(e,t=""){return e.includes("\\")||t==='"'?`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\$/g,()=>"$\
488
488
  $")}"`:t==="'"||/[$\s#'"\\]/.test(e)?`'${e.replace(/'/g,"\\'")}'`:e}i(cf,"encode");function Ya(e,t,n,r=""){if(!sF.test(t))throw new Error(`refusing to write invalid .env key: ${t}`);if(/[\n\r]/.test(n))throw new Error(`refusing to write a multi-line value for ${t}`);let o=me(e);if(o.get(t)===n&&o.has(t))return e;let s=e.includes(`\r
489
489
  `)?`\r
@@ -518,7 +518,7 @@ oundaries.","docs/product/guides/firewall.md"))}if(t.platform==="darwin")r.push(
518
518
  ct/concepts/security.md"));else if(e.fail2ban.state==="absent")r.push(on("security.fail2ban","info","Fail2ban","not installed",n?"Rate-limiting repeated SSH authentication failures is recommended on publicly exposed servers.":"This is optional on an isolated local machine.","docs/product/concepts/security.md"));else{let o=e.fail2ban.active===!0&&e.fail2ban.sshdJail===!0;r.push(on("security.fail2ban",o?"pass":n?"warn":"info","Fail2ban",`unit ${e.fail2ban.active?"active":"inactive or unknown"}; ss\
519
519
  hd jail ${e.fail2ban.sshdJail?"present":"absent or unknown"}`,"The sshd jail limits repeated authentication attempts without changing the SSH server policy.","docs/product/concepts/security.md"))}return r}i(VS,"securityVerdicts");function eo(e,t,n="http"){return e.flatMap(r=>{if(!zt(r.labels)||Qa(r.labels))return[];let o=Object.entries(r.labels),s=r.labels["com.docker.compose.project"]||null,a=r.labels["com.docker.compose.service"]||null,c=tc(r.labels),u=c.hosts[0];if(!c.usesDefaultRule&&!u)return[];let p=u||(s?`${We(s)}-${We(a||r.name)}.${t}`:`${We(r.name)}.${t}`),d=o.find(([f])=>/^traefik\.http\.services\..*\.loadbalancer\.server\.port$/.test(f))?.[1]||"auto";return[{project:s,service:a,container:r.name,hostname:p,url:`${n}\
520
520
  ://${p}`,port:d,state:r.state}]}).sort((r,o)=>r.hostname.localeCompare(o.hostname))}i(eo,"routesFor");function Ns(e,t,n="http"){let r=eo(e,t,n),o=new Map;for(let s of e){let a=s.labels["com.docker.compose.project"];if(!a)continue;let c=o.get(a)??[];c.push(s),o.set(a,c)}return[...o.entries()].map(([s,a])=>({name:s,state:a.some(c=>c.state==="running")?"running":"stopped",services:a.sort((c,u)=>(c.labels["com.docker.compose.service"]||c.name).localeCompare(u.labels["com.docker.compose.service"]||u.
521
- name)),urls:r.filter(c=>c.project===s)})).sort((s,a)=>s.name.localeCompare(a.name))}i(Ns,"projectsFor");import{scrypt as kF,randomBytes as _F,randomInt as aoe,timingSafeEqual as coe}from"node:crypto";var PF="$portta$scrypt$",KS=65536,JS=8,YS=1,EF=32,AF=96*1024*1024;function OF(e,t,n,r){return new Promise((o,s)=>{kF(e,t,n,r,(a,c)=>{a?s(a):o(c)})})}i(OF,"scryptPassword");async function XS(e){let t=_F(16),n=await OF(e,t,EF,{N:KS,r:JS,p:YS,maxmem:AF});return`${PF}${KS}$${JS}$${YS}$${t.toString("base64url")}$${n.toString("base64url")}`}i(XS,"hashPassword");var Z={};xd(Z,{BIGINT_FORMAT_RANGES:()=>ac,CONSTANT_CATCH:()=>lx,Class:()=>hf,NUMBER_FORMAT_RANGES:()=>Ms,aborted:()=>st,allowsEval:()=>Sf,assert:()=>jF,assertEqual:()=>$F,assertIs:()=>CF,assertNever:()=>RF,assertNotEqual:()=>TF,assignProp:()=>Xe,attachSchema:()=>zs,base64ToUint8Array:()=>ax,base64urlToUint8Array:()=>XF,cached:()=>oo,captureStackTrace:()=>sc,cleanEnum:()=>YF,cleanRegex:()=>Ls,clone:()=>ft,cloneDef:()=>NF,codePointLength:()=>Fs,constantCatch:()=>ux,createTransparentProxy:()=>UF,defineLazy:()=>yf,
521
+ name)),urls:r.filter(c=>c.project===s)})).sort((s,a)=>s.name.localeCompare(a.name))}i(Ns,"projectsFor");import{scrypt as kF,randomBytes as _F,randomInt as coe,timingSafeEqual as loe}from"node:crypto";var PF="$portta$scrypt$",KS=65536,JS=8,YS=1,EF=32,AF=96*1024*1024;function OF(e,t,n,r){return new Promise((o,s)=>{kF(e,t,n,r,(a,c)=>{a?s(a):o(c)})})}i(OF,"scryptPassword");async function XS(e){let t=_F(16),n=await OF(e,t,EF,{N:KS,r:JS,p:YS,maxmem:AF});return`${PF}${KS}$${JS}$${YS}$${t.toString("base64url")}$${n.toString("base64url")}`}i(XS,"hashPassword");var Z={};xd(Z,{BIGINT_FORMAT_RANGES:()=>ac,CONSTANT_CATCH:()=>lx,Class:()=>hf,NUMBER_FORMAT_RANGES:()=>Ms,aborted:()=>st,allowsEval:()=>Sf,assert:()=>jF,assertEqual:()=>$F,assertIs:()=>CF,assertNever:()=>RF,assertNotEqual:()=>TF,assignProp:()=>Xe,attachSchema:()=>zs,base64ToUint8Array:()=>ax,base64urlToUint8Array:()=>XF,cached:()=>oo,captureStackTrace:()=>sc,cleanEnum:()=>YF,cleanRegex:()=>Ls,clone:()=>ft,cloneDef:()=>NF,codePointLength:()=>Fs,constantCatch:()=>ux,createTransparentProxy:()=>UF,defineLazy:()=>yf,
522
522
  defineLazyInternal:()=>Q,derived:()=>nB,esc:()=>wf,escapeRegex:()=>cn,explicitlyAborted:()=>_f,extend:()=>ZF,finalizeIssue:()=>_t,floatSafeRemainder:()=>bf,getElementAtPath:()=>LF,getEnumValues:()=>no,getLengthableOrigin:()=>Bs,getParsedType:()=>BF,getSizableOrigin:()=>ix,hexToUint8Array:()=>eB,hide:()=>uc,installLazyProp:()=>iB,isObject:()=>ur,isPlainObject:()=>Cn,issue:()=>io,joinValues:()=>oc,jsonStringifyReplacer:()=>ro,members:()=>Ef,merge:()=>WF,mergeDefs:()=>an,normalizeParams:()=>B,nullish:()=>gf,
523
523
  numKeys:()=>FF,objectClone:()=>IF,omit:()=>HF,optionalKeys:()=>kf,own:()=>Tn,parsedType:()=>Pf,partial:()=>VF,pick:()=>qF,prefixIssues:()=>kt,primitiveTypes:()=>ox,promiseAllObject:()=>MF,propertyKeyTypes:()=>xf,randomString:()=>zF,rawShape:()=>so,required:()=>KF,safeExtend:()=>GF,shallowClone:()=>rx,sizeCaps:()=>lc,slugify:()=>vf,stringifyPrimitive:()=>ic,toZod:()=>ex,uint8ArrayToBase64:()=>cx,uint8ArrayToBase64url:()=>QF,uint8ArrayToHex:()=>tB,unwrapMessage:()=>to});function $F(e){return e}i($F,"assertEqual");function TF(e){return e}i(TF,"assertNotEqual");function ex(){return e=>e}i(ex,"toZod");function CF(e){}i(CF,"assertIs");function RF(e){throw new Error("Unexpected value in exhaustive check")}i(RF,"assertNever");function jF(e){}i(jF,"assert");function no(e){let t=Object.values(e).filter(r=>typeof r=="number");return Object.entries(e).filter(([r,o])=>t.indexOf(+r)===-1).map(([r,o])=>o)}i(no,"getEnumValues");function oc(e,t="|"){return e.map(n=>ic(n)).join(
524
524
  t)}i(oc,"joinValues");function ro(e,t){return typeof t=="bigint"?t.toString():t}i(ro,"jsonStringifyReplacer");var mf=class{static{i(this,"Cached")}constructor(t){this._getter=t,this._value=void 0}get value(){let t=this._getter;return t!==void 0&&(this._value=t(),this._getter=void 0),this._value}};function oo(e){return new mf(e)}i(oo,"cached");function gf(e){return e==null}i(gf,"nullish");function Ls(e){let t=e.startsWith("^")?1:0,n=e.endsWith("$")?e.length-1:e.length;return e.slice(t,n)}i(Ls,"cl\
@@ -550,7 +550,7 @@ get(){return this==null?n:Tn(this,t,n.bind(this))},set(r){Tn(this,t,r)}})}i(rB,"
550
550
  enumerable:r,value:s})}})}i(iB,"installLazyProp");var lx="~constantCatch";function ux(e){let t=i(()=>e,"fn");return t[lx]=!0,t}i(ux,"constantCatch");var px,Of=Object.freeze({status:"aborted"}),Af={value:void 0,enumerable:!1},dx="captureStackTrace"in Error?Error:null;function aB(e){let t=dx;if(t){let n=t.stackTraceLimit;if(typeof n=="number"){try{t.stackTraceLimit=0}catch{return dx=null,new e}try{return new e}finally{t.stackTraceLimit=n}}}return new e}i(aB,"newError");function k(e,t,n,r){let o={};function s(m){this.def=m,this.constr=f,this.traits=new Set}i(s,"Internals"),s.prototype=o;let a=n,c=a&&new WeakSet;function u(m,h){if(m._zod){if(m._zod.
551
551
  traits.has(e))return}else{Af.value=new s(h);try{Object.defineProperty(m,"_zod",Af)}finally{Af.value=void 0}}if(m._zod.traits.add(e),t(m,h),c){let g=Object.getPrototypeOf(m),y=m._zod.constr.prototype,w=g;for(;w&&w!==y;)w=Object.getPrototypeOf(w);let P=w??g;c.has(P)||(c.add(P),Ef(P,a))}let b=f.prototype;for(let g in b)Object.prototype.hasOwnProperty.call(b,g)&&(g in m||(m[g]=b[g].bind(m)))}i(u,"init");let p=r?.Parent??Object;class d extends p{static{i(this,"Definition")}}Object.defineProperty(d,"n\
552
552
  ame",{value:e});function f(m){let h=r?.Parent?aB(d):this;u(h,m);let b=h._zod.deferred;if(b){for(let y of b)y();h._zod.deferred=void 0}let g=globalThis.__zod_globalConfig?.postProcessor;return g&&g(h),h}return i(f,"_"),Object.defineProperty(f,"init",{value:u}),Object.defineProperty(f,Symbol.hasInstance,{value:i(m=>r?.Parent&&m instanceof r.Parent?!0:m?._zod?.traits?.has(e),"value")}),Object.defineProperty(f,"name",{value:e}),f}i(k,"$constructor");var Pt=class extends Error{static{i(this,"$ZodAsyncError")}constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}},ao=class extends Error{static{i(this,"$ZodEncodeError")}constructor(t){super(`Encountered unidirectional transform during encode: ${t}`),this.name="ZodEncodeError"}};(px=globalThis).__zod_globalConfig??(px.__zod_globalConfig={});var Je=globalThis.__zod_globalConfig;function Qe(e){return e&&Object.assign(Je,e),Je}i(Qe,"config");function cB(){let e=this._zod;return e.message??(e.message=JSON.stringify(e.def,ro,2)),e.message}i(cB,"_getMessage");function lB(e){this._zod.message=e}i(lB,"_setMessage");var uB={get:cB,set:lB,enumerable:!0,configurable:!0},Tf={value:void 0,enumerable:!1},fx=new WeakSet([Object.prototype,Error.prototype]),mx=i((e,t)=>{e.name="$ZodError",Tf.value=t,Object.defineProperty(e,"issues",Tf),Tf.value=void 0,Object.defineProperty(e,"message",uB);let n=Object.getPrototypeOf(e);fx.has(n)||(fx.add(n),Object.
553
- defineProperty(n,"toString",{configurable:!0,enumerable:!1,get(){let r=i(()=>this.message,"value");return Object.defineProperty(this,"toString",{value:r,configurable:!0,writable:!0}),r},set(r){Object.defineProperty(this,"toString",{value:r,configurable:!0,writable:!0})}}))},"initializer"),hx=k("$ZodError",mx),voe=k("$ZodError",mx,void 0,{Parent:Error});function pB(e,t,n){return Object.prototype.hasOwnProperty.call(e,t)||(t==="__proto__"?Object.defineProperty(e,t,{value:n(),writable:!0,enumerable:!0,
553
+ defineProperty(n,"toString",{configurable:!0,enumerable:!1,get(){let r=i(()=>this.message,"value");return Object.defineProperty(this,"toString",{value:r,configurable:!0,writable:!0}),r},set(r){Object.defineProperty(this,"toString",{value:r,configurable:!0,writable:!0})}}))},"initializer"),hx=k("$ZodError",mx),Soe=k("$ZodError",mx,void 0,{Parent:Error});function pB(e,t,n){return Object.prototype.hasOwnProperty.call(e,t)||(t==="__proto__"?Object.defineProperty(e,t,{value:n(),writable:!0,enumerable:!0,
554
554
  configurable:!0}):e[t]=n()),e[t]}i(pB,"node");function Cf(e,t=n=>n.message){let n={},r=[];for(let o of e.issues)o.path.length>0?pB(n,o.path[0],()=>[]).push(t(o)):r.push(t(o));return{formErrors:r,fieldErrors:n}}i(Cf,"flattenError");function Rf(e,t=n=>n.message){let n={_errors:[]},r=i((o,s=[])=>{for(let a of o.issues)if(a.code==="invalid_union"&&a.errors.length)a.errors.map(c=>r({issues:c},[...s,...a.path]));else if(a.code==="invalid_key")r({issues:a.issues},[...s,...a.path]);else if(a.code==="inv\
555
555
  alid_element")r({issues:a.issues},[...s,...a.path]);else{let c=[...s,...a.path];if(c.length===0)n._errors.push(t(a));else{let u=n,p=0;for(;p<c.length;){let d=c[p],f=p===c.length-1;if(d==="_errors"){f&&u._errors.push(t(a)),p++;continue}Object.prototype.hasOwnProperty.call(u,d)||Object.defineProperty(u,d,{value:{_errors:[]},enumerable:!0,writable:!0,configurable:!0});let m=u[d];f&&m._errors.push(t(a)),u=m,p++}}}},"processError");return r(e),n}i(Rf,"formatError");function pc(e,t){return{callee:t?.callee??e,Err:t?.Err}}i(pc,"finalizeParams");var dc=i(e=>{let t=i((n,r,o,s)=>{let a=o?{...o,async:!1}:{async:!1},c=n._zod.run({value:r,issues:[]},a);if(c instanceof Promise)throw new Pt;if(c.issues.length){let u=new(s?.Err??e)(c.issues.map(p=>_t(p,a,Qe())));throw sc(u,s?.callee??t),u}return c.value},"fn");return t},"_parse");var fc=i(e=>{let t=i(async(n,r,o,s)=>{let a=o?{...o,async:!0}:{async:!0},c=n._zod.run({value:r,issues:[]},a);if(c instanceof Promise&&(c=await c),c.issues.length){let u=new(s?.Err??e)(c.issues.map(p=>_t(p,a,Qe())));throw sc(u,s?.callee??t),u}return c.value},"fn");return t},"_parseAsync");var mc=i(e=>(t,n,r)=>{let o=r?{...r,async:!1}:{async:!1},s=t._zod.run({value:n,issues:[]},o);if(s instanceof Promise)throw new Pt;return s.issues.length?gx(e,s.issues,o):{success:!0,data:s.value}},"_safeParse");function gx(e,t,n){let r;return{success:!1,get error(){return r||(r=new e(t.map(o=>_t(o,n,Qe()))),t=void 0,n=void 0),r},set error(o){r=o,t=void 0,n=void 0}}}i(gx,"failure");var hc=i(e=>async(t,n,r)=>{let o=r?{...r,async:!0}:{async:!0},s=t._zod.run({value:n,issues:[]},o);return s instanceof Promise&&(s=await s),s.issues.length?gx(e,s.issues,o):{success:!0,data:s.value}},"_safeParseAsync");var dB=Symbol.for("zod.compile.invalid"),fB=Symbol.for("zod.compile.fallback"),jf=i(((e,t,n)=>{let r=e._zod.bag.validator;if(r!==void 0){if(r(t)!==dB)return!0;if(r.definite===!0&&n===void 0)return!1}return mB(e,t,n)}),"validate");function mB(e,t,n){let r=n?{...n,async:!1,abortEarly:!0}:{async:!1,abortEarly:!0},o=e._zod.bag.fallbackRun,s;if(o?(r[fB]=!0,s=o({value:t,issues:[]},r)):s=e._zod.run({value:t,issues:[]},r),s instanceof Promise)throw new Pt;return s.issues.length===0}i(mB,"validateFallbac\
556
556
  k");var If=i(async(e,t,n)=>{let r=n?{...n,async:!0,abortEarly:!0}:{async:!0,abortEarly:!0},o=e._zod.run({value:t,issues:[]},r);return o instanceof Promise&&(o=await o),o.issues.length===0},"validateAsync"),bx=i(e=>{let t=dc(e),n=i((r,o,s,a)=>{let c=s?{...s,direction:"backward"}:{direction:"backward"};return t(r,o,c,pc(n,a))},"fn");return n},"_encode");var yx=i(e=>{let t=dc(e),n=i((r,o,s,a)=>t(r,o,s,pc(n,a)),"fn");return n},"_decode");var wx=i(e=>{let t=fc(e),n=i(async(r,o,s,a)=>{let c=s?{...s,direction:"backward"}:{direction:"backward"};return await t(r,o,c,pc(n,a))},"fn");return n},"_encodeAsync");var vx=i(e=>{let t=fc(e),n=i(async(r,o,s,a)=>await t(r,o,s,pc(n,a)),"fn");return n},"_decodeAsync");var Sx=i(e=>(t,n,r)=>{let o=r?{...r,direction:"backward"}:{direction:"backward"};return mc(e)(t,n,o)},"_safeEncode");var xx=i(e=>(t,n,r)=>mc(e)(t,n,r),"_safeDecode");var kx=i(e=>async(t,n,r)=>{let o=r?{...r,direction:"backward"}:{direction:"backward"};return hc(e)(t,n,o)},"_safeEncodeAsync");var _x=i(e=>async(t,n,r)=>hc(e)(t,n,r),"_safeDecodeAsync");var Px=/^[cC][0-9a-z]{6,}$/,Ex=/^[0-9a-z]+$/,Ax=/^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$/,Ox=/^[0-9a-vA-V]{20}$/,$x=/^[A-Za-z0-9]{27}$/,Tx=/^[a-zA-Z0-9_-]{21}$/;function Cx(e){return new RegExp(`^[a-zA-Z0-9_-]{${e}}$`)}i(Cx,"nanoidOfLength");var Rx=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;var jx=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,Nf=i(e=>e?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,"uuid");var Ix=/^(?:[A-Za-z0-9_'+\-]+\.)*[A-Za-z0-9_'+\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;var hB="^(?=[\\s\\S]*[\\p{Extended_Pictographic}\\p{Regional_Indicator}\\u20E3])[\\p{Extended_Pictographic}\\p{Emoji_Component}]+$";function Dx(){return new RegExp(hB,"u")}i(Dx,"emoji");var Nx=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,Lx=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;var Mx=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,zx=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,
@@ -773,9 +773,9 @@ t.push(` - hostname: ${In(n.hostname)}`,` service: ${In(n.service)}`)}return
773
773
  s=="string"?o.s:"";if(!s||!a||!c)throw new Dn("the token is missing the account, tunnel or secret field");if(!th.test(a))throw new Dn("the tunnel id inside the token is not a UUID");return{AccountTag:s,TunnelID:a,TunnelSecret:c}}i(QE,"parseTunnelToken");function eA(e){return`${JSON.stringify(e)}
774
774
  `}i(eA,"renderTunnelCredentials");var u2=/(Unauthorized|failed to authenticate|invalid tunnel secret|token is invalid|401)/i,p2=/(Couldn't start tunnel|validation failed|error parsing YAML|unable to parse config)/i,d2=/Registered tunnel connection/i;function tA(e){return!e.tokenConfigured||!e.zoneConfigured?{state:"not-configured",detail:e.tokenConfigured?"no domain has been set":"no tunnel token has been set",hint:"Settings -> Cloudflare Tunnel"}:e.enabled?u2.test(e.logTail)?{state:"auth-error",detail:"Cloudflare rejected the t\
775
775
  unnel token",hint:"the tunnel may have been deleted, or the token belongs to another account. Replace the token."}:p2.test(e.logTail)?{state:"config-error",detail:"the connector refused its configuration",hint:"portta tunnel status --logs"}:e.containerState!=="running"?{state:"disconnected",detail:e.containerState?`the connector container is ${e.containerState}`:"the connector container does not exist",hint:"portta up"}:d2.test(e.logTail)?{state:"connected",detail:"holding registered connections\
776
- to the Cloudflare edge",hint:null}:e.containerHealth==="starting"||!e.logTail?{state:"starting",detail:"the connector is establishing its connections",hint:null}:{state:"disconnected",detail:"the connector is running but has registered no connection",hint:"check outbound network access; the connector dials Cloudflare on 7844/udp and 443/tcp"}:{state:"configured",detail:"set up, and not enabled",hint:"enable it to start the connector"}}i(tA,"tunnelStatusFrom");import{stderr as f2,stdin as nA}from"node:process";import{createInterface as m2}from"node:readline/promises";var Fe={success:0,failure:1,usage:2,precondition:3,refused:4},_e=class extends Error{static{i(this,"CliError")}exitCode;hint;constructor(t,n=Fe.failure,r){super(t),this.name="CliError",this.exitCode=n,this.hint=r}},L=class extends _e{static{i(this,"PreconditionError")}constructor(t,n){super(t,Fe.precondition,n)}},U=class extends _e{static{i(this,"RefusedError")}constructor(t,n){super(t,Fe.refused,n)}},C=class extends _e{static{i(this,"UsageError")}constructor(t,n){super(t,Fe.usage,n)}};async function et(e,t){if(t)return;if(!nA.isTTY)throw new U(`${e}; confirmation is unavailable without a TTY`,"pass --yes to confirm non-interactively");let n=m2({input:nA,output:f2});try{let r=await n.question(`${e} [y/N] `);if(!/^y(es)?$/i.test(r.trim()))throw new U("operation cancelled")}finally{n.close()}}i(et,"confirm");import{existsSync as dr,readFileSync as oA}from"node:fs";import{dirname as g2,join as Et,resolve as vo}from"node:path";var rA={name:"@codions/portta",version:"0.0.0-develop.20261104153517.sha-5a14f37",description:"Machine-first CLI for a shared Docker development gateway",keywords:["docker","docker-compose","traefik","development","gateway","devcontainer","reverse-proxy"],license:"MIT",type:"module",bin:{portta:"dist/cli.js"},files:["dist"],publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},scripts:{build:"node --import tsx scripts/build.mjs",typecheck:"tsc -p tsconfig.json --noEmit",test:"vi\
776
+ to the Cloudflare edge",hint:null}:e.containerHealth==="starting"||!e.logTail?{state:"starting",detail:"the connector is establishing its connections",hint:null}:{state:"disconnected",detail:"the connector is running but has registered no connection",hint:"check outbound network access; the connector dials Cloudflare on 7844/udp and 443/tcp"}:{state:"configured",detail:"set up, and not enabled",hint:"enable it to start the connector"}}i(tA,"tunnelStatusFrom");import{stderr as f2,stdin as nA}from"node:process";import{createInterface as m2}from"node:readline/promises";var Fe={success:0,failure:1,usage:2,precondition:3,refused:4},_e=class extends Error{static{i(this,"CliError")}exitCode;hint;constructor(t,n=Fe.failure,r){super(t),this.name="CliError",this.exitCode=n,this.hint=r}},L=class extends _e{static{i(this,"PreconditionError")}constructor(t,n){super(t,Fe.precondition,n)}},U=class extends _e{static{i(this,"RefusedError")}constructor(t,n){super(t,Fe.refused,n)}},C=class extends _e{static{i(this,"UsageError")}constructor(t,n){super(t,Fe.usage,n)}};async function et(e,t){if(t)return;if(!nA.isTTY)throw new U(`${e}; confirmation is unavailable without a TTY`,"pass --yes to confirm non-interactively");let n=m2({input:nA,output:f2});try{let r=await n.question(`${e} [y/N] `);if(!/^y(es)?$/i.test(r.trim()))throw new U("operation cancelled")}finally{n.close()}}i(et,"confirm");import{existsSync as dr,readFileSync as oA}from"node:fs";import{dirname as g2,join as Et,resolve as vo}from"node:path";var rA={name:"@codions/portta",version:"0.0.0-develop.20261104154502.sha-e00843e",description:"Machine-first CLI for a shared Docker development gateway",keywords:["docker","docker-compose","traefik","development","gateway","devcontainer","reverse-proxy"],license:"MIT",type:"module",bin:{portta:"dist/cli.js"},files:["dist"],publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},scripts:{build:"node --import tsx scripts/build.mjs",typecheck:"tsc -p tsconfig.json --noEmit",test:"vi\
777
777
  test run",prepack:"npm run build",prepublishOnly:"npm run typecheck && npm test"},engines:{node:">=24"},repository:{type:"git",url:"git+https://github.com/codions-labs/portta.git",directory:"packages/cli"},homepage:"https://github.com/codions-labs/portta#readme",bugs:"https://github.com/codions-labs/portta/issues",dependencies:{"@clack/prompts":"^1.1.0",commander:"14.0.2",execa:"9.6.1",systeminformation:"^5.33.8",yaml:"^2.8.2",zod:"4.6.7"},devDependencies:{"@types/node":"24.13.3",esbuild:"0.28.2",
778
- "portta-contracts":"0.1.0","portta-core":"0.1.0",typescript:"7.0.2",vitest:"5.0.5",tsx:"4.23.15"}};var pr=rA.version,Zc="2026-11-04T15:37:04Z";function ai(){return`portta ${pr}${Zc?` (built ${Zc})`:""}`}i(ai,"cliVersionLine");var b2="0.0.0-local";function oh(e){return dr(Et(e,"docker","compose","compose.yaml"))?dr(Et(e,"VERSION"))||dr(Et(e,"packages","cli","package.json")):!1}i(oh,"isGatewayRoot");function sh(e){let t=Et(e,"VERSION");if(dr(t))return oA(t,"utf8").trim();let n=Et(e,"packages","cli","package.json");if(dr(n))return b2;throw new L(`missing generated VERSION in ${e}`,"reinstall the @codions/portta npm package")}i(sh,"versionForRoot");function y2(){let e=process.env.HOME;return[process.env.PORTTA_HOME,e?Et(
778
+ "portta-contracts":"0.1.0","portta-core":"0.1.0",typescript:"7.0.2",vitest:"5.0.5",tsx:"4.23.15"}};var pr=rA.version,Zc="2026-11-04T15:46:56Z";function ai(){return`portta ${pr}${Zc?` (built ${Zc})`:""}`}i(ai,"cliVersionLine");var b2="0.0.0-local";function oh(e){return dr(Et(e,"docker","compose","compose.yaml"))?dr(Et(e,"VERSION"))||dr(Et(e,"packages","cli","package.json")):!1}i(oh,"isGatewayRoot");function sh(e){let t=Et(e,"VERSION");if(dr(t))return oA(t,"utf8").trim();let n=Et(e,"packages","cli","package.json");if(dr(n))return b2;throw new L(`missing generated VERSION in ${e}`,"reinstall the @codions/portta npm package")}i(sh,"versionForRoot");function y2(){let e=process.env.HOME;return[process.env.PORTTA_HOME,e?Et(
779
779
  e,"portta"):void 0,"/opt/portta",e?Et(e,".portta"):void 0,"/var/lib/portta"].filter(t=>!!t)}i(y2,"wellKnownRoots");function ih(e=process.cwd()){let t=process.env.PORTTA_ROOT;if(t&&oh(vo(t)))return vo(t);let n=vo(e);for(;;){if(oh(n))return n;let r=g2(n);if(r===n)break;n=r}for(let r of y2())if(oh(vo(r)))return vo(r);return null}i(ih,"findGatewayRoot");function E(e={}){let t=e.root?vo(e.root):ih();if(!t){if(e.required===!1){let c={...process.env,PORTTA_PROFILE:e.profile??process.env.PORTTA_PROFILE},
780
780
  u=rr(c);return{root:process.cwd(),env:c,config:u,composeFiles:[],version:pr}}throw new L("no Portta installation found","run `portta setup`, set PORTTA_HOME, or run this inside the gateway directory")}let n=dr(Et(t,".env"))?me(oA(Et(t,".env"),"utf8")):new Map,r=Xr(n,process.env);for(let[c,u]of Object.entries(e.overrides??{}))r[c]=u;e.profile&&(r.PORTTA_PROFILE=e.profile),r.PORTTA_ROOT=t,Wv(r);let o=rr(r);r.PORTTA_DOMAIN=o.domain,r.PORTTA_BIND_ADDRESS=o.bindAddress;let s=Zv(o);for(let c of s)if(!dr(
781
781
  Et(t,c)))throw new L(`missing compose file: ${c}`);let a=sh(t);return r.PORTTA_VERSION=a,{root:t,env:r,config:o,composeFiles:s,version:a}}i(E,"gatewayContext");function we(e){return["--project-directory",e.root,...e.composeFiles.flatMap(t=>["-f",Et(e.root,t)])]}i(we,"composeArguments");import{spawn as H4}from"node:child_process";import{closeSync as Z4,openSync as G4}from"node:fs";function xe(e){if(typeof e!="object"||e===null)return!1;let t=Object.getPrototypeOf(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)}i(xe,"isPlainObject");import{fileURLToPath as w2}from"node:url";var So=i((e,t)=>{let n=ch(v2(e));if(typeof n!="string")throw new TypeError(`${t} must be a string or a file URL: ${n}.`);return n},"safeNormalizeFileUrl"),v2=i(e=>ah(e)?e.toString():e,"normalizeDenoExecPath"),ah=i(e=>typeof e!="string"&&e&&Object.getPrototypeOf(e)===String.prototype,"isDenoExecPath"),ch=i(e=>e instanceof URL?w2(e):e,"normalizeFileUrl");var Gc=i((e,t=[],n={})=>{let r=So(e,"First argument"),[o,s]=xe(t)?[[],t]:[t,n];if(!Array.isArray(o))throw new TypeError(`Second argument must be either an array of arguments or an options object: ${o}`);if(o.some(u=>typeof u=="object"&&u!==null))throw new TypeError(`Second argument must be an array of strings: ${o}`);let a=o.map(String),c=a.find(u=>u.includes("\0"));if(c!==void 0)throw new TypeError(`Arguments cannot contain null bytes ("\\0"): ${c}`);if(!xe(s))throw new TypeError(`Last argument\
@@ -803,14 +803,14 @@ musicNote:"\u266A",musicNoteBeamed:"\u266B",arrowUp:"\u2191",arrowDown:"\u2193",
803
803
  \u2547",lineUpBoldDownBoldLeftRightBold:"\u254A",lineUpBoldDownBoldLeftBoldRight:"\u2549",lineUpBoldDownLeftRight:"\u2540",lineUpDownBoldLeftRight:"\u2541",lineUpDownLeftBoldRight:"\u253D",lineUpDownLeftRightBold:"\u253E",lineUpBoldDownBoldLeftRight:"\u2542",lineUpDownLeftBoldRightBold:"\u253F",lineUpBoldDownLeftBoldRight:"\u2543",lineUpBoldDownLeftRightBold:"\u2544",lineUpDownBoldLeftBoldRight:"\u2545",lineUpDownBoldLeftRightBold:"\u2546",lineUpDoubleDownDoubleLeftDoubleRightDouble:"\u256C",lineUpDoubleDownDoubleLeftRight:"\
804
804
  \u256B",lineUpDownLeftDoubleRightDouble:"\u256A",lineCross:"\u2573",lineBackslash:"\u2572",lineSlash:"\u2571"},SA={tick:"\u2714",info:"\u2139",warning:"\u26A0",cross:"\u2718",squareSmall:"\u25FB",squareSmallFilled:"\u25FC",circle:"\u25EF",circleFilled:"\u25C9",circleDotted:"\u25CC",circleDouble:"\u25CE",circleCircle:"\u24DE",circleCross:"\u24E7",circlePipe:"\u24BE",radioOn:"\u25C9",radioOff:"\u25EF",checkboxOn:"\u2612",checkboxOff:"\u2610",checkboxCircleOn:"\u24E7",checkboxCircleOff:"\u24BE",pointer:"\
805
805
  \u276F",triangleUpOutline:"\u25B3",triangleLeft:"\u25C0",triangleRight:"\u25B6",lozenge:"\u25C6",lozengeOutline:"\u25C7",hamburger:"\u2630",smiley:"\u32E1",mustache:"\u0DF4",star:"\u2605",play:"\u25B6",nodejs:"\u2B22",oneSeventh:"\u2150",oneNinth:"\u2151",oneTenth:"\u2152"},X2={tick:"\u221A",info:"i",warning:"\u203C",cross:"\xD7",squareSmall:"\u25A1",squareSmallFilled:"\u25A0",circle:"( )",circleFilled:"(*)",circleDotted:"( )",circleDouble:"( )",circleCircle:"(\u25CB)",circleCross:"(\xD7)",circlePipe:"\
806
- (\u2502)",radioOn:"(*)",radioOff:"( )",checkboxOn:"[\xD7]",checkboxOff:"[ ]",checkboxCircleOn:"(\xD7)",checkboxCircleOff:"( )",pointer:">",triangleUpOutline:"\u2206",triangleLeft:"\u25C4",triangleRight:"\u25BA",lozenge:"\u2666",lozengeOutline:"\u25CA",hamburger:"\u2261",smiley:"\u263A",mustache:"\u250C\u2500\u2510",star:"\u2736",play:"\u25BA",nodejs:"\u2666",oneSeventh:"1/7",oneNinth:"1/9",oneTenth:"1/10"},Q2={...vA,...SA},eq={...vA,...X2},tq=hh(),nq=tq?Q2:eq,Xc=nq,yle=Object.entries(SA);import rq from"node:tty";var oq=rq?.WriteStream?.prototype?.hasColors?.()??!1,F=i((e,t)=>{if(!oq)return o=>o;let n=`\x1B[${e}m`,r=`\x1B[${t}m`;return o=>{let s=o+"",a=s.indexOf(r);if(a===-1)return n+s+r;let c=n,u=0,d=(t===22?r:"")+n;for(;a!==-1;)c+=s.slice(u,a)+d,u=a+r.length,a=s.indexOf(r,u);return c+=s.slice(u)+r,c}},"format"),xle=F(0,0),xA=F(1,22),kle=F(2,22),_le=F(3,23),Ple=F(4,24),Ele=F("4:2",24),Ale=F("4:3",24),Ole=F("4:4",24),$le=F("4:5",24),Tle=F(53,55),Cle=F(7,27),Rle=F(8,28),jle=F(9,29),Ile=F(30,39),Dle=F(31,39),
807
- Nle=F(32,39),Lle=F(33,39),Mle=F(34,39),zle=F(35,39),Fle=F(36,39),Ble=F(37,39),Qc=F(90,39),Ule=F(40,49),qle=F(41,49),Hle=F(42,49),Zle=F(43,49),Gle=F(44,49),Wle=F(45,49),Vle=F(46,49),Kle=F(47,49),Jle=F(100,49),kA=F(91,39),Yle=F(92,39),_A=F(93,39),Xle=F(94,39),Qle=F(95,39),eue=F(96,39),tue=F(97,39),nue=F(101,49),rue=F(102,49),oue=F(103,49),sue=F(104,49),iue=F(105,49),aue=F(106,49),cue=F(107,49),lue=F("58;5;0",59),uue=F("58;5;1",59),pue=F("58;5;2",59),due=F("58;5;3",59),fue=F("58;5;4",59),mue=F("58;\
808
- 5;5",59),hue=F("58;5;6",59),gue=F("58;5;7",59),bue=F("58;5;8",59),yue=F("58;5;9",59),wue=F("58;5;10",59),vue=F("58;5;11",59),Sue=F("58;5;12",59),xue=F("58;5;13",59),kue=F("58;5;14",59),_ue=F("58;5;15",59);var AA=i(({type:e,message:t,timestamp:n,piped:r,commandId:o,result:{failed:s=!1}={},options:{reject:a=!0}})=>{let c=sq(n),u=iq[e]({failed:s,reject:a,piped:r}),p=aq[e]({reject:a});return`${Qc(`[${c}]`)} ${Qc(`[${o}]`)} ${p(u)} ${p(t)}`},"defaultVerboseFunction"),sq=i(e=>`${el(e.getHours(),2)}:${el(e.getMinutes(),2)}:${el(e.getSeconds(),2)}.${el(e.getMilliseconds(),3)}`,"serializeTimestamp"),el=i((e,t)=>String(e).padStart(t,"0"),"padField"),PA=i(({failed:e,reject:t})=>e?t?Xc.cross:Xc.warning:Xc.tick,
806
+ (\u2502)",radioOn:"(*)",radioOff:"( )",checkboxOn:"[\xD7]",checkboxOff:"[ ]",checkboxCircleOn:"(\xD7)",checkboxCircleOff:"( )",pointer:">",triangleUpOutline:"\u2206",triangleLeft:"\u25C4",triangleRight:"\u25BA",lozenge:"\u2666",lozengeOutline:"\u25CA",hamburger:"\u2261",smiley:"\u263A",mustache:"\u250C\u2500\u2510",star:"\u2736",play:"\u25BA",nodejs:"\u2666",oneSeventh:"1/7",oneNinth:"1/9",oneTenth:"1/10"},Q2={...vA,...SA},eq={...vA,...X2},tq=hh(),nq=tq?Q2:eq,Xc=nq,wle=Object.entries(SA);import rq from"node:tty";var oq=rq?.WriteStream?.prototype?.hasColors?.()??!1,F=i((e,t)=>{if(!oq)return o=>o;let n=`\x1B[${e}m`,r=`\x1B[${t}m`;return o=>{let s=o+"",a=s.indexOf(r);if(a===-1)return n+s+r;let c=n,u=0,d=(t===22?r:"")+n;for(;a!==-1;)c+=s.slice(u,a)+d,u=a+r.length,a=s.indexOf(r,u);return c+=s.slice(u)+r,c}},"format"),kle=F(0,0),xA=F(1,22),_le=F(2,22),Ple=F(3,23),Ele=F(4,24),Ale=F("4:2",24),Ole=F("4:3",24),$le=F("4:4",24),Tle=F("4:5",24),Cle=F(53,55),Rle=F(7,27),jle=F(8,28),Ile=F(9,29),Dle=F(30,39),Nle=F(31,39),
807
+ Lle=F(32,39),Mle=F(33,39),zle=F(34,39),Fle=F(35,39),Ble=F(36,39),Ule=F(37,39),Qc=F(90,39),qle=F(40,49),Hle=F(41,49),Zle=F(42,49),Gle=F(43,49),Wle=F(44,49),Vle=F(45,49),Kle=F(46,49),Jle=F(47,49),Yle=F(100,49),kA=F(91,39),Xle=F(92,39),_A=F(93,39),Qle=F(94,39),eue=F(95,39),tue=F(96,39),nue=F(97,39),rue=F(101,49),oue=F(102,49),sue=F(103,49),iue=F(104,49),aue=F(105,49),cue=F(106,49),lue=F(107,49),uue=F("58;5;0",59),pue=F("58;5;1",59),due=F("58;5;2",59),fue=F("58;5;3",59),mue=F("58;5;4",59),hue=F("58;\
808
+ 5;5",59),gue=F("58;5;6",59),bue=F("58;5;7",59),yue=F("58;5;8",59),wue=F("58;5;9",59),vue=F("58;5;10",59),Sue=F("58;5;11",59),xue=F("58;5;12",59),kue=F("58;5;13",59),_ue=F("58;5;14",59),Pue=F("58;5;15",59);var AA=i(({type:e,message:t,timestamp:n,piped:r,commandId:o,result:{failed:s=!1}={},options:{reject:a=!0}})=>{let c=sq(n),u=iq[e]({failed:s,reject:a,piped:r}),p=aq[e]({reject:a});return`${Qc(`[${c}]`)} ${Qc(`[${o}]`)} ${p(u)} ${p(t)}`},"defaultVerboseFunction"),sq=i(e=>`${el(e.getHours(),2)}:${el(e.getMinutes(),2)}:${el(e.getSeconds(),2)}.${el(e.getMilliseconds(),3)}`,"serializeTimestamp"),el=i((e,t)=>String(e).padStart(t,"0"),"padField"),PA=i(({failed:e,reject:t})=>e?t?Xc.cross:Xc.warning:Xc.tick,
809
809
  "getFinalIcon"),iq={command:i(({piped:e})=>e?"|":"$","command"),output:i(()=>" ","output"),ipc:i(()=>"*","ipc"),error:PA,duration:PA},EA=i(e=>e,"identity"),aq={command:i(()=>xA,"command"),output:i(()=>EA,"output"),ipc:i(()=>EA,"ipc"),error:i(({reject:e})=>e?kA:_A,"error"),duration:i(()=>Qc,"duration")};var OA=i((e,t,n)=>{let r=gA(t,n);return e.map(({verboseLine:o,verboseObject:s})=>cq(o,s,r)).filter(o=>o!==void 0).map(o=>lq(o)).join("")},"applyVerboseOnLines"),cq=i((e,t,n)=>{if(n===void 0)return e;let r=n(e,t);if(typeof r=="string")return r},"applyVerboseFunction"),lq=i(e=>e.endsWith(`
810
810
  `)?e:`${e}
811
811
  `,"appendNewline");var Ft=i(({type:e,verboseMessage:t,fdNumber:n,verboseInfo:r,result:o})=>{let s=pq({type:e,result:o,verboseInfo:r}),a=dq(t,s),c=OA(a,r,n);c!==""&&console.warn(c.slice(0,-1))},"verboseLog"),pq=i(({type:e,result:t,verboseInfo:{escapedCommand:n,commandId:r,rawOptions:{piped:o=!1,...s}}})=>({type:e,escapedCommand:n,commandId:`${r}`,timestamp:new Date,piped:o,result:t,options:s}),"getVerboseObject"),dq=i((e,t)=>e.split(`
812
812
  `).map(n=>fq({...t,message:n})),"getPrintedLines"),fq=i(e=>({verboseLine:AA(e),verboseObject:e}),"getPrintedLine"),tl=i(e=>{let t=typeof e=="string"?e:uq(e);return li(t).replaceAll(" "," ".repeat(mq))},"serializeVerboseMessage"),mq=2;var $A=i((e,t)=>{xo(t)&&Ft({type:"command",verboseMessage:e,verboseInfo:t})},"logCommand");var TA=i((e,t,n)=>{bq(e);let r=hq(e);return{verbose:e,escapedCommand:t,commandId:r,rawOptions:n}},"getVerboseInfo"),hq=i(e=>xo({verbose:e})?gq++:void 0,"getCommandId"),gq=0n,bq=i(e=>{for(let t of e){if(t===!1)throw new TypeError(`The "verbose: false" option was renamed to "verbose: 'none'".`);if(t===!0)throw new TypeError(`The "verbose: true" option was renamed to "verbose: 'short'".`);if(!Yc.includes(t)&&!Jc(t)){let n=Yc.map(r=>`'${r}'`).join(", ");throw new TypeError(`The "verbose" option must\
813
- not be ${t}. Allowed values are: ${n} or a function.`)}}},"validateVerbose");import{hrtime as CA}from"node:process";var nl=i(()=>CA.bigint(),"getStartTime"),gh=i(e=>Number(CA.bigint()-e)/1e6,"getDurationMs");var rl=i((e,t,n)=>{let r=nl(),{command:o,escapedCommand:s}=bA(e,t),a=ph(n,"verbose"),c=TA(a,s,{...n});return $A(s,c),{command:o,escapedCommand:s,startTime:r,verboseInfo:c}},"handleCommand");var $O=za(w0(),1);import eZ from"node:path";import OO from"node:process";import al from"node:process";import fr from"node:path";function sl(e={}){let{env:t=process.env,platform:n=process.platform}=e;return n!=="win32"?"PATH":Object.keys(t).reverse().find(r=>r.toUpperCase()==="PATH")||"Path"}i(sl,"pathKey");import{promisify as Hq}from"node:util";import{execFile as Zq,execFileSync as Rpe}from"node:child_process";import v0 from"node:path";import{fileURLToPath as Gq}from"node:url";var Dpe=Hq(Zq);function il(e){return e instanceof URL?Gq(e):e}i(il,"toPath");function S0(e){return{*[Symbol.iterator](){let t=v0.resolve(il(e)),n;for(;n!==t;)yield t,n=t,t=v0.resolve(t,"..")}}}i(S0,"traversePathUp");var Npe=10*1024*1024;var Wq=i(({cwd:e=al.cwd(),path:t=al.env[sl()],preferLocal:n=!0,execPath:r=al.execPath,addExecPath:o=!0}={})=>{let s=fr.resolve(il(e)),a=[],c=t.split(fr.delimiter);return n&&Vq(a,c,s),o&&Kq(a,c,r,s),t===""||t===fr.delimiter?`${a.join(fr.delimiter)}${t}`:[...a,t].join(fr.delimiter)},"npmRunPath"),Vq=i((e,t,n)=>{for(let r of S0(n)){let o=fr.join(r,"node_modules/.bin");t.includes(o)||e.push(o)}},"applyPreferLocal"),Kq=i((e,t,n,r)=>{let o=fr.resolve(r,il(n),"..");t.includes(o)||e.push(o)},"applyExecP\
813
+ not be ${t}. Allowed values are: ${n} or a function.`)}}},"validateVerbose");import{hrtime as CA}from"node:process";var nl=i(()=>CA.bigint(),"getStartTime"),gh=i(e=>Number(CA.bigint()-e)/1e6,"getDurationMs");var rl=i((e,t,n)=>{let r=nl(),{command:o,escapedCommand:s}=bA(e,t),a=ph(n,"verbose"),c=TA(a,s,{...n});return $A(s,c),{command:o,escapedCommand:s,startTime:r,verboseInfo:c}},"handleCommand");var $O=za(w0(),1);import eZ from"node:path";import OO from"node:process";import al from"node:process";import fr from"node:path";function sl(e={}){let{env:t=process.env,platform:n=process.platform}=e;return n!=="win32"?"PATH":Object.keys(t).reverse().find(r=>r.toUpperCase()==="PATH")||"Path"}i(sl,"pathKey");import{promisify as Hq}from"node:util";import{execFile as Zq,execFileSync as jpe}from"node:child_process";import v0 from"node:path";import{fileURLToPath as Gq}from"node:url";var Npe=Hq(Zq);function il(e){return e instanceof URL?Gq(e):e}i(il,"toPath");function S0(e){return{*[Symbol.iterator](){let t=v0.resolve(il(e)),n;for(;n!==t;)yield t,n=t,t=v0.resolve(t,"..")}}}i(S0,"traversePathUp");var Lpe=10*1024*1024;var Wq=i(({cwd:e=al.cwd(),path:t=al.env[sl()],preferLocal:n=!0,execPath:r=al.execPath,addExecPath:o=!0}={})=>{let s=fr.resolve(il(e)),a=[],c=t.split(fr.delimiter);return n&&Vq(a,c,s),o&&Kq(a,c,r,s),t===""||t===fr.delimiter?`${a.join(fr.delimiter)}${t}`:[...a,t].join(fr.delimiter)},"npmRunPath"),Vq=i((e,t,n)=>{for(let r of S0(n)){let o=fr.join(r,"node_modules/.bin");t.includes(o)||e.push(o)}},"applyPreferLocal"),Kq=i((e,t,n,r)=>{let o=fr.resolve(r,il(n),"..");t.includes(o)||e.push(o)},"applyExecP\
814
814
  ath"),x0=i(({env:e=al.env,...t}={})=>{e={...e};let n=sl({env:e});return t.path=e[n],e[n]=Wq(t),e},"npmRunPathEnv");import{setTimeout as uH}from"node:timers/promises";var k0=i((e,t,n)=>{let r=n?pi:ui,o=e instanceof Ot?{}:{cause:e};return new r(t,o)},"getFinalError"),Ot=class extends Error{static{i(this,"DiscardedError")}},_0=i((e,t)=>{Object.defineProperty(e.prototype,"name",{value:t,writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,E0,{value:!0,writable:!1,enumerable:!1,configurable:!1})},"setErrorName"),P0=i(e=>cl(e)&&E0 in e,"isExecaError"),E0=Symbol("isExecaError"),cl=i(e=>Object.prototype.toString.call(e)==="[object Error]","i\
815
815
  sErrorInstance"),ui=class extends Error{static{i(this,"ExecaError")}};_0(ui,ui.name);var pi=class extends Error{static{i(this,"ExecaSyncError")}};_0(pi,pi.name);import{constants as di}from"node:os";import{constants as Qq}from"node:os";var A0=i(()=>{let e=Eh-O0+1;return Array.from({length:e},Jq)},"getRealtimeSignals"),Jq=i((e,t)=>({name:`SIGRT${t+1}`,number:O0+t,action:"terminate",description:"Application-specific signal (realtime)",standard:"posix"}),"getRealtimeSignal"),O0=34,Eh=64;import{constants as Yq}from"node:os";var $0=[{name:"SIGHUP",number:1,action:"terminate",description:"Terminal closed",standard:"posix"},{name:"SIGINT",number:2,action:"terminate",description:"User interruption with CTRL-C",standard:"ansi"},{name:"SIGQUIT",number:3,action:"core",description:"User interruption with CTRL-\\",standard:"posix"},{name:"SIGILL",number:4,action:"core",description:"Invalid machine instruction",standard:"ansi"},{name:"SIGTRAP",number:5,action:"core",description:"Debugger breakpoint",standard:"posix"},{name:"\
816
816
  SIGABRT",number:6,action:"core",description:"Aborted",standard:"ansi"},{name:"SIGIOT",number:6,action:"core",description:"Aborted",standard:"bsd"},{name:"SIGBUS",number:7,action:"core",description:"Bus error due to misaligned, non-existing address or paging error",standard:"bsd"},{name:"SIGEMT",number:7,action:"terminate",description:"Command should be emulated but is not implemented",standard:"other"},{name:"SIGFPE",number:8,action:"core",description:"Floating point arithmetic error",standard:"\
@@ -820,7 +820,7 @@ sed or unpaused",standard:"other"},{name:"SIGCONT",number:18,action:"unpause",de
820
820
  User interruption with CTRL-BREAK",standard:"other"},{name:"SIGTTOU",number:22,action:"pause",description:"Background process cannot write to terminal output",standard:"posix"},{name:"SIGURG",number:23,action:"ignore",description:"Socket received out-of-band data",standard:"bsd"},{name:"SIGXCPU",number:24,action:"core",description:"Process timed out",standard:"bsd"},{name:"SIGXFSZ",number:25,action:"core",description:"File too big",standard:"bsd"},{name:"SIGVTALRM",number:26,action:"terminate",description:"\
821
821
  Timeout or timer",standard:"bsd"},{name:"SIGPROF",number:27,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGWINCH",number:28,action:"ignore",description:"Terminal window size changed",standard:"bsd"},{name:"SIGIO",number:29,action:"terminate",description:"I/O is available",standard:"other"},{name:"SIGPOLL",number:29,action:"terminate",description:"Watched event",standard:"other"},{name:"SIGINFO",number:29,action:"ignore",description:"Request for process information",standard:"\
822
822
  other"},{name:"SIGPWR",number:30,action:"terminate",description:"Device running out of power",standard:"systemv"},{name:"SIGSYS",number:31,action:"core",description:"Invalid system call",standard:"other"},{name:"SIGUNUSED",number:31,action:"terminate",description:"Invalid system call",standard:"other"}];var Ah=i(()=>{let e=A0();return[...$0,...e].map(Xq)},"getSignals"),Xq=i(({name:e,number:t,description:n,action:r,forced:o=!1,standard:s})=>{let{signals:{[e]:a}}=Yq,c=a!==void 0;return{name:e,number:c?a:t,description:n,supported:c,action:r,forced:o,standard:s}},"normalizeSignal");var eH=i(()=>{let e=Ah();return Object.fromEntries(e.map(tH))},"getSignalsByName"),tH=i(({name:e,number:t,description:n,supported:r,action:o,forced:s,standard:a})=>[e,{name:e,number:t,description:n,supported:r,action:o,forced:s,standard:a}],"getSignalByName"),T0=eH(),nH=i(()=>{let e=Ah(),t=Eh+1,n=Array.from({length:t},(r,o)=>rH(o,e));return Object.assign({},...n)},"getSignalsByNumber"),rH=i((e,t)=>{let n=oH(e,t);if(n===void 0)return{};let{name:r,description:o,supported:s,action:a,forced:c,standard:u}=n;
823
- return{[e]:{name:r,number:e,description:o,supported:s,action:a,forced:c,standard:u}}},"getSignalByNumber"),oH=i((e,t)=>{let n=t.find(({name:r})=>Qq.signals[r]===e);return n!==void 0?n:t.find(r=>r.number===e)},"findSignalByNumber"),sde=nH();var R0=i(e=>{let t="option `killSignal`";if(e===0)throw new TypeError(`Invalid ${t}: 0 cannot be used.`);return I0(e,t)},"normalizeKillSignal"),j0=i(e=>e===0?e:I0(e,"`subprocess.kill()`'s argument"),"normalizeSignalArgument"),I0=i((e,t)=>{if(Number.isInteger(e))return sH(e,t);if(typeof e=="string")return aH(e,t);throw new TypeError(`Invalid ${t} ${String(e)}: it must be a string or an integer.
823
+ return{[e]:{name:r,number:e,description:o,supported:s,action:a,forced:c,standard:u}}},"getSignalByNumber"),oH=i((e,t)=>{let n=t.find(({name:r})=>Qq.signals[r]===e);return n!==void 0?n:t.find(r=>r.number===e)},"findSignalByNumber"),ide=nH();var R0=i(e=>{let t="option `killSignal`";if(e===0)throw new TypeError(`Invalid ${t}: 0 cannot be used.`);return I0(e,t)},"normalizeKillSignal"),j0=i(e=>e===0?e:I0(e,"`subprocess.kill()`'s argument"),"normalizeSignalArgument"),I0=i((e,t)=>{if(Number.isInteger(e))return sH(e,t);if(typeof e=="string")return aH(e,t);throw new TypeError(`Invalid ${t} ${String(e)}: it must be a string or an integer.
824
824
  ${Oh()}`)},"normalizeSignal"),sH=i((e,t)=>{if(C0.has(e))return C0.get(e);throw new TypeError(`Invalid ${t} ${e}: this signal integer does not exist.
825
825
  ${Oh()}`)},"normalizeSignalInteger"),iH=i(()=>new Map(Object.entries(di.signals).reverse().map(([e,t])=>[t,e])),"getSignalsIntegerToName"),C0=iH(),aH=i((e,t)=>{if(e in di.signals)return e;throw e.toUpperCase()in di.signals?new TypeError(`Invalid ${t} '${e}': please rename it to '${e.toUpperCase()}'.`):new TypeError(`Invalid ${t} '${e}': this signal name does not exist.
826
826
  ${Oh()}`)},"normalizeSignalName"),Oh=i(()=>`Available signal names: ${cH()}.
@@ -954,7 +954,7 @@ RV(hg,mg,{value:this,writable:!1,enumerable:!1,configurable:!1})}on(t,n){this.li
954
954
  return e.unload()}}),"signalExitWrap"),bg=class extends Wl{static{i(this,"SignalExitFallback")}onExit(){return()=>{}}load(){}unload(){}},yg=class extends Wl{static{i(this,"SignalExit")}#t=wg.platform==="win32"?"SIGINT":"SIGHUP";#n=new gg;#e;#r;#s;#o={};#i=!1;constructor(t){super(),this.#e=t,this.#o={};for(let n of wr)this.#o[n]=()=>{let r=this.#e.listeners(n),{count:o}=this.#n,s=t;if(typeof s.__signal_exit_emitter__=="object"&&typeof s.__signal_exit_emitter__.count=="number"&&(o+=s.__signal_exit_emitter__.
955
955
  count),r.length===o){this.unload();let a=this.#n.emit("exit",null,n),c=n==="SIGHUP"?this.#t:n;a||t.kill(t.pid,c)}};this.#s=t.reallyExit,this.#r=t.emit}onExit(t,n){if(!Gl(this.#e))return()=>{};this.#i===!1&&this.load();let r=n?.alwaysLast?"afterExit":"exit";return this.#n.on(r,t),()=>{this.#n.removeListener(r,t),this.#n.listeners.exit.length===0&&this.#n.listeners.afterExit.length===0&&this.unload()}}load(){if(!this.#i){this.#i=!0,this.#n.count+=1;for(let t of wr)try{let n=this.#o[t];n&&this.#e.on(
956
956
  t,n)}catch{}this.#e.emit=(t,...n)=>this.#c(t,...n),this.#e.reallyExit=t=>this.#a(t)}}unload(){this.#i&&(this.#i=!1,wr.forEach(t=>{let n=this.#o[t];if(!n)throw new Error("Listener not defined for signal: "+t);try{this.#e.removeListener(t,n)}catch{}}),this.#e.emit=this.#r,this.#e.reallyExit=this.#s,this.#n.count-=1)}#a(t){return Gl(this.#e)?(this.#e.exitCode=t||0,this.#n.emit("exit",this.#e.exitCode,null),this.#s.call(this.#e,this.#e.exitCode)):0}#c(t,...n){let r=this.#r;if(t==="exit"&&Gl(this.#e)){
957
- typeof n[0]=="number"&&(this.#e.exitCode=n[0]);let o=r.call(this.#e,t,...n);return this.#n.emit("exit",this.#e.exitCode,null),o}else return r.call(this.#e,t,...n)}},wg=globalThis.process,{onExit:ST,load:lwe,unload:uwe}=jV(Gl(wg)?new yg(wg):new bg);var xT=i((e,{cleanup:t,detached:n},{signal:r})=>{if(!t||n)return;let o=ST(()=>{e.kill()});IV(r,()=>{o()})},"cleanupOnExit");var _T=i(({source:e,sourcePromise:t,boundOptions:n,createNested:r},...o)=>{let s=nl(),{destination:a,destinationStream:c,destinationError:u,from:p,unpipeSignal:d}=DV(n,r,o),{sourceStream:f,sourceError:m}=LV(e,p),{options:h,fileDescriptors:b}=Ut.get(e);return{sourcePromise:t,sourceStream:f,sourceOptions:h,sourceError:m,destination:a,destinationStream:c,destinationError:u,unpipeSignal:d,fileDescriptors:b,startTime:s}},"normalizePipeArguments"),DV=i((e,t,n)=>{try{let{destination:r,pipeOptions:{from:o,
957
+ typeof n[0]=="number"&&(this.#e.exitCode=n[0]);let o=r.call(this.#e,t,...n);return this.#n.emit("exit",this.#e.exitCode,null),o}else return r.call(this.#e,t,...n)}},wg=globalThis.process,{onExit:ST,load:uwe,unload:pwe}=jV(Gl(wg)?new yg(wg):new bg);var xT=i((e,{cleanup:t,detached:n},{signal:r})=>{if(!t||n)return;let o=ST(()=>{e.kill()});IV(r,()=>{o()})},"cleanupOnExit");var _T=i(({source:e,sourcePromise:t,boundOptions:n,createNested:r},...o)=>{let s=nl(),{destination:a,destinationStream:c,destinationError:u,from:p,unpipeSignal:d}=DV(n,r,o),{sourceStream:f,sourceError:m}=LV(e,p),{options:h,fileDescriptors:b}=Ut.get(e);return{sourcePromise:t,sourceStream:f,sourceOptions:h,sourceError:m,destination:a,destinationStream:c,destinationError:u,unpipeSignal:d,fileDescriptors:b,startTime:s}},"normalizePipeArguments"),DV=i((e,t,n)=>{try{let{destination:r,pipeOptions:{from:o,
958
958
  to:s,unpipeSignal:a}={}}=NV(e,t,...n),c=fl(r,s);return{destination:r,destinationStream:c,from:o,unpipeSignal:a}}catch(r){return{destinationError:r}}},"getDestinationStream"),NV=i((e,t,n,...r)=>{if(Array.isArray(n))return{destination:t(kT,e)(n,...r),pipeOptions:e};if(typeof n=="string"||n instanceof URL||ah(n)){if(Object.keys(e).length>0)throw new TypeError('Please use .pipe("file", ..., options) or .pipe(execa("file", ..., options)) instead of .pipe(options)("file", ...).');let[o,s,a]=Gc(n,...r);
959
959
  return{destination:t(kT)(o,s,a),pipeOptions:a}}if(Ut.has(n)){if(Object.keys(e).length>0)throw new TypeError("Please use .pipe(options)`command` or .pipe($(options)`command`) instead of .pipe(options)($`command`).");return{destination:n,pipeOptions:r[0]}}throw new TypeError(`The first argument must be a template string, an options object, or an Execa subprocess: ${n}`)},"getDestination"),kT=i(({options:e})=>({options:{...e,stdin:"pipe",piped:!0}}),"mapDestinationArguments"),LV=i((e,t)=>{try{return{
960
960
  sourceStream:Oo(e,t)}}catch(n){return{sourceError:n}}},"getSourceStream");var ET=i(({sourceStream:e,sourceError:t,destinationStream:n,destinationError:r,fileDescriptors:o,sourceOptions:s,startTime:a})=>{let c=MV({sourceStream:e,sourceError:t,destinationStream:n,destinationError:r});if(c!==void 0)throw vg({error:c,fileDescriptors:o,sourceOptions:s,startTime:a})},"handlePipeArgumentsError"),MV=i(({sourceStream:e,sourceError:t,destinationStream:n,destinationError:r})=>{if(t!==void 0&&r!==void 0)return r;if(r!==void 0)return fg(e),r;if(t!==void 0)return dg(n),t},"getPipeA\
@@ -984,11 +984,11 @@ context:f,onInternalError:m,controller:p});return{subprocess:u,promise:h}},"spaw
984
984
  signal:h,stdio:w,all:P,ipcOutput:y,context:u,options:t,command:a,escapedCommand:c,startTime:n});return Ro(R,r,t)},"handlePromise"),D4=i(({errorInfo:e,exitCode:t,signal:n,stdio:r,all:o,ipcOutput:s,context:a,options:c,command:u,escapedCommand:p,startTime:d})=>"error"in e?bi({error:e.error,command:u,escapedCommand:p,timedOut:a.terminationReason==="timeout",isCanceled:a.terminationReason==="cancel"||a.terminationReason==="gracefulCancel",isGracefullyCanceled:a.terminationReason==="gracefulCancel",isMaxBuffer:e.
985
985
  error instanceof qt,isForcefullyTerminated:a.isForcefullyTerminated,exitCode:t,signal:n,stdio:r,all:o,ipcOutput:s,options:c,startTime:d,isSync:!1}):Il({command:u,escapedCommand:p,stdio:r,all:o,ipcOutput:s,options:c,startTime:d}),"getAsyncResult");var eu=i((e,t)=>{let n=Object.fromEntries(Object.entries(t).map(([r,o])=>[r,N4(r,e[r],o)]));return{...e,...n}},"mergeOptions"),N4=i((e,t,n)=>L4.has(e)&&xe(t)&&xe(n)?{...t,...n}:n,"mergeOption"),L4=new Set(["env",...fh]);var zn=i((e,t,n,r)=>{let o=i((a,c,u)=>zn(a,c,n,u),"createNested"),s=i((...a)=>M4({mapArguments:e,deepOptions:n,boundOptions:t,setBoundExeca:r,createNested:o},...a),"boundExeca");return r!==void 0&&r(s,o,t),s},"createExeca"),M4=i(({mapArguments:e,deepOptions:t={},boundOptions:n={},setBoundExeca:r,createNested:o},s,...a)=>{if(xe(s))return o(e,eu(n,s),r);let{file:c,commandArguments:u,options:p,isSync:d}=z4({mapArguments:e,firstArgument:s,nextArguments:a,deepOptions:t,boundOptions:n});return d?X$(c,
986
986
  u,p):eC(c,u,p,o)},"callBoundExeca"),z4=i(({mapArguments:e,firstArgument:t,nextArguments:n,deepOptions:r,boundOptions:o})=>{let s=dA(t)?fA(t,n):[t,...n],[a,c,u]=Gc(...s),p=eu(eu(r,o),u),{file:d=a,commandArguments:f=c,options:m=p,isSync:h=!1}=e({file:a,commandArguments:c,options:p});return{file:d,commandArguments:f,options:m,isSync:h}},"parseArguments");var tC=i(({file:e,commandArguments:t})=>rC(e,t),"mapCommandAsync"),nC=i(({file:e,commandArguments:t})=>({...rC(e,t),isSync:!0}),"mapCommandSync"),rC=i((e,t)=>{if(t.length>0)throw new TypeError(`The command and its arguments must be passed as a single string: ${e} ${t}.`);let[n,...r]=F4(e);return{file:n,commandArguments:r}},"parseCommand"),F4=i(e=>{if(typeof e!="string")throw new TypeError(`The command must be a string: ${String(e)}.`);let t=e.trim();if(t==="")return[];let n=[];for(let r of t.split(
987
- B4)){let o=n.at(-1);o&&o.endsWith("\\")?n[n.length-1]=`${o.slice(0,-1)} ${r}`:n.push(r)}return n},"parseCommandString"),B4=/ +/g;var oC=i((e,t,n)=>{e.sync=t(U4,n),e.s=e.sync},"setScriptSync"),sC=i(({options:e})=>iC(e),"mapScriptAsync"),U4=i(({options:e})=>({...iC(e),isSync:!0}),"mapScriptSync"),iC=i(e=>({options:{...q4(e),...e}}),"getScriptOptions"),q4=i(({input:e,inputFile:t,stdio:n})=>e===void 0&&t===void 0&&n===void 0?{stdin:"inherit"}:{},"getScriptStdinOption"),aC={preferLocal:!0};var cC=zn(()=>({})),Oxe=zn(()=>({isSync:!0})),$xe=zn(tC),Txe=zn(nC),Cxe=zn(wO),Rxe=zn(sC,{},aC,oC),{sendMessage:jxe,getOneMessage:Ixe,getEachMessage:Dxe,getCancelSignal:Nxe}=sT();var _i={};function lC(e){_i=e}i(lC,"setProcessReporter");function W4(e){return e==="inherit"?"inherit":_i.quiet?"pipe":_i.verbose?"stream":e}i(W4,"effectiveStdio");function V4(e){return e!=="stream"?{stdio:e}:{stdin:"pipe",stdout:_i.json?"pipe":["pipe","inherit"],stderr:["pipe","inherit"]}}i(V4,"outputTargets");var K4=1e4,J4=3e4,Y4=18e4;function X4(e){let t=Math.round((Date.now()-e)/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m${String(t%60).padStart(2,"0")}s`}i(X4,"elapsed");function Q4(e,t,n=88){
987
+ B4)){let o=n.at(-1);o&&o.endsWith("\\")?n[n.length-1]=`${o.slice(0,-1)} ${r}`:n.push(r)}return n},"parseCommandString"),B4=/ +/g;var oC=i((e,t,n)=>{e.sync=t(U4,n),e.s=e.sync},"setScriptSync"),sC=i(({options:e})=>iC(e),"mapScriptAsync"),U4=i(({options:e})=>({...iC(e),isSync:!0}),"mapScriptSync"),iC=i(e=>({options:{...q4(e),...e}}),"getScriptOptions"),q4=i(({input:e,inputFile:t,stdio:n})=>e===void 0&&t===void 0&&n===void 0?{stdin:"inherit"}:{},"getScriptStdinOption"),aC={preferLocal:!0};var cC=zn(()=>({})),$xe=zn(()=>({isSync:!0})),Txe=zn(tC),Cxe=zn(nC),Rxe=zn(wO),jxe=zn(sC,{},aC,oC),{sendMessage:Ixe,getOneMessage:Dxe,getEachMessage:Nxe,getCancelSignal:Lxe}=sT();var _i={};function lC(e){_i=e}i(lC,"setProcessReporter");function W4(e){return e==="inherit"?"inherit":_i.quiet?"pipe":_i.verbose?"stream":e}i(W4,"effectiveStdio");function V4(e){return e!=="stream"?{stdio:e}:{stdin:"pipe",stdout:_i.json?"pipe":["pipe","inherit"],stderr:["pipe","inherit"]}}i(V4,"outputTargets");var K4=1e4,J4=3e4,Y4=18e4;function X4(e){let t=Math.round((Date.now()-e)/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m${String(t%60).padStart(2,"0")}s`}i(X4,"elapsed");function Q4(e,t,n=88){
988
988
  let r=[];for(let s=0;s<t.length;s+=1){let a=t[s]??"";if(a==="-f"||a==="--file"){s+=1;continue}r.push(a)}let o=[e,...r].join(" ");return o.length<=n?o:`${o.slice(0,n-1)}\u2026`}i(Q4,"describeCommand");function eK(e,t){if(_i.quiet)return()=>{};let n=Date.now(),r=Q4(e,t),o=!1,s=i(()=>{process.stderr.write(`wait still running: ${r} (${X4(n)})
989
989
  `),!o&&Date.now()-n>=Y4&&(o=!0,process.stderr.write(` -> a first build of the panel image takes several minutes; Ctrl-C is safe, and --verbose shows its output
990
- `))},"announce"),a,c=setTimeout(()=>{s(),a=setInterval(s,J4),a.unref?.()},K4);return c.unref?.(),()=>{clearTimeout(c),a&&clearInterval(a)}}i(eK,"startHeartbeat");async function _(e,t=[],n={}){let r=W4(n.stdio??"pipe"),o={cwd:n.cwd,env:n.env,input:n.input,reject:n.reject??!0,shell:!1,timeout:n.timeout,killSignal:n.killSignal,...V4(r)},s=r==="pipe"?eK(e,t):()=>{};try{let a=await cC(e,[...t],o),c=a.failed&&a.exitCode===void 0&&!a.signal&&!a.timedOut;return{stdout:typeof a.stdout=="string"?a.stdout:
991
- "",stderr:typeof a.stderr=="string"?a.stderr:"",exitCode:a.exitCode??(a.failed?1:0),failed:a.failed,...c&&"originalMessage"in a?{error:String(a.originalMessage)}:{}}}finally{s()}}i(_,"runProcess");function uC(e,t,n={}){let r=n.logFile?G4(n.logFile,"a",384):null;try{let o=H4(e,[...t],{cwd:n.cwd,env:n.env,shell:!1,detached:!0,stdio:r===null?"ignore":["ignore",r,r]});return o.unref(),o.pid}finally{r!==null&&Z4(r)}}i(uC,"spawnDetached");var tK=/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/;function No(e,t="Docker identifier"){if(!tK.test(e))throw new C(`invalid ${t}: ${e}`);return e}i(No,"identifier");var nK=l.object({Id:l.string(),Name:l.string(),Config:l.object({Image:l.string(),Labels:l.record(l.string(),l.string()).nullable().optional()}).passthrough(),State:l.object({Status:l.string(),Health:l.object({Status:l.string()}).passthrough().nullable().optional()}).passthrough(),HostConfig:l.object({NetworkMode:l.string().optional()}).passthrough().
990
+ `))},"announce"),a,c=setTimeout(()=>{s(),a=setInterval(s,J4),a.unref?.()},K4);return c.unref?.(),()=>{clearTimeout(c),a&&clearInterval(a)}}i(eK,"startHeartbeat");async function _(e,t=[],n={}){let r=W4(n.stdio??"pipe"),o={cwd:n.cwd,env:n.env,input:n.input,reject:n.reject??!0,shell:!1,timeout:n.timeout,...V4(r)},s=r==="pipe"?eK(e,t):()=>{};try{let a=await cC(e,[...t],o),c=a.failed&&a.exitCode===void 0&&!a.signal&&!a.timedOut;return{stdout:typeof a.stdout=="string"?a.stdout:"",stderr:typeof a.stderr==
991
+ "string"?a.stderr:"",exitCode:a.exitCode??(a.failed?1:0),failed:a.failed,...c&&"originalMessage"in a?{error:String(a.originalMessage)}:{}}}finally{s()}}i(_,"runProcess");function uC(e,t,n={}){let r=n.logFile?G4(n.logFile,"a",384):null;try{let o=H4(e,[...t],{cwd:n.cwd,env:n.env,shell:!1,detached:!0,stdio:r===null?"ignore":["ignore",r,r]});return o.unref(),o.pid}finally{r!==null&&Z4(r)}}i(uC,"spawnDetached");var tK=/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/;function No(e,t="Docker identifier"){if(!tK.test(e))throw new C(`invalid ${t}: ${e}`);return e}i(No,"identifier");var nK=l.object({Id:l.string(),Name:l.string(),Config:l.object({Image:l.string(),Labels:l.record(l.string(),l.string()).nullable().optional()}).passthrough(),State:l.object({Status:l.string(),Health:l.object({Status:l.string()}).passthrough().nullable().optional()}).passthrough(),HostConfig:l.object({NetworkMode:l.string().optional()}).passthrough().
992
992
  optional(),Mounts:l.array(l.object({Source:l.string().optional(),RW:l.boolean().optional()}).passthrough()).optional(),NetworkSettings:l.object({Networks:l.record(l.string(),l.unknown()).nullable().optional(),Ports:l.record(l.string(),l.array(l.object({HostIp:l.string().optional(),HostPort:l.string().optional()})).nullable()).nullable().optional()}).passthrough()}).passthrough();async function Ct(){let e=await _("docker",["info"],{reject:!1});if(e.error)throw new L("the docker CLI is not install\
993
993
  ed","install Docker Engine 24 or newer; Portta never installs Docker or invokes a system package manager");if(e.exitCode!==0)throw new L("cannot talk to the Docker daemon","start Docker or check DOCKER_HOST")}i(Ct,"requireDocker");async function pC(){let e=await _("docker",["info","--format","{{.OperatingSystem}}"],{reject:!1,timeout:8e3});if(e.exitCode!==0)return null;let t=e.stdout.trim();return t===""?null:t}i(pC,"dockerOperatingSystem");async function dC(){let e=await _("docker",["stats","--\
994
994
  no-stream","--format","{{json .}}"],{reject:!1,timeout:2e4});if(e.exitCode!==0||e.stdout.trim()==="")return[];let t=[];for(let n of e.stdout.split(`
@@ -1167,7 +1167,7 @@ savedAt??null};if(r.json)return r.data(p);r.line(`${o}: ${p.user} (${p.role}, vi
1167
1167
  al for ${o}`)}i(lD,"authLogout");async function uD(e,t){let n=new A(da(t)),r=ua(),o=Object.entries(r.panels).map(([s,a])=>({url:s,user:a.user,role:a.role,savedAt:a.savedAt}));if(n.json)return n.data({panels:o});if(o.length===0){n.line("no saved credentials");return}for(let s of o)n.line(`${s.url} ${s.user} ${s.role}`)}i(uD,"authWhoami");async function pD(e,t){let{client:n,output:r}=de(t),o=await n.request("GET",`/auth/tokens${e.all?"?all=true":""}`);if(r.json)return r.data(o);if(o.tokens.length===
1168
1168
  0)return r.line("no tokens");for(let s of o.tokens)r.line([s.id,s.enabled?"active":"revoked",s.actorKind,s.name,s.user].join(" "))}i(pD,"authTokenList");async function dD(e,t){if(!e.name)throw new C("--name is required");let{client:n,output:r}=de(t),o=await n.request("POST","/auth/tokens",{name:e.name,actorKind:e.human?"human":"agent",...e.scopes?{scopes:e.scopes.split(",").map(s=>s.trim()).filter(Boolean)}:{},...e.expiresInDays?{expiresInDays:Number(e.expiresInDays)}:{}});if(r.json)return r.data(
1169
1169
  o);r.line(`token: ${o.token}`),r.warning("this is the only time the token is shown"),r.hint("save it with `portta auth login --token \u2026`, or set PORTTA_TOKEN for one command")}i(dD,"authTokenCreate");async function fD(e,t,n){let{client:r,output:o}=de(n);await r.request("DELETE",`/auth/tokens/${encodeURIComponent(e)}`),o.progress(`revoked ${e}`)}i(fD,"authTokenRevoke");import{join as mD}from"node:path";function My(e){return e.optsWithGlobals()}i(My,"globals");function C5(e,t){let n=Se(t);return[{image:n.runtime,args:["build","--build-arg",`PORTTA_VERSION=${t}`,"--target","runtime","-f","apps/web/Dockerfile","-t",n.runtime,"."]},{image:n.apply,args:["build","--build-arg",`PORTTA_VERSION=${t}`,"-t",n.apply,mD(e,"docker","images","apply")]},{image:n.toolbox,args:["build","--build-arg",`PORTTA_VERSION=${t}`,"-t",n.toolbox,mD(e,"docker","images","toolbox")]}]}i(C5,"localReleaseBuilds");async function hD(e){
1170
- let t=E({profile:My(e).profile}),n=new A(My(e));await Ct();let r=C5(t.root,t.version);n.step(`local release ${t.version}`);for(let o of r)n.progress(`building ${o.image}`),await _("docker",o.args,{cwd:t.root,stdio:"inherit"});if(My(e).json)n.data({version:t.version,images:r.map(({image:o})=>o)});else for(let{image:o}of r)n.progress(`ready ${o}`)}i(hD,"buildCommand");import{copyFileSync as cX,existsSync as Ea,mkdirSync as lX,rmSync as uX,statSync as pX}from"node:fs";import{basename as dX,dirname as fX,join as mX}from"node:path";import{existsSync as tX,mkdirSync as CN,readFileSync as nX}from"node:fs";import{join as Ir}from"node:path";import{chmodSync as R5,existsSync as j5,mkdirSync as I5}from"node:fs";import{join as D5}from"node:path";var zy=[{path:"config/traefik/dynamic",mode:493},{path:"config/tls",mode:493},{path:"state/auth",mode:448},{path:"state/ssh",mode:448},{path:"state/runner",mode:448},{path:"state/cloudflared",mode:448},{path:"state/traefik/acme",mode:448},{path:"state/access",mode:493},{path:"state/tailscale",mode:493},{path:"state/git",mode:493},{path:"state/metrics",mode:493},{path:"state/environment",mode:493},{path:"state/logs",mode:493}];function rs(e){for(let{path:t,mode:n}of zy){let r=D5(e,t),o=!j5(r);I5(
1170
+ let t=E({profile:My(e).profile}),n=new A(My(e));await Ct();let r=C5(t.root,t.version);n.step(`local release ${t.version}`);for(let o of r)n.progress(`building ${o.image}`),await _("docker",o.args,{cwd:t.root,stdio:"inherit"});if(My(e).json)n.data({version:t.version,images:r.map(({image:o})=>o)});else for(let{image:o}of r)n.progress(`ready ${o}`)}i(hD,"buildCommand");import{copyFileSync as lX,existsSync as Ea,mkdirSync as uX,rmSync as pX,statSync as dX}from"node:fs";import{basename as fX,dirname as mX,join as hX}from"node:path";import{existsSync as nX,mkdirSync as CN,readFileSync as rX}from"node:fs";import{join as Ir}from"node:path";import{chmodSync as R5,existsSync as j5,mkdirSync as I5}from"node:fs";import{join as D5}from"node:path";var zy=[{path:"config/traefik/dynamic",mode:493},{path:"config/tls",mode:493},{path:"state/auth",mode:448},{path:"state/ssh",mode:448},{path:"state/runner",mode:448},{path:"state/cloudflared",mode:448},{path:"state/traefik/acme",mode:448},{path:"state/access",mode:493},{path:"state/tailscale",mode:493},{path:"state/git",mode:493},{path:"state/metrics",mode:493},{path:"state/environment",mode:493},{path:"state/logs",mode:493}];function rs(e){for(let{path:t,mode:n}of zy){let r=D5(e,t),o=!j5(r);I5(
1171
1171
  r,{recursive:!0}),(o||n===448)&&R5(r,n)}}i(rs,"ensureInstallationDirectories");import{join as N5}from"node:path";async function Ap(e){if(e.env.PORTTA_LOCAL_RELEASE!=="true")return;let t=[];for(let n of Object.values(Se(e.version)))(await _("docker",["image","inspect",n],{reject:!1})).exitCode!==0&&t.push(n);if(t.length>0)throw new L(`local release ${e.version} is incomplete: missing ${t.join(", ")}`,"run just build")}i(Ap,"requireLocalRelease");function Op(e){let t=Se(e.version).runtime;je(N5(e.root,".env"),{PORTTA_AUTH_IMAGE:t,PORTTA_WEB_IMAGE:t,PORTTA_WEB_BUILD:"false",PORTTA_WEB_DEV:"false"})}i(Op,"sele\
1172
1172
  ctLocalRelease");import{homedir as G5}from"node:os";import{accessSync as L5,constants as M5,globSync as z5,statSync as bD}from"node:fs";import{homedir as F5}from"node:os";import{join as yn}from"node:path";function B5(e){let[t,n]=e.split(".").map(Number);return t===100&&n!==void 0&&n>=64&&n<=127}i(B5,"isTailscaleRange");function yD(e){let t=e.split(".").map(Number);if(t.length!==4||t.some(o=>!Number.isInteger(o)||o<0||o>255))return!1;let[n,r]=t;return n===10||n===127||n===172&&r>=16&&r<=31||n===192&&r===168||n===169&&r===254?!0:B5(e)}i(yD,"isPrivateAddress");function gD(e){try{return L5(e,M5.X_OK),bD(e).isFile()}catch{return!1}}i(gD,"executable");async function fa(e){let t=await _("which",[e],{reject:!1}),
1173
1173
  n=t.stdout.trim().split(`
@@ -1220,25 +1220,25 @@ tal","--format=csv,noheader,nounits"])]),r=null;if(n!==null){let o=new Map;for(l
1220
1220
  e.id||e.id!==""&&o.id.startsWith(e.id)||e.id!==""&&e.id.startsWith(o.id.slice(0,12)));if(n)return n;let r=t.find(o=>o.name===e.name);return r||{id:e.id||e.name,name:e.name||e.id.slice(0,12),labels:{}}}i(VY,"matchIdentity");function KY(e,t,n){if(!n)return 0;let r=0;for(let[o,s]of n.byContainer){let a=t.find(c=>c.id.startsWith(o)||o.startsWith(c.id));a&&ar(a.labels)===e&&(r+=s)}return r}i(KY,"gpuMemoryOf");async function JY(e,t){let[n,r]=await Promise.all([J(!1),dC()]);if(n.length===0&&r.length===
1221
1221
  0)return[];let o=n.map(p=>({id:p.id,name:p.name,labels:p.labels})),s=r.map(p=>{let d=VY(p,o);return yS(bS(p.raw),{id:d.id,name:d.name,service:wS(d.labels)})}),a=vS(s,o),c=BD(o,e);XD(e,new Set(c.keys()));let u=process.env.PORTTA_PROJECT_NAME?.trim()||"portta";return Promise.all(a.map(async p=>{let d=c.get(p.composeProject),f=d?await UD(d):null;d&&await YD(e,p.composeProject,d);let m=KY(p.composeProject,o,t),h=m>0?{...p,gpuMemoryBytes:m}:p,b=p.composeProject===u?{...h,own:!0}:h;return f?{...b,git:f}:
1222
1222
  b}))}i(JY,"collectProjects");function YY(e){let t=null;try{t=Intl.DateTimeFormat().resolvedOptions().timeZone||null}catch{}return{name:t,offsetMinutes:-new Date(e).getTimezoneOffset()}}i(YY,"serverTimezone");async function zp(e,t=Date.now()){let n=Math.floor(t/1e3),r=await WY(),o=await oN(),[s,a,c,u,p,d,f]=await Promise.allSettled([o.mem(),o.currentLoad(),o.fsSize(),pC(),Promise.resolve(o.time()),o.cpuTemperature(),o.battery()]),m=r?.os??{},h=RD(e,typeof m.hostname=="string"?m.hostname:null),b=fS(
1223
- h,n),g=bt(c)??[];b.host=gS({system:r?.system,os:r?.os,cpu:r?.cpu,mem:bt(s),currentLoad:bt(a),loadavg:GY(),graphics:r?.graphics,time:bt(p),timezone:YY(t),cpuTemperature:bt(d),battery:bt(f),chassis:r?.chassis,storage:mS(e,g)});let y=await eN(t);y?.memory&&(b.host.gpuMemory=y.memory);let w=bt(u)??null;b.runtime={name:hS(w)};try{b.projects=await JY(e,y)}catch{b.projects=[]}return b.dockerStorage=nN(t),b}i(zp,"collectSnapshot");import{existsSync as bN,lstatSync as mN,mkdirSync as A7,readdirSync as yN,readFileSync as O7,rmSync as hN,statSync as $7}from"node:fs";import{homedir as gN}from"node:os";import{join as lt,relative as T7,resolve as C7,sep as R7}from"node:path";import{closeSync as XY,constants as sw,existsSync as Sa,fstatSync as QY,lstatSync as e7,openSync as t7,readFileSync as n7,readSync as r7,realpathSync as o7}from"node:fs";import{basename as Fp,dirname as s7,join as jr,resolve as Bp}from"node:path";var aN=za(vy(),1);function as(e){return e.optsWithGlobals()}i(as,"globals");async function cN(e,t){let n=as(t),r=E({profile:n.profile}),o=Ns(await J(),r.config.domain,r.config.tlsEnabled?"https":"http").filter(a=>!e.project||a.name===e.project),s=new A(n);if(s.json)s.data({instance:{name:r.config.projectName},projects:o.map(a=>({name:a.name,state:a.state,serviceCount:a.services.length,urls:a.urls}))});else for(let a of o)s.line(`${a.name} ${a.state} ${a.services.length} services ${a.urls.length} urls`)}i(cN,"proj\
1223
+ h,n),g=bt(c)??[];b.host=gS({system:r?.system,os:r?.os,cpu:r?.cpu,mem:bt(s),currentLoad:bt(a),loadavg:GY(),graphics:r?.graphics,time:bt(p),timezone:YY(t),cpuTemperature:bt(d),battery:bt(f),chassis:r?.chassis,storage:mS(e,g)});let y=await eN(t);y?.memory&&(b.host.gpuMemory=y.memory);let w=bt(u)??null;b.runtime={name:hS(w)};try{b.projects=await JY(e,y)}catch{b.projects=[]}return b.dockerStorage=nN(t),b}i(zp,"collectSnapshot");import{existsSync as bN,lstatSync as mN,mkdirSync as O7,readdirSync as yN,readFileSync as $7,rmSync as hN,statSync as T7}from"node:fs";import{homedir as gN}from"node:os";import{join as lt,relative as C7,resolve as R7,sep as j7}from"node:path";import{closeSync as XY,constants as sw,existsSync as Sa,fstatSync as QY,lstatSync as e7,openSync as t7,readFileSync as n7,readSync as r7,realpathSync as o7}from"node:fs";import{basename as Fp,dirname as s7,join as jr,resolve as Bp}from"node:path";var aN=za(vy(),1);function as(e){return e.optsWithGlobals()}i(as,"globals");async function cN(e,t){let n=as(t),r=E({profile:n.profile}),o=Ns(await J(),r.config.domain,r.config.tlsEnabled?"https":"http").filter(a=>!e.project||a.name===e.project),s=new A(n);if(s.json)s.data({instance:{name:r.config.projectName},projects:o.map(a=>({name:a.name,state:a.state,serviceCount:a.services.length,urls:a.urls}))});else for(let a of o)s.line(`${a.name} ${a.state} ${a.services.length} services ${a.urls.length} urls`)}i(cN,"proj\
1224
1224
  ectList");async function lN(e,t){let n=as(t),r=E({profile:n.profile}),o=Ns(await J(),r.config.domain,r.config.tlsEnabled?"https":"http").find(c=>c.name===e);if(!o)throw new C(`project not found: ${e}`);let s=new A(n),a={instance:{name:r.config.projectName},name:o.name,state:o.state,services:o.services.map(c=>({name:c.labels["com.docker.compose.service"]??c.name,container:c.name,image:c.image,state:c.state,ports:c.ports,networks:c.networks})),urls:o.urls};if(s.json)s.data(a);else{s.line(`${o.name}\
1225
1225
  \xB7 ${o.state}`);for(let c of a.services)s.line(`${c.name} ${c.state} ${c.image}`);for(let c of a.urls)s.line(c.url)}}i(lN,"projectShow");function i7(e,t){let n=`${e} ${t}`.toLowerCase();return/postgres|mysql|mariadb|mongo/.test(n)?"database":/redis|valkey|memcached/.test(n)?"cache":/rabbitmq|kafka|nats/.test(n)?"queue":"application"}i(i7,"classify");async function uN(e,t){let n=as(t),r=E({profile:n.profile}),o=(await J()).filter(a=>a.labels["com.docker.compose.project"]&&(!e.project||a.labels["\
1226
1226
  com.docker.compose.project"]===e.project)).map(a=>({project:a.labels["com.docker.compose.project"],service:a.labels["com.docker.compose.service"]??a.name,container:a.name,state:a.state,kind:i7(a.image,a.name),ports:a.ports,networks:a.networks,routed:zt(a.labels)})).sort((a,c)=>`${a.project}/${a.service}`.localeCompare(`${c.project}/${c.service}`)),s=new A(n);if(s.json)s.data({instance:{name:r.config.projectName},services:o});else for(let a of o)s.line(`${a.project} ${a.service} ${a.kind} ${a.state}`)}
1227
1227
  i(uN,"servicesCommand");var a7=l.union([l.string(),l.number(),l.object({target:l.union([l.string(),l.number()]).optional(),published:l.union([l.string(),l.number()]).optional()}).passthrough()]),c7=l.object({image:l.string().optional(),ports:l.array(a7).optional(),container_name:l.string().optional(),expose:l.array(l.union([l.string(),l.number()])).optional(),networks:l.union([l.array(l.string()),l.record(l.string(),l.unknown())]).optional(),volumes:l.array(l.union([l.string(),l.object({source:l.
1228
1228
  string().optional(),target:l.string().optional()}).passthrough()])).optional(),labels:l.union([l.array(l.string()),l.record(l.string(),l.union([l.string(),l.number(),l.boolean()]))]).optional()}).passthrough(),l7=l.object({name:l.string().optional(),services:l.record(l.string(),c7)}).passthrough(),u7=/postgres|postgis|timescale|mysql|mariadb|percona|redis|valkey|keydb|mongo|memcached|elasticsearch|opensearch|rabbitmq|kafka|clickhouse|cassandra|neo4j/i,p7=/nginx|httpd|apache|caddy|traefik|node|php|python|ruby|golang|openresty|haproxy|whoami|frankenphp|mailpit|mailhog|rustfs|minio/i,
1229
- d7=/(^|[-_])(worker|queue|scheduler|cron|consumer|beat|migrator|migrate|init|seed|setup)([-_]|$)/i,f7=/(^|[-_])(web|app|api|frontend|backend|site|www|http|nginx|server|ui|admin|dashboard|gateway)([-_]|$)/i;function m7(e,t){return d7.test(t)?"worker":u7.test(e)?"datastore":p7.test(e)||f7.test(t)?"http":"unknown"}i(m7,"classifyCompose");function h7(e){return(e.ports??[]).flatMap(t=>{if(typeof t=="object"&&t.published!==void 0)return[{host:String(t.published),container:String(t.target??"")}];if(typeof t==
1230
- "string"){let n=/^(?:[^:]+:)?(\d+|\$\{[^}]*\}):(\d+)(?:\/\w+)?$/.exec(t);return n?[{host:n[1],container:n[2]}]:[]}return[]})}i(h7,"publishedPorts");function g7(e){let t=(e.ports??[]).flatMap(n=>{if(typeof n=="object"&&n.target!==void 0)return[String(n.target)];if(typeof n=="number")return[String(n)];let r=/(?:^|:)(\d+)(?:\/\w+)?$/.exec(String(n));return r?[r[1]]:[]});return[...new Set(t)]}i(g7,"containerPorts");function b7(e){return Array.isArray(e.labels)?Object.fromEntries(e.labels.map(t=>{let n=t.
1231
- indexOf("=");return[t.slice(0,n),t.slice(n+1)]})):Object.fromEntries(Object.entries(e.labels??{}).map(([t,n])=>[t,String(n)]))}i(b7,"labelsOf");function y7(e){return["compose.yaml","compose.yml","docker-compose.yaml","docker-compose.yml"].map(t=>jr(e,t)).filter(Sa)}i(y7,"composeCandidates");async function pN(){try{return await J()}catch{return[]}}i(pN,"hostContainers");function sN(e){try{return o7(e)}catch{return Bp(e)}}i(sN,"safeRealpath");function w7(e){let t=Up(e,k7,!0);return t==="absent"||t===
1232
- "refused"?null:/^name:[ \t]*["']?([^"'\s#]+)/m.exec(t)?.[1]??null}i(w7,"declaredComposeName");function v7(e){let t=jr(e,go);if(!Sa(t))return{source:"defaults",path:go,config:DE(),issues:[]};let n;try{n=(0,aN.parse)(n7(t,"utf8"))}catch(o){let s=o instanceof Error?o.message:String(o);return{source:"file",path:go,config:null,issues:[{path:"",message:s}]}}let r=NE(n);return r.ok?{source:"file",path:go,config:r.config,issues:[]}:{source:"file",path:go,config:null,issues:r.issues}}i(v7,"readProjectCon\
1233
- fig");function Up(e,t,n=!1){if(e7(e,{throwIfNoEntry:!1})===void 0)return"absent";let r;try{let o=n?0:sw.O_NOFOLLOW;r=t7(e,sw.O_RDONLY|o|sw.O_NONBLOCK);let s=QY(r);if(!s.isFile()||s.size>t)return"refused";let a=Buffer.alloc(s.size),c=0;for(;c<a.length;){let u=r7(r,a,c,a.length-c,c);if(u===0)break;c+=u}return a.subarray(0,c).toString("utf8")}catch{return"refused"}finally{r!==void 0&&XY(r)}}i(Up,"readSmallFile");var S7=64*1024;function x7(e,t=!1){return Up(e,S7,t)}i(x7,"readSmallEnv");var k7=1024*1024;
1234
- async function iw(e,t={},n){let r=Bp(e),o;if(t.file){if(o=Bp(r,t.file),!Sa(o))throw new C(`no Compose file at ${o}`)}else{let x=y7(r);if(!x[0])throw new C(`no Compose file found in ${r}`);o=x[0]}let s=s7(o),a=t.unattended===!0,c=a?await _("docker",["compose","-f",o,"config","--format","json","--no-interpolate"],{cwd:s,timeout:2e4,killSignal:"SIGKILL"}):await _("docker",["compose","-f",o,"config","--format","json"],{cwd:s,reject:!1});!a&&c.exitCode!==0&&(c=await _("docker",["compose","-f",o,"conf\
1235
- ig","--format","json","--no-interpolate"],{cwd:s}));let u=l7.parse(JSON.parse(c.stdout)),p=["compose.portta.yaml","compose.portta.yml"].map(x=>jr(".portta",x)).find(x=>Sa(jr(s,x)))??["compose.portta.yaml","compose.portta.yml"].find(x=>Sa(jr(s,x)))??null,d=x7(jr(s,".env"),!a);if(d==="refused")throw new C(`${jr(s,".env")} is not read: ${a?"a link, a pipe":"a pipe"} or a file over 64 KB`);let f=d==="absent"||d==="refused"?void 0:me(d).get("COMPOSE_PROJECT_NAME"),m=w7(o),h=f||Vr(m??u.name??Fp(s)),b=Object.
1236
- entries(u.services).map(([x,$])=>({name:x,image:$.image??null,kind:m7($.image??"",x),container_name:$.container_name??null,published_ports:h7($),container_ports:g7($),expose:($.expose??[]).map(String),networks:Array.isArray($.networks)?$.networks:Object.keys($.networks??{}),volumes:($.volumes??[]).map(z=>typeof z=="string"?z.split(":")[0]:z.source??z.target??""),labels:b7($)})),g=n??await pN(),y=sN(s),w=i(x=>x.labels["com.docker.compose.project.working_dir"]??null,"workingDirOf"),P=i(x=>{let $=w(
1237
- x);return x.labels["com.docker.compose.project"]===h&&$!==null&&sN($)===y},"isThisProject"),R=b.flatMap(x=>{if(!x.container_name)return[];let $=g.find(D=>D.name===x.container_name);if(!$||P($))return[];let z=$.labels["com.docker.compose.project"];return[{service:x.name,container_name:x.container_name,used_by:z?`Compose project ${z}`:"a container outside Compose",state:$.state}]}),O=[...new Set(g.filter(x=>x.labels["com.docker.compose.project"]===h&&!P(x)).map(w).filter(x=>x!==null))].sort();return{
1238
- path:s,compose_file:Fp(o),gateway_overlay:p,project_config:v7(s),project:{name:h,source:f?".env":m?"compose name:":"directory name (implicit)"},domain:E({required:!1}).config.domain,services:b,findings:{published_host_ports:b.filter(x=>x.published_ports.length>0).map(x=>x.name),fixed_container_names:b.filter(x=>x.container_name).map(x=>x.name),published_datastores:b.filter(x=>x.kind==="datastore"&&x.published_ports.length>0).map(x=>x.name),implicit_namespace:!f&&!m,already_adopted:p!==null,container_name_collisions:R,
1239
- namespace_in_use:O.length>0?{project:h,working_dirs:O}:null,name_without_env:m!==null&&!f?m:null}}}i(iw,"analyze");async function dN(e,t,n){let r=await pN(),o=await iw(e,t,r),s=new A(as(n));if(s.json)s.data(o);else{s.line(`Project: ${Fp(o.path)}`),s.line(` path ${o.path}`),s.line(` compose file ${o.compose_file}`),s.line(` gateway overlay ${o.gateway_overlay??"none"}`),s.line(` project namespace ${o.project.name} (${o.project.source})`);let a=[...new Set(
1240
- o.services.flatMap(u=>Object.entries(u.labels).filter(([p])=>p.startsWith("portta.project")).map(([p,d])=>`${p}=${d}`)))];s.line(` declared identity ${a.length?a.join(" "):"none (inferred from the Compose labels)"}`);let c=o.project_config;if(c.issues.length){s.line(" project.yaml invalid, so its defaults are not applied:");for(let u of c.issues)s.line(` ${u.path?`${u.path}: `:""}${u.message}`)}else if(c.config){let u=c.config.name?`name ${c.config.name}`:"declares nothing";s.
1241
- line(` project.yaml ${c.source==="file"?u:"absent, so defaults apply"}`)}s.line(`
1229
+ d7=/(^|[-_])(worker|queue|scheduler|cron|consumer|beat|migrator|migrate|init|seed|setup)([-_]|$)/i,f7=/(^|[-_])(web|app|api|frontend|backend|site|www|http|nginx|server|ui|admin|dashboard|gateway)([-_]|$)/i;function m7(e,t){return d7.test(t)?"worker":u7.test(e)?"datastore":p7.test(e)||f7.test(t)?"http":"unknown"}i(m7,"classifyCompose");function h7(e){let t=[],n=0,r="";for(let o of e)o==="{"&&(n+=1),o==="}"&&(n=Math.max(0,n-1)),o===":"&&n===0?(t.push(r),r=""):r+=o;return t.push(r),t}i(h7,"portPart\
1230
+ s");function g7(e){return(e.ports??[]).flatMap(t=>{if(typeof t=="object"&&t.published!==void 0)return[{host:String(t.published),container:String(t.target??"")}];if(typeof t!="string")return[];let n=h7(t);if(n.length<2)return[];let r=n[n.length-2].trim(),o=n[n.length-1].replace(/\/\w+$/,"").trim();return r===""?[]:[{host:r,container:o}]})}i(g7,"publishedPorts");function b7(e){let t=(e.ports??[]).flatMap(n=>{if(typeof n=="object"&&n.target!==void 0)return[String(n.target)];if(typeof n=="number")return[
1231
+ String(n)];let r=/(?:^|:)(\d+)(?:\/\w+)?$/.exec(String(n));return r?[r[1]]:[]});return[...new Set(t)]}i(b7,"containerPorts");function y7(e){return Array.isArray(e.labels)?Object.fromEntries(e.labels.map(t=>{let n=t.indexOf("=");return[t.slice(0,n),t.slice(n+1)]})):Object.fromEntries(Object.entries(e.labels??{}).map(([t,n])=>[t,String(n)]))}i(y7,"labelsOf");function w7(e){return["compose.yaml","compose.yml","docker-compose.yaml","docker-compose.yml"].map(t=>jr(e,t)).filter(Sa)}i(w7,"composeCandid\
1232
+ ates");async function pN(){try{return await J()}catch{return[]}}i(pN,"hostContainers");function sN(e){try{return o7(e)}catch{return Bp(e)}}i(sN,"safeRealpath");function v7(e){let t=Up(e,_7,!0);return t==="absent"||t==="refused"?null:/^name:[ \t]*["']?([^"'\s#]+)/m.exec(t)?.[1]??null}i(v7,"declaredComposeName");function S7(e){let t=jr(e,go);if(!Sa(t))return{source:"defaults",path:go,config:DE(),issues:[]};let n;try{n=(0,aN.parse)(n7(t,"utf8"))}catch(o){let s=o instanceof Error?o.message:String(o);
1233
+ return{source:"file",path:go,config:null,issues:[{path:"",message:s}]}}let r=NE(n);return r.ok?{source:"file",path:go,config:r.config,issues:[]}:{source:"file",path:go,config:null,issues:r.issues}}i(S7,"readProjectConfig");function Up(e,t,n=!1){if(e7(e,{throwIfNoEntry:!1})===void 0)return"absent";let r;try{let o=n?0:sw.O_NOFOLLOW;r=t7(e,sw.O_RDONLY|o|sw.O_NONBLOCK);let s=QY(r);if(!s.isFile()||s.size>t)return"refused";let a=Buffer.alloc(s.size),c=0;for(;c<a.length;){let u=r7(r,a,c,a.length-c,c);if(u===
1234
+ 0)break;c+=u}return a.subarray(0,c).toString("utf8")}catch{return"refused"}finally{r!==void 0&&XY(r)}}i(Up,"readSmallFile");var x7=64*1024;function k7(e,t=!1){return Up(e,x7,t)}i(k7,"readSmallEnv");var _7=1024*1024;async function iw(e,t={},n){let r=Bp(e),o;if(t.file){if(o=Bp(r,t.file),!Sa(o))throw new C(`no Compose file at ${o}`)}else{let x=w7(r);if(!x[0])throw new C(`no Compose file found in ${r}`);o=x[0]}let s=s7(o),a=t.unattended===!0,c=a?await _("docker",["compose","-f",o,"config","--format",
1235
+ "json","--no-interpolate"],{cwd:s,timeout:2e4}):await _("docker",["compose","-f",o,"config","--format","json"],{cwd:s,reject:!1});!a&&c.exitCode!==0&&(c=await _("docker",["compose","-f",o,"config","--format","json","--no-interpolate"],{cwd:s}));let u=l7.parse(JSON.parse(c.stdout)),p=["compose.portta.yaml","compose.portta.yml"].map(x=>jr(".portta",x)).find(x=>Sa(jr(s,x)))??["compose.portta.yaml","compose.portta.yml"].find(x=>Sa(jr(s,x)))??null,d=k7(jr(s,".env"),!a);if(d==="refused")throw new C(`${jr(
1236
+ s,".env")} is not read: ${a?"a link, a pipe":"a pipe"} or a file over 64 KB`);let f=d==="absent"||d==="refused"?void 0:me(d).get("COMPOSE_PROJECT_NAME"),m=v7(o),h=f||Vr(m??u.name??Fp(s)),b=Object.entries(u.services).map(([x,$])=>({name:x,image:$.image??null,kind:m7($.image??"",x),container_name:$.container_name??null,published_ports:g7($),container_ports:b7($),expose:($.expose??[]).map(String),networks:Array.isArray($.networks)?$.networks:Object.keys($.networks??{}),volumes:($.volumes??[]).map(z=>typeof z==
1237
+ "string"?z.split(":")[0]:z.source??z.target??""),labels:y7($)})),g=n??await pN(),y=sN(s),w=i(x=>x.labels["com.docker.compose.project.working_dir"]??null,"workingDirOf"),P=i(x=>{let $=w(x);return x.labels["com.docker.compose.project"]===h&&$!==null&&sN($)===y},"isThisProject"),R=b.flatMap(x=>{if(!x.container_name)return[];let $=g.find(D=>D.name===x.container_name);if(!$||P($))return[];let z=$.labels["com.docker.compose.project"];return[{service:x.name,container_name:x.container_name,used_by:z?`Co\
1238
+ mpose project ${z}`:"a container outside Compose",state:$.state}]}),O=[...new Set(g.filter(x=>x.labels["com.docker.compose.project"]===h&&!P(x)).map(w).filter(x=>x!==null))].sort();return{path:s,compose_file:Fp(o),gateway_overlay:p,project_config:S7(s),project:{name:h,source:f?".env":m?"compose name:":"directory name (implicit)"},domain:E({required:!1}).config.domain,services:b,findings:{published_host_ports:b.filter(x=>x.published_ports.length>0).map(x=>x.name),fixed_container_names:b.filter(x=>x.
1239
+ container_name).map(x=>x.name),published_datastores:b.filter(x=>x.kind==="datastore"&&x.published_ports.length>0).map(x=>x.name),implicit_namespace:!f&&!m,already_adopted:p!==null,container_name_collisions:R,namespace_in_use:O.length>0?{project:h,working_dirs:O}:null,name_without_env:m!==null&&!f?m:null}}}i(iw,"analyze");async function dN(e,t,n){let r=await pN(),o=await iw(e,t,r),s=new A(as(n));if(s.json)s.data(o);else{s.line(`Project: ${Fp(o.path)}`),s.line(` path ${o.path}`),
1240
+ s.line(` compose file ${o.compose_file}`),s.line(` gateway overlay ${o.gateway_overlay??"none"}`),s.line(` project namespace ${o.project.name} (${o.project.source})`);let a=[...new Set(o.services.flatMap(u=>Object.entries(u.labels).filter(([p])=>p.startsWith("portta.project")).map(([p,d])=>`${p}=${d}`)))];s.line(` declared identity ${a.length?a.join(" "):"none (inferred from the Compose labels)"}`);let c=o.project_config;if(c.issues.length){s.line(" project.yaml \
1241
+ invalid, so its defaults are not applied:");for(let u of c.issues)s.line(` ${u.path?`${u.path}: `:""}${u.message}`)}else if(c.config){let u=c.config.name?`name ${c.config.name}`:"declares nothing";s.line(` project.yaml ${c.source==="file"?u:"absent, so defaults apply"}`)}s.line(`
1242
1242
  Services`);for(let u of o.services)s.line(` ${u.name} ${u.image??"<built>"} ${u.kind} ${u.published_ports.map(p=>`${p.host}:${p.container}`).join(",")||"-"}`);if(s.line(`
1243
1243
  Findings`),o.findings.published_host_ports.length){s.line(`
1244
1244
  Published host ports`);for(let u of o.services)for(let p of u.published_ports){let d=r.find(f=>f.ports.some(m=>m.publicPort===Number(p.host)));s.line(` ${u.name} ${p.host} -> ${p.container}${d?` already held by ${d.name}`:""}`)}}else s.line(`
@@ -1254,196 +1254,196 @@ Findings`),o.findings.published_host_ports.length){s.line(`
1254
1254
  ${o.compose_file} sets name: ${o.findings.name_without_env}, and .env does not define COMPOSE_PROJECT_NAME`),s.line(` the overlay writes \${COMPOSE_PROJECT_NAME:-${o.findings.name_without_env}}, so the hostnames follow name: and nothing needs changing;`),s.line(` set COMPOSE_PROJECT_NAME=${o.findings.name_without_env} in .env only if you also run \`docker compose -p\` with another name`)),s.line(`
1255
1255
  Adoption plan`),o.gateway_overlay)s.line(` This project already has ${o.gateway_overlay}.`);else for(let u of o.services.filter(p=>p.kind==="http"))s.line(` ${u.name} port ${u.container_ports[0]??u.expose[0]??"?"} -> http://${o.project.name}-${u.name}.${o.domain}`);s.line(`
1256
1256
  Nothing in this project was modified. See docs/product/guides/adopting-projects.md.`)}}i(dN,"analyzeCommand");async function iN(e,t){let n=await _("git",["-C",e,...t],{reject:!1});return n.exitCode===0?n.stdout.trim():null}i(iN,"gitOutput");async function fN(e,t){let n=Bp(e.path??process.cwd()),r=await iN(n,["rev-parse","--show-toplevel"]),o=await iN(n,["branch","--show-current"]),s=e.base??Fp(r??n).replace(/-(worktree|wt)$/i,""),a=e.suffix??(o?Ha(o):null),c=Vr(s,a);if(e.check!==!1&&(await J()).
1257
- some(d=>d.labels["com.docker.compose.project"]===c))throw new U(`Compose project ${c} is already running`,"pass --no-check only when sharing it is intentional");let u=new A(as(t));u.json?u.data({namespace:c,base:Vr(s),suffix:a}):u.data(c)}i(fN,"namespaceCommand");var _7="this project's containers are gone; start them with the runner (PORTTA_RUNNER=true) or docker compose up in the working directory";async function qp(e,t,n){let r=(await J()).filter(m=>m.labels["com.docker.compose.project"]===e);
1258
- if(r.length===0)throw new C(`no project '${e}' is running`,_7);let o=r.find(m=>m.labels["portta.managed"]==="true");if(o)throw new U(`refusing to ${t} ${o.name}: it is a Portta component`,"gateway components are restarted with portta restart");let s=r.map(m=>({service:m.labels["com.docker.compose.service"]??m.name,name:m.name,dependsOn:HE(m.labels[qE]),id:m.id,state:m.state})),a=Qm(s,"stop"),c=Qm(s,"start"),u=t==="restart"?[...a.map(m=>({...m,verb:"stop"})),...c.map(m=>({...m,verb:"start"}))]:(t===
1257
+ some(d=>d.labels["com.docker.compose.project"]===c))throw new U(`Compose project ${c} is already running`,"pass --no-check only when sharing it is intentional");let u=new A(as(t));u.json?u.data({namespace:c,base:Vr(s),suffix:a}):u.data(c)}i(fN,"namespaceCommand");var P7="this project's containers are gone; start them with the runner (PORTTA_RUNNER=true) or docker compose up in the working directory";async function qp(e,t,n){let r=(await J()).filter(m=>m.labels["com.docker.compose.project"]===e);
1258
+ if(r.length===0)throw new C(`no project '${e}' is running`,P7);let o=r.find(m=>m.labels["portta.managed"]==="true");if(o)throw new U(`refusing to ${t} ${o.name}: it is a Portta component`,"gateway components are restarted with portta restart");let s=r.map(m=>({service:m.labels["com.docker.compose.service"]??m.name,name:m.name,dependsOn:HE(m.labels[qE]),id:m.id,state:m.state})),a=Qm(s,"stop"),c=Qm(s,"start"),u=t==="restart"?[...a.map(m=>({...m,verb:"stop"})),...c.map(m=>({...m,verb:"start"}))]:(t===
1259
1259
  "stop"?a:c).map(m=>({...m,verb:t})),p=new A(as(n)),d=new Map(s.map(m=>[m.id,m.state])),f=0;for(let m of u){let h=d.get(m.id)??m.state;if(m.verb==="start"&&h==="running"||m.verb==="stop"&&h!=="running"&&h!=="restarting"){p.progress(`skip ${m.service} already ${m.verb==="start"?"running":"stopped"}`);continue}let g=await _("docker",[m.verb,m.id],{reject:!1});if(g.failed){f+=1,p.warning(`${m.verb} ${m.service}: ${g.stderr.trim()||g.stdout.trim()||"failed"}`);continue}d.set(m.id,m.verb==="start"?
1260
- "running":"exited"),p.progress(`ok ${m.verb} ${m.service}`)}if(f>0)throw new U(`${f} service(s) failed to ${t}`,"the rest of the project was still acted on")}i(qp,"projectAction");var j7=["compose.yaml","compose.yml","docker-compose.yaml","docker-compose.yml"],I7=new Set(["node_modules","lost+found","vendor","dist","build"]),D7=8,N7=5*6e4,L7=["/etc","/proc","/sys","/dev","/boot","/var/lib/docker","/var/run","/run"],M7=/^\/(?:root|home|Users|home\/[^/]+|Users\/[^/]+)\/*$/;function z7(e){let t=e.split("/").filter(Boolean);return t.length<2||t.some(n=>n.startsWith("."))||M7.test(e)?!1:!L7.some(n=>e===n||e.startsWith(`${n}/`))}i(z7,"isWalkableHome");function F7(e){return/(oci:\/\/|git\+[a-z]+:\/\/|git@[\w.-]+:|\b(?:file|path|extends):\s*['"]?https?:\/\/|^\s*-\s*['"]?https?:\/\/)/im.
1261
- test(e)}i(F7,"reachesOut");function B7(e,t){return[...e.matchAll(/^\s*(?:-\s*)?(?:path|file|extends):[ \t]*['"]?([^'"\s#]+)/gim)].map(r=>r[1]).some(r=>{let o=C7(t,r);return o!==t&&!o.startsWith(`${t}${R7}`)})}i(B7,"includesOutside");function U7(e){return lt(e,"state/discovery")}i(U7,"discoveryDir");function q7(e){try{let n=(bN(lt(e,".env"))?me(O7(lt(e,".env"),"utf8")):new Map).get("PORTTA_PROJECTS_HOME")?.trim(),r=n&&n!==""?n:Uc(gN(),process.getuid?.()===0),o=qc(r,e,gN());return z7(o)?o:null}catch{
1262
- return null}}i(q7,"projectsHomeOf");function H7(e){let t=[],n=i((r,o)=>{if(t.length>=200||o>3)return;let s;try{s=yN(r)}catch{return}let a=j7.find(c=>s.includes(c));if(a&&o>0){let c=lt(r,a),u=mN(c,{throwIfNoEntry:!1}),p=T7(e,r).split(/[\\/]/).join("/");if(u?.isFile()&&LE(p)){t.push({path:p,composeFile:a,modifiedAt:Math.floor(u.mtimeMs/1e3)});return}}for(let c of s.sort()){if(c.startsWith(".")||I7.has(c))continue;let u=mN(lt(r,c),{throwIfNoEntry:!1});u?.isDirectory()&&!u.isSymbolicLink()&&n(lt(r,c),
1263
- o+1)}},"walk");return n(e,0),t}i(H7,"findComposeFolders");var xa=new Map;async function Z7(e,t,n){let r=lt(t,n.path),o=Up(lt(r,n.composeFile),1024*1024);if(o==="absent"||o==="refused")return vn(e,`discovery: ${n.path} not reviewed: its Compose file is a link, a pipe or over 1 MB`),null;if(F7(o)||B7(o,r))return vn(e,`discovery: ${n.path} not reviewed: its Compose file reaches outside the folder`),null;let s=await iw(r,{unattended:!0}).catch(a=>(vn(e,`discovery: ${n.path} not reviewed: ${a instanceof
1260
+ "running":"exited"),p.progress(`ok ${m.verb} ${m.service}`)}if(f>0)throw new U(`${f} service(s) failed to ${t}`,"the rest of the project was still acted on")}i(qp,"projectAction");var I7=["compose.yaml","compose.yml","docker-compose.yaml","docker-compose.yml"],D7=new Set(["node_modules","lost+found","vendor","dist","build"]),N7=8,L7=5*6e4,M7=["/etc","/proc","/sys","/dev","/boot","/var/lib/docker","/var/run","/run"],z7=/^\/(?:root|home|Users|home\/[^/]+|Users\/[^/]+)\/*$/;function F7(e){let t=e.split("/").filter(Boolean);return t.length<2||t.some(n=>n.startsWith("."))||z7.test(e)?!1:!M7.some(n=>e===n||e.startsWith(`${n}/`))}i(F7,"isWalkableHome");function B7(e){return/(oci:\/\/|git\+[a-z]+:\/\/|git@[\w.-]+:|\b(?:file|path|extends):\s*['"]?https?:\/\/|^\s*-\s*['"]?https?:\/\/)/im.
1261
+ test(e)}i(B7,"reachesOut");function U7(e,t){return[...e.matchAll(/^\s*(?:-\s*)?(?:path|file|extends):[ \t]*['"]?([^'"\s#]+)/gim)].map(r=>r[1]).some(r=>{let o=R7(t,r);return o!==t&&!o.startsWith(`${t}${j7}`)})}i(U7,"includesOutside");function q7(e){return lt(e,"state/discovery")}i(q7,"discoveryDir");function H7(e){try{let n=(bN(lt(e,".env"))?me($7(lt(e,".env"),"utf8")):new Map).get("PORTTA_PROJECTS_HOME")?.trim(),r=n&&n!==""?n:Uc(gN(),process.getuid?.()===0),o=qc(r,e,gN());return F7(o)?o:null}catch{
1262
+ return null}}i(H7,"projectsHomeOf");function Z7(e){let t=[],n=i((r,o)=>{if(t.length>=200||o>3)return;let s;try{s=yN(r)}catch{return}let a=I7.find(c=>s.includes(c));if(a&&o>0){let c=lt(r,a),u=mN(c,{throwIfNoEntry:!1}),p=C7(e,r).split(/[\\/]/).join("/");if(u?.isFile()&&LE(p)){t.push({path:p,composeFile:a,modifiedAt:Math.floor(u.mtimeMs/1e3)});return}}for(let c of s.sort()){if(c.startsWith(".")||D7.has(c))continue;let u=mN(lt(r,c),{throwIfNoEntry:!1});u?.isDirectory()&&!u.isSymbolicLink()&&n(lt(r,c),
1263
+ o+1)}},"walk");return n(e,0),t}i(Z7,"findComposeFolders");var xa=new Map;async function G7(e,t,n){let r=lt(t,n.path),o=Up(lt(r,n.composeFile),1024*1024);if(o==="absent"||o==="refused")return vn(e,`discovery: ${n.path} not reviewed: its Compose file is a link, a pipe or over 1 MB`),null;if(B7(o)||U7(o,r))return vn(e,`discovery: ${n.path} not reviewed: its Compose file reaches outside the folder`),null;let s=await iw(r,{unattended:!0}).catch(a=>(vn(e,`discovery: ${n.path} not reviewed: ${a instanceof
1264
1264
  Error?a.message.split(`
1265
1265
  `)[0]:String(a)}`),null));return s?{version:1,path:n.path,composeFile:s.compose_file,project:s.project,domain:s.domain,adopted:s.gateway_overlay!==null,services:s.services.map(a=>({name:a.name,image:a.image,kind:a.kind,port:a.kind==="http"?a.container_ports[0]??a.expose[0]??null:null,publishedPorts:a.published_ports.map(c=>({host:String(c.host),container:String(c.container)})),containerName:a.container_name})),findings:{publishedHostPorts:s.findings.published_host_ports,fixedContainerNames:s.findings.
1266
- fixed_container_names,publishedDatastores:s.findings.published_datastores,implicitNamespace:s.findings.implicit_namespace,containerNameCollisions:s.findings.container_name_collisions.map(a=>({service:a.service,containerName:a.container_name,usedBy:a.used_by})),namespaceInUse:s.findings.namespace_in_use?{project:s.findings.namespace_in_use.project,workingDirs:s.findings.namespace_in_use.working_dirs}:null},collectedAt:Math.floor(Date.now()/1e3)}:null}i(Z7,"planFolder");async function Hp(e,t=Date.
1267
- now()){try{let n=q7(e),r=U7(e);if(!n||!bN(n)||!$7(n).isDirectory()){hN(r,{recursive:!0,force:!0});return}let o=H7(n);A7(lt(r,"plans"),{recursive:!0,mode:493});let s=D7;for(let p of o){let d=xa.get(p.path);(!d||d.modifiedAt!==p.modifiedAt||t-d.at>=N7)&&s>0&&(s-=1,xa.set(p.path,{at:t,modifiedAt:p.modifiedAt,plan:await Z7(e,n,p)}))}let a=new Set,c=o.map(p=>{let d=xa.get(p.path)?.plan??null;return d&&(a.add(bo(p.path)),Ve(lt(r,"plans",bo(p.path)),`${JSON.stringify(d)}
1266
+ fixed_container_names,publishedDatastores:s.findings.published_datastores,implicitNamespace:s.findings.implicit_namespace,containerNameCollisions:s.findings.container_name_collisions.map(a=>({service:a.service,containerName:a.container_name,usedBy:a.used_by})),namespaceInUse:s.findings.namespace_in_use?{project:s.findings.namespace_in_use.project,workingDirs:s.findings.namespace_in_use.working_dirs}:null},collectedAt:Math.floor(Date.now()/1e3)}:null}i(G7,"planFolder");async function Hp(e,t=Date.
1267
+ now()){try{let n=H7(e),r=q7(e);if(!n||!bN(n)||!T7(n).isDirectory()){hN(r,{recursive:!0,force:!0});return}let o=Z7(n);O7(lt(r,"plans"),{recursive:!0,mode:493});let s=N7;for(let p of o){let d=xa.get(p.path);(!d||d.modifiedAt!==p.modifiedAt||t-d.at>=L7)&&s>0&&(s-=1,xa.set(p.path,{at:t,modifiedAt:p.modifiedAt,plan:await G7(e,n,p)}))}let a=new Set,c=o.map(p=>{let d=xa.get(p.path)?.plan??null;return d&&(a.add(bo(p.path)),Ve(lt(r,"plans",bo(p.path)),`${JSON.stringify(d)}
1268
1268
  `)),{path:p.path,composeFile:p.composeFile,services:d?d.services.length:null,modifiedAt:p.modifiedAt,adopted:d?.adopted??!1,planned:d!==null}});for(let p of yN(lt(r,"plans")))!a.has(p)&&!p.startsWith(".")&&hN(lt(r,"plans",p),{force:!0});for(let p of[...xa.keys()])o.some(d=>d.path===p)||xa.delete(p);let u={version:1,home:n,collectedAt:Math.floor(t/1e3),folders:c};Ve(lt(r,"folders.json"),`${JSON.stringify(u)}
1269
- `)}catch{}}i(Hp,"publishDiscovery");import{existsSync as vN,readFileSync as SN,unlinkSync as V7}from"node:fs";var K7=6e4;function xN(e){let t=Tp(e);if(!vN(t))return null;let n=Number(SN(t,"utf8").trim());return Number.isInteger(n)&&n>0?n:null}i(xN,"readCollectorPid");function kN(e){try{return process.kill(e,0),!0}catch{return!1}}i(kN,"pidAlive");function J7(e){try{return SN(`/proc/${e}/cmdline`,"utf8").replace(/\0/g," ")}catch{return""}}i(J7,"commandLine");function Y7(e){let t=J7(e);return t===""?!0:t.includes("host")&&t.includes("watch")}i(Y7,"pidIsCollector");function aw(e){let t=xN(e);return t===null?
1270
- null:!kN(t)||!Y7(t)?(cw(e),null):t}i(aw,"collectorRunning");function cw(e){let t=Tp(e);vN(t)&&V7(t)}i(cw,"clearPid");function _N(e,t){Ve(Tp(e),`${t}
1271
- `)}i(_N,"writePid");function X7(){let e=process.argv[1];return{file:process.execPath,args:e?[e]:[]}}i(X7,"cliInvocation");function lw(e,t){let n=aw(e);if(n!==null)return{pid:n,started:!1};let{file:r,args:o}=X7(),s=t?["--profile",t]:[],a=uC(r,[...o,...s,"host","watch","--loop"],{cwd:e,env:{...process.env,PORTTA_ROOT:e}});return a===void 0?{pid:null,started:!1}:(_N(e,a),{pid:a,started:!0})}i(lw,"startCollector");function PN(e){let t=xN(e);if(cw(e),t===null||!kN(t))return!1;try{return process.kill(
1269
+ `)}catch{}}i(Hp,"publishDiscovery");import{existsSync as vN,readFileSync as SN,unlinkSync as K7}from"node:fs";var J7=6e4;function xN(e){let t=Tp(e);if(!vN(t))return null;let n=Number(SN(t,"utf8").trim());return Number.isInteger(n)&&n>0?n:null}i(xN,"readCollectorPid");function kN(e){try{return process.kill(e,0),!0}catch{return!1}}i(kN,"pidAlive");function Y7(e){try{return SN(`/proc/${e}/cmdline`,"utf8").replace(/\0/g," ")}catch{return""}}i(Y7,"commandLine");function X7(e){let t=Y7(e);return t===""?!0:t.includes("host")&&t.includes("watch")}i(X7,"pidIsCollector");function aw(e){let t=xN(e);return t===null?
1270
+ null:!kN(t)||!X7(t)?(cw(e),null):t}i(aw,"collectorRunning");function cw(e){let t=Tp(e);vN(t)&&K7(t)}i(cw,"clearPid");function _N(e,t){Ve(Tp(e),`${t}
1271
+ `)}i(_N,"writePid");function Q7(){let e=process.argv[1];return{file:process.execPath,args:e?[e]:[]}}i(Q7,"cliInvocation");function lw(e,t){let n=aw(e);if(n!==null)return{pid:n,started:!1};let{file:r,args:o}=Q7(),s=t?["--profile",t]:[],a=uC(r,[...o,...s,"host","watch","--loop"],{cwd:e,env:{...process.env,PORTTA_ROOT:e}});return a===void 0?{pid:null,started:!1}:(_N(e,a),{pid:a,started:!0})}i(lw,"startCollector");function PN(e){let t=xN(e);if(cw(e),t===null||!kN(t))return!1;try{return process.kill(
1272
1272
  t,"SIGTERM"),!0}catch{return!1}}i(PN,"stopCollector");function wN(e){return new Promise(t=>setTimeout(t,e))}i(wN,"sleep");async function EN(e,t){_N(e,process.pid),vn(e,`collector started pid=${process.pid}`);let n=0,r=0,o=0,s=!1,a,c=!0,u=i(()=>{c=!1},"halt");for(process.on("SIGTERM",u),process.on("SIGINT",u);c;){let p=Date.now();try{let m=await zp(e,p);Rp(e,m),(p-n>=15e3||n===0)&&(jD(e,m),n=p)}catch(m){vn(e,`collect failed: ${m instanceof Error?m.message:String(m)}`)}if(p-r>=Vv||r===0){r=p;try{let[
1273
- m,h]=await Promise.all([ha(),ba(e,void 0,Rr(e,t))]);wa(e,m),ya(e,h)}catch(m){vn(e,`environment collect failed: ${m instanceof Error?m.message:String(m)}`)}}!s&&p-o>=K7&&(o=p,s=!0,a=Hp(e,p).finally(()=>{s=!1}));let d=Date.now()-p,f=Math.max(0,5e3-d);if(!c)break;await wN(f)}a&&await Promise.race([a,wN(5e3)]),cw(e),vn(e,"collector stopped")}i(EN,"runCollectorLoop");function cs(e){return e.optsWithGlobals()}i(cs,"globals");async function eX(e,t){let n=await zp(e),r=Rp(e,n);await Hp(e);let[o,s]=await Promise.all([ha(),ba(e,void 0,Rr(e,t))]);return wa(e,o),ya(e,s),r}i(eX,"collectHostResources");async function AN(e){let t=cs(e).profile,n=E({profile:t}),[r,o]=await Promise.all([ha(),ba(n.root,void 0,Rr(n.root,t))]),s=wa(n.root,r),a=ya(n.root,o),c=new A(cs(e));c.json?c.data({file:s,securityFile:a,...r}):c.progress(`wrote ${s} and ${a}`)}i(AN,"environmentReport");
1274
- async function Zp(e,t){try{let n=E({profile:e}),{pid:r,started:o}=lw(n.root,n.config.profile);o&&t.progress(`host metrics collector started (pid ${r})`)}catch(n){t.warning(`Host metrics collector could not start: ${n instanceof Error?n.message:String(n)}`)}}i(Zp,"ensureMetricsCollector");function ka(e,t){try{let n=E({profile:e,required:!1});PN(n.root)&&t.progress("host metrics collector stopped")}catch{}}i(ka,"stopMetricsCollector");async function ON(e){let t=cs(e).profile,n=E({profile:t}),r=await eX(
1273
+ m,h]=await Promise.all([ha(),ba(e,void 0,Rr(e,t))]);wa(e,m),ya(e,h)}catch(m){vn(e,`environment collect failed: ${m instanceof Error?m.message:String(m)}`)}}!s&&p-o>=J7&&(o=p,s=!0,a=Hp(e,p).finally(()=>{s=!1}));let d=Date.now()-p,f=Math.max(0,5e3-d);if(!c)break;await wN(f)}a&&await Promise.race([a,wN(5e3)]),cw(e),vn(e,"collector stopped")}i(EN,"runCollectorLoop");function cs(e){return e.optsWithGlobals()}i(cs,"globals");async function tX(e,t){let n=await zp(e),r=Rp(e,n);await Hp(e);let[o,s]=await Promise.all([ha(),ba(e,void 0,Rr(e,t))]);return wa(e,o),ya(e,s),r}i(tX,"collectHostResources");async function AN(e){let t=cs(e).profile,n=E({profile:t}),[r,o]=await Promise.all([ha(),ba(n.root,void 0,Rr(n.root,t))]),s=wa(n.root,r),a=ya(n.root,o),c=new A(cs(e));c.json?c.data({file:s,securityFile:a,...r}):c.progress(`wrote ${s} and ${a}`)}i(AN,"environmentReport");
1274
+ async function Zp(e,t){try{let n=E({profile:e}),{pid:r,started:o}=lw(n.root,n.config.profile);o&&t.progress(`host metrics collector started (pid ${r})`)}catch(n){t.warning(`Host metrics collector could not start: ${n instanceof Error?n.message:String(n)}`)}}i(Zp,"ensureMetricsCollector");function ka(e,t){try{let n=E({profile:e,required:!1});PN(n.root)&&t.progress("host metrics collector stopped")}catch{}}i(ka,"stopMetricsCollector");async function ON(e){let t=cs(e).profile,n=E({profile:t}),r=await tX(
1275
1275
  n.root,t),o=new A(cs(e));if(o.json){o.data({file:r,collected:!0});return}o.progress(`wrote ${r}`)}i(ON,"hostCollect");async function $N(e){let t=cs(e),n=E({profile:t.profile});if(t.loop){await EN(n.root,t.profile);return}let r=new A(t),{pid:o,started:s}=lw(n.root,n.config.profile);if(r.json){r.data({pid:o,started:s,file:os(n.root)});return}r.progress(s?`host metrics collector started (pid ${o})`:`host metrics collector already running (pid ${o})`)}i($N,"hostWatch");async function TN(e){let t=cs(
1276
- e),n=E({profile:t.profile}),r=aw(n.root),o=jp(n.root),s=Math.floor(Date.now()/1e3),a=o?Math.max(0,s-o.collectedAt):null,c=a!==null&&a>30,u={running:r!==null,pid:r,collectedAt:o?.collectedAt??null,ageSeconds:a,stale:c,file:os(n.root)},p=new A(t);if(p.json){p.data(u);return}r===null?p.line("collector: stopped"):p.line(`collector: running (pid ${r})`),a===null?p.line("last collect: never"):p.line(`last collect: ${a}s ago${c?" (stale)":""}`)}i(TN,"hostStatus");function He(e){return e.optsWithGlobals()}i(He,"globals");function RN(e,t){let n=Ir(e,".env");je(n,t)}i(RN,"setValues");function _a(e,t){let n=Ir(e,"state/auth/protections.json"),r=Ze(n);Zr(n,r);let o=Ir(e,"config/traefik/dynamic");CN(o,{recursive:!0}),St(Ir(o,"portta-auth.yaml"),Gr(r));let s=Ir(o,"portta-aliases.yaml");if(tX(s)){let a=t==="remote-public";St(s,$s(Wr(nX(s,"utf8")),r,a))}}i(_a,"syncForwardAuth");var Gp={PORTTA_WEB:"true"};async function uw(e,t,n={},r="inherit"){let o=E({profile:He(
1276
+ e),n=E({profile:t.profile}),r=aw(n.root),o=jp(n.root),s=Math.floor(Date.now()/1e3),a=o?Math.max(0,s-o.collectedAt):null,c=a!==null&&a>30,u={running:r!==null,pid:r,collectedAt:o?.collectedAt??null,ageSeconds:a,stale:c,file:os(n.root)},p=new A(t);if(p.json){p.data(u);return}r===null?p.line("collector: stopped"):p.line(`collector: running (pid ${r})`),a===null?p.line("last collect: never"):p.line(`last collect: ${a}s ago${c?" (stale)":""}`)}i(TN,"hostStatus");function He(e){return e.optsWithGlobals()}i(He,"globals");function RN(e,t){let n=Ir(e,".env");je(n,t)}i(RN,"setValues");function _a(e,t){let n=Ir(e,"state/auth/protections.json"),r=Ze(n);Zr(n,r);let o=Ir(e,"config/traefik/dynamic");CN(o,{recursive:!0}),St(Ir(o,"portta-auth.yaml"),Gr(r));let s=Ir(o,"portta-aliases.yaml");if(nX(s)){let a=t==="remote-public";St(s,$s(Wr(rX(s,"utf8")),r,a))}}i(_a,"syncForwardAuth");var Gp={PORTTA_WEB:"true"};async function uw(e,t,n={},r="inherit"){let o=E({profile:He(
1277
1277
  e).profile,overrides:Gp});return _("docker",["compose",...we(o),...t],{cwd:o.root,env:{...o.env,...n},stdio:r})}i(uw,"webCompose");function pw(e,t){xt(Ir(E({profile:He(t).profile}).root,".env")),e.localRelease&&Op(E({profile:He(t).profile}));let n=E({profile:He(t).profile}),r=e.expose??n.config.webExpose;if(!_n(r))throw new C(`--expose must be one of: ${Kr.join(", ")}`);if(r==="vpn"&&n.config.profile==="remote-public")throw new U("the panel must not be routed on the tailnet hostname while Traefi\
1278
1278
  k binds every interface","portta web up --expose domain routes it on the gateway's own domain, behind the same login page");if(r==="domain"){let p=n.env.PORTTA_PANEL_ADVERTISED_HOST??"";if(!p||p==="localhost"||/^[0-9.]+$/.test(p))throw new U(`panel access 'domain' needs a hostname to route on, and this host advertises ${p||"nothing"}`,"portta config set panel.host portta.example.com");if(!n.config.tlsEnabled)throw new U("a panel routed on the domain would carry its session cookie in clear text",
1279
1279
  "enable TLS first: portta config set tls.enabled true")}let o=n.env.PORTTA_AUTH_MODE==="required";if(!rn(r)&&!o)throw new U(`panel access '${r}' answers whoever finds the address, and the panel would answer them as the local operator`,"portta config set panel.auth required");rn(r)&&!o&&r!=="local"&&new A(He(t)).warning(`anybody who reaches the panel over the ${r==="tailscale"?"tailnet":"VPN"} is the local operator`);let s=e.writable?!1:e.readOnly??(r==="vpn"?!0:n.config.webReadOnly),a={PORTTA_WEB:"\
1280
- true",PORTTA_WEB_EXPOSE:r,PORTTA_WEB_READ_ONLY:String(s),PORTTA_WEB_DEV:String(e.dev??n.config.webDev)};e.port&&(a.PORTTA_WEB_PORT=String(Number(e.port))),(!n.env.PORTTA_PANEL_URL||e.expose||e.port)&&(a.PORTTA_PANEL_URL=iX(n,r,e.port?String(Number(e.port)):String(n.config.webPort))),RN(n.root,a),rs(n.root),_a(n.root,n.config.profile);let c=E({profile:He(t).profile,overrides:a}),u=new A(He(t));return{context:c,values:a,output:u}}i(pw,"prepareWebUp");async function Pa(e,t){let n=pw(e,t),{context:r,
1280
+ true",PORTTA_WEB_EXPOSE:r,PORTTA_WEB_READ_ONLY:String(s),PORTTA_WEB_DEV:String(e.dev??n.config.webDev)};e.port&&(a.PORTTA_WEB_PORT=String(Number(e.port))),(!n.env.PORTTA_PANEL_URL||e.expose||e.port)&&(a.PORTTA_PANEL_URL=aX(n,r,e.port?String(Number(e.port)):String(n.config.webPort))),RN(n.root,a),rs(n.root),_a(n.root,n.config.profile);let c=E({profile:He(t).profile,overrides:a}),u=new A(He(t));return{context:c,values:a,output:u}}i(pw,"prepareWebUp");async function Pa(e,t){let n=pw(e,t),{context:r,
1281
1281
  output:o}=n;e.localRelease&&(r.env.PORTTA_LOCAL_RELEASE="true"),o.step("panel"),e.dev||await Ap(r),await Zt(r.config.network),o.progress("pulling alpine/socat:1.8.1.3"),await _("docker",["pull","alpine/socat:1.8.1.3"],{reject:!1,stdio:"stream"}),CN(Ir(r.root,"state","panel"),{recursive:!0});let s=["portta-auth","web","web-socket-proxy"],a=r.config.webDev||r.config.webBuild?["--build"]:[];if(o.progress(a.length>0?`starting ${s.join(", ")}, building the panel image`:`starting ${s.join(", ")}`),(await _(
1282
1282
  "docker",["compose",...we(r),"up","-d",...a,"--remove-orphans","--wait","--wait-timeout","180",...s],{cwd:r.root,env:r.env,stdio:"inherit",reject:!1})).exitCode!==0)throw new L("the panel did not report healthy within 180s","portta web logs shows what it is doing; portta doctor checks the rest");await dw(n,t)}i(Pa,"webUp");async function dw(e,t,n=!0,r){let{context:o,values:s,output:a}=e;n&&await Zp(o.config.profile,a);let c=E({profile:He(t).profile,overrides:s});try{let d=await fw(c,r);d.applied.
1283
1283
  length>0?a.progress(`applied ${d.applied.join(", ")}`):a.detail(`panel schema is current (${d.migrations.length} migrations)`)}catch(d){a.warning(`pending panel migrations were not applied: ${d instanceof Error?d.message:String(d)}`),a.hint(d instanceof _e&&d.hint?d.hint:"portta db migrate")}let u=mw(c);(await jN(Wp(c)))?.setupRequired&&(a.progress(`this panel has no owner yet: open ${u}/setup to create it`),a.hint("portta auth bootstrap --email you@example.com creates it from this host instea\
1284
- d")),a.data(u)}i(dw,"finishWebUp");function Wp(e){let t=e.env.PORTTA_WEB_BIND_ADDRESS??"127.0.0.1";return`http://${t==="0.0.0.0"||t==="::"||t==="[::]"?"127.0.0.1":t}:${e.config.webPort}`}i(Wp,"panelLoopbackApiUrl");var rX=12e4,oX=500;async function sX(e,t=rX){let n=`${Wp(e)}/api/health`,r=Date.now()+t;for(;Date.now()<r;){try{let o=await fetch(n,{signal:AbortSignal.timeout(3e3)});if(o.ok||o.status===401)return}catch{}await new Promise(o=>setTimeout(o,oX))}throw new L("the panel is not reachable",
1285
- "run portta web up")}i(sX,"waitForPanelLoopback");async function fw(e,t){await sX(e);let n=`${Wp(e)}/api/database/migrate`,r;try{r=await fetch(n,{method:"POST",headers:{"content-type":"application/json",...t?{authorization:`Bearer ${t}`}:{}},body:"{}",signal:AbortSignal.timeout(6e4)})}catch{throw new L("the panel is not reachable","run portta web up")}let o=await r.json().catch(()=>({}));if(!r.ok)throw new L(o.error??`the panel refused to migrate (HTTP ${r.status})`,o.hint??"run portta db status");
1284
+ d")),a.data(u)}i(dw,"finishWebUp");function Wp(e){let t=e.env.PORTTA_WEB_BIND_ADDRESS??"127.0.0.1";return`http://${t==="0.0.0.0"||t==="::"||t==="[::]"?"127.0.0.1":t}:${e.config.webPort}`}i(Wp,"panelLoopbackApiUrl");var oX=12e4,sX=500;async function iX(e,t=oX){let n=`${Wp(e)}/api/health`,r=Date.now()+t;for(;Date.now()<r;){try{let o=await fetch(n,{signal:AbortSignal.timeout(3e3)});if(o.ok||o.status===401)return}catch{}await new Promise(o=>setTimeout(o,sX))}throw new L("the panel is not reachable",
1285
+ "run portta web up")}i(iX,"waitForPanelLoopback");async function fw(e,t){await iX(e);let n=`${Wp(e)}/api/database/migrate`,r;try{r=await fetch(n,{method:"POST",headers:{"content-type":"application/json",...t?{authorization:`Bearer ${t}`}:{}},body:"{}",signal:AbortSignal.timeout(6e4)})}catch{throw new L("the panel is not reachable","run portta web up")}let o=await r.json().catch(()=>({}));if(!r.ok)throw new L(o.error??`the panel refused to migrate (HTTP ${r.status})`,o.hint??"run portta db status");
1286
1286
  return{applied:o.applied??[],migrations:o.migrations??[]}}i(fw,"requestPanelMigrate");function mw(e){return e.config.webExpose==="vpn"?`${e.config.tlsEnabled?"https":"http"}://${e.env.PORTTA_WEB_HOST??"portta-web"}.${e.config.domain}`:e.config.webExpose==="domain"?`${e.config.tlsEnabled?"https":"http"}://${e.env.PORTTA_PANEL_ADVERTISED_HOST??e.config.domain}`:e.config.webExpose==="public"?`http://${(e.env.PORTTA_PANEL_ADVERTISED_HOST||null)??"<this-host>"}:${e.config.webPort}`:`http://${e.env.PORTTA_WEB_BIND_ADDRESS??
1287
- "127.0.0.1"}:${e.config.webPort}`}i(mw,"webUrl");function iX(e,t,n){let r=e.config.tlsEnabled?"https":"http";if(t==="domain")return`${r}://${e.env.PORTTA_PANEL_ADVERTISED_HOST??e.config.domain}`;if(t==="vpn")return`${r}://${e.env.PORTTA_WEB_HOST??"portta-web"}.${e.config.domain}`;if(t==="public"){let a=e.env.PORTTA_PANEL_ADVERTISED_HOST||null;return a?`http://${a}:${n}`:`http://127.0.0.1:${n}`}let o=e.env.PORTTA_WEB_BIND_ADDRESS??"127.0.0.1";return`http://${o==="0.0.0.0"||o==="::"||o==="[::]"?"1\
1288
- 27.0.0.1":o}:${n}`}i(iX,"panelUrlFor");async function jN(e){try{let t=await fetch(`${e}/api/auth/status`,{signal:AbortSignal.timeout(5e3)});if(!t.ok)return null;let n=await t.json();return typeof n.mode!="string"?null:{mode:n.mode,setupRequired:n.setupRequired===!0}}catch{return null}}i(jN,"panelSetupState");var aX=["web","web-socket-proxy"];async function hw(e){let t=E({profile:He(e).profile,overrides:{...Gp,PORTTA_WEB_DEV:"true"}}),n={...t.env,PORTTA_WEB:"true",PORTTA_WEB_DEV:"true"},r=aX;await _(
1287
+ "127.0.0.1"}:${e.config.webPort}`}i(mw,"webUrl");function aX(e,t,n){let r=e.config.tlsEnabled?"https":"http";if(t==="domain")return`${r}://${e.env.PORTTA_PANEL_ADVERTISED_HOST??e.config.domain}`;if(t==="vpn")return`${r}://${e.env.PORTTA_WEB_HOST??"portta-web"}.${e.config.domain}`;if(t==="public"){let a=e.env.PORTTA_PANEL_ADVERTISED_HOST||null;return a?`http://${a}:${n}`:`http://127.0.0.1:${n}`}let o=e.env.PORTTA_WEB_BIND_ADDRESS??"127.0.0.1";return`http://${o==="0.0.0.0"||o==="::"||o==="[::]"?"1\
1288
+ 27.0.0.1":o}:${n}`}i(aX,"panelUrlFor");async function jN(e){try{let t=await fetch(`${e}/api/auth/status`,{signal:AbortSignal.timeout(5e3)});if(!t.ok)return null;let n=await t.json();return typeof n.mode!="string"?null:{mode:n.mode,setupRequired:n.setupRequired===!0}}catch{return null}}i(jN,"panelSetupState");var cX=["web","web-socket-proxy"];async function hw(e){let t=E({profile:He(e).profile,overrides:{...Gp,PORTTA_WEB_DEV:"true"}}),n={...t.env,PORTTA_WEB:"true",PORTTA_WEB_DEV:"true"},r=cX;await _(
1289
1289
  "docker",["compose",...we({...t,env:n}),"stop",...r],{cwd:t.root,env:n,reject:!1}),await _("docker",["compose",...we({...t,env:n}),"rm","-f",...r],{cwd:t.root,env:n,reject:!1});let o=new A(He(e));ka(He(e).profile,o),o.progress("panel stopped; gateway and projects were not touched")}i(hw,"webDown");async function IN(e){await hw(e);let t=E({profile:He(e).profile,overrides:Gp});RN(t.root,{PORTTA_WEB:"false"})}i(IN,"webDisable");async function DN(e){await uw(e,["restart","web","web-socket-proxy"])}i(
1290
1290
  DN,"webRestart");async function NN(e,t){let n=e??"web";if(!["web","web-socket-proxy","portta-auth"].includes(n))throw new C(`unknown panel service: ${n}`);let r=He(t);if(r.json){let o=await uw(t,["logs","--no-color","--no-log-prefix","--tail","100",n],{},"pipe");new A(r).data({lines:o.stdout.split(`
1291
1291
  `).filter(Boolean)})}else await uw(t,["logs","--follow","--tail","100",n])}i(NN,"webLogs");async function LN(e){let t=E({profile:He(e).profile}),n=Se(t.version).runtime;await _("docker",["build","--build-arg",`PORTTA_VERSION=${t.version}`,"--target","runtime","-f","apps/web/Dockerfile","-t",n,"."],{cwd:t.root,stdio:"inherit"})}i(LN,"webBuild");async function MN(e){let t=He(e),n=E({profile:t.profile,overrides:Gp}),r=await J(),o=r.find(p=>p.labels["portta.component"]==="web"),s=r.find(p=>p.labels["\
1292
1292
  portta.component"]==="web-socket-proxy"),a=o?.state==="running"?await jN(Wp(n)):null,c={enabled:n.config.webEnabled,devMode:re(n.env.PORTTA_WEB_DEV),readOnly:n.config.webReadOnly,expose:n.config.webExpose,authMode:n.config.authMode,setupRequired:a?a.setupRequired:null,url:mw(n),panel:{state:o?.state??"absent"},socketProxy:{state:s?.state??"absent"}},u=new A(t);if(u.json)u.data(c);else for(let[p,d]of Object.entries(c))u.line(`${p}: ${typeof d=="object"?JSON.stringify(d):String(d)}`)}i(MN,"webStat\
1293
- us");async function zN(e){let t=E({profile:He(e).profile}),n=mw(t);new A(He(e)).data(n);let r=process.platform==="darwin"?"open":"xportta-open";await _(r,[n],{reject:!1})}i(zN,"webOpen");function Yt(e){return e.optsWithGlobals()}i(Yt,"globals");async function hX(e){let t=E({profile:Yt(e).profile}),n=Se(t.version).toolbox;return(await _("docker",["image","inspect",n],{reject:!1})).exitCode===0||await _("docker",["build","-q","--build-arg",`PORTTA_VERSION=${t.version}`,"-t",n,mX(t.root,"docker","images","toolbox")],{stdio:"inherit"}),n}i(hX,"ensureToolbox");async function gX(e){let t=await _("docker",["inspect",e,"--format","{{ range .Config.Env }}{{ println . }}{{ end }}"]);return Object.
1293
+ us");async function zN(e){let t=E({profile:He(e).profile}),n=mw(t);new A(He(e)).data(n);let r=process.platform==="darwin"?"open":"xportta-open";await _(r,[n],{reject:!1})}i(zN,"webOpen");function Yt(e){return e.optsWithGlobals()}i(Yt,"globals");async function gX(e){let t=E({profile:Yt(e).profile}),n=Se(t.version).toolbox;return(await _("docker",["image","inspect",n],{reject:!1})).exitCode===0||await _("docker",["build","-q","--build-arg",`PORTTA_VERSION=${t.version}`,"-t",n,hX(t.root,"docker","images","toolbox")],{stdio:"inherit"}),n}i(gX,"ensureToolbox");async function bX(e){let t=await _("docker",["inspect",e,"--format","{{ range .Config.Env }}{{ println . }}{{ end }}"]);return Object.
1294
1294
  fromEntries(t.stdout.split(`
1295
- `).map(n=>[n.slice(0,n.indexOf("=")),n.slice(n.indexOf("=")+1)]).filter(([n])=>n))}i(gX,"containerEnvironment");function bX(e){return/postgres|postgis|timescale/i.test(e)?5432:/mysql|mariadb|percona/i.test(e)?3306:/redis|valkey|keydb/i.test(e)?6379:null}i(bX,"defaultPort");async function Vp(e,t,n,r){n[0]==="--"&&(n=n.slice(1));let o=E({profile:Yt(r).profile}),a=(await J(!1)).find(b=>b.labels["com.docker.compose.project"]===t.project&&b.labels["com.docker.compose.service"]===t.service);if(!a)throw new C(
1296
- `no running container for ${t.project}/${t.service}`);let c=a.networks.find(b=>![o.config.network,o.config.accessNetwork,o.config.controlNetwork].includes(b));if(!c)throw new L(`${t.project}/${t.service} has no private network`);let u=Number(t.port??bX(a.image));if(!u)throw new C("cannot determine the service port","pass --port");let p=await gX(a.id),d={...process.env},f=[],m=["run","--rm","-i",...process.stdin.isTTY&&process.stdout.isTTY?["-t"]:[],"--network",c];e==="psql"&&p.POSTGRES_PASSWORD&&
1297
- (d.PGPASSWORD=p.POSTGRES_PASSWORD,f.push("-e","PGPASSWORD")),e==="mysql"&&p.MYSQL_PASSWORD&&(d.MYSQL_PWD=p.MYSQL_PASSWORD,f.push("-e","MYSQL_PWD"));let h=await hX(r);m.push(...f,h,e),e==="psql"&&m.push("-h",t.service,"-p",String(u),...t.user??p.POSTGRES_USER?["-U",t.user??p.POSTGRES_USER]:[],...t.database??p.POSTGRES_DB?["-d",t.database??p.POSTGRES_DB]:[]),e==="mysql"&&m.push("-h",t.service,"-P",String(u),...t.user??p.MYSQL_USER?["-u",t.user??p.MYSQL_USER]:[],...t.database??p.MYSQL_DATABASE?[t.database??
1295
+ `).map(n=>[n.slice(0,n.indexOf("=")),n.slice(n.indexOf("=")+1)]).filter(([n])=>n))}i(bX,"containerEnvironment");function yX(e){return/postgres|postgis|timescale/i.test(e)?5432:/mysql|mariadb|percona/i.test(e)?3306:/redis|valkey|keydb/i.test(e)?6379:null}i(yX,"defaultPort");async function Vp(e,t,n,r){n[0]==="--"&&(n=n.slice(1));let o=E({profile:Yt(r).profile}),a=(await J(!1)).find(b=>b.labels["com.docker.compose.project"]===t.project&&b.labels["com.docker.compose.service"]===t.service);if(!a)throw new C(
1296
+ `no running container for ${t.project}/${t.service}`);let c=a.networks.find(b=>![o.config.network,o.config.accessNetwork,o.config.controlNetwork].includes(b));if(!c)throw new L(`${t.project}/${t.service} has no private network`);let u=Number(t.port??yX(a.image));if(!u)throw new C("cannot determine the service port","pass --port");let p=await bX(a.id),d={...process.env},f=[],m=["run","--rm","-i",...process.stdin.isTTY&&process.stdout.isTTY?["-t"]:[],"--network",c];e==="psql"&&p.POSTGRES_PASSWORD&&
1297
+ (d.PGPASSWORD=p.POSTGRES_PASSWORD,f.push("-e","PGPASSWORD")),e==="mysql"&&p.MYSQL_PASSWORD&&(d.MYSQL_PWD=p.MYSQL_PASSWORD,f.push("-e","MYSQL_PWD"));let h=await gX(r);m.push(...f,h,e),e==="psql"&&m.push("-h",t.service,"-p",String(u),...t.user??p.POSTGRES_USER?["-U",t.user??p.POSTGRES_USER]:[],...t.database??p.POSTGRES_DB?["-d",t.database??p.POSTGRES_DB]:[]),e==="mysql"&&m.push("-h",t.service,"-P",String(u),...t.user??p.MYSQL_USER?["-u",t.user??p.MYSQL_USER]:[],...t.database??p.MYSQL_DATABASE?[t.database??
1298
1298
  p.MYSQL_DATABASE]:[]),e==="redis-cli"&&m.push("-h",t.service,"-p",String(u)),m.push(...n),await _("docker",m,{env:d,stdio:"inherit"})}i(Vp,"clientExec");async function FN(e,t){await Pi({project:e.project,service:e.service??"postgres",port:e.port,localPort:e.localPort},t)}i(FN,"dbOpen");async function BN(e,t){await Pi({project:e.project,service:e.service??"redis",port:e.port,localPort:e.localPort},t)}i(BN,"redisOpen");async function gw(e,t){await nu(void 0,{project:e.project},t)}i(gw,"clientClose");
1299
1299
  async function UN(e,t){let n=e.service??"postgres",r=(await J()).find(c=>c.labels["portta.component"]==="access-bridge"&&c.labels["portta.access.project"]===e.project&&c.labels["portta.access.service"]===n);if(!r)throw new C(`no bridge is open for ${e.project}/${n}`);let o=r.ports.find(c=>c.publicPort!==null);if(!o?.publicPort)throw new L("bridge has no host port");let s=r.labels["portta.access.kind"],a=s==="postgres"?`postgresql://<user>@127.0.0.1:${o.publicPort}/<database>`:s==="mysql"?`mysql:\
1300
1300
  //<user>@127.0.0.1:${o.publicPort}/<database>`:s==="redis"?`redis://127.0.0.1:${o.publicPort}`:`127.0.0.1:${o.publicPort}`;new A(Yt(t)).data(a)}i(UN,"dbUrl");function Kp(e){let t=E({profile:Yt(e).profile});return{path:Mt(t.root),root:t.root}}i(Kp,"panelDatabase");async function qN(e){let t=await fw(E({profile:Yt(e).profile})),n=new A(Yt(e));n.json?n.data(t):t.applied.length===0?n.line(`no pending migrations (${t.migrations.length} applied)`):n.line(`applied ${t.applied.join(", ")}`)}i(qN,"dbMigr\
1301
- ate");function HN(e){let{path:t}=Kp(e),n=or(t).filter(a=>Ea(a)),r=n.reduce((a,c)=>a+pX(c).size,0),o={state:Ea(t)?"ready":"absent",path:t,files:n.map(a=>dX(a)),bytes:r},s=new A(Yt(e));if(s.json?s.data(o):s.line(`Panel database: ${o.state}
1301
+ ate");function HN(e){let{path:t}=Kp(e),n=or(t).filter(a=>Ea(a)),r=n.reduce((a,c)=>a+dX(c).size,0),o={state:Ea(t)?"ready":"absent",path:t,files:n.map(a=>fX(a)),bytes:r},s=new A(Yt(e));if(s.json?s.data(o):s.line(`Panel database: ${o.state}
1302
1302
  File: ${t}
1303
1303
  Size: ${r} bytes across ${n.length} file(s)`),o.state!=="ready")throw new L("the panel database does not exist yet","run portta web up; the panel creates it on first boot")}i(HN,"dbStatus");async function ZN(){let e=await _("sh",["-c","command -v sqlite3"],{reject:!1}),t=e.stdout.trim();if(e.exitCode!==0||!t)throw new L("sqlite3 is not installed on this host","install it (macOS ships it; apt install sqlite3, apk add sqlite) and try again");return t}i(ZN,"sqlite3");async function GN(e){if(!process.
1304
1304
  stdin.isTTY||!process.stdout.isTTY)throw new L("db shell needs an interactive terminal");let{path:t}=Kp(e);if(!Ea(t))throw new L(`no panel database at ${t}`,"run portta web up");await _(await ZN(),[t],{stdio:"inherit"})}i(GN,"dbShell");async function WN(e,t){let{path:n}=Kp(t);if(!Ea(n))throw new L(`no panel database at ${n}`,"run portta web up");let r=e??`portta-${new Date().toISOString().replaceAll(/[:.]/g,"-")}.db`;await _(await ZN(),[n,`.backup '${r.replaceAll("'","''")}'`],{stdio:"inherit"}),
1305
- new A(Yt(t)).progress(`panel database written to ${r}`)}i(WN,"dbDump");async function VN(e,t){if(!Ea(e))throw new C(`backup not found: ${e}`);let{path:n}=Kp(t);if((await J()).some(o=>o.labels["portta.component"]==="web"&&o.state==="running"))throw new L("the panel is running, and replacing its database under it would corrupt what it has open","portta web down then run this again, then portta web up");await et(`replace ${n} with ${e}? The current panel data is discarded.`,Yt(t).yes===!0),lX(fX(
1306
- n),{recursive:!0});for(let o of or(n))uX(o,{force:!0});cX(e,n),new A(Yt(t)).progress(`panel database restored from ${e}`)}i(VN,"dbRestore");import{join as KN}from"node:path";function Aa(e){return e.optsWithGlobals()}i(Aa,"globals");var bw={"panel.access":{key:"PORTTA_WEB_EXPOSE",description:"how the panel is reached",allowed:Kr},"panel.port":{key:"PORTTA_WEB_PORT",description:"host port the panel answers on"},"panel.auth":{key:"PORTTA_AUTH_MODE",description:"whether the panel asks who you are",allowed:["disabled","required"]},"panel.host":{key:"PORTTA_PANEL_ADVERTISED_HOST",description:"hostname the panel answers on, and the address a human types"},"panel.readOnly":{
1305
+ new A(Yt(t)).progress(`panel database written to ${r}`)}i(WN,"dbDump");async function VN(e,t){if(!Ea(e))throw new C(`backup not found: ${e}`);let{path:n}=Kp(t);if((await J()).some(o=>o.labels["portta.component"]==="web"&&o.state==="running"))throw new L("the panel is running, and replacing its database under it would corrupt what it has open","portta web down then run this again, then portta web up");await et(`replace ${n} with ${e}? The current panel data is discarded.`,Yt(t).yes===!0),uX(mX(
1306
+ n),{recursive:!0});for(let o of or(n))pX(o,{force:!0});lX(e,n),new A(Yt(t)).progress(`panel database restored from ${e}`)}i(VN,"dbRestore");import{join as KN}from"node:path";function Aa(e){return e.optsWithGlobals()}i(Aa,"globals");var bw={"panel.access":{key:"PORTTA_WEB_EXPOSE",description:"how the panel is reached",allowed:Kr},"panel.port":{key:"PORTTA_WEB_PORT",description:"host port the panel answers on"},"panel.auth":{key:"PORTTA_AUTH_MODE",description:"whether the panel asks who you are",allowed:["disabled","required"]},"panel.host":{key:"PORTTA_PANEL_ADVERTISED_HOST",description:"hostname the panel answers on, and the address a human types"},"panel.readOnly":{
1307
1307
  key:"PORTTA_WEB_READ_ONLY",description:"refuse every mutating panel endpoint",allowed:["true","false"]},"panel.image":{key:"PORTTA_WEB_IMAGE",description:"published panel image"},"gateway.profile":{key:"PORTTA_PROFILE",description:"local, remote-private or remote-public",allowed:["local","remote-private","remote-public"]},"domain.mode":{key:"PORTTA_DOMAIN_MODE",description:"how project hostnames get their base domain",allowed:Za},"domain.provider":{key:"PORTTA_AUTO_DOMAIN_PROVIDER",description:"\
1308
1308
  wildcard DNS service used by the auto mode",allowed:Kd},"domain.publicIp":{key:"PORTTA_PUBLIC_IP",description:"address the auto mode builds a hostname from"},"gateway.domain":{key:"PORTTA_DOMAIN",description:"base domain, when the mode is custom"},"gateway.bindAddress":{key:"PORTTA_BIND_ADDRESS",description:"interface Traefik publishes 80/443 on"},"public.domain":{key:"PUBLIC_DOMAIN",description:"public wildcard namespace"},"public.enabled":{key:"PUBLIC_ENABLED",description:"whether HTTP service\
1309
1309
  s may be published",allowed:["true","false"]},"private.domain":{key:"PRIVATE_DOMAIN",description:"wildcard namespace served over the VPN"},"tls.enabled":{key:"TLS_ENABLED",description:"serve HTTPS",allowed:["true","false"]},"tls.mode":{key:"TLS_MODE",description:"local certificate authority or ACME",allowed:["local","acme"]},"acme.email":{key:"ACME_EMAIL",description:"contact address for the ACME account"},"acme.challenge":{key:"ACME_CHALLENGE",description:"one wildcard over DNS-01, or one per h\
1310
1310
  ostname over HTTP-01",allowed:["dns","http"]},"acme.caServer":{key:"ACME_CA_SERVER",description:"ACME directory URL; point at staging while testing"},"dashboard.enabled":{key:"PORTTA_DASHBOARD",description:"Traefik's own dashboard, on loopback",allowed:["true","false"]},"tcp.enabled":{key:"PORTTA_TCP",description:"route datastores by hostname",allowed:["true","false"]},"tailscale.enabled":{key:"TAILSCALE_ENABLED",description:"run the Tailscale sidecar",allowed:["true","false"]}},yw=new Set(["POR\
1311
- TTA_AUTH_SECRET","TS_AUTHKEY","CF_DNS_API_TOKEN"]);function JN(e){let t=bw[e];if(!t)throw new C(`unknown setting: ${e}`,`portta config list shows the ${Object.keys(bw).length} settings this understands`);return t}i(JN,"setting");function yX(e,t){let n=KN(e,".env");je(n,t)}i(yX,"write");async function YN(e){let t=Aa(e),n=E({profile:t.profile}),r=Object.entries(bw).map(([s,a])=>({setting:s,variable:a.key,value:yw.has(a.key)?n.env[a.key]?"<set>":"":n.env[a.key]??"",description:a.description})),o=new A(
1312
- t);if(o.json){o.data({root:n.root,settings:r});return}for(let s of r)o.line(`${s.setting.padEnd(22)} ${String(s.value).padEnd(24)} ${s.description}`)}i(YN,"configList");async function XN(e,t){let n=Aa(t),r=E({profile:n.profile}),o=JN(e);if(yw.has(o.key))throw new U(`${e} is a secret and is never printed`,"portta doctor reports whether it is set");let s=r.env[o.key]??"",a=new A(n);a.json?a.data({setting:e,variable:o.key,value:s}):a.line(s)}i(XN,"configGet");async function wX(e,t,n,r){let o=E({root:e,
1313
- profile:t,overrides:n});r.progress("recreating gateway components"),await _("docker",["compose",...we(o),"up","-d","--remove-orphans","--wait","--wait-timeout","180"],{cwd:o.root,env:o.env,stdio:"inherit"})}i(wX,"apply");async function vX(){for(let e of["https://api.ipify.org","https://ifconfig.me/ip","https://icanhazip.com"])try{let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)continue;let n=(await t.text()).trim();if(/^(\d{1,3}\.){3}\d{1,3}$/.test(n))return n}catch{}return null}
1314
- i(vX,"detectPublicIp");async function SX(e,t,n){if(!Vd(t))throw new C(`domain.mode must be one of: ${Za.join(", ")}`);let r=E({root:e}),o={PORTTA_DOMAIN_MODE:t};if(t==="auto"){n.progress("detecting this host's public address");let s=await vX()??r.env.PORTTA_PUBLIC_IP??null;if(!s)throw new L("no public address could be detected for this host","set it yourself: portta config set domain.publicIp <address>");o.PORTTA_PUBLIC_IP=s;let a=r.env.PORTTA_AUTO_DOMAIN_PROVIDER,c=Ga(s,a&&Jd(a)?a:"sslip.io");if(!c)
1311
+ TTA_AUTH_SECRET","TS_AUTHKEY","CF_DNS_API_TOKEN"]);function JN(e){let t=bw[e];if(!t)throw new C(`unknown setting: ${e}`,`portta config list shows the ${Object.keys(bw).length} settings this understands`);return t}i(JN,"setting");function wX(e,t){let n=KN(e,".env");je(n,t)}i(wX,"write");async function YN(e){let t=Aa(e),n=E({profile:t.profile}),r=Object.entries(bw).map(([s,a])=>({setting:s,variable:a.key,value:yw.has(a.key)?n.env[a.key]?"<set>":"":n.env[a.key]??"",description:a.description})),o=new A(
1312
+ t);if(o.json){o.data({root:n.root,settings:r});return}for(let s of r)o.line(`${s.setting.padEnd(22)} ${String(s.value).padEnd(24)} ${s.description}`)}i(YN,"configList");async function XN(e,t){let n=Aa(t),r=E({profile:n.profile}),o=JN(e);if(yw.has(o.key))throw new U(`${e} is a secret and is never printed`,"portta doctor reports whether it is set");let s=r.env[o.key]??"",a=new A(n);a.json?a.data({setting:e,variable:o.key,value:s}):a.line(s)}i(XN,"configGet");async function vX(e,t,n,r){let o=E({root:e,
1313
+ profile:t,overrides:n});r.progress("recreating gateway components"),await _("docker",["compose",...we(o),"up","-d","--remove-orphans","--wait","--wait-timeout","180"],{cwd:o.root,env:o.env,stdio:"inherit"})}i(vX,"apply");async function SX(){for(let e of["https://api.ipify.org","https://ifconfig.me/ip","https://icanhazip.com"])try{let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)continue;let n=(await t.text()).trim();if(/^(\d{1,3}\.){3}\d{1,3}$/.test(n))return n}catch{}return null}
1314
+ i(SX,"detectPublicIp");async function xX(e,t,n){if(!Vd(t))throw new C(`domain.mode must be one of: ${Za.join(", ")}`);let r=E({root:e}),o={PORTTA_DOMAIN_MODE:t};if(t==="auto"){n.progress("detecting this host's public address");let s=await SX()??r.env.PORTTA_PUBLIC_IP??null;if(!s)throw new L("no public address could be detected for this host","set it yourself: portta config set domain.publicIp <address>");o.PORTTA_PUBLIC_IP=s;let a=r.env.PORTTA_AUTO_DOMAIN_PROVIDER,c=Ga(s,a&&Jd(a)?a:"sslip.io");if(!c)
1315
1315
  throw new L(`${s} is not an IPv4 address`);o.PORTTA_DOMAIN=c,n.progress(`projects will answer on *.${c}`);for(let u of Hv(c))n.progress(` ${u}`);r.config.bindAddress==="127.0.0.1"&&(n.warning("Traefik still listens on 127.0.0.1, so these names resolve here but nothing answers from outside"),n.hint("portta public enable exposes the HTTP services that opted in"))}if(t==="custom"){let s=r.env.PORTTA_DOMAIN;if(!s||s==="localhost")throw new L("domain mode custom needs a domain","set it first: port\
1316
- ta config set gateway.domain dev.example.com");n.hint(`*.${s} must resolve to this host; portta dns check confirms it`)}return t==="local"&&(o.PORTTA_DOMAIN="localhost",n.hint("projects will answer on *.localhost, which only resolves on this machine")),o}i(SX,"setDomainMode");async function xX(){let e=await _("tailscale",["ip","-4"],{reject:!1}),t=e.stdout.split(`
1317
- `)[0]?.trim()??"";return e.exitCode===0&&t?t:null}i(xX,"tailscaleAddress");async function kX(e,t,n){if(!_n(t))throw new C(`panel.access must be one of: ${Kr.join(", ")}`);let r=E({root:e}),o={PORTTA_WEB_EXPOSE:t,PORTTA_WEB:"true"},s=r.env.PORTTA_AUTH_MODE==="required";if(!rn(t)&&!s)throw new U(`panel access '${t}' answers whoever finds the address while the panel answers everybody as the local operator`,"portta config set panel.auth required then open /setup to create the owner");if(rn(t)&&!s&&
1316
+ ta config set gateway.domain dev.example.com");n.hint(`*.${s} must resolve to this host; portta dns check confirms it`)}return t==="local"&&(o.PORTTA_DOMAIN="localhost",n.hint("projects will answer on *.localhost, which only resolves on this machine")),o}i(xX,"setDomainMode");async function kX(){let e=await _("tailscale",["ip","-4"],{reject:!1}),t=e.stdout.split(`
1317
+ `)[0]?.trim()??"";return e.exitCode===0&&t?t:null}i(kX,"tailscaleAddress");async function _X(e,t,n){if(!_n(t))throw new C(`panel.access must be one of: ${Kr.join(", ")}`);let r=E({root:e}),o={PORTTA_WEB_EXPOSE:t,PORTTA_WEB:"true"},s=r.env.PORTTA_AUTH_MODE==="required";if(!rn(t)&&!s)throw new U(`panel access '${t}' answers whoever finds the address while the panel answers everybody as the local operator`,"portta config set panel.auth required then open /setup to create the owner");if(rn(t)&&!s&&
1318
1318
  t!=="local"&&(n.warning(`anybody who reaches the panel over the ${t==="tailscale"?"tailnet":"VPN"} is the local operator`),n.hint("portta config set panel.auth required asks who they are instead")),t==="vpn"&&r.config.profile==="remote-public")throw new U("the panel must not be routed on the tailnet hostname while Traefik binds every interface","portta config set panel.access domain routes it on the gateway's own domain");switch(t){case"public":if(r.config.profile!=="local"&&r.config.tailscaleEnabled)
1319
1319
  throw new U("panel access `public` cannot be combined with the Tailscale attachment","use panel.access tailscale, or set tailscale.enabled false");o.PORTTA_WEB_BIND_ADDRESS="0.0.0.0",n.warning("the panel will be reachable from every network this host is on; authentication is enforced by the proxy");break;case"domain":{let a=r.env.PORTTA_PANEL_ADVERTISED_HOST??"";if(!a||a==="localhost"||/^[0-9.]+$/.test(a))throw new U(`panel access 'domain' needs a hostname to route on, and this host advertises ${a||
1320
- "nothing"}`,"portta config set panel.host portta.example.com");if(!r.config.tlsEnabled)throw new U("a panel routed on the domain would carry its credential in clear text","enable TLS first: portta config set tls.enabled true");o.PORTTA_WEB_BIND_ADDRESS="127.0.0.1",n.warning(`the panel will answer on https://${a}, behind the same login page a protected project gets`);break}case"tailscale":{let a=await xX();if(!a)throw new L("this host has no Tailscale address","connect it yourself with `tailscale\
1321
- up`, then set this again");o.PORTTA_WEB_BIND_ADDRESS=a,o.PORTTA_PANEL_ADVERTISED_HOST=a;break}case"local":o.PORTTA_WEB_BIND_ADDRESS="127.0.0.1",o.PORTTA_PANEL_ADVERTISED_HOST="127.0.0.1";break;case"vpn":o.PORTTA_WEB_BIND_ADDRESS="127.0.0.1";break}return o}i(kX,"setPanelAccess");function _X(e,t,n){let r=E({root:e});if(t==="required")return r.env.PORTTA_AUTH_SECRET||n.hint("portta web up generates the session secret; nothing prints it"),{PORTTA_AUTH_MODE:"required"};let o=r.env.PORTTA_WEB_EXPOSE||
1320
+ "nothing"}`,"portta config set panel.host portta.example.com");if(!r.config.tlsEnabled)throw new U("a panel routed on the domain would carry its credential in clear text","enable TLS first: portta config set tls.enabled true");o.PORTTA_WEB_BIND_ADDRESS="127.0.0.1",n.warning(`the panel will answer on https://${a}, behind the same login page a protected project gets`);break}case"tailscale":{let a=await kX();if(!a)throw new L("this host has no Tailscale address","connect it yourself with `tailscale\
1321
+ up`, then set this again");o.PORTTA_WEB_BIND_ADDRESS=a,o.PORTTA_PANEL_ADVERTISED_HOST=a;break}case"local":o.PORTTA_WEB_BIND_ADDRESS="127.0.0.1",o.PORTTA_PANEL_ADVERTISED_HOST="127.0.0.1";break;case"vpn":o.PORTTA_WEB_BIND_ADDRESS="127.0.0.1";break}return o}i(_X,"setPanelAccess");function PX(e,t,n){let r=E({root:e});if(t==="required")return r.env.PORTTA_AUTH_SECRET||n.hint("portta web up generates the session secret; nothing prints it"),{PORTTA_AUTH_MODE:"required"};let o=r.env.PORTTA_WEB_EXPOSE||
1322
1322
  "local";if(!_n(o)||!rn(o))throw new U(`the panel is reached over '${o}', which answers whoever finds the address`,`portta config set panel.access <${ef.join("|")}> then set panel.auth disabled`);let s=r.env.PORTTA_WEB_BIND_ADDRESS||"127.0.0.1";if(o==="local"&&!(s==="127.0.0.1"||s==="localhost"||s==="::1"||s==="[::1]")&&r.env.PORTTA_AUTH_ALLOW_LAN!=="true")throw new U(`the panel is bound to ${s}, so turning the login off offers it to every device on this network`,"set PORTTA_AUTH_ALLOW_LAN=true\
1323
- in .env to accept that, or portta config set panel.access local");return o!=="local"&&n.warning(`anybody who reaches the panel over the ${o==="tailscale"?"tailnet":"VPN"} is now the local operator`),{PORTTA_AUTH_MODE:"disabled"}}i(_X,"setPanelAuth");async function QN(e,t,n,r){let o=Aa(r),s=new A(o),a=E({profile:o.profile}),c=JN(e);if(yw.has(c.key))throw new U(`${e} is a secret and is not set this way`,"edit .env; portta web up generates PORTTA_AUTH_SECRET when it is empty");if(c.allowed&&!c.allowed.
1324
- includes(t))throw new C(`${e} must be one of: ${c.allowed.join(", ")}`);let u;e==="panel.access"?u=await kX(a.root,t,s):e==="panel.auth"?u=_X(a.root,t,s):e==="domain.mode"?u=await SX(a.root,t,s):u={[c.key]:t},e==="gateway.domain"&&t&&a.config.domainMode!=="custom"&&(s.hint("domain.mode is not custom, so this value is not in use yet"),s.hint("portta config set domain.mode custom applies it")),yX(a.root,u),e==="panel.access"&&_a(a.root,a.config.profile),s.progress(`${e} = ${t}`),n.apply===!1?s.hint(
1325
- "nothing was restarted: run portta up to apply it"):await wX(a.root,o.profile,u,s),s.json&&s.data({setting:e,value:t,applied:n.apply!==!1,changed:u})}i(QN,"configSet");function eL(e){let t=E({profile:Aa(e).profile});xt(KN(t.root,".env")),new A(Aa(e)).progress("configuration prepared from .env.example; existing values preserved")}i(eL,"configPrepare");import{existsSync as LQ,readFileSync as MQ}from"node:fs";import{join as zQ}from"node:path";import{fileURLToPath as FQ,pathToFileURL as BQ}from"node:url";import{gunzipSync as UQ}from"node:zlib";var Ne=i((e,t)=>e.meta({ref:t}),"named"),Xn=l.number().describe("Unix timestamp in seconds"),ww=Ne(l.enum(wo).describe("What this account may do, everywhere"),"Role"),PX=Ne(l.object({id:l.string(),name:l.string(),email:l.string(),role:ww,banned:l.boolean(),banReason:l.string().nullable(),banExpires:Xn.nullable(),twoFactorEnabled:l.boolean(),createdAt:Xn,projects:l.array(l.object({id:l.number(),slug:l.string(),name:l.string()}).strict())}).strict(),"User"),V$e=Ne(l.object({users:l.array(PX)}).strict(),
1326
- "Users"),K$e=Ne(l.object({name:l.string().min(1).max(120),email:l.email(),password:l.string().min(10).max(128),role:ww.default("viewer"),projects:l.array(l.number().int().positive()).max(200).optional()}).strict(),"CreateUser"),J$e=Ne(l.object({role:ww}).strict(),"SetRole"),Y$e=Ne(l.object({password:l.string().min(10).max(128)}).strict(),"SetPassword"),X$e=Ne(l.object({banned:l.boolean(),reason:l.string().max(500).optional(),days:l.number().int().min(1).max(3650).optional()}).strict(),"BanUser"),
1327
- Q$e=Ne(l.object({projects:l.array(l.number().int().positive()).max(200)}).strict(),"SetUserProjects"),EX=Ne(l.object({id:l.string(),createdAt:Xn,expiresAt:Xn,ipAddress:l.string().nullable(),userAgent:l.string().nullable()}).strict(),"UserSession"),eTe=Ne(l.object({sessions:l.array(EX)}).strict(),"UserSessions"),tL=Ne(l.object({id:l.string(),name:l.string(),start:l.string().nullable(),actor:l.string(),actorKind:l.enum(["human","agent"]),scopes:l.array(l.string()),createdAt:Xn,expiresAt:Xn.nullable(),
1328
- lastUsedAt:Xn.nullable(),enabled:l.boolean(),user:l.string()}).strict(),"ApiToken"),tTe=Ne(l.object({tokens:l.array(tL)}).strict(),"ApiTokens"),nTe=Ne(l.object({name:l.string().min(1).max(80),actorKind:l.enum(["human","agent"]).default("agent"),scopes:l.array(l.string()).max(200).optional(),expiresInDays:l.number().int().min(1).max(365).optional()}).strict(),"CreateApiToken"),rTe=Ne(l.object({token:l.string().describe("The secret. Shown here and nowhere else, ever."),credential:tL}).strict(),"Cr\
1329
- eatedApiToken"),AX=Ne(l.object({id:l.string(),at:Xn,userId:l.string().nullable(),userEmail:l.string().nullable(),principalKind:l.enum(["local","user","token"]),actor:l.string(),action:l.enum(Uv),resourceType:l.string(),resourceId:l.string().nullable(),resourceName:l.string().nullable(),project:l.string().nullable().describe("Project slug, when the entry is about one"),ipAddress:l.string().nullable(),metadata:l.record(l.string(),l.unknown())}).strict(),"AuditEntry"),oTe=Ne(l.object({entries:l.array(
1330
- AX),nextBefore:l.string().nullable().describe("Pass as ?before= for the next page")}).strict(),"AuditPage"),sTe=Ne(l.object({permissions:l.array(l.string()).describe("In force right now"),defaults:l.array(l.string()).describe("What an agent holds when nothing is set"),available:l.array(l.string()).describe("Every permission this installation knows"),configured:l.boolean().describe("False when the default is what is in force")}).strict(),"AgentPermissions"),iTe=Ne(l.object({permissions:l.array(l.
1331
- string().min(1).max(64)).max(64).nullable().describe("Null restores the default")}).strict(),"SetAgentPermissions");var OX=l.enum(["user","developer","all"]),vw=l.object({version:l.string(),revision:l.string().nullable(),hash:l.string()}),$X=l.object({id:l.string(),text:l.string(),level:l.number().int(),line:l.number().int()}),nL=l.object({slug:l.string(),title:l.string(),description:l.string(),audience:l.enum(["user","developer"]),section:l.string(),category:l.string(),source:l.string(),url:l.string(),kind:l.enum(["markdown","api"])}),TX=l.object({title:l.string(),category:l.string(),audience:l.enum(["user",
1332
- "developer"]),sequential:l.boolean(),slugs:l.array(l.string())}),Sw=l.object({identity:vw,groups:l.array(TX),pages:l.array(nL)}),Jp=l.object({identity:vw,page:nL.extend({markdown:l.string(),headings:l.array($X)})}),xw=l.object({identity:vw,results:l.array(l.object({slug:l.string(),title:l.string(),description:l.string(),audience:l.enum(["user","developer"]),section:l.string(),category:l.string(),url:l.string(),anchor:l.string().nullable(),excerpt:l.string()}))}),Yp=l.object({audience:OX.default(
1323
+ in .env to accept that, or portta config set panel.access local");return o!=="local"&&n.warning(`anybody who reaches the panel over the ${o==="tailscale"?"tailnet":"VPN"} is now the local operator`),{PORTTA_AUTH_MODE:"disabled"}}i(PX,"setPanelAuth");async function QN(e,t,n,r){let o=Aa(r),s=new A(o),a=E({profile:o.profile}),c=JN(e);if(yw.has(c.key))throw new U(`${e} is a secret and is not set this way`,"edit .env; portta web up generates PORTTA_AUTH_SECRET when it is empty");if(c.allowed&&!c.allowed.
1324
+ includes(t))throw new C(`${e} must be one of: ${c.allowed.join(", ")}`);let u;e==="panel.access"?u=await _X(a.root,t,s):e==="panel.auth"?u=PX(a.root,t,s):e==="domain.mode"?u=await xX(a.root,t,s):u={[c.key]:t},e==="gateway.domain"&&t&&a.config.domainMode!=="custom"&&(s.hint("domain.mode is not custom, so this value is not in use yet"),s.hint("portta config set domain.mode custom applies it")),wX(a.root,u),e==="panel.access"&&_a(a.root,a.config.profile),s.progress(`${e} = ${t}`),n.apply===!1?s.hint(
1325
+ "nothing was restarted: run portta up to apply it"):await vX(a.root,o.profile,u,s),s.json&&s.data({setting:e,value:t,applied:n.apply!==!1,changed:u})}i(QN,"configSet");function eL(e){let t=E({profile:Aa(e).profile});xt(KN(t.root,".env")),new A(Aa(e)).progress("configuration prepared from .env.example; existing values preserved")}i(eL,"configPrepare");import{existsSync as MQ,readFileSync as zQ}from"node:fs";import{join as FQ}from"node:path";import{fileURLToPath as BQ,pathToFileURL as UQ}from"node:url";import{gunzipSync as qQ}from"node:zlib";var Ne=i((e,t)=>e.meta({ref:t}),"named"),Xn=l.number().describe("Unix timestamp in seconds"),ww=Ne(l.enum(wo).describe("What this account may do, everywhere"),"Role"),EX=Ne(l.object({id:l.string(),name:l.string(),email:l.string(),role:ww,banned:l.boolean(),banReason:l.string().nullable(),banExpires:Xn.nullable(),twoFactorEnabled:l.boolean(),createdAt:Xn,projects:l.array(l.object({id:l.number(),slug:l.string(),name:l.string()}).strict())}).strict(),"User"),K$e=Ne(l.object({users:l.array(EX)}).strict(),
1326
+ "Users"),J$e=Ne(l.object({name:l.string().min(1).max(120),email:l.email(),password:l.string().min(10).max(128),role:ww.default("viewer"),projects:l.array(l.number().int().positive()).max(200).optional()}).strict(),"CreateUser"),Y$e=Ne(l.object({role:ww}).strict(),"SetRole"),X$e=Ne(l.object({password:l.string().min(10).max(128)}).strict(),"SetPassword"),Q$e=Ne(l.object({banned:l.boolean(),reason:l.string().max(500).optional(),days:l.number().int().min(1).max(3650).optional()}).strict(),"BanUser"),
1327
+ eTe=Ne(l.object({projects:l.array(l.number().int().positive()).max(200)}).strict(),"SetUserProjects"),AX=Ne(l.object({id:l.string(),createdAt:Xn,expiresAt:Xn,ipAddress:l.string().nullable(),userAgent:l.string().nullable()}).strict(),"UserSession"),tTe=Ne(l.object({sessions:l.array(AX)}).strict(),"UserSessions"),tL=Ne(l.object({id:l.string(),name:l.string(),start:l.string().nullable(),actor:l.string(),actorKind:l.enum(["human","agent"]),scopes:l.array(l.string()),createdAt:Xn,expiresAt:Xn.nullable(),
1328
+ lastUsedAt:Xn.nullable(),enabled:l.boolean(),user:l.string()}).strict(),"ApiToken"),nTe=Ne(l.object({tokens:l.array(tL)}).strict(),"ApiTokens"),rTe=Ne(l.object({name:l.string().min(1).max(80),actorKind:l.enum(["human","agent"]).default("agent"),scopes:l.array(l.string()).max(200).optional(),expiresInDays:l.number().int().min(1).max(365).optional()}).strict(),"CreateApiToken"),oTe=Ne(l.object({token:l.string().describe("The secret. Shown here and nowhere else, ever."),credential:tL}).strict(),"Cr\
1329
+ eatedApiToken"),OX=Ne(l.object({id:l.string(),at:Xn,userId:l.string().nullable(),userEmail:l.string().nullable(),principalKind:l.enum(["local","user","token"]),actor:l.string(),action:l.enum(Uv),resourceType:l.string(),resourceId:l.string().nullable(),resourceName:l.string().nullable(),project:l.string().nullable().describe("Project slug, when the entry is about one"),ipAddress:l.string().nullable(),metadata:l.record(l.string(),l.unknown())}).strict(),"AuditEntry"),sTe=Ne(l.object({entries:l.array(
1330
+ OX),nextBefore:l.string().nullable().describe("Pass as ?before= for the next page")}).strict(),"AuditPage"),iTe=Ne(l.object({permissions:l.array(l.string()).describe("In force right now"),defaults:l.array(l.string()).describe("What an agent holds when nothing is set"),available:l.array(l.string()).describe("Every permission this installation knows"),configured:l.boolean().describe("False when the default is what is in force")}).strict(),"AgentPermissions"),aTe=Ne(l.object({permissions:l.array(l.
1331
+ string().min(1).max(64)).max(64).nullable().describe("Null restores the default")}).strict(),"SetAgentPermissions");var $X=l.enum(["user","developer","all"]),vw=l.object({version:l.string(),revision:l.string().nullable(),hash:l.string()}),TX=l.object({id:l.string(),text:l.string(),level:l.number().int(),line:l.number().int()}),nL=l.object({slug:l.string(),title:l.string(),description:l.string(),audience:l.enum(["user","developer"]),section:l.string(),category:l.string(),source:l.string(),url:l.string(),kind:l.enum(["markdown","api"])}),CX=l.object({title:l.string(),category:l.string(),audience:l.enum(["user",
1332
+ "developer"]),sequential:l.boolean(),slugs:l.array(l.string())}),Sw=l.object({identity:vw,groups:l.array(CX),pages:l.array(nL)}),Jp=l.object({identity:vw,page:nL.extend({markdown:l.string(),headings:l.array(TX)})}),xw=l.object({identity:vw,results:l.array(l.object({slug:l.string(),title:l.string(),description:l.string(),audience:l.enum(["user","developer"]),section:l.string(),category:l.string(),url:l.string(),anchor:l.string().nullable(),excerpt:l.string()}))}),Yp=l.object({audience:$X.default(
1333
1333
  "all")}).strict(),kw=Yp.extend({q:l.string().trim().min(1).max(200),limit:l.coerce.number().int().min(1).max(50).default(10)}),_w=l.object({slug:l.string().regex(/^[a-z0-9]+(?:[/-][a-z0-9]+)*$/),anchor:l.string().min(1).max(300).optional()}).strict();var T=i((e,t)=>e.meta({ref:t}),"named"),ye=l.number().describe("Unix timestamp in seconds"),Xp=T(l.enum(["gateway","integrated","external","standalone"]).describe("How the gateway classifies a container"),"Ownership"),Qp=T(l.object({id:l.string().describe("Stable key used to pick an icon, for example postgres, nginx or docker"),label:l.string().describe("Short human label shown next to the icon")}).strict(),"ServiceTech"),ut=T(l.enum(["created","running","paused","restarting","removing","exited",
1334
- "dead"]),"ContainerState"),us=T(l.enum(["healthy","unhealthy","starting","none"]),"Health"),oL=T(l.enum(["local","vpn","public"]).describe("Where a routed URL can be reached from"),"UrlScope"),ed=T(l.enum(["internal","local","lan","private","protected","public"]).describe("Who can reach an endpoint"),"EndpointScope"),CX=T(l.enum(["starttls-sni","tls-sni","unsupported","unevaluated"]).describe("Whether a TCP protocol can be told apart by hostname on a shared port"),"TcpRouting"),Dr=T(l.enum(["htt\
1334
+ "dead"]),"ContainerState"),us=T(l.enum(["healthy","unhealthy","starting","none"]),"Health"),oL=T(l.enum(["local","vpn","public"]).describe("Where a routed URL can be reached from"),"UrlScope"),ed=T(l.enum(["internal","local","lan","private","protected","public"]).describe("Who can reach an endpoint"),"EndpointScope"),RX=T(l.enum(["starttls-sni","tls-sni","unsupported","unevaluated"]).describe("Whether a TCP protocol can be told apart by hostname on a shared port"),"TcpRouting"),Dr=T(l.enum(["htt\
1335
1335
  p","postgres","mysql","redis","mongodb","memcached","search","amqp","clickhouse","smtp","tcp","worker"]),"ServiceKind"),td=T(l.object({ip:l.string(),hostPort:l.number().int(),containerPort:l.number().int(),protocol:l.string()}).strict(),"PublishedPort"),Oa=T(l.object({url:l.string().describe("Absolute URL served by Traefik"),host:l.string(),scope:oL,scheme:l.enum(["http","https"])}).strict(),"RouteUrl"),sL=T(l.object({type:l.string(),name:l.string().nullable(),source:l.string(),destination:l.string(),
1336
- rw:l.boolean()}).strict(),"MountSummary"),RX=T(l.object({displayName:l.string().optional(),description:l.string().optional(),color:l.string().optional(),pinned:l.boolean().optional(),archived:l.boolean().optional(),primaryService:l.string().optional(),hiddenServices:l.array(l.string()).optional(),serviceOrder:l.array(l.string()).optional()}).strict(),"EnvironmentOverrides"),Pw=T(l.object({alias:l.string().optional().describe("An additional hostname, routed by Traefik"),note:l.string().optional(),
1337
- hidden:l.boolean().optional()}).strict(),"ServiceOverrides"),jX=T(l.object({id:l.string().describe("Docker container id"),name:l.string(),image:l.string(),state:ut,status:l.string(),health:us,createdAt:ye,startedAt:ye.nullable(),uptimeSeconds:l.number().nullable(),ownership:Xp,gatewayComponent:l.string().nullable(),environment:l.string().nullable().describe("Environment key (COMPOSE_PROJECT_NAME on this Node)"),service:l.string().nullable().describe("Compose service name"),workingDir:l.string().
1336
+ rw:l.boolean()}).strict(),"MountSummary"),jX=T(l.object({displayName:l.string().optional(),description:l.string().optional(),color:l.string().optional(),pinned:l.boolean().optional(),archived:l.boolean().optional(),primaryService:l.string().optional(),hiddenServices:l.array(l.string()).optional(),serviceOrder:l.array(l.string()).optional()}).strict(),"EnvironmentOverrides"),Pw=T(l.object({alias:l.string().optional().describe("An additional hostname, routed by Traefik"),note:l.string().optional(),
1337
+ hidden:l.boolean().optional()}).strict(),"ServiceOverrides"),IX=T(l.object({id:l.string().describe("Docker container id"),name:l.string(),image:l.string(),state:ut,status:l.string(),health:us,createdAt:ye,startedAt:ye.nullable(),uptimeSeconds:l.number().nullable(),ownership:Xp,gatewayComponent:l.string().nullable(),environment:l.string().nullable().describe("Environment key (COMPOSE_PROJECT_NAME on this Node)"),service:l.string().nullable().describe("Compose service name"),workingDir:l.string().
1338
1338
  nullable(),namespace:l.string().nullable(),group:l.string().nullable().describe("Optional portta.project logical project label"),networks:l.array(l.string()),onGatewayNetwork:l.boolean(),traefikEnabled:l.boolean(),ports:l.array(td),exposedPorts:l.array(l.number().int()),kind:Dr,tech:Qp,urls:l.array(Oa),mounts:l.array(sL),labels:l.record(l.string(),l.string()),restartCount:l.number().int(),exitCode:l.number().int().nullable(),oneOff:l.boolean().describe("A docker compose run container: it belongs\
1339
- to the environment but is not one of its services"),completed:l.boolean().describe("Exited 0 with no restart policy: a one-shot that did its job, not a service that is down"),overrides:Pw.optional().describe("Absent when nothing was overridden")}).strict(),"ContainerSummary"),IX=T(l.object({ok:l.boolean().describe("Whether Compose can be driven for this project from the labels Docker recorded"),reason:l.string().nullable().describe("Why it is not operable, when it is not"),workingDir:l.string().
1340
- nullable(),configFiles:l.array(l.string())}).strict(),"EnvironmentOperable"),DX=T(l.object({ok:l.boolean().describe("Whether start can run by iterating the containers that still exist"),reason:l.string().nullable(),via:l.enum(["iteration","runner"]).nullable()}).strict(),"EnvironmentStartable"),NX=T(l.object({service:l.string(),containerId:l.string(),action:l.enum(["start","stop"]),ok:l.boolean(),skipped:l.boolean(),error:l.string().nullable()}).strict(),"EnvironmentActionEntry"),bTe=T(l.object(
1341
- {ok:l.boolean().describe("True only when every requested step succeeded or was skipped"),project:l.string(),action:l.enum(["start","stop","restart"]),requested:l.number().int(),succeeded:l.number().int(),failed:l.number().int(),skipped:l.number().int(),results:l.array(NX)}).strict(),"EnvironmentActionResult"),iL=T(l.object({overrides:l.number().int(),aliases:l.number().int(),projectLinks:l.number().int(),accessBridges:l.array(l.string()),accessForwarders:l.array(l.string()),accessFiles:l.array(l.
1342
- string())}).strict(),"EnvironmentPorttaRecords"),yTe=T(l.object({environment:l.string(),containers:l.array(l.object({id:l.string(),name:l.string(),service:l.string().nullable(),state:ut,image:l.string()}).strict()),networks:l.array(l.string()),volumes:l.array(l.object({name:l.string(),sizeBytes:l.number().nullable().describe("Null: the panel has no volume inspect")}).strict()),workingDir:l.string().nullable(),records:iL,runnerAvailable:l.boolean()}).strict(),"EnvironmentRemovalPreview"),wTe=T(l.
1343
- object({name:l.string().describe("COMPOSE_PROJECT_NAME; the Environment key on this Node"),presence:l.enum(["live","remembered"]).describe("live: it has containers on this Node. remembered: the panel saw it once and kept where it ran; it can be started through the runner, or forgotten"),integrated:l.boolean(),workingDir:l.string().nullable(),operable:IX.describe("Whether the runner can find this environment on the host"),startable:DX.describe("Whether start can iterate existing containers, or ne\
1344
- eds the runner"),namespace:l.string().nullable(),group:l.string().nullable().describe("Optional portta.project label; a hint, not a Project"),services:l.array(jX),serviceCount:l.number().int(),runningCount:l.number().int(),completedCount:l.number().int().optional().describe("Services that exited 0 with no restart policy; they count as fine, not as down"),healthyCount:l.number().int(),unhealthyCount:l.number().int(),networks:l.array(l.string()),urls:l.array(Oa),scopes:l.array(oL),startedAt:ye.nullable(),
1345
- uptimeSeconds:l.number().nullable(),overrides:RX.optional().describe("Absent when nothing was overridden"),location:l.enum(["managed","external","escaped","missing","inaccessible"]).optional()}).strict(),"Environment"),LX=T(l.enum(["manual","label","path"]).describe("Why this environment belongs to this Project"),"AdoptionSource"),MX=T(l.enum(["resolved","conflict","ambiguous","unattributed"]).describe("How sure the panel is of an association"),"AttributionState"),Ew=T(l.enum(["managed","externa\
1346
- l","escaped","missing","inaccessible"]).describe("Where this Project sits relative to Projects Home"),"ProjectLocation"),vTe=Ew.options,zX=T(l.object({environment:l.string().describe("COMPOSE_PROJECT_NAME, the Environment key"),source:LX,attribution:MX.optional(),running:l.boolean(),serviceCount:l.number().int(),runningCount:l.number().int(),completedCount:l.number().int().optional().describe("Services that exited 0 with no restart policy"),unhealthyCount:l.number().int(),urls:l.array(Oa)}).strict(),
1347
- "ProjectEnvironment"),aL=T(l.object({key:l.string().max(32),value:l.string().min(1).max(64)}).strict(),"ProjectTag"),STe=T(l.object({id:l.string(),slug:l.string(),name:l.string(),description:l.string().nullable(),archived:l.boolean(),relativePath:l.string().nullable(),location:Ew,tags:l.array(aL),environmentCount:l.number().int(),runningEnvironmentCount:l.number().int(),environments:l.array(l.object({name:l.string().describe("COMPOSE_PROJECT_NAME"),running:l.boolean(),serviceCount:l.number().int(),
1348
- runningCount:l.number().int(),unhealthyCount:l.number().int()}).strict())}).strict(),"ProjectSummary"),xTe=T(l.object({id:l.string(),slug:l.string(),name:l.string(),description:l.string().nullable(),archived:l.boolean(),relativePath:l.string().nullable(),resolvedPath:l.string().nullable(),location:Ew,tags:l.array(aL),environments:l.array(zX)}).strict(),"Project"),cL=T(l.object({name:l.string(),rule:l.string(),hosts:l.array(l.string()).describe("Every Host rule name, lowercased"),entryPoints:l.array(
1349
- l.string()),middlewares:l.array(l.string()),service:l.string(),provider:l.string(),status:l.string().describe("Traefik verdict: enabled, disabled or warning"),errors:l.array(l.string()).describe("Traefik error text when it rejected the router"),servers:l.array(l.string()).describe("Backends Traefik resolved for this router")}).strict(),"TraefikRouter"),kTe=T(l.object({available:l.boolean().describe("False when the API is off or unreachable"),reason:l.string().nullable(),baseUrl:l.string(),dashboardUrl:l.
1350
- string().nullable(),routers:l.array(cL),fetchedAt:ye}).strict(),"TraefikVerdict"),_Te=T(l.object({containerId:l.string(),available:l.boolean(),reason:l.string().nullable(),expectedHosts:l.array(l.string()).describe("Hostnames derived from labels, for comparison"),routers:l.array(cL.extend({dashboardUrl:l.string().nullable()}).strict()),fetchedAt:ye}).strict(),"ServiceTraefik"),FX=T(l.enum(["public","protected"]),"ShareMode"),BX=T(l.enum(["active","expired","dangling"]),"ShareState"),UX=T(l.object(
1351
- {id:l.string(),project:l.string(),service:l.string(),container:l.string().describe("Unique container name used as the Traefik backend"),port:l.number().int(),host:l.string(),url:l.string(),mode:FX,user:l.string().nullable().describe("Username for a protected share; never a password"),createdAt:ye,expiresAt:ye,expiresInSeconds:l.number(),state:BX}).strict(),"Share"),lL=T(l.object({host:l.string(),mode:l.enum(["protected","public"]),user:l.string().nullable().describe("The login name of a protecte\
1352
- d host. Never a password or a hash."),project:l.string().nullable(),service:l.string().nullable(),label:l.string()}).strict(),"ExposureEntry"),PTe=T(l.object({enforced:l.boolean().describe("True on a public host: a hostname with no entry is closed. Elsewhere protection is optional."),entries:l.array(lL),openRouters:l.object({count:l.number().int(),names:l.array(l.string()).describe("Only those this caller may see; count is the whole host.")}).strict().describe("Containers answering with no login\
1353
- on names that cannot be listed. Any of them means no address on this host can be called protected.")}).strict(),"ExposureView"),ETe=T(l.object({ok:l.literal(!0),entry:lL.nullable().describe("Null once the entry was removed"),password:l.string().optional().describe("Shown once, when a credential was generated. Only its hash is stored."),note:l.string()}).strict(),"ExposureResult"),ls=T(l.object({search:l.boolean().describe("Search engines such as Googlebot and Bingbot"),train:l.boolean().describe(
1354
- "AI crawlers that collect text to train models, such as GPTBot and ClaudeBot"),live:l.boolean().describe("AI agents that read a page because a person asked, such as ChatGPT-User"),preview:l.boolean().describe("Link previews in chats and social networks, such as Slackbot")}).strict().describe("Which kinds of crawler may read a hostname. true lets that kind in."),"CrawlerPolicy"),ATe=T(l.object({default:ls.describe("What every project follows unless it has an exception. Everything blocked by defau\
1355
- lt."),exceptions:l.array(l.object({project:l.string().describe("The slug of the project"),name:l.string(),policy:ls.nullable().describe("Null when the environments of the project disagree"),mixed:l.boolean().describe("True when the environments of the project do not all follow the same exception")}).strict()).describe("Only the projects this caller may see, including the ones whose environments disagree")}).strict(),"CrawlerSettings"),OTe=T(l.object({default:ls,own:ls.nullable().describe("The ex\
1356
- ception set for this project, or null when it follows the default"),effective:ls,mixed:l.boolean().describe("True when the environments of this project do not all have the same exception"),byEnvironment:l.record(l.string(),ls).describe("What each environment follows, which decides the verdict of each of its addresses")}).strict(),"ProjectCrawlers"),qX=T(l.object({path:l.string().describe("Relative to the project folder, with forward slashes"),kind:l.enum(["file","dir","link"]),size:l.number().int().
1357
- nullable(),status:l.enum(["M","A","D","U"]).nullable().describe("Against the last commit; U is not tracked yet"),ignored:l.boolean().describe("Listed because git ignores it, such as node_modules. Never read."),readable:l.enum(["text","hidden","binary","large","omitted"]).describe("hidden: usually holds a secret, so only its existence is shown"),diff:l.boolean().describe("Whether there are changes to show against the last commit")}).strict(),"ProjectFile"),$Te=T(l.object({environments:l.array(l.string()).
1358
- describe("The environments of this project that have a copy of their files"),environment:l.string().nullable(),branch:l.string().nullable(),head:l.object({hash:l.string(),subject:l.string(),at:l.number().int()}).strict().nullable(),changed:l.number().int(),untracked:l.number().int(),ahead:l.number().int().nullable(),collectedAt:l.number().int().nullable(),truncated:l.boolean().describe("The project is bigger than the copy: the changed files come first"),files:l.array(qX)}).strict(),"ProjectFiles\
1359
- View"),TTe=T(l.object({environment:l.string(),path:l.string(),content:l.string(),diff:l.string().nullable().describe("The changes against the last commit, as a patch")}).strict(),"ProjectFileContent"),HX=T(l.object({path:l.string().describe("Relative to Projects Home, with forward slashes"),composeFile:l.string(),services:l.number().int().nullable().describe("Null until the collector has analysed the folder"),modifiedAt:l.number().int(),adopted:l.boolean().describe("The folder already has a Port\
1360
- ta overlay"),planned:l.boolean().describe("Whether a plan can be reviewed"),registered:l.boolean().describe("A project already has this folder")}).strict(),"DiscoveredFolder"),CTe=T(l.object({home:l.string().nullable().describe("Projects Home as the host has it, or null when nothing was published"),collectedAt:l.number().int().nullable(),folders:l.array(HX)}).strict(),"DiscoveredFoldersView"),RTe=T(l.object({home:l.string().describe("Projects Home as the host has it, which the command is written\
1339
+ to the environment but is not one of its services"),completed:l.boolean().describe("Exited 0 with no restart policy: a one-shot that did its job, not a service that is down"),overrides:Pw.optional().describe("Absent when nothing was overridden")}).strict(),"ContainerSummary"),DX=T(l.object({ok:l.boolean().describe("Whether Compose can be driven for this project from the labels Docker recorded"),reason:l.string().nullable().describe("Why it is not operable, when it is not"),workingDir:l.string().
1340
+ nullable(),configFiles:l.array(l.string())}).strict(),"EnvironmentOperable"),NX=T(l.object({ok:l.boolean().describe("Whether start can run by iterating the containers that still exist"),reason:l.string().nullable(),via:l.enum(["iteration","runner"]).nullable()}).strict(),"EnvironmentStartable"),LX=T(l.object({service:l.string(),containerId:l.string(),action:l.enum(["start","stop"]),ok:l.boolean(),skipped:l.boolean(),error:l.string().nullable()}).strict(),"EnvironmentActionEntry"),yTe=T(l.object(
1341
+ {ok:l.boolean().describe("True only when every requested step succeeded or was skipped"),project:l.string(),action:l.enum(["start","stop","restart"]),requested:l.number().int(),succeeded:l.number().int(),failed:l.number().int(),skipped:l.number().int(),results:l.array(LX)}).strict(),"EnvironmentActionResult"),iL=T(l.object({overrides:l.number().int(),aliases:l.number().int(),projectLinks:l.number().int(),accessBridges:l.array(l.string()),accessForwarders:l.array(l.string()),accessFiles:l.array(l.
1342
+ string())}).strict(),"EnvironmentPorttaRecords"),wTe=T(l.object({environment:l.string(),containers:l.array(l.object({id:l.string(),name:l.string(),service:l.string().nullable(),state:ut,image:l.string()}).strict()),networks:l.array(l.string()),volumes:l.array(l.object({name:l.string(),sizeBytes:l.number().nullable().describe("Null: the panel has no volume inspect")}).strict()),workingDir:l.string().nullable(),records:iL,runnerAvailable:l.boolean()}).strict(),"EnvironmentRemovalPreview"),vTe=T(l.
1343
+ object({name:l.string().describe("COMPOSE_PROJECT_NAME; the Environment key on this Node"),presence:l.enum(["live","remembered"]).describe("live: it has containers on this Node. remembered: the panel saw it once and kept where it ran; it can be started through the runner, or forgotten"),integrated:l.boolean(),workingDir:l.string().nullable(),operable:DX.describe("Whether the runner can find this environment on the host"),startable:NX.describe("Whether start can iterate existing containers, or ne\
1344
+ eds the runner"),namespace:l.string().nullable(),group:l.string().nullable().describe("Optional portta.project label; a hint, not a Project"),services:l.array(IX),serviceCount:l.number().int(),runningCount:l.number().int(),completedCount:l.number().int().optional().describe("Services that exited 0 with no restart policy; they count as fine, not as down"),healthyCount:l.number().int(),unhealthyCount:l.number().int(),networks:l.array(l.string()),urls:l.array(Oa),scopes:l.array(oL),startedAt:ye.nullable(),
1345
+ uptimeSeconds:l.number().nullable(),overrides:jX.optional().describe("Absent when nothing was overridden"),location:l.enum(["managed","external","escaped","missing","inaccessible"]).optional()}).strict(),"Environment"),MX=T(l.enum(["manual","label","path"]).describe("Why this environment belongs to this Project"),"AdoptionSource"),zX=T(l.enum(["resolved","conflict","ambiguous","unattributed"]).describe("How sure the panel is of an association"),"AttributionState"),Ew=T(l.enum(["managed","externa\
1346
+ l","escaped","missing","inaccessible"]).describe("Where this Project sits relative to Projects Home"),"ProjectLocation"),STe=Ew.options,FX=T(l.object({environment:l.string().describe("COMPOSE_PROJECT_NAME, the Environment key"),source:MX,attribution:zX.optional(),running:l.boolean(),serviceCount:l.number().int(),runningCount:l.number().int(),completedCount:l.number().int().optional().describe("Services that exited 0 with no restart policy"),unhealthyCount:l.number().int(),urls:l.array(Oa)}).strict(),
1347
+ "ProjectEnvironment"),aL=T(l.object({key:l.string().max(32),value:l.string().min(1).max(64)}).strict(),"ProjectTag"),xTe=T(l.object({id:l.string(),slug:l.string(),name:l.string(),description:l.string().nullable(),archived:l.boolean(),relativePath:l.string().nullable(),location:Ew,tags:l.array(aL),environmentCount:l.number().int(),runningEnvironmentCount:l.number().int(),environments:l.array(l.object({name:l.string().describe("COMPOSE_PROJECT_NAME"),running:l.boolean(),serviceCount:l.number().int(),
1348
+ runningCount:l.number().int(),unhealthyCount:l.number().int()}).strict())}).strict(),"ProjectSummary"),kTe=T(l.object({id:l.string(),slug:l.string(),name:l.string(),description:l.string().nullable(),archived:l.boolean(),relativePath:l.string().nullable(),resolvedPath:l.string().nullable(),location:Ew,tags:l.array(aL),environments:l.array(FX)}).strict(),"Project"),cL=T(l.object({name:l.string(),rule:l.string(),hosts:l.array(l.string()).describe("Every Host rule name, lowercased"),entryPoints:l.array(
1349
+ l.string()),middlewares:l.array(l.string()),service:l.string(),provider:l.string(),status:l.string().describe("Traefik verdict: enabled, disabled or warning"),errors:l.array(l.string()).describe("Traefik error text when it rejected the router"),servers:l.array(l.string()).describe("Backends Traefik resolved for this router")}).strict(),"TraefikRouter"),_Te=T(l.object({available:l.boolean().describe("False when the API is off or unreachable"),reason:l.string().nullable(),baseUrl:l.string(),dashboardUrl:l.
1350
+ string().nullable(),routers:l.array(cL),fetchedAt:ye}).strict(),"TraefikVerdict"),PTe=T(l.object({containerId:l.string(),available:l.boolean(),reason:l.string().nullable(),expectedHosts:l.array(l.string()).describe("Hostnames derived from labels, for comparison"),routers:l.array(cL.extend({dashboardUrl:l.string().nullable()}).strict()),fetchedAt:ye}).strict(),"ServiceTraefik"),BX=T(l.enum(["public","protected"]),"ShareMode"),UX=T(l.enum(["active","expired","dangling"]),"ShareState"),qX=T(l.object(
1351
+ {id:l.string(),project:l.string(),service:l.string(),container:l.string().describe("Unique container name used as the Traefik backend"),port:l.number().int(),host:l.string(),url:l.string(),mode:BX,user:l.string().nullable().describe("Username for a protected share; never a password"),createdAt:ye,expiresAt:ye,expiresInSeconds:l.number(),state:UX}).strict(),"Share"),lL=T(l.object({host:l.string(),mode:l.enum(["protected","public"]),user:l.string().nullable().describe("The login name of a protecte\
1352
+ d host. Never a password or a hash."),project:l.string().nullable(),service:l.string().nullable(),label:l.string()}).strict(),"ExposureEntry"),ETe=T(l.object({enforced:l.boolean().describe("True on a public host: a hostname with no entry is closed. Elsewhere protection is optional."),entries:l.array(lL),openRouters:l.object({count:l.number().int(),names:l.array(l.string()).describe("Only those this caller may see; count is the whole host.")}).strict().describe("Containers answering with no login\
1353
+ on names that cannot be listed. Any of them means no address on this host can be called protected.")}).strict(),"ExposureView"),ATe=T(l.object({ok:l.literal(!0),entry:lL.nullable().describe("Null once the entry was removed"),password:l.string().optional().describe("Shown once, when a credential was generated. Only its hash is stored."),note:l.string()}).strict(),"ExposureResult"),ls=T(l.object({search:l.boolean().describe("Search engines such as Googlebot and Bingbot"),train:l.boolean().describe(
1354
+ "AI crawlers that collect text to train models, such as GPTBot and ClaudeBot"),live:l.boolean().describe("AI agents that read a page because a person asked, such as ChatGPT-User"),preview:l.boolean().describe("Link previews in chats and social networks, such as Slackbot")}).strict().describe("Which kinds of crawler may read a hostname. true lets that kind in."),"CrawlerPolicy"),OTe=T(l.object({default:ls.describe("What every project follows unless it has an exception. Everything blocked by defau\
1355
+ lt."),exceptions:l.array(l.object({project:l.string().describe("The slug of the project"),name:l.string(),policy:ls.nullable().describe("Null when the environments of the project disagree"),mixed:l.boolean().describe("True when the environments of the project do not all follow the same exception")}).strict()).describe("Only the projects this caller may see, including the ones whose environments disagree")}).strict(),"CrawlerSettings"),$Te=T(l.object({default:ls,own:ls.nullable().describe("The ex\
1356
+ ception set for this project, or null when it follows the default"),effective:ls,mixed:l.boolean().describe("True when the environments of this project do not all have the same exception"),byEnvironment:l.record(l.string(),ls).describe("What each environment follows, which decides the verdict of each of its addresses")}).strict(),"ProjectCrawlers"),HX=T(l.object({path:l.string().describe("Relative to the project folder, with forward slashes"),kind:l.enum(["file","dir","link"]),size:l.number().int().
1357
+ nullable(),status:l.enum(["M","A","D","U"]).nullable().describe("Against the last commit; U is not tracked yet"),ignored:l.boolean().describe("Listed because git ignores it, such as node_modules. Never read."),readable:l.enum(["text","hidden","binary","large","omitted"]).describe("hidden: usually holds a secret, so only its existence is shown"),diff:l.boolean().describe("Whether there are changes to show against the last commit")}).strict(),"ProjectFile"),TTe=T(l.object({environments:l.array(l.string()).
1358
+ describe("The environments of this project that have a copy of their files"),environment:l.string().nullable(),branch:l.string().nullable(),head:l.object({hash:l.string(),subject:l.string(),at:l.number().int()}).strict().nullable(),changed:l.number().int(),untracked:l.number().int(),ahead:l.number().int().nullable(),collectedAt:l.number().int().nullable(),truncated:l.boolean().describe("The project is bigger than the copy: the changed files come first"),files:l.array(HX)}).strict(),"ProjectFiles\
1359
+ View"),CTe=T(l.object({environment:l.string(),path:l.string(),content:l.string(),diff:l.string().nullable().describe("The changes against the last commit, as a patch")}).strict(),"ProjectFileContent"),ZX=T(l.object({path:l.string().describe("Relative to Projects Home, with forward slashes"),composeFile:l.string(),services:l.number().int().nullable().describe("Null until the collector has analysed the folder"),modifiedAt:l.number().int(),adopted:l.boolean().describe("The folder already has a Port\
1360
+ ta overlay"),planned:l.boolean().describe("Whether a plan can be reviewed"),registered:l.boolean().describe("A project already has this folder")}).strict(),"DiscoveredFolder"),RTe=T(l.object({home:l.string().nullable().describe("Projects Home as the host has it, or null when nothing was published"),collectedAt:l.number().int().nullable(),folders:l.array(ZX)}).strict(),"DiscoveredFoldersView"),jTe=T(l.object({home:l.string().describe("Projects Home as the host has it, which the command is written\
1361
1361
  against"),path:l.string(),composeFile:l.string(),project:l.object({name:l.string(),source:l.string()}).strict(),domain:l.string(),adopted:l.boolean(),services:l.array(l.object({name:l.string(),image:l.string().nullable(),kind:l.string(),port:l.string().nullable().describe("The port Portta would route to, for a service that speaks HTTP"),publishedPorts:l.array(l.object({host:l.string(),container:l.string()}).strict()),containerName:l.string().nullable()}).strict()),findings:l.object({publishedHostPorts:l.
1362
1362
  array(l.string()),fixedContainerNames:l.array(l.string()),publishedDatastores:l.array(l.string()),implicitNamespace:l.boolean(),containerNameCollisions:l.array(l.object({service:l.string(),containerName:l.string(),usedBy:l.string()}).strict()),namespaceInUse:l.object({project:l.string(),workingDirs:l.array(l.string())}).strict().nullable()}).strict(),collectedAt:l.number().int(),command:l.string().describe("The terminal command that adopts this folder, with nothing decided yet")}).strict(),"Fold\
1363
- erPlanView"),jTe=T(l.object({shares:l.array(UX),domain:l.string().describe("The domain share hostnames sit under, one label deep: <project>-<service>-<id>-share.<domain>"),publicAllowed:l.boolean().describe("Whether a public share would be accepted"),maxTtlSeconds:l.number().int()}).strict(),"ShareView"),nd=T(l.object({id:l.string(),status:l.enum(["pass","info","warn","fail"]),title:l.string(),detail:l.string(),fix:l.string(),params:l.record(l.string(),l.union([l.string(),l.number()])).optional(),
1364
- category:l.enum(["infrastructure","development","agents","security"]).optional(),details:l.array(l.object({status:l.enum(["pass","info","warn","fail"]),text:l.string()}).strict()).optional(),tool:l.object({installed:l.boolean(),version:l.string().nullable(),path:l.string().nullable(),minimum:l.string().optional(),recommended:l.string().optional()}).strict().optional(),rationale:l.string().optional(),docs:l.string().optional()}).strict(),"Diagnostic"),ZX=nd,uL=l.object({version:l.literal(1),collectedAt:ye.
1365
- nullable(),durationMs:l.number().int().nonnegative().nullable(),ageSeconds:l.number().int().nonnegative().nullable(),stale:l.boolean(),checks:l.array(ZX),summary:l.object({passed:l.number().int().nonnegative(),recommendations:l.number().int().nonnegative(),problems:l.number().int().nonnegative(),information:l.number().int().nonnegative(),ok:l.boolean()}).strict()}).strict(),ITe=T(uL,"EnvironmentReport"),DTe=T(uL,"SecurityReport"),GX=l.object({enabled:l.boolean(),mode:l.string()}).strict(),WX=l.object(
1366
- {enabled:l.boolean(),running:l.boolean(),hostname:l.string()}).strict(),VX=l.object({enabled:l.boolean(),domain:l.string().nullable()}).strict(),KX=l.object({expose:l.string(),routed:l.boolean(),auth:l.string(),authenticated:l.boolean(),readOnly:l.boolean(),docs:l.boolean()}).strict(),JX=l.object({enabled:l.boolean(),bindAddress:l.string(),port:l.string(),expose:l.literal("local"),advertisedHost:l.string().nullable(),authenticated:l.boolean(),endpoints:l.array(l.object({provider:l.string(),url:l.
1367
- string(),scope:ed,usable:l.boolean(),shareable:l.boolean(),problem:l.string().nullable()}).strict())}).strict(),rL=l.object({containerId:l.string().nullable(),state:ut.or(l.literal("absent")),health:us}).strict(),YX=l.object({containerId:l.string().nullable(),state:ut.or(l.literal("absent"))}).strict(),XX=l.object({name:l.string(),exists:l.boolean(),attached:l.number().int(),internal:l.boolean()}).strict(),pL=T(l.object({gatewayVersion:l.string(),panelVersion:l.string(),profile:l.string(),domain:l.
1368
- string(),privateDomain:l.string().nullable(),publicDomain:l.string().nullable(),bindAddress:l.string(),httpPort:l.string(),httpsPort:l.string(),scheme:l.enum(["http","https"]),up:l.boolean(),reachable:l.boolean(),tls:GX,tailscale:WX,publicAccess:VX,panel:KX.describe("Panel exposure and authentication without the secret hash"),dashboard:JX,traefik:rL,socketProxy:YX,database:rL,network:XX,routes:l.number().int()}).strict(),"GatewayStatus"),Y=l.number().nullable(),Re=l.string().nullable(),dL=l.object(
1369
- {one:l.number(),five:l.number(),fifteen:l.number()}).strict(),QX=T(l.object({manufacturer:Re,brand:Re,physicalCores:l.number().int().nullable(),logicalCores:l.number().int().nullable(),speed:Y,speedMax:Y}).strict(),"HostCpuInfo"),eQ=T(l.object({vendor:Re,model:l.string(),vramBytes:Y,utilisation:Y,temperature:Y}).strict(),"HostGpuInfo"),tQ=T(l.object({hasBattery:l.literal(!0),percent:Y.describe("0-1"),charging:l.boolean(),acConnected:l.boolean(),minutesRemaining:l.number().int().nullable(),cycleCount:l.
1370
- number().int().nullable()}).strict(),"HostBatteryInfo"),nQ=T(l.object({path:l.string(),mount:Re,filesystem:Re,totalBytes:l.number(),usedBytes:l.number(),availableBytes:l.number(),usedPercent:l.number()}).strict(),"HostStorageInfo"),rQ=l.enum(["notebook","desktop","server","vm"]),oQ=T(l.object({hostname:Re,manufacturer:Re,model:Re,productName:Re.describe("The commercial name, where the platform reports a trustworthy one (macOS so far)"),kind:rQ.nullable().describe("What the machine is, from its c\
1371
- hassis, hypervisor flag and battery; null when none of them say"),architecture:Re,virtual:l.boolean().nullable(),platform:Re,distro:Re,version:Re,release:Re,kernel:Re,uptimeSeconds:Y,timezone:Re.optional().describe("The IANA zone the server clock is set to; absent in readings from an older collector"),utcOffsetMinutes:Y.optional().describe("Minutes east of UTC when the reading was taken"),cpu:QX,memoryTotalBytes:Y,memoryUsedBytes:Y,memoryAvailableBytes:Y,memoryUsedPercent:Y,swapTotalBytes:Y,swapUsedBytes:Y,
1372
- cpuUtilisation:Y,cpuIdle:Y,load:dL.nullable(),storage:nQ.nullable(),gpu:l.array(eQ),gpuMemory:l.object({usedBytes:l.number(),totalBytes:l.number()}).strict().nullable().optional().describe("Memory used and present on the GPUs, from nvidia-smi; absent on other GPUs"),temperatureCelsius:Y.describe("CPU package temperature in Celsius, where the platform reports one"),battery:tQ.nullable().describe("Absent on a host with no battery")}).strict(),"HostMetrics"),sQ=T(l.object({id:l.string(),name:l.string(),
1373
- service:Re,cpuUtilisation:Y,memoryUsedBytes:Y,memoryLimitBytes:Y,memoryUsedPercent:Y,networkRxBytes:Y,networkTxBytes:Y,blockReadBytes:Y,blockWriteBytes:Y,pids:l.number().int().nullable()}).strict(),"ContainerResourceMetrics"),iQ=T(l.object({path:l.string().describe("The working directory it was read from"),branch:l.string().nullable().describe("Null when HEAD is detached or the repository has no commit yet"),detached:l.boolean(),upstream:l.string().nullable(),ahead:l.number().int().nullable().describe(
1363
+ erPlanView"),ITe=T(l.object({shares:l.array(qX),domain:l.string().describe("The domain share hostnames sit under, one label deep: <project>-<service>-<id>-share.<domain>"),publicAllowed:l.boolean().describe("Whether a public share would be accepted"),maxTtlSeconds:l.number().int()}).strict(),"ShareView"),nd=T(l.object({id:l.string(),status:l.enum(["pass","info","warn","fail"]),title:l.string(),detail:l.string(),fix:l.string(),params:l.record(l.string(),l.union([l.string(),l.number()])).optional(),
1364
+ category:l.enum(["infrastructure","development","agents","security"]).optional(),details:l.array(l.object({status:l.enum(["pass","info","warn","fail"]),text:l.string()}).strict()).optional(),tool:l.object({installed:l.boolean(),version:l.string().nullable(),path:l.string().nullable(),minimum:l.string().optional(),recommended:l.string().optional()}).strict().optional(),rationale:l.string().optional(),docs:l.string().optional()}).strict(),"Diagnostic"),GX=nd,uL=l.object({version:l.literal(1),collectedAt:ye.
1365
+ nullable(),durationMs:l.number().int().nonnegative().nullable(),ageSeconds:l.number().int().nonnegative().nullable(),stale:l.boolean(),checks:l.array(GX),summary:l.object({passed:l.number().int().nonnegative(),recommendations:l.number().int().nonnegative(),problems:l.number().int().nonnegative(),information:l.number().int().nonnegative(),ok:l.boolean()}).strict()}).strict(),DTe=T(uL,"EnvironmentReport"),NTe=T(uL,"SecurityReport"),WX=l.object({enabled:l.boolean(),mode:l.string()}).strict(),VX=l.object(
1366
+ {enabled:l.boolean(),running:l.boolean(),hostname:l.string()}).strict(),KX=l.object({enabled:l.boolean(),domain:l.string().nullable()}).strict(),JX=l.object({expose:l.string(),routed:l.boolean(),auth:l.string(),authenticated:l.boolean(),readOnly:l.boolean(),docs:l.boolean()}).strict(),YX=l.object({enabled:l.boolean(),bindAddress:l.string(),port:l.string(),expose:l.literal("local"),advertisedHost:l.string().nullable(),authenticated:l.boolean(),endpoints:l.array(l.object({provider:l.string(),url:l.
1367
+ string(),scope:ed,usable:l.boolean(),shareable:l.boolean(),problem:l.string().nullable()}).strict())}).strict(),rL=l.object({containerId:l.string().nullable(),state:ut.or(l.literal("absent")),health:us}).strict(),XX=l.object({containerId:l.string().nullable(),state:ut.or(l.literal("absent"))}).strict(),QX=l.object({name:l.string(),exists:l.boolean(),attached:l.number().int(),internal:l.boolean()}).strict(),pL=T(l.object({gatewayVersion:l.string(),panelVersion:l.string(),profile:l.string(),domain:l.
1368
+ string(),privateDomain:l.string().nullable(),publicDomain:l.string().nullable(),bindAddress:l.string(),httpPort:l.string(),httpsPort:l.string(),scheme:l.enum(["http","https"]),up:l.boolean(),reachable:l.boolean(),tls:WX,tailscale:VX,publicAccess:KX,panel:JX.describe("Panel exposure and authentication without the secret hash"),dashboard:YX,traefik:rL,socketProxy:XX,database:rL,network:QX,routes:l.number().int()}).strict(),"GatewayStatus"),Y=l.number().nullable(),Re=l.string().nullable(),dL=l.object(
1369
+ {one:l.number(),five:l.number(),fifteen:l.number()}).strict(),eQ=T(l.object({manufacturer:Re,brand:Re,physicalCores:l.number().int().nullable(),logicalCores:l.number().int().nullable(),speed:Y,speedMax:Y}).strict(),"HostCpuInfo"),tQ=T(l.object({vendor:Re,model:l.string(),vramBytes:Y,utilisation:Y,temperature:Y}).strict(),"HostGpuInfo"),nQ=T(l.object({hasBattery:l.literal(!0),percent:Y.describe("0-1"),charging:l.boolean(),acConnected:l.boolean(),minutesRemaining:l.number().int().nullable(),cycleCount:l.
1370
+ number().int().nullable()}).strict(),"HostBatteryInfo"),rQ=T(l.object({path:l.string(),mount:Re,filesystem:Re,totalBytes:l.number(),usedBytes:l.number(),availableBytes:l.number(),usedPercent:l.number()}).strict(),"HostStorageInfo"),oQ=l.enum(["notebook","desktop","server","vm"]),sQ=T(l.object({hostname:Re,manufacturer:Re,model:Re,productName:Re.describe("The commercial name, where the platform reports a trustworthy one (macOS so far)"),kind:oQ.nullable().describe("What the machine is, from its c\
1371
+ hassis, hypervisor flag and battery; null when none of them say"),architecture:Re,virtual:l.boolean().nullable(),platform:Re,distro:Re,version:Re,release:Re,kernel:Re,uptimeSeconds:Y,timezone:Re.optional().describe("The IANA zone the server clock is set to; absent in readings from an older collector"),utcOffsetMinutes:Y.optional().describe("Minutes east of UTC when the reading was taken"),cpu:eQ,memoryTotalBytes:Y,memoryUsedBytes:Y,memoryAvailableBytes:Y,memoryUsedPercent:Y,swapTotalBytes:Y,swapUsedBytes:Y,
1372
+ cpuUtilisation:Y,cpuIdle:Y,load:dL.nullable(),storage:rQ.nullable(),gpu:l.array(tQ),gpuMemory:l.object({usedBytes:l.number(),totalBytes:l.number()}).strict().nullable().optional().describe("Memory used and present on the GPUs, from nvidia-smi; absent on other GPUs"),temperatureCelsius:Y.describe("CPU package temperature in Celsius, where the platform reports one"),battery:nQ.nullable().describe("Absent on a host with no battery")}).strict(),"HostMetrics"),iQ=T(l.object({id:l.string(),name:l.string(),
1373
+ service:Re,cpuUtilisation:Y,memoryUsedBytes:Y,memoryLimitBytes:Y,memoryUsedPercent:Y,networkRxBytes:Y,networkTxBytes:Y,blockReadBytes:Y,blockWriteBytes:Y,pids:l.number().int().nullable()}).strict(),"ContainerResourceMetrics"),aQ=T(l.object({path:l.string().describe("The working directory it was read from"),branch:l.string().nullable().describe("Null when HEAD is detached or the repository has no commit yet"),detached:l.boolean(),upstream:l.string().nullable(),ahead:l.number().int().nullable().describe(
1374
1374
  "Commits not yet pushed; null without an upstream"),behind:l.number().int().nullable().describe("Commits not yet pulled, as last fetched; null without an upstream"),head:l.object({sha:l.string(),subject:l.string(),author:l.string(),at:ye}).strict().nullable(),changed:l.number().int().describe("Tracked files with changes not committed"),untracked:l.number().int(),files:l.array(l.object({path:l.string(),status:l.enum(["M","A","D","U"]).describe("Modified, added, deleted or new (untracked)")}).strict()).
1375
- describe("The first of them: changed + untracked can be longer"),lastChangeAt:ye.nullable().describe("The newest of the last commit and the files not committed"),collectedAt:ye}).strict(),"GitState"),aQ=T(l.object({id:l.string(),name:l.string(),composeProject:l.string(),own:l.literal(!0).optional().describe("Set on Portta's own containers (gateway, panel, proxies)"),cpuUtilisation:Y,memoryUsedBytes:Y,gpuMemoryBytes:Y.optional().describe("What its containers hold of the GPU's memory"),containerCount:l.
1376
- number().int(),networkRxBytes:Y,networkTxBytes:Y,containers:l.array(sQ),git:iQ.nullable().optional()}).strict(),"ProjectResourceMetrics"),cQ=T(l.object({id:l.string(),name:Re,hostname:Re}).strict(),"MetricsInstance"),lQ=T(l.object({name:l.enum(["orbstack","docker-desktop","docker-engine","unknown"])}).strict(),"RuntimeHint"),uQ=T(l.object({collectedAt:ye,projects:l.array(l.object({composeProject:l.string(),volumeBytes:l.number().describe("The project's named volumes"),layerBytes:l.number().describe(
1377
- "The writable layer of its containers")}).strict())}).strict().describe("What each Compose project keeps on the Docker disk. Images are shared and are not counted here"),"DockerStorageInfo"),NTe=T(l.object({version:l.literal(1),instance:cQ,collectedAt:ye.nullable(),ageSeconds:l.number().int().nullable(),stale:l.boolean(),collectorActive:l.boolean(),host:oQ.nullable(),runtime:lQ.nullable(),projects:l.array(aQ),dockerStorage:uQ.nullable().optional()}).strict(),"MetricsCurrent"),pQ=T(l.object({timestamp:ye,
1378
- host:l.object({cpuUtilisation:Y,memoryUsedBytes:Y,memoryUsedPercent:Y,storageUsedPercent:Y,load:dL.nullable(),gpuUtilisation:Y,temperatureCelsius:Y}).strict(),projects:l.array(l.object({id:l.string(),cpuUtilisation:Y,memoryUsedBytes:Y}).strict()),containers:l.array(l.object({id:l.string(),cpuUtilisation:Y,memoryUsedBytes:Y}).strict())}).strict(),"MetricsHistoryPoint"),LTe=T(l.object({windowSeconds:l.number().int(),points:l.array(pQ)}).strict(),"MetricsHistory"),dQ=T(l.object({projects:l.number().
1375
+ describe("The first of them: changed + untracked can be longer"),lastChangeAt:ye.nullable().describe("The newest of the last commit and the files not committed"),collectedAt:ye}).strict(),"GitState"),cQ=T(l.object({id:l.string(),name:l.string(),composeProject:l.string(),own:l.literal(!0).optional().describe("Set on Portta's own containers (gateway, panel, proxies)"),cpuUtilisation:Y,memoryUsedBytes:Y,gpuMemoryBytes:Y.optional().describe("What its containers hold of the GPU's memory"),containerCount:l.
1376
+ number().int(),networkRxBytes:Y,networkTxBytes:Y,containers:l.array(iQ),git:aQ.nullable().optional()}).strict(),"ProjectResourceMetrics"),lQ=T(l.object({id:l.string(),name:Re,hostname:Re}).strict(),"MetricsInstance"),uQ=T(l.object({name:l.enum(["orbstack","docker-desktop","docker-engine","unknown"])}).strict(),"RuntimeHint"),pQ=T(l.object({collectedAt:ye,projects:l.array(l.object({composeProject:l.string(),volumeBytes:l.number().describe("The project's named volumes"),layerBytes:l.number().describe(
1377
+ "The writable layer of its containers")}).strict())}).strict().describe("What each Compose project keeps on the Docker disk. Images are shared and are not counted here"),"DockerStorageInfo"),LTe=T(l.object({version:l.literal(1),instance:lQ,collectedAt:ye.nullable(),ageSeconds:l.number().int().nullable(),stale:l.boolean(),collectorActive:l.boolean(),host:sQ.nullable(),runtime:uQ.nullable(),projects:l.array(cQ),dockerStorage:pQ.nullable().optional()}).strict(),"MetricsCurrent"),dQ=T(l.object({timestamp:ye,
1378
+ host:l.object({cpuUtilisation:Y,memoryUsedBytes:Y,memoryUsedPercent:Y,storageUsedPercent:Y,load:dL.nullable(),gpuUtilisation:Y,temperatureCelsius:Y}).strict(),projects:l.array(l.object({id:l.string(),cpuUtilisation:Y,memoryUsedBytes:Y}).strict()),containers:l.array(l.object({id:l.string(),cpuUtilisation:Y,memoryUsedBytes:Y}).strict())}).strict(),"MetricsHistoryPoint"),MTe=T(l.object({windowSeconds:l.number().int(),points:l.array(dQ)}).strict(),"MetricsHistory"),fQ=T(l.object({projects:l.number().
1379
1379
  int(),integratedProjects:l.number().int(),services:l.number().int(),servicesRunning:l.number().int(),servicesHealthy:l.number().int(),servicesUnhealthy:l.number().int(),containersTotal:l.number().int(),containersRunning:l.number().int(),containersGateway:l.number().int(),containersIntegrated:l.number().int(),containersExternal:l.number().int(),containersStandalone:l.number().int(),bridges:l.number().int(),forwarders:l.number().int(),routes:l.number().int(),shares:l.number().int(),sharesStale:l.number().
1380
- int().describe("Shares that expired or whose target is gone")}).strict(),"OverviewCounts"),MTe=T(l.object({gateway:pL,counts:dQ,urls:l.array(Oa),problems:l.array(nd),generatedAt:ye}).strict(),"Overview"),fL=T(l.object({id:l.string(),name:l.string(),driver:l.string(),scope:l.string(),internal:l.boolean(),containerCount:l.number().int(),managed:l.boolean(),role:l.enum(["shared","control","access","project","other"])}).strict(),"NetworkSummary"),fQ=l.object({ip:l.string(),containerId:l.string(),containerName:l.
1381
- string(),ownership:Xp,containerPort:l.number().int()}).strict(),mQ=T(l.object({hostPort:l.number().int(),protocol:l.string(),bindings:l.array(fQ),conflict:l.boolean()}).strict(),"PortUsage"),zTe=T(l.object({engine:l.object({version:l.string(),apiVersion:l.string(),os:l.string(),arch:l.string(),cpus:l.number().int(),memoryBytes:l.number(),name:l.string()}).strict(),containers:l.object({total:l.number().int(),running:l.number().int(),paused:l.number().int(),stopped:l.number().int()}).strict(),byOwnership:l.
1382
- object({gateway:l.number().int(),integrated:l.number().int(),external:l.number().int(),standalone:l.number().int()}).strict(),networks:l.array(fL),ports:l.array(mQ)}).strict(),"DockerHost"),rd=T(l.object({id:l.string(),containerId:l.string(),project:l.string(),service:l.string(),targetPort:l.number().int(),localPort:l.number().int().nullable(),bindIp:l.string(),kind:Dr,network:l.string(),createdAt:ye.nullable(),expiresAt:ye.nullable(),state:ut.or(l.literal("absent")),connectionString:l.string()}).
1383
- strict(),"Bridge"),mL=T(l.object({alias:l.string(),containerId:l.string(),project:l.string(),service:l.string(),port:l.number().int(),kind:Dr,state:ut.or(l.literal("absent")),networks:l.array(l.string())}).strict(),"Forwarder"),hQ=T(l.object({containerId:l.string(),project:l.string(),service:l.string(),image:l.string(),kind:Dr,tech:Qp,state:ut,health:us,ports:l.array(l.number().int()),defaultPort:l.number().int().nullable(),publishedPorts:l.array(td),privateNetworks:l.array(l.string()),bridge:rd.
1384
- nullable(),forwarder:mL.nullable(),integrated:l.boolean(),routing:CX.describe("How this protocol can be routed by hostname"),routed:l.boolean().describe("Whether the container opted into a TCP router"),gatewayAddress:l.string().nullable(),gatewayConnectionString:l.string().nullable()}).strict(),"TcpService"),gQ=T(l.object({provider:l.string(),url:l.string(),scope:ed,usable:l.boolean(),shareable:l.boolean(),problem:l.string().nullable(),connectionString:l.string()}).strict(),"ServiceEndpoint"),FTe=T(
1385
- l.object({project:l.string(),service:l.string(),kind:Dr,endpoints:l.array(gQ),credentials:l.object({discovered:l.boolean(),user:l.string().nullable(),password:l.string().nullable().describe("Present only on this route; never logged or stored"),database:l.string().nullable(),source:l.string().nullable(),reason:l.string().nullable()}).strict()}).strict(),"ServiceConnection"),BTe=T(l.object({services:l.array(hQ),bridges:l.array(rd),forwarders:l.array(mL),bridgeImageHint:l.string(),tcpRoutingEnabled:l.
1386
- boolean().describe("Whether TCP entrypoints are currently published")}).strict(),"AccessView"),bQ=l.object({project:l.string().nullable(),service:l.string().nullable(),containerId:l.string(),containerName:l.string(),state:ut,urls:l.array(Oa),port:l.string()}).strict(),UTe=T(l.object({gateway:pL,domains:l.object({local:l.string(),private:l.string().nullable(),public:l.string().nullable(),scheme:l.enum(["http","https"])}).strict(),routes:l.array(bQ),networks:l.array(fL),tailscale:l.object({enabled:l.
1387
- boolean(),running:l.boolean(),hostname:l.string(),state:ut.or(l.literal("absent")),health:us}).strict(),dns:l.object({provider:l.string(),cloudflareEnabled:l.boolean(),zone:l.string().nullable()}).strict(),tls:l.object({enabled:l.boolean(),mode:l.string(),acmeEmailSet:l.boolean(),caServer:l.string()}).strict()}).strict(),"NetworkView"),yQ=T(l.object({key:l.string(),value:l.string().nullable().describe("Never populated for a secret"),runtimeValue:l.string().nullable(),effectiveValue:l.string().nullable().
1380
+ int().describe("Shares that expired or whose target is gone")}).strict(),"OverviewCounts"),zTe=T(l.object({gateway:pL,counts:fQ,urls:l.array(Oa),problems:l.array(nd),generatedAt:ye}).strict(),"Overview"),fL=T(l.object({id:l.string(),name:l.string(),driver:l.string(),scope:l.string(),internal:l.boolean(),containerCount:l.number().int(),managed:l.boolean(),role:l.enum(["shared","control","access","project","other"])}).strict(),"NetworkSummary"),mQ=l.object({ip:l.string(),containerId:l.string(),containerName:l.
1381
+ string(),ownership:Xp,containerPort:l.number().int()}).strict(),hQ=T(l.object({hostPort:l.number().int(),protocol:l.string(),bindings:l.array(mQ),conflict:l.boolean()}).strict(),"PortUsage"),FTe=T(l.object({engine:l.object({version:l.string(),apiVersion:l.string(),os:l.string(),arch:l.string(),cpus:l.number().int(),memoryBytes:l.number(),name:l.string()}).strict(),containers:l.object({total:l.number().int(),running:l.number().int(),paused:l.number().int(),stopped:l.number().int()}).strict(),byOwnership:l.
1382
+ object({gateway:l.number().int(),integrated:l.number().int(),external:l.number().int(),standalone:l.number().int()}).strict(),networks:l.array(fL),ports:l.array(hQ)}).strict(),"DockerHost"),rd=T(l.object({id:l.string(),containerId:l.string(),project:l.string(),service:l.string(),targetPort:l.number().int(),localPort:l.number().int().nullable(),bindIp:l.string(),kind:Dr,network:l.string(),createdAt:ye.nullable(),expiresAt:ye.nullable(),state:ut.or(l.literal("absent")),connectionString:l.string()}).
1383
+ strict(),"Bridge"),mL=T(l.object({alias:l.string(),containerId:l.string(),project:l.string(),service:l.string(),port:l.number().int(),kind:Dr,state:ut.or(l.literal("absent")),networks:l.array(l.string())}).strict(),"Forwarder"),gQ=T(l.object({containerId:l.string(),project:l.string(),service:l.string(),image:l.string(),kind:Dr,tech:Qp,state:ut,health:us,ports:l.array(l.number().int()),defaultPort:l.number().int().nullable(),publishedPorts:l.array(td),privateNetworks:l.array(l.string()),bridge:rd.
1384
+ nullable(),forwarder:mL.nullable(),integrated:l.boolean(),routing:RX.describe("How this protocol can be routed by hostname"),routed:l.boolean().describe("Whether the container opted into a TCP router"),gatewayAddress:l.string().nullable(),gatewayConnectionString:l.string().nullable()}).strict(),"TcpService"),bQ=T(l.object({provider:l.string(),url:l.string(),scope:ed,usable:l.boolean(),shareable:l.boolean(),problem:l.string().nullable(),connectionString:l.string()}).strict(),"ServiceEndpoint"),BTe=T(
1385
+ l.object({project:l.string(),service:l.string(),kind:Dr,endpoints:l.array(bQ),credentials:l.object({discovered:l.boolean(),user:l.string().nullable(),password:l.string().nullable().describe("Present only on this route; never logged or stored"),database:l.string().nullable(),source:l.string().nullable(),reason:l.string().nullable()}).strict()}).strict(),"ServiceConnection"),UTe=T(l.object({services:l.array(gQ),bridges:l.array(rd),forwarders:l.array(mL),bridgeImageHint:l.string(),tcpRoutingEnabled:l.
1386
+ boolean().describe("Whether TCP entrypoints are currently published")}).strict(),"AccessView"),yQ=l.object({project:l.string().nullable(),service:l.string().nullable(),containerId:l.string(),containerName:l.string(),state:ut,urls:l.array(Oa),port:l.string()}).strict(),qTe=T(l.object({gateway:pL,domains:l.object({local:l.string(),private:l.string().nullable(),public:l.string().nullable(),scheme:l.enum(["http","https"])}).strict(),routes:l.array(yQ),networks:l.array(fL),tailscale:l.object({enabled:l.
1387
+ boolean(),running:l.boolean(),hostname:l.string(),state:ut.or(l.literal("absent")),health:us}).strict(),dns:l.object({provider:l.string(),cloudflareEnabled:l.boolean(),zone:l.string().nullable()}).strict(),tls:l.object({enabled:l.boolean(),mode:l.string(),acmeEmailSet:l.boolean(),caServer:l.string()}).strict()}).strict(),"NetworkView"),wQ=T(l.object({key:l.string(),value:l.string().nullable().describe("Never populated for a secret"),runtimeValue:l.string().nullable(),effectiveValue:l.string().nullable().
1388
1388
  describe("Value the form should display after applying precedence and defaults"),defaultValue:l.string().nullable().describe("Canonical default when the key is absent from .env"),valueSource:l.enum(["saved","default","detected","derived","environment"]).optional().describe("Where the displayed value comes from, when that is useful to say"),secret:l.boolean(),isSet:l.boolean(),pending:l.boolean().describe("Saved value differs from the running process"),kind:l.enum(["boolean","string","number","ch\
1389
- oice"]),choices:l.array(l.string()).optional(),group:l.string(),label:l.string(),help:l.string(),restartRequired:l.boolean()}).strict(),"ConfigField"),wQ=T(l.object({mode:l.enum(["local","auto","custom"]),domain:l.string().describe("The base every project hostname is built on"),publicIp:l.string().nullable(),provider:l.string(),examples:l.array(l.string()).describe("Hostnames a project would get"),problem:l.string().nullable().describe("Set when the mode could not be honoured"),reachable:l.boolean().
1390
- describe("Whether Traefik listens somewhere these names can actually reach it"),advice:l.string().nullable().describe("What to do about it, when something is off")}).strict(),"ProjectDomain"),vQ=T(l.object({hostname:l.string(),service:l.string()}).strict(),"TunnelRoute"),qTe=T(l.object({state:l.enum(["not-configured","configured","starting","connected","disconnected","auth-error","config-error"]).describe("What the connector is doing, distinguished so the fix is obvious"),detail:l.string(),hint:l.
1389
+ oice"]),choices:l.array(l.string()).optional(),group:l.string(),label:l.string(),help:l.string(),restartRequired:l.boolean()}).strict(),"ConfigField"),vQ=T(l.object({mode:l.enum(["local","auto","custom"]),domain:l.string().describe("The base every project hostname is built on"),publicIp:l.string().nullable(),provider:l.string(),examples:l.array(l.string()).describe("Hostnames a project would get"),problem:l.string().nullable().describe("Set when the mode could not be honoured"),reachable:l.boolean().
1390
+ describe("Whether Traefik listens somewhere these names can actually reach it"),advice:l.string().nullable().describe("What to do about it, when something is off")}).strict(),"ProjectDomain"),SQ=T(l.object({hostname:l.string(),service:l.string()}).strict(),"TunnelRoute"),HTe=T(l.object({state:l.enum(["not-configured","configured","starting","connected","disconnected","auth-error","config-error"]).describe("What the connector is doing, distinguished so the fix is obvious"),detail:l.string(),hint:l.
1391
1391
  string().nullable().describe("The single next step, when there is one"),enabled:l.boolean().describe("Whether the connector is part of the running stack"),zone:l.string().nullable().describe("The domain whose wildcard reaches this gateway"),wildcard:l.string().nullable(),tunnelId:l.string().nullable().describe("Not a secret: cfargotunnel only accepts records from the owning account"),credentialConfigured:l.boolean(),container:l.object({name:l.string(),state:l.string(),health:l.string()}),routes:l.
1392
- array(vQ).describe("What the connector serves, in match order"),endpointCount:l.number().describe("HTTP services this tunnel could publish"),dnsRecord:l.object({type:l.string(),name:l.string(),target:l.string(),proxied:l.boolean()}).nullable().describe("The one record the operator creates by hand, once"),imageAvailable:l.boolean().describe("Whether the connector image is already pulled")}).strict(),"TunnelView"),hL=T(l.object({fields:l.array(yQ),projectDomain:wQ,envFile:l.object({path:l.string(),
1393
- exists:l.boolean(),writable:l.boolean()}).strict(),pendingRestart:l.boolean(),applyCommand:l.string().describe("Host command that applies saved changes"),groups:l.array(l.string())}).strict(),"ConfigView"),HTe=T(l.object({ok:l.boolean(),saved:l.array(l.string()),pendingRestart:l.boolean(),applyCommand:l.string(),view:hL}).strict(),"ConfigPatchResult"),SQ=T(l.object({key:l.string(),label:l.string(),group:l.string(),from:l.string().nullable().describe("Running value; null for a secret"),to:l.string().
1394
- nullable().describe("Saved value; null for a secret"),secret:l.boolean(),fromSet:l.boolean().describe("Whether the running process had a value"),toSet:l.boolean().describe("Whether the saved file has a value"),restartRequired:l.boolean()}).strict(),"PendingChange"),ZTe=T(l.object({ok:l.boolean(),discarded:l.array(l.string()),pendingRestart:l.boolean(),applyCommand:l.string(),view:hL}).strict(),"ConfigDiscardResult"),xQ=T(l.enum(["unavailable","idle","running","ok","failed"]),"ApplyState"),kQ=T(l.
1395
- enum(["disabled","refused","not-prepared"]),"ApplyUnavailableReason"),GTe=T(l.object({state:xQ,available:l.boolean().describe("An applier container exists on this host"),reason:l.string().nullable().describe("Why the panel cannot apply, in one line"),unavailableReason:kQ.nullable(),buildsImages:l.boolean(),startedAt:ye.nullable(),finishedAt:ye.nullable(),exitCode:l.number().int().nullable(),pendingRestart:l.boolean(),pendingKeys:l.array(l.string()),pendingChanges:l.array(SQ),movesPanel:l.boolean(),
1396
- logTail:l.array(l.string()),profile:l.string(),applyCommand:l.string().describe("Host command that applies saved changes")}).strict(),"ApplyStatus"),_Q=T(l.enum(["unavailable","idle","running","ok","failed"]),"RunnerState"),PQ=T(l.enum(["disabled","refused","not-prepared"]),"RunnerUnavailableReason"),Aw=T(l.object({state:_Q,available:l.boolean().describe("A runner container exists on this host"),reason:l.string().nullable().describe("Why the panel cannot operate a project, in one line"),unavailableReason:PQ.
1397
- nullable(),startedAt:ye.nullable(),finishedAt:ye.nullable(),exitCode:l.number().int().nullable(),logTail:l.array(l.string()),prepareCommand:l.string().describe("Host command that prepares the runner")}).strict(),"RunnerStatus"),WTe=T(l.object({ok:l.boolean(),project:l.string(),noCache:l.boolean(),via:l.literal("runner"),runner:Aw}).strict(),"ProjectRebuildResult"),VTe=T(l.object({ok:l.boolean(),project:l.string(),action:l.literal("start"),via:l.literal("runner"),runner:Aw}).strict(),"Environment\
1398
- RunnerStartResult"),KTe=T(l.object({ok:l.boolean(),project:l.string(),mode:l.enum(["keep-data","and-local-data"]),volumes:l.boolean(),via:l.enum(["runner","iteration"]),removedContainers:l.array(l.string()),cleaned:iL,remainingCommands:l.array(l.string()),runner:Aw.nullable(),note:l.string().nullable()}).strict(),"ProjectRemoveResult"),JTe=T(l.object({ok:l.literal(!0),startedAt:ye,note:l.string(),applyCommand:l.string()}).strict(),"ApplyResult"),EQ=l.object({stream:l.enum(["stdout","stderr"]),timestamp:l.
1399
- string().nullable(),text:l.string()}).strict(),YTe=T(l.object({containerId:l.string(),name:l.string(),lines:l.array(EQ),truncated:l.boolean()}).strict(),"LogsResponse"),AQ=T(l.object({containerId:l.string(),service:l.string().describe("Compose service name, or the container name when unlabelled"),name:l.string().describe("Container name"),state:ut,lineCount:l.number().int(),truncated:l.boolean(),error:l.string().nullable().describe("Why this source contributed no lines")}).strict(),"ProjectLogSo\
1400
- urce"),OQ=T(l.object({stream:l.enum(["stdout","stderr"]),timestamp:l.string().nullable(),text:l.string(),service:l.string().describe("Which source produced this line")}).strict(),"ProjectLogLine"),XTe=T(l.object({project:l.string(),sources:l.array(AQ),lines:l.array(OQ).describe("Merged and ordered by timestamp where one exists"),truncated:l.boolean(),ordered:l.boolean().describe("False when a source logged without timestamps, so ordering is approximate")}).strict(),"ProjectLogsResponse"),QTe=T(l.
1401
- object({ok:l.boolean(),action:l.string(),containerId:l.string(),message:l.string()}).strict(),"ActionResult"),eCe=T(l.object({containerId:l.string(),name:l.string(),image:l.string(),ownership:Xp,state:ut,project:l.string().nullable(),mounts:l.array(sL),namedVolumes:l.array(l.string()),networks:l.array(l.string()),warnings:l.array(l.string()),allowed:l.boolean()}).strict(),"RemovalPreview"),$Q=T(l.enum(["container","network","bridge","health","project","config","hello"]),"LiveEventKind"),tCe=T(l.
1402
- object({kind:$Q,action:l.string(),id:l.string().nullable(),name:l.string().nullable(),project:l.string().nullable(),ownership:Xp.nullable(),at:ye}).strict(),"LiveEvent"),nCe=T(l.object({applied:l.array(l.string()).describe("Filenames this call applied"),migrations:l.array(l.string()).describe("Every migration the panel has applied")}).strict(),"DatabaseMigrateResult"),rCe=T(l.object({error:l.string(),detail:l.string().optional(),hint:l.string().optional()}).strict().describe("Uniform error envel\
1403
- ope returned by the panel API"),"ApiError");var ps=i((e,t)=>e.meta({ref:t}),"named"),gL=l.number().describe("Unix timestamp in seconds"),TQ=ps(l.object({level:l.enum(["normal","watch","pressured","critical"]),measured:l.boolean(),reasons:l.array(l.object({resource:l.enum(["cpu","memory","swap","storage","gpu","temperature","load","battery"]),level:l.enum(["watch","pressured","critical"]),value:l.number().describe("A ratio for anything measured 0-1, else the raw reading")}).strict())}).strict(),"HostPressure"),CQ=ps(l.object({kind:l.enum([
1404
- "service-unhealthy","environment-degraded","diagnostic","host-pressure"]),severity:l.enum(["warn","fail"]),summary:l.string(),project:l.string().nullable().describe("Project slug"),environment:l.string().nullable(),service:l.string().nullable(),href:l.string().describe("Where in the panel to act on it"),code:l.string().nullable().describe("The id of the diagnostic check behind a `diagnostic` item, so a page can say it in its own language")}).strict(),"AttentionItem"),RQ=ps(l.object({slug:l.string(),
1405
- name:l.string(),archived:l.boolean(),environmentCount:l.number().int(),runningEnvironments:l.number().int(),unhealthyServices:l.number().int(),health:l.enum(["ok","partial","unhealthy","idle"]),resources:l.object({cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().nullable()}).strict().nullable()}).strict(),"ProjectPulse"),cCe=ps(l.object({generatedAt:gL,attention:l.array(CQ),projects:l.array(RQ),runtime:l.object({environmentsRunning:l.number().int(),environmentsTotal:l.number().int(),
1406
- servicesRunning:l.number().int(),servicesUnhealthy:l.number().int(),routedUrls:l.number().int()}).strict(),resources:l.object({host:l.object({cpuUtilisation:l.number().nullable(),memoryUsedPercent:l.number().nullable(),storageUsedPercent:l.number().nullable(),stale:l.boolean(),collectorActive:l.boolean(),pressure:TQ}).strict().nullable(),topProjects:l.array(l.object({slug:l.string().nullable(),name:l.string(),environment:l.string(),cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().
1407
- nullable()}).strict())}).strict(),gateway:l.object({up:l.boolean(),problems:l.array(nd)}).strict()}).strict(),"DevelopmentOverview"),jQ=ps(l.object({environment:l.string(),project:l.string().nullable().describe("Project slug, when adopted"),cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().nullable(),containerCount:l.number().int(),containers:l.array(l.object({id:l.string(),name:l.string(),service:l.string().nullable(),cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().
1408
- nullable(),memoryLimitBytes:l.number().nullable()}).strict())}).strict(),"EnvironmentResources"),lCe=ps(l.object({project:l.string(),collectedAt:gL.nullable(),stale:l.boolean(),collectorActive:l.boolean(),cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().nullable(),hostMemoryTotalBytes:l.number().nullable(),environments:l.array(jQ)}).strict(),"ProjectResources");var ds=i((e,t)=>e.meta({ref:t}),"named"),yL=l.number().describe("Unix timestamp in seconds"),bL=ds(l.object({provider:l.string(),url:l.string().describe("An http(s) URL, or host:port for a datastore"),scope:ed,usable:l.boolean(),shareable:l.boolean(),problem:l.string().nullable()}).strict(),"ServiceAccessEndpoint"),IQ=ds(l.object({kind:l.enum(["http","tcp","none"]).describe("How this service is reached"),primary:bL.nullable().describe("The one address to open first"),endpoints:l.array(bL),bridge:rd.
1392
+ array(SQ).describe("What the connector serves, in match order"),endpointCount:l.number().describe("HTTP services this tunnel could publish"),dnsRecord:l.object({type:l.string(),name:l.string(),target:l.string(),proxied:l.boolean()}).nullable().describe("The one record the operator creates by hand, once"),imageAvailable:l.boolean().describe("Whether the connector image is already pulled")}).strict(),"TunnelView"),hL=T(l.object({fields:l.array(wQ),projectDomain:vQ,envFile:l.object({path:l.string(),
1393
+ exists:l.boolean(),writable:l.boolean()}).strict(),pendingRestart:l.boolean(),applyCommand:l.string().describe("Host command that applies saved changes"),groups:l.array(l.string())}).strict(),"ConfigView"),ZTe=T(l.object({ok:l.boolean(),saved:l.array(l.string()),pendingRestart:l.boolean(),applyCommand:l.string(),view:hL}).strict(),"ConfigPatchResult"),xQ=T(l.object({key:l.string(),label:l.string(),group:l.string(),from:l.string().nullable().describe("Running value; null for a secret"),to:l.string().
1394
+ nullable().describe("Saved value; null for a secret"),secret:l.boolean(),fromSet:l.boolean().describe("Whether the running process had a value"),toSet:l.boolean().describe("Whether the saved file has a value"),restartRequired:l.boolean()}).strict(),"PendingChange"),GTe=T(l.object({ok:l.boolean(),discarded:l.array(l.string()),pendingRestart:l.boolean(),applyCommand:l.string(),view:hL}).strict(),"ConfigDiscardResult"),kQ=T(l.enum(["unavailable","idle","running","ok","failed"]),"ApplyState"),_Q=T(l.
1395
+ enum(["disabled","refused","not-prepared"]),"ApplyUnavailableReason"),WTe=T(l.object({state:kQ,available:l.boolean().describe("An applier container exists on this host"),reason:l.string().nullable().describe("Why the panel cannot apply, in one line"),unavailableReason:_Q.nullable(),buildsImages:l.boolean(),startedAt:ye.nullable(),finishedAt:ye.nullable(),exitCode:l.number().int().nullable(),pendingRestart:l.boolean(),pendingKeys:l.array(l.string()),pendingChanges:l.array(xQ),movesPanel:l.boolean(),
1396
+ logTail:l.array(l.string()),profile:l.string(),applyCommand:l.string().describe("Host command that applies saved changes")}).strict(),"ApplyStatus"),PQ=T(l.enum(["unavailable","idle","running","ok","failed"]),"RunnerState"),EQ=T(l.enum(["disabled","refused","not-prepared"]),"RunnerUnavailableReason"),Aw=T(l.object({state:PQ,available:l.boolean().describe("A runner container exists on this host"),reason:l.string().nullable().describe("Why the panel cannot operate a project, in one line"),unavailableReason:EQ.
1397
+ nullable(),startedAt:ye.nullable(),finishedAt:ye.nullable(),exitCode:l.number().int().nullable(),logTail:l.array(l.string()),prepareCommand:l.string().describe("Host command that prepares the runner")}).strict(),"RunnerStatus"),VTe=T(l.object({ok:l.boolean(),project:l.string(),noCache:l.boolean(),via:l.literal("runner"),runner:Aw}).strict(),"ProjectRebuildResult"),KTe=T(l.object({ok:l.boolean(),project:l.string(),action:l.literal("start"),via:l.literal("runner"),runner:Aw}).strict(),"Environment\
1398
+ RunnerStartResult"),JTe=T(l.object({ok:l.boolean(),project:l.string(),mode:l.enum(["keep-data","and-local-data"]),volumes:l.boolean(),via:l.enum(["runner","iteration"]),removedContainers:l.array(l.string()),cleaned:iL,remainingCommands:l.array(l.string()),runner:Aw.nullable(),note:l.string().nullable()}).strict(),"ProjectRemoveResult"),YTe=T(l.object({ok:l.literal(!0),startedAt:ye,note:l.string(),applyCommand:l.string()}).strict(),"ApplyResult"),AQ=l.object({stream:l.enum(["stdout","stderr"]),timestamp:l.
1399
+ string().nullable(),text:l.string()}).strict(),XTe=T(l.object({containerId:l.string(),name:l.string(),lines:l.array(AQ),truncated:l.boolean()}).strict(),"LogsResponse"),OQ=T(l.object({containerId:l.string(),service:l.string().describe("Compose service name, or the container name when unlabelled"),name:l.string().describe("Container name"),state:ut,lineCount:l.number().int(),truncated:l.boolean(),error:l.string().nullable().describe("Why this source contributed no lines")}).strict(),"ProjectLogSo\
1400
+ urce"),$Q=T(l.object({stream:l.enum(["stdout","stderr"]),timestamp:l.string().nullable(),text:l.string(),service:l.string().describe("Which source produced this line")}).strict(),"ProjectLogLine"),QTe=T(l.object({project:l.string(),sources:l.array(OQ),lines:l.array($Q).describe("Merged and ordered by timestamp where one exists"),truncated:l.boolean(),ordered:l.boolean().describe("False when a source logged without timestamps, so ordering is approximate")}).strict(),"ProjectLogsResponse"),eCe=T(l.
1401
+ object({ok:l.boolean(),action:l.string(),containerId:l.string(),message:l.string()}).strict(),"ActionResult"),tCe=T(l.object({containerId:l.string(),name:l.string(),image:l.string(),ownership:Xp,state:ut,project:l.string().nullable(),mounts:l.array(sL),namedVolumes:l.array(l.string()),networks:l.array(l.string()),warnings:l.array(l.string()),allowed:l.boolean()}).strict(),"RemovalPreview"),TQ=T(l.enum(["container","network","bridge","health","project","config","hello"]),"LiveEventKind"),nCe=T(l.
1402
+ object({kind:TQ,action:l.string(),id:l.string().nullable(),name:l.string().nullable(),project:l.string().nullable(),ownership:Xp.nullable(),at:ye}).strict(),"LiveEvent"),rCe=T(l.object({applied:l.array(l.string()).describe("Filenames this call applied"),migrations:l.array(l.string()).describe("Every migration the panel has applied")}).strict(),"DatabaseMigrateResult"),oCe=T(l.object({error:l.string(),detail:l.string().optional(),hint:l.string().optional()}).strict().describe("Uniform error envel\
1403
+ ope returned by the panel API"),"ApiError");var ps=i((e,t)=>e.meta({ref:t}),"named"),gL=l.number().describe("Unix timestamp in seconds"),CQ=ps(l.object({level:l.enum(["normal","watch","pressured","critical"]),measured:l.boolean(),reasons:l.array(l.object({resource:l.enum(["cpu","memory","swap","storage","gpu","temperature","load","battery"]),level:l.enum(["watch","pressured","critical"]),value:l.number().describe("A ratio for anything measured 0-1, else the raw reading")}).strict())}).strict(),"HostPressure"),RQ=ps(l.object({kind:l.enum([
1404
+ "service-unhealthy","environment-degraded","diagnostic","host-pressure"]),severity:l.enum(["warn","fail"]),summary:l.string(),project:l.string().nullable().describe("Project slug"),environment:l.string().nullable(),service:l.string().nullable(),href:l.string().describe("Where in the panel to act on it"),code:l.string().nullable().describe("The id of the diagnostic check behind a `diagnostic` item, so a page can say it in its own language")}).strict(),"AttentionItem"),jQ=ps(l.object({slug:l.string(),
1405
+ name:l.string(),archived:l.boolean(),environmentCount:l.number().int(),runningEnvironments:l.number().int(),unhealthyServices:l.number().int(),health:l.enum(["ok","partial","unhealthy","idle"]),resources:l.object({cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().nullable()}).strict().nullable()}).strict(),"ProjectPulse"),lCe=ps(l.object({generatedAt:gL,attention:l.array(RQ),projects:l.array(jQ),runtime:l.object({environmentsRunning:l.number().int(),environmentsTotal:l.number().int(),
1406
+ servicesRunning:l.number().int(),servicesUnhealthy:l.number().int(),routedUrls:l.number().int()}).strict(),resources:l.object({host:l.object({cpuUtilisation:l.number().nullable(),memoryUsedPercent:l.number().nullable(),storageUsedPercent:l.number().nullable(),stale:l.boolean(),collectorActive:l.boolean(),pressure:CQ}).strict().nullable(),topProjects:l.array(l.object({slug:l.string().nullable(),name:l.string(),environment:l.string(),cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().
1407
+ nullable()}).strict())}).strict(),gateway:l.object({up:l.boolean(),problems:l.array(nd)}).strict()}).strict(),"DevelopmentOverview"),IQ=ps(l.object({environment:l.string(),project:l.string().nullable().describe("Project slug, when adopted"),cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().nullable(),containerCount:l.number().int(),containers:l.array(l.object({id:l.string(),name:l.string(),service:l.string().nullable(),cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().
1408
+ nullable(),memoryLimitBytes:l.number().nullable()}).strict())}).strict(),"EnvironmentResources"),uCe=ps(l.object({project:l.string(),collectedAt:gL.nullable(),stale:l.boolean(),collectorActive:l.boolean(),cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().nullable(),hostMemoryTotalBytes:l.number().nullable(),environments:l.array(IQ)}).strict(),"ProjectResources");var ds=i((e,t)=>e.meta({ref:t}),"named"),yL=l.number().describe("Unix timestamp in seconds"),bL=ds(l.object({provider:l.string(),url:l.string().describe("An http(s) URL, or host:port for a datastore"),scope:ed,usable:l.boolean(),shareable:l.boolean(),problem:l.string().nullable()}).strict(),"ServiceAccessEndpoint"),DQ=ds(l.object({kind:l.enum(["http","tcp","none"]).describe("How this service is reached"),primary:bL.nullable().describe("The one address to open first"),endpoints:l.array(bL),bridge:rd.
1409
1409
  nullable().describe("An open loopback bridge, for a datastore"),routed:l.boolean().describe("Whether the service opted into the gateway"),problem:l.string().nullable().describe("Why it cannot be reached, when it cannot")}).strict(),"ServiceAccess"),wL=ds(l.object({cpuUtilisation:l.number().nullable(),memoryUsedBytes:l.number().nullable(),memoryLimitBytes:l.number().nullable(),diskBytes:l.number().nullable().describe("Null: the collector has no per-container disk yet"),collectedAt:yL.nullable(),stale:l.
1410
- boolean()}).strict(),"ServiceResources"),DQ=ds(l.object({start:l.boolean(),stop:l.boolean(),restart:l.boolean(),logs:l.boolean(),openAccess:l.boolean().describe("A loopback bridge can be opened"),share:l.boolean().describe("A temporary hostname can be created")}).strict(),"ServiceActions"),NQ=ds(l.object({name:l.string().describe("Compose service name"),environment:l.string().describe("COMPOSE_PROJECT_NAME"),containerId:l.string(),containerName:l.string(),image:l.string(),kind:Dr,tech:Qp,state:ut,
1411
- health:us,startedAt:yL.nullable(),uptimeSeconds:l.number().nullable(),restartCount:l.number().int(),exitCode:l.number().int().nullable(),completed:l.boolean().optional().describe("Exited 0 with no restart policy: a one-shot that did its job"),ports:l.array(td),exposedPorts:l.array(l.number().int()),networks:l.array(l.string()),onGatewayNetwork:l.boolean(),access:IQ,resources:wL.nullable(),actions:DQ,overrides:Pw.optional(),hidden:l.boolean().describe("Collapsed by an environment override")}).strict(),
1412
- "Service"),mCe=ds(l.object({environment:l.string(),services:l.array(NQ),resources:wL.nullable().describe("The environment as a whole")}).strict(),"EnvironmentServices");function qQ(e){return async(t,n)=>{let r=(t==="list"?Yp:t==="search"?kw:_w).parse(n),o=new URLSearchParams(Object.entries(r).filter(([,c])=>c!==void 0).map(([c,u])=>[c,String(u)])),a=await e(`${t==="list"?"/documentation":t==="search"?"/documentation/search":"/documentation/page"}?${o}`);return(t==="list"?Sw:t==="search"?xw:Jp).parse(a)}}i(qQ,"remoteDocumentationReader");var od="documentation.json.gz";function HQ(){let e=zQ(import.meta.dirname,od),t=LQ(e),n=t?BQ(e):new URL("../../../../docs/.gen\
1413
- erated/corpus.json",import.meta.url);try{let r=MQ(n),o=JSON.parse(t?UQ(r).toString("utf8"):r.toString("utf8"));if(o.schemaVersion!==1)throw new Error("unsupported corpus version");return o}catch{throw new L(`documentation is unavailable at ${FQ(n)}`,"reinstall this CLI or run npm run docs:generate in the checkout")}}i(HQ,"loadLocalDocumentation");function ZQ(e=HQ){return async(t,n)=>{let r=e();if(t==="list"){let a=Yp.parse(n);return $S(r,a.audience)}if(t==="search"){let a=kw.parse(n);return{identity:r.
1414
- identity,results:AS(r.pages,a.q,a)}}let o=_w.parse(n),s=OS(r,o.slug,o.anchor);if(!s)throw new _e("no such document or heading");return Jp.parse({identity:r.identity,page:s})}}i(ZQ,"localDocumentationReader");async function sd(e,t,n){let r=n.optsWithGlobals(),o=new A(r),s=r.url?qQ(c=>de(n).client.request("GET",c)):ZQ(),a=e==="show"?{slug:t,...r.anchor?{anchor:r.anchor}:{}}:{...r.audience?{audience:r.audience}:{},...e==="search"?{q:t,...r.limit?{limit:r.limit}:{}}:{}};try{let c=await s(e,a),u=r.url?
1410
+ boolean()}).strict(),"ServiceResources"),NQ=ds(l.object({start:l.boolean(),stop:l.boolean(),restart:l.boolean(),logs:l.boolean(),openAccess:l.boolean().describe("A loopback bridge can be opened"),share:l.boolean().describe("A temporary hostname can be created")}).strict(),"ServiceActions"),LQ=ds(l.object({name:l.string().describe("Compose service name"),environment:l.string().describe("COMPOSE_PROJECT_NAME"),containerId:l.string(),containerName:l.string(),image:l.string(),kind:Dr,tech:Qp,state:ut,
1411
+ health:us,startedAt:yL.nullable(),uptimeSeconds:l.number().nullable(),restartCount:l.number().int(),exitCode:l.number().int().nullable(),completed:l.boolean().optional().describe("Exited 0 with no restart policy: a one-shot that did its job"),ports:l.array(td),exposedPorts:l.array(l.number().int()),networks:l.array(l.string()),onGatewayNetwork:l.boolean(),access:DQ,resources:wL.nullable(),actions:NQ,overrides:Pw.optional(),hidden:l.boolean().describe("Collapsed by an environment override")}).strict(),
1412
+ "Service"),hCe=ds(l.object({environment:l.string(),services:l.array(LQ),resources:wL.nullable().describe("The environment as a whole")}).strict(),"EnvironmentServices");function HQ(e){return async(t,n)=>{let r=(t==="list"?Yp:t==="search"?kw:_w).parse(n),o=new URLSearchParams(Object.entries(r).filter(([,c])=>c!==void 0).map(([c,u])=>[c,String(u)])),a=await e(`${t==="list"?"/documentation":t==="search"?"/documentation/search":"/documentation/page"}?${o}`);return(t==="list"?Sw:t==="search"?xw:Jp).parse(a)}}i(HQ,"remoteDocumentationReader");var od="documentation.json.gz";function ZQ(){let e=FQ(import.meta.dirname,od),t=MQ(e),n=t?UQ(e):new URL("../../../../docs/.gen\
1413
+ erated/corpus.json",import.meta.url);try{let r=zQ(n),o=JSON.parse(t?qQ(r).toString("utf8"):r.toString("utf8"));if(o.schemaVersion!==1)throw new Error("unsupported corpus version");return o}catch{throw new L(`documentation is unavailable at ${BQ(n)}`,"reinstall this CLI or run npm run docs:generate in the checkout")}}i(ZQ,"loadLocalDocumentation");function GQ(e=ZQ){return async(t,n)=>{let r=e();if(t==="list"){let a=Yp.parse(n);return $S(r,a.audience)}if(t==="search"){let a=kw.parse(n);return{identity:r.
1414
+ identity,results:AS(r.pages,a.q,a)}}let o=_w.parse(n),s=OS(r,o.slug,o.anchor);if(!s)throw new _e("no such document or heading");return Jp.parse({identity:r.identity,page:s})}}i(GQ,"localDocumentationReader");async function sd(e,t,n){let r=n.optsWithGlobals(),o=new A(r),s=r.url?HQ(c=>de(n).client.request("GET",c)):GQ(),a=e==="show"?{slug:t,...r.anchor?{anchor:r.anchor}:{}}:{...r.audience?{audience:r.audience}:{},...e==="search"?{q:t,...r.limit?{limit:r.limit}:{}}:{}};try{let c=await s(e,a),u=r.url?
1415
1415
  "panel":"local";if(o.json){o.data({origin:u,...c});return}let p=c.identity;if(o.line(`Portta ${p.version} documentation (${u}, ${p.hash.slice(0,12)})`),e==="show"){let{page:d}=Jp.parse(c);o.line(`${d.url}
1416
1416
 
1417
1417
  ${d.markdown}`)}else if(e==="list")for(let d of Sw.parse(c).pages)o.line(`${d.slug} ${d.title} [${d.audience} / ${d.section}]`);else{let{results:d}=xw.parse(c);d.length||o.line("No matching documentation.");for(let f of d)o.line(`${f.url} ${f.title}
1418
- ${f.excerpt}`)}}catch(c){throw c instanceof l.ZodError?new C(c.issues.map(u=>u.message).join("; ")):c}}i(sd,"docsCommand");import{chmodSync as yee,existsSync as Mr,mkdirSync as wee,readdirSync as vee,readFileSync as zL,rmSync as FL}from"node:fs";import{join as yt}from"node:path";import{existsSync as id,readdirSync as GQ,statSync as vL}from"node:fs";import{join as $a}from"node:path";var WQ=["packages/cli/src","packages/cli/scripts","packages/cli/package.json","packages/core/src","packages/contracts/src"];function SL(e){return $a(e,"packages/cli/dist/cli.js")}i(SL,"checkoutCliDist");function VQ(e){return id($a(e,"packages/cli/src/cli.ts"))&&id($a(e,"package.json"))}i(VQ,"isCheckout");function xL(e){if(!id(e))return 0;let t=vL(e);if(t.isFile())return/\.(ts|mjs|json)$/.test(e)?t.mtimeMs:0;let n=0;for(let r of GQ(e,{withFileTypes:!0}))n=Math.max(n,xL($a(e,r.name)));return n}i(xL,
1419
- "newestSourceMtime");function KQ(e){if(!VQ(e))return!1;let t=SL(e);if(!id(t))return!0;let n=vL(t).mtimeMs;return WQ.some(r=>xL($a(e,r))>n)}i(KQ,"checkoutCliNeedsBuild");async function kL(e,t){return KQ(e)?(t.progress("building the TypeScript CLI"),await _("npm",["run","build","--workspace=@codions/portta"],{cwd:e,stdio:"inherit"}),!0):!1}i(kL,"ensureCheckoutCli");async function _L(e){let t=await _(process.execPath,[SL(e),...process.argv.slice(2)],{cwd:e,stdio:"inherit",reject:!1});process.exit(t.
1420
- exitCode)}i(_L,"reexecBuiltCli");import{existsSync as Nr,readdirSync as JQ,readFileSync as YQ}from"node:fs";import{join as Sn}from"node:path";var XQ=2;function Ow(e){return e.ports.filter(t=>t.publicPort!==null).map(t=>`${t.ip}:${t.publicPort}`).join(" ")}i(Ow,"publishedBindings");function QQ(e){return e.ports.filter(t=>t.publicPort!==null).map(t=>`${t.privatePort}/${t.type}=${t.ip}:${t.publicPort}`).join(" ")}i(QQ,"bindMap");function eee(e){return e.ports.filter(t=>t.publicPort!==null).map(t=>`${t.ip}:${t.publicPort}->${t.privatePort}/${t.type}`).join(" ")}i(eee,"publishedWithTargets");function fs(e,t){return e.find(n=>n.labels["port\
1421
- ta.managed"]==="true"&&n.labels["portta.component"]===t)}i(fs,"gatewayContainer");async function PL(e){let t=await _("docker",["network","inspect",e,"--format",'{{ .Internal }} {{ index .Labels "portta.managed" }} {{ len .Containers }}'],{reject:!1});if(t.failed)return{exists:!1,internal:!1,managed:!1,endpoints:0};let[n="",r="",o="0"]=t.stdout.trim().split(" ");return{exists:!0,internal:n==="true",managed:r==="true",endpoints:Number(o)||0}}i(PL,"networkFacts");async function $w(e,t){let n=await _(
1418
+ ${f.excerpt}`)}}catch(c){throw c instanceof l.ZodError?new C(c.issues.map(u=>u.message).join("; ")):c}}i(sd,"docsCommand");import{chmodSync as wee,existsSync as Mr,mkdirSync as vee,readdirSync as See,readFileSync as zL,rmSync as FL}from"node:fs";import{join as yt}from"node:path";import{existsSync as id,readdirSync as WQ,statSync as vL}from"node:fs";import{join as $a}from"node:path";var VQ=["packages/cli/src","packages/cli/scripts","packages/cli/package.json","packages/core/src","packages/contracts/src"];function SL(e){return $a(e,"packages/cli/dist/cli.js")}i(SL,"checkoutCliDist");function KQ(e){return id($a(e,"packages/cli/src/cli.ts"))&&id($a(e,"package.json"))}i(KQ,"isCheckout");function xL(e){if(!id(e))return 0;let t=vL(e);if(t.isFile())return/\.(ts|mjs|json)$/.test(e)?t.mtimeMs:0;let n=0;for(let r of WQ(e,{withFileTypes:!0}))n=Math.max(n,xL($a(e,r.name)));return n}i(xL,
1419
+ "newestSourceMtime");function JQ(e){if(!KQ(e))return!1;let t=SL(e);if(!id(t))return!0;let n=vL(t).mtimeMs;return VQ.some(r=>xL($a(e,r))>n)}i(JQ,"checkoutCliNeedsBuild");async function kL(e,t){return JQ(e)?(t.progress("building the TypeScript CLI"),await _("npm",["run","build","--workspace=@codions/portta"],{cwd:e,stdio:"inherit"}),!0):!1}i(kL,"ensureCheckoutCli");async function _L(e){let t=await _(process.execPath,[SL(e),...process.argv.slice(2)],{cwd:e,stdio:"inherit",reject:!1});process.exit(t.
1420
+ exitCode)}i(_L,"reexecBuiltCli");import{existsSync as Nr,readdirSync as YQ,readFileSync as XQ}from"node:fs";import{join as Sn}from"node:path";var QQ=2;function Ow(e){return e.ports.filter(t=>t.publicPort!==null).map(t=>`${t.ip}:${t.publicPort}`).join(" ")}i(Ow,"publishedBindings");function eee(e){return e.ports.filter(t=>t.publicPort!==null).map(t=>`${t.privatePort}/${t.type}=${t.ip}:${t.publicPort}`).join(" ")}i(eee,"bindMap");function tee(e){return e.ports.filter(t=>t.publicPort!==null).map(t=>`${t.ip}:${t.publicPort}->${t.privatePort}/${t.type}`).join(" ")}i(tee,"publishedWithTargets");function fs(e,t){return e.find(n=>n.labels["po\
1421
+ rtta.managed"]==="true"&&n.labels["portta.component"]===t)}i(fs,"gatewayContainer");async function PL(e){let t=await _("docker",["network","inspect",e,"--format",'{{ .Internal }} {{ index .Labels "portta.managed" }} {{ len .Containers }}'],{reject:!1});if(t.failed)return{exists:!1,internal:!1,managed:!1,endpoints:0};let[n="",r="",o="0"]=t.stdout.trim().split(" ");return{exists:!0,internal:n==="true",managed:r==="true",endpoints:Number(o)||0}}i(PL,"networkFacts");async function $w(e,t){let n=await _(
1422
1422
  e,t,{reject:!1});return n.failed?null:n.stdout.trim().split(`
1423
1423
  `)[0]??null}i($w,"version");async function AL(e){let t=[],n=e.env,r=e.config,o=e.root,s=n.PORTTA_STATE_DIR||Sn(o,"state"),a=i((...I)=>{for(let X of I)X&&t.push(X)},"add");a(v("gateway.version","pass","gateway version",e.version)),a(Qd(n.PORTTA_PROFILE??r.profile)?v("config.profile","pass","profile",r.profile):v("config.profile","fail","profile",`unknown profile '${n.PORTTA_PROFILE}'`,"set PORTTA_PROFILE to one of: local remote-private remote-public"));let c=Sn(o,".env");Nr(c)?(a(v("config.env","\
1424
1424
  pass",".env","present")),a(Kv(Yn(c)))):a(v("config.env","warn",".env","absent; running on built-in defaults","cp .env.example .env"));let u=WI();u.length>0&&a(v("agents.layer","warn","AI agents",`installed without the Portta layer: ${u.join(", ")}`,"portta agents install (dry run first: portta agents install --dry-run)"));let p=await Zy(),d=p.find(I=>I.id==="runtime.docker");a(d??v("runtime.docker","fail","Docker","diagnostic unavailable"));let f=await fa("docker"),m=!1;f&&(m=!(await _("docker",
1425
- ["info"],{reject:!1})).failed,m&&a(v("runtime.context","pass","docker context",await $w("docker",["context","show"])??"unknown")));let h=await $w("docker",["compose","version","--short"]);if(a(h===null?v("runtime.compose","fail","docker compose","plugin missing","install the Docker Compose v2 plugin"):Rs(h,XQ)?v("runtime.compose","pass","docker compose",h):v("runtime.compose","fail","docker compose",`v${h} is too old`,"install the Compose v2 plugin")),!m)return a(...p.filter(I=>I.id!=="runtime.d\
1425
+ ["info"],{reject:!1})).failed,m&&a(v("runtime.context","pass","docker context",await $w("docker",["context","show"])??"unknown")));let h=await $w("docker",["compose","version","--short"]);if(a(h===null?v("runtime.compose","fail","docker compose","plugin missing","install the Docker Compose v2 plugin"):Rs(h,QQ)?v("runtime.compose","pass","docker compose",h):v("runtime.compose","fail","docker compose",`v${h} is too old`,"install the Compose v2 plugin")),!m)return a(...p.filter(I=>I.id!=="runtime.d\
1426
1426
  ocker")),t;let b=await _("docker",["compose",...we(e),"config","--quiet"],{cwd:o,env:n,reject:!1});a(b.failed?v("config.compose","fail","compose configuration",`the ${r.profile} profile does not render`,"portta inspect shows the file list; the error is above"):v("config.compose","pass","compose configuration",`renders for the ${r.profile} profile`));let g=await J(),y=g.filter(I=>I.state==="running"),w=await PL(r.network);w.exists?(a(v("network.shared","pass","shared network",`${r.network} (${w.
1427
1427
  endpoints} attached)`)),a(w.managed?v("network.shared.owned","pass","shared network ownership","created by the gateway"):v("network.shared.owned","warn","shared network ownership",`'${r.network}' has no portta.managed label`,"harmless: the gateway will never remove a network it does not own"))):a(v("network.shared","fail","shared network",`'${r.network}' does not exist`,"portta bootstrap"));let P=n.PORTTA_CONTROL_NETWORK||`${r.network}-control`,R=await PL(P);a(R.exists?R.internal?v("network.cont\
1428
1428
  rol","pass","control network",`${P} (internal)`):v("network.control","fail","control network",`${P} is not marked internal`,"the Docker socket proxy must sit on an internal network; recreate the gateway"):v("network.control","warn","control network","not created yet",`portta up ${r.profile}`));let O=fs(g,"traefik");O?(a(O.state==="running"&&O.health==="healthy"?v("traefik.state","pass","traefik","running and healthy"):O.state==="running"?v("traefik.state","warn","traefik",`running, health=${O.health??
1429
1429
  "none"}`,"portta logs traefik"):v("traefik.state","fail","traefik",`state=${O.state}`,`portta up ${r.profile}`)),a(Jv(O.image)),a((O.mounts??[]).some(I=>I.source.includes("docker.sock"))?v("traefik.socket","fail","docker socket","the Docker socket is mounted into Traefik","remove the bind mount; Traefik must use the socket proxy on the control network"):v("traefik.socket","pass","docker socket","not mounted into Traefik"))):a(v("traefik.state","warn","traefik","container not created",`portta up ${r.
1430
1430
  profile}`));let x=fs(g,"socket-proxy");if(!x)a(v("proxy.state","warn","docker socket proxy","container not created",`portta up ${r.profile}`));else{a(x.state==="running"?v("proxy.state","pass","docker socket proxy","running"):v("proxy.state","fail","docker socket proxy",`state=${x.state}`,`portta up ${r.profile}`));let I=Ow(x);a(I?v("proxy.exposure","fail","docker socket proxy exposure",`publishes host ports: ${I}`,"the Docker API must never be reachable from the host or the network"):v("proxy.e\
1431
1431
  xposure","pass","docker socket proxy exposure","no host ports published"));let X=(x.mounts??[]).find(le=>le.source.includes("docker.sock"));a(X?X.readWrite?v("proxy.socket","fail","docker socket mount","mounted read-write","mount /var/run/docker.sock read-only (:ro)"):v("proxy.socket","pass","docker socket mount","read-only"):v("proxy.socket","warn","docker socket mount","could not determine mount mode"))}if(r.webEnabled){let I=Mt(o);a(Nr(I)?v("db.file","pass","panel database",I):v("db.file","wa\
1432
- rn","panel database",`${I} not created yet; the panel creates it on first boot`,"portta web up"))}let $=(n.PORTTA_WEB_EXPOSE||"local")==="public";if(O&&O.state==="running"){let I=QQ(O);a(v("exposure.binds","pass","published ports",I||"none")),a(eS(r.profile,I,$))}for(let I of y.filter(X=>X.labels["portta.managed"]==="true")){let X=eee(I);Qv(X)&&a(v("exposure.sensitive","fail","sensitive port exposure",`${I.name} publishes a database or Docker API port on all interfaces: ${X}`,"bind it to 127.0.0\
1433
- .1 or remove the published port"))}let z=r.profile!=="local"&&r.tailscaleEnabled?"tailscale":"host";if(a(v("config.attachment","pass","traefik attachment",z)),z==="tailscale"){let I=fs(g,"tailscale");if(!I)a(v("tailscale.state","warn","tailscale","container not created",`portta up ${r.profile}`));else{if(I.state==="running"&&I.health==="healthy"){let le=await _("docker",["exec",I.id,"tailscale","ip","-4"],{reject:!1}),tn=le.failed?"":le.stdout.trim().split(`
1432
+ rn","panel database",`${I} not created yet; the panel creates it on first boot`,"portta web up"))}let $=(n.PORTTA_WEB_EXPOSE||"local")==="public";if(O&&O.state==="running"){let I=eee(O);a(v("exposure.binds","pass","published ports",I||"none")),a(eS(r.profile,I,$))}for(let I of y.filter(X=>X.labels["portta.managed"]==="true")){let X=tee(I);Qv(X)&&a(v("exposure.sensitive","fail","sensitive port exposure",`${I.name} publishes a database or Docker API port on all interfaces: ${X}`,"bind it to 127.0.\
1433
+ 0.1 or remove the published port"))}let z=r.profile!=="local"&&r.tailscaleEnabled?"tailscale":"host";if(a(v("config.attachment","pass","traefik attachment",z)),z==="tailscale"){let I=fs(g,"tailscale");if(!I)a(v("tailscale.state","warn","tailscale","container not created",`portta up ${r.profile}`));else{if(I.state==="running"&&I.health==="healthy"){let le=await _("docker",["exec",I.id,"tailscale","ip","-4"],{reject:!1}),tn=le.failed?"":le.stdout.trim().split(`
1434
1434
  `)[0]??"";a(tn?v("tailscale.state","pass","tailscale",`connected as ${tn}`):v("tailscale.state","fail","tailscale","running but has no tailnet address","check TS_AUTHKEY and the tailnet's device approval settings"))}else a(v("tailscale.state","fail","tailscale",`state=${I.state} health=${I.health??""}`,"portta logs tailscale"));O&&a(O.networkMode?.startsWith("container:")?v("tailscale.netns","pass","traefik network namespace","shared with tailscale"):v("tailscale.netns","fail","traefik network n\
1435
1435
  amespace",`traefik is not in the tailscale namespace (${O.networkMode??"unknown"})`,`portta up ${r.profile}`)),a(Nr(Sn(s,"tailscale"))?v("tailscale.state.dir","pass","tailscale state","persisted under state/tailscale"):v("tailscale.state.dir","warn","tailscale state","state directory missing","portta bootstrap"))}let X=!!n.TS_AUTHKEY;a(!X&&!Nr(Sn(s,"tailscale/tailscaled.state"))?v("tailscale.authkey","fail","tailscale auth","no TS_AUTHKEY and no persisted state","set TS_AUTHKEY in .env; prefer a\
1436
1436
  n ephemeral, tagged, pre-authorized key"):v("tailscale.authkey","pass","tailscale auth",X?"auth key set":"using persisted state"))}a(tS(r.dashboardEnabled,n.PORTTA_DASHBOARD_BIND_ADDRESS||"127.0.0.1",n.PORTTA_DASHBOARD_PORT||"8080"));let D=n.PORTTA_WEB_BIND_ADDRESS||"127.0.0.1",V=n.PORTTA_WEB_PORT||"8081";r.webEnabled&&a(...nS({expose:n.PORTTA_WEB_EXPOSE||"local",bindAddress:D,port:V,authMode:n.PORTTA_AUTH_MODE||"disabled",secretPresent:!!n.PORTTA_AUTH_SECRET,readOnly:re(n.PORTTA_WEB_READ_ONLY),
1437
1437
  allowLan:re(n.PORTTA_AUTH_ALLOW_LAN)})),a(n.PORTTA_AUTH_SECRET?v("auth.secret","pass","authentication signing secret","set"):v("auth.secret","fail","authentication signing secret","PORTTA_AUTH_SECRET is unset","portta bootstrap (generates it without printing it)"));let M=fs(g,"auth"),K=Sn(o,"state/auth/protections.json");if(a(oS(Nr(K),Yn(K),!!M)),a(rS("auth.service","authentication service",!!M,M?.state??null,M?.health??null,"portta logs portta-auth")),r.profile==="remote-public"){M?.state!=="\
1438
1438
  running"&&a(v("public.auth","fail","public host","portta-auth is not running, so every routed hostname is closed","portta up then portta logs portta-auth"));let I=On(g);I.length>0&&a(v("public.gate","fail","public host",`routed with no login gate, so open to the internet: ${I.join(", ")}`,"portta runtime down <path>, then portta adopt <path> and portta runtime up <path> to plan it behind the gate")),re(n.PORTTA_RUNNER_PUBLIC)&&a(v("public.runner","warn","public host","PORTTA_RUNNER_PUBLIC is o\
1439
- n: a signed-in panel session can start, stop and remove projects","remove PORTTA_RUNNER_PUBLIC from .env to operate projects on the host only"));let X=nee(o);X.length>0&&a(v("public.exposure","warn","public host",`routed with no decision, so closed: ${X.join(", ")}`,"portta adopt <path> --protect <service> or --public <service>, or portta protect host|open <host>"))}if(r.tcpEnabled){a(r.profile==="remote-public"?v("tcp.profile","fail","tcp entrypoints","enabled on the remote-public profile, wh\
1439
+ n: a signed-in panel session can start, stop and remove projects","remove PORTTA_RUNNER_PUBLIC from .env to operate projects on the host only"));let X=ree(o);X.length>0&&a(v("public.exposure","warn","public host",`routed with no decision, so closed: ${X.join(", ")}`,"portta adopt <path> --protect <service> or --public <service>, or portta protect host|open <host>"))}if(r.tcpEnabled){a(r.profile==="remote-public"?v("tcp.profile","fail","tcp entrypoints","enabled on the remote-public profile, wh\
1440
1440
  ere Traefik binds every interface","set PORTTA_TCP=false; reach databases over the VPN or a loopback bridge"):v("tcp.profile","pass","tcp entrypoints",`postgres :${n.PORTTA_TCP_POSTGRES_PORT||5432}, redis :${n.PORTTA_TCP_REDIS_PORT||6379} on ${r.bindAddress}`)),a(r.tlsEnabled?v("tcp.tls","pass","tcp tls",`certificates configured (${r.tlsMode})`):v("tcp.tls","warn","tcp tls","no certificate configured; Traefik will serve a self-signed one","sslmode=require works; for verify-full run: portta tls i\
1441
1441
  nit"));let I=y.filter(le=>Object.keys(le.labels).some(tn=>tn.startsWith("traefik.tcp.routers."))),X=I.filter(le=>le.networks.includes(r.network)).map(le=>le.name);a(X.length>0?v("tcp.network","fail","routed datastores",`on the shared HTTP network: ${X.join(" ")}`,`attach them to ${n.PORTTA_ACCESS_NETWORK||`${r.network}-access`} instead; see docs/product/guides/tcp-routing.md`):v("tcp.network","pass","routed datastores",`${I.length} routed, none on the shared network`))}else a(v("tcp.profile","pa\
1442
1442
  ss","tcp entrypoints","disabled"));if(r.webEnabled){let I=fs(g,"web");if($){let le=I?Ow(I):"";a(le?v("web.bind","fail","web panel",`published directly on the host at ${le}, bypassing the authenticating entrypoint`,"remove the ports: entry; docker/compose/features/panel-public.yaml owns this port"):v("web.bind","pass","web panel",`reached only through Traefik's authenticated panel entrypoint on ${D}:${V}`))}else sr(D)?a(v("web.bind","pass","web panel",`enabled on ${D}:${V} (loopback)`)):Jr(D)?a(v(
1443
1443
  "web.bind","fail","web panel",`enabled and bound to ${D} with nothing authenticating it`,"portta config set panel.access public (or set PORTTA_WEB_BIND_ADDRESS=127.0.0.1)")):a(v("web.bind","pass","web panel",`enabled on ${D}:${V} (access: ${n.PORTTA_WEB_EXPOSE||"local"})`));if(n.PORTTA_WEB_EXPOSE==="vpn"&&r.profile==="remote-public"&&a(v("web.expose","fail","web panel routing","routed on the tailnet hostname while Traefik answers the internet","portta web up --expose domain, or set PORTTA_WEB_\
1444
1444
  EXPOSE=local")),n.PORTTA_WEB_EXPOSE==="domain"){let le=n.PORTTA_PANEL_ADVERTISED_HOST??"";a(r.tlsEnabled?v("web.expose","pass","web panel routing",`routed on ${le} over HTTPS`):v("web.expose","fail","web panel routing","routed on the domain with TLS off, so the credential crosses in clear text","portta config set tls.enabled true"))}a(I?I.state==="running"?v("web.state","pass","web panel container",`${I.state} (${I.health??"none"})`):v("web.state","warn","web panel container",I.state,"portta web\
1445
1445
  up"):v("web.state","warn","web panel container","not running","portta web up"));let X=fs(g,"web-socket-proxy");if(X){let le=Ow(X);a(le?v("web.proxy","fail","web panel socket proxy",`published on the host: ${le}`,"it must be reachable only from the panel; do not add a ports: entry to docker/compose/features/web.yaml"):v("web.proxy","pass","web panel socket proxy","unpublished, reachable only from the panel"))}}else a(v("web.bind","pass","web panel","disabled"));if(a(v("domain.mode","pass","proje\
1446
- ct domain mode",`${r.domainMode} (*.${r.domain})`)),r.domainProblem&&a(v("domain.resolved","fail","project domain",r.domainProblem,"portta config set domain.mode auto")),a(...await tee(r,n)),r.tlsEnabled)if(r.tlsMode==="acme"){let I=r.acmeChallenge==="http";a(n.ACME_EMAIL?v("tls.acme","pass","ACME configuration",I?`${n.ACME_EMAIL} over HTTP-01`:`${n.ACME_EMAIL} via ${n.ACME_DNS_PROVIDER??""}`):v("tls.acme","fail","ACME configuration","ACME_EMAIL is not set","set ACME_EMAIL in .env")),I?(a(v("tls\
1446
+ ct domain mode",`${r.domainMode} (*.${r.domain})`)),r.domainProblem&&a(v("domain.resolved","fail","project domain",r.domainProblem,"portta config set domain.mode auto")),a(...await nee(r,n)),r.tlsEnabled)if(r.tlsMode==="acme"){let I=r.acmeChallenge==="http";a(n.ACME_EMAIL?v("tls.acme","pass","ACME configuration",I?`${n.ACME_EMAIL} over HTTP-01`:`${n.ACME_EMAIL} via ${n.ACME_DNS_PROVIDER??""}`):v("tls.acme","fail","ACME configuration","ACME_EMAIL is not set","set ACME_EMAIL in .env")),I?(a(v("tls\
1447
1447
  .acme.challenge","pass","ACME challenge","HTTP-01: one certificate per hostname, issued on first request")),a(r.bindAddress==="0.0.0.0"?v("tls.acme.reachable","pass","ACME reachability",":80 is bound on every interface"):v("tls.acme.reachable","fail","ACME reachability",`HTTP-01 needs :80 reachable from the internet, and Traefik binds ${r.bindAddress}`,"portta public enable, or use ACME_CHALLENGE=dns"))):(a(v("tls.acme.challenge","pass","ACME challenge",`DNS-01: one wildcard for *.${r.domain}`)),
1448
1448
  a(n.CF_DNS_API_TOKEN?v("tls.acme.credential","pass","ACME DNS credential","CF_DNS_API_TOKEN is set"):v("tls.acme.credential","fail","ACME DNS credential","DNS-01 cannot issue anything without a provider credential","set CF_DNS_API_TOKEN, or use ACME_CHALLENGE=http for per-hostname certificates")));let X=Sn(s,"traefik/acme/acme.json");if(Nr(X)){let le=Yn(X);a(le==="600"?v("tls.acme.perms","pass","ACME store permissions",le):v("tls.acme.perms","fail","ACME store permissions",`${le??"unknown"} is t\
1449
1449
  oo permissive`,"chmod 600 state/traefik/acme/acme.json"))}else a(v("tls.acme.store","warn","ACME store","no certificate has been issued yet"))}else r.tlsMode==="local"?a(v("tls.local","pass","TLS","local certificate mode")):a(v("tls.mode","fail","TLS mode",`unknown TLS_MODE '${r.tlsMode}'`,"use TLS_MODE=local or acme"));else a(v("tls.disabled","pass","TLS","disabled (plain HTTP)"));let q=eo(y,r.domain,r.tlsEnabled?"https":"http");a(v("routes.count","pass","routed services",String(q.length)));let j=nf(
@@ -1454,71 +1454,71 @@ filter(I=>I.labels["portta.component"]==="access-bridge");a(v("access.bridges","
1454
1454
  labels["portta.access.project"],le=I.labels["portta.access.service"];return!y.some(tn=>tn.labels["com.docker.compose.project"]===X&&tn.labels["com.docker.compose.service"]===le)}).map(I=>I.labels["portta.access.id"]??I.name);a(ks.length>0?v("access.stale","warn","stale access bridges",`target gone: ${ks.join(" ")}`,"portta access gc"):v("access.stale","pass","stale access bridges","none"));let _s=y.filter(I=>I.labels["portta.component"]==="access-forwarder"),La=_s.filter(I=>I.networks.includes(r.
1455
1455
  network)).map(I=>I.labels["portta.forward.alias"]??I.name);a(La.length>0?v("access.forwarder.network","fail","published forwarders",`attached to the shared HTTP network: ${La.join(" ")}`,`a forwarder belongs on the project network and ${n.PORTTA_ACCESS_NETWORK||`${r.network}-access`} only`):v("access.forwarder.network","pass","published forwarders",`${_s.length} on the access network only`));let Ps=g.filter(I=>I.labels["portta.managed"]==="true"&&["exited","dead"].includes(I.state)).map(I=>I.name);
1456
1456
  if(a(Ps.length>0?v("orphans","warn","stopped gateway containers",Ps.join(" "),`portta up ${r.profile} (or remove them explicitly)`):v("orphans","pass","stopped gateway containers","none")),r.webEnabled){let I=n.PORTTA_WEB_EXPOSE||"local";a(["local","tailscale","public","vpn","domain"].includes(I)?v("panel.access","pass","panel access",`${I} (bind ${D}:${V})`):v("panel.access","fail","panel access",`unknown mode '${I}'`,"portta config set panel.access public|tailscale|local"))}a(...p.filter(I=>I.
1457
- id!=="runtime.docker"));let Hr=await fa("tailscale");if(!Hr)a(v("vpn.tailscale","warn","tailscale","not found","optional; the panel can also be reached publicly or over an SSH tunnel"));else{let I=await $w(Hr,["ip","-4"]);a(I?v("vpn.tailscale","pass","tailscale",`connected (${I})`):v("vpn.tailscale","warn","tailscale","installed but not connected","tailscale up (run it yourself; Portta never authenticates it for you)"))}return t}i(AL,"runDoctor");async function tee(e,t){let n=[],r=e.domain,o=t.
1457
+ id!=="runtime.docker"));let Hr=await fa("tailscale");if(!Hr)a(v("vpn.tailscale","warn","tailscale","not found","optional; the panel can also be reached publicly or over an SSH tunnel"));else{let I=await $w(Hr,["ip","-4"]);a(I?v("vpn.tailscale","pass","tailscale",`connected (${I})`):v("vpn.tailscale","warn","tailscale","installed but not connected","tailscale up (run it yourself; Portta never authenticates it for you)"))}return t}i(AL,"runDoctor");async function nee(e,t){let n=[],r=e.domain,o=t.
1458
1458
  PORTTA_WEB_EXPOSE||"local";if(r==="localhost"||r.endsWith(".localhost"))return n.push(Yv(await EL("portta-probe.localhost"))),o!=="local"&&n.push(v("domain.reachable","warn","project hostnames","*.localhost only resolves on this machine, and the panel is reached from elsewhere","portta config set domain.mode auto")),n;n.push(v("dns.domain","pass","domain",r));let s=(await EL(`portta-probe.${r}`))[0];if(!s)n.push(v("dns.wildcard","fail","wildcard DNS",`*.${r} does not resolve`,"portta dns setup"));else if(Va(
1459
1459
  s))n.push(v("dns.wildcard","pass","wildcard DNS",`*.${r} -> ${s} (this machine)`));else{let u=t.PORTTA_PUBLIC_IP??"";n.push(u?s===u?v("dns.wildcard","pass","wildcard DNS",`*.${r} -> ${s} (this host)`):v("dns.wildcard","warn","wildcard DNS",`*.${r} -> ${s}, and this host is ${u}`,"normal behind a proxy or CDN that forwards here; otherwise point the wildcard at this host, or refresh the address: portta config set domain.mode auto"):v("dns.wildcard","pass","wildcard DNS",`*.${r} -> ${s}`))}let a=e.
1460
1460
  bindAddress,c=s?Xv(r,s,a):null;if(c)n.push(c),o!=="local"&&n.push(v("domain.reachable.remote","warn","project hostnames",`*.${r} resolves to loopback, and the panel is reached from elsewhere`,"point the wildcard at this host, or portta config set domain.mode auto"));else if(sr(a)){let u=t.PORTTA_PUBLIC_IP??"",p=u&&yD(u)?`portta config set gateway.bindAddress ${u} serves them on that network only`:"portta public enable exposes the HTTP services that opted in";n.push(v("domain.reachable","warn",
1461
- "project hostnames",`*.${r} points here, but Traefik listens on ${a} only`,p))}else n.push(v("domain.reachable","pass","project hostnames",`*.${r}, served on ${a}`));return n}i(tee,"domainChecks");async function EL(e){try{let{resolve4:t,lookup:n}=await import("node:dns/promises");try{return await t(e)}catch{return(await n(e,{family:4,all:!0})).map(o=>o.address)}}catch{return[]}}i(EL,"resolveIpv4");function nee(e){let t=Sn(e,"runtime","compose");if(!Nr(t))return[];let n;try{n=Ze(Sn(e,"state/auth/\
1462
- protections.json"))}catch{return[]}let r=[];for(let o of JQ(t))try{let s=JSON.parse(YQ(Sn(t,o,"plan.json"),"utf8"));for(let a of s.services??[])a.host&&!Ge(n,a.host)&&r.push(a.host)}catch{}return r}i(nee,"undecidedHosts");import{existsSync as ree}from"node:fs";import{join as OL}from"node:path";async function Tw(e){let t=await _("docker",["container","inspect",Ts,"--format",`{{ index .Config.Labels "${e}" }}`],{reject:!1});return t.exitCode===0?t.stdout.trim():null}i(Tw,"label");async function oee(){let e=await _("docker",["container","inspect",Ts,"--format","{{ .State.Status }}"],{reject:!1});return e.exitCode===0?e.stdout.trim():null}i(oee,"state");async function ms(){return await Tw("portta.managed")!=="true"||await oee()==="running"?!1:(await _("docker",["rm","-f",Ts],{reject:!1})).
1461
+ "project hostnames",`*.${r} points here, but Traefik listens on ${a} only`,p))}else n.push(v("domain.reachable","pass","project hostnames",`*.${r}, served on ${a}`));return n}i(nee,"domainChecks");async function EL(e){try{let{resolve4:t,lookup:n}=await import("node:dns/promises");try{return await t(e)}catch{return(await n(e,{family:4,all:!0})).map(o=>o.address)}}catch{return[]}}i(EL,"resolveIpv4");function ree(e){let t=Sn(e,"runtime","compose");if(!Nr(t))return[];let n;try{n=Ze(Sn(e,"state/auth/\
1462
+ protections.json"))}catch{return[]}let r=[];for(let o of YQ(t))try{let s=JSON.parse(XQ(Sn(t,o,"plan.json"),"utf8"));for(let a of s.services??[])a.host&&!Ge(n,a.host)&&r.push(a.host)}catch{}return r}i(ree,"undecidedHosts");import{existsSync as oee}from"node:fs";import{join as OL}from"node:path";async function Tw(e){let t=await _("docker",["container","inspect",Ts,"--format",`{{ index .Config.Labels "${e}" }}`],{reject:!1});return t.exitCode===0?t.stdout.trim():null}i(Tw,"label");async function see(){let e=await _("docker",["container","inspect",Ts,"--format","{{ .State.Status }}"],{reject:!1});return e.exitCode===0?e.stdout.trim():null}i(see,"state");async function ms(){return await Tw("portta.managed")!=="true"||await see()==="running"?!1:(await _("docker",["rm","-f",Ts],{reject:!1})).
1463
1463
  exitCode===0}i(ms,"removeApplier");async function $L(e){let t=await Tw("portta.component")==="apply";if(!re(e.env.PORTTA_APPLY??"false"))return t?await ms()?{action:"removed"}:{action:"absent"}:{action:"absent"};let n=Bv(e.env);if(n!==null)return t&&await ms(),{action:"refused",reason:n};let r=Fv(e.root,e.version);if(t){if(await Tw("portta.apply.spec")===r)return{action:"kept"};if(!await ms())return{action:"failed",reason:"the running applier could not be replaced"}}let o=OL(e.root,"docker","ima\
1464
- ges","apply"),s=Se(e.version).apply;if(!ree(OL(o,"Dockerfile")))return{action:"failed",reason:`no applier image source at ${o}`};if((await _("docker",["image","inspect",s],{reject:!1})).exitCode!==0&&(await _("docker",["build","--build-arg",`PORTTA_VERSION=${e.version}`,"-t",s,o],{reject:!1,stdio:"stream"})).exitCode!==0)return{action:"failed",reason:`could not build ${s}`};let c=await _("docker",zv(e.root,r,e.version),{reject:!1});return c.exitCode===0?{action:"created"}:{action:"failed",reason:c.
1465
- stderr.trim()||"docker create failed"}}i($L,"ensureApplier");import{existsSync as hs,readdirSync as see,readFileSync as iee}from"node:fs";import{basename as TL,join as Lr}from"node:path";var CL=".portta",Cw="compose.portta.yaml",Rw="compose.yaml",aee=12e4,cee=500,lee="portta-demo-",uee="portta.example.json";function pee(e){return hs(e)?see(e,{withFileTypes:!0}).filter(t=>t.isDirectory()&&t.name.startsWith(lee)).map(t=>Lr(e,t.name)).sort():[]}i(pee,"demoDirectories");function RL(e){return pee(e).map(t=>{if(!hs(Lr(t,Rw)))return null;let n=Lr(CL,Cw),r=hs(Lr(t,n))||hs(Lr(t,Cw));return{name:TL(t),dir:t,files:r?[Rw,hs(Lr(t,n))?n:Cw]:[Rw],overlay:r}}).filter(t=>t!==null).sort((t,n)=>t.
1466
- name.localeCompare(n.name))}i(RL,"findDemoStacks");function jL(e,t){let n=e.files.flatMap(r=>["-f",r]);return t==="up"?["compose",...n,"up","-d"]:["compose",...n,"down","-v"]}i(jL,"demoComposeArgs");function dee(e){let t=Lr(e,CL,uee);if(!hs(t))return null;try{let r=JSON.parse(iee(t,"utf8")).project;return typeof r?.slug!="string"||typeof r.name!="string"?null:{slug:r.slug,name:r.name,description:typeof r.description=="string"?r.description:null,relativePath:typeof r.relativePath=="string"?r.relativePath:
1467
- TL(e)}}catch{return null}}i(dee,"readDemoProject");async function fee(e,t,n){let r=t.map(a=>dee(a.dir)).filter(a=>a!==null);if(r.length===0)return;let{client:o,output:s}=de(e,{actor:void 0,actorKind:"human",...n?{token:n}:{}});for(let a of r){let c=await o.answer("POST","/projects",a);c.ok?s.progress(`registered Project ${a.name} (${a.slug})`):c.status===409?s.progress(`Project ${a.slug} already registered`):(s.warning(`could not register Project ${a.slug}: the panel answered ${c.status}`),s.hint(
1468
- `portta projects create --slug ${a.slug} --path ${a.relativePath}`))}}i(fee,"registerDemoProjects");function IL(e){return new A(pa(e))}i(IL,"outputFor");function DL(e){let t=E({profile:pa(e).profile,required:!1}),n=t.env.HOME??process.env.HOME??"",r=t.env.PORTTA_PROJECTS_HOME?.trim()||Uc(n,typeof process.getuid=="function"&&process.getuid()===0);return qc(r,t.root,n)}i(DL,"demoHome");function ad(e){let t=DL(e),n=RL(t);if(n.length>0)return n;throw new L(`--demo found no portta-demo-* Compose proj\
1469
- ect in ${t}`,"clone the example repositories there, or set PORTTA_PROJECTS_HOME in .env to the directory that holds them")}i(ad,"requireDemoStacks");async function jw(e,t){let n=IL(e),r=ad(e);n.step("demo stacks");for(let o of r)n.progress(`starting ${o.name}`),await _("docker",jL(o,"up"),{cwd:o.dir,stdio:"inherit"});await fee(e,r,t)}i(jw,"demoStacksUp");async function Iw(e){let t=IL(e),n=RL(DL(e));if(n.length!==0){t.step("demo stacks");for(let r of n)t.progress(`stopping ${r.name}`),await _("do\
1470
- cker",jL(r,"down"),{cwd:r.dir,stdio:"inherit"})}}i(Iw,"demoStacksDown");function mee(e){let t=E({profile:pa(e).profile,required:!1}),n=t.config.webExpose==="public"?"127.0.0.1":t.env.PORTTA_WEB_BIND_ADDRESS??"127.0.0.1",r=t.config.webPort||Number(t.env.PORTTA_WEB_PORT??8081);return`http://${n}:${r}/api/health`}i(mee,"panelHealthUrl");async function Dw(e){try{let t=await fetch(mee(e),{signal:AbortSignal.timeout(3e3)});return t.ok||t.status===401}catch{return!1}}i(Dw,"panelIsReachable");async function Nw(e,t=aee){
1471
- let n=Date.now()+t;for(;Date.now()<n;){if(await Dw(e))return;await new Promise(r=>setTimeout(r,cee))}throw new L("the panel did not become reachable in time","start it with `portta web up` or `portta dev`, then retry")}i(Nw,"waitForPanel");async function NL(e){let{client:t,output:n}=de(e,{actor:void 0,actorKind:"human"}),r=await t.request("GET","/auth/status");if(r.mode==="open"){n.progress("panel is open; demo owner is not needed");return}let o=!1;if(r.setupRequired){let a=await t.answer("POST",
1472
- "/auth/setup",{...Pn});a.status===409?n.progress("panel already has an owner"):a.ok?(n.progress(`created demo owner ${Pn.email}`),o=!0):(await t.request("POST","/auth/setup",{...Pn}),o=!0)}else n.progress("panel already has an owner");let s=await hee(t.url);return(o||s)&&n.progress(`sign in as ${Pn.email} / ${Pn.password}`),s}i(NL,"ensureDevDemoOwner");async function hee(e){try{let t=e,n=new URL(e).host,r=await fetch(`${e}/api/auth/sign-in/email`,{method:"POST",headers:{"content-type":"applicati\
1464
+ ges","apply"),s=Se(e.version).apply;if(!oee(OL(o,"Dockerfile")))return{action:"failed",reason:`no applier image source at ${o}`};if((await _("docker",["image","inspect",s],{reject:!1})).exitCode!==0&&(await _("docker",["build","--build-arg",`PORTTA_VERSION=${e.version}`,"-t",s,o],{reject:!1,stdio:"stream"})).exitCode!==0)return{action:"failed",reason:`could not build ${s}`};let c=await _("docker",zv(e.root,r,e.version),{reject:!1});return c.exitCode===0?{action:"created"}:{action:"failed",reason:c.
1465
+ stderr.trim()||"docker create failed"}}i($L,"ensureApplier");import{existsSync as hs,readdirSync as iee,readFileSync as aee}from"node:fs";import{basename as TL,join as Lr}from"node:path";var CL=".portta",Cw="compose.portta.yaml",Rw="compose.yaml",cee=12e4,lee=500,uee="portta-demo-",pee="portta.example.json";function dee(e){return hs(e)?iee(e,{withFileTypes:!0}).filter(t=>t.isDirectory()&&t.name.startsWith(uee)).map(t=>Lr(e,t.name)).sort():[]}i(dee,"demoDirectories");function RL(e){return dee(e).map(t=>{if(!hs(Lr(t,Rw)))return null;let n=Lr(CL,Cw),r=hs(Lr(t,n))||hs(Lr(t,Cw));return{name:TL(t),dir:t,files:r?[Rw,hs(Lr(t,n))?n:Cw]:[Rw],overlay:r}}).filter(t=>t!==null).sort((t,n)=>t.
1466
+ name.localeCompare(n.name))}i(RL,"findDemoStacks");function jL(e,t){let n=e.files.flatMap(r=>["-f",r]);return t==="up"?["compose",...n,"up","-d"]:["compose",...n,"down","-v"]}i(jL,"demoComposeArgs");function fee(e){let t=Lr(e,CL,pee);if(!hs(t))return null;try{let r=JSON.parse(aee(t,"utf8")).project;return typeof r?.slug!="string"||typeof r.name!="string"?null:{slug:r.slug,name:r.name,description:typeof r.description=="string"?r.description:null,relativePath:typeof r.relativePath=="string"?r.relativePath:
1467
+ TL(e)}}catch{return null}}i(fee,"readDemoProject");async function mee(e,t,n){let r=t.map(a=>fee(a.dir)).filter(a=>a!==null);if(r.length===0)return;let{client:o,output:s}=de(e,{actor:void 0,actorKind:"human",...n?{token:n}:{}});for(let a of r){let c=await o.answer("POST","/projects",a);c.ok?s.progress(`registered Project ${a.name} (${a.slug})`):c.status===409?s.progress(`Project ${a.slug} already registered`):(s.warning(`could not register Project ${a.slug}: the panel answered ${c.status}`),s.hint(
1468
+ `portta projects create --slug ${a.slug} --path ${a.relativePath}`))}}i(mee,"registerDemoProjects");function IL(e){return new A(pa(e))}i(IL,"outputFor");function DL(e){let t=E({profile:pa(e).profile,required:!1}),n=t.env.HOME??process.env.HOME??"",r=t.env.PORTTA_PROJECTS_HOME?.trim()||Uc(n,typeof process.getuid=="function"&&process.getuid()===0);return qc(r,t.root,n)}i(DL,"demoHome");function ad(e){let t=DL(e),n=RL(t);if(n.length>0)return n;throw new L(`--demo found no portta-demo-* Compose proj\
1469
+ ect in ${t}`,"clone the example repositories there, or set PORTTA_PROJECTS_HOME in .env to the directory that holds them")}i(ad,"requireDemoStacks");async function jw(e,t){let n=IL(e),r=ad(e);n.step("demo stacks");for(let o of r)n.progress(`starting ${o.name}`),await _("docker",jL(o,"up"),{cwd:o.dir,stdio:"inherit"});await mee(e,r,t)}i(jw,"demoStacksUp");async function Iw(e){let t=IL(e),n=RL(DL(e));if(n.length!==0){t.step("demo stacks");for(let r of n)t.progress(`stopping ${r.name}`),await _("do\
1470
+ cker",jL(r,"down"),{cwd:r.dir,stdio:"inherit"})}}i(Iw,"demoStacksDown");function hee(e){let t=E({profile:pa(e).profile,required:!1}),n=t.config.webExpose==="public"?"127.0.0.1":t.env.PORTTA_WEB_BIND_ADDRESS??"127.0.0.1",r=t.config.webPort||Number(t.env.PORTTA_WEB_PORT??8081);return`http://${n}:${r}/api/health`}i(hee,"panelHealthUrl");async function Dw(e){try{let t=await fetch(hee(e),{signal:AbortSignal.timeout(3e3)});return t.ok||t.status===401}catch{return!1}}i(Dw,"panelIsReachable");async function Nw(e,t=cee){
1471
+ let n=Date.now()+t;for(;Date.now()<n;){if(await Dw(e))return;await new Promise(r=>setTimeout(r,lee))}throw new L("the panel did not become reachable in time","start it with `portta web up` or `portta dev`, then retry")}i(Nw,"waitForPanel");async function NL(e){let{client:t,output:n}=de(e,{actor:void 0,actorKind:"human"}),r=await t.request("GET","/auth/status");if(r.mode==="open"){n.progress("panel is open; demo owner is not needed");return}let o=!1;if(r.setupRequired){let a=await t.answer("POST",
1472
+ "/auth/setup",{...Pn});a.status===409?n.progress("panel already has an owner"):a.ok?(n.progress(`created demo owner ${Pn.email}`),o=!0):(await t.request("POST","/auth/setup",{...Pn}),o=!0)}else n.progress("panel already has an owner");let s=await gee(t.url);return(o||s)&&n.progress(`sign in as ${Pn.email} / ${Pn.password}`),s}i(NL,"ensureDevDemoOwner");async function gee(e){try{let t=e,n=new URL(e).host,r=await fetch(`${e}/api/auth/sign-in/email`,{method:"POST",headers:{"content-type":"applicati\
1473
1473
  on/json",origin:t,host:n},body:JSON.stringify({email:Pn.email,password:Pn.password}),signal:AbortSignal.timeout(15e3)});if(!r.ok)return;let o=r.headers.get("set-cookie")?.split(";")[0];if(!o)return;let s=await fetch(`${e}/api/auth/tokens`,{method:"POST",headers:{"content-type":"application/json",origin:t,host:n,cookie:o},body:JSON.stringify({name:"dev-demo",actorKind:"human"}),signal:AbortSignal.timeout(15e3)});if(!s.ok)return;let a=await s.json();return typeof a.token=="string"?a.token:void 0}catch{
1474
- return}}i(hee,"mintDevDemoToken");import{existsSync as gee}from"node:fs";import{join as LL}from"node:path";async function Lw(e){let t=await _("docker",["container","inspect",ii,"--format",`{{ index .Config.Labels "${e}" }}`],{reject:!1});return t.exitCode===0?t.stdout.trim():null}i(Lw,"label");async function bee(){let e=await _("docker",["container","inspect",ii,"--format","{{ .State.Status }}"],{reject:!1});return e.exitCode===0?e.stdout.trim():null}i(bee,"state");async function gs(){return await Lw("portta.managed")!=="true"||await bee()==="running"?!1:(await _("docker",["rm","-f",ii],{reject:!1})).
1474
+ return}}i(gee,"mintDevDemoToken");import{existsSync as bee}from"node:fs";import{join as LL}from"node:path";async function Lw(e){let t=await _("docker",["container","inspect",ii,"--format",`{{ index .Config.Labels "${e}" }}`],{reject:!1});return t.exitCode===0?t.stdout.trim():null}i(Lw,"label");async function yee(){let e=await _("docker",["container","inspect",ii,"--format","{{ .State.Status }}"],{reject:!1});return e.exitCode===0?e.stdout.trim():null}i(yee,"state");async function gs(){return await Lw("portta.managed")!=="true"||await yee()==="running"?!1:(await _("docker",["rm","-f",ii],{reject:!1})).
1475
1475
  exitCode===0}i(gs,"removeRunner");async function ML(e){let t=await Lw("portta.component")==="runner";if(!re(e.env.PORTTA_RUNNER??"false"))return t?await gs()?{action:"removed"}:{action:"absent"}:{action:"absent"};let n=VE(e.env);if(n!==null)return t&&await gs(),{action:"refused",reason:n};let r=WE(e.root,e.version);if(t){if(await Lw("portta.runner.spec")===r)return{action:"kept"};if(!await gs())return{action:"failed",reason:"the running runner could not be replaced"}}let o=LL(e.root,"docker","im\
1476
- ages","apply"),s=Se(e.version).apply;if(!gee(LL(o,"Dockerfile")))return{action:"failed",reason:`no runner image source at ${o}`};if((await _("docker",["image","inspect",s],{reject:!1})).exitCode!==0&&(await _("docker",["build","--build-arg",`PORTTA_VERSION=${e.version}`,"-t",s,o],{reject:!1,stdio:"stream"})).exitCode!==0)return{action:"failed",reason:`could not build ${s}`};let c=await _("docker",GE(e.root,r,e.version),{reject:!1});return c.exitCode===0?{action:"created"}:{action:"failed",reason:c.
1477
- stderr.trim()||"docker create failed"}}i(ML,"ensureRunner");function See(){return{PORTTA_WEB:"true",PORTTA_WEB_DEV:"true",PORTTA_WEB_BUILD:"false",PORTTA_AUTH_IMAGE:"",PORTTA_WEB_IMAGE:""}}i(See,"checkoutLocalEnv");function xee(e,t){let n=yt(e,".env");je(n,t)}i(xee,"persistEnv");function kee(e){let t=E({profile:fe(e).profile}).composeFiles;return t.includes(Yd)||t.includes(Xd)}i(kee,"buildsLocally");function fe(e){return e.optsWithGlobals()}i(fe,"globals");async function Xt(e,t,n="inherit",r={}){let o=fe(e),s=E({profile:o.profile});return _("docker",["co\
1478
- mpose",...we(s),...t],{cwd:s.root,env:s.env,stdio:n,reject:r.reject})}i(Xt,"compose");function zw(e,t,n){try{qa(e,t)}catch(r){n?.progress(`warn could not record the applied settings: ${r.message}`)}}i(zw,"recordApplied");function Fw(e){let t=yt(e,".env");return me(Mr(t)?zL(t,"utf8"):"")}i(Fw,"envBeforeUp");function BL(e,t){let n=yt(e,"state/auth");wee(n,{recursive:!0,mode:448}),yee(n,448);let r=yt(e,".env");xt(r),_a(e,t)}i(BL,"ensureAuthState");function Mw(e){let t=e.split(".");return`${t[0]??
1479
- "0"}.${t[1]??"0"}`}i(Mw,"series");async function _ee(e){let t=e.env.PORTTA_WEB_IMAGE??"",n=t.includes(":")?t.slice(t.lastIndexOf(":")+1):null;if(!e.config.webEnabled)return{version:null,detail:"disabled"};let r=e.config.webExpose==="public"?"127.0.0.1":e.env.PORTTA_WEB_BIND_ADDRESS??"127.0.0.1";try{let o=await fetch(`http://${r}:${e.config.webPort}/api/health`,{signal:AbortSignal.timeout(3e3)});if(o.status===401)return{version:n,detail:n?`${n} (from the image tag; the API is behind authenticatio\
1480
- n)`:"behind authentication"};if(!o.ok)return{version:n,detail:`unreachable (HTTP ${o.status})`};let s=await o.json();return{version:s.panelVersion??n,detail:s.panelVersion??"unknown"}}catch{return{version:n,detail:n?`${n} (from the image tag; the panel did not answer)`:"not running"}}}i(_ee,"panelReport");async function UL(e){let t=fe(e),n=new A(t),r=E({required:!1}),o=pr,s=r.version,a=Mw(o)===Mw(s);if(!n.json&&!r.composeFiles.length){n.data(ai());return}let c=await _ee(r);if(n.json){n.data({cli:o,
1476
+ ages","apply"),s=Se(e.version).apply;if(!bee(LL(o,"Dockerfile")))return{action:"failed",reason:`no runner image source at ${o}`};if((await _("docker",["image","inspect",s],{reject:!1})).exitCode!==0&&(await _("docker",["build","--build-arg",`PORTTA_VERSION=${e.version}`,"-t",s,o],{reject:!1,stdio:"stream"})).exitCode!==0)return{action:"failed",reason:`could not build ${s}`};let c=await _("docker",GE(e.root,r,e.version),{reject:!1});return c.exitCode===0?{action:"created"}:{action:"failed",reason:c.
1477
+ stderr.trim()||"docker create failed"}}i(ML,"ensureRunner");function xee(){return{PORTTA_WEB:"true",PORTTA_WEB_DEV:"true",PORTTA_WEB_BUILD:"false",PORTTA_AUTH_IMAGE:"",PORTTA_WEB_IMAGE:""}}i(xee,"checkoutLocalEnv");function kee(e,t){let n=yt(e,".env");je(n,t)}i(kee,"persistEnv");function _ee(e){let t=E({profile:fe(e).profile}).composeFiles;return t.includes(Yd)||t.includes(Xd)}i(_ee,"buildsLocally");function fe(e){return e.optsWithGlobals()}i(fe,"globals");async function Xt(e,t,n="inherit",r={}){let o=fe(e),s=E({profile:o.profile});return _("docker",["co\
1478
+ mpose",...we(s),...t],{cwd:s.root,env:s.env,stdio:n,reject:r.reject})}i(Xt,"compose");function zw(e,t,n){try{qa(e,t)}catch(r){n?.progress(`warn could not record the applied settings: ${r.message}`)}}i(zw,"recordApplied");function Fw(e){let t=yt(e,".env");return me(Mr(t)?zL(t,"utf8"):"")}i(Fw,"envBeforeUp");function BL(e,t){let n=yt(e,"state/auth");vee(n,{recursive:!0,mode:448}),wee(n,448);let r=yt(e,".env");xt(r),_a(e,t)}i(BL,"ensureAuthState");function Mw(e){let t=e.split(".");return`${t[0]??
1479
+ "0"}.${t[1]??"0"}`}i(Mw,"series");async function Pee(e){let t=e.env.PORTTA_WEB_IMAGE??"",n=t.includes(":")?t.slice(t.lastIndexOf(":")+1):null;if(!e.config.webEnabled)return{version:null,detail:"disabled"};let r=e.config.webExpose==="public"?"127.0.0.1":e.env.PORTTA_WEB_BIND_ADDRESS??"127.0.0.1";try{let o=await fetch(`http://${r}:${e.config.webPort}/api/health`,{signal:AbortSignal.timeout(3e3)});if(o.status===401)return{version:n,detail:n?`${n} (from the image tag; the API is behind authenticatio\
1480
+ n)`:"behind authentication"};if(!o.ok)return{version:n,detail:`unreachable (HTTP ${o.status})`};let s=await o.json();return{version:s.panelVersion??n,detail:s.panelVersion??"unknown"}}catch{return{version:n,detail:n?`${n} (from the image tag; the panel did not answer)`:"not running"}}}i(Pee,"panelReport");async function UL(e){let t=fe(e),n=new A(t),r=E({required:!1}),o=pr,s=r.version,a=Mw(o)===Mw(s);if(!n.json&&!r.composeFiles.length){n.data(ai());return}let c=await Pee(r);if(n.json){n.data({cli:o,
1481
1481
  built:Zc??null,gateway:s,panel:c.version,root:r.root,compatible:a,apiSeries:Mw(s)});return}n.line(ai()),n.line(` gateway ${s} (${r.root})`),n.line(` panel ${c.detail}`),a||(n.warning(`this CLI is ${o} and the installation is ${s}`),n.hint(`update the installation with portta setup, or install the matching CLI: npm install -g @codions/portta@${s}`))}i(UL,"versionCommand");async function Bw(e,t){let n=fe(t),r=new A(n),o=E({profile:n.profile});if(r.step("checkout"),await Ct(),(await _("docke\
1482
1482
  r",["compose","version","--short"],{reject:!1})).exitCode!==0)throw new _e("Docker Compose v2 is required",Fe.precondition);xt(yt(o.root,".env")),rs(o.root),BL(o.root,o.config.profile);let a=await Zt(o.config.network);r.progress(`${a.padEnd(8)} shared network ${o.config.network}`),e.skipPull||await Xt(t,["pull","--ignore-buildable"]),await Hw(t)}i(Bw,"bootstrapCommand");async function Uw(e,t,n){e&&n.setOptionValueWithSource("profile",e,"cli"),xt(yt(E({profile:e??fe(n).profile}).root,".env")),t.localRelease&&
1483
1483
  Op(E({profile:e??fe(n).profile}));let r=E({profile:e??fe(n).profile});if(t.localRelease&&(r.env.PORTTA_LOCAL_RELEASE="true"),t.demo&&ad(n),r.config.profile==="remote-public"&&r.config.tcpEnabled)throw new U("TCP entrypoints must not run on the remote-public profile");if(r.config.profile==="remote-public"&&r.config.webEnabled&&r.config.webExpose==="vpn")throw new U("the panel must not be routed on the tailnet hostname while Traefik binds every interface","portta web up --expose domain routes it\
1484
- on the gateway's own domain, behind the same login page");let o=new A(fe(n)),s=kee(n);if(o.step("gateway components"),await Ct(),await Ap(r),await Zt(r.config.network),r.config.tcpEnabled&&await Zt(r.config.accessNetwork),BL(r.root,r.config.profile),r.config.profile==="remote-public"){let f=await J(!0),m=On(f),h=LS(f),b="run portta runtime down <path>, then portta adopt and portta runtime up it again";if(m.length>0&&!h)throw new U(`these services route with no login gate, so starting a public g\
1484
+ on the gateway's own domain, behind the same login page");let o=new A(fe(n)),s=_ee(n);if(o.step("gateway components"),await Ct(),await Ap(r),await Zt(r.config.network),r.config.tcpEnabled&&await Zt(r.config.accessNetwork),BL(r.root,r.config.profile),r.config.profile==="remote-public"){let f=await J(!0),m=On(f),h=LS(f),b="run portta runtime down <path>, then portta adopt and portta runtime up it again";if(m.length>0&&!h)throw new U(`these services route with no login gate, so starting a public g\
1485
1485
  ateway would open them: ${m.join(", ")}`,b);m.length>0&&o.warning(`routed with no login gate, so open to the internet: ${m.join(", ")}. ${b}`)}let a=Fw(r.root);o.progress(s?"starting components, building local images":"starting components");let c=!t.attach,u=await Xt(n,["up",t.attach?"":"-d",...s?["--build"]:[],t.attach?"":"--remove-orphans",...c?["--wait","--wait-timeout","180"]:[]].filter(Boolean),"inherit",c?{reject:!1}:{});if(c&&u.exitCode!==0)throw new L("the gateway did not report healthy \
1486
1486
  within 180s","portta logs shows what it is doing; portta doctor checks the rest");zw(r.root,a,o),await Zp(r.config.profile,o);let p=await $L(r);p.action==="created"&&o.progress("ok applier ready; the panel can apply settings without a terminal"),p.action==="removed"&&o.progress("ok applier removed (PORTTA_APPLY is false)"),p.action==="refused"&&o.progress(`warn not preparing the applier: ${p.reason}`),p.action==="failed"&&o.progress(`warn ${p.reason}; settings still apply w\
1487
1487
  ith: portta up`);let d=await ML(r);d.action==="created"&&o.progress("ok runner ready; the panel can operate a project without a terminal"),d.action==="removed"&&o.progress("ok runner removed (PORTTA_RUNNER is false)"),d.action==="refused"&&o.progress(`warn not preparing the runner: ${d.reason}`),d.action==="failed"&&o.progress(`warn ${d.reason}; project operations still run from a shell`),t.demo&&(await Dw(n)||await Pa({},n),await Nw(n),await jw(n),await Ta({},n))}i(Uw,"upCom\
1488
1488
  mand");async function qw(e,t,n){e&&n.setOptionValueWithSource("profile",e,"cli");let r=E({profile:e??fe(n).profile,required:!1}),o=new A(fe(n));if(await kL(r.root,o)){await _L(r.root);return}t.demo&&ad(n);let s=!Mr(yt(r.root,".env"));o.progress(`dev runs: ${[...t.reset?["wipe Portta-managed containers and volumes"]:[],...s?["prepare the checkout"]:[],"start gateway components","start the panel","create the development owner",...t.demo?["start example stacks from Projects Home"]:[],"list routed h\
1489
- ostnames"].join(" -> ")}`),t.reset&&await Cee(n),s&&(n.setOptionValueWithSource("yes",!0,"cli"),await Bw({skipPull:!0},n)),xee(E({profile:e??fe(n).profile}).root,See());let a=pw({dev:!0},n);await Uw(e,{attach:!1},n),await Nw(n);let c=await NL(n);await dw(a,n,!1,c),t.demo&&await jw(n,c),await Ta({},n)}i(qw,"devCommand");async function qL(e,t){e.demo&&await Iw(t),await Xt(t,["down"]),await ms(),await gs(),ka(fe(t).profile,new A(fe(t)))}i(qL,"downCommand");function Pee(e){return or(Mt(e))}i(Pee,"pa\
1490
- nelDatabaseArtefacts");var Eee=["state/metrics","state/environment"];function Aee(e){let t=[];for(let n of Eee){let r=yt(e,n);if(Mr(r)){for(let o of vee(r,{withFileTypes:!0}))FL(yt(r,o.name),{recursive:!0,force:!0});t.push(n)}}return t}i(Aee,"clearRegenerableState");function Oee(e,t){return e.labels["portta.managed"]==="true"||(e.labels["portta.project"]??"").trim()!==""||e.networks.includes(t.shared)?!0:!!(t.access&&e.networks.includes(t.access))}i(Oee,"isPorttaOwnedContainer");function $ee(e,t){
1491
- let n=new Map;for(let r of e){if(!Oee(r,{shared:t.sharedNetwork,access:t.accessNetwork}))continue;let o=r.labels["com.docker.compose.project"];!o||o===t.gatewayProject||n.has(o)||n.set(o,r.labels["com.docker.compose.project.working_dir"]||null)}return[...n.entries()].map(([r,o])=>({name:r,workingDir:o})).sort((r,o)=>r.name.localeCompare(o.name))}i($ee,"porttaOwnedComposeProjects");var Tee="stop every Portta-managed stack, drop their volumes, and restart this checkout as if it were new?";async function Cee(e){
1492
- await et(Tee,fe(e).yes===!0),await Ct();let t=E({profile:fe(e).profile}),n=new A(fe(e));n.step("Portta runtime"),await Iw(e);let r=await J();for(let a of $ee(r,{gatewayProject:t.config.projectName,sharedNetwork:t.config.network,accessNetwork:t.config.accessNetwork})){let c=No(a.name,"compose project"),u=["compose","--project-name",c],p=a.workingDir&&Mr(a.workingDir)?a.workingDir:void 0;p&&u.push("--project-directory",p),u.push("down","--volumes","--remove-orphans"),n.progress(`stopping ${c}`),await _(
1493
- "docker",u,{cwd:p,stdio:"inherit"})}await Xt(e,["down","-v","--remove-orphans"]),await ms(),await gs(),ka(fe(e).profile,n);for(let a of await J()){if(a.labels["portta.managed"]!=="true")continue;let c=No(a.name,"container");(await _("docker",["rm","-f",c],{reject:!1})).exitCode===0&&n.progress(`removed ${c}`)}let o=0;for(let a of Pee(t.root))Mr(a)&&(FL(a,{force:!0}),o+=1);n.progress(o>0?`removed the panel database (${o} file(s))`:"the panel database was already absent");let s=Aee(t.root);s.length>
1494
- 0&&n.progress(`cleared ${s.join(", ")}`)}i(Cee,"wipePorttaRuntime");async function HL(e,t){await qw(void 0,{reset:!0,demo:e.demo},t)}i(HL,"resetCommand");async function ZL(e){let t=E({profile:fe(e).profile}).root,n=Fw(t);await Xt(e,["up","-d","--force-recreate","--wait","--wait-timeout","180"]),zw(t,n)}i(ZL,"restartCommand");async function GL(e,t,n){let r=fe(n);if(r.json){let o=await Xt(n,["logs","--no-color","--no-log-prefix","--tail",t.tail??"200",...e?[e]:[]],"pipe");new A(r).data({lines:o.stdout.
1489
+ ostnames"].join(" -> ")}`),t.reset&&await Ree(n),s&&(n.setOptionValueWithSource("yes",!0,"cli"),await Bw({skipPull:!0},n)),kee(E({profile:e??fe(n).profile}).root,xee());let a=pw({dev:!0},n);await Uw(e,{attach:!1},n),await Nw(n);let c=await NL(n);await dw(a,n,!1,c),t.demo&&await jw(n,c),await Ta({},n)}i(qw,"devCommand");async function qL(e,t){e.demo&&await Iw(t),await Xt(t,["down"]),await ms(),await gs(),ka(fe(t).profile,new A(fe(t)))}i(qL,"downCommand");function Eee(e){return or(Mt(e))}i(Eee,"pa\
1490
+ nelDatabaseArtefacts");var Aee=["state/metrics","state/environment"];function Oee(e){let t=[];for(let n of Aee){let r=yt(e,n);if(Mr(r)){for(let o of See(r,{withFileTypes:!0}))FL(yt(r,o.name),{recursive:!0,force:!0});t.push(n)}}return t}i(Oee,"clearRegenerableState");function $ee(e,t){return e.labels["portta.managed"]==="true"||(e.labels["portta.project"]??"").trim()!==""||e.networks.includes(t.shared)?!0:!!(t.access&&e.networks.includes(t.access))}i($ee,"isPorttaOwnedContainer");function Tee(e,t){
1491
+ let n=new Map;for(let r of e){if(!$ee(r,{shared:t.sharedNetwork,access:t.accessNetwork}))continue;let o=r.labels["com.docker.compose.project"];!o||o===t.gatewayProject||n.has(o)||n.set(o,r.labels["com.docker.compose.project.working_dir"]||null)}return[...n.entries()].map(([r,o])=>({name:r,workingDir:o})).sort((r,o)=>r.name.localeCompare(o.name))}i(Tee,"porttaOwnedComposeProjects");var Cee="stop every Portta-managed stack, drop their volumes, and restart this checkout as if it were new?";async function Ree(e){
1492
+ await et(Cee,fe(e).yes===!0),await Ct();let t=E({profile:fe(e).profile}),n=new A(fe(e));n.step("Portta runtime"),await Iw(e);let r=await J();for(let a of Tee(r,{gatewayProject:t.config.projectName,sharedNetwork:t.config.network,accessNetwork:t.config.accessNetwork})){let c=No(a.name,"compose project"),u=["compose","--project-name",c],p=a.workingDir&&Mr(a.workingDir)?a.workingDir:void 0;p&&u.push("--project-directory",p),u.push("down","--volumes","--remove-orphans"),n.progress(`stopping ${c}`),await _(
1493
+ "docker",u,{cwd:p,stdio:"inherit"})}await Xt(e,["down","-v","--remove-orphans"]),await ms(),await gs(),ka(fe(e).profile,n);for(let a of await J()){if(a.labels["portta.managed"]!=="true")continue;let c=No(a.name,"container");(await _("docker",["rm","-f",c],{reject:!1})).exitCode===0&&n.progress(`removed ${c}`)}let o=0;for(let a of Eee(t.root))Mr(a)&&(FL(a,{force:!0}),o+=1);n.progress(o>0?`removed the panel database (${o} file(s))`:"the panel database was already absent");let s=Oee(t.root);s.length>
1494
+ 0&&n.progress(`cleared ${s.join(", ")}`)}i(Ree,"wipePorttaRuntime");async function HL(e,t){await qw(void 0,{reset:!0,demo:e.demo},t)}i(HL,"resetCommand");async function ZL(e){let t=E({profile:fe(e).profile}).root,n=Fw(t);await Xt(e,["up","-d","--force-recreate","--wait","--wait-timeout","180"]),zw(t,n)}i(ZL,"restartCommand");async function GL(e,t,n){let r=fe(n);if(r.json){let o=await Xt(n,["logs","--no-color","--no-log-prefix","--tail",t.tail??"200",...e?[e]:[]],"pipe");new A(r).data({lines:o.stdout.
1495
1495
  split(`
1496
1496
  `).filter(Boolean)})}else await Xt(n,["logs",...t.follow===!1?[]:["--follow"],"--tail",t.tail??"200",...e?[e]:[]])}i(GL,"logsCommand");async function WL(e){xt(yt(E({profile:fe(e).profile}).root,".env")),await Xt(e,["config","--quiet"]),await Xt(e,["pull","--ignore-buildable"]),await et("recreate gateway components with the pulled images?",fe(e).yes===!0);let t=E({profile:fe(e).profile}).root,n=Fw(t);await Xt(e,["up","-d","--force-recreate","--wait","--wait-timeout","180"]),zw(t,n)}i(WL,"updateCo\
1497
1497
  mmand");async function VL(e){let t=fe(e),n=E({profile:t.profile}),r=new A(t),o=new Set(["TS_AUTHKEY","CF_DNS_API_TOKEN","PORTTA_AUTH_SECRET"]),s=Object.fromEntries(Object.entries(n.env).filter(([a])=>a.startsWith("PORTTA_")||["TLS_ENABLED","TLS_MODE","PUBLIC_DOMAIN","PRIVATE_DOMAIN","TAILSCALE_ENABLED"].includes(a)).map(([a,c])=>[a,o.has(a)?c?"<set>":"<unset>":c]));if(r.json)r.data({profile:n.config.profile,configuration:s,composeFiles:n.composeFiles});else{r.line(`profile: ${n.config.profile}`);
1498
1498
  for(let[a,c]of Object.entries(s).sort())r.line(`${a}=${c}`);r.line(`compose files: ${n.composeFiles.join(", ")}`)}}i(VL,"inspectCommand");async function KL(e){let t=fe(e),n=E({profile:t.profile}),r=await J(),o=eo(r,n.config.domain,n.config.tlsEnabled?"https":"http"),s=r.filter(u=>u.labels["portta.managed"]==="true"),a={version:n.version,instance:{name:n.config.projectName},profile:n.config.profile,domain:n.config.domain,bindAddress:n.config.bindAddress,network:{name:n.config.network,exists:await zg(
1499
1499
  n.config.network)},components:s.map(u=>({name:u.name,state:u.state,component:u.labels["portta.component"]??null})),projectCount:Ns(r,n.config.domain,n.config.tlsEnabled?"https":"http").length,routeCount:o.length,tls:n.config.tlsEnabled,public:n.config.publicEnabled},c=new A(t);if(c.json)c.data(a);else{c.line(`portta ${a.version} \xB7 ${a.profile} \xB7 ${a.domain}`),c.line(`network ${a.network.exists?"ready":"missing"} \xB7 ${a.components.length} components \xB7 ${a.routeCount} routes`);for(let u of a.
1500
- components)c.line(`${u.component??u.name} ${u.state}`)}}i(KL,"statusCommand");function Ree(e){return e.map(t=>({line:`${t.status==="pass"?"ok ":t.status==="info"?"info":t.status==="warn"?"warn":"FAIL"} ${t.message}`,...t.fix&&t.status!=="pass"?{hint:t.fix}:{}}))}i(Ree,"doctorReport");async function Hw(e){let t=fe(e),n=E({profile:t.profile}),r=(await AL(n)).map(c=>({id:c.id,status:c.status,message:`${c.title}: ${c.detail}`,...c.fix?{fix:c.fix}:{}}));for(let c of n.composeFiles)r.push({id:`compos\
1500
+ components)c.line(`${u.component??u.name} ${u.state}`)}}i(KL,"statusCommand");function jee(e){return e.map(t=>({line:`${t.status==="pass"?"ok ":t.status==="info"?"info":t.status==="warn"?"warn":"FAIL"} ${t.message}`,...t.fix&&t.status!=="pass"?{hint:t.fix}:{}}))}i(jee,"doctorReport");async function Hw(e){let t=fe(e),n=E({profile:t.profile}),r=(await AL(n)).map(c=>({id:c.id,status:c.status,message:`${c.title}: ${c.detail}`,...c.fix?{fix:c.fix}:{}}));for(let c of n.composeFiles)r.push({id:`compos\
1501
1501
  e:${c}`,status:Mr(yt(n.root,c))?"pass":"fail",message:`${c} exists`});let o=JL(n.root);if(o.length>0){let c=new Set((await J()).map(p=>p.name)),u=o.filter(p=>!c.has(p.container));r.push(u.length===0?{id:"aliases",status:"pass",message:`${o.length} hostname alias(es) routed`}:{id:"aliases",status:"fail",message:`alias target missing: ${u.map(p=>`${p.host} -> ${p.container}`).join(", ")}`,fix:"remove the alias in the panel, or start the environment again"})}let s=r.filter(c=>c.status==="fail"),a=new A(
1502
- t);if(a.json)a.data({ok:s.length===0,instance:{name:n.config.projectName},checks:r});else for(let c of Ree(r))a.line(c.line),c.hint&&a.hint(c.hint);if(s.length)throw new _e(`${s.length} doctor check(s) failed`)}i(Hw,"doctorCommand");function JL(e){let t=yt(e,"config/traefik/dynamic/portta-aliases.yaml");if(!Mr(t))return[];try{return Wr(zL(t,"utf8"))}catch{return[]}}i(JL,"readAliases");async function Ta(e,t){let n=fe(t),r=E({profile:n.profile}),o=r.config.tlsEnabled?"https":"http",s=eo(await J(),
1502
+ t);if(a.json)a.data({ok:s.length===0,instance:{name:n.config.projectName},checks:r});else for(let c of jee(r))a.line(c.line),c.hint&&a.hint(c.hint);if(s.length)throw new _e(`${s.length} doctor check(s) failed`)}i(Hw,"doctorCommand");function JL(e){let t=yt(e,"config/traefik/dynamic/portta-aliases.yaml");if(!Mr(t))return[];try{return Wr(zL(t,"utf8"))}catch{return[]}}i(JL,"readAliases");async function Ta(e,t){let n=fe(t),r=E({profile:n.profile}),o=r.config.tlsEnabled?"https":"http",s=eo(await J(),
1503
1503
  r.config.domain,o).map(p=>({...p,alias:!1})),a=JL(r.root).map(p=>({project:p.project,service:p.service,container:p.container,hostname:p.host,url:`${o}://${p.host}`,port:String(p.port),state:"alias",alias:!0})),c=[...s,...a].filter(p=>!e.project||p.project===e.project).sort((p,d)=>p.hostname.localeCompare(d.hostname)),u=new A(n);if(u.json)u.data({instance:{name:r.config.projectName},routes:c});else for(let p of c)u.line(`${p.url} ${p.project??"-"} ${p.service??p.container}${p.alias?" alias":""}`)}
1504
- i(Ta,"urlsCommand");import{chmodSync as zr,copyFileSync as jee,cpSync as Zw,existsSync as Dt,mkdirSync as cd,mkdtempSync as XL,readFileSync as Iee,rmSync as Gw,statSync as Dee,writeFileSync as Nee}from"node:fs";import{hostname as Lee,tmpdir as QL}from"node:os";import{dirname as eM,join as ve}from"node:path";function Ww(e){return e.optsWithGlobals()}i(Ww,"globals");var tM=1;function nM(e){return[".env","VERSION","config","state"].filter(t=>Dt(ve(e,t)))}i(nM,"backupPaths");function Mee(e){return`${JSON.stringify(e)}
1505
- `}i(Mee,"renderManifest");function zee(e){try{let t=JSON.parse(e);return t.version!==tM||typeof t.portta!="string"||typeof t.created!="string"||typeof t.host!="string"?null:t}catch{return null}}i(zee,"parseManifest");async function YL(e){let t=await _("docker",["inspect","-f","{{.State.Running}}",e],{reject:!1});return!t.failed&&t.stdout.trim()==="true"}i(YL,"containerRunning");async function Fee(e,t){let n=Mt(e.root);if(!Dt(n))return!1;let r=await _("sh",["-c","command -v sqlite3"],{reject:!1}),
1506
- o=r.stdout.trim();return r.failed||!o||(await _(o,[n,`VACUUM INTO '${t.replaceAll("'","''")}'`],{reject:!1})).failed||!Dt(t)?!1:(zr(t,384),!0)}i(Fee,"dumpDatabase");async function rM(e,t){let n=Ww(t),r=new A(n),o=E({profile:n.profile}),s=new Date().toISOString().replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z"),a=e.output??ve(o.root,`portta-backup-${s}.tar.gz`),c=XL(ve(QL(),"portta-backup-"));zr(c,448);try{Nee(ve(c,"portta-backup.json"),Mee({version:tM,portta:o.version,created:new Date().toISOString().
1507
- replace(/\.\d+Z$/,"Z"),host:Lee()||"unknown"}));let u=nM(o.root);for(let h of u)cd(ve(c,"tree",eM(h)),{recursive:!0}),Zw(ve(o.root,h),ve(c,"tree",h),{recursive:!0});let p=!1;e.database!==!1&&(p=await Fee(o,ve(c,"panel.db")),p||(r.warning("the panel database was not included"),r.hint("it exists once the panel has started, and copying it needs sqlite3 on this host; --no-database silences this")));let d=process.umask(63),f;try{f=await _("tar",["-czf",a,"-C",c,"."],{reject:!1})}finally{process.umask(
1508
- d)}if(f.failed)throw new L(`could not write ${a}`,f.stderr.trim());let m=Dee(a).size;if(r.json){r.data({file:a,size:m,paths:u,database:p});return}r.progress("backup written"),r.line(` file ${a}`),r.line(` size ${Bee(m)}`),r.line(` contents ${u.length} path(s)${p?" + database":""}`),r.line(""),r.warning("this archive contains credentials: .env, the panel password hash and any tokens")}finally{Gw(c,{recursive:!0,force:!0})}}i(rM,"backupCommand");function Bee(e){let t=["B","K","M","G",
1509
- "T"],n=e,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r+=1;return`${r===0?n:n.toFixed(1)}${t[r]}`}i(Bee,"humanSize");async function oM(e,t,n){let r=Ww(n),o=new A(r),s=E({profile:r.profile});if(!e)throw new C("which backup?","portta restore <file>");if(!Dt(e))throw new C(`no such file: ${e}`);let a=XL(ve(QL(),"portta-restore-"));zr(a,448);try{if((await _("tar",["-xzf",e,"-C",a],{reject:!1})).failed)throw new C("that file is not a Portta backup");let u=ve(a,"portta-backup.json");if(!Dt(u))throw new C("\
1510
- that archive has no Portta manifest");let p=zee(Iee(u,"utf8"));if(!p)throw new C("that archive has an unreadable Portta manifest");if(o.progress(`restoring a backup taken from Portta ${p.portta}`),!t.force&&await YL(`${s.env.PORTTA_PROJECT_NAME||"portta"}-traefik-1`))throw new L("the gateway is running","portta down, then restore; or pass --force to replace configuration underneath it");let d=new Date().toISOString().replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z"),f=ve(s.root,"state",`restore-${d}`);
1504
+ i(Ta,"urlsCommand");import{chmodSync as zr,copyFileSync as Iee,cpSync as Zw,existsSync as Dt,mkdirSync as cd,mkdtempSync as XL,readFileSync as Dee,rmSync as Gw,statSync as Nee,writeFileSync as Lee}from"node:fs";import{hostname as Mee,tmpdir as QL}from"node:os";import{dirname as eM,join as ve}from"node:path";function Ww(e){return e.optsWithGlobals()}i(Ww,"globals");var tM=1;function nM(e){return[".env","VERSION","config","state"].filter(t=>Dt(ve(e,t)))}i(nM,"backupPaths");function zee(e){return`${JSON.stringify(e)}
1505
+ `}i(zee,"renderManifest");function Fee(e){try{let t=JSON.parse(e);return t.version!==tM||typeof t.portta!="string"||typeof t.created!="string"||typeof t.host!="string"?null:t}catch{return null}}i(Fee,"parseManifest");async function YL(e){let t=await _("docker",["inspect","-f","{{.State.Running}}",e],{reject:!1});return!t.failed&&t.stdout.trim()==="true"}i(YL,"containerRunning");async function Bee(e,t){let n=Mt(e.root);if(!Dt(n))return!1;let r=await _("sh",["-c","command -v sqlite3"],{reject:!1}),
1506
+ o=r.stdout.trim();return r.failed||!o||(await _(o,[n,`VACUUM INTO '${t.replaceAll("'","''")}'`],{reject:!1})).failed||!Dt(t)?!1:(zr(t,384),!0)}i(Bee,"dumpDatabase");async function rM(e,t){let n=Ww(t),r=new A(n),o=E({profile:n.profile}),s=new Date().toISOString().replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z"),a=e.output??ve(o.root,`portta-backup-${s}.tar.gz`),c=XL(ve(QL(),"portta-backup-"));zr(c,448);try{Lee(ve(c,"portta-backup.json"),zee({version:tM,portta:o.version,created:new Date().toISOString().
1507
+ replace(/\.\d+Z$/,"Z"),host:Mee()||"unknown"}));let u=nM(o.root);for(let h of u)cd(ve(c,"tree",eM(h)),{recursive:!0}),Zw(ve(o.root,h),ve(c,"tree",h),{recursive:!0});let p=!1;e.database!==!1&&(p=await Bee(o,ve(c,"panel.db")),p||(r.warning("the panel database was not included"),r.hint("it exists once the panel has started, and copying it needs sqlite3 on this host; --no-database silences this")));let d=process.umask(63),f;try{f=await _("tar",["-czf",a,"-C",c,"."],{reject:!1})}finally{process.umask(
1508
+ d)}if(f.failed)throw new L(`could not write ${a}`,f.stderr.trim());let m=Nee(a).size;if(r.json){r.data({file:a,size:m,paths:u,database:p});return}r.progress("backup written"),r.line(` file ${a}`),r.line(` size ${Uee(m)}`),r.line(` contents ${u.length} path(s)${p?" + database":""}`),r.line(""),r.warning("this archive contains credentials: .env, the panel password hash and any tokens")}finally{Gw(c,{recursive:!0,force:!0})}}i(rM,"backupCommand");function Uee(e){let t=["B","K","M","G",
1509
+ "T"],n=e,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r+=1;return`${r===0?n:n.toFixed(1)}${t[r]}`}i(Uee,"humanSize");async function oM(e,t,n){let r=Ww(n),o=new A(r),s=E({profile:r.profile});if(!e)throw new C("which backup?","portta restore <file>");if(!Dt(e))throw new C(`no such file: ${e}`);let a=XL(ve(QL(),"portta-restore-"));zr(a,448);try{if((await _("tar",["-xzf",e,"-C",a],{reject:!1})).failed)throw new C("that file is not a Portta backup");let u=ve(a,"portta-backup.json");if(!Dt(u))throw new C("\
1510
+ that archive has no Portta manifest");let p=Fee(Dee(u,"utf8"));if(!p)throw new C("that archive has an unreadable Portta manifest");if(o.progress(`restoring a backup taken from Portta ${p.portta}`),!t.force&&await YL(`${s.env.PORTTA_PROJECT_NAME||"portta"}-traefik-1`))throw new L("the gateway is running","portta down, then restore; or pass --force to replace configuration underneath it");let d=new Date().toISOString().replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z"),f=ve(s.root,"state",`restore-${d}`);
1511
1511
  cd(f,{recursive:!0});for(let b of[".env","config"])Dt(ve(s.root,b))&&Zw(ve(s.root,b),ve(f,b),{recursive:!0});o.progress(`kept what was there under ${f}`);let m=ve(a,"tree");if(Dt(m)){for(let b of nM(m))Zw(ve(m,b),ve(s.root,b),{recursive:!0,force:!0});o.progress("configuration and state restored")}Dt(ve(s.root,".env"))&&zr(ve(s.root,".env"),384);let h=ve(a,"panel.db");if(Dt(h)){let b=await YL(`${s.env.PORTTA_PROJECT_NAME||"portta"}-web-1`),g=Mt(s.root);if(b)o.warning("the panel is running, so its\
1512
- database was not replaced"),o.hint(`portta web down then: portta restore ${e} --force`);else{cd(eM(g),{recursive:!0});for(let y of or(g))Gw(y,{force:!0});jee(h,g),zr(g,384),o.progress("panel database restored")}}o.line(""),o.progress("restore complete"),o.hint("portta up then portta doctor")}finally{Gw(a,{recursive:!0,force:!0})}}i(oM,"restoreCommand");var Uee=[{path:".env",mode:384},{path:"state/traefik/acme",mode:448},{path:"state/traefik/acme/acme.json",mode:384},{path:"state/cloudflar\
1513
- ed",mode:448},{path:"state/cloudflared/credentials.json",mode:384},{path:"state/runner",mode:448},{path:"state/ssh",mode:448},{path:"state/auth",mode:448}];async function sM(e,t){let n=Ww(t),r=new A(n),o=E({profile:n.profile}),s=e.dryRun??!1,a=[];r.progress("Repair");for(let{path:p,mode:d}of zy){let f=ve(o.root,p);if(!Dt(f)){if(a.push(`create ${p}`),s){r.line(` would create ${p}`);continue}cd(f,{recursive:!0}),zr(f,d),r.progress(`created ${p}`)}}for(let{path:p,mode:d}of Uee){let f=ve(o.root,p);
1512
+ database was not replaced"),o.hint(`portta web down then: portta restore ${e} --force`);else{cd(eM(g),{recursive:!0});for(let y of or(g))Gw(y,{force:!0});Iee(h,g),zr(g,384),o.progress("panel database restored")}}o.line(""),o.progress("restore complete"),o.hint("portta up then portta doctor")}finally{Gw(a,{recursive:!0,force:!0})}}i(oM,"restoreCommand");var qee=[{path:".env",mode:384},{path:"state/traefik/acme",mode:448},{path:"state/traefik/acme/acme.json",mode:384},{path:"state/cloudflar\
1513
+ ed",mode:448},{path:"state/cloudflared/credentials.json",mode:384},{path:"state/runner",mode:448},{path:"state/ssh",mode:448},{path:"state/auth",mode:448}];async function sM(e,t){let n=Ww(t),r=new A(n),o=E({profile:n.profile}),s=e.dryRun??!1,a=[];r.progress("Repair");for(let{path:p,mode:d}of zy){let f=ve(o.root,p);if(!Dt(f)){if(a.push(`create ${p}`),s){r.line(` would create ${p}`);continue}cd(f,{recursive:!0}),zr(f,d),r.progress(`created ${p}`)}}for(let{path:p,mode:d}of qee){let f=ve(o.root,p);
1514
1514
  if(!Dt(f))continue;let m=Yn(f),h=d.toString(8);if(!(!m||m===h)){if(a.push(`chmod ${p} ${h}`),s){r.line(` would change ${p} from ${m} to ${h}`);continue}zr(f,d),r.progress(`${p} is now ${h} (was ${m})`)}}let c=[o.env.PORTTA_NETWORK||"portta"];re(o.env.PORTTA_TCP)&&c.push(o.env.PORTTA_ACCESS_NETWORK||"portta-access");for(let p of c){if(!(await _("docker",["network","inspect",p],{reject:!1})).failed)continue;if(a.push(`create network ${p}`),s){r.line(` would create network ${p}`);continue}(await _(
1515
1515
  "docker",["network","create","--label","portta.managed=true",p],{reject:!1})).failed?r.warning(`could not create network ${p}`):r.progress(`created network ${p}`)}if(s){if(r.line(""),r.json){r.data({dryRun:!0,changes:a});return}r.progress(a.length===0?"nothing to repair":`${a.length} thing(s) would be repaired`);return}if(r.progress("reconciling containers"),(await _("docker",["compose",...we(o),"up","-d","--remove-orphans"],{cwd:o.root,env:o.env,stdio:"inherit",reject:!1})).failed)throw new L("\
1516
- the gateway did not come up","portta doctor");if(r.line(""),r.json){r.data({dryRun:!1,changes:a});return}r.progress(a.length===0?"nothing needed repairing; containers reconciled":`${a.length} thing(s) repaired; containers reconciled`),r.hint("portta doctor confirms the result")}i(sM,"repairCommand");import{lookup as qee}from"node:dns/promises";import{join as Hee}from"node:path";function Qn(e){return e.optsWithGlobals()}i(Qn,"globals");async function iM(e,t){let n=Qn(t),r=E({profile:n.profile}),s=(await J()).flatMap(p=>p.ports.filter(d=>d.publicPort!==null).map(d=>({container:p.name,ip:d.ip,hostPort:d.publicPort,containerPort:d.privatePort,protocol:d.type}))),a=null;if(e.publicIp)try{let p=await fetch("https://api.ipify.org",{signal:AbortSignal.timeout(3e3)});a=p.ok?await p.text():null}catch{}let c={instance:{name:r.config.projectName},bindAddress:r.config.bindAddress,publicIp:a,
1516
+ the gateway did not come up","portta doctor");if(r.line(""),r.json){r.data({dryRun:!1,changes:a});return}r.progress(a.length===0?"nothing needed repairing; containers reconciled":`${a.length} thing(s) repaired; containers reconciled`),r.hint("portta doctor confirms the result")}i(sM,"repairCommand");import{lookup as Hee}from"node:dns/promises";import{join as Zee}from"node:path";function Qn(e){return e.optsWithGlobals()}i(Qn,"globals");async function iM(e,t){let n=Qn(t),r=E({profile:n.profile}),s=(await J()).flatMap(p=>p.ports.filter(d=>d.publicPort!==null).map(d=>({container:p.name,ip:d.ip,hostPort:d.publicPort,containerPort:d.privatePort,protocol:d.type}))),a=null;if(e.publicIp)try{let p=await fetch("https://api.ipify.org",{signal:AbortSignal.timeout(3e3)});a=p.ok?await p.text():null}catch{}let c={instance:{name:r.config.projectName},bindAddress:r.config.bindAddress,publicIp:a,
1517
1517
  bindings:s,publicBindings:s.filter(p=>["0.0.0.0","::"].includes(p.ip))},u=new A(n);if(u.json)u.data(c);else{u.line(`gateway bind: ${c.bindAddress}`),a&&u.line(`public ip: ${a}`);for(let p of s)u.line(`${p.ip}:${p.hostPort} ${p.container} ${p.containerPort}/${p.protocol}`)}}i(iM,"networkStatus");async function aM(e){let t=Qn(e),n=E({profile:t.profile}),r={enabled:n.config.publicEnabled,profile:n.config.profile,domain:n.config.publicDomain,bindAddress:n.config.bindAddress},o=new A(t);o.json?o.data(
1518
- r):o.line(r.enabled?`enabled on ${r.domain??"<unset>"}`:"disabled")}i(aM,"publicStatus");async function Ca(e,t,n){let r=E({profile:Qn(n).profile}),o=Hee(r.root,".env");je(o,{[e]:t})}i(Ca,"writeSetting");async function cM(e){let t=Qn(e),n=E({profile:t.profile}),r=n.config.publicDomain??(n.config.domainMode!=="local"&&n.config.domain!=="localhost"?n.config.domain:null);if(!r)throw new L("public access needs a domain, and this host has only localhost","portta config set domain.mode auto derives o\
1518
+ r):o.line(r.enabled?`enabled on ${r.domain??"<unset>"}`:"disabled")}i(aM,"publicStatus");async function Ca(e,t,n){let r=E({profile:Qn(n).profile}),o=Zee(r.root,".env");je(o,{[e]:t})}i(Ca,"writeSetting");async function cM(e){let t=Qn(e),n=E({profile:t.profile}),r=n.config.publicDomain??(n.config.domainMode!=="local"&&n.config.domain!=="localhost"?n.config.domain:null);if(!r)throw new L("public access needs a domain, and this host has only localhost","portta config set domain.mode auto derives o\
1519
1519
  ne from this host's address");if(n.config.tcpEnabled)throw new U("public access cannot be enabled while TCP entrypoints are active");let o=On(await J(!0));if(o.length>0)throw new U(`these running services route with no login gate, so they would be open on a public host: ${o.join(", ")}`,"stop each project (portta runtime down <path>), enable public access, then portta adopt and portta runtime up it again");await et(`serve this host's HTTP services on *.${r} over the internet? Each site stays clo\
1520
1520
  sed until you decide who may open it`,t.yes===!0),await Ca("PUBLIC_ENABLED","true",e),n.config.publicDomain||await Ca("PUBLIC_DOMAIN",r,e),await Ca("PORTTA_PROFILE","remote-public",e);let s=E({profile:"remote-public"});await _("docker",["compose",...we(s),"up","-d"],{cwd:s.root,env:s.env,stdio:"inherit"})}i(cM,"publicEnable");async function lM(e){await Ca("PUBLIC_ENABLED","false",e),await Ca("PORTTA_PROFILE","remote-private",e),new A(Qn(e)).progress("public access disabled; run portta up to appl\
1521
- y the private profile")}i(lM,"publicDisable");async function Zee(e){try{return[...new Set((await qee(e,{all:!0})).map(t=>t.address))]}catch{return[]}}i(Zee,"resolved");async function uM(e){let t=Qn(e),n=E({profile:t.profile}),r=n.config.publicDomain??n.config.privateDomain??n.config.domain,o=`probe.${r}`,s=await Zee(o),a={domain:r,hostname:o,addresses:s,resolves:s.length>0},c=new A(t);if(c.json?c.data(a):c.line(a.resolves?`${o} -> ${s.join(", ")}`:`${o} does not resolve`),!a.resolves)throw new L(
1521
+ y the private profile")}i(lM,"publicDisable");async function Gee(e){try{return[...new Set((await Hee(e,{all:!0})).map(t=>t.address))]}catch{return[]}}i(Gee,"resolved");async function uM(e){let t=Qn(e),n=E({profile:t.profile}),r=n.config.publicDomain??n.config.privateDomain??n.config.domain,o=`probe.${r}`,s=await Gee(o),a={domain:r,hostname:o,addresses:s,resolves:s.length>0},c=new A(t);if(c.json?c.data(a):c.line(a.resolves?`${o} -> ${s.join(", ")}`:`${o} does not resolve`),!a.resolves)throw new L(
1522
1522
  `wildcard DNS does not resolve for ${r}`)}i(uM,"dnsCheck");async function pM(e){let t=Qn(e),n=E({profile:t.profile}),r={enabled:n.env.CLOUDFLARE_ENABLED==="true",zone:n.env.CLOUDFLARE_ZONE??null,domain:n.config.publicDomain??n.config.privateDomain??n.config.domain,tokenSet:!!n.env.CLOUDFLARE_API_TOKEN},o=new A(t);if(o.json)o.data(r);else for(let[s,a]of Object.entries(r))o.line(`${s}: ${String(a)}`)}i(pM,"dnsStatus");async function Vw(e,t,n){let r=await fetch(`https://api.cloudflare.com/client/v4${e}`,
1523
1523
  {...n,headers:{authorization:`Bearer ${t}`,"content-type":"application/json",...n?.headers??{}},signal:AbortSignal.timeout(1e4)}),o=await r.json();if(!r.ok||!o.success)throw new L(o.errors?.[0]?.message??`Cloudflare returned HTTP ${r.status}`);return o.result}i(Vw,"cloudflare");async function dM(e,t){let n=Qn(t),r=E({profile:n.profile}),o=r.env.CLOUDFLARE_ZONE,s=r.env.CLOUDFLARE_API_TOKEN,a=r.config.publicDomain??r.config.privateDomain;if(!o||!a)throw new L("CLOUDFLARE_ZONE and PUBLIC_DOMAIN or \
1524
1524
  PRIVATE_DOMAIN are required");let c=e.target;if(!c)throw new C("--target <ip> is required");let u={type:"A",name:`*.${a}`,content:c,ttl:1,proxied:!1},p=new A(n);if(e.dryRun||!s){if(p.data(u),!s&&!e.dryRun)throw new L("CLOUDFLARE_API_TOKEN is not set","create the printed record manually or set a scoped Zone:DNS:Edit token");return}await et(`create or update ${u.name} -> ${c} in Cloudflare?`,n.yes===!0);let d=await Vw(`/zones?name=${encodeURIComponent(o)}`,s);if(!d[0])throw new L(`Cloudflare zone \
@@ -1526,38 +1526,38 @@ not found: ${o}`);let f=await Vw(`/zones/${d[0].id}/dns_records?type=A&name=${en
1526
1526
  ts/${ns(e)}`);if(r.json)return r.data(o);if(r.line(`${o.name} (${o.slug})${o.archived?" \xB7 archived":""}`),o.description&&r.line(` ${o.description}`),o.resolvedPath&&r.line(` ${o.resolvedPath} \xB7 ${o.location}`),o.environments.length>0){r.line(" environments:");for(let s of o.environments)r.line(` ${s.environment.padEnd(24)} ${s.running?`${s.runningCount}/${s.serviceCount} running`:"stopped"}${s.unhealthyCount?` \xB7 ${s.unhealthyCount} unhealthy`:""} [${s.source}]`)}}i(mM,"projectsSh\
1527
1527
  ow");async function hM(e,t){let{client:n,output:r}=de(t),o=e.name??e.slug,s=e.slug??o?.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),a=await n.request("POST","/projects",{slug:s,name:o,description:e.description??null,...e.path?{relativePath:e.path}:{}});if(r.json)return r.data(a);r.progress(`created ${a.name} (${a.slug})`)}i(hM,"projectsCreate");async function gM(e,t){let{client:n,output:r}=de(t),o=await n.request("GET",`/projects/${ns(e)}/resources`);if(r.json)return r.data(o);o.
1528
1528
  collectorActive||r.warning("the metrics collector is not running: `portta host watch`");let s=i(c=>c===null?"-":`${Math.round(c/1048576)} MB`,"mb"),a=i(c=>c===null?"-":`${Math.round(c)}%`,"pct");r.line(`${o.project}: CPU ${a(o.cpuUtilisation)} \xB7 RAM ${s(o.memoryUsedBytes)}${o.stale?" (stale)":""}`);for(let c of o.environments){r.line(` ${c.environment}: CPU ${a(c.cpuUtilisation)} \xB7 RAM ${s(c.memoryUsedBytes)}`);for(let u of c.containers)r.line(` ${(u.service??u.name).padEnd(20)} ${a(u.
1529
- cpuUtilisation).padStart(5)} ${s(u.memoryUsedBytes)}`)}}i(gM,"projectsResources");async function bM(e,t,n){let{client:r,output:o}=de(n),s=await r.request("GET",`/environments/${ns(e)}/logs${oD({service:t.service,tail:t.tail})}`);if(o.json)return o.data(s);for(let a of s.lines)o.line(`${a.service.padEnd(12)} | ${a.line}`)}i(bM,"envLogs");import{readFileSync as Gee}from"node:fs";function xn(e){return e.optsWithGlobals()}i(xn,"globals");function yM(e,t){let n=t??(E({profile:xn(e).profile}).config.tlsEnabled?"websecure":"web");if(!/^[A-Za-z0-9_-]+$/.test(n))throw new C(`invalid entrypoint: ${n}`);return n}i(yM,"entryPointFor");function Kw(e){if(!e)return null;let{hash:t,...n}=e;return n}i(Kw,"publicRecord");async function wM(e,t,n){let r=dt(e);if(t.passwordOnly===!0&&t.user!==void 0)throw new C("--password-only and --user ask for opposite things: pick one");let o=t.passwordOnly===
1530
- !0?null:t.user??"reviewer";if(o!==null&&!/^[A-Za-z0-9._-]{1,64}$/.test(o))throw new C(`invalid username: ${o}`);let s=yM(n,t.entrypoint),a=t.passwordStdin!==!0,c=a?rp():Gee(0,"utf8").trim();if(!c)throw new C("no password on stdin");let u=E({profile:xn(n).profile}),p=u.root,d=await op(Ze(Er(p).store),{host:r,entryPoint:s,user:o,password:c,...t.label?{label:t.label}:{},...t.project?{project:t.project}:{},...t.service?{service:t.service}:{}});Jo(p,d,u.config.profile);let f=new A(xn(n)),m={protection:Kw(
1529
+ cpuUtilisation).padStart(5)} ${s(u.memoryUsedBytes)}`)}}i(gM,"projectsResources");async function bM(e,t,n){let{client:r,output:o}=de(n),s=await r.request("GET",`/environments/${ns(e)}/logs${oD({service:t.service,tail:t.tail})}`);if(o.json)return o.data(s);for(let a of s.lines)o.line(`${a.service.padEnd(12)} | ${a.line}`)}i(bM,"envLogs");import{readFileSync as Wee}from"node:fs";function xn(e){return e.optsWithGlobals()}i(xn,"globals");function yM(e,t){let n=t??(E({profile:xn(e).profile}).config.tlsEnabled?"websecure":"web");if(!/^[A-Za-z0-9_-]+$/.test(n))throw new C(`invalid entrypoint: ${n}`);return n}i(yM,"entryPointFor");function Kw(e){if(!e)return null;let{hash:t,...n}=e;return n}i(Kw,"publicRecord");async function wM(e,t,n){let r=dt(e);if(t.passwordOnly===!0&&t.user!==void 0)throw new C("--password-only and --user ask for opposite things: pick one");let o=t.passwordOnly===
1530
+ !0?null:t.user??"reviewer";if(o!==null&&!/^[A-Za-z0-9._-]{1,64}$/.test(o))throw new C(`invalid username: ${o}`);let s=yM(n,t.entrypoint),a=t.passwordStdin!==!0,c=a?rp():Wee(0,"utf8").trim();if(!c)throw new C("no password on stdin");let u=E({profile:xn(n).profile}),p=u.root,d=await op(Ze(Er(p).store),{host:r,entryPoint:s,user:o,password:c,...t.label?{label:t.label}:{},...t.project?{project:t.project}:{},...t.service?{service:t.service}:{}});Jo(p,d,u.config.profile);let f=new A(xn(n)),m={protection:Kw(
1531
1531
  Ge(d,r)),generated:a,...a?{password:c}:{}};f.json?f.data(m):(f.line(`protected: ${r}`),f.line(o===null?"password only: no username is asked for":`user: ${o}`),a&&(f.line(`password: ${c}`),f.warning("this is the only time the generated password is shown")),f.hint("on a public host this takes effect at once; elsewhere add portta-forward-auth@file to the router"))}i(wM,"protectHost");async function vM(e,t,n){let r=dt(e),o=E({profile:xn(n).profile}),s=o.root,a=sp(Ze(Er(s).store),{host:r,entryPoint:yM(
1532
1532
  n,t.entrypoint),...t.label?{label:t.label}:{},...t.project?{project:t.project}:{},...t.service?{service:t.service}:{}});Jo(s,a,o.config.profile);let c=new A(xn(n));c.json?c.data({protection:Kw(Ge(a,r))}):(c.line(`open to everybody: ${r}`),c.warning("no login is asked for this host; `portta protect host` puts one back"))}i(vM,"openHost");async function SM(e,t){let n=dt(e),r=E({profile:xn(t).profile}),o=r.root,s=mI(Ze(Er(o).store),n);if(!s)throw new C(`host has no protection record: ${n}`);Jo(o,s,
1533
- r.config.profile),new A(xn(t)).progress(`removed the record for ${n}; on a public host it is now closed`)}i(SM,"unprotectHost");async function xM(e,t){let r=E({profile:xn(t).profile}).root,o=Ze(Er(r).store),a=(e?[Ge(o,dt(e))].filter(u=>u!==null):o.protections).map(Kw),c=new A(xn(t));if(c.json)c.data({protections:a});else if(!a.length)c.progress("no matching hosts");else for(let u of a)c.line(`${u.host} ${u.mode} ${u.user??"-"} ${u.scope} epoch ${u.epoch}`)}i(xM,"protectStatus");import{isIP as Wee}from"node:net";import{join as Vee}from"node:path";var kM=/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$/,Kee=/^[^\s@,;'"]+@[^\s@,;'"]+\.[^\s@,;'"]+$/;async function Jee(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}i(Jee,"readFirstLine");async function Yee(e){let t=((await e()).split(/\r?\n/)[0]??"").trim();if(!t)throw new C("--cloudflare-token-stdin was given but standard input held no token");if(/[\s"'#\\]/.test(t))throw new C("the token on standard in\
1534
- put is not a valid API token");return t}i(Yee,"readToken");function Xee(e){let t=e.domain;if(!t)throw new C("--domain is required","portta public init --domain example.com --email you@example.com");if(!kM.test(t))throw new C(`--domain must be a lowercase hostname with a dot, such as example.com: ${t}`);let n=e.email;if(!n)throw new C("--email is required (the ACME contact)");if(!Kee.test(n))throw new C(`--email is not an email address: ${n}`);let r=e.panelHost??t;if(!kM.test(r))throw new C(`--pa\
1535
- nel-host must be a lowercase hostname: ${r}`);if(r!==t&&(!r.endsWith(`.${t}`)||r.split(".").length!==t.split(".").length+1))throw new C(`--panel-host must be ${t} or one label under it, covered by *.${t}: ${r}`);let o=e.ip===void 0?0:Wee(e.ip);if(e.ip!==void 0&&o===0)throw new C(`--ip is not an IPv4 or IPv6 address: ${e.ip}`);let s=o===6?"AAAA":"A",a=e.ip??"<server-ip>";return{panelHost:r,values:{PORTTA_PROFILE:"remote-public",PUBLIC_ENABLED:"true",PUBLIC_DOMAIN:t,PORTTA_DOMAIN_MODE:"custom",PORTTA_DOMAIN:t,
1536
- TLS_ENABLED:"true",TLS_MODE:"acme",ACME_EMAIL:n,ACME_DNS_PROVIDER:"cloudflare",PORTTA_WEB:"true",PORTTA_WEB_EXPOSE:"domain",PORTTA_PANEL_ADVERTISED_HOST:r,PORTTA_PANEL_URL:`https://${r}`,PORTTA_AUTH_MODE:"required"},records:[{type:s,name:t,content:a,proxied:!1},{type:s,name:`*.${t}`,content:a,proxied:!1}]}}i(Xee,"planPublicInit");async function _M(e,t,n={}){let r=t.optsWithGlobals(),o=Xee(e),s=e.cloudflareTokenStdin?await Yee(n.readStdin??Jee):void 0,a=E({profile:r.profile}),c=e.dryRun===!0;if(a.
1537
- config.tcpEnabled)throw new U("public access cannot be configured while TCP entrypoints are active");let u=[];try{u=await J(!0)}catch(w){if(!c)throw w}let p=On(u);if(p.length>0)throw new U(`these running services route with no login gate, so they would be open on a public host: ${p.join(", ")}`,"stop each project (portta runtime down <path>), configure public access, then portta adopt and portta runtime up it again");let d=Vee(a.root,".env"),f=me(An(d)),m=s===void 0?o.values:{...o.values,CF_DNS_API_TOKEN:s},
1533
+ r.config.profile),new A(xn(t)).progress(`removed the record for ${n}; on a public host it is now closed`)}i(SM,"unprotectHost");async function xM(e,t){let r=E({profile:xn(t).profile}).root,o=Ze(Er(r).store),a=(e?[Ge(o,dt(e))].filter(u=>u!==null):o.protections).map(Kw),c=new A(xn(t));if(c.json)c.data({protections:a});else if(!a.length)c.progress("no matching hosts");else for(let u of a)c.line(`${u.host} ${u.mode} ${u.user??"-"} ${u.scope} epoch ${u.epoch}`)}i(xM,"protectStatus");import{isIP as Vee}from"node:net";import{join as Kee}from"node:path";var kM=/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$/,Jee=/^[^\s@,;'"]+@[^\s@,;'"]+\.[^\s@,;'"]+$/;async function Yee(){let e=[];for await(let t of process.stdin)e.push(Buffer.from(t));return Buffer.concat(e).toString("utf8")}i(Yee,"readFirstLine");async function Xee(e){let t=((await e()).split(/\r?\n/)[0]??"").trim();if(!t)throw new C("--cloudflare-token-stdin was given but standard input held no token");if(/[\s"'#\\]/.test(t))throw new C("the token on standard in\
1534
+ put is not a valid API token");return t}i(Xee,"readToken");function Qee(e){let t=e.domain;if(!t)throw new C("--domain is required","portta public init --domain example.com --email you@example.com");if(!kM.test(t))throw new C(`--domain must be a lowercase hostname with a dot, such as example.com: ${t}`);let n=e.email;if(!n)throw new C("--email is required (the ACME contact)");if(!Jee.test(n))throw new C(`--email is not an email address: ${n}`);let r=e.panelHost??t;if(!kM.test(r))throw new C(`--pa\
1535
+ nel-host must be a lowercase hostname: ${r}`);if(r!==t&&(!r.endsWith(`.${t}`)||r.split(".").length!==t.split(".").length+1))throw new C(`--panel-host must be ${t} or one label under it, covered by *.${t}: ${r}`);let o=e.ip===void 0?0:Vee(e.ip);if(e.ip!==void 0&&o===0)throw new C(`--ip is not an IPv4 or IPv6 address: ${e.ip}`);let s=o===6?"AAAA":"A",a=e.ip??"<server-ip>";return{panelHost:r,values:{PORTTA_PROFILE:"remote-public",PUBLIC_ENABLED:"true",PUBLIC_DOMAIN:t,PORTTA_DOMAIN_MODE:"custom",PORTTA_DOMAIN:t,
1536
+ TLS_ENABLED:"true",TLS_MODE:"acme",ACME_EMAIL:n,ACME_DNS_PROVIDER:"cloudflare",PORTTA_WEB:"true",PORTTA_WEB_EXPOSE:"domain",PORTTA_PANEL_ADVERTISED_HOST:r,PORTTA_PANEL_URL:`https://${r}`,PORTTA_AUTH_MODE:"required"},records:[{type:s,name:t,content:a,proxied:!1},{type:s,name:`*.${t}`,content:a,proxied:!1}]}}i(Qee,"planPublicInit");async function _M(e,t,n={}){let r=t.optsWithGlobals(),o=Qee(e),s=e.cloudflareTokenStdin?await Xee(n.readStdin??Yee):void 0,a=E({profile:r.profile}),c=e.dryRun===!0;if(a.
1537
+ config.tcpEnabled)throw new U("public access cannot be configured while TCP entrypoints are active");let u=[];try{u=await J(!0)}catch(w){if(!c)throw w}let p=On(u);if(p.length>0)throw new U(`these running services route with no login gate, so they would be open on a public host: ${p.join(", ")}`,"stop each project (portta runtime down <path>), configure public access, then portta adopt and portta runtime up it again");let d=Kee(a.root,".env"),f=me(An(d)),m=s===void 0?o.values:{...o.values,CF_DNS_API_TOKEN:s},
1538
1538
  h=Object.entries(m).filter(([w,P])=>f.get(w)!==P).map(([w])=>w),b=s!==void 0||!!f.get("CF_DNS_API_TOKEN");c||(await et(`write the public-server settings for ${o.values.PUBLIC_DOMAIN} to ${d}? Nothing is started`,r.yes===!0),h.length>0&&je(d,m));let g=new A(r),y={domain:o.values.PUBLIC_DOMAIN,panelHost:o.panelHost,dryRun:c,written:c?!1:h.length>0,keys:h,tokenSet:b,records:o.records,tokenPermission:"Zone, DNS, Edit on the zone",next:["portta up remote-public","portta dns check",`printf %s "$PASSWO\
1539
1539
  RD" | portta auth bootstrap --url https://${o.panelHost} --allow-remote --name <name> --email <email> --password-stdin`,"portta doctor"]};if(g.json){g.data(y);return}g.line(c?"dry run: nothing was written":h.length>0?`wrote ${d}`:"already configured; nothing changed"),g.line(`${c?"would set":"keys"}: ${h.length>0?h.join(", "):"(none)"}`),g.line(),g.line("DNS records to create (DNS only, not proxied):");for(let w of o.records)g.line(` ${w.type} ${w.name} ${w.content}`);g.line(),g.line("Cloudflar\
1540
1540
  e token permission: Zone, DNS, Edit on the zone"),b||g.line("CF_DNS_API_TOKEN is not set: put the token in .env or rerun with --cloudflare-token-stdin"),g.line(),g.line("Create the owner as soon as DNS and the certificate answer, before sharing the address: until it"),g.line("exists, whoever reaches the panel first can claim it at /setup. In this mode the panel has no"),g.line("loopback port, so the command goes through its own https address."),g.line(),g.line("Next:");for(let w of y.next)g.line(
1541
- ` ${w}`)}i(_M,"publicInit");import{realpathSync as Qee}from"node:fs";import{resolve as AM}from"node:path";function ld(e){try{return Qee(e)}catch{return null}}i(ld,"safeRealpath");async function PM(e,t){let n=await _("git",["-C",e,...t],{reject:!1});return n.exitCode===0?n.stdout.trim():null}i(PM,"git");async function ete(e){let t=await PM(e,["rev-parse","--show-toplevel"]),n=t?ld(t):null,r=null;if(n){let o=await PM(e,["rev-parse","--git-common-dir"]);o&&(r=ld(AM(e,o,"..")))}return{path:e,gitRoot:n,commonRoot:r}}i(ete,"pathFacts");function tte(e,t){return e===t||e.startsWith(`${t}/`)}i(tte,"inside");
1542
- function nte(e,t){return e.path===t?"root":tte(e.path,t)?"subdirectory":e.commonRoot===t&&e.gitRoot!==t?"worktree":null}i(nte,"basisOf");async function rte(e){let t=await e.request("GET","/projects");return Promise.all(t.projects.map(n=>e.request("GET",`/projects/${ns(n.slug)}`)))}i(rte,"registeredProjects");async function ote(e,t){let n=AM(e),r=ld(n);if(!r)throw new C(`${n} does not exist on this host`,"pass an absolute path to a directory that exists");let o=await ete(r),s;try{s=await rte(t)}catch(d){
1543
- if(d instanceof _e&&d.exitCode===Fe.refused)return Jw(r,"unauthorized",d.message,d.hint??"sign in with `portta auth login`, or ask for access to the Project",[]);throw d}let a=[];for(let d of s){let f=d.resolvedPath?ld(d.resolvedPath):null;if(!f)continue;let m=nte(o,f);m&&a.push({project:d,path:f,basis:m})}if(a.length===0)return Jw(r,"unknown",`${r} belongs to no Project the panel knows`,"create the Project with `portta projects create --path <dir>`, or check `portta projects list`",[]);let c=Math.
1541
+ ` ${w}`)}i(_M,"publicInit");import{realpathSync as ete}from"node:fs";import{resolve as AM}from"node:path";function ld(e){try{return ete(e)}catch{return null}}i(ld,"safeRealpath");async function PM(e,t){let n=await _("git",["-C",e,...t],{reject:!1});return n.exitCode===0?n.stdout.trim():null}i(PM,"git");async function tte(e){let t=await PM(e,["rev-parse","--show-toplevel"]),n=t?ld(t):null,r=null;if(n){let o=await PM(e,["rev-parse","--git-common-dir"]);o&&(r=ld(AM(e,o,"..")))}return{path:e,gitRoot:n,commonRoot:r}}i(tte,"pathFacts");function nte(e,t){return e===t||e.startsWith(`${t}/`)}i(nte,"inside");
1542
+ function rte(e,t){return e.path===t?"root":nte(e.path,t)?"subdirectory":e.commonRoot===t&&e.gitRoot!==t?"worktree":null}i(rte,"basisOf");async function ote(e){let t=await e.request("GET","/projects");return Promise.all(t.projects.map(n=>e.request("GET",`/projects/${ns(n.slug)}`)))}i(ote,"registeredProjects");async function ste(e,t){let n=AM(e),r=ld(n);if(!r)throw new C(`${n} does not exist on this host`,"pass an absolute path to a directory that exists");let o=await tte(r),s;try{s=await ote(t)}catch(d){
1543
+ if(d instanceof _e&&d.exitCode===Fe.refused)return Jw(r,"unauthorized",d.message,d.hint??"sign in with `portta auth login`, or ask for access to the Project",[]);throw d}let a=[];for(let d of s){let f=d.resolvedPath?ld(d.resolvedPath):null;if(!f)continue;let m=rte(o,f);m&&a.push({project:d,path:f,basis:m})}if(a.length===0)return Jw(r,"unknown",`${r} belongs to no Project the panel knows`,"create the Project with `portta projects create --path <dir>`, or check `portta projects list`",[]);let c=Math.
1544
1544
  max(...a.map(d=>d.path.length)),u=a.filter(d=>d.path.length===c);if(u.length>1)return Jw(r,"ambiguous",`${r} could belong to ${u.map(d=>d.project.slug).join(" or ")}; nothing was chosen`,"name the Project explicitly, or fix the duplicate directory in the panel",u.map(d=>({slug:d.project.slug,path:d.path,basis:d.basis})));let p=u[0];return{resolved:!0,path:r,basis:p.basis,project:{id:p.project.id,slug:p.project.slug,name:p.project.name,path:p.path},worktree:p.basis==="worktree"&&o.gitRoot&&o.commonRoot?
1545
- {path:o.gitRoot,mainPath:o.commonRoot}:null}}i(ote,"resolvePath");function Jw(e,t,n,r,o){return{resolved:!1,path:e,error:{kind:t,message:n,hint:r,candidates:o}}}i(Jw,"failure");var EM={unknown:Fe.failure,ambiguous:Fe.failure,unauthorized:Fe.refused};function ste(e,t){if(e.json){e.data(t),t.resolved||(process.exitCode=EM[t.error.kind]);return}if(!t.resolved){e.error(`${t.error.kind}: ${t.error.message}`);for(let n of t.error.candidates)e.line(` ${n.slug.padEnd(20)} ${n.path} [${n.basis}]`);t.error.
1546
- hint&&e.hint(t.error.hint),process.exitCode=EM[t.error.kind];return}e.line(`${t.project.name} (${t.project.slug}) \xB7 by ${t.basis}`),t.worktree&&e.line(` worktree of ${t.worktree.mainPath}`),e.line(` path ${t.project.path}`)}i(ste,"reportOutcome");async function OM(e,t){let{client:n,output:r}=de(t),o=await ote(e.path??process.cwd(),n);ste(r,o)}i(OM,"projectsResolve");import{chmodSync as ite,copyFileSync as ud,cpSync as RM,existsSync as er,mkdirSync as pd,readdirSync as Ra,realpathSync as $M,rmSync as jM,writeFileSync as ate}from"node:fs";import{homedir as TM}from"node:os";import{dirname as cte,join as ge,resolve as bs}from"node:path";import{fileURLToPath as lte}from"node:url";function ute(e){return e.optsWithGlobals()}i(ute,"globals");function Yw(e){return Number(/^v?(\d+)/.exec(e)?.[1]??0)}i(Yw,"major");async function CM(e,t){let n=await _(e,t,{reject:!1});return{ok:n.exitCode===0,value:n.stdout.trim()}}i(CM,"available");function pte(){let e=process.env.PORTTA_RUNTIME_ROOT;if(e)return bs(e);let n=[ge(import.meta.dirname,"runtime"),ge(import.meta.dirname,"..","runtime")].find(r=>er(ge(r,"VERSION")));if(!n)throw new L("the Portta package does not contain its runtime a\
1547
- ssets","reinstall the `@codions/portta` npm package");return n}i(pte,"packagedRuntime");var dte="compose";function fte(e,t){let n=ge(t,"runtime");if(!(er(n)&&$M(e)===$M(n))){for(let r of er(n)?Ra(n):[])r!==dte&&jM(ge(n,r),{recursive:!0,force:!0});RM(e,n,{recursive:!0,force:!0})}}i(fte,"refreshRuntimeCache");function mte(e,t){pd(t,{recursive:!0}),fte(e,t);for(let p of Ra(e)){if(p==="config")continue;let d=ge(t,p);jM(d,{recursive:!0,force:!0}),RM(ge(e,p),d,{recursive:!0,force:!0})}let n=ge(e,"conf\
1548
- ig","traefik","dynamic"),r=ge(t,"config","traefik","dynamic");pd(r,{recursive:!0});for(let p of Ra(n)){let d=ge(r,p);er(d)||ud(ge(n,p),d)}let o=ge(t,"bin");pd(o,{recursive:!0});let s=import.meta.dirname,a=lte(import.meta.url),c=ge(o,"portta");if(bs(a)!==bs(s)){for(let p of Ra(s).filter(d=>d.endsWith(".js")))ud(ge(s,p),ge(o,p));ate(ge(o,"package.json"),`{ "type": "module" }
1549
- `),ud(ge(s,"cli.js"),c)}ite(c,493);let u=ge(s,od);er(u)&&ud(u,ge(o,od))}i(mte,"installRuntime");async function IM(e,t){let n=ute(t),r=new A(n);if(process.platform==="win32")throw new L("setup requires a POSIX host");let o=ih(),s=bs(e.dir??o??ge(TM(),"portta")),a=e.profile??n.profile??"local",c=pte(),u=[],p=i((R,O,x)=>{u.push({step:R,status:O,detail:x}),r.json||r.progress(`${O.padEnd(8)} ${x}`)},"record"),d=process.versions.node;if(Yw(d)<24)throw new L(`Node ${d} is too old`,"Node 24 or newer is \
1545
+ {path:o.gitRoot,mainPath:o.commonRoot}:null}}i(ste,"resolvePath");function Jw(e,t,n,r,o){return{resolved:!1,path:e,error:{kind:t,message:n,hint:r,candidates:o}}}i(Jw,"failure");var EM={unknown:Fe.failure,ambiguous:Fe.failure,unauthorized:Fe.refused};function ite(e,t){if(e.json){e.data(t),t.resolved||(process.exitCode=EM[t.error.kind]);return}if(!t.resolved){e.error(`${t.error.kind}: ${t.error.message}`);for(let n of t.error.candidates)e.line(` ${n.slug.padEnd(20)} ${n.path} [${n.basis}]`);t.error.
1546
+ hint&&e.hint(t.error.hint),process.exitCode=EM[t.error.kind];return}e.line(`${t.project.name} (${t.project.slug}) \xB7 by ${t.basis}`),t.worktree&&e.line(` worktree of ${t.worktree.mainPath}`),e.line(` path ${t.project.path}`)}i(ite,"reportOutcome");async function OM(e,t){let{client:n,output:r}=de(t),o=await ste(e.path??process.cwd(),n);ite(r,o)}i(OM,"projectsResolve");import{chmodSync as ate,copyFileSync as ud,cpSync as RM,existsSync as er,mkdirSync as pd,readdirSync as Ra,realpathSync as $M,rmSync as jM,writeFileSync as cte}from"node:fs";import{homedir as TM}from"node:os";import{dirname as lte,join as ge,resolve as bs}from"node:path";import{fileURLToPath as ute}from"node:url";function pte(e){return e.optsWithGlobals()}i(pte,"globals");function Yw(e){return Number(/^v?(\d+)/.exec(e)?.[1]??0)}i(Yw,"major");async function CM(e,t){let n=await _(e,t,{reject:!1});return{ok:n.exitCode===0,value:n.stdout.trim()}}i(CM,"available");function dte(){let e=process.env.PORTTA_RUNTIME_ROOT;if(e)return bs(e);let n=[ge(import.meta.dirname,"runtime"),ge(import.meta.dirname,"..","runtime")].find(r=>er(ge(r,"VERSION")));if(!n)throw new L("the Portta package does not contain its runtime a\
1547
+ ssets","reinstall the `@codions/portta` npm package");return n}i(dte,"packagedRuntime");var fte="compose";function mte(e,t){let n=ge(t,"runtime");if(!(er(n)&&$M(e)===$M(n))){for(let r of er(n)?Ra(n):[])r!==fte&&jM(ge(n,r),{recursive:!0,force:!0});RM(e,n,{recursive:!0,force:!0})}}i(mte,"refreshRuntimeCache");function hte(e,t){pd(t,{recursive:!0}),mte(e,t);for(let p of Ra(e)){if(p==="config")continue;let d=ge(t,p);jM(d,{recursive:!0,force:!0}),RM(ge(e,p),d,{recursive:!0,force:!0})}let n=ge(e,"conf\
1548
+ ig","traefik","dynamic"),r=ge(t,"config","traefik","dynamic");pd(r,{recursive:!0});for(let p of Ra(n)){let d=ge(r,p);er(d)||ud(ge(n,p),d)}let o=ge(t,"bin");pd(o,{recursive:!0});let s=import.meta.dirname,a=ute(import.meta.url),c=ge(o,"portta");if(bs(a)!==bs(s)){for(let p of Ra(s).filter(d=>d.endsWith(".js")))ud(ge(s,p),ge(o,p));cte(ge(o,"package.json"),`{ "type": "module" }
1549
+ `),ud(ge(s,"cli.js"),c)}ate(c,493);let u=ge(s,od);er(u)&&ud(u,ge(o,od))}i(hte,"installRuntime");async function IM(e,t){let n=pte(t),r=new A(n);if(process.platform==="win32")throw new L("setup requires a POSIX host");let o=ih(),s=bs(e.dir??o??ge(TM(),"portta")),a=e.profile??n.profile??"local",c=dte(),u=[],p=i((R,O,x)=>{u.push({step:R,status:O,detail:x}),r.json||r.progress(`${O.padEnd(8)} ${x}`)},"record"),d=process.versions.node;if(Yw(d)<24)throw new L(`Node ${d} is too old`,"Node 24 or newer is \
1550
1550
  required");p("node","ok",`Node ${d}`),await Ct();let f=await CM("docker",["version","--format","{{.Server.Version}}"]);if(!f.ok||Yw(f.value)<24)throw new L("Docker Engine 24 or newer is required","setup never installs Docker or invokes a system package manager");let m=await CM("docker",["compose","version","--short"]);if(!m.ok||Yw(m.value)<2)throw new L("Docker Compose v2 is required");if(p("docker","ok",`Docker ${f.value}, Compose ${m.value}`),e.dryRun){p("runtime","planned",`install packaged r\
1551
1551
  untime in ${s}`),p("environment","planned",`prepare .env from .env.example in ${s}, keeping set values`),p("network","planned","ensure the shared gateway network"),p("gateway","planned",`pull pinned images and start profile ${a}`),r.json&&r.data({dryRun:!0,target:s,steps:u});return}if(await et(`set up Portta in ${s}?`,n.yes===!0),er(s)&&Ra(s).length>0&&!er(ge(s,"docker","compose","compose.yaml")))throw new U(`${s} exists and is not a Portta installation`,"choose an empty --dir; setup never overw\
1552
- rites an unrelated directory");pd(cte(s),{recursive:!0});let h=er(ge(s,"VERSION"));mte(c,s),p("runtime",h?"updated":"created",`${s}`);let b=ge(s,".env");xt(b),p("environment","updated","environment prepared from .env.example"),rs(s),p("directories","ok","gateway state directories");let g=E({root:s,profile:a}),y=await Zt(g.config.network);p("network",y,`shared network ${g.config.network}`),e.skipPull?p("images","skipped","image pull disabled"):(await _("docker",["compose",...we(g),"pull","--ignor\
1552
+ rites an unrelated directory");pd(lte(s),{recursive:!0});let h=er(ge(s,"VERSION"));hte(c,s),p("runtime",h?"updated":"created",`${s}`);let b=ge(s,".env");xt(b),p("environment","updated","environment prepared from .env.example"),rs(s),p("directories","ok","gateway state directories");let g=E({root:s,profile:a}),y=await Zt(g.config.network);p("network",y,`shared network ${g.config.network}`),e.skipPull?p("images","skipped","image pull disabled"):(await _("docker",["compose",...we(g),"pull","--ignor\
1553
1553
  e-buildable"],{cwd:s,env:g.env}),p("images","ok","pinned images pulled"));let w=me(An(b));await _("docker",["compose",...we(g),"up","-d","--wait","--wait-timeout","180"],{cwd:s,env:g.env}),p("gateway","ok",`gateway up on ${a}`);try{qa(s,w)}catch(R){p("applied","skipped",`could not record the applied settings: ${R.message}`)}if(!(await _("docker",["compose",...we(g),"ps","--status","running","--quiet"],{cwd:s,env:g.env})).stdout.trim())throw new L("gateway started but no component remained runnin\
1554
1554
  g",`run portta doctor inside ${s}`);if(p("doctor","ok","gateway components are running"),r.json){r.data({dryRun:!1,target:s,steps:u});return}r.progress(""),r.progress(`Portta is installed in ${s}.`),bs(s)!==bs(ge(TM(),"portta"))&&r.progress(`Run portta from anywhere with PORTTA_HOME=${s} exported, or from inside that directory.`),r.progress(`The panel is off by default: portta web up starts it on http://127.0.0.1:${g.config.webPort}`),r.progress("portta doctor checks the installation.")}i(IM,"se\
1555
- tupCommand");import{existsSync as hte}from"node:fs";import{join as Xw}from"node:path";var gte=l.object({id:l.string(),mode:l.enum(["public","protected"]),host:l.string(),entryPoint:l.string(),container:l.string(),port:l.number(),expiresAt:l.number(),user:l.string().nullable().optional()}).passthrough();function ja(e){return e.optsWithGlobals()}i(ja,"globals");function DM(e){return Xw(E({profile:ja(e).profile}).root,"config/traefik/dynamic/portta-shares.yaml")}i(DM,"path");function bte(e){return E({profile:ja(e).profile}).root}i(bte,"root");function Qw(e){let t=DM(e);if(!hte(t))return[];
1555
+ tupCommand");import{existsSync as gte}from"node:fs";import{join as Xw}from"node:path";var bte=l.object({id:l.string(),mode:l.enum(["public","protected"]),host:l.string(),entryPoint:l.string(),container:l.string(),port:l.number(),expiresAt:l.number(),user:l.string().nullable().optional()}).passthrough();function ja(e){return e.optsWithGlobals()}i(ja,"globals");function DM(e){return Xw(E({profile:ja(e).profile}).root,"config/traefik/dynamic/portta-shares.yaml")}i(DM,"path");function yte(e){return E({profile:ja(e).profile}).root}i(yte,"root");function Qw(e){let t=DM(e);if(!gte(t))return[];
1556
1556
  let n=An(t).split(`
1557
- `).find(r=>r.startsWith(Hc));return n?l.array(gte).parse(JSON.parse(n.slice(Hc.length))):[]}i(Qw,"read");function NM(e,t){St(DM(e),JE(t))}i(NM,"write");function LM(e,t){let n=bte(e),r=Xw(n,"state/auth/protections.json"),o=Ze(r),s={...o,protections:o.protections.filter(a=>!t.has(a.scope))};Zr(r,s),St(Xw(n,"config/traefik/dynamic/portta-auth.yaml"),Gr(s))}i(LM,"removeScopes");async function MM(e){let t=Qw(e),n=new A(ja(e));if(n.json)n.data({shares:t});else if(!t.length)n.progress("nothing is share\
1557
+ `).find(r=>r.startsWith(Hc));return n?l.array(bte).parse(JSON.parse(n.slice(Hc.length))):[]}i(Qw,"read");function NM(e,t){St(DM(e),JE(t))}i(NM,"write");function LM(e,t){let n=yte(e),r=Xw(n,"state/auth/protections.json"),o=Ze(r),s={...o,protections:o.protections.filter(a=>!t.has(a.scope))};Zr(r,s),St(Xw(n,"config/traefik/dynamic/portta-auth.yaml"),Gr(s))}i(LM,"removeScopes");async function MM(e){let t=Qw(e),n=new A(ja(e));if(n.json)n.data({shares:t});else if(!t.length)n.progress("nothing is share\
1558
1558
  d");else for(let r of t)n.line(`${r.id} ${r.mode} ${r.host} ${r.container}:${r.port} ${r.expiresAt}`)}i(MM,"shareList");async function zM(e,t){if(!/^[A-Za-z0-9]+$/.test(e))throw new C(`invalid share id: ${e}`);let n=Qw(t);if(!n.some(r=>r.id===e))throw new C(`no share ${e}`);NM(t,n.filter(r=>r.id!==e)),LM(t,new Set([`share:${e}`])),new A(ja(t)).progress(`share ${e} revoked; the project router was not touched`)}i(zM,"shareRevoke");async function FM(e){let t=Qw(e),n=Math.floor(Date.now()/1e3),r=t.filter(
1559
- o=>o.expiresAt>n);r.length!==t.length&&(NM(e,r),LM(e,new Set(t.filter(o=>o.expiresAt<=n).map(o=>`share:${o.id}`)))),new A(ja(e)).progress(`removed ${t.length-r.length} expired share(s)`)}i(FM,"shareGc");import{chmodSync as BM,existsSync as Ia,mkdirSync as wte,writeFileSync as vte}from"node:fs";import{platform as dd}from"node:os";import{join as tr}from"node:path";async function yte(e){return!(await _("docker",["image","inspect",e],{reject:!1})).failed}i(yte,"toolboxExists");async function ev(e,t){let n=Se(t).toolbox;if(await yte(n))return n;if((await _("docker",["build","-q","--build-arg",`PORTTA_VERSION=${t}`,"-t",n,`${e}/docker/images/toolbox`],{reject:!1})).failed)throw new L("could not build the toolbox image",`docker build -t ${n} docker/images/toolbox/`);return n}i(ev,"ensureToolbox");async function ys(e,t,n={}){let r=await ev(e,sh(e)),o=["run","--\
1560
- rm"];n.input!==void 0&&o.push("-i"),o.push("--network",n.network??"none");for(let s of n.volumes??[])o.push("--volume",s);for(let[s,a]of Object.entries(n.env??{}))o.push("--env",`${s}=${a}`);return o.push(r,...t),_("docker",o,{input:n.input,reject:!1})}i(ys,"runInToolbox");function fd(e){return e.optsWithGlobals()}i(fd,"globals");function tv(e){let t=tr(e,"config/tls");return{directory:t,caKey:tr(t,"portta-ca.key"),caCertificate:tr(t,"portta-ca.crt"),leafKey:tr(t,"wildcard.key"),leafCertificate:tr(t,"wildcard.crt"),dynamic:tr(e,"config/traefik/dynamic/local-tls.yaml")}}i(tv,"tlsPaths");function Ste(){return`# Generated by \`portta tls init\`. Safe to delete: re-run the command to
1559
+ o=>o.expiresAt>n);r.length!==t.length&&(NM(e,r),LM(e,new Set(t.filter(o=>o.expiresAt<=n).map(o=>`share:${o.id}`)))),new A(ja(e)).progress(`removed ${t.length-r.length} expired share(s)`)}i(FM,"shareGc");import{chmodSync as BM,existsSync as Ia,mkdirSync as vte,writeFileSync as Ste}from"node:fs";import{platform as dd}from"node:os";import{join as tr}from"node:path";async function wte(e){return!(await _("docker",["image","inspect",e],{reject:!1})).failed}i(wte,"toolboxExists");async function ev(e,t){let n=Se(t).toolbox;if(await wte(n))return n;if((await _("docker",["build","-q","--build-arg",`PORTTA_VERSION=${t}`,"-t",n,`${e}/docker/images/toolbox`],{reject:!1})).failed)throw new L("could not build the toolbox image",`docker build -t ${n} docker/images/toolbox/`);return n}i(ev,"ensureToolbox");async function ys(e,t,n={}){let r=await ev(e,sh(e)),o=["run","--\
1560
+ rm"];n.input!==void 0&&o.push("-i"),o.push("--network",n.network??"none");for(let s of n.volumes??[])o.push("--volume",s);for(let[s,a]of Object.entries(n.env??{}))o.push("--env",`${s}=${a}`);return o.push(r,...t),_("docker",o,{input:n.input,reject:!1})}i(ys,"runInToolbox");function fd(e){return e.optsWithGlobals()}i(fd,"globals");function tv(e){let t=tr(e,"config/tls");return{directory:t,caKey:tr(t,"portta-ca.key"),caCertificate:tr(t,"portta-ca.crt"),leafKey:tr(t,"wildcard.key"),leafCertificate:tr(t,"wildcard.crt"),dynamic:tr(e,"config/traefik/dynamic/local-tls.yaml")}}i(tv,"tlsPaths");function xte(){return`# Generated by \`portta tls init\`. Safe to delete: re-run the command to
1561
1561
  # recreate it. The certificate and key live in config/tls/, which is git-ignored.
1562
1562
  tls:
1563
1563
  stores:
@@ -1568,39 +1568,39 @@ tls:
1568
1568
  certificates:
1569
1569
  - certFile: /etc/traefik/tls/wildcard.crt
1570
1570
  keyFile: /etc/traefik/tls/wildcard.key
1571
- `}i(Ste,"localTlsDynamic");function xte(e){let t=e.split(`
1572
- `),n=t.findIndex(r=>r.includes("Subject Alternative Name"));return n===-1?[]:[...(t[n+1]??"").matchAll(/DNS:([^,\s]+)/g)].map(r=>r[1])}i(xte,"parseSubjectAltNames");async function UM(e,t){if(!Ia(t))return{expires:null,names:[]};let n=await _("which",["openssl"],{reject:!1}),r=i(async(...a)=>n.failed||!n.stdout.trim()?ys(e,["openssl","x509","-in","/in/cert.pem","-noout",...a],{volumes:[`${t}:/in/cert.pem:ro`]}):_("openssl",["x509","-in",t,"-noout",...a],{reject:!1}),"read"),o=await r("-enddate"),
1573
- s=await r("-text");return{expires:o.failed?null:o.stdout.trim().replace(/^notAfter=/,""),names:s.failed?[]:xte(s.stdout)}}i(UM,"certificateFacts");async function qM(e){let t=fd(e),n=E({profile:t.profile}),r=tv(n.root),o=await UM(n.root,r.leafCertificate),s=await UM(n.root,r.caCertificate),a={enabled:n.config.tlsEnabled,mode:n.config.tlsMode,domain:n.config.domain,certificate:{present:Ia(r.leafCertificate),path:r.leafCertificate,expires:o.expires,names:o.names},authority:{present:Ia(r.caCertificate),
1571
+ `}i(xte,"localTlsDynamic");function kte(e){let t=e.split(`
1572
+ `),n=t.findIndex(r=>r.includes("Subject Alternative Name"));return n===-1?[]:[...(t[n+1]??"").matchAll(/DNS:([^,\s]+)/g)].map(r=>r[1])}i(kte,"parseSubjectAltNames");async function UM(e,t){if(!Ia(t))return{expires:null,names:[]};let n=await _("which",["openssl"],{reject:!1}),r=i(async(...a)=>n.failed||!n.stdout.trim()?ys(e,["openssl","x509","-in","/in/cert.pem","-noout",...a],{volumes:[`${t}:/in/cert.pem:ro`]}):_("openssl",["x509","-in",t,"-noout",...a],{reject:!1}),"read"),o=await r("-enddate"),
1573
+ s=await r("-text");return{expires:o.failed?null:o.stdout.trim().replace(/^notAfter=/,""),names:s.failed?[]:kte(s.stdout)}}i(UM,"certificateFacts");async function qM(e){let t=fd(e),n=E({profile:t.profile}),r=tv(n.root),o=await UM(n.root,r.leafCertificate),s=await UM(n.root,r.caCertificate),a={enabled:n.config.tlsEnabled,mode:n.config.tlsMode,domain:n.config.domain,certificate:{present:Ia(r.leafCertificate),path:r.leafCertificate,expires:o.expires,names:o.names},authority:{present:Ia(r.caCertificate),
1574
1574
  path:r.caCertificate,expires:s.expires},acme:n.config.tlsMode==="acme"?{emailSet:!!n.env.ACME_EMAIL,directory:n.env.ACME_CA_SERVER,provider:n.env.ACME_DNS_PROVIDER}:null},c=new A(t);if(c.json){c.data(a);return}if(c.line(`enabled: ${a.enabled}`),c.line(`mode: ${a.mode}`),c.line(`domain: ${a.domain}`),a.acme){c.line(`acme email: ${a.acme.emailSet?"set":"<unset>"}`),c.line(`acme directory: ${a.acme.directory??""}`),c.line(`dns provider: ${a.acme.provider??""}`);return}c.line(`local CA: ${a.authority.
1575
- present?a.authority.path:"not created"}`),a.authority.present||c.hint("portta tls init"),a.certificate.present&&(c.line(`certificate: ${a.certificate.path}`),a.certificate.names.length&&c.line(`covers: ${a.certificate.names.join(", ")}`),a.certificate.expires&&c.line(`expires: ${a.certificate.expires}`))}i(qM,"tlsStatus");async function HM(e){let t=fd(e),n=new A(t),r=E({profile:t.profile});await Ct();let o=tv(r.root),s=r.config.domain;if(wte(o.directory,{recursive:!0}),BM(o.directory,448),Ia(o.caKey))
1575
+ present?a.authority.path:"not created"}`),a.authority.present||c.hint("portta tls init"),a.certificate.present&&(c.line(`certificate: ${a.certificate.path}`),a.certificate.names.length&&c.line(`covers: ${a.certificate.names.join(", ")}`),a.certificate.expires&&c.line(`expires: ${a.certificate.expires}`))}i(qM,"tlsStatus");async function HM(e){let t=fd(e),n=new A(t),r=E({profile:t.profile});await Ct();let o=tv(r.root),s=r.config.domain;if(vte(o.directory,{recursive:!0}),BM(o.directory,448),Ia(o.caKey))
1576
1576
  n.progress("reusing the existing local CA");else{n.progress("creating a local certificate authority");let u=await ys(r.root,["sh","-c",["set -e",'openssl req -x509 -newkey rsa:4096 -sha256 -days 1825 -nodes -keyout /out/portta-ca.key -out /out/portta-ca.crt -subj "/CN=Portta local CA/O=Portta" -addext "basicConstraints=critical,CA:TRUE,pathlen:0" -addext "keyUsage=critical,keyCertSign,cRLSign"',"chmod 600 /out/portta-ca.key"].join(`
1577
1577
  `)],{volumes:[`${o.directory}:/out`]});if(u.failed)throw new L("could not create the CA",u.stderr.trim()||"see docs/product/guides/dns-and-tls.md");n.progress(`created ${o.caCertificate}`)}n.progress(`issuing a wildcard certificate for *.${s}`);let a=await ys(r.root,["sh","-c",["set -e",'openssl req -newkey rsa:2048 -nodes -keyout /out/wildcard.key -out /tmp/wildcard.csr -subj "/CN=*.$DOMAIN"','printf "subjectAltName=DNS:*.%s,DNS:%s\\nextendedKeyUsage=serverAuth\\nbasicConstraints=CA:FALSE\\n" "$DO\
1578
1578
  MAIN" "$DOMAIN" > /tmp/ext',"openssl x509 -req -in /tmp/wildcard.csr -CA /out/portta-ca.crt -CAkey /out/portta-ca.key -CAcreateserial -out /out/wildcard.crt -days 397 -sha256 -extfile /tmp/ext","chmod 600 /out/wildcard.key"].join(`
1579
- `)],{volumes:[`${o.directory}:/out`],env:{DOMAIN:s}});if(a.failed)throw new L("could not issue the certificate",a.stderr.trim()||"see docs/product/guides/dns-and-tls.md");for(let u of[o.caKey,o.leafKey])try{BM(u,384)}catch{}n.progress(`issued ${o.leafCertificate} for *.${s}`),vte(o.dynamic,Ste());let c=tr(r.root,".env");je(c,{TLS_ENABLED:"true",TLS_MODE:"local"}),n.progress("TLS enabled in .env"),n.line(""),ZM(n,o.caCertificate),n.hint(`then: portta up ${r.config.profile}`)}i(HM,"tlsInit");function ZM(e,t){
1579
+ `)],{volumes:[`${o.directory}:/out`],env:{DOMAIN:s}});if(a.failed)throw new L("could not issue the certificate",a.stderr.trim()||"see docs/product/guides/dns-and-tls.md");for(let u of[o.caKey,o.leafKey])try{BM(u,384)}catch{}n.progress(`issued ${o.leafCertificate} for *.${s}`),Ste(o.dynamic,xte());let c=tr(r.root,".env");je(c,{TLS_ENABLED:"true",TLS_MODE:"local"}),n.progress("TLS enabled in .env"),n.line(""),ZM(n,o.caCertificate),n.hint(`then: portta up ${r.config.profile}`)}i(HM,"tlsInit");function ZM(e,t){
1580
1580
  e.line("Trusting the local CA"),e.line("This writes to your operating system trust store, so the gateway will not do it for you. Run the command that matches your system:"),e.line(""),dd()==="darwin"?(e.line(" sudo security add-trusted-cert -d -r trustRoot \\"),e.line(` -k /Library/Keychains/System.keychain "${t}"`)):dd()==="linux"?(e.line(` sudo cp "${t}" /usr/local/share/ca-certificates/portta-ca.crt`),e.line(" sudo update-ca-certificates")):e.line(` Import ${t} into your system trust s\
1581
1581
  tore as a root certificate.`),e.line(""),e.line("Firefox keeps its own store: Settings -> Privacy & Security -> Certificates -> View Certificates -> Authorities -> Import."),e.line("Remove it later with: portta tls untrust")}i(ZM,"printTrust");async function GM(e){let t=fd(e),n=E({profile:t.profile}),r=tv(n.root);if(!Ia(r.caCertificate))throw new L("no local CA yet","portta tls init");ZM(new A(t),r.caCertificate)}i(GM,"tlsTrust");async function WM(e){let t=fd(e),n=E({profile:t.profile}),r=new A(
1582
- t);r.line("Removing the local CA from the trust store"),dd()==="darwin"?(r.line(' sudo security delete-certificate -c "Portta local CA" \\'),r.line(" /Library/Keychains/System.keychain")):dd()==="linux"?(r.line(" sudo rm -f /usr/local/share/ca-certificates/portta-ca.crt"),r.line(" sudo update-ca-certificates --fresh")):r.line(' Remove "Portta local CA" from your system trust store.'),r.line(""),r.line(`To delete the key material as well: rm -rf ${kte(n.root)}`)}i(WM,"tlsUntrust");function kte(e){
1583
- return tr(e,"config/tls")}i(kte,"paths");function md(e){return e.optsWithGlobals()}i(md,"globals");async function VM(e){let t=E({profile:md(e).profile}),n=await ev(t.root,t.version),r=new A(md(e));md(e).json?r.data({image:n}):r.progress(`toolbox ready: ${n}`)}i(VM,"toolboxBuild");async function KM(e,t){if(e.length===0)throw new C("toolbox run needs a command");let n=E({profile:md(t).profile}),r=await ys(n.root,e,{network:"bridge"});r.stdout&&process.stdout.write(r.stdout),r.stderr&&process.stderr.write(r.stderr),r.exitCode!==0&&(process.
1584
- exitCode=r.exitCode)}i(KM,"toolboxRun");import{chmodSync as JM,closeSync as _te,existsSync as hd,mkdirSync as Pte,openSync as Ete,readFileSync as Ate,rmSync as YM,writeFileSync as XM}from"node:fs";import{join as ws}from"node:path";import{ReadStream as Ote}from"node:tty";function vs(e){return e.optsWithGlobals()}i(vs,"globals");function gd(e){let t=ws(e,"state/cloudflared");return{directory:t,config:ws(t,"config.yml"),credentials:ws(t,"credentials.json")}}i(gd,"tunnelPaths");function QM(e){return`${e.PORTTA_PROJECT_NAME||"portta"}-cloudflared-1`}i(QM,"tunnelContainer");function e1(e){let t=gd(e);return hd(t.config)&&hd(t.credentials)}i(e1,"tunnelConfigured");function $te(e){let t=tf({profile:e.config.profile,tailscaleEnabled:e.config.tailscaleEnabled}),n=e.env.PORTTA_HTTP_PORT||
1585
- "80";return`http://${t==="tailscale"?"tailscale":"traefik"}:${n}`}i($te,"defaultOrigin");async function Tte(e){let t=QM(e.env),n=await _("docker",["inspect","-f","{{.State.Status}}",t],{reject:!1}),r=await _("docker",["inspect","-f","{{if .State.Health}}{{.State.Health.Status}}{{end}}",t],{reject:!1}),o=await _("docker",["logs","--tail","200",t],{reject:!1});return{container:t,state:n.failed?null:n.stdout.trim()||null,health:r.failed?null:r.stdout.trim()||null,logTail:`${o.stdout}${o.stderr}`}}i(
1586
- Tte,"containerFacts");async function Cte(e){let t=await Tte(e);return{status:tA({tokenConfigured:e1(e.root),zoneConfigured:!!e.env.CLOUDFLARE_TUNNEL_ZONE,enabled:e.config.tunnelEnabled,containerState:t.state,containerHealth:t.health,logTail:t.logTail}),container:t.container,containerState:t.state??"absent"}}i(Cte,"readStatus");async function nv(e){let t=vs(e),n=E({profile:t.profile}),r=new A(t),{status:o,container:s,containerState:a}=await Cte(n),c=n.env.CLOUDFLARE_TUNNEL_ZONE??"",u=n.env.CLOUDFLARE_TUNNEL_ID??
1582
+ t);r.line("Removing the local CA from the trust store"),dd()==="darwin"?(r.line(' sudo security delete-certificate -c "Portta local CA" \\'),r.line(" /Library/Keychains/System.keychain")):dd()==="linux"?(r.line(" sudo rm -f /usr/local/share/ca-certificates/portta-ca.crt"),r.line(" sudo update-ca-certificates --fresh")):r.line(' Remove "Portta local CA" from your system trust store.'),r.line(""),r.line(`To delete the key material as well: rm -rf ${_te(n.root)}`)}i(WM,"tlsUntrust");function _te(e){
1583
+ return tr(e,"config/tls")}i(_te,"paths");function md(e){return e.optsWithGlobals()}i(md,"globals");async function VM(e){let t=E({profile:md(e).profile}),n=await ev(t.root,t.version),r=new A(md(e));md(e).json?r.data({image:n}):r.progress(`toolbox ready: ${n}`)}i(VM,"toolboxBuild");async function KM(e,t){if(e.length===0)throw new C("toolbox run needs a command");let n=E({profile:md(t).profile}),r=await ys(n.root,e,{network:"bridge"});r.stdout&&process.stdout.write(r.stdout),r.stderr&&process.stderr.write(r.stderr),r.exitCode!==0&&(process.
1584
+ exitCode=r.exitCode)}i(KM,"toolboxRun");import{chmodSync as JM,closeSync as Pte,existsSync as hd,mkdirSync as Ete,openSync as Ate,readFileSync as Ote,rmSync as YM,writeFileSync as XM}from"node:fs";import{join as ws}from"node:path";import{ReadStream as $te}from"node:tty";function vs(e){return e.optsWithGlobals()}i(vs,"globals");function gd(e){let t=ws(e,"state/cloudflared");return{directory:t,config:ws(t,"config.yml"),credentials:ws(t,"credentials.json")}}i(gd,"tunnelPaths");function QM(e){return`${e.PORTTA_PROJECT_NAME||"portta"}-cloudflared-1`}i(QM,"tunnelContainer");function e1(e){let t=gd(e);return hd(t.config)&&hd(t.credentials)}i(e1,"tunnelConfigured");function Tte(e){let t=tf({profile:e.config.profile,tailscaleEnabled:e.config.tailscaleEnabled}),n=e.env.PORTTA_HTTP_PORT||
1585
+ "80";return`http://${t==="tailscale"?"tailscale":"traefik"}:${n}`}i(Tte,"defaultOrigin");async function Cte(e){let t=QM(e.env),n=await _("docker",["inspect","-f","{{.State.Status}}",t],{reject:!1}),r=await _("docker",["inspect","-f","{{if .State.Health}}{{.State.Health.Status}}{{end}}",t],{reject:!1}),o=await _("docker",["logs","--tail","200",t],{reject:!1});return{container:t,state:n.failed?null:n.stdout.trim()||null,health:r.failed?null:r.stdout.trim()||null,logTail:`${o.stdout}${o.stderr}`}}i(
1586
+ Cte,"containerFacts");async function Rte(e){let t=await Cte(e);return{status:tA({tokenConfigured:e1(e.root),zoneConfigured:!!e.env.CLOUDFLARE_TUNNEL_ZONE,enabled:e.config.tunnelEnabled,containerState:t.state,containerHealth:t.health,logTail:t.logTail}),container:t.container,containerState:t.state??"absent"}}i(Rte,"readStatus");async function nv(e){let t=vs(e),n=E({profile:t.profile}),r=new A(t),{status:o,container:s,containerState:a}=await Rte(n),c=n.env.CLOUDFLARE_TUNNEL_ZONE??"",u=n.env.CLOUDFLARE_TUNNEL_ID??
1587
1587
  "",p=hd(gd(n.root).credentials);if(r.json){r.data({state:o.state,detail:o.detail,hint:o.hint,zone:c||null,wildcard:c?`*.${c}`:null,tunnel:u||null,connector:{container:s,state:a},credential:p});return}r.line(""),r.line("Cloudflare Tunnel"),r.line(""),r.line(` state ${o.state}`),r.line(` domain ${c||"<unset>"}`),c&&r.line(` wildcard *.${c}`),r.line(` tunnel ${u||"<unset>"}`),r.line(` connector ${s} (${a})`),r.line(` credential ${p?"configured":"not set"}`),r.line(""),o.
1588
- state==="connected"?r.progress(`carrying traffic for *.${c}`):o.state==="starting"||o.state==="not-configured"||o.state==="configured"?r.progress(o.detail):r.error(o.detail);let d=Rte(o);d&&r.hint(d)}i(nv,"tunnelStatus");function Rte(e){switch(e.state){case"not-configured":return"portta tunnel setup --zone <domain>";case"configured":return"portta tunnel enable";case"config-error":return"portta tunnel logs";case"auth-error":return"the tunnel may have been deleted, or the token belongs to another \
1589
- account: portta tunnel setup --zone <domain>";case"disconnected":return"portta tunnel logs (the connector dials out on 7844/udp and 443/tcp)";case"starting":case"connected":return null}}i(Rte,"cliHint");async function jte(){let e;try{e=Ete("/dev/tty","r")}catch{throw new L("no terminal available to read the token","portta tunnel setup --zone <domain> --token-file <file>")}process.stderr.write("Tunnel token (input is hidden): ");let t=new Ote(e),n=t.isTTY?()=>t.setRawMode(!1):()=>{};t.isTTY&&t.
1588
+ state==="connected"?r.progress(`carrying traffic for *.${c}`):o.state==="starting"||o.state==="not-configured"||o.state==="configured"?r.progress(o.detail):r.error(o.detail);let d=jte(o);d&&r.hint(d)}i(nv,"tunnelStatus");function jte(e){switch(e.state){case"not-configured":return"portta tunnel setup --zone <domain>";case"configured":return"portta tunnel enable";case"config-error":return"portta tunnel logs";case"auth-error":return"the tunnel may have been deleted, or the token belongs to another \
1589
+ account: portta tunnel setup --zone <domain>";case"disconnected":return"portta tunnel logs (the connector dials out on 7844/udp and 443/tcp)";case"starting":case"connected":return null}}i(jte,"cliHint");async function Ite(){let e;try{e=Ate("/dev/tty","r")}catch{throw new L("no terminal available to read the token","portta tunnel setup --zone <domain> --token-file <file>")}process.stderr.write("Tunnel token (input is hidden): ");let t=new $te(e),n=t.isTTY?()=>t.setRawMode(!1):()=>{};t.isTTY&&t.
1590
1590
  setRawMode(!0);try{return await new Promise(r=>{let o="";t.on("data",s=>{for(let a of s){if(a===13||a===10){process.stderr.write(`
1591
1591
  `),r(o.trim());return}if(a===3){process.stderr.write(`
1592
- `),r("");return}a===127||a===8?o=o.slice(0,-1):o+=String.fromCharCode(a)}})})}finally{n(),t.destroy(),_te(e)}}i(jte,"promptForToken");async function t1(e,t){let n=vs(t),r=new A(n);if(e.token!==void 0)throw new C("a token must not be passed as an argument: it would be visible in `ps` and in your shell history",`portta tunnel setup --zone ${e.zone??"<domain>"} --token-file <file>, or omit it to be prompted`);if(!e.zone)throw new C("--zone is required","the domain whose wildcard points at the tunne\
1593
- l, e.g. example.com");let o=E({profile:n.profile}),s;if(e.tokenFile){if(!hd(e.tokenFile))throw new C(`no such file: ${e.tokenFile}`);s=Ate(e.tokenFile,"utf8").replace(/\s+/g,"")}else s=await jte();if(!s)throw new C("no token was given");let a=gd(o.root);Pte(a.directory,{recursive:!0}),JM(a.directory,448);let c;try{c=QE(s)}catch(f){throw new C(`the token was refused: ${f instanceof Error?f.message:String(f)}`,"copy the whole eyJ... string from the Cloudflare dashboard, not the install command aro\
1594
- und it")}XM(a.credentials,eA(c),{mode:384}),JM(a.credentials,384);let u=e.origin||$te(o),p={id:c.TunnelID,zone:e.zone,origin:u,credentialsFile:"/etc/cloudflared/credentials.json",includeApex:e.apex??!1};XM(a.config,XE(p));let d=ws(o.root,".env");if(je(d,{CLOUDFLARE_TUNNEL_ZONE:e.zone,CLOUDFLARE_TUNNEL_ID:c.TunnelID}),r.json){r.data({zone:e.zone,tunnel:c.TunnelID,origin:u,routes:nh(p),dns:{type:"CNAME",name:`*.${e.zone}`,target:rh(c.TunnelID),proxied:!0}});return}r.progress("the connector is conf\
1592
+ `),r("");return}a===127||a===8?o=o.slice(0,-1):o+=String.fromCharCode(a)}})})}finally{n(),t.destroy(),Pte(e)}}i(Ite,"promptForToken");async function t1(e,t){let n=vs(t),r=new A(n);if(e.token!==void 0)throw new C("a token must not be passed as an argument: it would be visible in `ps` and in your shell history",`portta tunnel setup --zone ${e.zone??"<domain>"} --token-file <file>, or omit it to be prompted`);if(!e.zone)throw new C("--zone is required","the domain whose wildcard points at the tunne\
1593
+ l, e.g. example.com");let o=E({profile:n.profile}),s;if(e.tokenFile){if(!hd(e.tokenFile))throw new C(`no such file: ${e.tokenFile}`);s=Ote(e.tokenFile,"utf8").replace(/\s+/g,"")}else s=await Ite();if(!s)throw new C("no token was given");let a=gd(o.root);Ete(a.directory,{recursive:!0}),JM(a.directory,448);let c;try{c=QE(s)}catch(f){throw new C(`the token was refused: ${f instanceof Error?f.message:String(f)}`,"copy the whole eyJ... string from the Cloudflare dashboard, not the install command aro\
1594
+ und it")}XM(a.credentials,eA(c),{mode:384}),JM(a.credentials,384);let u=e.origin||Tte(o),p={id:c.TunnelID,zone:e.zone,origin:u,credentialsFile:"/etc/cloudflared/credentials.json",includeApex:e.apex??!1};XM(a.config,XE(p));let d=ws(o.root,".env");if(je(d,{CLOUDFLARE_TUNNEL_ZONE:e.zone,CLOUDFLARE_TUNNEL_ID:c.TunnelID}),r.json){r.data({zone:e.zone,tunnel:c.TunnelID,origin:u,routes:nh(p),dns:{type:"CNAME",name:`*.${e.zone}`,target:rh(c.TunnelID),proxied:!0}});return}r.progress("the connector is conf\
1595
1595
  igured"),r.line(""),r.line(` zone ${e.zone}`),r.line(` tunnel ${c.TunnelID}`),r.line(` origin ${u}`);for(let f of nh(p))r.line(` routes ${f}`);r.line(""),r.line("One DNS record makes every project hostname work, now and in future:"),r.line(""),r.line(" Type CNAME"),r.line(` Name *.${e.zone}`),r.line(` Target ${rh(c.TunnelID)}`),r.line(" Proxy on (orange cloud)"),r.line(""),r.line("Then: portta tunnel enable")}i(t1,"tunnelSetup");async function n1(e){let t=vs(e),
1596
1596
  n=new A(t),r=E({profile:t.profile});if(!e1(r.root))throw new L("the connector is not configured","portta tunnel setup --zone <domain>");let o=ws(r.root,".env");if(je(o,{CLOUDFLARE_TUNNEL_ENABLED:"true"}),n.progress("Cloudflare Tunnel enabled"),n.progress("starting the connector"),r=E({profile:t.profile,overrides:{CLOUDFLARE_TUNNEL_ENABLED:"true"}}),(await _("docker",["compose",...we(r),"up","-d","--remove-orphans"],{cwd:r.root,env:r.env,stdio:"inherit",reject:!1})).failed)throw new L("the connec\
1597
1597
  tor did not start","portta tunnel logs");await nv(e)}i(n1,"tunnelEnable");async function r1(e,t){let n=vs(t),r=new A(n);r.progress("stopping the connector");let o=E({profile:n.profile,overrides:{CLOUDFLARE_TUNNEL_ENABLED:"true"}});await _("docker",["compose",...we(o),"rm","-sf","cloudflared"],{cwd:o.root,env:o.env,reject:!1});let s=ws(o.root,".env"),a={CLOUDFLARE_TUNNEL_ENABLED:"false"};if(e.forget){let c=gd(o.root);YM(c.config,{force:!0}),YM(c.credentials,{force:!0}),a.CLOUDFLARE_TUNNEL_ID=""}je(
1598
1598
  s,a),r.progress(e.forget?"the connector is stopped and its configuration removed":"the connector is stopped; its configuration is kept for re-enabling"),r.line(""),r.line("nothing was changed in your Cloudflare account"),r.line(" The tunnel, the DNS record and any Access policy are still there."),r.line(" Remove them yourself if you want them gone.")}i(r1,"tunnelDisable");async function o1(e,t){let n=vs(t),r=E({profile:n.profile});if((await _("docker",["logs","--tail",e.lines??"50",QM(r.env)],
1599
- {stdio:"inherit",reject:!1})).failed)throw new L("the connector container does not exist","portta tunnel enable")}i(o1,"tunnelLogs");function Ite(e){return e===404?{ok:!0,detail:"the tunnel is carrying traffic (404 from the gateway). Traefik answered, which means Cloudflare -> tunnel -> connector -> Traefik all work; 404 is correct here, because nothing is routed at that name.",hint:null}:e===200||e>=300&&e<400?{ok:!0,detail:`the tunnel is carrying traffic (${e})`,hint:null}:e===530?{ok:!1,detail:"\
1600
- Cloudflare has no connector for this tunnel (530)",hint:"portta tunnel status"}:e===502||e===504?{ok:!1,detail:`the connector answered but could not reach the gateway (${e})`,hint:"portta status (is Traefik running?)"}:e===0?{ok:!1,detail:"no answer at all",hint:"check that the wildcard resolves"}:{ok:!1,detail:`unexpected response: ${e}`,hint:null}}i(Ite,"describeProbe");async function s1(e){let t=vs(e),n=new A(t),o=E({profile:t.profile}).env.CLOUDFLARE_TUNNEL_ZONE;if(!o)throw new L("no domai\
1601
- n is configured","portta tunnel setup --zone <domain>");let s=`portta-tunnel-check.${o}`;n.progress(`asking Cloudflare for https://${s}`);let a=0,c=new AbortController,u=setTimeout(()=>c.abort(),2e4);try{a=(await fetch(`https://${s}/`,{signal:c.signal,redirect:"manual"})).status}catch{a=0}finally{clearTimeout(u)}let p=Ite(a);if(n.json){n.data({host:s,code:a,ok:p.ok,detail:p.detail,hint:p.hint});return}if(p.ok?n.progress(p.detail):n.error(p.detail),p.hint&&n.hint(p.hint),!p.ok)throw new L(`the tu\
1602
- nnel is not carrying traffic (${a})`,p.hint??"portta tunnel status")}i(s1,"tunnelTest");import{randomBytes as Dte}from"node:crypto";import{readFileSync as Nte}from"node:fs";function rv(e){if(e.passwordStdin){let n=Nte(0,"utf8").trim();if(!n)throw new C("no password on stdin");if(n.length<10)throw new C("the password must be at least 10 characters");return{password:n,generated:!1}}return{password:Dte(20).toString("base64url").slice(0,20).match(/.{1,5}/g).join("-"),generated:!0}}i(rv,"passwordFrom");function Lte(e){return[e.email,e.role,e.banned?"banned":"active",e.projects.length?e.projects.map(t=>t.slug).join(","):"all",e.id]}i(Lte,"line");async function i1(e,t){let{
1603
- client:n,output:r}=de(t),o=await n.request("GET","/users");if(r.json)return r.data(o);if(o.users.length===0)return r.line("no users");Ep(r,[["EMAIL","ROLE","STATE","PROJECTS","ID"],...o.users.map(Lte)])}i(i1,"usersList");async function a1(e,t){if(!e.name||!e.email)throw new C("--name and --email are required");let n=e.role??"viewer";if(!eh(n))throw new C(`--role must be one of: ${wo.join(", ")}`);let{password:r,generated:o}=rv(e),{client:s,output:a}=de(t),c=await s.request("POST","/users",{name:e.
1599
+ {stdio:"inherit",reject:!1})).failed)throw new L("the connector container does not exist","portta tunnel enable")}i(o1,"tunnelLogs");function Dte(e){return e===404?{ok:!0,detail:"the tunnel is carrying traffic (404 from the gateway). Traefik answered, which means Cloudflare -> tunnel -> connector -> Traefik all work; 404 is correct here, because nothing is routed at that name.",hint:null}:e===200||e>=300&&e<400?{ok:!0,detail:`the tunnel is carrying traffic (${e})`,hint:null}:e===530?{ok:!1,detail:"\
1600
+ Cloudflare has no connector for this tunnel (530)",hint:"portta tunnel status"}:e===502||e===504?{ok:!1,detail:`the connector answered but could not reach the gateway (${e})`,hint:"portta status (is Traefik running?)"}:e===0?{ok:!1,detail:"no answer at all",hint:"check that the wildcard resolves"}:{ok:!1,detail:`unexpected response: ${e}`,hint:null}}i(Dte,"describeProbe");async function s1(e){let t=vs(e),n=new A(t),o=E({profile:t.profile}).env.CLOUDFLARE_TUNNEL_ZONE;if(!o)throw new L("no domai\
1601
+ n is configured","portta tunnel setup --zone <domain>");let s=`portta-tunnel-check.${o}`;n.progress(`asking Cloudflare for https://${s}`);let a=0,c=new AbortController,u=setTimeout(()=>c.abort(),2e4);try{a=(await fetch(`https://${s}/`,{signal:c.signal,redirect:"manual"})).status}catch{a=0}finally{clearTimeout(u)}let p=Dte(a);if(n.json){n.data({host:s,code:a,ok:p.ok,detail:p.detail,hint:p.hint});return}if(p.ok?n.progress(p.detail):n.error(p.detail),p.hint&&n.hint(p.hint),!p.ok)throw new L(`the tu\
1602
+ nnel is not carrying traffic (${a})`,p.hint??"portta tunnel status")}i(s1,"tunnelTest");import{randomBytes as Nte}from"node:crypto";import{readFileSync as Lte}from"node:fs";function rv(e){if(e.passwordStdin){let n=Lte(0,"utf8").trim();if(!n)throw new C("no password on stdin");if(n.length<10)throw new C("the password must be at least 10 characters");return{password:n,generated:!1}}return{password:Nte(20).toString("base64url").slice(0,20).match(/.{1,5}/g).join("-"),generated:!0}}i(rv,"passwordFrom");function Mte(e){return[e.email,e.role,e.banned?"banned":"active",e.projects.length?e.projects.map(t=>t.slug).join(","):"all",e.id]}i(Mte,"line");async function i1(e,t){let{
1603
+ client:n,output:r}=de(t),o=await n.request("GET","/users");if(r.json)return r.data(o);if(o.users.length===0)return r.line("no users");Ep(r,[["EMAIL","ROLE","STATE","PROJECTS","ID"],...o.users.map(Mte)])}i(i1,"usersList");async function a1(e,t){if(!e.name||!e.email)throw new C("--name and --email are required");let n=e.role??"viewer";if(!eh(n))throw new C(`--role must be one of: ${wo.join(", ")}`);let{password:r,generated:o}=rv(e),{client:s,output:a}=de(t),c=await s.request("POST","/users",{name:e.
1604
1604
  name,email:e.email,password:r,role:n,...e.projects?{projects:(rD(e.projects)??[]).map(Number)}:{}});if(a.json)return a.data({...c,password:o?r:void 0});a.line(`${c.email} ${c.role}`),o&&(a.line(`password: ${r}`),a.warning("this is the only time the generated password is shown"))}i(a1,"usersCreate");async function c1(e,t,n,r){if(!eh(t))throw new C(`role must be one of: ${wo.join(", ")}`);let{client:o,output:s}=de(r),a=await bd(o,e),c=await o.request("PATCH",`/users/${encodeURIComponent(a.id)}/ro\
1605
1605
  le`,{role:t});if(s.json)return s.data(c);s.progress(`${c.email} is now ${c.role}`)}i(c1,"usersSetRole");async function l1(e,t,n){let{password:r,generated:o}=rv(t),{client:s,output:a}=de(n),c=await bd(s,e);if(await s.request("PATCH",`/users/${encodeURIComponent(c.id)}/password`,{password:r}),a.json)return a.data({email:c.email,password:o?r:void 0});a.progress(`password set for ${c.email}; every session of that account was ended`),o&&(a.line(`password: ${r}`),a.warning("this is the only time the g\
1606
1606
  enerated password is shown"))}i(l1,"usersSetPassword");async function u1(e,t,n,r){let{client:o,output:s}=de(n),a=await bd(o,e),u=(await o.request("GET","/projects")).projects.find(m=>m.slug===t);if(!u)throw new C(`no project '${t}'`,"list them with `portta projects list`");let p=a.projects.map(m=>m.id),d=await o.request("PUT",`/users/${encodeURIComponent(a.id)}/projects`,{projects:r(p,u.id).map(Number)});if(s.json)return s.data(d);let f=d.projects.map(m=>m.slug);s.progress(`${d.email} reaches ${f.
@@ -1614,7 +1614,7 @@ ateway components").option("--local-release","use the locally built image for th
1614
1614
  t portta-demo-* projects from PORTTA_PROJECTS_HOME").action((e,t,n)=>qw(e,t,n));S(G.command("down"),"Stop the current Compose runtime, or gateway components; keep projects and data").option("--demo","also stop portta-demo-* projects from PORTTA_PROJECTS_HOME and drop their volumes").action((e,t)=>Yo()?rt("down",{},t):qL(e,t));S(G.command("reset"),"Stop every Portta-managed stack, drop their volumes, and restart this checkout as if it were new").option("--demo","also recreate portta-demo-* projec\
1615
1615
  ts from PORTTA_PROJECTS_HOME").action((e,t)=>HL(e,t));S(G.command("restart"),"Restart the current Compose runtime, or recreate gateway components").action((e,t)=>Yo()?rt("restart",{},t):ZL(t));S(G.command("status"),"Show the current Compose runtime, or gateway status").action((e,t)=>Yo()?rt("status",{},t):KL(t));S(G.command("doctor"),"Run read-only host and gateway diagnostics").action((e,t)=>Hw(t));S(G.command("urls"),"List routed HTTP hostnames").option("--project <name>").action(Ta);S(G.command(
1616
1616
  "logs [service]"),"Follow current Compose runtime or gateway component logs").option("--no-follow").option("--tail <lines>","line count","200").action((e,t,n)=>Yo()?rt("logs",{service:e,follow:t.follow,tail:t.tail},n):GL(e,t,n));S(G.command("inspect"),"Print resolved configuration without secrets").action((e,t)=>VL(t));S(G.command("update"),"Pull pinned images and recreate after confirmation").action((e,t)=>WL(t));S(G.command("services"),"List services in the current Compose runtime").action((e,t)=>rt(
1617
- "status",{},t));var Mte=S(G.command("compose"),"Inspect the effective Compose model for the current runtime");S(Mte.command("config [path]"),"Print the effective model from the persisted Runtime Plan").action((e,t,n)=>rt("config",{path:e},n));var Nt=S(G.command("envs"),"Inspect and operate Compose environments on this host").alias("env").alias("environment");S(Nt.command("list"),"List running Compose environments").action((e,t)=>cN(e,t));S(Nt.command("show <name>"),"Show one environment, its ser\
1617
+ "status",{},t));var zte=S(G.command("compose"),"Inspect the effective Compose model for the current runtime");S(zte.command("config [path]"),"Print the effective model from the persisted Runtime Plan").action((e,t,n)=>rt("config",{path:e},n));var Nt=S(G.command("envs"),"Inspect and operate Compose environments on this host").alias("env").alias("environment");S(Nt.command("list"),"List running Compose environments").action((e,t)=>cN(e,t));S(Nt.command("show <name>"),"Show one environment, its ser\
1618
1618
  vices and URLs").action((e,t,n)=>lN(e,n));S(Nt.command("services"),"List services across running environments").option("--project <name>").action(uN);S(Nt.command("report"),"Collect host environment readiness into state/environment").action((e,t)=>AN(t));S(Nt.command("analyze <path>"),"Read-only adoption report").option("--file <path>","the Compose file, relative to <path> or absolute; default: compose.yaml and its variants in <path>").action(dN);S(G.command("adopt <path>"),"Analyze and prepare \
1619
1619
  an isolated Compose Runtime Plan without changing the project").option("--dry-run","print the plan and pending decisions without writing state").option("--service <name:port>","HTTP service to expose; repeatable",(e,t)=>t.concat(e),[]).option("--project <name>","explicit Compose project namespace").option("--manual","record manual integration instead of generated runtime mutations").option("--remove-container-name <service>","explicitly remove this fixed container name; repeatable",(e,t)=>t.concat(
1620
1620
  e),[]).option("--allow-shared-networks","confirm that fixed or external networks may be shared").option("--allow-shared-volumes","confirm that fixed or external volumes may be shared").option("--protect <service>","public host: ask for a generated credential to open this service; repeatable",(e,t)=>t.concat(e),[]).option("--public <service>","public host: let everybody open this service, with no login; repeatable",(e,t)=>t.concat(e),[]).action(async(e,t,n)=>{await AI({path:e,service:t.service,project:t.
@@ -1625,7 +1625,7 @@ ependents first").action((e,t,n)=>qp(e,"stop",n));S(Nt.command("restart <name>")
1625
1625
  ed: list, create, resolve, resources");S(Ae(Da.command("list")),"List Projects").action(fM);S(Ae(Da.command("show <slug>")),"One Project with its environments").action((e,t,n)=>mM(e,n));S(Ae(Da.command("create")),"Create a Project").option("--slug <slug>").option("--name <name>").option("--description <text>").option("--path <dir>","directory under Projects Home, such as group/project").action(hM);S(Ae(Da.command("resolve")),"Which Project a directory belongs to: its root, a subdirectory or a wo\
1626
1626
  rktree").option("--path <abs>","the directory to resolve; defaults to the current one").action(OM);S(Ae(Da.command("resources <slug>")),"A Project's resource usage, attributed through its environments").action((e,t,n)=>gM(e,n));var Na=S(G.command("access"),"Open short-lived loopback bridges");S(Qt(h1(Na.command("open"))),"Open a bridge").option("--port <number>").option("--local-port <number>").option("--ttl <duration>").option("--network <name>").option("--bind <ip>","bind address","127.0.0.1").
1627
1627
  action(Pi);S(Na.command("list").alias("ls"),"List bridges").action((e,t)=>bC(t));S(Na.command("close [id]"),"Close only gateway-owned bridges").option("--project <name>").option("--all").action(nu);S(Na.command("inspect <id>"),"Inspect one bridge").action((e,t,n)=>yC(e,n));S(Na.command("gc"),"Remove expired and orphaned bridges").action((e,t)=>wC(t));var ov=S(G.command("service"),"Manage persistent private TCP forwarders");S(Qt(h1(ov.command("publish"))),"Publish a service privately").option("--\
1628
- private").option("--public").option("--port <number>").option("--alias <name>").action(vC);S(ov.command("list"),"List private forwarders").action((e,t)=>SC(t));S(ov.command("unpublish [alias]"),"Remove gateway-owned forwarders").option("--project <name>").action(xC);var zte=S(G.command("network"),"Inspect host network exposure");S(zte.command("status"),"List published bindings").option("--public-ip","make one outbound public-IP lookup").action(iM);var yd=S(G.command("public"),"Control deliberate\
1628
+ private").option("--public").option("--port <number>").option("--alias <name>").action(vC);S(ov.command("list"),"List private forwarders").action((e,t)=>SC(t));S(ov.command("unpublish [alias]"),"Remove gateway-owned forwarders").option("--project <name>").action(xC);var Fte=S(G.command("network"),"Inspect host network exposure");S(Fte.command("status"),"List published bindings").option("--public-ip","make one outbound public-IP lookup").action(iM);var yd=S(G.command("public"),"Control deliberate\
1629
1629
  public HTTP exposure");S(yd.command("status"),"Show current public exposure").action((e,t)=>aM(t));S(yd.command("enable"),"Enable public HTTP after confirmation").action((e,t)=>cM(t));S(yd.command("init"),"Configure this host as a public server: domain, TLS and panel, without starting anything").requiredOption("--domain <domain>","the base domain, such as example.com").requiredOption("--email <address>","the ACME contact").option("--panel-host <host>","where the panel answers; the domain or one\
1630
1630
  label under it (default: the domain)").option("--ip <address>","the server's public IP, used only to print the DNS records").option("--cloudflare-token-stdin","read the Cloudflare DNS token from one line of standard input").option("--dry-run","print the plan and the DNS records; write nothing").action(_M);S(yd.command("disable"),"Disable public HTTP").action((e,t)=>lM(t));var sv=S(G.command("dns"),"Inspect or configure wildcard DNS");S(sv.command("check"),"Resolve a wildcard probe").action((e,t)=>uM(
1631
1631
  t));S(sv.command("status"),"Show DNS configuration without secrets").action((e,t)=>pM(t));S(sv.command("setup"),"Plan or apply a Cloudflare wildcard record").option("--target <ip>").option("--dry-run").action(dM);var kn=S(G.command("web"),"Run the optional administration panel").option("--local-release","use the locally built image for this checkout");S(kn.command("up"),"Enable and start the panel").option("--expose <scope>","local, tailscale, vpn, public or domain").option("--port <number>").option(
@@ -1636,7 +1636,7 @@ h"),"Keep collecting host and Docker metrics").option("--loop","run in the foreg
1636
1636
  ares").action((e,t)=>FM(t));var Fr=S(G.command("auth"),"Who this terminal is, to a panel");S(Ae(Fr.command("status",{isDefault:!0}),!1),"Whether this panel asks who you are, and who it thinks you are").action(cD);S(Ae(Fr.command("login"),!1),"Save a token for a panel, after checking it").option("--token <token>","the token; omitted, it is read from the terminal without echoing").action(aD);S(Ae(Fr.command("logout"),!1),"Forget the saved credential for a panel").action(lD);S(Fr.command("whoami"),
1637
1637
  "Every panel this host has a credential for").action(uD);S(Ae(Fr.command("bootstrap"),!1),"Create the panel owner, once, from this host").requiredOption("--name <name>").requiredOption("--email <email>").option("--password-stdin").action(iD);S(Fr.command("reset-password <email>"),"Reset a password from the host, when nobody can sign in to do it").option("--password-stdin","read the password from stdin instead of generating one").action(m1);var cv=S(Fr.command("token"),"Personal API tokens for th\
1638
1638
  is panel");S(Ae(cv.command("list",{isDefault:!0})),"Your tokens, without their secrets").option("--all","every account's tokens; needs user:list").action(pD);S(Ae(cv.command("create"),!1),"Create a token; its secret is shown once").requiredOption("--name <name>").option("--human","a person's token, holding their whole role").option("--scopes <a,b>","permissions this token holds, inside your role").option("--expires-in-days <days>","1 to 365; omitted, it is valid until revoked").action(dD);S(Ae(cv.
1639
- command("revoke <id>")),"Revoke a token").action(fD);var Fte=S(G.command("agent"),"What an AI agent needs to know about this host and directory");S(Fte.command("context"),"Where a directory stands on a Portta host, for the start of an agent session; always exits 0").option("--path <dir>","the directory to describe; defaults to the current one").option("--home <dir>","the home directory, where scope.yaml is read from; defaults to $HOME").option("--format <format>","text, or hook for the short tex\
1639
+ command("revoke <id>")),"Revoke a token").action(fD);var Bte=S(G.command("agent"),"What an AI agent needs to know about this host and directory");S(Bte.command("context"),"Where a directory stands on a Portta host, for the start of an agent session; always exits 0").option("--path <dir>","the directory to describe; defaults to the current one").option("--home <dir>","the home directory, where scope.yaml is read from; defaults to $HOME").option("--format <format>","text, or hook for the short tex\
1640
1640
  t an agent hook injects","text").action(LI);var lv=S(G.command("agents"),"Install the Portta layer into AI coding agents on this machine");S(lv.command("install [agents...]"),"Write the instruction, hook and skills for the agents found here (claude, codex, opencode, pi)").option("--home <dir>","use this directory as the home; wins over CLAUDE_CONFIG_DIR and CODEX_HOME").option("--dry-run","print what would change without writing anything").action(KI);S(lv.command("status [agents...]"),"Compare w\
1641
1641
  hat is installed with what should be").option("--home <dir>","use this directory as the home; wins over CLAUDE_CONFIG_DIR and CODEX_HOME").action(JI);S(lv.command("uninstall [agents...]"),"Remove only what the installer wrote: marker blocks, its hook entries and its files").option("--home <dir>","use this directory as the home; wins over CLAUDE_CONFIG_DIR and CODEX_HOME").option("--dry-run","print what would be removed without removing anything").action(YI);var vd=S(G.command("protect"),"Who may\
1642
1642
  open a project hostname: a credential, everybody, or nobody");S(vd.command("status [host]",{isDefault:!0}),"List host decisions without credentials").action((e,t,n)=>xM(e,n));S(vd.command("host <host>"),"Create or rotate a hostname credential").option("--user <name>").option("--password-only","ask for the password alone, with no username").option("--password-stdin").option("--entrypoint <name>").option("--label <text>").option("--project <name>").option("--service <name>").action(wM);S(vd.command(
@@ -1653,5 +1653,5 @@ Actor (PORTTA_ACTOR)"):n}i(Ae,"panelOptions");var pv=S(G.command("docs"),"Read t
1653
1653
  (e,t)=>nv(t));S(xs.command("setup"),"Write the connector configuration from a tunnel token").requiredOption("--zone <domain>","the domain whose wildcard points at the tunnel").option("--token-file <path>","read the tunnel token from a file").option("--origin <url>","where the connector reaches the proxy").option("--apex","serve the zone apex as well as the wildcard").option("--token <value>","refused; use --token-file or the prompt").action(t1);S(xs.command("enable"),"Start the connector").action(
1654
1654
  (e,t)=>n1(t));S(xs.command("disable"),"Stop the connector, keeping the configuration").option("--forget","delete the configuration and credentials too").action(r1);S(xs.command("test"),"Check that the tunnel is carrying traffic").action((e,t)=>s1(t));S(xs.command("logs"),"Show the connector's own output").option("-n, --lines <count>","line count","50").action(o1);var Sd=S(G.command("tls"),"Drive local certificates with openssl");S(Sd.command("status",{isDefault:!0}),"Show certificate and TLS con\
1655
1655
  figuration").action((e,t)=>qM(t));S(Sd.command("init"),"Create a local CA and a wildcard certificate for the domain").action((e,t)=>HM(t));S(Sd.command("trust"),"Print the command to trust the CA on this machine").action((e,t)=>GM(t));S(Sd.command("untrust"),"Print the command to remove it again").action((e,t)=>WM(t));var g1=S(G.command("toolbox"),"Run pinned operational tools in Docker");S(g1.command("build"),"Build the toolbox image").action((e,t)=>VM(t));S(g1.command("run [args...]"),"Run a c\
1656
- ommand in an ephemeral toolbox container").allowUnknownOption(!0).allowExcessArguments(!0).action((e,t,n)=>KM(e,n));function Bte(){for(let e of[process.stdout,process.stderr])e.on("error",t=>{throw t.code==="EPIPE"&&process.exit(0),t})}i(Bte,"tolerateClosedOutput");async function Ute(){Bte();try{if(process.argv.length===2){G.outputHelp();return}await G.parseAsync(process.argv)}catch(e){if(e instanceof Ev){if(e.code==="commander.helpDisplayed"||e.code==="commander.version")return;process.exitCode=
1657
- Fe.usage;return}let t=new A(G.opts());if(e instanceof _e){t.error(e.message),e.hint&&t.hint(e.hint),process.exitCode=e.exitCode;return}t.error(e instanceof Error?e.message:String(e)),process.exitCode=Fe.failure}}i(Ute,"main");await Ute();
1656
+ ommand in an ephemeral toolbox container").allowUnknownOption(!0).allowExcessArguments(!0).action((e,t,n)=>KM(e,n));function Ute(){for(let e of[process.stdout,process.stderr])e.on("error",t=>{throw t.code==="EPIPE"&&process.exit(0),t})}i(Ute,"tolerateClosedOutput");async function qte(){Ute();try{if(process.argv.length===2){G.outputHelp();return}await G.parseAsync(process.argv)}catch(e){if(e instanceof Ev){if(e.code==="commander.helpDisplayed"||e.code==="commander.version")return;process.exitCode=
1657
+ Fe.usage;return}let t=new A(G.opts());if(e instanceof _e){t.error(e.message),e.hint&&t.hint(e.hint),process.exitCode=e.exitCode;return}t.error(e instanceof Error?e.message:String(e)),process.exitCode=Fe.failure}}i(qte,"main");await qte();