modelence 0.26.2 → 0.26.3-dev.1

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.
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import {Command,Option}from'commander';import {readFileSync,promises,createWriteStream,openAsBlob}from'fs';import {fileURLToPath}from'url';import fe,{join,dirname,relative,isAbsolute,resolve,sep}from'path';import {parse}from'dotenv';import {createInterface}from'readline';import {execFile,execSync,spawnSync}from'child_process';import $t from'open';import It from'os';import Fe from'fs/promises';import {createJiti}from'jiti';import {z as z$1}from'zod';import {build}from'tsup';import {loadConfigFromFile,build as build$1,mergeConfig}from'vite';import fo from'archiver';import {promisify}from'util';import {parse as parse$1,printParseErrorCode}from'jsonc-parser';async function I(e,{pick:t,purpose:o,pickEnvironment:n=false,appId:r,hint:i,env:a}={}){let c=t==="deploy"&&a&&Object.keys(a).length>0?a:void 0,p=await fetch(`${e}/api/cli/auth`,{method:"POST",...c?{headers:{"Content-Type":"application/json"},body:JSON.stringify({env:c})}:{}});if(!p.ok)throw new Error("Failed to create CLI authentication code");let{code:s,verificationUrl:l}=await p.json(),u=new URL(l),m=t??(n?"environment":void 0);m&&u.searchParams.set("pick",m),o&&u.searchParams.set("purpose",o),r&&u.searchParams.set("appId",r);for(let[g,T]of Object.entries(i??{}))u.searchParams.set(g,T);console.log(`Please visit ${u} to authenticate`),console.log(`Code: ${s}`);try{await $t(u.toString());}catch{console.log("Could not open a browser automatically. Please open the URL above manually.");}return await Tt(e,s)}var L=class extends Error{};async function Tt(e,t){let r=Date.now()+6e5,i=false;for(;Date.now()<r;){try{let a=await At(e,t);if(a)return a}catch(a){if(a instanceof L)throw a;i||(i=true,console.error("Error polling for CLI token (retrying):",a));}await new Promise(a=>setTimeout(a,2e3));}throw new Error("Unable to authenticate CLI - timed out. Please try again.")}async function At(e,t){let o=await fetch(`${e}/api/cli/token?code=${t}`,{method:"GET"});if(!o.ok){let a=await o.text().catch(()=>"");throw o.status>=400&&o.status<500&&o.status!==429||a.includes("Invalid or expired code")?new L("The sign-in code has expired or is no longer valid. Please run the command again."):new Error(`CLI token polling failed: ${o.status} ${o.statusText}`)}let{token:n,expiresAt:r,target:i}=await o.json();return n?{token:n,expiresAt:r,target:i}:null}var Nt="auth.json",Ot=40*60*1e3;function R(){let e=process.env.MODELENCE_HOME||join(It.homedir(),".modelence");return join(e,Nt)}async function F(){try{let e=JSON.parse(await promises.readFile(R(),"utf8"));return e&&typeof e=="object"?e:{}}catch{return {}}}async function se(e){let t=R();await promises.mkdir(dirname(t),{recursive:true,mode:448}),await promises.writeFile(t,JSON.stringify(e,null,2)+`
3
- `,{mode:384});}async function Se(e){let{hosts:t={}}=await F(),o=t[e];return !o?.token||!o.expiresAt||new Date(o.expiresAt).getTime()-Ot<=Date.now()?null:o.token}async function Pe(e){let{hosts:t={}}=await F();return Object.entries(t).filter(([o,n])=>(!e||o===e)&&!!n?.token).map(([o,n])=>({host:o,token:n.token}))}async function Ce(e,t,o){let n=await F();await se({...n,hosts:{...n.hosts,[e]:{token:t,expiresAt:o}}});}async function U(e){if(!e){await se({});return}let t=await F(),{[e]:o,...n}=t.hosts??{};await se({...t,hosts:n});}var D=".modelence",H="project.json",b="https://cloud.modelence.com";function xe(e=process.cwd()){return join(e,D,H)}async function N(e=process.cwd()){try{let t=await promises.readFile(xe(e),"utf8"),o=JSON.parse(t);return o&&typeof o=="object"?o:{}}catch{return {}}}async function V(e,t=process.cwd()){let o=e(await N(t));await promises.mkdir(join(t,D),{recursive:true}),await promises.writeFile(xe(t),JSON.stringify(o,null,2)+`
4
- `);}function B(e){if(!e||typeof e!="object")return {};let{appId:t,deploy:o}=e;return {...typeof t=="string"&&t?{appId:t}:{},...o&&typeof o.environmentId=="string"?{deploy:o}:{}}}function K(e,t){return B(t===b?e:e.hosts?.[t])}function $e(e,t){let o=Object.keys(e.hosts??{}).filter(n=>B(e.hosts?.[n]).deploy);return B(e).deploy&&o.unshift(b),[...new Set(o)].filter(n=>n!==t)}function z(e,t,o){return t===b?{...e,...o}:{...e,hosts:{...e.hosts,[t]:{...e.hosts?.[t],...o}}}}var E=class extends Error{constructor(o,n){super(o);this.status=n;this.name="StudioApiError";}};async function h(e,t,{method:o="GET",token:n,body:r,query:i}={}){let a=new URL(`${e}${t}`);for(let[s,l]of Object.entries(i??{}))a.searchParams.set(s,String(l));let c={};n&&(c.Authorization=`Bearer ${n}`),r!==void 0&&(c["Content-Type"]="application/json");let p=await fetch(a,{method:o,headers:c,body:r===void 0?void 0:JSON.stringify(r)});if(!p.ok){let s=await p.text(),l=s||p.statusText;try{let u=JSON.parse(s);l=u.error||u.message||l;}catch{}throw new E(l,p.status)}return await p.json()}function J(e){return e instanceof E&&e.status===401}async function Te(e){return process.env.MODELENCE_TOKEN?process.env.MODELENCE_TOKEN:await Se(e)}async function ce(e,t,o){if(o)try{await Ce(e,t,o);}catch(n){console.warn("Could not save the login for next time:",n);}}async function Ae(e,t){let{appId:o,environmentId:n,appAlias:r,envAlias:i}=e;try{await V(a=>z(a,t,{appId:o,deploy:{environmentId:n,appAlias:r,envAlias:i}}));}catch(a){console.warn("Could not record the deploy target in .modelence/project.json:",a);}}function v(e){let t=e.trim().replace(/\/+$/,""),o=/^[a-z][a-z0-9+.-]*:\/\//i.test(t)?t:`https://${t}`,n=URL.canParse(o)?new URL(o):null;if(!n||n.protocol!=="https:"&&n.protocol!=="http:")throw new Error(`Invalid Modelence host "${e}"; expected e.g. https://cloud.modelence.com`);return `${n.origin}${n.pathname.replace(/\/+$/,"")}`}async function G(e,t){if(e)return v(e);if(process.env.MODELENCE_SERVICE_ENDPOINT)return v(process.env.MODELENCE_SERVICE_ENDPOINT);let o={};try{o=parse(await promises.readFile(join(t,".modelence.env"),"utf8"));}catch{}return o.MODELENCE_SERVICE_ENDPOINT?v(o.MODELENCE_SERVICE_ENDPOINT):b}function Ie(e,t){if(!(!process.env.MODELENCE_TOKEN||e||process.env.MODELENCE_SERVICE_ENDPOINT||t===b))throw new Error(`Refusing to send MODELENCE_TOKEN to ${t}, which comes from .modelence.env. Pass --host ${t} or set MODELENCE_SERVICE_ENDPOINT if that is the Studio to deploy to.`)}var pe=".modelence.env";async function Ut(e,t){let o="setupToken"in t?{"X-Modelence-Setup-Token":t.setupToken}:{Authorization:`Bearer ${t.cliToken}`},n=await fetch(`${e}/api/setup`,{method:"GET",headers:o});if(!n.ok){let r=await n.text();throw new Error(r||`Request failed with status ${n.status}`)}return n.json()}async function Ne(e){let t=createInterface({input:process.stdin,output:process.stdout});return new Promise(o=>{t.question(e,n=>{t.close(),o(n.trim());});})}async function Bt(){return (await Ne(`Warning: ${pe} already exists. Do you want to overwrite it? (y/N) `)).toLowerCase()==="y"}function Ht(e){return String(e).replace(/"/g,'\\"')}async function Vt(e){return K(await N(),e).appId}async function Kt(e,t){await V(o=>z(o,t,{appId:e}));}var Oe=".claude",O=join(Oe,"settings.json"),W="modelence@modelence",de="modelence/modelence",zt={modelence:{source:{source:"github",repo:de}}},Jt="https://docs.modelence.com/ai-coding-agents",De=`Install the Modelence plugin for Claude Code by hand:
5
- claude plugin marketplace add ${de}
2
+ import {Command,Option}from'commander';import {readFileSync,promises,createWriteStream,openAsBlob}from'fs';import {fileURLToPath}from'url';import ge,{join,dirname,relative,isAbsolute,resolve,sep}from'path';import {parse}from'dotenv';import {createInterface}from'readline';import {execFile,execSync,spawnSync}from'child_process';import $t from'open';import It from'os';import Ue from'fs/promises';import {createJiti}from'jiti';import {z as z$1}from'zod';import {build}from'tsup';import {loadConfigFromFile,build as build$1,mergeConfig}from'vite';import fo from'archiver';import {promisify}from'util';import {parse as parse$1,printParseErrorCode}from'jsonc-parser';async function I(e,{pick:t,purpose:o,pickEnvironment:n=false,createOnly:r=false,appId:i,hint:a,env:c}={}){let p=t==="deploy"&&c&&Object.keys(c).length>0?c:void 0,s=await fetch(`${e}/api/cli/auth`,{method:"POST",...p?{headers:{"Content-Type":"application/json"},body:JSON.stringify({env:p})}:{}});if(!s.ok)throw new Error("Failed to create CLI authentication code");let{code:l,verificationUrl:m}=await s.json(),d=new URL(m),g=t??(n?"environment":void 0);g&&d.searchParams.set("pick",g),g==="environment"&&r&&d.searchParams.set("new","1"),o&&d.searchParams.set("purpose",o),i&&d.searchParams.set("appId",i);for(let[T,re]of Object.entries(a??{}))d.searchParams.set(T,re);console.log(`Please visit ${d} to authenticate`),console.log(`Code: ${l}`);try{await $t(d.toString());}catch{console.log("Could not open a browser automatically. Please open the URL above manually.");}return await Tt(e,l)}var L=class extends Error{};async function Tt(e,t){let r=Date.now()+6e5,i=false;for(;Date.now()<r;){try{let a=await At(e,t);if(a)return a}catch(a){if(a instanceof L)throw a;i||(i=true,console.error("Error polling for CLI token (retrying):",a));}await new Promise(a=>setTimeout(a,2e3));}throw new Error("Unable to authenticate CLI - timed out. Please try again.")}async function At(e,t){let o=await fetch(`${e}/api/cli/token?code=${t}`,{method:"GET"});if(!o.ok){let a=await o.text().catch(()=>"");throw o.status>=400&&o.status<500&&o.status!==429||a.includes("Invalid or expired code")?new L("The sign-in code has expired or is no longer valid. Please run the command again."):new Error(`CLI token polling failed: ${o.status} ${o.statusText}`)}let{token:n,expiresAt:r,target:i}=await o.json();return n?{token:n,expiresAt:r,target:i}:null}var Nt="auth.json",Ot=40*60*1e3;function R(){let e=process.env.MODELENCE_HOME||join(It.homedir(),".modelence");return join(e,Nt)}async function F(){try{let e=JSON.parse(await promises.readFile(R(),"utf8"));return e&&typeof e=="object"?e:{}}catch{return {}}}async function ae(e){let t=R();await promises.mkdir(dirname(t),{recursive:true,mode:448}),await promises.writeFile(t,JSON.stringify(e,null,2)+`
3
+ `,{mode:384});}async function Pe(e){let{hosts:t={}}=await F(),o=t[e];return !o?.token||!o.expiresAt||new Date(o.expiresAt).getTime()-Ot<=Date.now()?null:o.token}async function Ce(e){let{hosts:t={}}=await F();return Object.entries(t).filter(([o,n])=>(!e||o===e)&&!!n?.token).map(([o,n])=>({host:o,token:n.token}))}async function ke(e,t,o){let n=await F();await ae({...n,hosts:{...n.hosts,[e]:{token:t,expiresAt:o}}});}async function U(e){if(!e){await ae({});return}let t=await F(),{[e]:o,...n}=t.hosts??{};await ae({...t,hosts:n});}var D=".modelence",H="project.json",b="https://cloud.modelence.com";function $e(e=process.cwd()){return join(e,D,H)}async function N(e=process.cwd()){try{let t=await promises.readFile($e(e),"utf8"),o=JSON.parse(t);return o&&typeof o=="object"?o:{}}catch{return {}}}async function V(e,t=process.cwd()){let o=e(await N(t));await promises.mkdir(join(t,D),{recursive:true}),await promises.writeFile($e(t),JSON.stringify(o,null,2)+`
4
+ `);}function B(e){if(!e||typeof e!="object")return {};let{appId:t,deploy:o}=e;return {...typeof t=="string"&&t?{appId:t}:{},...o&&typeof o.environmentId=="string"?{deploy:o}:{}}}function K(e,t){return B(t===b?e:e.hosts?.[t])}function Te(e,t){let o=Object.keys(e.hosts??{}).filter(n=>B(e.hosts?.[n]).deploy);return B(e).deploy&&o.unshift(b),[...new Set(o)].filter(n=>n!==t)}function z(e,t,o){return t===b?{...e,...o}:{...e,hosts:{...e.hosts,[t]:{...e.hosts?.[t],...o}}}}var E=class extends Error{constructor(o,n){super(o);this.status=n;this.name="StudioApiError";}};async function h(e,t,{method:o="GET",token:n,body:r,query:i}={}){let a=new URL(`${e}${t}`);for(let[s,l]of Object.entries(i??{}))a.searchParams.set(s,String(l));let c={};n&&(c.Authorization=`Bearer ${n}`),r!==void 0&&(c["Content-Type"]="application/json");let p=await fetch(a,{method:o,headers:c,body:r===void 0?void 0:JSON.stringify(r)});if(!p.ok){let s=await p.text(),l=s||p.statusText;try{let m=JSON.parse(s);l=m.error||m.message||l;}catch{}throw new E(l,p.status)}return await p.json()}function J(e){return e instanceof E&&e.status===401}async function Ae(e){return process.env.MODELENCE_TOKEN?process.env.MODELENCE_TOKEN:await Pe(e)}async function le(e,t,o){if(o)try{await ke(e,t,o);}catch(n){console.warn("Could not save the login for next time:",n);}}async function Ie(e,t){let{appId:o,environmentId:n,appAlias:r,envAlias:i}=e;try{await V(a=>z(a,t,{appId:o,deploy:{environmentId:n,appAlias:r,envAlias:i}}));}catch(a){console.warn("Could not record the deploy target in .modelence/project.json:",a);}}function v(e){let t=e.trim().replace(/\/+$/,""),o=/^[a-z][a-z0-9+.-]*:\/\//i.test(t)?t:`https://${t}`,n=URL.canParse(o)?new URL(o):null;if(!n||n.protocol!=="https:"&&n.protocol!=="http:")throw new Error(`Invalid Modelence host "${e}"; expected e.g. https://cloud.modelence.com`);return `${n.origin}${n.pathname.replace(/\/+$/,"")}`}async function G(e,t){if(e)return v(e);if(process.env.MODELENCE_SERVICE_ENDPOINT)return v(process.env.MODELENCE_SERVICE_ENDPOINT);let o={};try{o=parse(await promises.readFile(join(t,".modelence.env"),"utf8"));}catch{}return o.MODELENCE_SERVICE_ENDPOINT?v(o.MODELENCE_SERVICE_ENDPOINT):b}function De(e,t){if(!(!process.env.MODELENCE_TOKEN||e||process.env.MODELENCE_SERVICE_ENDPOINT||t===b))throw new Error(`Refusing to send MODELENCE_TOKEN to ${t}, which comes from .modelence.env. Pass --host ${t} or set MODELENCE_SERVICE_ENDPOINT if that is the Studio to deploy to.`)}var de=".modelence.env";async function Ut(e,t){let o="setupToken"in t?{"X-Modelence-Setup-Token":t.setupToken}:{Authorization:`Bearer ${t.cliToken}`},n=await fetch(`${e}/api/setup`,{method:"GET",headers:o});if(!n.ok){let r=await n.text();throw new Error(r||`Request failed with status ${n.status}`)}return n.json()}async function Oe(e){let t=createInterface({input:process.stdin,output:process.stdout});return new Promise(o=>{t.question(e,n=>{t.close(),o(n.trim());});})}async function Bt(){return (await Oe(`Warning: ${de} already exists. Do you want to overwrite it? (y/N) `)).toLowerCase()==="y"}function Ht(e){return String(e).replace(/"/g,'\\"')}async function Vt(e){return K(await N(),e).appId}async function Kt(e,t){await V(o=>z(o,t,{appId:e}));}var _e=".claude",O=join(_e,"settings.json"),W="modelence@modelence",ue="modelence/modelence",zt={modelence:{source:{source:"github",repo:ue}}},Jt="https://docs.modelence.com/ai-coding-agents",Ne=`Install the Modelence plugin for Claude Code by hand:
5
+ claude plugin marketplace add ${ue}
6
6
  claude plugin install ${W} --scope project
7
- Guide: ${Jt}`;async function Gt(){let e=join(process.cwd(),O),t;try{t=await promises.readFile(e,"utf8");}catch(n){if(n.code!=="ENOENT"){console.warn(`Could not read ${O}; leaving it unchanged.`);return}}let o={};if(t!==void 0)try{o=JSON.parse(t);}catch{console.warn(`Could not parse ${O}; leaving it unchanged.`);return}o.extraKnownMarketplaces={...o.extraKnownMarketplaces,...zt},o.enabledPlugins?.[W]===void 0&&(o.enabledPlugins={...o.enabledPlugins,[W]:true});try{await promises.mkdir(join(process.cwd(),Oe),{recursive:!0}),await promises.writeFile(e,JSON.stringify(o,null,2)+`
8
- `),console.log(`Declared the Modelence Claude Code plugin in ${O}`);}catch(n){console.warn(`Failed to write ${O}:`,n);}}function le(e){return spawnSync("claude",e,{encoding:"utf8",shell:process.platform==="win32"})}async function qt(){let e=le(["--version"]);if(e.error||e.status!==0){console.log(De);return}let t=(await Ne("Install the Modelence plugin for Claude Code? (Y/n) ")).toLowerCase();if(t&&t!=="y"&&t!=="yes")return;let o=le(["plugin","marketplace","add",de]),n=le(["plugin","install",W,"--scope","project"]);if(n.status===0)console.log("Installed the Modelence plugin for Claude Code. Sign in once from Claude Code: run /mcp, choose modelence, then Authenticate.");else {let r=o.status!==0?o:n;console.warn(`Could not install the Modelence plugin: ${(r.stderr||r.stdout||"").trim()}`),console.warn(De);}}async function Wt(e){try{let t=e.replace(".env",".backup.env");await promises.copyFile(e,t),console.log(`Backup created at ${t}`);}catch(t){console.warn("Failed to create backup file:",t);}}async function _e(e){try{let t={...e,host:v(e.host)},o=join(process.cwd(),pe),n={},r=!1;try{let s=await promises.readFile(o,"utf8");n=parse(s),r=!0,await Wt(o),await Bt()||(console.log("Setup canceled"),process.exit(0));}catch{}let i;if(t.token)i={setupToken:t.token};else {let{token:s}=await I(t.host,{pickEnvironment:!0,appId:await Vt(t.host)});i={cliToken:s};}console.log("Fetching service configuration...");let a=await Ut(t.host,i),c={...n,MODELENCE_TELEMETRY_ENABLED:"false",MODELENCE_ENVIRONMENT_ID:a.environmentId,MODELENCE_SERVICE_ENDPOINT:t.host,MODELENCE_SERVICE_TOKEN:a.serviceToken,MODELENCE_CONTAINER_ID:a.containerId,MODELENCE_RUNTIME:process.env.MODELENCE_RUNTIME||"local"},p=Object.entries(c).map(([s,l])=>`${s}="${Ht(l)}"`).join(`
7
+ Guide: ${Jt}`;async function Gt(){let e=join(process.cwd(),O),t;try{t=await promises.readFile(e,"utf8");}catch(n){if(n.code!=="ENOENT"){console.warn(`Could not read ${O}; leaving it unchanged.`);return}}let o={};if(t!==void 0)try{o=JSON.parse(t);}catch{console.warn(`Could not parse ${O}; leaving it unchanged.`);return}o.extraKnownMarketplaces={...o.extraKnownMarketplaces,...zt},o.enabledPlugins?.[W]===void 0&&(o.enabledPlugins={...o.enabledPlugins,[W]:true});try{await promises.mkdir(join(process.cwd(),_e),{recursive:!0}),await promises.writeFile(e,JSON.stringify(o,null,2)+`
8
+ `),console.log(`Declared the Modelence Claude Code plugin in ${O}`);}catch(n){console.warn(`Failed to write ${O}:`,n);}}function pe(e){return spawnSync("claude",e,{encoding:"utf8",shell:process.platform==="win32"})}async function qt(){let e=pe(["--version"]);if(e.error||e.status!==0){console.log(Ne);return}let t=(await Oe("Install the Modelence plugin for Claude Code? (Y/n) ")).toLowerCase();if(t&&t!=="y"&&t!=="yes")return;let o=pe(["plugin","marketplace","add",ue]),n=pe(["plugin","install",W,"--scope","project"]);if(n.status===0)console.log("Installed the Modelence plugin for Claude Code. Sign in once from Claude Code: run /mcp, choose modelence, then Authenticate.");else {let r=o.status!==0?o:n;console.warn(`Could not install the Modelence plugin: ${(r.stderr||r.stdout||"").trim()}`),console.warn(Ne);}}async function Wt(e){try{let t=e.replace(".env",".backup.env");await promises.copyFile(e,t),console.log(`Backup created at ${t}`);}catch(t){console.warn("Failed to create backup file:",t);}}async function je(e){try{if(e.new&&e.token)throw new Error("--new cannot be combined with --token");let t={...e,host:v(e.host)},o=join(process.cwd(),de),n={},r=!1;try{let s=await promises.readFile(o,"utf8");n=parse(s),r=!0,await Wt(o),await Bt()||(console.log("Setup canceled"),process.exit(0));}catch{}let i;if(t.token)i={setupToken:t.token};else {let{token:s}=await I(t.host,{pickEnvironment:!0,createOnly:t.new,appId:await Vt(t.host)});i={cliToken:s};}console.log("Fetching service configuration...");let a=await Ut(t.host,i),c={...n,MODELENCE_TELEMETRY_ENABLED:"false",MODELENCE_ENVIRONMENT_ID:a.environmentId,MODELENCE_SERVICE_ENDPOINT:t.host,MODELENCE_SERVICE_TOKEN:a.serviceToken,MODELENCE_CONTAINER_ID:a.containerId,MODELENCE_RUNTIME:process.env.MODELENCE_RUNTIME||"local"},p=Object.entries(c).map(([s,l])=>`${s}="${Ht(l)}"`).join(`
9
9
  `);if(await promises.writeFile(o,p.trim()+`
10
- `),console.log(`Successfully configured ${pe} file`),a.appId)try{await Kt(a.appId,t.host),console.log(`Recorded the app ID in ${D}/${H}`);}catch(s){console.warn(`Failed to record the app ID in ${D}/${H}:`,s);}await Gt(),!t.token&&process.stdin.isTTY&&await qt(),r&&console.log("The project now points to a different environment. Restart your dev server, and if you use an AI coding agent, start a new session."),!r&&c.MODELENCE_RUNTIME==="local"&&(console.log(`
10
+ `),console.log(`Successfully configured ${de} file`),a.appId)try{await Kt(a.appId,t.host),console.log(`Recorded the app ID in ${D}/${H}`);}catch(s){console.warn(`Failed to record the app ID in ${D}/${H}:`,s);}await Gt(),!t.token&&process.stdin.isTTY&&await qt(),r&&console.log("The project now points to a different environment. Restart your dev server, and if you use an AI coding agent, start a new session."),!r&&c.MODELENCE_RUNTIME==="local"&&(console.log(`
11
11
  Next step \u2014 run the app on this machine:
12
12
  `),console.log(" npm install (if you haven't already)"),console.log(` npm run dev (starts the app)
13
- `));}catch(t){console.error(`Setup failed: ${t instanceof Error?t.message:"Unknown error"}`),process.exit(1);}}var Zt=z$1.object({serverDir:z$1.string(),serverEntry:z$1.string(),postBuildCommand:z$1.string().optional()});async function je(){let e=join(process.cwd(),"modelence.config.ts"),o=await createJiti(import.meta.url,{interopDefault:true,requireCache:false}).import(e);if(typeof o!="object")throw new Error("modelence.config.ts should export an object");return Zt.parse(o)}var Me=null,ue=null;function Le(){if(!ue)throw new Error("Configuration not loaded");return ue}function P(){let{serverDir:e,serverEntry:t}=Le();return join(e,t).replace(/\\/g,"/")}function Re(){return Le().postBuildCommand}function X(e){let t=me("build");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}function C(e){return join(process.cwd(),e).replace(/\\/g,"/")}function me(e){let t=C(".modelence");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}async function k(){try{ue=await je();}catch(e){throw console.error(e),new Error("Unable to load modelence.config.ts")}try{let e=await Fe.readFile(join(process.cwd(),".modelence.env"),"utf-8");Me=parse(e);}catch(e){if(e.code==="ENOENT")Me={};else throw e}}async function no(){let e=Re();if(e){console.log("Running post-build command..."),execSync(e);return}await ro(),await io();}async function ro(){console.log("Building client with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),t={build:{outDir:fe.resolve(process.cwd(),".modelence/build/client").replace(/\\/g,"/"),emptyOutDir:true,ssrManifest:true}};await build$1(mergeConfig(e?.config||{},t,true));}async function io(){console.log("Building SSR bundle with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),o={build:{ssr:fe.resolve(process.cwd(),"src/client/index.tsx").replace(/\\/g,"/"),outDir:fe.resolve(process.cwd(),".modelence/build/ssr").replace(/\\/g,"/"),emptyOutDir:true,rollupOptions:{output:{format:"esm",entryFileNames:"index.mjs"}}}};await build$1(mergeConfig(e?.config||{},o,true));}async function so(){return console.log("Building server with tsup..."),new Promise(e=>{build({entry:[P()],format:"esm",sourcemap:true,minify:process.env.NODE_ENV==="production",outDir:".modelence/build",clean:true,watch:false,bundle:true,skipNodeModulesBundle:true,treeshake:true,platform:"node",outExtension:()=>({js:".mjs"}),onSuccess:async()=>{e(void 0);}});})}async function Z(){console.log("Building Modelence project...");try{let e=X();await Fe.rm(e,{recursive:!0,force:!0}),await so(),await no(),console.log("Build completed successfully!");}catch(e){throw console.error(e),new Error("Build failed")}try{await Fe.access(me());}catch{throw new Error("Could not find the .modelence directory. Looks like something went wrong during the build.")}}var Je=promisify(execFile),Ke=200*1024*1024,go=[".git","node_modules",".modelence/build",".modelence/tmp",".modelence/cache"],ho=[/^\.modelence(\.[^/]+)?\.env$/];function Ge(e){return /^\.env(?:\.|$)/.test(e)&&!/\.(example|sample|template)$/.test(e)}function yo(e){return e.split(/\r?\n/).some(t=>{if(/^\s*[#;]/.test(t))return false;let o=/https?:\/\/([^/\s]+)@/.exec(t)?.[1];if(o&&o.replace(/\$\{[A-Za-z_][A-Za-z0-9_]*\}/g,"").replace(/:/g,"")!=="")return true;let n=/^\s*[^=]*?(?:_authToken|_auth|_password|npmAuthToken|npmAuthIdent)["']?\s*[=:]\s*(.*?)\s*$/i.exec(t);if(!n)return false;let r=n[1].replace(/\s+#.*$/,"").replace(/^["']|["']$/g,"").trim();return r!==""&&!/^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(r)})}function Q(e){return e.split(sep).join("/")}function wo(e){return he(e)||Ge(Q(e).split("/").at(-1)??"")}function he(e){let t=Q(e),o=t.split("/");for(let r of go)if(r.split("/").length===1){if(o.slice(0,-1).includes(r))return true}else if(t===r||t.startsWith(`${r}/`))return true;let n=o[o.length-1];return ho.some(r=>r.test(n))}async function Eo(e){try{let{stdout:t}=await Je("git",["rev-parse","--is-inside-work-tree"],{cwd:e});return t.trim()==="true"}catch{return false}}async function ze(e,t){let{stdout:o}=await Je("git",["ls-files",...t,"-z"],{cwd:e,maxBuffer:67108864});return o.split("\0").filter(n=>n.length>0)}async function qe(e,t=""){let o=await promises.readdir(join(e,t),{withFileTypes:true}),n=[];for(let r of o){let i=t?`${t}/${r.name}`:r.name;r.isDirectory()?wo(`${i}/x`)||n.push(...await qe(e,i)):(r.isFile()||r.isSymbolicLink())&&n.push(i);}return n}async function vo(e,t){let o=join(e,t),n=await promises.readlink(o),r=resolve(dirname(o),n),i=relative(e,r);return i.startsWith("..")||isAbsolute(i)?null:{path:t,target:Q(relative(dirname(o),r))||"."}}async function bo(e=process.cwd()){let t=await Eo(e),o=new Set(t?await ze(e,["--cached"]):[]),n=t?[...o,...await ze(e,["--others","--exclude-standard"])]:await qe(e),r={files:[],symlinks:[],usedGit:t,excludedFiles:[],skipped:[],committedEnvFiles:[]};for(let i of n){let a=i.split("/").at(-1)??"",c=Ge(a);if(he(i)||c&&!o.has(i)){r.excludedFiles.push(i);continue}let p;try{p=await promises.lstat(join(e,i));}catch{continue}if(p.isSymbolicLink()){if(he(`${i}/x`)){r.excludedFiles.push(i);continue}let s=await vo(e,i);s?r.symlinks.push(s):r.skipped.push({path:i,reason:"symlink to outside the project"});}else if(p.isDirectory())r.skipped.push({path:i,reason:"git submodule"});else if(p.isFile()){if([".npmrc",".yarnrc.yml",".yarnrc"].includes(a)&&yo(await promises.readFile(join(e,i),"utf8"))){r.excludedFiles.push(i);continue}r.files.push(i),c&&r.committedEnvFiles.push(i);}}return {...r,files:r.files.sort(),symlinks:r.symlinks.sort((i,a)=>i.path.localeCompare(a.path)),excludedFiles:r.excludedFiles.sort(),committedEnvFiles:r.committedEnvFiles.sort()}}async function We(e,t){let{files:o,symlinks:n,...r}=await bo(e);if(o.length===0)throw new Error("No files to upload");await promises.mkdir(join(t,".."),{recursive:true}),await promises.rm(t,{force:true});let i=createWriteStream(t),a=fo("zip",{zlib:{level:6}}),c=new Promise((s,l)=>{i.on("close",s),i.on("error",l),a.on("error",l);});a.pipe(i);for(let s of o)a.file(join(e,s),{name:Q(relative("",s))});for(let s of n)a.symlink(s.path,s.target,511);await Promise.all([a.finalize(),c]);let{size:p}=await promises.stat(t);if(p>Ke)throw await promises.rm(t,{force:true}),new Error(`Source is ${(p/1024/1024).toFixed(0)} MB compressed; the limit is ${Ke/1024/1024} MB. Add build output and large assets to .gitignore.`);return {...r,fileCount:o.length+n.length,sizeBytes:p}}var d="modelence.config.json",ko=1,j="https://docs.modelence.com/deploy/setup",ee=`Use ${j}.md to set up Modelence deployment for this project`;function Ze(e){return `${e.replace(/\/$/,"")}/schema/${d}?version=${ko}`}function te(e=process.cwd()){return join(e,d)}async function $(e=process.cwd()){let t;try{t=await promises.readFile(te(e),"utf8");}catch{return null}let o=[],n=parse$1(t,o,{allowTrailingComma:true,disallowComments:false});if(o.length>0)throw new Error(`${d} is not valid JSON: ${xo(t,o[0])}`);if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`${d} must contain a JSON object`);return n}function xo(e,t){let o=e.slice(0,t.offset),n=o.split(`
13
+ `));}catch(t){console.error(`Setup failed: ${t instanceof Error?t.message:"Unknown error"}`),process.exit(1);}}var Zt=z$1.object({serverDir:z$1.string(),serverEntry:z$1.string(),postBuildCommand:z$1.string().optional()});async function Me(){let e=join(process.cwd(),"modelence.config.ts"),o=await createJiti(import.meta.url,{interopDefault:true,requireCache:false}).import(e);if(typeof o!="object")throw new Error("modelence.config.ts should export an object");return Zt.parse(o)}var Le=null,me=null;function Re(){if(!me)throw new Error("Configuration not loaded");return me}function P(){let{serverDir:e,serverEntry:t}=Re();return join(e,t).replace(/\\/g,"/")}function Fe(){return Re().postBuildCommand}function X(e){let t=fe("build");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}function C(e){return join(process.cwd(),e).replace(/\\/g,"/")}function fe(e){let t=C(".modelence");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}async function k(){try{me=await Me();}catch(e){throw console.error(e),new Error("Unable to load modelence.config.ts")}try{let e=await Ue.readFile(join(process.cwd(),".modelence.env"),"utf-8");Le=parse(e);}catch(e){if(e.code==="ENOENT")Le={};else throw e}}async function no(){let e=Fe();if(e){console.log("Running post-build command..."),execSync(e);return}await ro(),await io();}async function ro(){console.log("Building client with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),t={build:{outDir:ge.resolve(process.cwd(),".modelence/build/client").replace(/\\/g,"/"),emptyOutDir:true,ssrManifest:true}};await build$1(mergeConfig(e?.config||{},t,true));}async function io(){console.log("Building SSR bundle with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),o={build:{ssr:ge.resolve(process.cwd(),"src/client/index.tsx").replace(/\\/g,"/"),outDir:ge.resolve(process.cwd(),".modelence/build/ssr").replace(/\\/g,"/"),emptyOutDir:true,rollupOptions:{output:{format:"esm",entryFileNames:"index.mjs"}}}};await build$1(mergeConfig(e?.config||{},o,true));}async function so(){return console.log("Building server with tsup..."),new Promise(e=>{build({entry:[P()],format:"esm",sourcemap:true,minify:process.env.NODE_ENV==="production",outDir:".modelence/build",clean:true,watch:false,bundle:true,skipNodeModulesBundle:true,treeshake:true,platform:"node",outExtension:()=>({js:".mjs"}),onSuccess:async()=>{e(void 0);}});})}async function Z(){console.log("Building Modelence project...");try{let e=X();await Ue.rm(e,{recursive:!0,force:!0}),await so(),await no(),console.log("Build completed successfully!");}catch(e){throw console.error(e),new Error("Build failed")}try{await Ue.access(fe());}catch{throw new Error("Could not find the .modelence directory. Looks like something went wrong during the build.")}}var Ge=promisify(execFile),ze=200*1024*1024,go=[".git","node_modules",".modelence/build",".modelence/tmp",".modelence/cache"],ho=[/^\.modelence(\.[^/]+)?\.env$/];function qe(e){return /^\.env(?:\.|$)/.test(e)&&!/\.(example|sample|template)$/.test(e)}function wo(e){return e.split(/\r?\n/).some(t=>{if(/^\s*[#;]/.test(t))return false;let o=/https?:\/\/([^/\s]+)@/.exec(t)?.[1];if(o&&o.replace(/\$\{[A-Za-z_][A-Za-z0-9_]*\}/g,"").replace(/:/g,"")!=="")return true;let n=/^\s*[^=]*?(?:_authToken|_auth|_password|npmAuthToken|npmAuthIdent)["']?\s*[=:]\s*(.*?)\s*$/i.exec(t);if(!n)return false;let r=n[1].replace(/\s+#.*$/,"").replace(/^["']|["']$/g,"").trim();return r!==""&&!/^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/.test(r)})}function Q(e){return e.split(sep).join("/")}function yo(e){return we(e)||qe(Q(e).split("/").at(-1)??"")}function we(e){let t=Q(e),o=t.split("/");for(let r of go)if(r.split("/").length===1){if(o.slice(0,-1).includes(r))return true}else if(t===r||t.startsWith(`${r}/`))return true;let n=o[o.length-1];return ho.some(r=>r.test(n))}async function Eo(e){try{let{stdout:t}=await Ge("git",["rev-parse","--is-inside-work-tree"],{cwd:e});return t.trim()==="true"}catch{return false}}async function Je(e,t){let{stdout:o}=await Ge("git",["ls-files",...t,"-z"],{cwd:e,maxBuffer:67108864});return o.split("\0").filter(n=>n.length>0)}async function We(e,t=""){let o=await promises.readdir(join(e,t),{withFileTypes:true}),n=[];for(let r of o){let i=t?`${t}/${r.name}`:r.name;r.isDirectory()?yo(`${i}/x`)||n.push(...await We(e,i)):(r.isFile()||r.isSymbolicLink())&&n.push(i);}return n}async function vo(e,t){let o=join(e,t),n=await promises.readlink(o),r=resolve(dirname(o),n),i=relative(e,r);return i.startsWith("..")||isAbsolute(i)?null:{path:t,target:Q(relative(dirname(o),r))||"."}}async function bo(e=process.cwd()){let t=await Eo(e),o=new Set(t?await Je(e,["--cached"]):[]),n=t?[...o,...await Je(e,["--others","--exclude-standard"])]:await We(e),r={files:[],symlinks:[],usedGit:t,excludedFiles:[],skipped:[],committedEnvFiles:[]};for(let i of n){let a=i.split("/").at(-1)??"",c=qe(a);if(we(i)||c&&!o.has(i)){r.excludedFiles.push(i);continue}let p;try{p=await promises.lstat(join(e,i));}catch{continue}if(p.isSymbolicLink()){if(we(`${i}/x`)){r.excludedFiles.push(i);continue}let s=await vo(e,i);s?r.symlinks.push(s):r.skipped.push({path:i,reason:"symlink to outside the project"});}else if(p.isDirectory())r.skipped.push({path:i,reason:"git submodule"});else if(p.isFile()){if([".npmrc",".yarnrc.yml",".yarnrc"].includes(a)&&wo(await promises.readFile(join(e,i),"utf8"))){r.excludedFiles.push(i);continue}r.files.push(i),c&&r.committedEnvFiles.push(i);}}return {...r,files:r.files.sort(),symlinks:r.symlinks.sort((i,a)=>i.path.localeCompare(a.path)),excludedFiles:r.excludedFiles.sort(),committedEnvFiles:r.committedEnvFiles.sort()}}async function Ye(e,t){let{files:o,symlinks:n,...r}=await bo(e);if(o.length===0)throw new Error("No files to upload");await promises.mkdir(join(t,".."),{recursive:true}),await promises.rm(t,{force:true});let i=createWriteStream(t),a=fo("zip",{zlib:{level:6}}),c=new Promise((s,l)=>{i.on("close",s),i.on("error",l),a.on("error",l);});a.pipe(i);for(let s of o)a.file(join(e,s),{name:Q(relative("",s))});for(let s of n)a.symlink(s.path,s.target,511);await Promise.all([a.finalize(),c]);let{size:p}=await promises.stat(t);if(p>ze)throw await promises.rm(t,{force:true}),new Error(`Source is ${(p/1024/1024).toFixed(0)} MB compressed; the limit is ${ze/1024/1024} MB. Add build output and large assets to .gitignore.`);return {...r,fileCount:o.length+n.length,sizeBytes:p}}var u="modelence.config.json",ko=1,j="https://docs.modelence.com/deploy/setup",ee=`Use ${j}.md to set up Modelence deployment for this project`;function Qe(e){return `${e.replace(/\/$/,"")}/schema/${u}?version=${ko}`}function te(e=process.cwd()){return join(e,u)}async function $(e=process.cwd()){let t;try{t=await promises.readFile(te(e),"utf8");}catch{return null}let o=[],n=parse$1(t,o,{allowTrailingComma:true,disallowComments:false});if(o.length>0)throw new Error(`${u} is not valid JSON: ${xo(t,o[0])}`);if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`${u} must contain a JSON object`);return n}function xo(e,t){let o=e.slice(0,t.offset),n=o.split(`
14
14
  `).length,r=t.offset-o.lastIndexOf(`
15
- `);return `${printParseErrorCode(t.error)} at line ${n}, column ${r}`}async function Qe(e,t=process.cwd()){await promises.writeFile(te(t),JSON.stringify(e,null,2)+`
16
- `);}function et(e){let t=[],o=Object.entries(e.resources??{});for(let[n,r]of o){o.length>1&&t.push(` resource: ${n}`),t.push(` image: ${r.image??"default (node-22-slim)"}`),r.root&&r.root!=="."&&t.push(` root: ${r.root}`),t.push(...Ye("build",r.build,"default (npm install)")),t.push(...Ye("start",r.start,"(none)"));for(let i of r.static??[])t.push(` static: ${i.path} -> ${i.dir}/`);}for(let[n,r]of Object.entries(e.env??{}))t.push(` env: ${n} (${r.type??"text"})`);return t}function Ye(e,t,o){let n=` ${`${e}:`.padEnd(8)} `;return t?t.commands.length===0?[`${n}(none)`]:t.commands.map(r=>`${n}${r}`):[`${n}${o}`]}async function nt(e,t="."){if(typeof t!="string"||isAbsolute(t))throw new Error("root must be a relative directory inside the project.");let o=await promises.realpath(e),n=resolve(o,t);if(!tt(o,n))throw new Error("root must stay inside the project.");let r;try{r=await promises.realpath(n);}catch{throw new Error(`root "${t}" does not exist.`)}if(!tt(o,r)||!(await promises.stat(r)).isDirectory())throw new Error("root must be a directory inside the project.");return r}function tt(e,t){let o=relative(e,t);return o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}var rt=["$schema","resources","env"];async function it(e){let t=await $(e);if(!t)throw new Error(Io(e));Do(t);for(let o of Object.values(t.resources??{}))o?.root!==void 0&&await nt(e,o.root);console.log(`Build plan (${d}):`);for(let o of et(t))console.log(o);return t}function Io(e){return [`${d} not found in ${e}.`,"Modelence Cloud builds and runs your app exactly as this file describes (install, build and start commands, Node.js version, static directories).","Ask your coding agent to create it with this prompt:","",` ${ee}`,"",`Reference: ${j}`].join(`
17
- `)}function Do(e){let t=Object.keys(e).filter(o=>!rt.includes(o));if(t.length>0)throw new Error(`${d} has unknown key "${t[0]}" (allowed: ${rt.join(", ")}).`);for(let o of ["resources","env"]){let n=e[o];if(n!==void 0&&(!n||typeof n!="object"||Array.isArray(n)))throw new Error(`${d}: "${o}" must be an object.`)}for(let[o,n]of Object.entries(e.resources??{})){if(!st(n))throw new Error(`${d}: "resources.${o}" must be an object.`);for(let r of ["build","start"])No(n[r],`resources.${o}.${r}`);}}function No(e,t){if(e!==void 0){if(!st(e)||!Array.isArray(e.commands))throw new Error(`${d}: "${t}" must be an object with a "commands" array, e.g. { "commands": ["npm ci"] }.`);e.commands.forEach((o,n)=>{if(typeof o!="string")throw new Error(`${d}: "${t}.commands.${n}" must be a string.`);if(o.trim()==="")throw new Error(`${d}: "${t}.commands.${n}" must not be empty.`)});}}function st(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}async function at(e,t){return t.prebuilt?{kind:"bundle",reason:"prebuilt-flag"}:await $(e)!==null?{kind:"source",reason:"spec-file"}:await jo(e)?{kind:"bundle",reason:"modelence-dependency"}:{kind:"source",reason:"default"}}function ct(e){return e.reason!=="modelence-dependency"?null:`No ${d} found; this is a Modelence app, so it is built locally and uploaded as before. Add a ${d} to build it on Modelence Cloud instead.`}async function jo(e){let t;try{t=await promises.readFile(join(e,"package.json"),"utf8");}catch{return false}let o;try{o=JSON.parse(t);}catch{return false}if(!o||typeof o!="object")return false;let n=o;return ["dependencies","devDependencies"].some(r=>{let i=n[r];return !!(i&&typeof i=="object"&&"modelence"in i)})}function lt(e,t,o=[]){if(e.app&&e.env)return {appAlias:e.app,envAlias:e.env};if(e.env&&t.deploy?.appAlias)return {appAlias:t.deploy.appAlias,envAlias:e.env};if(e.env&&t.appId)return {appId:t.appId,envAlias:e.env};if(e.env&&!e.app&&o.length>0)throw new Error(`--env needs --app here: ${oe(o)} Pass --app too, or --host to deploy there.`);if(e.app||e.env)throw new Error("Pass both --app and --env, or neither to pick the target in the browser.");return t.deploy?.environmentId?{environmentId:t.deploy.environmentId}:null}function oe(e){return `the target saved in .modelence/project.json is for ${e.join(", ")}, not this Studio.`}function pt(){return !!process.env.CI}function ne(e,t,{deployAgain:o=false}={}){if(!e||e.length===0)return null;let n=e.length===1,r=t?` Set ${n?"it":"them"} at ${t}`:"";return `${e.join(", ")} ${n?"is":"are"} declared in ${d} but ${n?"has":"have"} no value in this environment.`+(r?r+(o?", then deploy again.":""):"")}var dt=3e3,Mo=30*60*1e3,Lo=10*60*1e3;async function ut(e,t,o){let n=Date.now()+Lo,r=false;for(;Date.now()<n;){let i;try{({status:i}=await h(e,"/api/environment/status",{token:t,query:{environmentId:o}}));}catch(a){if(a instanceof E&&a.status===404)return false;throw a}if(i==="ready")return r;if(i==="failed")throw new Error("The environment failed to provision; check it in the dashboard.");r||(console.log("Waiting for the environment to finish provisioning..."),r=true),await new Promise(a=>setTimeout(a,dt));}throw new Error("Timed out waiting for the environment to be ready.")}async function mt(e,t,o,n){let r=Date.now()+Mo,i="",a="",c=null,p=false;for(;Date.now()<r;){let s;try{s=await h(e.host,"/api/deploy/status",{token:e.token,query:{environmentId:o,buildId:n,...c?{logCursor:c}:{}}});}catch(l){if(!J(l)||p)throw l;p=true,await t();continue}for(let l of s.logs)process.stdout.write(` \u2502 ${l.replace(/\n$/,"")}
18
- `);if(c=s.logCursor??c,s.status!==i){i=s.status;let l=Ro(s);l&&l!==a&&(a=l,console.log(l));}if(s.status==="deploy-completed"){s.siteUrl&&console.log(`Live at ${s.siteUrl}`);return}if(s.status==="build-failed"||s.status==="deploy-failed"){let l=s.containerLogs??[],u=ne(s.missingEnvVars,s.configUrl,{deployAgain:s.errors.length===0&&l.length===0});u&&console.error(u);for(let m of s.errors)console.error(` ${m}`);if(l.length>0){console.error("Container output:");for(let m of l)console.error(` \u2502 ${m.replace(/\n$/,"")}`);}process.exitCode=1;return}await new Promise(l=>setTimeout(l,dt));}console.error("Timed out waiting for the deployment; check the dashboard for its status."),process.exitCode=1;}function Ro(e){switch(e.status){case "build-pending":return "Building image...";case "deploy-pending":case "deploying":return "Image built. Deploying containers...";case "rolling-out":return "Rolling out new containers...";case "deploy-completed":return "Deployed successfully.";case "build-failed":return "Build failed.";case "deploy-failed":return "Deployment failed.";default:return null}}async function ft({session:e,target:t,kind:o,archivePath:n,spec:r,checkEnv:i}){let{host:a,token:c}=e,p=()=>h(a,"/api/upload-bundle",{method:"POST",token:c,body:{...t,kind:o}}),s=await p();if(!s.environmentId)throw new Error("Modelence Cloud is too old for this CLI version (no environment id from /api/upload-bundle). Try again later, or deploy with modelence@0.25.");await ut(a,c,s.environmentId)&&(s=await p()),console.log(`Uploading to ${s.appAlias}/${s.envAlias}...`);let l=await openAsBlob(n,{type:"application/zip"}),u=await fetch(s.uploadUrl,{method:"PUT",body:l,headers:{"Content-Type":"application/zip"}});if(!u.ok)throw new Error(`Failed to upload: ${await Uo(u)}`);let m=await h(a,"/api/deploy",{method:"POST",token:c,body:{environmentId:s.environmentId,bundleName:s.bundleName,kind:o,spec:r,...i?{checkEnv:i}:{}}});console.log(`Deployment started: ${m.deploymentUrl}`);let g=ne(m.missingEnvVars,m.configUrl);return g&&console.warn(`Warning: ${g}`),{environmentId:m.environmentId,buildId:m.buildId}}async function Uo(e){let t=await e.text().catch(()=>""),o=t.match(/<Code>([^<]+)<\/Code>/)?.[1],n=t.match(/<Message>([^<]+)<\/Message>/)?.[1],r=e.statusText||`HTTP ${e.status}`;return o?`${r} (${o}${n?`: ${n}`:""})`:r}async function wt(e){let t=process.cwd(),o=await G(e.host,t);Ie(e.host,o);let n=await at(t,e),r=n.kind,i=ct(n);i&&console.log(i);let a=await N(t),c=K(a,o),p=c.deploy?[]:$e(a,o),s=pt(),l=lt(e,c,p),u=s?await Te(o):null;if(s&&(!u||!l))throw new Error(Vo(!!u,!!l,p));!s&&!l&&p.length>0&&console.log(`Note: ${oe(p)} Pick a target for ${o} in the browser, or pass --host to deploy there.`);let m,g=join(t,".modelence","tmp",`${r}.zip`);r==="bundle"?(m=await $(t)??void 0,await k(),await Z(),await zo(g)):(m=await it(t),Ko(await We(t,g)));try{let T=l;if(!s){let f=await I(o,{pick:"deploy",purpose:"deploy",appId:c.appId,hint:l??void 0,env:m?.env});if(u=f.token,await ce(o,f.token,f.expiresAt),!f.target)throw new Error("No deploy target selected. Run again and pick an environment in the browser.");T={environmentId:f.target.environmentId},await Ae(f.target,o);}if(!u||!T)throw new Error("No token or deploy target to deploy with.");let kt=T,re={host:o,token:u},Ee=async()=>{if(await U(o),s)throw new Error("Modelence Cloud rejected the token (expired or revoked), and CI deploys never sign in again in the browser. Set a fresh MODELENCE_TOKEN. A deployment that already started keeps running; check the dashboard.");console.log("Your login has expired; please sign in again.");let f=await I(o,{purpose:"deploy",appId:c.appId});await ce(o,f.token,f.expiresAt),re.token=f.token;},xt=s&&!e.skipEnvCheck,ve=()=>ft({session:re,target:kt,kind:r,archivePath:g,spec:m,checkEnv:xt}),A;try{A=await ve();}catch(f){if(!J(f))throw f;await Ee(),A=await ve();}A.buildId&&await mt(re,Ee,A.environmentId,A.buildId);}finally{await promises.rm(g,{force:true});}}function Vo(e,t,o){let n=[t?null:"pass --app and --env",e?null:"set MODELENCE_TOKEN"].filter(Boolean),r=!t&&o.length>0?` Note: ${oe(o)} Pass --host to deploy there.`:"";return `CI deploys never open the browser to sign in or pick a target. To deploy from here, ${n.join(" and ")}.${r}`}var gt=10;function ht(e){let t=e.slice(0,gt).join(", "),o=e.length-gt;return o>0?`${t} and ${o} more`:t}function Ko(e){console.log(`Packed ${e.fileCount} files (${Et(e.sizeBytes)})`+(e.usedGit?" from git":"; not a git repository, so only default exclusions applied")),e.excludedFiles.length>0&&console.log(`Not uploaded (local, generated or credentials; store secrets in the target environment): ${ht(e.excludedFiles)}`),e.committedEnvFiles.length>0&&console.log(`Uploaded environment files committed to git: ${ht(e.committedEnvFiles)}`);for(let{path:t,reason:o}of e.skipped)console.warn(`Warning: ${t} is not uploaded (${o}).`);}function Et(e){return `${(e/1024/1024).toFixed(2)} MB`}async function zo(e){await promises.rm(e,{force:true}),console.log("Creating deployment bundle..."),await promises.mkdir(join(e,".."),{recursive:true});let t=createWriteStream(e),o=fo("zip",{zlib:{level:9}}),n=new Promise((c,p)=>{t.on("close",c),t.on("error",p),o.on("error",p);});o.pipe(t);let r=["package.json","package-lock.json","next.config.js","next.config.ts","modelence.config.ts"],i=["public","server","scripts",join(".modelence","build"),".next"];for(let c of r)await yt(C(c))&&o.file(C(c),{name:c});for(let c of i)await yt(C(c))&&o.directory(C(c),c);await o.finalize(),await n;let a=await promises.stat(e);console.log(`Deployment bundle created (${Et(a.size)})`);}async function yt(e){try{return await promises.access(e),!0}catch{return false}}function vt(e={}){console.log("Starting Modelence dev server...");let t=P(),o=fe.resolve("./node_modules/.bin/tsx");execSync(`"${o}" watch --ignore "vite.config.ts.timestamp-*" "${t}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"development",...e.takeover?{MODELENCE_TAKEOVER:"1"}:{}}});}function St(){console.log("Starting Modelence production server...");let e=P(),t=fe.basename(e,fe.extname(e)),o=X(`${t}.mjs`);execSync(`node "${o}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"production"}});}async function Pt(e){let t=e.host?v(e.host):void 0,o=await Pe(t);await Promise.all(o.map(n=>Wo(n.host,n.token))),await U(t),console.log(t?`Removed the saved login for ${t}.`:`Removed saved logins (${R()}).`);}async function Wo(e,t){try{await h(e,"/api/cli/logout",{method:"POST",token:t});}catch{}}async function Ct(e){let t=process.cwd(),o=te(t);if(!e.force&&await Xo(o))throw new Error(`${d} already exists; pass --force to overwrite it.`);let n=await G(e.host,t),r={$schema:Ze(n),resources:{app:{type:"service",image:"node-22-slim",build:{commands:["npm ci"]},static:[]}},env:{}};await Qe(r,t),console.log(`Wrote a ${d} template.`),console.log("Ask your coding agent to fill it in with this prompt:"),console.log(""),console.log(` ${ee}`),console.log(""),console.log(`Reference: ${j}`),console.log(`Once ${d} describes your app, run \`npx modelence@latest deploy\`.`);}async function Xo(e){try{return await promises.access(e),!0}catch{return false}}var rn=fileURLToPath(import.meta.url),sn=dirname(rn),an=JSON.parse(readFileSync(join(sn,"../../package.json"),"utf-8")),w=new Command().name("modelence").description("Modelence CLI tool").version(an.version);w.command("setup").description("Setup Modelence environment variables").option("-t, --token <token>","Modelence setup token (omit to authorize in the browser)").option("-h, --host <host>","Modelence host","https://cloud.modelence.com").action(async e=>{await _e(e);});w.command("build").description("Build the application").action(async()=>{await k(),await Z();});w.command("deploy").description("Deploy the project described by modelence.config.json to Modelence Cloud (picks the target in the browser; in CI from --app/--env or the saved target)").option("-a, --app <app>","Application alias (preselected in the browser; the target in CI)").option("-e, --env <env>","Environment alias (preselected in the browser; the target in CI)").option("-h, --host <host>","Modelence host").option("--prebuilt","Build locally and upload the .modelence/build bundle (Modelence apps only)").option("--skip-env-check","In CI, deploy even when variables modelence.config.json requires have no value").addOption(new Option("-y, --yes").hideHelp()).action(async e=>{try{await wt(e);}catch(t){console.error(`Deploy failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});w.command("init").description("Create a modelence.config.json template for this project").option("--force","Overwrite an existing modelence.config.json").option("-h, --host <host>","Modelence host used for the schema URL").action(async e=>{try{await Ct(e);}catch(t){console.error(`Init failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});w.command("logout").description("Forget the saved Modelence Cloud login").option("-h, --host <host>","Only forget the login for this host").action(async e=>{await Pt(e);});w.command("dev").description("Start development server").option("--takeover","Disconnect any instance currently holding the environment and connect this one").action(async e=>{await k(),vt(e);});w.command("start").description("Start production server").action(async()=>{await k(),St();});w.parse(process.argv);//# sourceMappingURL=modelence.js.map
15
+ `);return `${printParseErrorCode(t.error)} at line ${n}, column ${r}`}async function et(e,t=process.cwd()){await promises.writeFile(te(t),JSON.stringify(e,null,2)+`
16
+ `);}function tt(e){let t=[],o=Object.entries(e.resources??{});for(let[n,r]of o){o.length>1&&t.push(` resource: ${n}`),t.push(` image: ${r.image??"default (node-22-slim)"}`),r.root&&r.root!=="."&&t.push(` root: ${r.root}`),t.push(...Xe("build",r.build,"default (npm install)")),t.push(...Xe("start",r.start,"(none)"));for(let i of r.static??[])t.push(` static: ${i.path} -> ${i.dir}/`);}for(let[n,r]of Object.entries(e.env??{}))t.push(` env: ${n} (${r.type??"text"})`);return t}function Xe(e,t,o){let n=` ${`${e}:`.padEnd(8)} `;return t?t.commands.length===0?[`${n}(none)`]:t.commands.map(r=>`${n}${r}`):[`${n}${o}`]}async function rt(e,t="."){if(typeof t!="string"||isAbsolute(t))throw new Error("root must be a relative directory inside the project.");let o=await promises.realpath(e),n=resolve(o,t);if(!ot(o,n))throw new Error("root must stay inside the project.");let r;try{r=await promises.realpath(n);}catch{throw new Error(`root "${t}" does not exist.`)}if(!ot(o,r)||!(await promises.stat(r)).isDirectory())throw new Error("root must be a directory inside the project.");return r}function ot(e,t){let o=relative(e,t);return o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}var it=["$schema","resources","env"];async function st(e){let t=await $(e);if(!t)throw new Error(Io(e));Do(t);for(let o of Object.values(t.resources??{}))o?.root!==void 0&&await rt(e,o.root);console.log(`Build plan (${u}):`);for(let o of tt(t))console.log(o);return t}function Io(e){return [`${u} not found in ${e}.`,"Modelence Cloud builds and runs your app exactly as this file describes (install, build and start commands, Node.js version, static directories).","Ask your coding agent to create it with this prompt:","",` ${ee}`,"",`Reference: ${j}`].join(`
17
+ `)}function Do(e){let t=Object.keys(e).filter(o=>!it.includes(o));if(t.length>0)throw new Error(`${u} has unknown key "${t[0]}" (allowed: ${it.join(", ")}).`);for(let o of ["resources","env"]){let n=e[o];if(n!==void 0&&(!n||typeof n!="object"||Array.isArray(n)))throw new Error(`${u}: "${o}" must be an object.`)}for(let[o,n]of Object.entries(e.resources??{})){if(!at(n))throw new Error(`${u}: "resources.${o}" must be an object.`);for(let r of ["build","start"])No(n[r],`resources.${o}.${r}`);}}function No(e,t){if(e!==void 0){if(!at(e)||!Array.isArray(e.commands))throw new Error(`${u}: "${t}" must be an object with a "commands" array, e.g. { "commands": ["npm ci"] }.`);e.commands.forEach((o,n)=>{if(typeof o!="string")throw new Error(`${u}: "${t}.commands.${n}" must be a string.`);if(o.trim()==="")throw new Error(`${u}: "${t}.commands.${n}" must not be empty.`)});}}function at(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}async function ct(e,t){return t.prebuilt?{kind:"bundle",reason:"prebuilt-flag"}:await $(e)!==null?{kind:"source",reason:"spec-file"}:await jo(e)?{kind:"bundle",reason:"modelence-dependency"}:{kind:"source",reason:"default"}}function lt(e){return e.reason!=="modelence-dependency"?null:`No ${u} found; this is a Modelence app, so it is built locally and uploaded as before. Add a ${u} to build it on Modelence Cloud instead.`}async function jo(e){let t;try{t=await promises.readFile(join(e,"package.json"),"utf8");}catch{return false}let o;try{o=JSON.parse(t);}catch{return false}if(!o||typeof o!="object")return false;let n=o;return ["dependencies","devDependencies"].some(r=>{let i=n[r];return !!(i&&typeof i=="object"&&"modelence"in i)})}function pt(e,t,o=[]){if(e.app&&e.env)return {appAlias:e.app,envAlias:e.env};if(e.env&&t.deploy?.appAlias)return {appAlias:t.deploy.appAlias,envAlias:e.env};if(e.env&&t.appId)return {appId:t.appId,envAlias:e.env};if(e.env&&!e.app&&o.length>0)throw new Error(`--env needs --app here: ${oe(o)} Pass --app too, or --host to deploy there.`);if(e.app||e.env)throw new Error("Pass both --app and --env, or neither to pick the target in the browser.");return t.deploy?.environmentId?{environmentId:t.deploy.environmentId}:null}function oe(e){return `the target saved in .modelence/project.json is for ${e.join(", ")}, not this Studio.`}function dt(){return !!process.env.CI}function ne(e,t,{deployAgain:o=false}={}){if(!e||e.length===0)return null;let n=e.length===1,r=t?` Set ${n?"it":"them"} at ${t}`:"";return `${e.join(", ")} ${n?"is":"are"} declared in ${u} but ${n?"has":"have"} no value in this environment.`+(r?r+(o?", then deploy again.":""):"")}var ut=3e3,Mo=30*60*1e3,Lo=10*60*1e3;async function mt(e,t,o){let n=Date.now()+Lo,r=false;for(;Date.now()<n;){let i;try{({status:i}=await h(e,"/api/environment/status",{token:t,query:{environmentId:o}}));}catch(a){if(a instanceof E&&a.status===404)return false;throw a}if(i==="ready")return r;if(i==="failed")throw new Error("The environment failed to provision; check it in the dashboard.");r||(console.log("Waiting for the environment to finish provisioning..."),r=true),await new Promise(a=>setTimeout(a,ut));}throw new Error("Timed out waiting for the environment to be ready.")}async function ft(e,t,o,n){let r=Date.now()+Mo,i="",a="",c=null,p=false;for(;Date.now()<r;){let s;try{s=await h(e.host,"/api/deploy/status",{token:e.token,query:{environmentId:o,buildId:n,...c?{logCursor:c}:{}}});}catch(l){if(!J(l)||p)throw l;p=true,await t();continue}for(let l of s.logs)process.stdout.write(` \u2502 ${l.replace(/\n$/,"")}
18
+ `);if(c=s.logCursor??c,s.status!==i){i=s.status;let l=Ro(s);l&&l!==a&&(a=l,console.log(l));}if(s.status==="deploy-completed"){s.siteUrl&&console.log(`Live at ${s.siteUrl}`);return}if(s.status==="build-failed"||s.status==="deploy-failed"){let l=s.containerLogs??[],m=ne(s.missingEnvVars,s.configUrl,{deployAgain:s.errors.length===0&&l.length===0});m&&console.error(m);for(let d of s.errors)console.error(` ${d}`);if(l.length>0){console.error("Container output:");for(let d of l)console.error(` \u2502 ${d.replace(/\n$/,"")}`);}process.exitCode=1;return}await new Promise(l=>setTimeout(l,ut));}console.error("Timed out waiting for the deployment; check the dashboard for its status."),process.exitCode=1;}function Ro(e){switch(e.status){case "build-pending":return "Building image...";case "deploy-pending":case "deploying":return "Image built. Deploying containers...";case "rolling-out":return "Rolling out new containers...";case "deploy-completed":return "Deployed successfully.";case "build-failed":return "Build failed.";case "deploy-failed":return "Deployment failed.";default:return null}}async function gt({session:e,target:t,kind:o,archivePath:n,spec:r,checkEnv:i}){let{host:a,token:c}=e,p=()=>h(a,"/api/upload-bundle",{method:"POST",token:c,body:{...t,kind:o}}),s=await p();if(!s.environmentId)throw new Error("Modelence Cloud is too old for this CLI version (no environment id from /api/upload-bundle). Try again later, or deploy with modelence@0.25.");await mt(a,c,s.environmentId)&&(s=await p()),console.log(`Uploading to ${s.appAlias}/${s.envAlias}...`);let l=await openAsBlob(n,{type:"application/zip"}),m=await fetch(s.uploadUrl,{method:"PUT",body:l,headers:{"Content-Type":"application/zip"}});if(!m.ok)throw new Error(`Failed to upload: ${await Uo(m)}`);let d=await h(a,"/api/deploy",{method:"POST",token:c,body:{environmentId:s.environmentId,bundleName:s.bundleName,kind:o,spec:r,...i?{checkEnv:i}:{}}});console.log(`Deployment started: ${d.deploymentUrl}`);let g=ne(d.missingEnvVars,d.configUrl);return g&&console.warn(`Warning: ${g}`),{environmentId:d.environmentId,buildId:d.buildId}}async function Uo(e){let t=await e.text().catch(()=>""),o=t.match(/<Code>([^<]+)<\/Code>/)?.[1],n=t.match(/<Message>([^<]+)<\/Message>/)?.[1],r=e.statusText||`HTTP ${e.status}`;return o?`${r} (${o}${n?`: ${n}`:""})`:r}async function Et(e){let t=process.cwd(),o=await G(e.host,t);De(e.host,o);let n=await ct(t,e),r=n.kind,i=lt(n);i&&console.log(i);let a=await N(t),c=K(a,o),p=c.deploy?[]:Te(a,o),s=dt(),l=pt(e,c,p),m=s?await Ae(o):null;if(s&&(!m||!l))throw new Error(Vo(!!m,!!l,p));!s&&!l&&p.length>0&&console.log(`Note: ${oe(p)} Pick a target for ${o} in the browser, or pass --host to deploy there.`);let d,g=join(t,".modelence","tmp",`${r}.zip`);r==="bundle"?(d=await $(t)??void 0,await k(),await Z(),await zo(g)):(d=await st(t),Ko(await Ye(t,g)));try{let T=l;if(!s){let f=await I(o,{pick:"deploy",purpose:"deploy",appId:c.appId,hint:l??void 0,env:d?.env});if(m=f.token,await le(o,f.token,f.expiresAt),!f.target)throw new Error("No deploy target selected. Run again and pick an environment in the browser.");T={environmentId:f.target.environmentId},await Ie(f.target,o);}if(!m||!T)throw new Error("No token or deploy target to deploy with.");let re=T,ie={host:o,token:m},ve=async()=>{if(await U(o),s)throw new Error("Modelence Cloud rejected the token (expired or revoked), and CI deploys never sign in again in the browser. Set a fresh MODELENCE_TOKEN. A deployment that already started keeps running; check the dashboard.");console.log("Your login has expired; please sign in again.");let f=await I(o,{purpose:"deploy",appId:c.appId});await le(o,f.token,f.expiresAt),ie.token=f.token;},xt=s&&!e.skipEnvCheck,be=()=>gt({session:ie,target:re,kind:r,archivePath:g,spec:d,checkEnv:xt}),A;try{A=await be();}catch(f){if(!J(f))throw f;await ve(),A=await be();}A.buildId&&await ft(ie,ve,A.environmentId,A.buildId);}finally{await promises.rm(g,{force:true});}}function Vo(e,t,o){let n=[t?null:"pass --app and --env",e?null:"set MODELENCE_TOKEN"].filter(Boolean),r=!t&&o.length>0?` Note: ${oe(o)} Pass --host to deploy there.`:"";return `CI deploys never open the browser to sign in or pick a target. To deploy from here, ${n.join(" and ")}.${r}`}var ht=10;function wt(e){let t=e.slice(0,ht).join(", "),o=e.length-ht;return o>0?`${t} and ${o} more`:t}function Ko(e){console.log(`Packed ${e.fileCount} files (${vt(e.sizeBytes)})`+(e.usedGit?" from git":"; not a git repository, so only default exclusions applied")),e.excludedFiles.length>0&&console.log(`Not uploaded (local, generated or credentials; store secrets in the target environment): ${wt(e.excludedFiles)}`),e.committedEnvFiles.length>0&&console.log(`Uploaded environment files committed to git: ${wt(e.committedEnvFiles)}`);for(let{path:t,reason:o}of e.skipped)console.warn(`Warning: ${t} is not uploaded (${o}).`);}function vt(e){return `${(e/1024/1024).toFixed(2)} MB`}async function zo(e){await promises.rm(e,{force:true}),console.log("Creating deployment bundle..."),await promises.mkdir(join(e,".."),{recursive:true});let t=createWriteStream(e),o=fo("zip",{zlib:{level:9}}),n=new Promise((c,p)=>{t.on("close",c),t.on("error",p),o.on("error",p);});o.pipe(t);let r=["package.json","package-lock.json","next.config.js","next.config.ts","modelence.config.ts"],i=["public","server","scripts",join(".modelence","build"),".next"];for(let c of r)await yt(C(c))&&o.file(C(c),{name:c});for(let c of i)await yt(C(c))&&o.directory(C(c),c);await o.finalize(),await n;let a=await promises.stat(e);console.log(`Deployment bundle created (${vt(a.size)})`);}async function yt(e){try{return await promises.access(e),!0}catch{return false}}function bt(e={}){console.log("Starting Modelence dev server...");let t=P(),o=ge.resolve("./node_modules/.bin/tsx");execSync(`"${o}" watch --ignore "vite.config.ts.timestamp-*" "${t}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"development",...e.takeover?{MODELENCE_TAKEOVER:"1"}:{}}});}function Pt(){console.log("Starting Modelence production server...");let e=P(),t=ge.basename(e,ge.extname(e)),o=X(`${t}.mjs`);execSync(`node "${o}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"production"}});}async function Ct(e){let t=e.host?v(e.host):void 0,o=await Ce(t);await Promise.all(o.map(n=>Wo(n.host,n.token))),await U(t),console.log(t?`Removed the saved login for ${t}.`:`Removed saved logins (${R()}).`);}async function Wo(e,t){try{await h(e,"/api/cli/logout",{method:"POST",token:t});}catch{}}async function kt(e){let t=process.cwd(),o=te(t);if(!e.force&&await Xo(o))throw new Error(`${u} already exists; pass --force to overwrite it.`);let n=await G(e.host,t),r={$schema:Qe(n),resources:{app:{type:"service",image:"node-22-slim",build:{commands:["npm ci"]},static:[]}},env:{}};await et(r,t),console.log(`Wrote a ${u} template.`),console.log("Ask your coding agent to fill it in with this prompt:"),console.log(""),console.log(` ${ee}`),console.log(""),console.log(`Reference: ${j}`),console.log(`Once ${u} describes your app, run \`npx modelence@latest deploy\`.`);}async function Xo(e){try{return await promises.access(e),!0}catch{return false}}var rn=fileURLToPath(import.meta.url),sn=dirname(rn),an=JSON.parse(readFileSync(join(sn,"../../package.json"),"utf-8")),y=new Command().name("modelence").description("Modelence CLI tool").version(an.version);y.command("setup").description("Setup Modelence environment variables").option("-t, --token <token>","Modelence setup token (omit to authorize in the browser)").option("--new","Connect to a new environment, created in the browser").option("-h, --host <host>","Modelence host","https://cloud.modelence.com").action(async e=>{await je(e);});y.command("build").description("Build the application").action(async()=>{await k(),await Z();});y.command("deploy").description("Deploy the project described by modelence.config.json to Modelence Cloud (picks the target in the browser; in CI from --app/--env or the saved target)").option("-a, --app <app>","Application alias (preselected in the browser; the target in CI)").option("-e, --env <env>","Environment alias (preselected in the browser; the target in CI)").option("-h, --host <host>","Modelence host").option("--prebuilt","Build locally and upload the .modelence/build bundle (Modelence apps only)").option("--skip-env-check","In CI, deploy even when variables modelence.config.json requires have no value").addOption(new Option("-y, --yes").hideHelp()).action(async e=>{try{await Et(e);}catch(t){console.error(`Deploy failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});y.command("init").description("Create a modelence.config.json template for this project").option("--force","Overwrite an existing modelence.config.json").option("-h, --host <host>","Modelence host used for the schema URL").action(async e=>{try{await kt(e);}catch(t){console.error(`Init failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});y.command("logout").description("Forget the saved Modelence Cloud login").option("-h, --host <host>","Only forget the login for this host").action(async e=>{await Ct(e);});y.command("dev").description("Start development server").option("--takeover","Disconnect any instance currently holding the environment and connect this one").action(async e=>{await k(),bt(e);});y.command("start").description("Start production server").action(async()=>{await k(),Pt();});y.parse(process.argv);//# sourceMappingURL=modelence.js.map
19
19
  //# sourceMappingURL=modelence.js.map