@sleekcms/sync 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{readFileSync as
|
|
2
|
+
import{readFileSync as Be}from"node:fs";import{fileURLToPath as Ar}from"node:url";import{createRequire as jr}from"node:module";import $t from"node:path";import{render as Ir}from"ink";import{execSync as Ht,spawn as B}from"child_process";import{program as Ut,Option as yt}from"commander";function Jt(){return Ut.name("cms-sync").description("SleekCMS CLI tool to sync and edit CMS templates locally. Log in once, then add the sites you want to sync \u2014 changes are watched and pushed automatically.").addOption(new yt("-v, --version","output the version number").hideHelp()).addOption(new yt("-e, --env <env>","Environment (localhost, development, production)").default("production").hideHelp()).addOption(new yt("-d, --dev <secret>","Dev secret for non-production envs (sent as the _dev cookie; enables OTP-in-response). Falls back to SLEEKCMS_DEV_SECRET.").hideHelp()).option("-p, --path <path>","Directory path for files (default: ~/SleekCMS)").addHelpText("after",`
|
|
3
3
|
Examples:
|
|
4
4
|
$ sleekcms # log in and pick sites to sync
|
|
5
5
|
$ sleekcms -e development # use a non-production backend
|
|
6
|
-
`).parse(process.argv),
|
|
7
|
-
`)){let
|
|
6
|
+
`).parse(process.argv),Ut.opts()}function $(t){let e=process.platform==="win32"?`where ${t}`:`which ${t}`;try{return Ht(e,{stdio:"ignore"}),!0}catch{return!1}}function Xt(t){if(process.platform!=="darwin")return!1;try{return Ht(`osascript -e 'id of application "${t}"'`,{stdio:"ignore"}),!0}catch{return!1}}function Ge(t,e){let r={detached:!0,stdio:"ignore",windowsHide:!0};process.platform==="win32"?B("cmd.exe",["/c",t,...e],r).unref():B(t,e,r).unref()}var Wt=[{name:"VS Code",cmd:"code",args:t=>["-n",t]},{name:"Cursor",cmd:"cursor",args:t=>["-n",t]}];function qt(t,e){let n=(e?Wt.filter(i=>i.cmd===e):Wt).find(i=>$(i.cmd));return n?(Ge(n.cmd,n.args(t)),n.name):null}function Ue(t){if(process.platform==="darwin")return B("open",["-a","Terminal",t],{detached:!0,stdio:"ignore"}).unref(),!0;if(process.platform==="win32"){if($("wt"))B("wt.exe",["-d",t],{detached:!0,stdio:"ignore"}).unref();else{let e=$("powershell")?"powershell.exe":"cmd.exe";B("cmd.exe",["/c","start","",e],{cwd:t,detached:!0,stdio:"ignore"}).unref()}return!0}return!1}function We(t){return Xt("iTerm")?(B("open",["-a","iTerm",t],{detached:!0,stdio:"ignore"}).unref(),!0):!1}function qe(t){return`'${t.replace(/'/g,"'\\''")}'`}var He=[{cmd:"x-terminal-emulator",args:t=>["-e","bash","-c",t]},{cmd:"gnome-terminal",args:t=>["--","bash","-c",t]},{cmd:"konsole",args:t=>["-e","bash","-c",t]},{cmd:"xfce4-terminal",args:t=>["-x","bash","-c",t]},{cmd:"kitty",args:t=>["bash","-c",t]},{cmd:"alacritty",args:t=>["-e","bash","-c",t]},{cmd:"xterm",args:t=>["-e","bash","-c",t]}];function Kt(t,e){if(!$(e))return!1;if(process.platform==="darwin"){let n=`tell application "Terminal" to do script ("cd " & quoted form of "${t}" & " && ${e}")`;return B("osascript",["-e",n,"-e",'tell application "Terminal" to activate'],{detached:!0,stdio:"ignore"}).unref(),!0}if(process.platform==="win32")return $("wt")?B("wt.exe",["-d",t,"cmd","/k",e],{detached:!0,stdio:"ignore"}).unref():B("cmd.exe",["/c","start","","cmd","/k",e],{cwd:t,detached:!0,stdio:"ignore"}).unref(),!0;let r=`cd ${qe(t)} && ${e}; exec bash`;for(let n of He)if($(n.cmd))try{return B(n.cmd,n.args(r),{cwd:t,detached:!0,stdio:"ignore"}).unref(),!0}catch{}return!1}function Je(t){return Kt(t,"claude")}function Xe(t){return Kt(t,"pi")}function zt(t){if(!t)return!1;try{return process.platform==="darwin"?B("open",[t],{detached:!0,stdio:"ignore"}).unref():process.platform==="win32"?B("cmd.exe",["/c","start","",t],{detached:!0,stdio:"ignore",windowsHide:!0}).unref():B("xdg-open",[t],{detached:!0,stdio:"ignore"}).unref(),!0}catch{return!1}}function Yt(){let t=process.platform==="darwin",e=process.platform==="win32",r=[];return(t||e)&&r.push({key:"terminal",label:"terminal",run:Ue}),Xt("iTerm")&&r.push({key:"iterm",label:"iterm",run:We}),$("code")&&r.push({key:"code",label:"vscode",run:n=>qt(n,"code")!==null}),$("cursor")&&r.push({key:"cursor",label:"cursor",run:n=>qt(n,"cursor")!==null}),$("claude")&&r.push({key:"claude",label:"claude",run:Je}),$("pi")&&r.push({key:"pi",label:"pi",run:Xe}),r}import{EventEmitter as yr}from"node:events";import{spawn as wr}from"node:child_process";import Y from"fs-extra";import Pt from"path";import br from"chokidar";import f from"fs-extra";import ze from"os";import S from"path";var Vt={localhost:"http://app.sleekcms.test/api/mcp",development:"https://app.sleekcms.dev/api/mcp",production:"https://app.sleekcms.com/api/mcp"},Ye=["src/views/blocks","src/views/entries","src/views/pages","src/views/layouts","src/models/blocks","src/models/entries","src/models/pages","src/content/pages","src/content/entries","src/public/js","src/public/css"],wt=class extends Error{status;body;constructor(e,r,n){super(e),this.status=r,this.body=n}};async function xt(t,e,r,n,i){let o=await fetch(t+n,{method:r,headers:{Authorization:`Bearer ${e}`,...i!==void 0?{"Content-Type":"application/json"}:{}},body:i!==void 0?JSON.stringify(i):void 0});if(!o.ok){let c=await o.text();throw new wt(`${r} ${n} \u2192 ${o.status}: ${c}`,o.status,c)}return o.json()}async function Ve(t,e){e&&(await f.outputFile(S.join(t,"AGENT.md"),e),await f.outputFile(S.join(t,"CLAUDE.md"),e),await f.outputFile(S.join(t,".vscode","copilot-instructions.md"),e)),await f.outputFile(S.join(t,".vscode","settings.json"),JSON.stringify({"files.associations":{"*.model":"javascript"},"[javascript]":{"editor.defaultFormatter":"esbenp.prettier-vscode"},"js/ts.validate.enabled":!1},null,2))}async function Qe(t,e){if(!e)return;let r=S.join(t,"build.mjs"),n=e.match(/build\.mjs v\d+/)?.[0];if(await f.pathExists(r)){let i=(await f.readFile(r,"utf-8")).match(/build\.mjs v\d+/)?.[0];if(i&&i===n)return}await f.outputFile(r,e)}async function Ze(t,e,r){let n=S.join(t,".cache","token");if(await f.pathExists(n)){if((await f.readFile(n,"utf-8")).trim()===e)return;r?.("\u267B\uFE0F Workspace was tied to a different site \u2014 recreating it."),await f.emptyDir(t)}await f.outputFile(n,e)}function tr(t,e){let r=`${e.name.substr(0,20)} ${e.id}`.replace(/[\s_]+/g,"-").toLowerCase(),n=t||S.join(ze.homedir(),"SleekCMS");return S.resolve(n,r)}async function St(t){let e=(t.token||"").trim();if(!e)throw new Error("syncSite: token is required");let r=t.log??(v=>console.log(v)),n=t.onProgress,i=(t.env||e.split("-")[2]||"production").toLowerCase(),o=Vt[i]||Vt.production,c=await xt(o,e,"GET","/get_site"),h=t.viewsDir?S.resolve(t.viewsDir):tr(t.path,c);await f.ensureDir(h),await Ze(h,e,r),await Promise.all(Ye.map(v=>f.ensureDir(S.join(h,v)))),await Qe(h,t.buildScript);let p=S.join(h,".cache","state.json");t.flush&&await f.remove(p);let x=!await f.pathExists(p),y=x?{}:(await f.readJson(p)).fileMap||{},m=0,w=0;return x?({fileMap:y,pulled:w}=await lr(h,o,e,r,n),await Ve(h,t.agentMd)):m=await nr(h,y,o,e,r,n),await f.outputJson(p,{fileMap:y},{spaces:2}),{viewsDir:h,site:c,isFirstRun:x,pushed:m,pulled:w}}var er=new Set([".DS_Store","Thumbs.db","desktop.ini"]);async function rr(t){let e=S.join(t,"src");if(!await f.pathExists(e))return[];let r=[];async function n(i){let o=await f.readdir(i,{withFileTypes:!0});for(let c of o){if(er.has(c.name))continue;let h=S.join(i,c.name);c.isDirectory()?await n(h):c.isFile()&&r.push(S.relative(t,h).replace(/\\/g,"/"))}}return await n(e),r}async function nr(t,e,r,n,i,o){let c=[];for(let m of await rr(t)){let w=S.join(t,m),v=e[m],M=await f.stat(w);if(v&&v.mtimeMs===M.mtimeMs)continue;let R=await f.readFile(w,"utf-8");R.trim()&&c.push({rel:m,full:w,stat:M,content:R,prior:v})}if(c.length===0)return 0;let h;try{h=await xt(r,n,"POST","/save_files",c.map(m=>({path:m.rel,content:m.content})))}catch(m){let w=m;return i(`\u274C Error saving files: ${w.body||w.message}`),0}let p=await or(t),x=0,y=ir(h);for(let m=0;m<c.length;m++){let w=c[m],v=sr(w,m,h,y);if(o?.(m+1,c.length),!v){let M="No save response returned";p[w.rel]=M,i(`\u274C Error saving ${w.rel}: ${M}`);continue}if(v.error){p[w.rel]=v.error,i(`\u274C Error saving ${w.rel}: ${v.error}`);continue}delete p[w.rel],e[w.rel]={mtimeMs:w.stat.mtimeMs},i(`\u2705 ${w.prior?"Updated":"Created"} ${w.rel}`),x++}return await cr(t,p),x}function ir(t){let e=new Map;for(let r of t)r.path&&e.set(r.path,r);return e}function sr(t,e,r,n){let i=n.get(t.rel);if(i)return i;let o=r[e];if(!o?.path||o.path===t.rel)return o}var vt="sync-errors.log",bt=new Map;async function or(t){let e=S.resolve(t),r=bt.get(e);if(r)return r;let n=await ar(e);return bt.set(e,n),n}async function ar(t){let e=S.join(t,vt);if(!await f.pathExists(e))return{};let r=await f.readFile(e,"utf-8"),n={};for(let i of r.split(`
|
|
7
|
+
`)){let o=i.indexOf(": ");o>0&&(n[i.slice(0,o)]=i.slice(o+2))}return n}async function cr(t,e){let r=S.join(t,vt),n=Object.entries(e);if(n.length===0){await f.remove(r);return}await f.outputFile(r,n.map(([i,o])=>`${i}: ${o}`).join(`
|
|
8
8
|
`)+`
|
|
9
|
-
`)}async function Ve(t,e,r,n,i){wt.delete(v.resolve(t)),await f.remove(v.join(t,vt)),n("\u{1F4E5} Fetching files...");let s=await bt(e,r,"GET","/get_files"),c={},d=0;for(let h of s){let S=v.join(t,h.path);await f.outputFile(S,h.content);let y=(await f.stat(S)).mtimeMs;d++,i?.(d,s.length),c[h.path]={mtimeMs:y}}return n(`\u2714\uFE0F Synced ${s.length} file(s).`),{fileMap:c,pulled:d}}import Ye from"path";import Qe from"chokidar";var Ze=5e3,tr=/(^|[/\\])(\.DS_Store|Thumbs\.db|desktop\.ini)$/,z=class{viewsDir;onSync;debounceMs;watcher=null;debounceTimer=null;isShuttingDown=!1;dirty=!1;syncInFlight=!1;constructor(e){this.viewsDir=e.viewsDir,this.onSync=e.onSync,this.debounceMs=e.debounceMs??Ze}start(){if(this.watcher)return;let e=Ye.join(this.viewsDir,"src");this.watcher=Qe.watch([e],{persistent:!0,ignoreInitial:!0,ignored:tr}).on("change",()=>this.scheduleSync()).on("add",()=>this.scheduleSync()).on("unlink",()=>this.scheduleSync())}setShuttingDown(e){this.isShuttingDown=e}async stop(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.watcher&&(await this.watcher.close(),this.watcher=null)}scheduleSync(){this.isShuttingDown||(this.dirty=!0,this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>this.flush(),this.debounceMs))}async flush(){if(this.debounceTimer=null,!(!this.dirty||this.isShuttingDown)){if(this.syncInFlight){this.debounceTimer=setTimeout(()=>this.flush(),this.debounceMs);return}this.dirty=!1,this.syncInFlight=!0;try{await this.onSync()}catch(e){let r=e;console.error("\u274C Sync failed:",r.body||r.message)}finally{this.syncInFlight=!1}}}};import it from"fs-extra";import er from"os";import zt from"path";var Xt={localhost:"http://app.sleekcms.test/api",development:"https://app.sleekcms.dev/api",production:"https://app.sleekcms.com/api"};function Tt(t){return Xt[t]||Xt.production}var rr=zt.join(er.homedir(),"SleekCMS"),st=zt.join(rr,"auth.json"),xt;function Kt(t){xt=t||void 0}function kt(t){let e=[];return t&&e.push(`_auth=${t}`),xt&&e.push(`_dev=${xt}`),e.length?e.join("; "):void 0}var O=class extends Error{status;body;constructor(e,r,n=""){super(e),this.name="UserAuthError",this.status=r,this.body=n}};async function Vt(){try{let t=await it.readJson(st);return t&&t.userToken?t:null}catch{return null}}async function Yt(t){await it.outputJson(st,t,{spaces:2});try{await it.chmod(st,384)}catch{}}async function Qt(){await it.remove(st)}async function G(t){let e={},r=kt(t.userToken);r&&(e.Cookie=r),t.subdomain&&(e["x-subdomain"]=t.subdomain),t.slug&&(e.site=t.slug),t.body!==void 0&&(e["Content-Type"]="application/json");let n=await fetch(Tt(t.env)+t.path,{method:t.method,headers:e,body:t.body!==void 0?JSON.stringify(t.body):void 0});if(!n.ok){let i=await n.text().catch(()=>"");throw new O(`${t.method} ${t.path} \u2192 ${n.status}: ${i}`,n.status,i)}return n.json()}async function Zt(t,e){let r={"Content-Type":"application/json"},n=kt();n&&(r.Cookie=n);let i=await fetch(Tt(t)+"/auth/otp",{method:"PUT",headers:r,body:JSON.stringify({email:e})});if(!i.ok){let c=await i.text().catch(()=>"");throw new O(`Failed to send OTP \u2192 ${i.status}: ${c}`,i.status,c)}return{otp:(await i.json().catch(()=>({}))).do_not_use_in_code}}async function Ct(t,e,r){let n={"Content-Type":"application/json"},i=kt();i&&(n.Cookie=i);let s=await fetch(Tt(t)+"/auth/login",{method:"POST",headers:n,body:JSON.stringify({email:e,otp:r})});if(!s.ok){let h=await s.text().catch(()=>"");throw new O(`Login failed \u2192 ${s.status}: ${h}`,s.status,h)}let c=s.headers.getSetCookie?.()??[],d=nr(c);if(!d)throw new O("Login succeeded but no _auth cookie was returned.",500);return d}function nr(t){for(let e of t){let r=e.match(/(?:^|;\s*)_auth=([^;]+)/);if(r&&r[1])return decodeURIComponent(r[1])}return null}async function Et(t,e){return G({env:t,userToken:e,method:"GET",path:"/org"})}async function te(t,e,r){return G({env:t,userToken:e,method:"GET",path:"/site",subdomain:r})}async function ee(t,e,r,n){let i;try{i=await G({env:t,userToken:e,method:"GET",path:"/site_build",subdomain:r,slug:n})}catch{return null}if(!Array.isArray(i)||i.length===0)return null;let s=i[0],c=i.find(h=>typeof h.url=="string"&&h.url.length>0),d=Array.isArray(s.errors)?s.errors.map(h=>String(h)):[];return d.length>0?{status:"error",mode:"preview",errors:d,url:c?.url||void 0,at:s.updated_at?Date.parse(s.updated_at):void 0}:c?{status:"success",mode:"preview",url:c.url||void 0,at:c.updated_at?Date.parse(c.updated_at):void 0}:null}async function re(t,e,r,n){let{token:i}=await G({env:t,userToken:e,method:"POST",path:"/site_user/api_token",subdomain:r,slug:n,body:{refresh:!1}});return i}async function ne(t,e,r){let n=await G({env:t,userToken:e,method:"POST",path:"/org",body:r?{name:r}:{}});return{id:n.id,name:n.name,subdomain:n.subdomain}}async function ie(t,e,r,n){let i=await G({env:t,userToken:e,method:"POST",path:"/site",subdomain:r,body:{name:n}});return{id:i.id,name:i.name,slug:i.slug}}var se=500;function ar(){return new Date().toTimeString().slice(0,8)}function ot(t){let e=t;if(e.body){try{let r=JSON.parse(e.body);if(r&&typeof r.message=="string")return r.message;if(r&&typeof r.error=="string")return r.error}catch{}return e.body}return e.message}async function oe(t){t&&(await K.remove(Bt.join(t,"src")),await K.remove(Bt.join(t,".cache","state.json")))}var at=class extends ir{env="production";userToken="";email;catalog=[];synced=new Map;message;messageIsError=!1;agentMd;buildScript;isShuttingDown=!1;constructor(e,r){super(),this.agentMd=e,this.buildScript=r}changed(){this.emit("change")}flash(e,r=!1){this.message=e,this.messageIsError=r,this.changed()}appendLog(e,r){let n=this.synced.get(e);n&&(n.logs.push({time:ar(),text:r}),n.logs.length>se&&n.logs.splice(0,n.logs.length-se),this.changed())}siteCount(){return this.synced.size}syncingCount(){let e=0;for(let r of this.synced.values())r.status==="syncing"&&e++;return e}watchingCount(){let e=0;for(let r of this.synced.values())(r.status==="watching"||r.status==="syncing")&&e++;return e}async init(e,r,n){this.env=e,this.userToken=r,n&&(this.email=n);let i=await Et(e,r);await this.buildCatalog(i)}async buildCatalog(e){let r=[];for(let n of e)try{r.push({org:n,sites:await te(this.env,this.userToken,n.subdomain)})}catch(i){if(i instanceof O&&i.status===401)throw i;r.push({org:n,sites:[]})}this.catalog=r,this.changed()}isSynced(e){return this.synced.has(e)}availableSites(){let e=[];for(let r of this.catalog)for(let n of r.sites)this.synced.has(n.id)||e.push({org:r.org,site:n});return e}async addSite(e,r){if(this.synced.has(r.id))return;let n;try{n=await re(this.env,this.userToken,e.subdomain,r.slug)}catch(s){this.flash(`Failed to authorize "${r.name}": ${ot(s)}`,!0);return}let i={org:e,site:r,siteToken:n,viewsDir:"",status:"syncing",logs:[]};this.synced.set(r.id,i),this.appendLog(r.id,"\u2795 added \u2014 pulling files"),this.changed();try{let s=await St({token:n,env:this.env,agentMd:this.agentMd,buildScript:this.buildScript,log:c=>this.appendLog(r.id,c),onProgress:(c,d)=>{i.progress={done:c,total:d},this.changed()}});i.viewsDir=s.viewsDir,i.progress=void 0,i.status="watching",i.lastSyncedAt=Date.now(),i.lastMsg=`pulled ${s.pulled} file(s)`,i.watcher=new z({viewsDir:s.viewsDir,onSync:()=>this.runSync(r.id)}),i.watcher.start(),this.watchBuildStatus(r.id),this.seedLastBuild(r.id),this.appendLog(r.id,"\u{1F440} watching for changes")}catch(s){let c=s;i.status="error",i.progress=void 0,i.lastMsg=c.body||c.message,this.appendLog(r.id,`\u274C ${c.body||c.message}`)}this.changed()}async removeSite(e){let r=this.synced.get(e);r&&(r.watcher?.setShuttingDown(!0),await r.watcher?.stop(),await r.buildWatcher?.close(),await oe(r.viewsDir),this.synced.delete(e),this.changed())}buildSite(e,r=!1){let n=this.synced.get(e);if(!n||!n.viewsDir)return;let i=r?"live":"preview";this.writeBuildFile(n.viewsDir,{status:"building",mode:i,stage:"queued",url:n.lastBuild?.url,at:Date.now()}),sr("node",r?["build.mjs","--deploy"]:["build.mjs"],{cwd:n.viewsDir,stdio:"ignore"}).on("error",d=>{this.writeBuildFile(n.viewsDir,{status:"error",mode:i,errors:[d.message],url:n.lastBuild?.url,at:Date.now()}),this.appendLog(e,`\u274C build: ${d.message}`)}),this.appendLog(e,r?"\u{1F680} deploying\u2026":"\u{1F528} building\u2026")}buildFile(e){return Bt.join(e,".cache","build.json")}async readBuildFile(e){try{let r=await K.readJson(this.buildFile(e));return r&&r.status?r:null}catch{return null}}async writeBuildFile(e,r){let n=this.buildFile(e),i=`${n}.tmp`;try{await K.outputJson(i,r),await K.rename(i,n)}catch{}}watchBuildStatus(e){let r=this.synced.get(e);!r||!r.viewsDir||(r.buildWatcher=or.watch(this.buildFile(r.viewsDir),{ignoreInitial:!1}).on("add",()=>{this.readBuildStatus(e)}).on("change",()=>{this.readBuildStatus(e)}))}async readBuildStatus(e){let r=this.synced.get(e);if(!r)return;let n=await this.readBuildFile(r.viewsDir);if(!n)return;let i=r.lastBuild?.url;r.lastBuild={status:n.status,mode:n.mode??"preview",url:n.url??(n.status==="success"?void 0:i),errors:n.errors,stage:n.stage,at:n.at},this.changed()}async seedLastBuild(e){let r=this.synced.get(e);if(!r)return;let n=await ee(this.env,this.userToken,r.org.subdomain,r.site.slug);if(!n)return;let i=this.synced.get(e);if(!i)return;let s=await this.readBuildFile(i.viewsDir);s?.at!=null&&(n.at==null||s.at>=n.at)||await this.writeBuildFile(i.viewsDir,n)}async ensureOrg(e){if(e)return e;if(this.catalog[0])return this.catalog[0].org;let r;try{r=await Et(this.env,this.userToken)}catch(n){return this.flash(`Couldn't check your organizations: ${ot(n)}`,!0),null}if(r.length>0){try{await this.buildCatalog(r)}catch{}return r[0]}try{let n=this.email?`${this.email.split("@")[0]}'s Sites`:"My Sites";this.flash("No organization yet \u2014 creating one\u2026");let i=await ne(this.env,this.userToken,n);return this.catalog=[...this.catalog,{org:i,sites:[]}],this.changed(),i}catch(n){return this.flash(`Could not create an organization: ${ot(n)}`,!0),null}}async createNewSite(e,r){let n=await this.ensureOrg(r);if(!n)return;let i;try{i=await ie(this.env,this.userToken,n.subdomain,e)}catch(c){this.flash(`Could not create "${e}": ${ot(c)}`,!0);return}let s=this.catalog.find(c=>c.org.id===n.id);s&&!s.sites.some(c=>c.id===i.id)&&(s.sites=[...s.sites,i]),this.flash(`Created "${i.name}".`),await this.addSite(n,i)}async refetch(e){await this.runSync(e,{flush:!0})}async runSync(e,r={}){let n=this.synced.get(e);if(!(!n||!n.viewsDir||n.status==="paused")){n.status="syncing",this.changed();try{let i=await St({token:n.siteToken,env:this.env,viewsDir:n.viewsDir,agentMd:this.agentMd,buildScript:this.buildScript,flush:r.flush,log:s=>this.appendLog(e,s),onProgress:(s,c)=>{n.progress={done:s,total:c},this.changed()}});n.progress=void 0,n.status="watching",n.lastSyncedAt=Date.now(),r.flush?n.lastMsg=`re-fetched ${i.pulled} file(s)`:n.lastMsg=i.pushed>0?`pushed ${i.pushed} file(s)`:"up to date"}catch(i){let s=i;n.status="error",n.progress=void 0,n.lastMsg=s.body||s.message,this.appendLog(e,`\u274C ${s.body||s.message}`)}this.changed()}}async togglePause(e){let r=this.synced.get(e);!r||!r.viewsDir||(r.status==="paused"?(r.watcher=new z({viewsDir:r.viewsDir,onSync:()=>this.runSync(e)}),r.watcher.start(),r.status="watching",this.appendLog(e,"\u25B6 resumed \u2014 watching for changes")):(r.watcher?.setShuttingDown(!0),await r.watcher?.stop(),r.watcher=void 0,r.progress=void 0,r.status="paused",this.appendLog(e,"\u23F8 paused")),this.changed())}async cleanupAll(){for(let e of this.synced.values())e.watcher?.setShuttingDown(!0),await e.watcher?.stop(),await e.buildWatcher?.close(),await oe(e.viewsDir)}async exit(){this.isShuttingDown||(this.isShuttingDown=!0,await this.cleanupAll(),this.emit("exit"))}async logout(){this.isShuttingDown||(this.isShuttingDown=!0,await Qt(),await this.cleanupAll(),this.emit("logout"))}};import{useEffect as wr,useState as pe}from"react";import{Box as br,Text as Sr,useInput as vr}from"ink";import{useState as V}from"react";import{Box as Y,Text as U}from"ink";import ae from"ink-text-input";import{jsx as I,jsxs as q}from"react/jsx-runtime";function ce(t){let e=t;return e?.body||e?.message||String(t)}function ue({env:t,initialError:e,onAuthed:r}){let[n,i]=V("email"),[s,c]=V(""),[d,h]=V(""),[S,y]=V(e),[m,w]=V(),x=async L=>{let T=L.trim();if(T){y(void 0),i("busy");try{let{otp:C}=await Zt(t,T);if(c(T),C){let J=await Ct(t,T,C);await r(J,T);return}w(`OTP sent to ${T}`),i("otp")}catch(C){y(ce(C)),i("email")}}},P=async L=>{let T=L.trim();if(T){y(void 0),i("busy");try{let C=await Ct(t,s,T);await r(C,s)}catch(C){y(ce(C)),h(""),i("otp")}}};return q(Y,{flexDirection:"column",children:[q(U,{bold:!0,children:["\u25C6 SleekCMS \u2014 sign in",t!=="production"?` (${t})`:""]}),S?q(U,{color:"red",children:["\u2717 ",S]}):null,n==="email"&&q(Y,{marginTop:1,children:[I(U,{children:"Email: "}),I(ae,{value:s,onChange:c,onSubmit:x,placeholder:"you@example.com"})]}),n==="otp"&&q(Y,{flexDirection:"column",marginTop:1,children:[m?I(U,{color:"green",children:m}):null,q(Y,{children:[I(U,{children:"Enter OTP: "}),I(ae,{value:d,onChange:h,onSubmit:P})]})]}),n==="busy"&&I(Y,{marginTop:1,children:I(U,{children:"Working\u2026"})})]})}import{Fragment as ur,useEffect as dt,useMemo as lr,useState as M}from"react";import{Box as p,Text as u,useInput as dr,useStdout as gr}from"ink";import ge from"ink-text-input";import cr from"node:os";function Pt(t){if(!t)return"\u2014";let e=cr.homedir();return t.startsWith(e)?"~"+t.slice(e.length):t}function Dt(t){if(!t)return"\u2014";let e=Math.floor((Date.now()-t)/1e3);if(e<5)return"just now";if(e<60)return`${e}s ago`;let r=Math.floor(e/60);if(r<60)return`${r}m ago`;let n=Math.floor(r/60);return n<24?`${n}h ago`:`${Math.floor(n/24)}d ago`}function ut(t){return!t||t.total<=0?null:Math.round(t.done/t.total*100)}var ct=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];function le(t){return ct[(t%ct.length+ct.length)%ct.length]}function lt(t){switch(t){case"syncing":return{dot:"\u25CF",color:"green",label:"syncing"};case"watching":return{dot:"\u25CB",color:"gray",label:"watching"};case"paused":return{dot:"\u2016",color:"yellow",label:"paused"};case"error":return{dot:"\u2717",color:"red",label:"error"}}}function de(t){if(!t)return{dot:"\xB7",color:"gray",label:"\u2014"};switch(t.status){case"building":return{dot:"\u2234",color:"yellow",label:"building"};case"error":return{dot:"\u2717",color:"red",label:"failed"};case"success":return{dot:"\u2713",color:"green",label:t.mode==="live"?"live":"preview"}}}import{Fragment as Q,jsx as o,jsxs as l}from"react/jsx-runtime";var _=(t,e)=>e<=0?0:Math.max(0,Math.min(t,e-1)),hr=16,pr=5;function mr({k:t}){return o(u,{color:"black",backgroundColor:"green",children:` ${t} `})}function $({k:t,label:e,width:r=16}){return l(p,{width:r,children:[o(mr,{k:t}),o(u,{color:"gray",children:` ${e}`})]})}function fr({percent:t,width:e=28}){let r=Math.round(Math.max(0,Math.min(100,t))/100*e);return l(u,{children:[o(u,{color:"green",children:"\u2588".repeat(r)}),o(u,{color:"gray",children:"\u2591".repeat(Math.max(0,e-r))})]})}function yr({frame:t,width:e=24,seg:r=6}){let n=e+r,i=t%n-r,s="";for(let c=0;c<e;c++)s+=c>=i&&c<i+r?"\u25AE":"\u25AF";return o(u,{color:"yellow",children:s})}function he({controller:t}){let{stdout:e}=gr(),r=lr(()=>Jt(),[]),[,n]=M(0),[i,s]=M(()=>new Date),[c,d]=M(null),[h,S]=M(()=>t.synced.size>0||t.catalog.some(g=>g.sites.length>0)?"dashboard":t.catalog.length<=1?"newName":"newOrg"),[y,m]=M(0),[w,x]=M(""),[P,L]=M(!1),[T,C]=M(""),[J,Z]=M(!1),[$t,be]=M(0),Lt=()=>n(a=>a+1);dt(()=>(t.on("change",Lt),()=>{t.off("change",Lt)}),[t]),dt(()=>{let a=setInterval(()=>s(new Date),1e3);return()=>clearInterval(a)},[]);let F=t.catalog.flatMap(a=>a.sites.map(g=>({org:a.org,site:g,entry:t.synced.get(g.id)}))).sort((a,g)=>(a.entry?0:1)-(g.entry?0:1)),A=T.trim().toLowerCase(),E=A?F.filter(a=>a.site.name.toLowerCase().includes(A)||(a.org.name||a.org.subdomain||"").toLowerCase().includes(A)):F,N=E.findIndex(a=>a.site.id===c);N<0&&(N=0);let k=E[N],b=k?.entry,R=b?.lastBuild,ht=R?.status==="building",pt=de(R),tt=ht;if(!tt){for(let a of t.synced.values())if(a.status==="watching"||a.status==="syncing"){tt=!0;break}}dt(()=>{if(!tt)return;let a=setInterval(()=>be(g=>g+1),120);return()=>clearInterval(a)},[tt]);let Rt=E.findIndex(a=>!a.entry),W=Math.max(pr,(e?.rows??30)-hr),H=E.length,et=H>W,Se=Math.floor(W/2),X=et?Math.max(0,Math.min(N-Se,H-W)):0,mt=Math.min(H,X+W),ve=E.slice(X,mt);dt(()=>{h!=="dashboard"||P||F.length>0||(x(""),t.catalog.length<=1?S("newName"):(m(0),S("newOrg")))},[F.length,h,P,t.catalog.length]);let rt=a=>{if(E.length===0)return;let g=_(N+a,E.length);d(E[g].site.id)},xe=()=>{k&&(k.entry?t.removeSite(k.site.id):t.addSite(k.org,k.site))},Te=()=>{x(""),t.catalog.length<=1?S("newName"):(m(0),S("newOrg"))},ke=a=>{if(!b){t.flash("Press \u23CE to start syncing this site first.",!0);return}let g=a.run(b.viewsDir);t.flash(g?`Opened ${a.label} at ${Pt(b.viewsDir)}`:`Couldn't open ${a.label}.`,!g)},Ce=()=>{if(!b){t.flash("Press \u23CE to start syncing this site first.",!0);return}t.togglePause(b.site.id)},Ft=a=>{if(!b){t.flash("Press \u23CE to start syncing this site first.",!0);return}t.buildSite(b.site.id,a),t.flash(a?"Deploying \u2014 building live\u2026":"Building preview\u2026")},Ee=()=>{let a=b?.lastBuild?.url;if(!a){t.flash("No build URL yet \u2014 press b to build.",!0);return}t.flash(qt(a)?`Opening ${a}`:"Couldn't open the browser.",!1)};dr((a,g)=>{if(h==="newOrg"){g.escape?S("dashboard"):g.upArrow?m(B=>_(B-1,t.catalog.length)):g.downArrow?m(B=>_(B+1,t.catalog.length)):g.return&&S("newName");return}if(J){g.escape?(Z(!1),C(""),d(null)):g.return?Z(!1):g.upArrow?rt(-1):g.downArrow&&rt(1);return}if(g.escape){C(""),d(null);return}if(a==="/")return void Z(!0);if(a==="n")return void Te();if(a==="q")return void t.logout();if(g.upArrow)return rt(-1);if(g.downArrow)return rt(1);if(g.return||a===" ")return xe();if(a==="p")return Ce();if(a==="b")return Ft(!1);if(a==="B")return Ft(!0);if(a==="o")return Ee();if(a>="1"&&a<="9"){let B=r[parseInt(a,10)-1];if(B)return ke(B)}},{isActive:h!=="newName"});let Be=async a=>{let g=a.trim();if(!g){S("dashboard");return}let B=t.catalog[_(y,t.catalog.length)]?.org??t.catalog[0]?.org;L(!0),S("dashboard"),await t.createNewSite(g,B),L(!1)},Pe=Math.max(5,(e?.rows??30)-18);return l(p,{flexDirection:"column",children:[l(p,{justifyContent:"space-between",paddingX:1,children:[l(p,{children:[o(u,{color:"green",bold:!0,children:"\u25C6 SleekCMS"}),o(u,{color:"gray",children:" \u2502 "}),o(u,{children:t.email??"signed in"})]}),l(p,{children:[l(u,{color:"gray",children:[A?`${E.length}/${F.length}`:F.length," sites \xB7 "]}),l(u,{color:"green",children:[t.watchingCount()," watching"]}),o(u,{color:"gray",children:` \xB7 ${i.toTimeString().slice(0,8)}`})]})]}),l(p,{children:[l(p,{flexDirection:"column",borderStyle:"round",borderColor:"green",width:38,paddingX:1,children:[l(p,{justifyContent:"space-between",children:[o(u,{color:"green",bold:!0,children:"SITE WORKSPACES"}),F.length>W&&!J&&!A?o(u,{color:"gray",children:"/ filter"}):null]}),J?l(p,{children:[o(u,{color:"cyan",children:"/ "}),o(ge,{value:T,onChange:C,onSubmit:()=>Z(!1),placeholder:"type to filter\u2026"})]}):A?o(u,{color:"gray",children:`/ ${T} \xB7 ${E.length} match${E.length===1?"":"es"}`}):null,o(p,{flexDirection:"column",marginTop:1,minHeight:et?W+3:void 0,children:E.length===0?o(u,{color:"gray",children:A?`no matches for \u201C${T}\u201D`:"no sites \u2014 press n to create one"}):l(Q,{children:[et?o(u,{color:"gray",children:X>0?` \u2191 ${X} more`:" "}):null,ve.map((a,g)=>{let B=X+g,At=a.entry?lt(a.entry.status):{dot:"\xB7",color:"gray",label:"idle"},jt=ut(a.entry?.progress),De=a.entry?a.entry.status==="syncing"&&jt!=null?`${jt}%`:a.entry.status==="paused"?"paused":"--":"",nt=B===N,Oe=B===Rt&&Rt>0;return l(ur,{children:[Oe?o(u,{color:"gray",children:"\u2500".repeat(34)}):null,l(p,{justifyContent:"space-between",children:[l(p,{children:[o(u,{color:nt?"green":"gray",children:nt?"\u276F ":" "}),l(u,{color:a.entry?.status==="watching"?"green":At.color,children:[a.entry?.status==="watching"?le($t):At.dot," "]}),o(u,{color:nt?"white":a.entry?void 0:"gray",bold:nt,children:a.site.name})]}),o(u,{color:a.entry?.status==="syncing"?"green":"gray",children:De})]})]},a.site.id)}),et?o(u,{color:"gray",children:mt<H?` \u2193 ${H-mt} more`:" "}):null]})}),o(p,{marginTop:1,children:o(u,{color:"gray",children:"+ new site \xB7 n"})})]}),l(p,{flexDirection:"column",flexGrow:1,marginLeft:1,children:[o(p,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:1,children:k?l(Q,{children:[l(u,{children:[k.org.name||k.org.subdomain?l(u,{color:"gray",children:[k.org.name||k.org.subdomain," / "]}):null,o(u,{color:"cyan",bold:!0,children:k.site.name})]}),l(p,{marginTop:1,children:[o(u,{color:"gray",children:"status "}),b?o(u,{color:lt(b.status).color,children:`: ${lt(b.status).label}`}):o(u,{color:"gray",children:": idle \u2014 not syncing (press \u23CE to start)"})]}),l(p,{children:[o(u,{color:"gray",children:"path "}),o(u,{children:b?.viewsDir?Pt(b.viewsDir):"\u2014"})]}),l(p,{children:[o(u,{color:"gray",children:"synced "}),o(u,{children:Dt(b?.lastSyncedAt)}),o(u,{color:"gray",children:" progress "}),o(u,{color:b?.status==="syncing"?"green":"gray",children:b?.status==="syncing"?`${ut(b.progress)??0}%`:"\u2014"})]}),o(p,{marginTop:1,children:o(fr,{percent:b?b.status==="syncing"?ut(b.progress)??0:b.status==="watching"?100:0:0})}),b?l(Q,{children:[l(p,{marginTop:1,children:[o(u,{color:"gray",children:"build "}),o(u,{color:pt.color,children:`${pt.dot} ${pt.label}`}),o(u,{color:"gray",children:" last "}),o(u,{children:ht?"in progress":Dt(R?.at)})]}),l(p,{children:[o(u,{color:"gray",children:"url "}),R?.url?o(u,{color:"cyan",children:R.url}):o(u,{color:"gray",children:"\u2014"})]}),R?.status==="error"&&R.errors?.length?l(p,{children:[o(u,{color:"red",children:"\u258C "}),o(u,{color:"red",children:`\u2717 ${R.errors[0]}`})]}):null,ht?l(p,{children:[o(yr,{frame:$t}),o(u,{color:"gray",children:` ${R?.stage??"building"}`})]}):null]}):null]}):o(u,{color:"gray",children:"No site selected."})}),h==="dashboard"?l(p,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:1,marginTop:1,flexGrow:1,children:[l(u,{children:[o(u,{color:"cyan",bold:!0,children:"LOGS \xB7 "}),o(u,{color:"white",children:k?.site.name??"\u2014"})]}),o(p,{flexDirection:"column",marginTop:1,children:!b||b.logs.length===0?o(u,{color:"gray",children:"no activity yet"}):b.logs.slice(-Pe).map((a,g)=>l(p,{children:[l(u,{color:"gray",children:[a.time," "]}),o(u,{children:a.text})]},g))})]}):l(p,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginTop:1,flexGrow:1,children:[h==="newOrg"&&l(Q,{children:[o(u,{color:"cyan",bold:!0,children:"CREATE SITE \u2014 PICK ORG"}),o(u,{color:"gray",children:"\u2191/\u2193 select \xB7 \u23CE next \xB7 esc cancel"}),o(p,{flexDirection:"column",marginTop:1,children:t.catalog.map((a,g)=>l(u,{color:g===_(y,t.catalog.length)?"blue":void 0,bold:g===_(y,t.catalog.length),children:[g===_(y,t.catalog.length)?"\u276F ":" ",a.org.name||a.org.subdomain]},a.org.id))})]}),h==="newName"&&l(Q,{children:[o(u,{color:"cyan",bold:!0,children:"CREATE SITE"}),l(p,{marginTop:1,children:[o(u,{children:"New site name: "}),o(ge,{value:w,onChange:x,onSubmit:Be})]}),o(u,{color:"gray",children:"\u23CE create \xB7 empty + \u23CE to cancel"})]})]})]})]}),t.message?o(p,{paddingX:1,children:l(u,{color:t.messageIsError?"red":"gray",children:[t.messageIsError?"\u2717 ":"",t.message]})}):null,l(p,{flexDirection:"column",marginTop:1,children:[l(p,{paddingX:1,flexWrap:"wrap",children:[o($,{k:"\u2191\u2193",label:"select"}),o($,{k:"/",label:"search"}),o($,{k:"\u23CE",label:"start/stop"}),o($,{k:"p",label:"pause"}),o($,{k:"b",label:"build"}),o($,{k:"o",label:"open url"}),o($,{k:"n",label:"new site"}),o($,{k:"q",label:"logout"}),o($,{k:"ctrl+c",label:"quit",width:14})]}),r.length>0?o(p,{paddingX:1,marginTop:1,flexWrap:"wrap",children:r.map((a,g)=>o($,{k:String(g+1),label:a.label},a.key))}):null]})]})}import{jsx as gt}from"react/jsx-runtime";function me(t){let e=t;return e?.body||e?.message||String(t)}function fe({controller:t,env:e,devSecret:r,savedToken:n,savedEmail:i}){let[s,c]=pe(n?"loading":"auth"),[d,h]=pe();vr((y,m)=>{m.ctrl&&y==="c"&&t.exit()}),wr(()=>{n&&t.init(e,n,i).then(()=>c("manage")).catch(y=>{y instanceof O&&y.status===401?h("Saved session expired \u2014 please sign in again."):h(me(y)),c("auth")})},[]);let S=async(y,m)=>{h(void 0),await Yt({env:e,userToken:y,devSecret:r,email:m}),c("loading");try{await t.init(e,y,m),c("manage")}catch(w){h(me(w)),c("auth")}};return s==="auth"?gt(ue,{env:e,initialError:d,onAuthed:S}):s==="loading"?gt(br,{children:gt(Sr,{children:"Loading your sites\u2026 "})}):gt(he,{controller:t})}import{jsx as Dr}from"react/jsx-runtime";var Cr=Tr(import.meta.url),Ot=Gt();if(Ot.version){let t=Cr("../package.json");console.log(t.version),process.exit(0)}var we=Mt.dirname(xr(import.meta.url)),Er=ye(Mt.join(we,"AGENT.md"),"utf-8"),Br=ye(Mt.join(we,"build.mjs"),"utf-8");async function Pr(){let t=new at(Er,Br),e=await Vt(),r=(Ot.env??e?.env??"production").toLowerCase(),n=Ot.dev??process.env.SLEEKCMS_DEV_SECRET??e?.devSecret;Kt(n),process.stdout.isTTY&&process.stdout.write("\x1B[2J\x1B[3J\x1B[H");let i=kr(Dr(fe,{controller:t,env:r,devSecret:n,savedToken:e?.userToken,savedEmail:e?.email}),{exitOnCtrlC:!1}),s=c=>{i.unmount(),console.log(c),process.exit(0)};t.once("exit",()=>s("\u2713 Stopped. Local site files were cleaned up.")),t.once("logout",()=>s("\u{1F44B} Logged out. Run `sleekcms` to sign in again.")),process.on("SIGINT",()=>{t.exit()}),process.on("SIGTERM",()=>{t.exit()}),await i.waitUntilExit()}Pr().catch(t=>{let e=t;console.error("\u274C",e.body||e.message),process.exit(1)});
|
|
9
|
+
`)}async function lr(t,e,r,n,i){bt.delete(S.resolve(t)),await f.remove(S.join(t,vt)),n("\u{1F4E5} Fetching files...");let o=await xt(e,r,"GET","/get_files"),c={},h=0;for(let p of o){let x=S.join(t,p.path);await f.outputFile(x,p.content);let y=(await f.stat(x)).mtimeMs;h++,i?.(h,o.length),c[p.path]={mtimeMs:y}}return n(`\u2714\uFE0F Synced ${o.length} file(s).`),{fileMap:c,pulled:h}}import ur from"path";import dr from"chokidar";var gr=5e3,hr=/(^|[/\\])(\.DS_Store|Thumbs\.db|desktop\.ini)$/,z=class{viewsDir;onSync;debounceMs;watcher=null;debounceTimer=null;isShuttingDown=!1;dirty=!1;syncInFlight=!1;constructor(e){this.viewsDir=e.viewsDir,this.onSync=e.onSync,this.debounceMs=e.debounceMs??gr}start(){if(this.watcher)return;let e=ur.join(this.viewsDir,"src");this.watcher=dr.watch([e],{persistent:!0,ignoreInitial:!0,ignored:hr}).on("change",()=>this.scheduleSync()).on("add",()=>this.scheduleSync()).on("unlink",()=>this.scheduleSync())}setShuttingDown(e){this.isShuttingDown=e}async stop(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.watcher&&(await this.watcher.close(),this.watcher=null)}scheduleSync(){this.isShuttingDown||(this.dirty=!0,this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>this.flush(),this.debounceMs))}async flush(){if(this.debounceTimer=null,!(!this.dirty||this.isShuttingDown)){if(this.syncInFlight){this.debounceTimer=setTimeout(()=>this.flush(),this.debounceMs);return}this.dirty=!1,this.syncInFlight=!0;try{await this.onSync()}catch(e){let r=e;console.error("\u274C Sync failed:",r.body||r.message)}finally{this.syncInFlight=!1}}}};import st from"fs-extra";import pr from"os";import Zt from"path";var Qt={localhost:"http://app.sleekcms.test/api",development:"https://app.sleekcms.dev/api",production:"https://app.sleekcms.com/api"};function kt(t){return Qt[t]||Qt.production}var mr=Zt.join(pr.homedir(),"SleekCMS"),ot=Zt.join(mr,"auth.json"),Tt;function te(t){Tt=t||void 0}function Bt(t){let e=[];return t&&e.push(`_auth=${t}`),Tt&&e.push(`_dev=${Tt}`),e.length?e.join("; "):void 0}var L=class extends Error{status;body;constructor(e,r,n=""){super(e),this.name="UserAuthError",this.status=r,this.body=n}};async function ee(){try{let t=await st.readJson(ot);return t&&t.userToken?t:null}catch{return null}}async function re(t){await st.outputJson(ot,t,{spaces:2});try{await st.chmod(ot,384)}catch{}}async function ne(){await st.remove(ot)}async function W(t){let e={},r=Bt(t.userToken);r&&(e.Cookie=r),t.subdomain&&(e["x-subdomain"]=t.subdomain),t.slug&&(e.site=t.slug),t.body!==void 0&&(e["Content-Type"]="application/json");let n=await fetch(kt(t.env)+t.path,{method:t.method,headers:e,body:t.body!==void 0?JSON.stringify(t.body):void 0});if(!n.ok){let i=await n.text().catch(()=>"");throw new L(`${t.method} ${t.path} \u2192 ${n.status}: ${i}`,n.status,i)}return n.json()}async function ie(t,e){let r={"Content-Type":"application/json"},n=Bt();n&&(r.Cookie=n);let i=await fetch(kt(t)+"/auth/otp",{method:"PUT",headers:r,body:JSON.stringify({email:e})});if(!i.ok){let c=await i.text().catch(()=>"");throw new L(`Failed to send OTP \u2192 ${i.status}: ${c}`,i.status,c)}return{otp:(await i.json().catch(()=>({}))).do_not_use_in_code}}async function Et(t,e,r){let n={"Content-Type":"application/json"},i=Bt();i&&(n.Cookie=i);let o=await fetch(kt(t)+"/auth/login",{method:"POST",headers:n,body:JSON.stringify({email:e,otp:r})});if(!o.ok){let p=await o.text().catch(()=>"");throw new L(`Login failed \u2192 ${o.status}: ${p}`,o.status,p)}let c=o.headers.getSetCookie?.()??[],h=fr(c);if(!h)throw new L("Login succeeded but no _auth cookie was returned.",500);return h}function fr(t){for(let e of t){let r=e.match(/(?:^|;\s*)_auth=([^;]+)/);if(r&&r[1])return decodeURIComponent(r[1])}return null}async function Ct(t,e){return W({env:t,userToken:e,method:"GET",path:"/org"})}async function se(t,e,r){return W({env:t,userToken:e,method:"GET",path:"/site",subdomain:r})}async function oe(t,e,r,n){let i;try{i=await W({env:t,userToken:e,method:"GET",path:"/site_build",subdomain:r,slug:n})}catch{return null}if(!Array.isArray(i)||i.length===0)return null;let o=i[0],c=i.find(p=>typeof p.url=="string"&&p.url.length>0),h=Array.isArray(o.errors)?o.errors.map(p=>String(p)):[];return h.length>0?{status:"error",mode:"preview",errors:h,url:c?.url||void 0,at:o.updated_at?Date.parse(o.updated_at):void 0}:c?{status:"success",mode:"preview",url:c.url||void 0,at:c.updated_at?Date.parse(c.updated_at):void 0}:null}async function ae(t,e,r,n){let{token:i}=await W({env:t,userToken:e,method:"POST",path:"/site_user/api_token",subdomain:r,slug:n,body:{refresh:!1}});return i}async function ce(t,e,r){let n=await W({env:t,userToken:e,method:"POST",path:"/org",body:r?{name:r}:{}});return{id:n.id,name:n.name,subdomain:n.subdomain}}async function le(t,e,r,n){let i=await W({env:t,userToken:e,method:"POST",path:"/site",subdomain:r,body:{name:n}});return{id:i.id,name:i.name,slug:i.slug}}var ue=500;function xr(){return new Date().toTimeString().slice(0,8)}function at(t){let e=t;if(e.body){try{let r=JSON.parse(e.body);if(r&&typeof r.message=="string")return r.message;if(r&&typeof r.error=="string")return r.error}catch{}return e.body}return e.message}async function de(t){t&&(await Y.remove(Pt.join(t,"src")),await Y.remove(Pt.join(t,".cache","state.json")))}var ct=class extends yr{env="production";userToken="";email;catalog=[];synced=new Map;message;messageIsError=!1;agentMd;buildScript;isShuttingDown=!1;constructor(e,r){super(),this.agentMd=e,this.buildScript=r}changed(){this.emit("change")}flash(e,r=!1){this.message=e,this.messageIsError=r,this.changed()}appendLog(e,r){let n=this.synced.get(e);n&&(n.logs.push({time:xr(),text:r}),n.logs.length>ue&&n.logs.splice(0,n.logs.length-ue),this.changed())}siteCount(){return this.synced.size}syncingCount(){let e=0;for(let r of this.synced.values())r.status==="syncing"&&e++;return e}watchingCount(){let e=0;for(let r of this.synced.values())(r.status==="watching"||r.status==="syncing")&&e++;return e}async init(e,r,n){this.env=e,this.userToken=r,n&&(this.email=n);let i=await Ct(e,r);await this.buildCatalog(i)}async buildCatalog(e){let r=[];for(let n of e)try{r.push({org:n,sites:await se(this.env,this.userToken,n.subdomain)})}catch(i){if(i instanceof L&&i.status===401)throw i;r.push({org:n,sites:[]})}this.catalog=r,this.changed()}isSynced(e){return this.synced.has(e)}availableSites(){let e=[];for(let r of this.catalog)for(let n of r.sites)this.synced.has(n.id)||e.push({org:r.org,site:n});return e}async addSite(e,r){if(this.synced.has(r.id))return;let n;try{n=await ae(this.env,this.userToken,e.subdomain,r.slug)}catch(o){this.flash(`Failed to authorize "${r.name}": ${at(o)}`,!0);return}let i={org:e,site:r,siteToken:n,viewsDir:"",status:"syncing",logs:[]};this.synced.set(r.id,i),this.appendLog(r.id,"\u2795 added \u2014 pulling files"),this.changed();try{let o=await St({token:n,env:this.env,agentMd:this.agentMd,buildScript:this.buildScript,log:c=>this.appendLog(r.id,c),onProgress:(c,h)=>{i.progress={done:c,total:h},this.changed()}});i.viewsDir=o.viewsDir,i.progress=void 0,i.status="watching",i.lastSyncedAt=Date.now(),i.lastMsg=`pulled ${o.pulled} file(s)`,i.watcher=new z({viewsDir:o.viewsDir,onSync:()=>this.runSync(r.id)}),i.watcher.start(),this.watchBuildStatus(r.id),this.seedLastBuild(r.id),this.appendLog(r.id,"\u{1F440} watching for changes")}catch(o){let c=o;i.status="error",i.progress=void 0,i.lastMsg=c.body||c.message,this.appendLog(r.id,`\u274C ${c.body||c.message}`)}this.changed()}async removeSite(e){let r=this.synced.get(e);r&&(r.watcher?.setShuttingDown(!0),await r.watcher?.stop(),await r.buildWatcher?.close(),await de(r.viewsDir),this.synced.delete(e),this.changed())}buildSite(e,r=!1){let n=this.synced.get(e);if(!n||!n.viewsDir)return;let i=r?"live":"preview";this.writeBuildFile(n.viewsDir,{status:"building",mode:i,stage:"queued",url:n.lastBuild?.url,at:Date.now()}),wr("node",r?["build.mjs","--deploy"]:["build.mjs"],{cwd:n.viewsDir,stdio:"ignore"}).on("error",h=>{this.writeBuildFile(n.viewsDir,{status:"error",mode:i,errors:[h.message],url:n.lastBuild?.url,at:Date.now()}),this.appendLog(e,`\u274C build: ${h.message}`)}),this.appendLog(e,r?"\u{1F680} deploying\u2026":"\u{1F528} building\u2026")}buildFile(e){return Pt.join(e,".cache","build.json")}async readBuildFile(e){try{let r=await Y.readJson(this.buildFile(e));return r&&r.status?r:null}catch{return null}}async writeBuildFile(e,r){let n=this.buildFile(e),i=`${n}.tmp`;try{await Y.outputJson(i,r),await Y.rename(i,n)}catch{}}watchBuildStatus(e){let r=this.synced.get(e);!r||!r.viewsDir||(r.buildWatcher=br.watch(this.buildFile(r.viewsDir),{ignoreInitial:!1}).on("add",()=>{this.readBuildStatus(e)}).on("change",()=>{this.readBuildStatus(e)}))}async readBuildStatus(e){let r=this.synced.get(e);if(!r)return;let n=await this.readBuildFile(r.viewsDir);if(!n)return;let i=r.lastBuild?.url;r.lastBuild={status:n.status,mode:n.mode??"preview",url:n.url??(n.status==="success"?void 0:i),errors:n.errors,stage:n.stage,at:n.at},this.changed()}async seedLastBuild(e){let r=this.synced.get(e);if(!r)return;let n=await oe(this.env,this.userToken,r.org.subdomain,r.site.slug);if(!n)return;let i=this.synced.get(e);if(!i)return;let o=await this.readBuildFile(i.viewsDir);o?.at!=null&&(n.at==null||o.at>=n.at)||await this.writeBuildFile(i.viewsDir,n)}async ensureOrg(e){if(e)return e;if(this.catalog[0])return this.catalog[0].org;let r;try{r=await Ct(this.env,this.userToken)}catch(n){return this.flash(`Couldn't check your organizations: ${at(n)}`,!0),null}if(r.length>0){try{await this.buildCatalog(r)}catch{}return r[0]}try{let n=this.email?`${this.email.split("@")[0]}'s Sites`:"My Sites";this.flash("No organization yet \u2014 creating one\u2026");let i=await ce(this.env,this.userToken,n);return this.catalog=[...this.catalog,{org:i,sites:[]}],this.changed(),i}catch(n){return this.flash(`Could not create an organization: ${at(n)}`,!0),null}}async createNewSite(e,r){let n=await this.ensureOrg(r);if(!n)return;let i;try{i=await le(this.env,this.userToken,n.subdomain,e)}catch(c){this.flash(`Could not create "${e}": ${at(c)}`,!0);return}let o=this.catalog.find(c=>c.org.id===n.id);o&&!o.sites.some(c=>c.id===i.id)&&(o.sites=[...o.sites,i]),this.flash(`Created "${i.name}".`),await this.addSite(n,i)}async refetch(e){await this.runSync(e,{flush:!0})}async runSync(e,r={}){let n=this.synced.get(e);if(!(!n||!n.viewsDir||n.status==="paused")){n.status="syncing",this.changed();try{let i=await St({token:n.siteToken,env:this.env,viewsDir:n.viewsDir,agentMd:this.agentMd,buildScript:this.buildScript,flush:r.flush,log:o=>this.appendLog(e,o),onProgress:(o,c)=>{n.progress={done:o,total:c},this.changed()}});n.progress=void 0,n.status="watching",n.lastSyncedAt=Date.now(),r.flush?n.lastMsg=`re-fetched ${i.pulled} file(s)`:n.lastMsg=i.pushed>0?`pushed ${i.pushed} file(s)`:"up to date"}catch(i){let o=i;n.status="error",n.progress=void 0,n.lastMsg=o.body||o.message,this.appendLog(e,`\u274C ${o.body||o.message}`)}this.changed()}}async togglePause(e){let r=this.synced.get(e);!r||!r.viewsDir||(r.status==="paused"?(r.watcher=new z({viewsDir:r.viewsDir,onSync:()=>this.runSync(e)}),r.watcher.start(),r.status="watching",this.appendLog(e,"\u25B6 resumed \u2014 watching for changes")):(r.watcher?.setShuttingDown(!0),await r.watcher?.stop(),r.watcher=void 0,r.progress=void 0,r.status="paused",this.appendLog(e,"\u23F8 paused")),this.changed())}async cleanupAll(){for(let e of this.synced.values())e.watcher?.setShuttingDown(!0),await e.watcher?.stop(),await e.buildWatcher?.close(),await de(e.viewsDir)}async exit(){this.isShuttingDown||(this.isShuttingDown=!0,await this.cleanupAll(),this.emit("exit"))}async logout(){this.isShuttingDown||(this.isShuttingDown=!0,await ne(),await this.cleanupAll(),this.emit("logout"))}};import{useEffect as $r,useState as ve}from"react";import{Box as Lr,Text as Rr,useInput as Fr}from"ink";import{useState as V}from"react";import{Box as Q,Text as q}from"ink";import ge from"ink-text-input";import{jsx as _,jsxs as H}from"react/jsx-runtime";function he(t){let e=t;return e?.body||e?.message||String(t)}function pe({env:t,initialError:e,onAuthed:r}){let[n,i]=V("email"),[o,c]=V(""),[h,p]=V(""),[x,y]=V(e),[m,w]=V(),v=async R=>{let T=R.trim();if(T){y(void 0),i("busy");try{let{otp:C}=await ie(t,T);if(c(T),C){let J=await Et(t,T,C);await r(J,T);return}w(`OTP sent to ${T}`),i("otp")}catch(C){y(he(C)),i("email")}}},M=async R=>{let T=R.trim();if(T){y(void 0),i("busy");try{let C=await Et(t,o,T);await r(C,o)}catch(C){y(he(C)),p(""),i("otp")}}};return H(Q,{flexDirection:"column",children:[H(q,{bold:!0,children:["\u25C6 SleekCMS \u2014 sign in",t!=="production"?` (${t})`:""]}),x?H(q,{color:"red",children:["\u2717 ",x]}):null,n==="email"&&H(Q,{marginTop:1,children:[_(q,{children:"Email: "}),_(ge,{value:o,onChange:c,onSubmit:v,placeholder:"you@example.com"})]}),n==="otp"&&H(Q,{flexDirection:"column",marginTop:1,children:[m?_(q,{color:"green",children:m}):null,H(Q,{children:[_(q,{children:"Enter OTP: "}),_(ge,{value:h,onChange:p,onSubmit:M})]})]}),n==="busy"&&_(Q,{marginTop:1,children:_(q,{children:"Working\u2026"})})]})}import{Fragment as vr,useEffect as gt,useMemo as Tr,useState as O}from"react";import{Box as d,Text as l,useInput as kr,useStdout as Br}from"ink";import ye from"ink-text-input";import Sr from"node:os";function Ot(t){if(!t)return"\u2014";let e=Sr.homedir();return t.startsWith(e)?"~"+t.slice(e.length):t}function Dt(t){if(!t)return"\u2014";let e=Math.floor((Date.now()-t)/1e3);if(e<5)return"just now";if(e<60)return`${e}s ago`;let r=Math.floor(e/60);if(r<60)return`${r}m ago`;let n=Math.floor(r/60);return n<24?`${n}h ago`:`${Math.floor(n/24)}d ago`}function ut(t){return!t||t.total<=0?null:Math.round(t.done/t.total*100)}var lt=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];function me(t){return lt[(t%lt.length+lt.length)%lt.length]}function dt(t){switch(t){case"syncing":return{dot:"\u25CF",color:"green",label:"syncing"};case"watching":return{dot:"\u25CB",color:"gray",label:"watching"};case"paused":return{dot:"\u2016",color:"yellow",label:"paused"};case"error":return{dot:"\u2717",color:"red",label:"error"}}}function fe(t){if(!t)return{dot:"\xB7",color:"gray",label:"\u2014"};switch(t.status){case"building":return{dot:"\u2234",color:"yellow",label:"building"};case"error":return{dot:"\u2717",color:"red",label:"failed"};case"success":return{dot:"\u2713",color:"green",label:t.mode==="live"?"live":"preview"}}}import{Fragment as Z,jsx as s,jsxs as u}from"react/jsx-runtime";var N=(t,e)=>e<=0?0:Math.max(0,Math.min(t,e-1)),Er=16,Cr=5,Pr="greenBright",we="blueBright",be="magentaBright";function xe({k:t,bg:e=Pr}){return s(l,{color:"black",backgroundColor:e,children:` ${t} `})}function j({k:t,label:e,width:r=16,bg:n}){return u(d,{width:r,children:[s(xe,{k:t,bg:n}),s(l,{color:"gray",children:` ${e}`})]})}function E({k:t,label:e,bg:r}){return u(d,{marginBottom:1,children:[s(d,{width:9,children:s(xe,{k:t,bg:r})}),s(l,{color:"gray",children:e})]})}function Or({launchers:t}){return u(d,{flexDirection:"column",borderStyle:"round",borderColor:"green",paddingX:2,paddingY:1,width:66,children:[u(d,{justifyContent:"space-between",children:[s(l,{color:"green",bold:!0,children:"KEYBOARD SHORTCUTS"}),s(l,{color:"gray",children:"? or esc to close"})]}),u(d,{marginTop:1,children:[u(d,{flexDirection:"column",width:34,children:[s(l,{color:"cyan",bold:!0,children:"Navigate"}),s(E,{k:"\u2191\u2193",label:"move selection"}),s(E,{k:"\u23CE",label:"start / stop sync"}),s(E,{k:"esc",label:"clear filter / back"}),s(d,{marginTop:1,children:s(l,{color:"cyan",bold:!0,children:"Global"})}),s(E,{k:"/",label:"search sites"}),s(E,{k:"n",label:"new site"}),s(E,{k:"?",label:"toggle this help",bg:we}),s(E,{k:"q",label:"logout"}),s(E,{k:"ctrl+c",label:"quit"})]}),u(d,{flexDirection:"column",flexGrow:1,children:[s(l,{color:"cyan",bold:!0,children:"Site actions"}),s(E,{k:"p",label:"pause / resume sync"}),s(E,{k:"b",label:"build preview"}),s(E,{k:"B",label:"deploy live"}),s(E,{k:"o",label:"open preview url"}),t.map((e,r)=>s(E,{k:String(r+1),label:`open in ${e.label}`,bg:be},e.key))]})]})]})}function Dr({percent:t,width:e=28}){let r=Math.round(Math.max(0,Math.min(100,t))/100*e);return u(l,{children:[s(l,{color:"green",children:"\u2588".repeat(r)}),s(l,{color:"gray",children:"\u2591".repeat(Math.max(0,e-r))})]})}function Mr({frame:t,width:e=24,seg:r=6}){let n=e+r,i=t%n-r,o="";for(let c=0;c<e;c++)o+=c>=i&&c<i+r?"\u25AE":"\u25AF";return s(l,{color:"yellow",children:o})}function Se({controller:t}){let{stdout:e}=Br(),r=Tr(()=>Yt(),[]),[,n]=O(0),[i,o]=O(()=>new Date),[c,h]=O(null),[p,x]=O(()=>t.synced.size>0||t.catalog.some(g=>g.sites.length>0)?"dashboard":t.catalog.length<=1?"newName":"newOrg"),[y,m]=O(0),[w,v]=O(""),[M,R]=O(!1),[T,C]=O(""),[J,tt]=O(!1),[Lt,Ce]=O(0),[Rt,Ft]=O(!1),[Pe,Oe]=O(!1),At=()=>n(a=>a+1);gt(()=>(t.on("change",At),()=>{t.off("change",At)}),[t]),gt(()=>{let a=setInterval(()=>o(new Date),1e3);return()=>clearInterval(a)},[]);let A=t.catalog.flatMap(a=>a.sites.map(g=>({org:a.org,site:g,entry:t.synced.get(g.id)}))).sort((a,g)=>(a.entry?0:1)-(g.entry?0:1)),I=T.trim().toLowerCase(),P=I?A.filter(a=>a.site.name.toLowerCase().includes(I)||(a.org.name||a.org.subdomain||"").toLowerCase().includes(I)):A,G=P.findIndex(a=>a.site.id===c);G<0&&(G=0);let k=P[G],b=k?.entry,F=b?.lastBuild,pt=F?.status==="building",mt=fe(F),et=pt;if(!et){for(let a of t.synced.values())if(a.status==="watching"||a.status==="syncing"){et=!0;break}}gt(()=>{if(!et)return;let a=setInterval(()=>Ce(g=>g+1),120);return()=>clearInterval(a)},[et]);let jt=P.findIndex(a=>!a.entry),U=Math.max(Cr,(e?.rows??30)-Er),X=P.length,rt=X>U,De=Math.floor(U/2),K=rt?Math.max(0,Math.min(G-De,X-U)):0,ft=Math.min(X,K+U),Me=P.slice(K,ft);gt(()=>{p!=="dashboard"||M||A.length>0||(v(""),t.catalog.length<=1?x("newName"):(m(0),x("newOrg")))},[A.length,p,M,t.catalog.length]);let nt=a=>{if(P.length===0)return;let g=N(G+a,P.length);h(P[g].site.id)},$e=()=>{k&&(k.entry?t.removeSite(k.site.id):t.addSite(k.org,k.site))},Le=()=>{v(""),t.catalog.length<=1?x("newName"):(m(0),x("newOrg"))},Re=a=>{if(!b){t.flash("Press \u23CE to start syncing this site first.",!0);return}Oe(!0);let g=a.run(b.viewsDir);t.flash(g?`Opened ${a.label} at ${Ot(b.viewsDir)}`:`Couldn't open ${a.label}.`,!g)},Fe=()=>{if(!b){t.flash("Press \u23CE to start syncing this site first.",!0);return}t.togglePause(b.site.id)},It=a=>{if(!b){t.flash("Press \u23CE to start syncing this site first.",!0);return}t.buildSite(b.site.id,a),t.flash(a?"Deploying \u2014 building live\u2026":"Building preview\u2026")},Ae=()=>{let a=b?.lastBuild?.url;if(!a){t.flash("No build URL yet \u2014 press b to build.",!0);return}t.flash(zt(a)?`Opening ${a}`:"Couldn't open the browser.",!1)};kr((a,g)=>{if(Rt){(a==="?"||g.escape)&&Ft(!1);return}if(p==="newOrg"){g.escape?x("dashboard"):g.upArrow?m(D=>N(D-1,t.catalog.length)):g.downArrow?m(D=>N(D+1,t.catalog.length)):g.return&&x("newName");return}if(J){g.escape?(tt(!1),C(""),h(null)):g.return?tt(!1):g.upArrow?nt(-1):g.downArrow&&nt(1);return}if(g.escape){C(""),h(null);return}if(a==="?")return void Ft(!0);if(a==="/")return void tt(!0);if(a==="n")return void Le();if(a==="q")return void t.logout();if(g.upArrow)return nt(-1);if(g.downArrow)return nt(1);if(g.return||a===" ")return $e();if(a==="p")return Fe();if(a==="b")return It(!1);if(a==="B")return It(!0);if(a==="o")return Ae();if(a>="1"&&a<="9"){let D=r[parseInt(a,10)-1];if(D)return Re(D)}},{isActive:p!=="newName"});let je=async a=>{let g=a.trim();if(!g){x("dashboard");return}let D=t.catalog[N(y,t.catalog.length)]?.org??t.catalog[0]?.org;R(!0),x("dashboard"),await t.createNewSite(g,D),R(!1)},Ie=Math.max(5,(e?.rows??30)-18),_t=u(d,{justifyContent:"space-between",paddingX:1,children:[u(d,{children:[s(l,{color:"green",bold:!0,children:"\u25C6 SleekCMS"}),s(l,{color:"gray",children:" \u2502 "}),s(l,{children:t.email??"signed in"})]}),u(d,{children:[u(l,{color:"gray",children:[I?`${P.length}/${A.length}`:A.length," sites \xB7 "]}),u(l,{color:"green",children:[t.watchingCount()," watching"]}),s(l,{color:"gray",children:` \xB7 ${i.toTimeString().slice(0,8)}`})]})]});return Rt?u(d,{flexDirection:"column",children:[_t,s(d,{marginTop:1,justifyContent:"center",children:s(Or,{launchers:r})})]}):u(d,{flexDirection:"column",children:[_t,u(d,{children:[u(d,{flexDirection:"column",borderStyle:"round",borderColor:"green",width:38,paddingX:1,children:[u(d,{justifyContent:"space-between",children:[s(l,{color:"green",bold:!0,children:"SITE WORKSPACES"}),A.length>U&&!J&&!I?s(l,{color:"gray",children:"/ filter"}):null]}),J?u(d,{children:[s(l,{color:"cyan",children:"/ "}),s(ye,{value:T,onChange:C,onSubmit:()=>tt(!1),placeholder:"type to filter\u2026"})]}):I?s(l,{color:"gray",children:`/ ${T} \xB7 ${P.length} match${P.length===1?"":"es"}`}):null,s(d,{flexDirection:"column",marginTop:1,minHeight:rt?U+3:void 0,children:P.length===0?s(l,{color:"gray",children:I?`no matches for \u201C${T}\u201D`:"no sites \u2014 press n to create one"}):u(Z,{children:[rt?s(l,{color:"gray",children:K>0?` \u2191 ${K} more`:" "}):null,Me.map((a,g)=>{let D=K+g,Nt=a.entry?dt(a.entry.status):{dot:"\xB7",color:"gray",label:"idle"},Gt=ut(a.entry?.progress),_e=a.entry?a.entry.status==="syncing"&&Gt!=null?`${Gt}%`:a.entry.status==="paused"?"paused":"--":"",it=D===G,Ne=D===jt&&jt>0;return u(vr,{children:[Ne?s(l,{color:"gray",children:"\u2500".repeat(34)}):null,u(d,{justifyContent:"space-between",children:[u(d,{children:[s(l,{color:it?"green":"gray",children:it?"\u276F ":" "}),u(l,{color:a.entry?.status==="watching"?"green":Nt.color,children:[a.entry?.status==="watching"?me(Lt):Nt.dot," "]}),s(l,{color:it?"white":a.entry?void 0:"gray",bold:it,children:a.site.name})]}),s(l,{color:a.entry?.status==="syncing"?"green":"gray",children:_e})]})]},a.site.id)}),rt?s(l,{color:"gray",children:ft<X?` \u2193 ${X-ft} more`:" "}):null]})}),s(d,{marginTop:1,children:s(l,{color:"gray",children:"+ new site \xB7 n"})})]}),u(d,{flexDirection:"column",flexGrow:1,marginLeft:1,children:[s(d,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:1,children:k?u(Z,{children:[u(l,{children:[k.org.name||k.org.subdomain?u(l,{color:"gray",children:[k.org.name||k.org.subdomain," / "]}):null,s(l,{color:"cyan",bold:!0,children:k.site.name})]}),u(d,{marginTop:1,children:[s(l,{color:"gray",children:"status "}),b?s(l,{color:dt(b.status).color,children:`: ${dt(b.status).label}`}):s(l,{color:"gray",children:": idle \u2014 not syncing (press \u23CE to start)"})]}),u(d,{children:[s(l,{color:"gray",children:"path "}),s(l,{children:b?.viewsDir?Ot(b.viewsDir):"\u2014"})]}),u(d,{children:[s(l,{color:"gray",children:"synced "}),s(l,{children:Dt(b?.lastSyncedAt)}),s(l,{color:"gray",children:" progress "}),s(l,{color:b?.status==="syncing"?"green":"gray",children:b?.status==="syncing"?`${ut(b.progress)??0}%`:"\u2014"})]}),s(d,{marginTop:1,children:s(Dr,{percent:b?b.status==="syncing"?ut(b.progress)??0:b.status==="watching"?100:0:0})}),b?u(Z,{children:[u(d,{marginTop:1,children:[s(l,{color:"gray",children:"build "}),s(l,{color:mt.color,children:`${mt.dot} ${mt.label}`}),s(l,{color:"gray",children:" last "}),s(l,{children:pt?"in progress":Dt(F?.at)})]}),u(d,{children:[s(l,{color:"gray",children:"url "}),F?.url?s(l,{color:"cyan",children:F.url}):s(l,{color:"gray",children:"\u2014"})]}),F?.status==="error"&&F.errors?.length?u(d,{children:[s(l,{color:"red",children:"\u258C "}),s(l,{color:"red",children:`\u2717 ${F.errors[0]}`})]}):null,pt?u(d,{children:[s(Mr,{frame:Lt}),s(l,{color:"gray",children:` ${F?.stage??"building"}`})]}):null]}):null]}):s(l,{color:"gray",children:"No site selected."})}),p==="dashboard"?u(d,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:1,marginTop:1,flexGrow:1,children:[u(l,{children:[s(l,{color:"cyan",bold:!0,children:"LOGS \xB7 "}),s(l,{color:"white",children:k?.site.name??"\u2014"})]}),s(d,{flexDirection:"column",marginTop:1,children:!b||b.logs.length===0?s(l,{color:"gray",children:"no activity yet"}):b.logs.slice(-Ie).map((a,g)=>u(d,{children:[u(l,{color:"gray",children:[a.time," "]}),s(l,{children:a.text})]},g))})]}):u(d,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginTop:1,flexGrow:1,children:[p==="newOrg"&&u(Z,{children:[s(l,{color:"cyan",bold:!0,children:"CREATE SITE \u2014 PICK ORG"}),s(l,{color:"gray",children:"\u2191/\u2193 select \xB7 \u23CE next \xB7 esc cancel"}),s(d,{flexDirection:"column",marginTop:1,children:t.catalog.map((a,g)=>u(l,{color:g===N(y,t.catalog.length)?"blue":void 0,bold:g===N(y,t.catalog.length),children:[g===N(y,t.catalog.length)?"\u276F ":" ",a.org.name||a.org.subdomain]},a.org.id))})]}),p==="newName"&&u(Z,{children:[s(l,{color:"cyan",bold:!0,children:"CREATE SITE"}),u(d,{marginTop:1,children:[s(l,{children:"New site name: "}),s(ye,{value:w,onChange:v,onSubmit:je})]}),s(l,{color:"gray",children:"\u23CE create \xB7 empty + \u23CE to cancel"})]})]})]})]}),t.message?s(d,{paddingX:1,children:u(l,{color:t.messageIsError?"red":"gray",children:[t.messageIsError?"\u2717 ":"",t.message]})}):null,u(d,{flexDirection:"column",marginTop:1,children:[u(d,{paddingX:1,justifyContent:"space-between",children:[u(d,{flexWrap:"wrap",children:[s(j,{k:"\u2191\u2193",label:"select"}),s(j,{k:"/",label:"search"}),s(j,{k:"\u23CE",label:"start/stop"}),s(j,{k:"p",label:"pause"}),A.length===0?s(j,{k:"n",label:"new site"}):null,s(j,{k:"ctrl+c",label:"quit",width:14})]}),s(j,{k:"?",label:"all keys",width:12,bg:we})]}),!Pe&&r.length>0?s(d,{paddingX:1,marginTop:1,flexWrap:"wrap",children:r.map((a,g)=>s(j,{k:String(g+1),label:a.label,bg:be},a.key))}):null]})]})}import{jsx as ht}from"react/jsx-runtime";function Te(t){let e=t;return e?.body||e?.message||String(t)}function ke({controller:t,env:e,devSecret:r,savedToken:n,savedEmail:i}){let[o,c]=ve(n?"loading":"auth"),[h,p]=ve();Fr((y,m)=>{m.ctrl&&y==="c"&&t.exit()}),$r(()=>{n&&t.init(e,n,i).then(()=>c("manage")).catch(y=>{y instanceof L&&y.status===401?p("Saved session expired \u2014 please sign in again."):p(Te(y)),c("auth")})},[]);let x=async(y,m)=>{p(void 0),await re({env:e,userToken:y,devSecret:r,email:m}),c("loading");try{await t.init(e,y,m),c("manage")}catch(w){p(Te(w)),c("auth")}};return o==="auth"?ht(pe,{env:e,initialError:h,onAuthed:x}):o==="loading"?ht(Lr,{children:ht(Rr,{children:"Loading your sites\u2026 "})}):ht(Se,{controller:t})}import{jsx as Wr}from"react/jsx-runtime";var _r=jr(import.meta.url),Mt=Jt();if(Mt.version){let t=_r("../package.json");console.log(t.version),process.exit(0)}var Ee=$t.dirname(Ar(import.meta.url)),Nr=Be($t.join(Ee,"AGENT.md"),"utf-8"),Gr=Be($t.join(Ee,"build.mjs"),"utf-8");async function Ur(){let t=new ct(Nr,Gr),e=await ee(),r=(Mt.env??e?.env??"production").toLowerCase(),n=Mt.dev??process.env.SLEEKCMS_DEV_SECRET??e?.devSecret;te(n),process.stdout.isTTY&&process.stdout.write("\x1B[2J\x1B[3J\x1B[H");let i=Ir(Wr(ke,{controller:t,env:r,devSecret:n,savedToken:e?.userToken,savedEmail:e?.email}),{exitOnCtrlC:!1}),o=c=>{i.unmount(),console.log(c),process.exit(0)};t.once("exit",()=>o("\u2713 Stopped. Local site files were cleaned up.")),t.once("logout",()=>o("\u{1F44B} Logged out. Run `sleekcms` to sign in again.")),process.on("SIGINT",()=>{t.exit()}),process.on("SIGTERM",()=>{t.exit()}),await i.waitUntilExit()}Ur().catch(t=>{let e=t;console.error("\u274C",e.body||e.message),process.exit(1)});
|