modelence 0.26.2-dev.1 → 0.26.2-dev.2

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,21 @@
1
1
  #!/usr/bin/env node
2
- import {Command}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 xt from'open';import At from'os';import Re 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 uo from'archiver';import {promisify}from'util';import {parse as parse$1,printParseErrorCode}from'jsonc-parser';async function $(e,{pick:t,purpose:o,pickEnvironment:n=false,appId:r,env:i}={}){let a=t==="deploy"&&i&&Object.keys(i).length>0?i:void 0,l=await fetch(`${e}/api/cli/auth`,{method:"POST",...a?{headers:{"Content-Type":"application/json"},body:JSON.stringify({env:a})}:{}});if(!l.ok)throw new Error("Failed to create CLI authentication code");let{code:p,verificationUrl:s}=await l.json(),c=new URL(s),u=t??(n?"environment":void 0);u&&c.searchParams.set("pick",u),o&&c.searchParams.set("purpose",o),r&&c.searchParams.set("appId",r),console.log(`Please visit ${c} to authenticate`),console.log(`Code: ${p}`);try{await xt(c.toString());}catch{console.log("Could not open a browser automatically. Please open the URL above manually.");}return await kt(e,p)}var j=class extends Error{};async function kt(e,t){let r=Date.now()+6e5,i=false;for(;Date.now()<r;){try{let a=await $t(e,t);if(a)return a}catch(a){if(a instanceof j)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 $t(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 j("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 It="auth.json",Dt=40*60*1e3;function M(){let e=process.env.MODELENCE_HOME||join(At.homedir(),".modelence");return join(e,It)}async function L(){try{let e=JSON.parse(await promises.readFile(M(),"utf8"));return e&&typeof e=="object"?e:{}}catch{return {}}}async function ie(e){let t=M();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 L(),o=t[e];return !o?.token||!o.expiresAt||new Date(o.expiresAt).getTime()-Dt<=Date.now()?null:o.token}async function Se(e){let{hosts:t={}}=await L();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 L();await ie({...n,hosts:{...n.hosts,[e]:{token:t,expiresAt:o}}});}async function R(e){if(!e){await ie({});return}let t=await L(),{[e]:o,...n}=t.hosts??{};await ie({...t,hosts:n});}var A=".modelence",U="project.json",v="https://cloud.modelence.com";function ke(e=process.cwd()){return join(e,A,U)}async function T(e=process.cwd()){try{let t=await promises.readFile(ke(e),"utf8"),o=JSON.parse(t);return o&&typeof o=="object"?o:{}}catch{return {}}}async function B(e,t=process.cwd()){let o=e(await T(t));await promises.mkdir(join(t,A),{recursive:true}),await promises.writeFile(ke(t),JSON.stringify(o,null,2)+`
4
- `);}function F(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 H(e,t){return F(t===v?e:e.hosts?.[t])}function $e(e,t){let o=Object.keys(e.hosts??{}).filter(n=>F(e.hosts?.[n]).deploy);return F(e).deploy&&o.unshift(v),[...new Set(o)].filter(n=>n!==t)}function V(e,t,o){return t===v?{...e,...o}:{...e,hosts:{...e.hosts,[t]:{...e.hosts?.[t],...o}}}}var w=class extends Error{constructor(o,n){super(o);this.status=n;this.name="StudioApiError";}};async function g(e,t,{method:o="GET",token:n,body:r,query:i}={}){let a=new URL(`${e}${t}`);for(let[s,c]of Object.entries(i??{}))a.searchParams.set(s,String(c));let l={};n&&(l.Authorization=`Bearer ${n}`),r!==void 0&&(l["Content-Type"]="application/json");let p=await fetch(a,{method:o,headers:l,body:r===void 0?void 0:JSON.stringify(r)});if(!p.ok){let s=await p.text(),c=s||p.statusText;try{let u=JSON.parse(s);c=u.error||u.message||c;}catch{}throw new w(c,p.status)}return await p.json()}function K(e){return e instanceof w&&e.status===401}async function Ae(e){return process.env.MODELENCE_TOKEN?process.env.MODELENCE_TOKEN:await Pe(e)}async function ae(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 ce(e,t){let{appId:o,environmentId:n,appAlias:r,envAlias:i}=e;try{await B(a=>V(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 E(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 z(e,t){if(e)return E(e);if(process.env.MODELENCE_SERVICE_ENDPOINT)return E(process.env.MODELENCE_SERVICE_ENDPOINT);let o={};try{o=parse(await promises.readFile(join(t,".modelence.env"),"utf8"));}catch{}return o.MODELENCE_SERVICE_ENDPOINT?E(o.MODELENCE_SERVICE_ENDPOINT):v}function Te(e,t){if(!(!process.env.MODELENCE_TOKEN||e||process.env.MODELENCE_SERVICE_ENDPOINT||t===v))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 Rt(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 De(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 Ft(){return (await De(`Warning: ${pe} already exists. Do you want to overwrite it? (y/N) `)).toLowerCase()==="y"}function Ut(e){return String(e).replace(/"/g,'\\"')}async function Bt(e){return H(await T(),e).appId}async function Ht(e,t){await B(o=>V(o,t,{appId:e}));}var Ne=".claude",I=join(Ne,"settings.json"),G="modelence@modelence",de="modelence/modelence",Vt={modelence:{source:{source:"github",repo:de}}},Kt="https://docs.modelence.com/ai-coding-agents",Ie=`Install the Modelence plugin for Claude Code by hand:
5
- claude plugin marketplace add ${de}
6
- claude plugin install ${G} --scope project
7
- Guide: ${Kt}`;async function zt(){let e=join(process.cwd(),I),t;try{t=await promises.readFile(e,"utf8");}catch(n){if(n.code!=="ENOENT"){console.warn(`Could not read ${I}; leaving it unchanged.`);return}}let o={};if(t!==void 0)try{o=JSON.parse(t);}catch{console.warn(`Could not parse ${I}; leaving it unchanged.`);return}o.extraKnownMarketplaces={...o.extraKnownMarketplaces,...Vt},o.enabledPlugins?.[G]===void 0&&(o.enabledPlugins={...o.enabledPlugins,[G]:true});try{await promises.mkdir(join(process.cwd(),Ne),{recursive:!0}),await promises.writeFile(e,JSON.stringify(o,null,2)+`
8
- `),console.log(`Declared the Modelence Claude Code plugin in ${I}`);}catch(n){console.warn(`Failed to write ${I}:`,n);}}function le(e){return spawnSync("claude",e,{encoding:"utf8",shell:process.platform==="win32"})}async function Jt(){let e=le(["--version"]);if(e.error||e.status!==0){console.log(Ie);return}let t=(await De("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",G,"--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(Ie);}}async function Gt(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:E(e.host)},o=join(process.cwd(),pe),n={},r=!1;try{let s=await promises.readFile(o,"utf8");n=parse(s),r=!0,await Gt(o),await Ft()||(console.log("Setup canceled"),process.exit(0));}catch{}let i;if(t.token)i={setupToken:t.token};else {let{token:s}=await $(t.host,{pickEnvironment:!0,appId:await Bt(t.host)});i={cliToken:s};}console.log("Fetching service configuration...");let a=await Rt(t.host,i),l={...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(l).map(([s,c])=>`${s}="${Ut(c)}"`).join(`
2
+ import {Command}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 Dt from'open';import Ot from'os';import Be 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 yo from'archiver';import {promisify}from'util';import {parse as parse$1,printParseErrorCode}from'jsonc-parser';async function A(e,{pick:t,purpose:o,pickEnvironment:n=false,appId:r,env:i}={}){let s=t==="deploy"&&i&&Object.keys(i).length>0?i:void 0,c=await fetch(`${e}/api/cli/auth`,{method:"POST",...s?{headers:{"Content-Type":"application/json"},body:JSON.stringify({env:s})}:{}});if(!c.ok)throw new Error("Failed to create CLI authentication code");let{code:p,verificationUrl:a}=await c.json(),l=new URL(a),d=t??(n?"environment":void 0);d&&l.searchParams.set("pick",d),o&&l.searchParams.set("purpose",o),r&&l.searchParams.set("appId",r),console.log(`Please visit ${l} to authenticate`),console.log(`Code: ${p}`);try{await Dt(l.toString());}catch{console.log("Could not open a browser automatically. Please open the URL above manually.");}return await Nt(e,p)}var R=class extends Error{};async function Nt(e,t){let r=Date.now()+6e5,i=false;for(;Date.now()<r;){try{let s=await _t(e,t);if(s)return s}catch(s){if(s instanceof R)throw s;i||(i=true,console.error("Error polling for CLI token (retrying):",s));}await new Promise(s=>setTimeout(s,2e3));}throw new Error("Unable to authenticate CLI - timed out. Please try again.")}async function _t(e,t){let o=await fetch(`${e}/api/cli/token?code=${t}`,{method:"GET"});if(!o.ok){let s=await o.text().catch(()=>"");throw o.status>=400&&o.status<500&&o.status!==429||s.includes("Invalid or expired code")?new R("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 Mt="auth.json",Rt=40*60*1e3;function L(){let e=process.env.MODELENCE_HOME||join(Ot.homedir(),".modelence");return join(e,Mt)}async function F(){try{let e=JSON.parse(await promises.readFile(L(),"utf8"));return e&&typeof e=="object"?e:{}}catch{return {}}}async function se(e){let t=L();await promises.mkdir(dirname(t),{recursive:true,mode:448}),await promises.writeFile(t,JSON.stringify(e,null,2)+`
3
+ `,{mode:384});}async function ke(e){let{hosts:t={}}=await F(),o=t[e];return !o?.token||!o.expiresAt||new Date(o.expiresAt).getTime()-Rt<=Date.now()?null:o.token}async function xe(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 $e(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 T=".modelence",H="project.json",E="https://cloud.modelence.com";function Te(e=process.cwd()){return join(e,T,H)}async function I(e=process.cwd()){try{let t=await promises.readFile(Te(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 I(t));await promises.mkdir(join(t,T),{recursive:true}),await promises.writeFile(Te(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===E?e:e.hosts?.[t])}function Ie(e,t){let o=Object.keys(e.hosts??{}).filter(n=>B(e.hosts?.[n]).deploy);return B(e).deploy&&o.unshift(E),[...new Set(o)].filter(n=>n!==t)}function z(e,t,o){return t===E?{...e,...o}:{...e,hosts:{...e.hosts,[t]:{...e.hosts?.[t],...o}}}}var h=class extends Error{constructor(o,n){super(o);this.status=n;this.name="StudioApiError";}};async function g(e,t,{method:o="GET",token:n,body:r,query:i}={}){let s=new URL(`${e}${t}`);for(let[a,l]of Object.entries(i??{}))s.searchParams.set(a,String(l));let c={};n&&(c.Authorization=`Bearer ${n}`),r!==void 0&&(c["Content-Type"]="application/json");let p=await fetch(s,{method:o,headers:c,body:r===void 0?void 0:JSON.stringify(r)});if(!p.ok){let a=await p.text(),l=a||p.statusText;try{let d=JSON.parse(a);l=d.error||d.message||l;}catch{}throw new h(l,p.status)}return await p.json()}function D(e){return e instanceof h&&e.status===401}async function De(e){return process.env.MODELENCE_TOKEN?process.env.MODELENCE_TOKEN:await ke(e)}async function ce(e,t,o){if(o)try{await $e(e,t,o);}catch(n){console.warn("Could not save the login for next time:",n);}}async function le(e,t){let{appId:o,environmentId:n,appAlias:r,envAlias:i}=e;try{await V(s=>z(s,t,{appId:o,deploy:{environmentId:n,appAlias:r,envAlias:i}}));}catch(s){console.warn("Could not record the deploy target in .modelence/project.json:",s);}}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 J(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):E}function Ne(e,t){if(!(!process.env.MODELENCE_TOKEN||e||process.env.MODELENCE_SERVICE_ENDPOINT||t===E))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 Kt(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 zt(){return (await Oe(`Warning: ${de} already exists. Do you want to overwrite it? (y/N) `)).toLowerCase()==="y"}function Jt(e){return String(e).replace(/"/g,'\\"')}async function Gt(e){return K(await I(),e).appId}async function Wt(e,t){await V(o=>z(o,t,{appId:e}));}var je=".claude",N=join(je,"settings.json"),W="modelence@modelence",ue="modelence/modelence",qt={modelence:{source:{source:"github",repo:ue}}},Yt="https://docs.modelence.com/ai-coding-agents",_e=`Install the Modelence plugin for Claude Code by hand:
5
+ claude plugin marketplace add ${ue}
6
+ claude plugin install ${W} --scope project
7
+ Guide: ${Yt}`;async function Xt(){let e=join(process.cwd(),N),t;try{t=await promises.readFile(e,"utf8");}catch(n){if(n.code!=="ENOENT"){console.warn(`Could not read ${N}; leaving it unchanged.`);return}}let o={};if(t!==void 0)try{o=JSON.parse(t);}catch{console.warn(`Could not parse ${N}; leaving it unchanged.`);return}o.extraKnownMarketplaces={...o.extraKnownMarketplaces,...qt},o.enabledPlugins?.[W]===void 0&&(o.enabledPlugins={...o.enabledPlugins,[W]:true});try{await promises.mkdir(join(process.cwd(),je),{recursive:!0}),await promises.writeFile(e,JSON.stringify(o,null,2)+`
8
+ `),console.log(`Declared the Modelence Claude Code plugin in ${N}`);}catch(n){console.warn(`Failed to write ${N}:`,n);}}function pe(e){return spawnSync("claude",e,{encoding:"utf8",shell:process.platform==="win32"})}async function Zt(){let e=pe(["--version"]);if(e.error||e.status!==0){console.log(_e);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(_e);}}async function Qt(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 Me(e){try{let t={...e,host:v(e.host)},o=join(process.cwd(),de),n={},r=!1;try{let a=await promises.readFile(o,"utf8");n=parse(a),r=!0,await Qt(o),await zt()||(console.log("Setup canceled"),process.exit(0));}catch{}let i;if(t.token)i={setupToken:t.token};else {let{token:a}=await A(t.host,{pickEnvironment:!0,appId:await Gt(t.host)});i={cliToken:a};}console.log("Fetching service configuration...");let s=await Kt(t.host,i),c={...n,MODELENCE_TELEMETRY_ENABLED:"false",MODELENCE_ENVIRONMENT_ID:s.environmentId,MODELENCE_SERVICE_ENDPOINT:t.host,MODELENCE_SERVICE_TOKEN:s.serviceToken,MODELENCE_CONTAINER_ID:s.containerId,MODELENCE_RUNTIME:process.env.MODELENCE_RUNTIME||"local"},p=Object.entries(c).map(([a,l])=>`${a}="${Jt(l)}"`).join(`
9
9
  `);if(await promises.writeFile(o,p.trim()+`
10
- `),console.log(`Successfully configured ${pe} file`),a.appId)try{await Ht(a.appId,t.host),console.log(`Recorded the app ID in ${A}/${U}`);}catch(s){console.warn(`Failed to record the app ID in ${A}/${U}:`,s);}await zt(),!t.token&&process.stdin.isTTY&&await Jt(),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&&l.MODELENCE_RUNTIME==="local"&&(console.log(`
10
+ `),console.log(`Successfully configured ${de} file`),s.appId)try{await Wt(s.appId,t.host),console.log(`Recorded the app ID in ${T}/${H}`);}catch(a){console.warn(`Failed to record the app ID in ${T}/${H}:`,a);}await Xt(),!t.token&&process.stdin.isTTY&&await Zt(),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 Yt=z$1.object({serverDir:z$1.string(),serverEntry:z$1.string(),postBuildCommand:z$1.string().optional()});async function Oe(){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 Yt.parse(o)}var je=null,ue=null;function Me(){if(!ue)throw new Error("Configuration not loaded");return ue}function P(){let{serverDir:e,serverEntry:t}=Me();return join(e,t).replace(/\\/g,"/")}function Le(){return Me().postBuildCommand}function q(e){let t=me("build");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}function S(e){return join(process.cwd(),e).replace(/\\/g,"/")}function me(e){let t=S(".modelence");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}async function C(){try{ue=await Oe();}catch(e){throw console.error(e),new Error("Unable to load modelence.config.ts")}try{let e=await Re.readFile(join(process.cwd(),".modelence.env"),"utf-8");je=parse(e);}catch(e){if(e.code==="ENOENT")je={};else throw e}}async function to(){let e=Le();if(e){console.log("Running post-build command..."),execSync(e);return}await oo(),await no();}async function oo(){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 no(){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 ro(){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 Y(){console.log("Building Modelence project...");try{let e=q();await Re.rm(e,{recursive:!0,force:!0}),await ro(),await to(),console.log("Build completed successfully!");}catch(e){throw console.error(e),new Error("Build failed")}try{await Re.access(me());}catch{throw new Error("Could not find the .modelence directory. Looks like something went wrong during the build.")}}var ze=promisify(execFile),Ve=200*1024*1024,mo=[".git","node_modules",".modelence/build",".modelence/tmp",".modelence/cache"],fo=[/^\.modelence(\.[^/]+)?\.env$/];function Je(e){return /^\.env(?:\.|$)/.test(e)&&!/\.(example|sample|template)$/.test(e)}function go(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 X(e){return e.split(sep).join("/")}function ho(e){return he(e)||Je(X(e).split("/").at(-1)??"")}function he(e){let t=X(e),o=t.split("/");for(let r of mo)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 fo.some(r=>r.test(n))}async function yo(e){try{let{stdout:t}=await ze("git",["rev-parse","--is-inside-work-tree"],{cwd:e});return t.trim()==="true"}catch{return false}}async function Ke(e,t){let{stdout:o}=await ze("git",["ls-files",...t,"-z"],{cwd:e,maxBuffer:67108864});return o.split("\0").filter(n=>n.length>0)}async function Ge(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()?ho(`${i}/x`)||n.push(...await Ge(e,i)):(r.isFile()||r.isSymbolicLink())&&n.push(i);}return n}async function wo(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:X(relative(dirname(o),r))||"."}}async function Eo(e=process.cwd()){let t=await yo(e),o=new Set(t?await Ke(e,["--cached"]):[]),n=t?[...o,...await Ke(e,["--others","--exclude-standard"])]:await Ge(e),r={files:[],symlinks:[],usedGit:t,excludedFiles:[],skipped:[],committedEnvFiles:[]};for(let i of n){let a=i.split("/").at(-1)??"",l=Je(a);if(he(i)||l&&!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 wo(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)&&go(await promises.readFile(join(e,i),"utf8"))){r.excludedFiles.push(i);continue}r.files.push(i),l&&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 Eo(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=uo("zip",{zlib:{level:6}}),l=new Promise((s,c)=>{i.on("close",s),i.on("error",c),a.on("error",c);});a.pipe(i);for(let s of o)a.file(join(e,s),{name:X(relative("",s))});for(let s of n)a.symlink(s.path,s.target,511);await Promise.all([a.finalize(),l]);let{size:p}=await promises.stat(t);if(p>Ve)throw await promises.rm(t,{force:true}),new Error(`Source is ${(p/1024/1024).toFixed(0)} MB compressed; the limit is ${Ve/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",So=1,N="https://docs.modelence.com/deploy/setup",Z=`Use ${N}.md to set up Modelence deployment for this project`;function Xe(e){return `${e.replace(/\/$/,"")}/schema/${d}?version=${So}`}function Q(e=process.cwd()){return join(e,d)}async function ee(e=process.cwd()){let t;try{t=await promises.readFile(Q(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: ${Co(t,o[0])}`);if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`${d} must contain a JSON object`);return n}function Co(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 oo=z$1.object({serverDir:z$1.string(),serverEntry:z$1.string(),postBuildCommand:z$1.string().optional()});async function Re(){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 oo.parse(o)}var Le=null,me=null;function Fe(){if(!me)throw new Error("Configuration not loaded");return me}function S(){let{serverDir:e,serverEntry:t}=Fe();return join(e,t).replace(/\\/g,"/")}function Ue(){return Fe().postBuildCommand}function Y(e){let t=fe("build");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}function P(e){return join(process.cwd(),e).replace(/\\/g,"/")}function fe(e){let t=P(".modelence");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}async function C(){try{me=await Re();}catch(e){throw console.error(e),new Error("Unable to load modelence.config.ts")}try{let e=await Be.readFile(join(process.cwd(),".modelence.env"),"utf-8");Le=parse(e);}catch(e){if(e.code==="ENOENT")Le={};else throw e}}async function ao(){let e=Ue();if(e){console.log("Running post-build command..."),execSync(e);return}await co(),await lo();}async function co(){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 lo(){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 po(){return console.log("Building server with tsup..."),new Promise(e=>{build({entry:[S()],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 X(){console.log("Building Modelence project...");try{let e=Y();await Be.rm(e,{recursive:!0,force:!0}),await po(),await ao(),console.log("Build completed successfully!");}catch(e){throw console.error(e),new Error("Build failed")}try{await Be.access(fe());}catch{throw new Error("Could not find the .modelence directory. Looks like something went wrong during the build.")}}var We=promisify(execFile),Je=200*1024*1024,vo=[".git","node_modules",".modelence/build",".modelence/tmp",".modelence/cache"],Eo=[/^\.modelence(\.[^/]+)?\.env$/];function qe(e){return /^\.env(?:\.|$)/.test(e)&&!/\.(example|sample|template)$/.test(e)}function bo(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 Z(e){return e.split(sep).join("/")}function So(e){return we(e)||qe(Z(e).split("/").at(-1)??"")}function we(e){let t=Z(e),o=t.split("/");for(let r of vo)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 Eo.some(r=>r.test(n))}async function Po(e){try{let{stdout:t}=await We("git",["rev-parse","--is-inside-work-tree"],{cwd:e});return t.trim()==="true"}catch{return false}}async function Ge(e,t){let{stdout:o}=await We("git",["ls-files",...t,"-z"],{cwd:e,maxBuffer:67108864});return o.split("\0").filter(n=>n.length>0)}async function Ye(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()?So(`${i}/x`)||n.push(...await Ye(e,i)):(r.isFile()||r.isSymbolicLink())&&n.push(i);}return n}async function Co(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:Z(relative(dirname(o),r))||"."}}async function ko(e=process.cwd()){let t=await Po(e),o=new Set(t?await Ge(e,["--cached"]):[]),n=t?[...o,...await Ge(e,["--others","--exclude-standard"])]:await Ye(e),r={files:[],symlinks:[],usedGit:t,excludedFiles:[],skipped:[],committedEnvFiles:[]};for(let i of n){let s=i.split("/").at(-1)??"",c=qe(s);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 a=await Co(e,i);a?r.symlinks.push(a):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(s)&&bo(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,s)=>i.path.localeCompare(s.path)),excludedFiles:r.excludedFiles.sort(),committedEnvFiles:r.committedEnvFiles.sort()}}async function Xe(e,t){let{files:o,symlinks:n,...r}=await ko(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),s=yo("zip",{zlib:{level:6}}),c=new Promise((a,l)=>{i.on("close",a),i.on("error",l),s.on("error",l);});s.pipe(i);for(let a of o)s.file(join(e,a),{name:Z(relative("",a))});for(let a of n)s.symlink(a.path,a.target,511);await Promise.all([s.finalize(),c]);let{size:p}=await promises.stat(t);if(p>Je)throw await promises.rm(t,{force:true}),new Error(`Source is ${(p/1024/1024).toFixed(0)} MB compressed; the limit is ${Je/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",To=1,O="https://docs.modelence.com/deploy/setup",Q=`Use ${O}.md to set up Modelence deployment for this project`;function et(e){return `${e.replace(/\/$/,"")}/schema/${u}?version=${To}`}function ee(e=process.cwd()){return join(e,u)}async function te(e=process.cwd()){let t;try{t=await promises.readFile(ee(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: ${Io(t,o[0])}`);if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`${u} must contain a JSON object`);return n}function Io(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 Ze(e,t=process.cwd()){await promises.writeFile(Q(t),JSON.stringify(e,null,2)+`
16
- `);}function Qe(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(...qe("build",r.build,"default (npm install)")),t.push(...qe("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 qe(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 ot(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(!et(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(!et(o,r)||!(await promises.stat(r)).isDirectory())throw new Error("root must be a directory inside the project.");return r}function et(e,t){let o=relative(e,t);return o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}var nt=["$schema","resources","env"];async function rt(e){let t=await ee(e);if(!t)throw new Error(Ao(e));To(t);for(let o of Object.values(t.resources??{}))o?.root!==void 0&&await ot(e,o.root);console.log(`Build plan (${d}):`);for(let o of Qe(t))console.log(o);return t}function Ao(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:","",` ${Z}`,"",`Reference: ${N}`].join(`
17
- `)}function To(e){let t=Object.keys(e).filter(o=>!nt.includes(o));if(t.length>0)throw new Error(`${d} has unknown key "${t[0]}" (allowed: ${nt.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(!it(n))throw new Error(`${d}: "resources.${o}" must be an object.`);for(let r of ["build","start"])Io(n[r],`resources.${o}.${r}`);}}function Io(e,t){if(e!==void 0){if(!it(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 it(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}async function st(e,t){return t.prebuilt?{kind:"bundle",reason:"prebuilt-flag"}:await ee(e)!==null?{kind:"source",reason:"spec-file"}:await _o(e)?{kind:"bundle",reason:"modelence-dependency"}:{kind:"source",reason:"default"}}function at(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 _o(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 ct(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: ${te(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 te(e){return `the target saved in .modelence/project.json is for ${e.join(", ")}, not this Studio.`}function lt(e,t){if("environmentId"in e){let o=t.deploy;return `${o?.environmentId===e.environmentId?`${o.appAlias}/${o.envAlias}`:e.environmentId} (saved in .modelence/project.json)`}return "appAlias"in e?`${e.appAlias}/${e.envAlias}`:e.envAlias}function pt(e,t){let o=t.deploy;return !o||"environmentId"in e?false:"appAlias"in e&&e.appAlias!==o.appAlias?true:e.envAlias!==o.envAlias}function oe(){return !process.env.CI&&!!process.stdin.isTTY}async function dt(e){let t=createInterface({input:process.stdin,output:process.stdout}),o=await new Promise(n=>t.question(`${e} (y/N) `,n));return t.close(),o.trim().toLowerCase()==="y"}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 ut=3e3,jo=30*60*1e3,Mo=10*60*1e3;async function mt(e,t,o){let n=Date.now()+Mo,r=false;for(;Date.now()<n;){let i;try{({status:i}=await g(e,"/api/environment/status",{token:t,query:{environmentId:o}}));}catch(a){if(a instanceof w&&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()+jo,i="",a="",l=null,p=false;for(;Date.now()<r;){let s;try{s=await g(e.host,"/api/deploy/status",{token:e.token,query:{environmentId:o,buildId:n,...l?{logCursor:l}:{}}});}catch(c){if(!K(c)||p)throw c;p=true,await t();continue}for(let c of s.logs)process.stdout.write(` \u2502 ${c.replace(/\n$/,"")}
18
- `);if(l=s.logCursor??l,s.status!==i){i=s.status;let c=Lo(s);c&&c!==a&&(a=c,console.log(c));}if(s.status==="deploy-completed"){s.siteUrl&&console.log(`Live at ${s.siteUrl}`);return}if(s.status==="build-failed"||s.status==="deploy-failed"){let c=s.containerLogs??[],u=ne(s.missingEnvVars,s.configUrl,{deployAgain:s.errors.length===0&&c.length===0});u&&console.error(u);for(let f of s.errors)console.error(` ${f}`);if(c.length>0){console.error("Container output:");for(let f of c)console.error(` \u2502 ${f.replace(/\n$/,"")}`);}process.exitCode=1;return}await new Promise(c=>setTimeout(c,ut));}console.error("Timed out waiting for the deployment; check the dashboard for its status."),process.exitCode=1;}function Lo(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 we({session:e,target:t,kind:o,archivePath:n,spec:r}){let{host:i,token:a}=e,l=()=>g(i,"/api/upload-bundle",{method:"POST",token:a,body:{...t,kind:o}}),p=await l();if(!p.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(i,a,p.environmentId)&&(p=await l()),console.log(`Uploading to ${p.appAlias}/${p.envAlias}...`);let s=await openAsBlob(n,{type:"application/zip"}),c=await fetch(p.uploadUrl,{method:"PUT",body:s,headers:{"Content-Type":"application/zip"}});if(!c.ok)throw new Error(`Failed to upload: ${await Fo(c)}`);let u=await g(i,"/api/deploy",{method:"POST",token:a,body:{environmentId:p.environmentId,bundleName:p.bundleName,kind:o,spec:r}});console.log(`Deployment started: ${u.deploymentUrl}`);let f=ne(u.missingEnvVars,u.configUrl);return f&&console.warn(`Warning: ${f}`),{environmentId:u.environmentId,buildId:u.buildId}}async function Fo(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 z(e.host,t);Te(e.host,o);let n=await st(t,e),r=n.kind,i=at(n);i&&console.log(i);let a=await T(t),l=H(a,o),p=l.deploy?[]:$e(a,o),s=ct(e,l,p),c=await Ae(o);if((!c||!s)&&!oe())throw new Error(Ho(!!c,!!s,p));!s&&p.length>0&&console.log(`Note: ${te(p)} Pick a target for ${o} in the browser, or pass --host to deploy there.`),await Vo(s,l,e.yes);let u,f=join(t,".modelence","tmp",`${r}.zip`);r==="bundle"?(await C(),await Y(),await zo(f)):(u=await rt(t),Ko(await We(t,f)));try{if(!c||!s){let m=await $(o,{pick:s?void 0:"deploy",purpose:"deploy",appId:l.appId,env:u?.env});c=m.token,await ae(o,m.token,m.expiresAt),m.target&&(s={environmentId:m.target.environmentId},await ce(m.target,o));}if(!s)throw new Error("No deploy target selected. Run again and pick an environment in the browser, or pass --app and --env.");let O={host:o,token:c},ve=async()=>{if(await R(o),!oe())throw new Error("Modelence Cloud rejected the token (expired or revoked), and nobody is at the terminal to sign in again. Set a fresh MODELENCE_TOKEN. A deployment that already started keeps running; check the dashboard.");console.log("Your saved login has expired; please sign in again.");let m=await $(o,{pick:s?void 0:"deploy",purpose:"deploy",appId:l.appId,env:u?.env});await ae(o,m.token,m.expiresAt),m.target&&(s={environmentId:m.target.environmentId},await ce(m.target,o)),O.token=m.token;},k;try{k=await we({session:O,target:s,kind:r,archivePath:f,spec:u});}catch(m){if(!K(m))throw m;await ve(),k=await we({session:O,target:s,kind:r,archivePath:f,spec:u});}k.buildId&&await ft(O,ve,k.environmentId,k.buildId);}finally{await promises.rm(f,{force:true});}}function Ho(e,t,o){let n=[t?null:"pass --app and --env",e?null:"set MODELENCE_TOKEN"].filter(Boolean),r=!t&&o.length>0?` Note: ${te(o)} Pass --host to deploy there.`:"";return `Nobody is at the terminal to sign in or pick a target in the browser (CI or a non-interactive shell). To deploy from here, ${n.join(" and ")}.${r}`}async function Vo(e,t,o){if(!e)return;let n=lt(e,t);if(console.log(`Deploying to ${n}`),o||!pt(e,t)||!oe())return;let r=`${t.deploy?.appAlias}/${t.deploy?.envAlias}`;if(!await dt(`This project normally deploys to ${r}. Deploy to ${n} instead?`))throw new Error("Cancelled.")}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=uo("zip",{zlib:{level:9}}),n=new Promise((l,p)=>{t.on("close",l),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 l of r)await yt(S(l))&&o.file(S(l),{name:l});for(let l of i)await yt(S(l))&&o.directory(S(l),l);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 Pt(){console.log("Starting Modelence production server...");let e=P(),t=fe.basename(e,fe.extname(e)),o=q(`${t}.mjs`);execSync(`node "${o}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"production"}});}async function St(e){let t=e.host?E(e.host):void 0,o=await Se(t);await Promise.all(o.map(n=>qo(n.host,n.token))),await R(t),console.log(t?`Removed the saved login for ${t}.`:`Removed saved logins (${M()}).`);}async function qo(e,t){try{await g(e,"/api/cli/logout",{method:"POST",token:t});}catch{}}async function Ct(e){let t=process.cwd(),o=Q(t);if(!e.force&&await Xo(o))throw new Error(`${d} already exists; pass --force to overwrite it.`);let n=await z(e.host,t),r={$schema:Xe(n),resources:{app:{type:"service",image:"node-22-slim",build:{commands:["npm ci"]},static:[]}},env:{}};await Ze(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(` ${Z}`),console.log(""),console.log(`Reference: ${N}`),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 nn=fileURLToPath(import.meta.url),rn=dirname(nn),sn=JSON.parse(readFileSync(join(rn,"../../package.json"),"utf-8")),y=new Command().name("modelence").description("Modelence CLI tool").version(sn.version);y.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);});y.command("build").description("Build the application").action(async()=>{await C(),await Y();});y.command("deploy").description("Deploy the project described by modelence.config.json to Modelence Cloud (picks the target in the browser on first run)").option("-a, --app <app>","Application alias").option("-e, --env <env>","Environment alias").option("-h, --host <host>","Modelence host").option("--prebuilt","Build locally and upload the .modelence/build bundle (Modelence apps only)").option("-y, --yes","Deploy to the given --app/--env without asking, even if it is not the saved target").action(async e=>{try{await wt(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 Ct(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 St(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 C(),vt(e);});y.command("start").description("Start production server").action(async()=>{await C(),Pt();});y.parse(process.argv);//# sourceMappingURL=modelence.js.map
15
+ `);return `${printParseErrorCode(t.error)} at line ${n}, column ${r}`}async function tt(e,t=process.cwd()){await promises.writeFile(ee(t),JSON.stringify(e,null,2)+`
16
+ `);}function ot(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(...Ze("build",r.build,"default (npm install)")),t.push(...Ze("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 Ze(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 it(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(!nt(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(!nt(o,r)||!(await promises.stat(r)).isDirectory())throw new Error("root must be a directory inside the project.");return r}function nt(e,t){let o=relative(e,t);return o!==".."&&!o.startsWith(`..${sep}`)&&!isAbsolute(o)}var st=["$schema","resources","env"];async function at(e){let t=await te(e);if(!t)throw new Error(Oo(e));jo(t);for(let o of Object.values(t.resources??{}))o?.root!==void 0&&await it(e,o.root);console.log(`Build plan (${u}):`);for(let o of ot(t))console.log(o);return t}function Oo(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:","",` ${Q}`,"",`Reference: ${O}`].join(`
17
+ `)}function jo(e){let t=Object.keys(e).filter(o=>!st.includes(o));if(t.length>0)throw new Error(`${u} has unknown key "${t[0]}" (allowed: ${st.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(!ct(n))throw new Error(`${u}: "resources.${o}" must be an object.`);for(let r of ["build","start"])Mo(n[r],`resources.${o}.${r}`);}}function Mo(e,t){if(e!==void 0){if(!ct(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 ct(e){return !!e&&typeof e=="object"&&!Array.isArray(e)}async function lt(e,t){return t.prebuilt?{kind:"bundle",reason:"prebuilt-flag"}:await te(e)!==null?{kind:"source",reason:"spec-file"}:await Fo(e)?{kind:"bundle",reason:"modelence-dependency"}:{kind:"source",reason:"default"}}function pt(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 Fo(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 dt(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 ut(e,t){if("environmentId"in e){let o=t.deploy;return `${o?.environmentId===e.environmentId?`${o.appAlias}/${o.envAlias}`:e.environmentId} (saved in .modelence/project.json)`}return "appAlias"in e?`${e.appAlias}/${e.envAlias}`:e.envAlias}function mt(e,t){let o=t.deploy;return !o||"environmentId"in e?false:"appAlias"in e&&e.appAlias!==o.appAlias?true:e.envAlias!==o.envAlias}function j(){return !process.env.CI&&!!process.stdin.isTTY}async function gt(e){let t=createInterface({input:process.stdin,output:process.stdout}),o=await new Promise(n=>t.question(`${e} (y/N) `,n));return t.close(),o.trim().toLowerCase()==="y"}async function ht(e,{secret:t=false,input:o=process.stdin,output:n=process.stdout}={}){if(!t){let i=createInterface({input:process.stdin,output:process.stdout}),s=await new Promise(c=>i.question(e,c));return i.close(),s}if(!o.setRawMode)throw new Error("A secret can only be entered in an interactive terminal");let r=o.setRawMode.bind(o);return n.write(e),await new Promise((i,s)=>{let c=[],p=!!o.isRaw,a=()=>{o.removeListener("data",l),r(p),o.pause(),n.write(`
18
+ `);},l=d=>{if(!d.startsWith("\x1B"))for(let m of d){if(m==="\r"||m===`
19
+ `){a(),i(c.join(""));return}if(m===""||m===""){a(),s(new Error("Cancelled"));return}m==="\x7F"||m==="\b"?c.length>0&&(c=c.slice(0,-1),n.write("\b \b")):m>=" "&&(c=[...c,m],n.write("*"));}};r(true),o.setEncoding("utf8"),o.resume(),o.on("data",l);})}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 wt=3e3,Uo=30*60*1e3,Bo=10*60*1e3;async function yt(e,t,o){let n=Date.now()+Bo,r=false;for(;Date.now()<n;){let i;try{({status:i}=await g(e,"/api/environment/status",{token:t,query:{environmentId:o}}));}catch(s){if(s instanceof h&&s.status===404)return false;throw s}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(s=>setTimeout(s,wt));}throw new Error("Timed out waiting for the environment to be ready.")}async function vt(e,t,o,n){let r=Date.now()+Uo,i="",s="",c=null,p=false;for(;Date.now()<r;){let a;try{a=await g(e.host,"/api/deploy/status",{token:e.token,query:{environmentId:o,buildId:n,...c?{logCursor:c}:{}}});}catch(l){if(!D(l)||p)throw l;p=true,await t();continue}for(let l of a.logs)process.stdout.write(` \u2502 ${l.replace(/\n$/,"")}
20
+ `);if(c=a.logCursor??c,a.status!==i){i=a.status;let l=Ho(a);l&&l!==s&&(s=l,console.log(l));}if(a.status==="deploy-completed"){a.siteUrl&&console.log(`Live at ${a.siteUrl}`);return}if(a.status==="build-failed"||a.status==="deploy-failed"){let l=a.containerLogs??[],d=ne(a.missingEnvVars,a.configUrl,{deployAgain:a.errors.length===0&&l.length===0});d&&console.error(d);for(let m of a.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,wt));}console.error("Timed out waiting for the deployment; check the dashboard for its status."),process.exitCode=1;}function Ho(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 ve({session:e,target:t,kind:o,archivePath:n,spec:r}){let{host:i,token:s}=e,c=()=>g(i,"/api/upload-bundle",{method:"POST",token:s,body:{...t,kind:o}}),p=await c();if(!p.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 yt(i,s,p.environmentId)&&(p=await c()),console.log(`Uploading to ${p.appAlias}/${p.envAlias}...`);let a=await openAsBlob(n,{type:"application/zip"}),l=await fetch(p.uploadUrl,{method:"PUT",body:a,headers:{"Content-Type":"application/zip"}});if(!l.ok)throw new Error(`Failed to upload: ${await Ko(l)}`);let d=await g(i,"/api/deploy",{method:"POST",token:s,body:{environmentId:p.environmentId,bundleName:p.bundleName,kind:o,spec:r}});console.log(`Deployment started: ${d.deploymentUrl}`);let m=ne(d.missingEnvVars,d.configUrl);return m&&console.warn(`Warning: ${m}`),{environmentId:d.environmentId,buildId:d.buildId}}async function Ko(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({session:e,target:t,env:o}){if(!o||Object.keys(o).length===0)return;let n=c=>g(e.host,"/api/deploy/env",{method:"POST",token:e.token,body:{...t,env:o,values:c}}),r;try{({missingEnvVars:r}=await n([]));}catch(c){if(c instanceof h&&c.status===404)return;throw c}if(r.length===0)return;let i=r.length===1;console.log(`${r.join(", ")} ${i?"is":"are"} declared in ${u} but ${i?"has":"have"} no value in this environment. Enter ${i?"it":"them"} now, or leave empty to skip:`);let s=[];for(let c of r){let p=o[c]?.type==="secret",a=await ht(` ${c}${p?" (secret)":""}: `,{secret:p});a.length>0&&s.push({key:c,value:a});}s.length>0&&(await n(s),console.log(`Saved ${s.length} variable${s.length===1?"":"s"}.`));}async function Ct(e){let t=process.cwd(),o=await J(e.host,t);Ne(e.host,o);let n=await lt(t,e),r=n.kind,i=pt(n);i&&console.log(i);let s=await I(t),c=K(s,o),p=c.deploy?[]:Ie(s,o),a=dt(e,c,p),l=await De(o);if((!l||!a)&&!j())throw new Error(Go(!!l,!!a,p));!a&&p.length>0&&console.log(`Note: ${oe(p)} Pick a target for ${o} in the browser, or pass --host to deploy there.`),await Wo(a,c,e.yes);let d,m=join(t,".modelence","tmp",`${r}.zip`);r==="bundle"?(await C(),await X(),await Yo(m)):(d=await at(t),qo(await Xe(t,m)));let be=false;try{if(!l||!a){let f=await A(o,{pick:a?void 0:"deploy",purpose:"deploy",appId:c.appId,env:d?.env});l=f.token,await ce(o,f.token,f.expiresAt),f.target&&(a={environmentId:f.target.environmentId},await le(f.target,o),be=!0);}if(!a)throw new Error("No deploy target selected. Run again and pick an environment in the browser, or pass --app and --env.");let x={host:o,token:l},re=async()=>{if(await U(o),!j())throw new Error("Modelence Cloud rejected the token (expired or revoked), and nobody is at the terminal to sign in again. Set a fresh MODELENCE_TOKEN. A deployment that already started keeps running; check the dashboard.");console.log("Your saved login has expired; please sign in again.");let f=await A(o,{pick:a?void 0:"deploy",purpose:"deploy",appId:c.appId,env:d?.env});await ce(o,f.token,f.expiresAt),f.target&&(a={environmentId:f.target.environmentId},await le(f.target,o)),x.token=f.token;};if(!be&&j()){let f=a,Se=()=>Et({session:x,target:f,env:d?.env});try{await Se();}catch(Pe){if(!D(Pe))throw Pe;await re(),await Se();}}let $;try{$=await ve({session:x,target:a,kind:r,archivePath:m,spec:d});}catch(f){if(!D(f))throw f;await re(),$=await ve({session:x,target:a,kind:r,archivePath:m,spec:d});}$.buildId&&await vt(x,re,$.environmentId,$.buildId);}finally{await promises.rm(m,{force:true});}}function Go(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 `Nobody is at the terminal to sign in or pick a target in the browser (CI or a non-interactive shell). To deploy from here, ${n.join(" and ")}.${r}`}async function Wo(e,t,o){if(!e)return;let n=ut(e,t);if(console.log(`Deploying to ${n}`),o||!mt(e,t)||!j())return;let r=`${t.deploy?.appAlias}/${t.deploy?.envAlias}`;if(!await gt(`This project normally deploys to ${r}. Deploy to ${n} instead?`))throw new Error("Cancelled.")}var bt=10;function St(e){let t=e.slice(0,bt).join(", "),o=e.length-bt;return o>0?`${t} and ${o} more`:t}function qo(e){console.log(`Packed ${e.fileCount} files (${kt(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): ${St(e.excludedFiles)}`),e.committedEnvFiles.length>0&&console.log(`Uploaded environment files committed to git: ${St(e.committedEnvFiles)}`);for(let{path:t,reason:o}of e.skipped)console.warn(`Warning: ${t} is not uploaded (${o}).`);}function kt(e){return `${(e/1024/1024).toFixed(2)} MB`}async function Yo(e){await promises.rm(e,{force:true}),console.log("Creating deployment bundle..."),await promises.mkdir(join(e,".."),{recursive:true});let t=createWriteStream(e),o=yo("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 Pt(P(c))&&o.file(P(c),{name:c});for(let c of i)await Pt(P(c))&&o.directory(P(c),c);await o.finalize(),await n;let s=await promises.stat(e);console.log(`Deployment bundle created (${kt(s.size)})`);}async function Pt(e){try{return await promises.access(e),!0}catch{return false}}function xt(e={}){console.log("Starting Modelence dev server...");let t=S(),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 At(){console.log("Starting Modelence production server...");let e=S(),t=ge.basename(e,ge.extname(e)),o=Y(`${t}.mjs`);execSync(`node "${o}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"production"}});}async function Tt(e){let t=e.host?v(e.host):void 0,o=await xe(t);await Promise.all(o.map(n=>en(n.host,n.token))),await U(t),console.log(t?`Removed the saved login for ${t}.`:`Removed saved logins (${L()}).`);}async function en(e,t){try{await g(e,"/api/cli/logout",{method:"POST",token:t});}catch{}}async function It(e){let t=process.cwd(),o=ee(t);if(!e.force&&await on(o))throw new Error(`${u} already exists; pass --force to overwrite it.`);let n=await J(e.host,t),r={$schema:et(n),resources:{app:{type:"service",image:"node-22-slim",build:{commands:["npm ci"]},static:[]}},env:{}};await tt(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(` ${Q}`),console.log(""),console.log(`Reference: ${O}`),console.log(`Once ${u} describes your app, run \`npx modelence@latest deploy\`.`);}async function on(e){try{return await promises.access(e),!0}catch{return false}}var ln=fileURLToPath(import.meta.url),pn=dirname(ln),dn=JSON.parse(readFileSync(join(pn,"../../package.json"),"utf-8")),y=new Command().name("modelence").description("Modelence CLI tool").version(dn.version);y.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 Me(e);});y.command("build").description("Build the application").action(async()=>{await C(),await X();});y.command("deploy").description("Deploy the project described by modelence.config.json to Modelence Cloud (picks the target in the browser on first run)").option("-a, --app <app>","Application alias").option("-e, --env <env>","Environment alias").option("-h, --host <host>","Modelence host").option("--prebuilt","Build locally and upload the .modelence/build bundle (Modelence apps only)").option("-y, --yes","Deploy to the given --app/--env without asking, even if it is not the saved target").action(async e=>{try{await Ct(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 It(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 Tt(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 C(),xt(e);});y.command("start").description("Start production server").action(async()=>{await C(),At();});y.parse(process.argv);//# sourceMappingURL=modelence.js.map
19
21
  //# sourceMappingURL=modelence.js.map