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