modelence 0.26.0-nd.dev.1 → 0.26.0-nd.dev.3

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,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import {Command}from'commander';import {readFileSync,promises,createWriteStream}from'fs';import {fileURLToPath}from'url';import K,{join,dirname,relative,sep}from'path';import {parse}from'dotenv';import {createInterface}from'readline';import {execFile,execSync,spawnSync}from'child_process';import _e from'open';import le 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 bt from'archiver';import at from'os';import {promisify}from'util';async function P(e,{pick:t,pickEnvironment:n=false,appId:o}={}){let r=await fetch(`${e}/api/cli/auth`,{method:"POST"});if(!r.ok)throw new Error("Failed to create CLI authentication code");let{code:s,verificationUrl:c}=await r.json(),a=new URL(c),i=t??(n?"environment":void 0);i&&a.searchParams.set("pick",i),o&&a.searchParams.set("appId",o),console.log(`Please visit ${a} to authenticate`),console.log(`Code: ${s}`);try{await _e(a.toString());}catch{console.log("Could not open a browser automatically. Please open the URL above manually.");}return await $e(e,s)}async function $e(e,t){let r=Date.now()+6e5;for(;Date.now()<r;){try{let s=await Re(e,t);if(s)return s}catch(s){console.error("Error polling for CLI token:",s);}await new Promise(s=>setTimeout(s,5e3));}throw new Error("Unable to authenticate CLI - timed out. Please try again.")}async function Re(e,t){let n=await fetch(`${e}/api/cli/token?code=${t}`,{method:"GET"});if(!n.ok)throw new Error(`CLI token polling failed: ${n.statusText}`);let{token:o,expiresAt:r,target:s}=await n.json();return o?{token:o,expiresAt:r,target:s}:null}var k=".modelence",N="project.json";function ee(e=process.cwd()){return join(e,k,N)}async function D(e=process.cwd()){try{let t=await promises.readFile(ee(e),"utf8"),n=JSON.parse(t);return n&&typeof n=="object"?n:{}}catch{return {}}}async function S(e,t=process.cwd()){let n=await D(t);await promises.mkdir(join(t,k),{recursive:true}),await promises.writeFile(ee(t),JSON.stringify({...n,...e},null,2)+`
3
- `);}var V=".modelence.env";async function Be(e,t){let n="setupToken"in t?{"X-Modelence-Setup-Token":t.setupToken}:{Authorization:`Bearer ${t.cliToken}`},o=await fetch(`${e}/api/setup`,{method:"GET",headers:n});if(!o.ok){let r=await o.text();throw new Error(r||`Request failed with status ${o.status}`)}return o.json()}async function ne(e){let t=createInterface({input:process.stdin,output:process.stdout});return new Promise(n=>{t.question(e,o=>{t.close(),n(o.trim());});})}async function Ue(){return (await ne(`Warning: ${V} already exists. Do you want to overwrite it? (y/N) `)).toLowerCase()==="y"}function Ve(e){return String(e).replace(/"/g,'\\"')}async function Je(){let{appId:e}=await D();return typeof e=="string"&&e?e:void 0}async function Ge(e){await S({appId:e});}var oe=".claude",I=join(oe,"settings.json"),O="modelence@modelence",J="modelence/modelence",ze={modelence:{source:{source:"github",repo:J}}},Ke="https://docs.modelence.com/ai-coding-agents",te=`Install the Modelence plugin for Claude Code by hand:
4
- claude plugin marketplace add ${J}
5
- claude plugin install ${O} --scope project
6
- Guide: ${Ke}`;async function qe(){let e=join(process.cwd(),I),t;try{t=await promises.readFile(e,"utf8");}catch(o){if(o.code!=="ENOENT"){console.warn(`Could not read ${I}; leaving it unchanged.`);return}}let n={};if(t!==void 0)try{n=JSON.parse(t);}catch{console.warn(`Could not parse ${I}; leaving it unchanged.`);return}n.extraKnownMarketplaces={...n.extraKnownMarketplaces,...ze},n.enabledPlugins?.[O]===void 0&&(n.enabledPlugins={...n.enabledPlugins,[O]:true});try{await promises.mkdir(join(process.cwd(),oe),{recursive:!0}),await promises.writeFile(e,JSON.stringify(n,null,2)+`
7
- `),console.log(`Declared the Modelence Claude Code plugin in ${I}`);}catch(o){console.warn(`Failed to write ${I}:`,o);}}function U(e){return spawnSync("claude",e,{encoding:"utf8",shell:process.platform==="win32"})}async function We(){let e=U(["--version"]);if(e.error||e.status!==0){console.log(te);return}let t=(await ne("Install the Modelence plugin for Claude Code? (Y/n) ")).toLowerCase();if(t&&t!=="y"&&t!=="yes")return;let n=U(["plugin","marketplace","add",J]),o=U(["plugin","install",O,"--scope","project"]);if(o.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=n.status!==0?n:o;console.warn(`Could not install the Modelence plugin: ${(r.stderr||r.stdout||"").trim()}`),console.warn(te);}}async function Ye(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 re(e){try{let t=join(process.cwd(),V),n={},o=!1;try{let i=await promises.readFile(t,"utf8");n=parse(i),o=!0,await Ye(t),await Ue()||(console.log("Setup canceled"),process.exit(0));}catch{}let r;if(e.token)r={setupToken:e.token};else {let{token:i}=await P(e.host,{pickEnvironment:!0,appId:await Je()});r={cliToken:i};}console.log("Fetching service configuration...");let s=await Be(e.host,r),c={...n,MODELENCE_TELEMETRY_ENABLED:"false",MODELENCE_ENVIRONMENT_ID:s.environmentId,MODELENCE_SERVICE_ENDPOINT:e.host,MODELENCE_SERVICE_TOKEN:s.serviceToken,MODELENCE_CONTAINER_ID:s.containerId,MODELENCE_RUNTIME:process.env.MODELENCE_RUNTIME||"local"},a=Object.entries(c).map(([i,u])=>`${i}="${Ve(u)}"`).join(`
2
+ import {Command}from'commander';import {readFileSync,promises,createWriteStream}from'fs';import {fileURLToPath}from'url';import q,{join,dirname,relative,sep}from'path';import {parse}from'dotenv';import {createInterface}from'readline';import {execFile,execSync,spawnSync}from'child_process';import _e from'open';import de 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 kt from'archiver';import ct from'os';import {promisify}from'util';async function k(e,{pick:t,pickEnvironment:n=false,appId:o}={}){let r=await fetch(`${e}/api/cli/auth`,{method:"POST"});if(!r.ok)throw new Error("Failed to create CLI authentication code");let{code:s,verificationUrl:c}=await r.json(),a=new URL(c),i=t??(n?"environment":void 0);i&&a.searchParams.set("pick",i),o&&a.searchParams.set("appId",o),console.log(`Please visit ${a} to authenticate`),console.log(`Code: ${s}`);try{await _e(a.toString());}catch{console.log("Could not open a browser automatically. Please open the URL above manually.");}return await Re(e,s)}async function Re(e,t){let r=Date.now()+6e5;for(;Date.now()<r;){try{let s=await je(e,t);if(s)return s}catch(s){console.error("Error polling for CLI token:",s);}await new Promise(s=>setTimeout(s,5e3));}throw new Error("Unable to authenticate CLI - timed out. Please try again.")}async function je(e,t){let n=await fetch(`${e}/api/cli/token?code=${t}`,{method:"GET"});if(!n.ok)throw new Error(`CLI token polling failed: ${n.statusText}`);let{token:o,expiresAt:r,target:s}=await n.json();return o?{token:o,expiresAt:r,target:s}:null}var P=".modelence",S="project.json";function te(e=process.cwd()){return join(e,P,S)}async function D(e=process.cwd()){try{let t=await promises.readFile(te(e),"utf8"),n=JSON.parse(t);return n&&typeof n=="object"?n:{}}catch{return {}}}async function A(e,t=process.cwd()){let n=await D(t);await promises.mkdir(join(t,P),{recursive:true}),await promises.writeFile(te(t),JSON.stringify({...n,...e},null,2)+`
3
+ `);}var J=".modelence.env";async function Ue(e,t){let n="setupToken"in t?{"X-Modelence-Setup-Token":t.setupToken}:{Authorization:`Bearer ${t.cliToken}`},o=await fetch(`${e}/api/setup`,{method:"GET",headers:n});if(!o.ok){let r=await o.text();throw new Error(r||`Request failed with status ${o.status}`)}return o.json()}async function oe(e){let t=createInterface({input:process.stdin,output:process.stdout});return new Promise(n=>{t.question(e,o=>{t.close(),n(o.trim());});})}async function Ve(){return (await oe(`Warning: ${J} already exists. Do you want to overwrite it? (y/N) `)).toLowerCase()==="y"}function Je(e){return String(e).replace(/"/g,'\\"')}async function Ge(){let{appId:e}=await D();return typeof e=="string"&&e?e:void 0}async function ze(e){await A({appId:e});}var re=".claude",I=join(re,"settings.json"),M="modelence@modelence",G="modelence/modelence",Ke={modelence:{source:{source:"github",repo:G}}},qe="https://docs.modelence.com/ai-coding-agents",ne=`Install the Modelence plugin for Claude Code by hand:
4
+ claude plugin marketplace add ${G}
5
+ claude plugin install ${M} --scope project
6
+ Guide: ${qe}`;async function We(){let e=join(process.cwd(),I),t;try{t=await promises.readFile(e,"utf8");}catch(o){if(o.code!=="ENOENT"){console.warn(`Could not read ${I}; leaving it unchanged.`);return}}let n={};if(t!==void 0)try{n=JSON.parse(t);}catch{console.warn(`Could not parse ${I}; leaving it unchanged.`);return}n.extraKnownMarketplaces={...n.extraKnownMarketplaces,...Ke},n.enabledPlugins?.[M]===void 0&&(n.enabledPlugins={...n.enabledPlugins,[M]:true});try{await promises.mkdir(join(process.cwd(),re),{recursive:!0}),await promises.writeFile(e,JSON.stringify(n,null,2)+`
7
+ `),console.log(`Declared the Modelence Claude Code plugin in ${I}`);}catch(o){console.warn(`Failed to write ${I}:`,o);}}function V(e){return spawnSync("claude",e,{encoding:"utf8",shell:process.platform==="win32"})}async function Ye(){let e=V(["--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 n=V(["plugin","marketplace","add",G]),o=V(["plugin","install",M,"--scope","project"]);if(o.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=n.status!==0?n:o;console.warn(`Could not install the Modelence plugin: ${(r.stderr||r.stdout||"").trim()}`),console.warn(ne);}}async function He(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 ie(e){try{let t=join(process.cwd(),J),n={},o=!1;try{let i=await promises.readFile(t,"utf8");n=parse(i),o=!0,await He(t),await Ve()||(console.log("Setup canceled"),process.exit(0));}catch{}let r;if(e.token)r={setupToken:e.token};else {let{token:i}=await k(e.host,{pickEnvironment:!0,appId:await Ge()});r={cliToken:i};}console.log("Fetching service configuration...");let s=await Ue(e.host,r),c={...n,MODELENCE_TELEMETRY_ENABLED:"false",MODELENCE_ENVIRONMENT_ID:s.environmentId,MODELENCE_SERVICE_ENDPOINT:e.host,MODELENCE_SERVICE_TOKEN:s.serviceToken,MODELENCE_CONTAINER_ID:s.containerId,MODELENCE_RUNTIME:process.env.MODELENCE_RUNTIME||"local"},a=Object.entries(c).map(([i,u])=>`${i}="${Je(u)}"`).join(`
8
8
  `);if(await promises.writeFile(t,a.trim()+`
9
- `),console.log(`Successfully configured ${V} file`),s.appId)try{await Ge(s.appId),console.log(`Recorded the app ID in ${k}/${N}`);}catch(i){console.warn(`Failed to record the app ID in ${k}/${N}:`,i);}await qe(),!e.token&&process.stdin.isTTY&&await We(),o&&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."),!o&&c.MODELENCE_RUNTIME==="local"&&(console.log(`
9
+ `),console.log(`Successfully configured ${J} file`),s.appId)try{await ze(s.appId),console.log(`Recorded the app ID in ${P}/${S}`);}catch(i){console.warn(`Failed to record the app ID in ${P}/${S}:`,i);}await We(),!e.token&&process.stdin.isTTY&&await Ye(),o&&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."),!o&&c.MODELENCE_RUNTIME==="local"&&(console.log(`
10
10
  Next step \u2014 run the app on this machine:
11
11
  `),console.log(" npm install (if you haven't already)"),console.log(` npm run dev (starts the app)
12
- `));}catch(t){console.error(`Setup failed: ${t instanceof Error?t.message:"Unknown error"}`),process.exit(1);}}var Qe=z$1.object({serverDir:z$1.string(),serverEntry:z$1.string(),postBuildCommand:z$1.string().optional()});async function ie(){let e=join(process.cwd(),"modelence.config.ts"),n=await createJiti(import.meta.url,{interopDefault:true,requireCache:false}).import(e);if(typeof n!="object")throw new Error("modelence.config.ts should export an object");return Qe.parse(n)}var se=null,G=null;function ae(){if(!G)throw new Error("Configuration not loaded");return G}function w(){let{serverDir:e,serverEntry:t}=ae();return join(e,t).replace(/\\/g,"/")}function ce(){return ae().postBuildCommand}function _(e){let t=z("build");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}function y(e){return join(process.cwd(),e).replace(/\\/g,"/")}function z(e){let t=y(".modelence");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}async function v(){try{G=await ie();}catch(e){throw console.error(e),new Error("Unable to load modelence.config.ts")}try{let e=await le.readFile(join(process.cwd(),".modelence.env"),"utf-8");se=parse(e);}catch(e){if(e.code==="ENOENT")se={};else throw e}}async function ot(){let e=ce();if(e){console.log("Running post-build command..."),execSync(e);return}await rt(),await it();}async function rt(){console.log("Building client with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),t={build:{outDir:K.resolve(process.cwd(),".modelence/build/client").replace(/\\/g,"/"),emptyOutDir:true,ssrManifest:true}};await build$1(mergeConfig(e?.config||{},t,true));}async function it(){console.log("Building SSR bundle with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),n={build:{ssr:K.resolve(process.cwd(),"src/client/index.tsx").replace(/\\/g,"/"),outDir:K.resolve(process.cwd(),".modelence/build/ssr").replace(/\\/g,"/"),emptyOutDir:true,rollupOptions:{output:{format:"esm",entryFileNames:"index.mjs"}}}};await build$1(mergeConfig(e?.config||{},n,true));}async function st(){return console.log("Building server with tsup..."),new Promise(e=>{build({entry:[w()],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 $(){console.log("Building Modelence project...");try{let e=_();await le.rm(e,{recursive:!0,force:!0}),await st(),await ot(),console.log("Build completed successfully!");}catch(e){throw console.error(e),new Error("Build failed")}try{await le.access(z());}catch{throw new Error("Could not find the .modelence directory. Looks like something went wrong during the build.")}}var lt="auth.json",dt=60*1e3;function R(){let e=process.env.MODELENCE_HOME||join(at.homedir(),".modelence");return join(e,lt)}async function Y(){try{let e=JSON.parse(await promises.readFile(R(),"utf8"));return e&&typeof e=="object"?e:{}}catch{return {}}}async function W(e){let t=R();await promises.mkdir(dirname(t),{recursive:true,mode:448}),await promises.writeFile(t,JSON.stringify(e,null,2)+`
13
- `,{mode:384});}async function fe(e){let{hosts:t={}}=await Y(),n=t[e];return !n?.token||!n.expiresAt||new Date(n.expiresAt).getTime()-dt<=Date.now()?null:n.token}async function ge(e,t,n){let o=await Y();await W({...o,hosts:{...o.hosts,[e]:{token:t,expiresAt:n}}});}async function j(e){if(!e){await W({});return}let t=await Y(),{[e]:n,...o}=t.hosts??{};await W({...t,hosts:o});}var ut=18;async function m(e){try{return await promises.access(e),!0}catch{return false}}async function pt(e){try{let t=JSON.parse(await promises.readFile(e,"utf8"));return t&&typeof t=="object"?t:null}catch{return null}}function mt(e){if(typeof e!="string")return;let t=e.match(/(\d+)(?:\.\d+)?(?:\.\d+)?/);if(!t)return;let n=Number(t[1]);return n>=ut?String(n):void 0}function ft(e){for(let t of e.split(/\r?\n/)){let n=t.match(/^\s*web\s*:\s*(.+?)\s*$/);if(n)return n[1]}}function gt(e,t){switch(e){case "pnpm":return {install:"npm install -g pnpm && pnpm install --frozen-lockfile",run:n=>`pnpm run ${n}`,start:"pnpm start"};case "yarn":return {install:"yarn install --frozen-lockfile",run:n=>`yarn ${n}`,start:"yarn start"};default:return {install:t?"npm ci":"npm install",run:n=>`npm run ${n}`,start:"npm start"}}}async function he(e=process.cwd()){let t=[],n=await pt(join(e,"package.json"));if(!n)throw new Error("No package.json found in the current directory");let o=n.scripts??{},r=n.engines??{},s=await m(join(e,"modelence.config.ts"))||await m(join(e,"modelence.config.js")),c="npm";await m(join(e,"pnpm-lock.yaml"))?c="pnpm":await m(join(e,"yarn.lock"))&&(c="yarn");let a=await m(join(e,"package-lock.json"));c==="npm"&&!a&&t.push("No package-lock.json found; dependencies are installed with `npm install`.");let i=gt(c,a),u;o.build?u=i.run("build"):s||t.push("No `build` script found; the deploy skips the build step.");let l;try{l=ft(await promises.readFile(join(e,"Procfile"),"utf8"));}catch{}!l&&o.start&&(l=i.start);let d=mt(r.node),b=!s&&!l&&u?await ht(e,n):void 0;return b?(t.push(`No start script found; the site is served from ${b}/ with single-page app fallback.`),{preset:"static",packageManager:c,nodeVersion:d,installCommand:i.install,buildCommand:u,outputDirectory:b,notes:t}):(l||t.push("No `start` script or Procfile found; the container runs `npm start`. Pass --start-command to override."),{preset:s?"modelence":"node",packageManager:c,nodeVersion:d,installCommand:i.install,buildCommand:u,startCommand:l,notes:t})}async function ht(e,t){let n={...t.dependencies??{},...t.devDependencies??{}},o=await m(join(e,"vite.config.ts"))||await m(join(e,"vite.config.js"))||await m(join(e,"vite.config.mts"));if(n.vite||o)return "dist";if(n["react-scripts"])return "build";if(n["@angular/cli"]||n.astro||await m(join(e,"index.html")))return "dist"}var ye=promisify(execFile),we=200*1024*1024,Pt=[".git","node_modules",".modelence/build",".modelence/tmp",".modelence/cache"],kt=[/^\.modelence(\.[^/]+)?\.env$/];function ve(e){return e.split(sep).join("/")}function Ee(e){let t=ve(e),n=t.split("/");for(let r of Pt)if(r.split("/").length===1){if(n.slice(0,-1).includes(r))return true}else if(t===r||t.startsWith(`${r}/`))return true;let o=n[n.length-1];return kt.some(r=>r.test(o))}async function Dt(e){try{let{stdout:t}=await ye("git",["rev-parse","--is-inside-work-tree"],{cwd:e});return t.trim()==="true"}catch{return false}}async function It(e){let{stdout:t}=await ye("git",["ls-files","--cached","--others","--exclude-standard","-z"],{cwd:e,maxBuffer:67108864});return t.split("\0").filter(n=>n.length>0)}async function Ce(e,t=""){let n=await promises.readdir(join(e,t),{withFileTypes:true}),o=[];for(let r of n){let s=t?`${t}/${r.name}`:r.name;r.isDirectory()?Ee(`${s}/x`)||o.push(...await Ce(e,s)):r.isFile()&&o.push(s);}return o}async function Tt(e=process.cwd()){let t=await Dt(e),n=t?await It(e):await Ce(e),o=[];for(let r of n)if(!Ee(r))try{(await promises.stat(join(e,r))).isFile()&&o.push(r);}catch{}return {files:o.sort(),usedGit:t}}async function be(e,t){let{files:n,usedGit:o}=await Tt(e);if(n.length===0)throw new Error("No files to upload");await promises.mkdir(join(t,".."),{recursive:true}),await promises.rm(t,{force:true});let r=createWriteStream(t),s=bt("zip",{zlib:{level:6}}),c=new Promise((i,u)=>{r.on("close",i),r.on("error",u),s.on("error",u);});s.pipe(r);for(let i of n)s.file(join(e,i),{name:ve(relative("",i))});await s.finalize(),await c;let{size:a}=await promises.stat(t);if(a>we)throw await promises.rm(t,{force:true}),new Error(`Source is ${(a/1024/1024).toFixed(0)} MB compressed; the limit is ${we/1024/1024} MB. Add build output and large assets to .gitignore.`);return {fileCount:n.length,sizeBytes:a,usedGit:o}}var C=class extends Error{constructor(n,o){super(n);this.status=o;this.name="StudioApiError";}};async function x(e,t,{method:n="GET",token:o,body:r,query:s}={}){let c=new URL(t,e);for(let[u,l]of Object.entries(s??{}))c.searchParams.set(u,String(l));let a={};o&&(a.Authorization=`Bearer ${o}`),r!==void 0&&(a["Content-Type"]="application/json");let i=await fetch(c,{method:n,headers:a,body:r===void 0?void 0:JSON.stringify(r)});if(!i.ok){let u=await i.text(),l=u||i.statusText;try{let d=JSON.parse(u);l=d.error||d.message||l;}catch{}throw new C(l,i.status)}return await i.json()}var At="https://cloud.modelence.com",Ie=3e3,Ot=30*60*1e3,Mt=10*60*1e3;async function Te(e){let t=process.cwd(),n=await Ft(e.host,t),o=e.prebuilt?"bundle":"source",r=Bt(e),s=await D(t),c,a=join(t,".modelence","tmp",`${o}.zip`);if(o==="bundle")await v(),await $(),await Vt(a);else {let l=await he(t);c={preset:l.preset,nodeVersion:l.nodeVersion,installCommand:l.installCommand,buildCommand:l.buildCommand,startCommand:l.startCommand,outputDirectory:l.outputDirectory},Ut({...c,...Q(r)},l.notes);let{fileCount:d,sizeBytes:b,usedGit:Me}=await be(t,a);console.log(`Packed ${d} files (${xe(b)})`+(Me?" from git":"; not a git repository, so only default exclusions applied"));}let i=jt(e,s),u=await Lt(n);if(!u||!i){let l=await P(n,{pick:"deploy",appId:s.appId});u=l.token,await ke(n,l.token,l.expiresAt),l.target&&(i={environmentId:l.target.environmentId},await X(l.target));}if(!i)throw new Error("No deploy target selected. Run again and pick an environment in the browser, or pass --app and --env.");try{await Pe({host:n,token:u,target:i,kind:o,archivePath:a,overrides:r,detected:c,project:s});}catch(l){if(!(l instanceof C)||l.status!==401)throw l;await j(n),console.log("Your saved login has expired; please sign in again.");let d=await P(n,{pick:"deploy",appId:s.appId});await ke(n,d.token,d.expiresAt),d.target&&(i={environmentId:d.target.environmentId},await X(d.target)),await Pe({host:n,token:d.token,target:i,kind:o,archivePath:a,overrides:r,detected:c,project:s});}finally{await promises.rm(a,{force:true});}}async function Pe({host:e,token:t,target:n,kind:o,archivePath:r,overrides:s,detected:c,project:a}){let i=await x(e,"/api/upload-bundle",{method:"POST",token:t,body:{...n,kind:o}});await _t(e,t,i.environmentId),console.log(`Uploading to ${i.appAlias}/${i.envAlias}...`);let u=await promises.readFile(r),l=await fetch(i.uploadUrl,{method:"PUT",body:new Uint8Array(u),headers:{"Content-Type":"application/zip"}});if(!l.ok)throw new Error(`Failed to upload: ${l.statusText}`);let d=await x(e,"/api/deploy",{method:"POST",token:t,body:{environmentId:i.environmentId,bundleName:i.bundleName,kind:o,plan:Q(s),detected:c?Q(c):void 0}});(!a.deploy||a.deploy.environmentId!==d.environmentId)&&await X({environmentId:d.environmentId,appAlias:d.appAlias,envAlias:d.envAlias}),console.log(`Deployment started: ${d.deploymentUrl}`),d.buildId&&await $t(e,t,d.environmentId,d.buildId);}async function _t(e,t,n){let o=Date.now()+Mt,r=false;for(;Date.now()<o;){let s;try{({status:s}=await x(e,"/api/environment/status",{token:t,query:{environmentId:n}}));}catch(c){if(c instanceof C&&c.status===404)return;throw c}if(s==="ready")return;if(s==="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(c=>setTimeout(c,Ie));}throw new Error("Timed out waiting for the environment to be ready.")}async function $t(e,t,n,o){let r=Date.now()+Ot,s="",c=0;for(;Date.now()<r;){let a=await x(e,"/api/deploy/status",{token:t,query:{environmentId:n,buildId:o,logOffset:c}});for(let i of a.logs)process.stdout.write(` \u2502 ${i.replace(/\n$/,"")}
14
- `);if(c=a.logCount,a.status!==s){s=a.status;let i=Rt(a);i&&console.log(i);}if(a.status==="deploy-completed"){a.siteUrl&&console.log(`Live at ${a.siteUrl}`);return}if(a.status==="build-failed"||a.status==="deploy-failed"){for(let i of a.errors)console.error(` ${i}`);process.exitCode=1;return}await new Promise(i=>setTimeout(i,Ie));}console.error("Timed out waiting for the deployment; check the dashboard for its status."),process.exitCode=1;}function Rt(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}}function jt(e,t){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.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}async function Lt(e){return process.env.MODELENCE_TOKEN?process.env.MODELENCE_TOKEN:await fe(e)}async function ke(e,t,n){if(n)try{await ge(e,t,n);}catch(o){console.warn("Could not save the login for next time:",o);}}async function X(e){let t={environmentId:e.environmentId,appAlias:e.appAlias,envAlias:e.envAlias};try{await S({deploy:t,..."appId"in e?{appId:e.appId}:{}});}catch(n){console.warn("Could not record the deploy target in .modelence/project.json:",n);}}async function Ft(e,t){if(e)return e.replace(/\/$/,"");if(process.env.MODELENCE_SERVICE_ENDPOINT)return process.env.MODELENCE_SERVICE_ENDPOINT.replace(/\/$/,"");try{let n=parse(await promises.readFile(join(t,".modelence.env"),"utf8"));if(n.MODELENCE_SERVICE_ENDPOINT)return n.MODELENCE_SERVICE_ENDPOINT.replace(/\/$/,"")}catch{}return At}function Bt(e){return {preset:e.preset,nodeVersion:e.nodeVersion,rootDirectory:e.rootDir,installCommand:e.installCommand,buildCommand:e.buildCommand,startCommand:e.startCommand,outputDirectory:e.outputDir}}function Q(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}function Ut(e,t){console.log("Build plan:"),console.log(` preset: ${e.preset??"node"}`),console.log(` node: ${e.nodeVersion??"default (22)"}`),e.rootDirectory&&console.log(` root: ${e.rootDirectory}`),console.log(` install: ${e.installCommand??"default"}`),console.log(` build: ${e.buildCommand||"(none)"}`),e.preset==="static"?console.log(` serve: ${e.outputDirectory??"dist"}/ (static site)`):console.log(` start: ${e.startCommand??"npm start"}`);for(let n of t)console.log(` note: ${n}`);}function xe(e){return `${(e/1024/1024).toFixed(2)} MB`}async function Vt(e){await promises.rm(e,{force:true}),console.log("Creating deployment bundle..."),await promises.mkdir(join(e,".."),{recursive:true});let t=createWriteStream(e),n=bt("zip",{zlib:{level:9}}),o=new Promise((a,i)=>{t.on("close",a),t.on("error",i),n.on("error",i);});n.pipe(t);let r=["package.json","package-lock.json","next.config.js","next.config.ts","modelence.config.ts"],s=["public","server","scripts",join(".modelence","build"),".next"];for(let a of r)await De(y(a))&&n.file(y(a),{name:a});for(let a of s)await De(y(a))&&n.directory(y(a),a);await n.finalize(),await o;let c=await promises.stat(e);console.log(`Deployment bundle created (${xe(c.size)})`);}async function De(e){try{return await promises.access(e),!0}catch{return false}}function Ne(e={}){console.log("Starting Modelence dev server...");let t=w(),n=K.resolve("./node_modules/.bin/tsx");execSync(`"${n}" watch --ignore "vite.config.ts.timestamp-*" "${t}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"development",...e.takeover?{MODELENCE_TAKEOVER:"1"}:{}}});}function Ae(){console.log("Starting Modelence production server...");let e=w(),t=K.basename(e,K.extname(e)),n=_(`${t}.mjs`);execSync(`node "${n}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"production"}});}async function Oe(e){await j(e.host),console.log(e.host?`Removed the saved login for ${e.host}.`:`Removed saved logins (${R()}).`);}var Xt=fileURLToPath(import.meta.url),Qt=dirname(Xt),Zt=JSON.parse(readFileSync(join(Qt,"../../package.json"),"utf-8")),g=new Command().name("modelence").description("Modelence CLI tool").version(Zt.version);g.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 re(e);});g.command("build").description("Build the application").action(async()=>{await v(),await $();});g.command("deploy").description("Deploy the current directory to Modelence Cloud (any Node.js app; 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("--preset <preset>","Build preset: node, static or modelence (default: detected)").option("--node-version <version>","Node.js version for the container, e.g. 22").option("--root-dir <path>","Subdirectory containing the app (monorepos)").option("--install-command <command>","Override the detected install command").option("--build-command <command>",'Override the detected build command ("" to skip)').option("--start-command <command>","Override the detected start command").option("--output-dir <path>","Static sites: directory the build writes, e.g. dist").action(async e=>{try{await Te(e);}catch(t){console.error(`Deploy failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});g.command("logout").description("Forget the saved Modelence Cloud login").option("-h, --host <host>","Only forget the login for this host").action(async e=>{await Oe(e);});g.command("dev").description("Start development server").option("--takeover","Disconnect any instance currently holding the environment and connect this one").action(async e=>{await v(),Ne(e);});g.command("start").description("Start production server").action(async()=>{await v(),Ae();});g.parse(process.argv);//# sourceMappingURL=modelence.js.map
12
+ `));}catch(t){console.error(`Setup failed: ${t instanceof Error?t.message:"Unknown error"}`),process.exit(1);}}var Ze=z$1.object({serverDir:z$1.string(),serverEntry:z$1.string(),postBuildCommand:z$1.string().optional()});async function se(){let e=join(process.cwd(),"modelence.config.ts"),n=await createJiti(import.meta.url,{interopDefault:true,requireCache:false}).import(e);if(typeof n!="object")throw new Error("modelence.config.ts should export an object");return Ze.parse(n)}var ae=null,z=null;function ce(){if(!z)throw new Error("Configuration not loaded");return z}function w(){let{serverDir:e,serverEntry:t}=ce();return join(e,t).replace(/\\/g,"/")}function le(){return ce().postBuildCommand}function _(e){let t=K("build");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}function y(e){return join(process.cwd(),e).replace(/\\/g,"/")}function K(e){let t=y(".modelence");return e?join(t,e).replace(/\\/g,"/"):t.replace(/\\/g,"/")}async function v(){try{z=await se();}catch(e){throw console.error(e),new Error("Unable to load modelence.config.ts")}try{let e=await de.readFile(join(process.cwd(),".modelence.env"),"utf-8");ae=parse(e);}catch(e){if(e.code==="ENOENT")ae={};else throw e}}async function rt(){let e=le();if(e){console.log("Running post-build command..."),execSync(e);return}await it(),await st();}async function it(){console.log("Building client with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),t={build:{outDir:q.resolve(process.cwd(),".modelence/build/client").replace(/\\/g,"/"),emptyOutDir:true,ssrManifest:true}};await build$1(mergeConfig(e?.config||{},t,true));}async function st(){console.log("Building SSR bundle with Vite...");let e=await loadConfigFromFile({command:"build",mode:process.env.NODE_ENV||"production"}),n={build:{ssr:q.resolve(process.cwd(),"src/client/index.tsx").replace(/\\/g,"/"),outDir:q.resolve(process.cwd(),".modelence/build/ssr").replace(/\\/g,"/"),emptyOutDir:true,rollupOptions:{output:{format:"esm",entryFileNames:"index.mjs"}}}};await build$1(mergeConfig(e?.config||{},n,true));}async function at(){return console.log("Building server with tsup..."),new Promise(e=>{build({entry:[w()],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 R(){console.log("Building Modelence project...");try{let e=_();await de.rm(e,{recursive:!0,force:!0}),await at(),await rt(),console.log("Build completed successfully!");}catch(e){throw console.error(e),new Error("Build failed")}try{await de.access(K());}catch{throw new Error("Could not find the .modelence directory. Looks like something went wrong during the build.")}}var dt="auth.json",ut=60*1e3;function j(){let e=process.env.MODELENCE_HOME||join(ct.homedir(),".modelence");return join(e,dt)}async function H(){try{let e=JSON.parse(await promises.readFile(j(),"utf8"));return e&&typeof e=="object"?e:{}}catch{return {}}}async function Y(e){let t=j();await promises.mkdir(dirname(t),{recursive:true,mode:448}),await promises.writeFile(t,JSON.stringify(e,null,2)+`
13
+ `,{mode:384});}async function ge(e){let{hosts:t={}}=await H(),n=t[e];return !n?.token||!n.expiresAt||new Date(n.expiresAt).getTime()-ut<=Date.now()?null:n.token}async function he(e,t,n){let o=await H();await Y({...o,hosts:{...o.hosts,[e]:{token:t,expiresAt:n}}});}async function L(e){if(!e){await Y({});return}let t=await H(),{[e]:n,...o}=t.hosts??{};await Y({...t,hosts:o});}var pt=18;async function m(e){try{return await promises.access(e),!0}catch{return false}}async function we(e){try{let t=JSON.parse(await promises.readFile(e,"utf8"));return t&&typeof t=="object"?t:null}catch{return null}}function mt(e){if(typeof e!="string")return;let t=e.match(/(\d+)(?:\.\d+)?(?:\.\d+)?/);if(!t)return;let n=Number(t[1]);return n>=pt?String(n):void 0}function ft(e){for(let t of e.split(/\r?\n/)){let n=t.match(/^\s*web\s*:\s*(.+?)\s*$/);if(n)return n[1]}}function gt(e,t){let o=t.packages?.[""];if(!o)return true;for(let r of ["dependencies","devDependencies","optionalDependencies"]){let s=e[r]??{},c=o[r]??{},a=new Set([...Object.keys(s),...Object.keys(c)]);for(let i of a)if(s[i]!==c[i])return false}return true}function ht(e,t){switch(e){case "pnpm":return {install:"npm install -g pnpm && pnpm install --frozen-lockfile",run:n=>`pnpm run ${n}`,start:"pnpm start"};case "yarn":return {install:"yarn install --frozen-lockfile",run:n=>`yarn ${n}`,start:"yarn start"};default:return {install:t?"npm ci":"npm install",run:n=>`npm run ${n}`,start:"npm start"}}}async function ye(e=process.cwd()){let t=[],n=await we(join(e,"package.json"));if(!n)throw new Error("No package.json found in the current directory");let o=n.scripts??{},r=n.engines??{},s=await m(join(e,"modelence.config.ts"))||await m(join(e,"modelence.config.js")),c="npm";await m(join(e,"pnpm-lock.yaml"))?c="pnpm":await m(join(e,"yarn.lock"))&&(c="yarn");let a=await m(join(e,"package-lock.json"));if(c==="npm"&&!a&&t.push("No package-lock.json found; dependencies are installed with `npm install`."),c==="npm"&&a){let N=await we(join(e,"package-lock.json"));N&&!gt(n,N)&&(a=false,t.push("package-lock.json is out of date with package.json, so dependencies are installed with `npm install`. Run `npm install` locally and commit the lockfile to get reproducible `npm ci` installs."));}let i=ht(c,a),u;o.build?u=i.run("build"):s||t.push("No `build` script found; the deploy skips the build step.");let l;try{l=ft(await promises.readFile(join(e,"Procfile"),"utf8"));}catch{}!l&&o.start&&(l=i.start);let d=mt(r.node),b=!s&&!l&&u?await wt(e,n):void 0;return b?(t.push(`No start script found; the site is served from ${b}/ with single-page app fallback.`),{preset:"static",packageManager:c,nodeVersion:d,installCommand:i.install,buildCommand:u,outputDirectory:b,notes:t}):(l||t.push("No `start` script or Procfile found; the container runs `npm start`. Pass --start-command to override."),{preset:s?"modelence":"node",packageManager:c,nodeVersion:d,installCommand:i.install,buildCommand:u,startCommand:l,notes:t})}async function wt(e,t){let n={...t.dependencies??{},...t.devDependencies??{}},o=await m(join(e,"vite.config.ts"))||await m(join(e,"vite.config.js"))||await m(join(e,"vite.config.mts"));if(n.vite||o)return "dist";if(n["react-scripts"])return "build";if(n["@angular/cli"]||n.astro||await m(join(e,"index.html")))return "dist"}var Ee=promisify(execFile),ve=200*1024*1024,Pt=[".git","node_modules",".modelence/build",".modelence/tmp",".modelence/cache"],Dt=[/^\.modelence(\.[^/]+)?\.env$/];function Ce(e){return e.split(sep).join("/")}function be(e){let t=Ce(e),n=t.split("/");for(let r of Pt)if(r.split("/").length===1){if(n.slice(0,-1).includes(r))return true}else if(t===r||t.startsWith(`${r}/`))return true;let o=n[n.length-1];return Dt.some(r=>r.test(o))}async function It(e){try{let{stdout:t}=await Ee("git",["rev-parse","--is-inside-work-tree"],{cwd:e});return t.trim()==="true"}catch{return false}}async function Tt(e){let{stdout:t}=await Ee("git",["ls-files","--cached","--others","--exclude-standard","-z"],{cwd:e,maxBuffer:67108864});return t.split("\0").filter(n=>n.length>0)}async function ke(e,t=""){let n=await promises.readdir(join(e,t),{withFileTypes:true}),o=[];for(let r of n){let s=t?`${t}/${r.name}`:r.name;r.isDirectory()?be(`${s}/x`)||o.push(...await ke(e,s)):r.isFile()&&o.push(s);}return o}async function xt(e=process.cwd()){let t=await It(e),n=t?await Tt(e):await ke(e),o=[];for(let r of n)if(!be(r))try{(await promises.stat(join(e,r))).isFile()&&o.push(r);}catch{}return {files:o.sort(),usedGit:t}}async function Pe(e,t){let{files:n,usedGit:o}=await xt(e);if(n.length===0)throw new Error("No files to upload");await promises.mkdir(join(t,".."),{recursive:true}),await promises.rm(t,{force:true});let r=createWriteStream(t),s=kt("zip",{zlib:{level:6}}),c=new Promise((i,u)=>{r.on("close",i),r.on("error",u),s.on("error",u);});s.pipe(r);for(let i of n)s.file(join(e,i),{name:Ce(relative("",i))});await s.finalize(),await c;let{size:a}=await promises.stat(t);if(a>ve)throw await promises.rm(t,{force:true}),new Error(`Source is ${(a/1024/1024).toFixed(0)} MB compressed; the limit is ${ve/1024/1024} MB. Add build output and large assets to .gitignore.`);return {fileCount:n.length,sizeBytes:a,usedGit:o}}var C=class extends Error{constructor(n,o){super(n);this.status=o;this.name="StudioApiError";}};async function x(e,t,{method:n="GET",token:o,body:r,query:s}={}){let c=new URL(t,e);for(let[u,l]of Object.entries(s??{}))c.searchParams.set(u,String(l));let a={};o&&(a.Authorization=`Bearer ${o}`),r!==void 0&&(a["Content-Type"]="application/json");let i=await fetch(c,{method:n,headers:a,body:r===void 0?void 0:JSON.stringify(r)});if(!i.ok){let u=await i.text(),l=u||i.statusText;try{let d=JSON.parse(u);l=d.error||d.message||l;}catch{}throw new C(l,i.status)}return await i.json()}var Ot="https://cloud.modelence.com",xe=3e3,Mt=30*60*1e3,$t=10*60*1e3;async function Ne(e){let t=process.cwd(),n=await Bt(e.host,t),o=e.prebuilt?"bundle":"source",r=Ut(e),s=await D(t),c,a=join(t,".modelence","tmp",`${o}.zip`);if(o==="bundle")await v(),await R(),await Gt(a);else {let l=await ye(t);c={preset:l.preset,nodeVersion:l.nodeVersion,installCommand:l.installCommand,buildCommand:l.buildCommand,startCommand:l.startCommand,outputDirectory:l.outputDirectory},Vt({...c,...Z(r)},l.notes);let{fileCount:d,sizeBytes:b,usedGit:N}=await Pe(t,a);console.log(`Packed ${d} files (${Se(b)})`+(N?" from git":"; not a git repository, so only default exclusions applied"));}let i=Lt(e,s),u=await Ft(n);if(!u||!i){let l=await k(n,{pick:"deploy",appId:s.appId});u=l.token,await Ie(n,l.token,l.expiresAt),l.target&&(i={environmentId:l.target.environmentId},await Q(l.target));}if(!i)throw new Error("No deploy target selected. Run again and pick an environment in the browser, or pass --app and --env.");try{await De({host:n,token:u,target:i,kind:o,archivePath:a,overrides:r,detected:c,project:s});}catch(l){if(!(l instanceof C)||l.status!==401)throw l;await L(n),console.log("Your saved login has expired; please sign in again.");let d=await k(n,{pick:"deploy",appId:s.appId});await Ie(n,d.token,d.expiresAt),d.target&&(i={environmentId:d.target.environmentId},await Q(d.target)),await De({host:n,token:d.token,target:i,kind:o,archivePath:a,overrides:r,detected:c,project:s});}finally{await promises.rm(a,{force:true});}}async function De({host:e,token:t,target:n,kind:o,archivePath:r,overrides:s,detected:c,project:a}){let i=await x(e,"/api/upload-bundle",{method:"POST",token:t,body:{...n,kind:o}});await _t(e,t,i.environmentId),console.log(`Uploading to ${i.appAlias}/${i.envAlias}...`);let u=await promises.readFile(r),l=await fetch(i.uploadUrl,{method:"PUT",body:new Uint8Array(u),headers:{"Content-Type":"application/zip"}});if(!l.ok)throw new Error(`Failed to upload: ${l.statusText}`);let d=await x(e,"/api/deploy",{method:"POST",token:t,body:{environmentId:i.environmentId,bundleName:i.bundleName,kind:o,plan:Z(s),detected:c?Z(c):void 0}});(!a.deploy||a.deploy.environmentId!==d.environmentId)&&await Q({environmentId:d.environmentId,appAlias:d.appAlias,envAlias:d.envAlias}),d.plan&&Jt(d.plan,c),console.log(`Deployment started: ${d.deploymentUrl}`),d.buildId&&await Rt(e,t,d.environmentId,d.buildId);}async function _t(e,t,n){let o=Date.now()+$t,r=false;for(;Date.now()<o;){let s;try{({status:s}=await x(e,"/api/environment/status",{token:t,query:{environmentId:n}}));}catch(c){if(c instanceof C&&c.status===404)return;throw c}if(s==="ready")return;if(s==="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(c=>setTimeout(c,xe));}throw new Error("Timed out waiting for the environment to be ready.")}async function Rt(e,t,n,o){let r=Date.now()+Mt,s="",c=0;for(;Date.now()<r;){let a=await x(e,"/api/deploy/status",{token:t,query:{environmentId:n,buildId:o,logOffset:c}});for(let i of a.logs)process.stdout.write(` \u2502 ${i.replace(/\n$/,"")}
14
+ `);if(c=a.logCount,a.status!==s){s=a.status;let i=jt(a);i&&console.log(i);}if(a.status==="deploy-completed"){a.siteUrl&&console.log(`Live at ${a.siteUrl}`);return}if(a.status==="build-failed"||a.status==="deploy-failed"){for(let i of a.errors)console.error(` ${i}`);process.exitCode=1;return}await new Promise(i=>setTimeout(i,xe));}console.error("Timed out waiting for the deployment; check the dashboard for its status."),process.exitCode=1;}function jt(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}}function Lt(e,t){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.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}async function Ft(e){return process.env.MODELENCE_TOKEN?process.env.MODELENCE_TOKEN:await ge(e)}async function Ie(e,t,n){if(n)try{await he(e,t,n);}catch(o){console.warn("Could not save the login for next time:",o);}}async function Q(e){let t={environmentId:e.environmentId,appAlias:e.appAlias,envAlias:e.envAlias};try{await A({deploy:t,..."appId"in e?{appId:e.appId}:{}});}catch(n){console.warn("Could not record the deploy target in .modelence/project.json:",n);}}async function Bt(e,t){if(e)return e.replace(/\/$/,"");if(process.env.MODELENCE_SERVICE_ENDPOINT)return process.env.MODELENCE_SERVICE_ENDPOINT.replace(/\/$/,"");try{let n=parse(await promises.readFile(join(t,".modelence.env"),"utf8"));if(n.MODELENCE_SERVICE_ENDPOINT)return n.MODELENCE_SERVICE_ENDPOINT.replace(/\/$/,"")}catch{}return Ot}function Ut(e){return {preset:e.preset,nodeVersion:e.nodeVersion,rootDirectory:e.rootDir,installCommand:e.installCommand,buildCommand:e.buildCommand,startCommand:e.startCommand,outputDirectory:e.outputDir}}function Z(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}function Vt(e,t){console.log("Build plan:"),console.log(` preset: ${e.preset??"node"}`),console.log(` node: ${e.nodeVersion??"default (22)"}`),e.rootDirectory&&console.log(` root: ${e.rootDirectory}`),console.log(` install: ${e.installCommand??"default"}`),console.log(` build: ${e.buildCommand||"(none)"}`),e.preset==="static"?console.log(` serve: ${e.outputDirectory??"dist"}/ (static site)`):console.log(` start: ${e.startCommand??"npm start"}`);for(let n of t)console.log(` note: ${n}`);}function Jt(e,t){if(!t)return;let n=[];e.preset&&t.preset&&e.preset!==t.preset&&n.push(`preset ${e.preset} (detected ${t.preset})`);for(let o of ["installCommand","buildCommand","startCommand"]){let r=t[o];r!==void 0&&e[o]!==void 0&&e[o]!==r&&n.push(`${o.replace("Command","")} "${e[o]}" (detected "${r}")`);}n.length>0&&(console.log("Using the environment's Build & Deploy settings: "+n.join(", ")),console.log("Edit them in the dashboard, or pass --preset/--*-command to change them."));}function Se(e){return `${(e/1024/1024).toFixed(2)} MB`}async function Gt(e){await promises.rm(e,{force:true}),console.log("Creating deployment bundle..."),await promises.mkdir(join(e,".."),{recursive:true});let t=createWriteStream(e),n=kt("zip",{zlib:{level:9}}),o=new Promise((a,i)=>{t.on("close",a),t.on("error",i),n.on("error",i);});n.pipe(t);let r=["package.json","package-lock.json","next.config.js","next.config.ts","modelence.config.ts"],s=["public","server","scripts",join(".modelence","build"),".next"];for(let a of r)await Te(y(a))&&n.file(y(a),{name:a});for(let a of s)await Te(y(a))&&n.directory(y(a),a);await n.finalize(),await o;let c=await promises.stat(e);console.log(`Deployment bundle created (${Se(c.size)})`);}async function Te(e){try{return await promises.access(e),!0}catch{return false}}function Ae(e={}){console.log("Starting Modelence dev server...");let t=w(),n=q.resolve("./node_modules/.bin/tsx");execSync(`"${n}" watch --ignore "vite.config.ts.timestamp-*" "${t}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"development",...e.takeover?{MODELENCE_TAKEOVER:"1"}:{}}});}function Me(){console.log("Starting Modelence production server...");let e=w(),t=q.basename(e,q.extname(e)),n=_(`${t}.mjs`);execSync(`node "${n}"`,{stdio:"inherit",cwd:process.cwd(),env:{...process.env,NODE_ENV:"production"}});}async function $e(e){await L(e.host),console.log(e.host?`Removed the saved login for ${e.host}.`:`Removed saved logins (${j()}).`);}var Zt=fileURLToPath(import.meta.url),en=dirname(Zt),tn=JSON.parse(readFileSync(join(en,"../../package.json"),"utf-8")),g=new Command().name("modelence").description("Modelence CLI tool").version(tn.version);g.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 ie(e);});g.command("build").description("Build the application").action(async()=>{await v(),await R();});g.command("deploy").description("Deploy the current directory to Modelence Cloud (any Node.js app; 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("--preset <preset>","Build preset: node, static or modelence (default: detected)").option("--node-version <version>","Node.js version for the container, e.g. 22").option("--root-dir <path>","Subdirectory containing the app (monorepos)").option("--install-command <command>","Override the detected install command").option("--build-command <command>",'Override the detected build command ("" to skip)').option("--start-command <command>","Override the detected start command").option("--output-dir <path>","Static sites: directory the build writes, e.g. dist").action(async e=>{try{await Ne(e);}catch(t){console.error(`Deploy failed: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}});g.command("logout").description("Forget the saved Modelence Cloud login").option("-h, --host <host>","Only forget the login for this host").action(async e=>{await $e(e);});g.command("dev").description("Start development server").option("--takeover","Disconnect any instance currently holding the environment and connect this one").action(async e=>{await v(),Ae(e);});g.command("start").description("Start production server").action(async()=>{await v(),Me();});g.parse(process.argv);//# sourceMappingURL=modelence.js.map
15
15
  //# sourceMappingURL=modelence.js.map