@zenku/cli-node 0.1.36 → 0.1.37
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/package.json +1 -1
- package/zenku-bundle.cjs +1 -1
package/package.json
CHANGED
package/zenku-bundle.cjs
CHANGED
|
@@ -318,6 +318,6 @@ ${new Date().toISOString()}
|
|
|
318
318
|
`),process.stdout.write(`Last Exit: ${c?.lastExitCode??"-"}
|
|
319
319
|
`),process.stdout.write(`Last Err: ${c?.lastError||"-"}
|
|
320
320
|
`)}})}catch(o){g("%s",P(o))}}),e.command("remove").description("Remove a schedule").option("--scope <scope>","scope: user|system","user").argument("<id>","schedule ID").action((i,n)=>{try{let o=nt(n.scope);Lt(o,!1);let s=bt(o),a=s.findIndex(c=>c.id===i);a===-1&&g('schedule "%s" not found',i),s.splice(a,1),Gs(o,s);let u=on(o);db(u,i),ii(o,u),v({json:()=>({success:!0,id:i,scope:o}),human:()=>C('Schedule "%s" removed',i)})}catch(o){g("%s",P(o))}});function t(i,n,o){Lt(n,!1);let s=bt(n),a=cm(s,i);a.enabled=o,a.updatedAt=new Date().toISOString(),Gs(n,s)}e.command("enable").description("Enable a schedule").option("--scope <scope>","scope: user|system","user").argument("<id>","schedule ID").action((i,n)=>{try{let o=nt(n.scope);t(i,o,!0),v({json:()=>({success:!0,id:i,enabled:!0,scope:o}),human:()=>C('Schedule "%s" enabled',i)})}catch(o){g("%s",P(o))}}),e.command("disable").description("Disable a schedule").option("--scope <scope>","scope: user|system","user").argument("<id>","schedule ID").action((i,n)=>{try{let o=nt(n.scope);t(i,o,!1),v({json:()=>({success:!0,id:i,enabled:!1,scope:o}),human:()=>C('Schedule "%s" disabled',i)})}catch(o){g("%s",P(o))}}),e.command("run").description("Run a schedule immediately").option("--scope <scope>","scope: user|system","user").option("--dry-run","print execution details without running").argument("<id>","schedule ID").action(async(i,n)=>{try{let o=nt(n.scope),s=!!n.dryRun;Lt(o,s);let a=bt(o),u=cm(a,i),c=await hb(o,u,s);v({json:()=>c,human:()=>{if(c.dryRun){E("Dry run: %s",um(u));return}(c.exitCode??1)===0?C('Schedule "%s" ran successfully',i):E('Schedule "%s" finished with exit code %s',i,W(c.exitCode??"null"))}})}catch(o){g("%s",P(o))}}),e.command("tick").description("Run one scheduler tick (intended for host scheduler integration)").option("--scope <scope>","scope: user|system","user").action(async i=>{try{let n=nt(i.scope);Lt(n,!1);let o=await mb(n);v({json:()=>o,human:()=>{o.locked?E("Tick skipped: another tick is already running."):E("Tick completed: executed=%s skipped=%s",String(o.executed),String(o.skipped))}})}catch(n){g("%s",P(n))}});let r=new O("host").description("Manage host scheduler integration");return r.command("install").description("Install host scheduler integration").option("--scope <scope>","scope: user|system","user").option("--dry-run","show generated artifacts and commands").action(i=>{try{let n=nt(i.scope),o=!!i.dryRun;Lt(n,o);let a=qs().install(n,o);v({json:()=>a,human:()=>{C("%s host scheduler %s",o?"Previewed":"Installed",n);for(let u of a.actions)E("- %s",u)}})}catch(n){g("%s",P(n))}}),r.command("uninstall").description("Remove host scheduler integration").option("--scope <scope>","scope: user|system","user").option("--dry-run","show generated commands").action(i=>{try{let n=nt(i.scope),o=!!i.dryRun;Lt(n,o);let a=qs().uninstall(n,o);v({json:()=>a,human:()=>{C("%s host scheduler %s",o?"Previewed uninstall for":"Uninstalled",n);for(let u of a.actions)E("- %s",u)}})}catch(n){g("%s",P(n))}}),r.command("status").description("Show host scheduler status").option("--scope <scope>","scope: user|system","user").action(i=>{try{let n=nt(i.scope),s=qs().status(n);v({json:()=>s,human:()=>{E("Platform: %s",s.platform),E("Scope: %s",s.scope),E("Installed: %s",s.installed?"yes":"no");for(let[a,u]of Object.entries(s.details))E("%s: %s",a,W(u))}})}catch(n){g("%s",P(n))}}),e.addCommand(r),e}function yb(e){e.addCommand(VS())}var me=require("node:fs"),Pe=require("node:path"),oi=require("node:os");function lm(e){return e||(process.env.CLAUDE_CONFIG_DIR?process.env.CLAUDE_CONFIG_DIR:(0,Pe.join)((0,oi.homedir)(),".claude"))}function Db(e){return e||(process.env.ZENKU_MACHINE_ID?process.env.ZENKU_MACHINE_ID:(0,oi.hostname)())}function dm(e){let t=[],r;try{r=(0,me.readdirSync)(e,{withFileTypes:!0})}catch{return t}for(let i of r){let n=(0,Pe.join)(e,i.name);i.isDirectory()?t.push(...dm(n)):i.isFile()&&i.name.endsWith(".jsonl")&&t.push(n)}return t}function ct(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function WS(e,t){let r=(0,me.statSync)(e);return Date.now()-r.mtimeMs>=t*86400*1e3}function bb(e,t,r){let i=(0,Pe.relative)(t,e);return`${r}/${i}`}function pm(e){return e.replace(/'/g,"\\'")}async function $b(e,t,r,i,n,o,s){let u=(0,me.statSync)(t).size,c=null;try{let p=await e.collection("session_files").getFirstListItem(`key='${pm(r)}'`);c={id:p.id,size:p.size}}catch{}if(c&&c.size===u)return{status:"skipped",key:r,size:u};if(s)return c?E("[DRY-RUN] Would update: %s (%s -> %s)",r,ct(c.size),ct(u)):E("[DRY-RUN] Would upload: %s (%s)",r,ct(u)),{status:c?"updated":"uploaded",key:r,size:u};let l=(0,me.readFileSync)(t),d=new File([l],(0,Pe.basename)(t),{type:"application/x-ndjson"});try{return c?(await e.collection("session_files").update(c.id,{size:u,file:d}),C("Updated: %s (%s -> %s)",r,ct(c.size),ct(u)),{status:"updated",key:r,size:u}):(await e.collection("session_files").create({key:r,machine_id:i,size:u,tenant_id:n,account_id:o,file:d}),C("Uploaded: %s (%s)",r,ct(u)),{status:"uploaded",key:r,size:u})}catch(p){let f=p instanceof Error?p.message:String(p);return{status:"failed",key:r,size:u,error:f}}}function GS(){let e=new O("sessions").description("Upload and manage Claude Code session transcripts");return e.command("sync").description("Scan local Claude Code sessions and upload new/changed files").option("--machine-id <id>","machine identifier for R2 key namespacing").option("--claude-dir <path>","Claude config directory").option("--dry-run","show what would be uploaded without uploading").option("--cleanup-days <days>","delete local files older than N days after successful upload").action(async t=>{let r=lm(t.claudeDir),i=Db(t.machineId),n=t.dryRun??!1,o=t.cleanupDays?Number(t.cleanupDays):0;o&&(Number.isNaN(o)||o<1)&&g("--cleanup-days requires a positive integer");let s=(0,Pe.join)(r,"projects"),a=dm(s);if(a.length===0){E("No session files found in %s",s);return}let{client:u,profile:c}=await T("library"),l=Ue(c),d=Ne(c);o>0&&E("Cleanup mode: syncing files older than %s days",o),E("Scanning %s sessions in %s",a.length,s);let p=0,f=0,y=0,w=0,F=0,R=0;for(let Q of a){if(o>0&&!WS(Q,o)){R++;continue}let z=bb(Q,s,i),G=await $b(u,Q,z,i,l,d,n);switch(G.status){case"uploaded":p++;break;case"updated":f++;break;case"skipped":y++;break;case"failed":E("Failed: %s \u2014 %s",z,G.error),w++;continue}if(o>0)if(n)E("[DRY-RUN] Would delete local: %s",Q);else try{(0,me.unlinkSync)(Q),F++}catch{E("Failed to delete local: %s",Q)}}E(""),o>0?E("Summary: %s total, %s too new (<%sd), %s uploaded, %s updated, %s unchanged, %s deleted locally, %s failed",a.length,R,o,p,f,y,F,w):E("Summary: %s total, %s uploaded, %s updated, %s unchanged, %s failed",a.length,p,f,y,w)}),e.command("list").description("List Claude Code session files").option("--remote","list uploaded session files from PocketBase").option("--claude-dir <path>","Claude config directory").action(async t=>{if(t.remote){let{client:r}=await T("library"),i=await S("Fetching session files...",()=>r.collection("session_files").getList(1,200,{sort:"-created"}));v({json:()=>i.items,human:()=>{let n=i.items.map(o=>[o.id,o.key,o.machine_id,ct(o.size),o.created]);B(["ID","KEY","MACHINE","SIZE","CREATED"],n)}})}else{let r=lm(t.claudeDir),i=(0,Pe.join)(r,"projects"),n=dm(i);v({json:()=>n.map(o=>{let s=(0,me.statSync)(o);return{path:o,size:s.size,modified:s.mtime}}),human:()=>{let o=n.map(s=>{let a=(0,me.statSync)(s);return[(0,Pe.relative)(i,s),ct(a.size),a.mtime.toISOString().slice(0,19)]});B(["PATH","SIZE","MODIFIED"],o),E(`
|
|
321
|
-
%s files, %s total`,n.length,ct(n.reduce((s,a)=>s+(0,me.statSync)(a).size,0)))}})}}),e.command("upload").description("Upload a single session file").option("--hook","hook mode: read session path from stdin JSON").option("--machine-id <id>","machine identifier for R2 key namespacing").option("--claude-dir <path>","Claude config directory").argument("[file]","path to .jsonl file (when not using --hook)").action(async(t,r)=>{let i=lm(r.claudeDir),n=Db(r.machineId),o=(0,Pe.join)(i,"projects"),s;if(r.hook){let f;try{f=(0,me.readFileSync)(0,"utf-8")}catch{g("failed to read from stdin")}let y;try{y=JSON.parse(f)}catch{g("invalid JSON on stdin")}let w=y.transcript_path;w||g("no transcript_path in hook input"),s=w.replace(/^~/,(0,oi.homedir)())}else t?s=t:g("provide a file path or use --hook to read from stdin");try{(0,me.statSync)(s)}catch{g("file not found: %s",s)}let a=bb(s,o,n),{client:u,profile:c}=await T("library"),l=Ue(c),d=Ne(c),p=await $b(u,s,a,n,l,d,!1);p.status==="failed"&&g("upload failed: %s",p.error),v({json:()=>p,human:()=>{p.status==="skipped"&&E("Skipped (unchanged): %s",a)}})}),e.command("download").description("Download session files from PocketBase").argument("[dir]","output directory",".").option("--key <key>","download a specific file by key").option("--machine-id <id>","download all files from a specific machine").action(async(t,r)=>{let{client:i}=await T("library"),n=[];r.key&&n.push(`key='${pm(r.key)}'`),r.machineId&&n.push(`machine_id='${pm(r.machineId)}'`);let o=n.length>0?n.join(" && "):"",s=await S("Fetching session files...",()=>i.collection("session_files").getFullList({sort:"key",filter:o}));if(s.length===0){E("No session files found");return}E("Downloading %s files to %s",s.length,t);let a=await i.files.getToken(),u=0,c=0;for(let l of s){let d=l.key,p=l.file,f=(0,Pe.join)(t,d),y=i.files.getURL(l,p,{token:a});try{let w=await fetch(y);if(!w.ok){E("Failed: %s \u2014 HTTP %s",d,w.status),c++;continue}let F=Buffer.from(await w.arrayBuffer());(0,me.mkdirSync)((0,Pe.dirname)(f),{recursive:!0}),(0,me.writeFileSync)(f,F),C("Downloaded: %s (%s)",d,ct(F.length)),u++}catch(w){let F=w instanceof Error?w.message:String(w);E("Failed: %s \u2014 %s",d,F),c++}}E(""),E("Summary: %s total, %s downloaded, %s failed",s.length,u,c),v({json:()=>s.map(l=>({id:l.id,key:l.key,machine_id:l.machine_id,size:l.size})),human:()=>{}})}),e}function _b(e){e.addCommand(GS())}var wb=require("node:fs"),Js=require("node:path"),xb=require("node:url"),JS={};function Xn(){return"0.1.36"}var Cb=require("node:path");function kb(){return!0}var KS="@zenku";function Sb(e){return e.replace(/\\/g,"/")}function HS(e){let t=e.toLowerCase();return t==="node"||t==="node.exe"||t==="bun"}function Ks(){let{platform:e,arch:t}=process,r=new Set(["darwin-arm64","darwin-x64","linux-arm64","linux-x64"]),i=`${e}-${t}`;if(!r.has(i))throw new Error(`Unsupported platform: ${i}`);return`cli-${i}`}function Ib(e){return`${KS}/${e}`}function Hs(){if(kb())return"bundle";let e=Sb(process.execPath),t=Sb(process.argv[1]??""),r=(0,Cb.basename)(process.execPath).toLowerCase();return r==="zenku-test"||r==="zenku-test.exe"||r.includes("zenku-test")||t.length>0&&(t.endsWith(".js")||t.endsWith(".cjs")||t.endsWith(".mjs"))||HS(r)?"development":e.includes("/node_modules/")&&e.includes("/@zenku/")&&e.includes("/cli-")?"npm-managed":e.includes("/apps/zenku-cli/")||e.includes("/apps\\zenku-cli\\")?"development":"standalone"}function Qn(e){return e==="bundle"?{command:"npm update -g @zenku/cli-node",message:"Self-upgrade is not available in bundle mode. Update via npm: npm update -g @zenku/cli-node"}:e==="npm-managed"?{command:"npm update -g @zenku/cli",message:"This install is npm-managed. Update via npm: npm update -g @zenku/cli"}:e==="development"?{command:"pnpm --filter @hikari/zenku-cli compile",message:"Development/test builds are not self-updated. Rebuild locally: pnpm --filter @hikari/zenku-cli compile"}:{command:"zenku upgrade",message:"Run `zenku upgrade` to install the latest binary."}}var fm=require("node:child_process"),Eb=require("node:crypto"),ue=require("node:fs"),Fb=require("node:os"),$t=require("node:path");function YS(e){let t=e.trim().split(/\s+/)[0]??"",r=t.indexOf("-");if(r<=0||r>=t.length-1)throw new Error("invalid integrity format");let i=t.slice(0,r),n=t.slice(r+1);return{algo:i,hash:n}}function XS(e,t){let{algo:r,hash:i}=YS(t),n=(0,ue.readFileSync)(e);if((0,Eb.createHash)(r).update(n).digest("base64")!==i)throw new Error("checksum mismatch")}function Ob(e){try{return(0,ue.accessSync)(e,ue.constants.W_OK),!0}catch{return!1}}function QS(e,t){let r=(0,$t.dirname)(t),i=(0,$t.join)(r,`.zenku-upgrade-${process.pid}`);(0,ue.copyFileSync)(e,i),(0,ue.chmodSync)(i,493);try{(0,ue.renameSync)(i,t)}catch{try{(0,ue.unlinkSync)(i)}catch{}throw new Error(`failed to replace binary at ${t}`)}}async function e2(e,t){let r=await fetch(e);if(!r.ok)throw new Error(`download failed: HTTP ${r.status}`);let i=Buffer.from(await r.arrayBuffer());(0,ue.writeFileSync)(t,i)}function Pb(e){return Ob((0,$t.dirname)(e))}async function Ys(e,t,r){let i=`${e.version}.tgz`,n=(0,ue.mkdtempSync)((0,$t.join)((0,Fb.tmpdir)(),"zenku-upgrade-")),o=(0,$t.join)(n,i);try{await e2(e.tarball,o),XS(o,e.integrity),(0,fm.execFileSync)("tar",["xzf",o,"-C",n],{stdio:"pipe"});let s=(0,$t.join)(n,"package","zenku");if(!(0,ue.existsSync)(s))throw new Error("downloaded package is missing binary");let a=(0,$t.dirname)(t);if(Ob(a)){QS(s,t);return}if(!r.allowSudo)throw new Error(`no write permission for ${a}`);(0,fm.execFileSync)("sudo",["install","-m","755",s,t],{stdio:"inherit"})}finally{(0,ue.rmSync)(n,{recursive:!0,force:!0})}}var Ab="https://registry.npmjs.org",t2=15e3;async function zb(e){let t=new AbortController,r=setTimeout(()=>t.abort(),t2);try{let i=await fetch(e,{signal:t.signal});if(!i.ok)throw new Error(`HTTP ${i.status}`);return await i.json()}catch(i){throw i instanceof DOMException&&i.name==="AbortError"?new Error("request timed out"):i}finally{clearTimeout(r)}}function Tb(e,t){if(!e.version)throw new Error(`registry response missing version for tag "${t}"`);if(!e.dist?.tarball)throw new Error(`registry response missing dist.tarball for v${e.version}`);if(!e.dist?.integrity)throw new Error(`registry response missing dist.integrity for v${e.version}`);return{version:e.version,tarball:e.dist.tarball,integrity:e.dist.integrity,tag:t}}async function Xs(e,t){let r=Ib(e),i=encodeURIComponent(r),n=t==="stable"?"stable":"latest";try{let o=await zb(`${Ab}/${i}/${n}`);return Tb(o,n)}catch(o){if(t==="stable"){let s=await zb(`${Ab}/${i}/latest`);return Tb(s,"latest")}throw o}}function n2(){try{let e=we(),{effective:t}=Ut(e,void 0);return t.channel}catch{return"latest"}}function r2(e){return e==="bundle"?"cli-node":Ks()}function jb(e){e.addCommand(new O("upgrade").description("Upgrade zenku to the latest version").action(async()=>{let t=Hs(),r=Qn(t),i=Xn(),n=n2();if(t==="development"){v({json:()=>({mode:t,message:r.message,previous:i,latest:i,upgraded:!1,command:r.command}),human:()=>{E("%s",r.message)}});return}let o=r2(t),s=await S("Checking for updates...",()=>Xs(o,n));if(i===s.version){let a=`Already up to date (v${i}).`;v({json:()=>({previous:i,latest:s.version,upgraded:!1,mode:t,message:a}),human:()=>E("%s",a)});return}if(t!=="standalone"){v({json:()=>({previous:i,latest:s.version,upgraded:!1,mode:t,command:r.command,message:r.message}),human:()=>{E("v%s -> v%s",i,s.version),E("%s",r.message),E("Run: %s",r.command)}});return}E("v%s -> v%s",i,s.version),await S(`Downloading v${s.version}...`,async()=>{await Ys(s,process.execPath,{allowSudo:!0})}),v({json:()=>({previous:i,latest:s.version,upgraded:!0,mode:t}),human:()=>E("Upgraded zenku to v%s.",s.version)})}))}function i2(e){return{name:e.name(),description:e.description??"",required:e.required,variadic:e.variadic,defaultValue:e.defaultValue}}function o2(e){return{name:e.name(),flags:e.flags,description:e.description??"",short:e.short,long:e.long,required:e.required,optional:e.optional,variadic:e.variadic,mandatory:e.mandatory,defaultValue:e.defaultValue}}function Ub(e,t){let r=[...t,e.name()].filter(Boolean),i=e.commands.map(n=>Ub(n,r)).sort((n,o)=>n.commandPath.localeCompare(o.commandPath));return{name:e.name(),commandPath:r.join(" "),summary:e.summary(),description:e.description(),aliases:e.aliases(),usage:e.usage(),arguments:e.registeredArguments.map(i2),options:e.options.filter(n=>n.long!=="--help").map(o2),subcommands:i}}function Nb(e){let t=new O("meta").description("Machine-readable metadata for CLI integrations");t.command("commands").description("Print CLI command tree metadata").action(()=>{v({json:()=>Ub(e,[]),human:()=>{process.stdout.write("Use `zenku --json meta commands` for command metadata.\n")}})}),e.addCommand(t)}var he=require("node:fs"),si=require("node:path");var s2="update-state.json",a2="update.lock",Rb={version:1,lastCheckedAt:"",lastSeenLatestVersion:"",pendingNotice:null,lastNotifiedVersion:"",lastNotifiedAt:""};function mm(){return(0,si.join)(ts(),s2)}function u2(){return(0,si.join)(ts(),a2)}function Bb(){let e=(0,si.dirname)(mm());(0,he.existsSync)(e)||(0,he.mkdirSync)(e,{recursive:!0,mode:448})}function Qs(){let e=mm();if(!(0,he.existsSync)(e))return{...Rb};try{let t=JSON.parse((0,he.readFileSync)(e,"utf-8"));return{version:1,lastCheckedAt:t.lastCheckedAt??"",lastSeenLatestVersion:t.lastSeenLatestVersion??"",pendingNotice:t.pendingNotice??null,lastNotifiedVersion:t.lastNotifiedVersion??"",lastNotifiedAt:t.lastNotifiedAt??""}}catch{return{...Rb}}}function _t(e){Bb();let t=mm(),r=`${t}.${process.pid}.tmp`;(0,he.writeFileSync)(r,JSON.stringify(e,null,2),{encoding:"utf-8",mode:384}),(0,he.renameSync)(r,t)}function Lb(){Bb();let e=u2(),t;try{t=(0,he.openSync)(e,"wx",384)}catch{return null}return(0,he.writeFileSync)(t,String(process.pid),{encoding:"utf-8"}),{release:()=>{try{(0,he.closeSync)(t)}catch{}(0,he.rmSync)(e,{force:!0})}}}function hm(){return new Date().toISOString()}function c2(){let e=we(),t=J(te()),r;try{({profile:r}=Y(t))}catch{r=e.profiles[t]}return{cfg:e,profileName:t,profile:r}}function l2(e,t,r=Date.now()){if(!e.lastCheckedAt)return!0;let i=Date.parse(e.lastCheckedAt);return Number.isFinite(i)?r-i>=t*6e4:!0}function ea(e,t,r,i){return{version:e,message:t,command:r,channel:i,createdAt:hm()}}function d2(e){return e==="bundle"?"cli-node":e==="standalone"||e==="npm-managed"?Ks():null}function p2(e){return e==="development"}async function Zb(){if(process.env.ZENKU_SCHEDULED==="1")return;let e;try{e=c2()}catch{return}let{cfg:t,profile:r}=e,{effective:i}=Ut(t,r);if(!i.enabled)return;let n=Lb();if(n)try{let o=Qs();if(!l2(o,i.checkIntervalMinutes))return;let s=Hs(),a=Xn();if(p2(s)){o.lastCheckedAt=hm(),o.pendingNotice=null,_t(o);return}let u=d2(s);if(!u)return;let c=await Xs(u,i.channel);if(o.lastCheckedAt=hm(),o.lastSeenLatestVersion=c.version,c.version===a){o.pendingNotice=null,_t(o);return}if(s==="standalone"&&i.autoApplyStandalone){if(Pb(process.execPath))try{await Ys(c,process.execPath,{allowSudo:!1}),o.pendingNotice=ea(c.version,`Updated zenku to v${c.version}. Restart to use the new version.`,"",s),_t(o);return}catch{let p=Qn("standalone");o.pendingNotice=ea(c.version,`Update available: v${a} -> v${c.version}. ${p.message}`,p.command,s),_t(o);return}let d=Qn("standalone");o.pendingNotice=ea(c.version,`Update available: v${a} -> v${c.version}. ${d.message}`,d.command,s),_t(o);return}let l=Qn(s);o.pendingNotice=ea(c.version,`Update available: v${a} -> v${c.version}. ${l.message}`,l.command,s),_t(o)}catch{}finally{n.release()}}function Mb(e){e.command("_update-check",{hidden:!0}).description("Internal updater worker command").action(async()=>{await Zb()})}var qb=require("node:child_process");function f2(e){let t=[],r=e;for(;r&&r.parent;)t.unshift(r.name()),r=r.parent;return t}function m2(){let e=process.argv[1]??"";return!e||e.startsWith("-")?!1:e.endsWith(".js")||e.endsWith(".cjs")||e.endsWith(".mjs")||e.includes("zenku")}function h2(e){let t=process.execPath,r=m2()?[process.argv[1],"_update-check","--non-interactive"]:["_update-check","--non-interactive"];return e&&r.push("--profile",e),{executable:t,args:r}}function g2(e){let t=f2(e);return!!(t.includes("_update-check")||t[0]==="upgrade"||process.env.ZENKU_SCHEDULED==="1"||process.env.ZENKU_INTERNAL_UPDATE_CHECK==="1")}function v2(e,t){return t||(process.env.ZENKU_PROFILE?process.env.ZENKU_PROFILE:e.defaultProfile?e.defaultProfile:"default")}function y2(e,t){let r=e.trim();return!t||r.includes(t)?r:`${r} Run: ${t}`}function D2(e,t,r){return e&&!t?"interactive":!e&&r?"stderr":"none"}function b2(e,t,r=Date.now()){let i=e.pendingNotice;if(!i)return!1;if(!e.lastNotifiedVersion||e.lastNotifiedVersion!==i.version||!e.lastNotifiedAt)return!0;let n=Date.parse(e.lastNotifiedAt);return Number.isFinite(n)?r-n>=t*6e4:!0}function $2(e,t){let r=D2(le(),xe(),t);if(r==="interactive"){process.stdout.write(`${e}
|
|
321
|
+
%s files, %s total`,n.length,ct(n.reduce((s,a)=>s+(0,me.statSync)(a).size,0)))}})}}),e.command("upload").description("Upload a single session file").option("--hook","hook mode: read session path from stdin JSON").option("--machine-id <id>","machine identifier for R2 key namespacing").option("--claude-dir <path>","Claude config directory").argument("[file]","path to .jsonl file (when not using --hook)").action(async(t,r)=>{let i=lm(r.claudeDir),n=Db(r.machineId),o=(0,Pe.join)(i,"projects"),s;if(r.hook){let f;try{f=(0,me.readFileSync)(0,"utf-8")}catch{g("failed to read from stdin")}let y;try{y=JSON.parse(f)}catch{g("invalid JSON on stdin")}let w=y.transcript_path;w||g("no transcript_path in hook input"),s=w.replace(/^~/,(0,oi.homedir)())}else t?s=t:g("provide a file path or use --hook to read from stdin");try{(0,me.statSync)(s)}catch{g("file not found: %s",s)}let a=bb(s,o,n),{client:u,profile:c}=await T("library"),l=Ue(c),d=Ne(c),p=await $b(u,s,a,n,l,d,!1);p.status==="failed"&&g("upload failed: %s",p.error),v({json:()=>p,human:()=>{p.status==="skipped"&&E("Skipped (unchanged): %s",a)}})}),e.command("download").description("Download session files from PocketBase").argument("[dir]","output directory",".").option("--key <key>","download a specific file by key").option("--machine-id <id>","download all files from a specific machine").action(async(t,r)=>{let{client:i}=await T("library"),n=[];r.key&&n.push(`key='${pm(r.key)}'`),r.machineId&&n.push(`machine_id='${pm(r.machineId)}'`);let o=n.length>0?n.join(" && "):"",s=await S("Fetching session files...",()=>i.collection("session_files").getFullList({sort:"key",filter:o}));if(s.length===0){E("No session files found");return}E("Downloading %s files to %s",s.length,t);let a=await i.files.getToken(),u=0,c=0;for(let l of s){let d=l.key,p=l.file,f=(0,Pe.join)(t,d),y=i.files.getURL(l,p,{token:a});try{let w=await fetch(y);if(!w.ok){E("Failed: %s \u2014 HTTP %s",d,w.status),c++;continue}let F=Buffer.from(await w.arrayBuffer());(0,me.mkdirSync)((0,Pe.dirname)(f),{recursive:!0}),(0,me.writeFileSync)(f,F),C("Downloaded: %s (%s)",d,ct(F.length)),u++}catch(w){let F=w instanceof Error?w.message:String(w);E("Failed: %s \u2014 %s",d,F),c++}}E(""),E("Summary: %s total, %s downloaded, %s failed",s.length,u,c),v({json:()=>s.map(l=>({id:l.id,key:l.key,machine_id:l.machine_id,size:l.size})),human:()=>{}})}),e}function _b(e){e.addCommand(GS())}var wb=require("node:fs"),Js=require("node:path"),xb=require("node:url"),JS={};function Xn(){return"0.1.37"}var Cb=require("node:path");function kb(){return!0}var KS="@zenku";function Sb(e){return e.replace(/\\/g,"/")}function HS(e){let t=e.toLowerCase();return t==="node"||t==="node.exe"||t==="bun"}function Ks(){let{platform:e,arch:t}=process,r=new Set(["darwin-arm64","darwin-x64","linux-arm64","linux-x64"]),i=`${e}-${t}`;if(!r.has(i))throw new Error(`Unsupported platform: ${i}`);return`cli-${i}`}function Ib(e){return`${KS}/${e}`}function Hs(){if(kb())return"bundle";let e=Sb(process.execPath),t=Sb(process.argv[1]??""),r=(0,Cb.basename)(process.execPath).toLowerCase();return r==="zenku-test"||r==="zenku-test.exe"||r.includes("zenku-test")||t.length>0&&(t.endsWith(".js")||t.endsWith(".cjs")||t.endsWith(".mjs"))||HS(r)?"development":e.includes("/node_modules/")&&e.includes("/@zenku/")&&e.includes("/cli-")?"npm-managed":e.includes("/apps/zenku-cli/")||e.includes("/apps\\zenku-cli\\")?"development":"standalone"}function Qn(e){return e==="bundle"?{command:"npm update -g @zenku/cli-node",message:"Self-upgrade is not available in bundle mode. Update via npm: npm update -g @zenku/cli-node"}:e==="npm-managed"?{command:"npm update -g @zenku/cli",message:"This install is npm-managed. Update via npm: npm update -g @zenku/cli"}:e==="development"?{command:"pnpm --filter @hikari/zenku-cli compile",message:"Development/test builds are not self-updated. Rebuild locally: pnpm --filter @hikari/zenku-cli compile"}:{command:"zenku upgrade",message:"Run `zenku upgrade` to install the latest binary."}}var fm=require("node:child_process"),Eb=require("node:crypto"),ue=require("node:fs"),Fb=require("node:os"),$t=require("node:path");function YS(e){let t=e.trim().split(/\s+/)[0]??"",r=t.indexOf("-");if(r<=0||r>=t.length-1)throw new Error("invalid integrity format");let i=t.slice(0,r),n=t.slice(r+1);return{algo:i,hash:n}}function XS(e,t){let{algo:r,hash:i}=YS(t),n=(0,ue.readFileSync)(e);if((0,Eb.createHash)(r).update(n).digest("base64")!==i)throw new Error("checksum mismatch")}function Ob(e){try{return(0,ue.accessSync)(e,ue.constants.W_OK),!0}catch{return!1}}function QS(e,t){let r=(0,$t.dirname)(t),i=(0,$t.join)(r,`.zenku-upgrade-${process.pid}`);(0,ue.copyFileSync)(e,i),(0,ue.chmodSync)(i,493);try{(0,ue.renameSync)(i,t)}catch{try{(0,ue.unlinkSync)(i)}catch{}throw new Error(`failed to replace binary at ${t}`)}}async function e2(e,t){let r=await fetch(e);if(!r.ok)throw new Error(`download failed: HTTP ${r.status}`);let i=Buffer.from(await r.arrayBuffer());(0,ue.writeFileSync)(t,i)}function Pb(e){return Ob((0,$t.dirname)(e))}async function Ys(e,t,r){let i=`${e.version}.tgz`,n=(0,ue.mkdtempSync)((0,$t.join)((0,Fb.tmpdir)(),"zenku-upgrade-")),o=(0,$t.join)(n,i);try{await e2(e.tarball,o),XS(o,e.integrity),(0,fm.execFileSync)("tar",["xzf",o,"-C",n],{stdio:"pipe"});let s=(0,$t.join)(n,"package","zenku");if(!(0,ue.existsSync)(s))throw new Error("downloaded package is missing binary");let a=(0,$t.dirname)(t);if(Ob(a)){QS(s,t);return}if(!r.allowSudo)throw new Error(`no write permission for ${a}`);(0,fm.execFileSync)("sudo",["install","-m","755",s,t],{stdio:"inherit"})}finally{(0,ue.rmSync)(n,{recursive:!0,force:!0})}}var Ab="https://registry.npmjs.org",t2=15e3;async function zb(e){let t=new AbortController,r=setTimeout(()=>t.abort(),t2);try{let i=await fetch(e,{signal:t.signal});if(!i.ok)throw new Error(`HTTP ${i.status}`);return await i.json()}catch(i){throw i instanceof DOMException&&i.name==="AbortError"?new Error("request timed out"):i}finally{clearTimeout(r)}}function Tb(e,t){if(!e.version)throw new Error(`registry response missing version for tag "${t}"`);if(!e.dist?.tarball)throw new Error(`registry response missing dist.tarball for v${e.version}`);if(!e.dist?.integrity)throw new Error(`registry response missing dist.integrity for v${e.version}`);return{version:e.version,tarball:e.dist.tarball,integrity:e.dist.integrity,tag:t}}async function Xs(e,t){let r=Ib(e),i=encodeURIComponent(r),n=t==="stable"?"stable":"latest";try{let o=await zb(`${Ab}/${i}/${n}`);return Tb(o,n)}catch(o){if(t==="stable"){let s=await zb(`${Ab}/${i}/latest`);return Tb(s,"latest")}throw o}}function n2(){try{let e=we(),{effective:t}=Ut(e,void 0);return t.channel}catch{return"latest"}}function r2(e){return e==="bundle"?"cli-node":Ks()}function jb(e){e.addCommand(new O("upgrade").description("Upgrade zenku to the latest version").action(async()=>{let t=Hs(),r=Qn(t),i=Xn(),n=n2();if(t==="development"){v({json:()=>({mode:t,message:r.message,previous:i,latest:i,upgraded:!1,command:r.command}),human:()=>{E("%s",r.message)}});return}let o=r2(t),s=await S("Checking for updates...",()=>Xs(o,n));if(i===s.version){let a=`Already up to date (v${i}).`;v({json:()=>({previous:i,latest:s.version,upgraded:!1,mode:t,message:a}),human:()=>E("%s",a)});return}if(t!=="standalone"){v({json:()=>({previous:i,latest:s.version,upgraded:!1,mode:t,command:r.command,message:r.message}),human:()=>{E("v%s -> v%s",i,s.version),E("%s",r.message),E("Run: %s",r.command)}});return}E("v%s -> v%s",i,s.version),await S(`Downloading v${s.version}...`,async()=>{await Ys(s,process.execPath,{allowSudo:!0})}),v({json:()=>({previous:i,latest:s.version,upgraded:!0,mode:t}),human:()=>E("Upgraded zenku to v%s.",s.version)})}))}function i2(e){return{name:e.name(),description:e.description??"",required:e.required,variadic:e.variadic,defaultValue:e.defaultValue}}function o2(e){return{name:e.name(),flags:e.flags,description:e.description??"",short:e.short,long:e.long,required:e.required,optional:e.optional,variadic:e.variadic,mandatory:e.mandatory,defaultValue:e.defaultValue}}function Ub(e,t){let r=[...t,e.name()].filter(Boolean),i=e.commands.map(n=>Ub(n,r)).sort((n,o)=>n.commandPath.localeCompare(o.commandPath));return{name:e.name(),commandPath:r.join(" "),summary:e.summary(),description:e.description(),aliases:e.aliases(),usage:e.usage(),arguments:e.registeredArguments.map(i2),options:e.options.filter(n=>n.long!=="--help").map(o2),subcommands:i}}function Nb(e){let t=new O("meta").description("Machine-readable metadata for CLI integrations");t.command("commands").description("Print CLI command tree metadata").action(()=>{v({json:()=>Ub(e,[]),human:()=>{process.stdout.write("Use `zenku --json meta commands` for command metadata.\n")}})}),e.addCommand(t)}var he=require("node:fs"),si=require("node:path");var s2="update-state.json",a2="update.lock",Rb={version:1,lastCheckedAt:"",lastSeenLatestVersion:"",pendingNotice:null,lastNotifiedVersion:"",lastNotifiedAt:""};function mm(){return(0,si.join)(ts(),s2)}function u2(){return(0,si.join)(ts(),a2)}function Bb(){let e=(0,si.dirname)(mm());(0,he.existsSync)(e)||(0,he.mkdirSync)(e,{recursive:!0,mode:448})}function Qs(){let e=mm();if(!(0,he.existsSync)(e))return{...Rb};try{let t=JSON.parse((0,he.readFileSync)(e,"utf-8"));return{version:1,lastCheckedAt:t.lastCheckedAt??"",lastSeenLatestVersion:t.lastSeenLatestVersion??"",pendingNotice:t.pendingNotice??null,lastNotifiedVersion:t.lastNotifiedVersion??"",lastNotifiedAt:t.lastNotifiedAt??""}}catch{return{...Rb}}}function _t(e){Bb();let t=mm(),r=`${t}.${process.pid}.tmp`;(0,he.writeFileSync)(r,JSON.stringify(e,null,2),{encoding:"utf-8",mode:384}),(0,he.renameSync)(r,t)}function Lb(){Bb();let e=u2(),t;try{t=(0,he.openSync)(e,"wx",384)}catch{return null}return(0,he.writeFileSync)(t,String(process.pid),{encoding:"utf-8"}),{release:()=>{try{(0,he.closeSync)(t)}catch{}(0,he.rmSync)(e,{force:!0})}}}function hm(){return new Date().toISOString()}function c2(){let e=we(),t=J(te()),r;try{({profile:r}=Y(t))}catch{r=e.profiles[t]}return{cfg:e,profileName:t,profile:r}}function l2(e,t,r=Date.now()){if(!e.lastCheckedAt)return!0;let i=Date.parse(e.lastCheckedAt);return Number.isFinite(i)?r-i>=t*6e4:!0}function ea(e,t,r,i){return{version:e,message:t,command:r,channel:i,createdAt:hm()}}function d2(e){return e==="bundle"?"cli-node":e==="standalone"||e==="npm-managed"?Ks():null}function p2(e){return e==="development"}async function Zb(){if(process.env.ZENKU_SCHEDULED==="1")return;let e;try{e=c2()}catch{return}let{cfg:t,profile:r}=e,{effective:i}=Ut(t,r);if(!i.enabled)return;let n=Lb();if(n)try{let o=Qs();if(!l2(o,i.checkIntervalMinutes))return;let s=Hs(),a=Xn();if(p2(s)){o.lastCheckedAt=hm(),o.pendingNotice=null,_t(o);return}let u=d2(s);if(!u)return;let c=await Xs(u,i.channel);if(o.lastCheckedAt=hm(),o.lastSeenLatestVersion=c.version,c.version===a){o.pendingNotice=null,_t(o);return}if(s==="standalone"&&i.autoApplyStandalone){if(Pb(process.execPath))try{await Ys(c,process.execPath,{allowSudo:!1}),o.pendingNotice=ea(c.version,`Updated zenku to v${c.version}. Restart to use the new version.`,"",s),_t(o);return}catch{let p=Qn("standalone");o.pendingNotice=ea(c.version,`Update available: v${a} -> v${c.version}. ${p.message}`,p.command,s),_t(o);return}let d=Qn("standalone");o.pendingNotice=ea(c.version,`Update available: v${a} -> v${c.version}. ${d.message}`,d.command,s),_t(o);return}let l=Qn(s);o.pendingNotice=ea(c.version,`Update available: v${a} -> v${c.version}. ${l.message}`,l.command,s),_t(o)}catch{}finally{n.release()}}function Mb(e){e.command("_update-check",{hidden:!0}).description("Internal updater worker command").action(async()=>{await Zb()})}var qb=require("node:child_process");function f2(e){let t=[],r=e;for(;r&&r.parent;)t.unshift(r.name()),r=r.parent;return t}function m2(){let e=process.argv[1]??"";return!e||e.startsWith("-")?!1:e.endsWith(".js")||e.endsWith(".cjs")||e.endsWith(".mjs")||e.includes("zenku")}function h2(e){let t=process.execPath,r=m2()?[process.argv[1],"_update-check","--non-interactive"]:["_update-check","--non-interactive"];return e&&r.push("--profile",e),{executable:t,args:r}}function g2(e){let t=f2(e);return!!(t.includes("_update-check")||t[0]==="upgrade"||process.env.ZENKU_SCHEDULED==="1"||process.env.ZENKU_INTERNAL_UPDATE_CHECK==="1")}function v2(e,t){return t||(process.env.ZENKU_PROFILE?process.env.ZENKU_PROFILE:e.defaultProfile?e.defaultProfile:"default")}function y2(e,t){let r=e.trim();return!t||r.includes(t)?r:`${r} Run: ${t}`}function D2(e,t,r){return e&&!t?"interactive":!e&&r?"stderr":"none"}function b2(e,t,r=Date.now()){let i=e.pendingNotice;if(!i)return!1;if(!e.lastNotifiedVersion||e.lastNotifiedVersion!==i.version||!e.lastNotifiedAt)return!0;let n=Date.parse(e.lastNotifiedAt);return Number.isFinite(n)?r-n>=t*6e4:!0}function $2(e,t){let r=D2(le(),xe(),t);if(r==="interactive"){process.stdout.write(`${e}
|
|
322
322
|
`);return}r==="stderr"&&process.stderr.write(`[zenku update] ${e}
|
|
323
323
|
`)}function _2(e,t){let r=Qs();if(!b2(r,e))return;let i=r.pendingNotice;i&&($2(y2(i.message,i.command),t),r.lastNotifiedVersion=i.version,r.lastNotifiedAt=new Date().toISOString(),_t(r))}function w2(e){let{executable:t,args:r}=h2(e);(0,qb.spawn)(t,r,{detached:!0,stdio:"ignore",env:{...process.env,ZENKU_INTERNAL_UPDATE_CHECK:"1"}}).unref()}function Vb(e,t){if(g2(e))return;let r;try{r=we()}catch{return}let i=v2(r,t.profile),n=r.profiles[i],{effective:o}=Ut(r,n);if(o.enabled){try{_2(o.checkIntervalMinutes,o.notifyInNonInteractive)}catch{}try{w2(i)}catch{}}}function Wb(){let e=new O;return e.name("zenku").description("Zenku CLI \u2014 manage PocketBase services from the terminal.").version(Xn()).option("--profile <name>","config profile to use").option("--tenant <id>","override tenant ID for this command").option("--account <id>","override account ID for this command").option("--json","output as JSON").option("--interactive","force interactive mode").option("--non-interactive","force non-interactive mode").hook("preAction",t=>{let r=t.optsWithGlobals();Hy(r.profile??""),jy(r.tenant??""),Uy(r.account??""),Ay(!!r.json),r.interactive&&r.nonInteractive&&g("--interactive and --non-interactive cannot be used together"),r.interactive?kp("interactive"):r.nonInteractive&&kp("non-interactive"),Vb(t,{profile:r.profile})}),e.commandsGroup("Core Commands:"),cD(e),pD(e),mD(e),OD(e),e.commandsGroup("Platform Commands:"),sD(e),aD(e),AD(e),yb(e),e.commandsGroup("Auth & Config:"),eD(e),tD(e),nD(e),iD(e),e.commandsGroup("Other:"),Nb(e),_b(e),jb(e),Mb(e),e.addHelpCommand(new O("help").argument("[command]")),e}var x2=Wb();x2.parse();
|