@forsion/extend 0.9.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/desktop.mjs CHANGED
@@ -1,7 +1,7 @@
1
- var $n=null;function Lr(t){$n=t}function Se(){if(!$n)throw new Error("core host not set (call setCoreHost first)");return $n}var Hr=new TextEncoder,ni=new TextDecoder("utf-8",{ignoreBOM:!0}),vt=t=>Hr.encode(t),Ke=t=>ni.decode(t),Mn=t=>typeof t=="string"?Hr.encode(t).length:t.length;function zr(t){let e="";for(let n=0;n<t.length;n+=32768)e+=String.fromCharCode(...t.subarray(n,n+32768));return btoa(e)}function en(t){let e=t.replace(/-/g,"+").replace(/_/g,"/");return Uint8Array.from(atob(e.padEnd(Math.ceil(e.length/4)*4,"=")),n=>n.charCodeAt(0))}async function qr(t){let e=new Blob([t]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response(e).arrayBuffer())}function We(t,e){if(typeof e!="string"||!e.startsWith("/"))return null;let n=String(t||"").replace(/\/+$/,"").replace(/\/api$/,"");if(!n)return null;let r,s;try{r=new URL(n),s=new URL(n+"/api"+e)}catch{return null}return r.protocol!=="http:"&&r.protocol!=="https:"||s.origin!==r.origin||!s.pathname.startsWith("/api/")?null:s.toString()}function xt(t,e,n){return t.fetch?t.fetch(e,n):fetch(e,{...n,headers:{Authorization:`Bearer ${t.token}`,...n.headers}})}async function Ae(t,e,n,r,s=6e4){let o=await(t.fetch??fetch)(t.base+n,{method:e,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...t.token&&!t.fetch?{Authorization:`Bearer ${t.token}`}:{}},body:r===void 0?void 0:JSON.stringify(r),signal:AbortSignal.timeout(s)}),i=await o.json().catch(()=>({}));return{status:o.status,json:i}}var ri=50*1024*1024,si=new Set(["type","source","name","summary","githubRepoUrl","npmPackage","version","readme","description","tags","minAppVersion","maxAppVersion","platforms"]);function oi(t){if(!t||typeof t!="object")return null;let e=t;if(e.id!==void 0&&(typeof e.id!="string"||!/^[a-zA-Z0-9_-]{1,128}$/.test(e.id))||!e.fields||typeof e.fields!="object"||Array.isArray(e.fields))return null;let n=new FormData,r=0;for(let[s,o]of Object.entries(e.fields)){if(!si.has(s)||typeof o!="string"||(r+=o.length,r>25e4)||e.id&&!["summary","version","readme","description","tags","minAppVersion","maxAppVersion","platforms"].includes(s))return null;n.append(s,o)}if(e.zip!==void 0){if(!e.zip||typeof e.zip.name!="string"||!/\.zip$/i.test(e.zip.name)||!(e.zip.data instanceof Uint8Array)||!e.zip.data.byteLength||e.zip.data.byteLength>ri)return null;n.append("zip",new Blob([new Uint8Array(e.zip.data)],{type:"application/zip"}),e.zip.name.replace(/[\\/]/g,"_").slice(-255))}return{path:e.id?`/market/mine/${e.id}/update`:"/market/submit",body:n}}function Br(t){t.handle("cloud:marketSubmit",async(e,n)=>{if(!t.isTrustedSender(e))return{status:0,error:"untrusted"};let r=oi(n);if(!r)return{status:400,json:{error:"invalid_request"}};let s=await t.getCloud();if(!s.token)return{status:401,error:"not_signed_in"};let o=We(s.base,r.path);if(!o)return{status:0,error:"no_cloud_url"};try{let i=await xt(s,o,{method:"POST",body:r.body,redirect:"error",signal:AbortSignal.timeout(12e4)});return{status:i.status,json:await i.json().catch(()=>null)}}catch(i){return{status:0,error:String(i?.message||i)}}})}async function Wr(t){if(!t.token)return"";try{let e=await Ae(t,"POST","/api/auth/handoff",{},5e3);if(e.status===200&&typeof e.json?.code=="string"&&e.json.code)return`code=${encodeURIComponent(e.json.code)}`;if((e.status===404||e.status===405)&&!t.fetch)return`token=${encodeURIComponent(t.token)}`}catch{}return""}var Vr=["membership","credits","storefront"],Yr=["monthly","quarterly","yearly"],ii=/^[A-Za-z0-9_-]{1,64}$/;function Gr(t){let e={status:0,error:"untrusted"},n={ok:!1,error:"untrusted"};t.handle("auth:openAccountCenter",async(s,o)=>{if(!t.isTrustedSender(s))return n;let i=await t.getCloud(),l=i.base;if(!l)return{ok:!1};let a=o&&/^[a-z0-9-]+$/i.test(o)?`#${o}`:"",d=await Wr(i),u=`${l}/account${d?`?${d}`:""}${a}`;return await t.openExternal(u),{ok:!0}}),t.handle("auth:openPayCenter",async(s,o,i,l)=>{if(!t.isTrustedSender(s))return n;if(o!==void 0&&!Vr.includes(o))return{ok:!1,error:"invalid_tab"};if(i!==void 0&&(typeof i!="string"||!ii.test(i)))return{ok:!1,error:"invalid_plan"};if(l!==void 0&&!Yr.includes(l))return{ok:!1,error:"invalid_period"};let a=(o??"membership")==="membership"&&i?`&plan=${encodeURIComponent(i)}${l?`&period=${l}`:""}`:"",d=await t.getCloud(),u=d.base;if(!u)return{ok:!1};let m=await Wr(d),g=`${u}/pay?tab=${o??"membership"}${a}${m?`&${m}`:""}&redirect=${encodeURIComponent(`${u}/account`)}`;return await t.openExternal(g),{ok:!0}}),t.handle("profile:publicOrigin",async s=>{if(!t.isTrustedSender(s))return n;let{base:o}=await t.getCloud();if(!o)return{ok:!1};try{let i=await fetch(`${o}/account`,{redirect:"manual",signal:AbortSignal.timeout(4e3)});i.body?.cancel().catch(()=>{});let l=i.status>=300&&i.status<400?i.headers.get("location"):null;return l&&/^https?:\/\//i.test(l)?{ok:!0,origin:new URL(l).origin}:{ok:!1}}catch{return{ok:!1}}});let r=()=>t.getCloud();t.handle("account:quota",async s=>{if(!t.isTrustedSender(s))return e;let o=await r();if(!o.token)return{status:401,json:null};try{return await Ae(o,"GET","/api/token-quota/my",void 0,15e3)}catch(i){return{status:0,json:{detail:String(i?.message||i)}}}}),t.handle("account:useResetCard",async(s,o)=>{if(!t.isTrustedSender(s))return e;let i=await r();if(!i.token)return{status:401,json:null};if(o!==void 0&&o!=="both")return{status:400,json:{error:"invalid_type",detail:`invalid reset card type: ${o}`}};let l=o??"both";try{return await Ae(i,"POST","/api/token-quota/reset-card/use",{type:l},15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),t.handle("account:bgConvert",async(s,o)=>{if(!t.isTrustedSender(s))return e;let i=await r();if(!i.token)return{status:401,json:null};if(!Number.isInteger(o)||o<1||o>100)return{status:400,json:{error:"invalid_percent"}};try{return await Ae(i,"POST","/api/token-quota/background/convert",{percent:o},15e3)}catch(l){return{status:0,json:{detail:String(l?.message||l)}}}}),t.handle("account:bgAutoMain",async(s,o)=>{if(!t.isTrustedSender(s))return e;let i=await r();if(!i.token)return{status:401,json:null};if(typeof o!="boolean")return{status:400,json:{error:"invalid_request"}};try{return await Ae(i,"POST","/api/token-quota/background/auto-main",{enabled:o},15e3)}catch(l){return{status:0,json:{detail:String(l?.message||l)}}}}),t.handle("feedback:submit",async(s,o)=>{if(!t.isTrustedSender(s))return n;let i=await t.getCloud();if(!i.base||!i.token)return{ok:!1,error:"not-logged-in"};let l=(o?.description||"").trim();if(!l)return{ok:!1,error:"empty"};if(l.length>1e4)return{ok:!1,error:"description-too-long"};let a=[],d=!1;if(o?.sessionLogJson){let u=vt(o.sessionLogJson);if(u.length>5*1024*1024)return{ok:!1,error:"attachment-too-large"};a.push({filename:o.sessionLogName||"tangu-session.json",mime_type:"application/json",size:u.length,data_base64:zr(u)})}try{let u=await xt(i,`${i.base}/api/feedback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({description:l,attachments:a}),signal:AbortSignal.timeout(2e4)});if(!u.ok){let g=`HTTP ${u.status}`;try{g=(await u.json())?.detail||g}catch{}return{ok:!1,error:g}}return{ok:!0,id:(await u.json().catch(()=>({})))?.id??null,attachmentSkipped:d}}catch(u){return{ok:!1,error:u?.message||String(u)}}}),t.handle("cloud:fetch",async(s,o)=>{if(!t.isTrustedSender(s))return{status:0,error:"untrusted"};let i=o??{},l=typeof i.path=="string"?i.path:"",a=i.projectSource===void 0?null:i.projectSource;if(a!==null&&(typeof a!="string"||!/^[a-z0-9][a-z0-9-]{0,63}$/.test(a)))return{status:0,error:"bad_project_source"};let d=Math.min(12e4,Math.max(1e3,Number(i.timeoutMs)||15e3)),u=typeof i.method=="string"?i.method.toUpperCase():"GET";if(!/^(GET|POST|PUT|PATCH|DELETE)$/.test(u))return{status:0,error:"bad_method"};if(!l.startsWith("/"))return{status:0,error:"bad_path"};let m=await t.getCloud();if(!String(m.base||""))return{status:0,error:"no_cloud_url"};let g=We(m.base,l);if(!g)return{status:0,error:"bad_path"};if(!m.token)return{status:401,error:"not_signed_in"};let p=i.body!==void 0&&u!=="GET"&&u!=="DELETE",y=new AbortController,f=setTimeout(()=>y.abort(),d);try{let w=await xt(m,g,{method:u,headers:{...p?{"Content-Type":"application/json"}:{},...a?{"X-Project-Source":a}:{}},body:p?JSON.stringify(i.body):void 0,signal:y.signal});return{status:w.status,json:await w.json().catch(()=>null)}}catch(w){return{status:0,error:String(w?.message||w)}}finally{clearTimeout(f)}}),Br(t)}import{createHash as Qi}from"node:crypto";import{existsSync as ea,promises as ta}from"node:fs";import na from"node:path";import{EventEmitter as Oi}from"node:events";import{stat as Ni}from"node:fs";import{readdir as Ui,stat as ji}from"node:fs/promises";import*as re from"node:path";import{lstat as Jr,readdir as ai,realpath as li,stat as ci}from"node:fs/promises";import{join as ui,resolve as di,sep as Xr}from"node:path";import{Readable as fi}from"node:stream";var Pe={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},ut={root:".",fileFilter:t=>!0,directoryFilter:t=>!0,type:Pe.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:256};Object.freeze(ut);var es="READDIRP_RECURSIVE_ERROR",mi=new Set(["ENOENT","EPERM","EACCES","ELOOP",es]),Kr=[Pe.DIR_TYPE,Pe.EVERYTHING_TYPE,Pe.FILE_DIR_TYPE,Pe.FILE_TYPE],pi=new Set([Pe.DIR_TYPE,Pe.EVERYTHING_TYPE,Pe.FILE_DIR_TYPE]),gi=new Set([Pe.EVERYTHING_TYPE,Pe.FILE_DIR_TYPE,Pe.FILE_TYPE]),hi=t=>mi.has(t.code),yi=process.platform==="win32",Zr=t=>!0,Qr=t=>{if(t===void 0)return Zr;if(typeof t=="function")return t;if(typeof t=="string"){let e=t.trim();return n=>n.basename===e}if(Array.isArray(t)){let e=t.map(n=>n.trim());return n=>e.some(r=>n.basename===r)}return Zr},On=class extends fi{parents;reading;parent;_stat;_maxDepth;_wantsDir;_wantsFile;_wantsEverything;_root;_isDirent;_statsProp;_rdOptions;_fileFilter;_directoryFilter;_relStart;constructor(e={}){super({objectMode:!0,autoDestroy:!0,highWaterMark:e.highWaterMark??ut.highWaterMark});let n={...ut,...e},r=n.root??ut.root,s=n.type??ut.type;this._fileFilter=Qr(n.fileFilter),this._directoryFilter=Qr(n.directoryFilter);let o=n.lstat?Jr:ci;yi?this._stat=l=>o(l,{bigint:!0}):this._stat=o,this._maxDepth=n.depth!=null&&Number.isSafeInteger(n.depth)?n.depth:ut.depth,this._wantsDir=pi.has(s),this._wantsFile=gi.has(s),this._wantsEverything=s===Pe.EVERYTHING_TYPE,this._root=di(r),this._relStart=this._root.endsWith(Xr)?this._root.length:this._root.length+1,this._isDirent=!n.alwaysStat,this._statsProp=this._isDirent?"dirent":"stats",this._rdOptions={encoding:"utf8",withFileTypes:this._isDirent};let i={path:this._root,depth:1};i.pending=this._exploreDir(this._root,1),this.parents=[i],this.reading=!1,this.parent=void 0}async _read(e){if(!this.reading){this.reading=!0;try{for(;!this.destroyed&&e>0;){let n=this.parent,r=n&&n.files;if(r&&r.length>0){let{path:s,depth:o}=n,i=r.splice(0,e).map(a=>this._formatEntry(a,s)),l=this._isDirent?i:await Promise.all(i);for(let a of l){if(!a)continue;if(this.destroyed)return;let d=this._getEntryType(a);typeof d!="string"&&(d=await d),d==="directory"&&this._directoryFilter(a)?(o<=this._maxDepth&&this.parents.push({path:a.fullPath,depth:o+1}),this._wantsDir&&(this.push(a),e--)):(d==="file"||this._includeAsFile(a))&&this._fileFilter(a)&&this._wantsFile&&(this.push(a),e--)}}else{let s=this.parents.pop();if(!s){this.push(null);break}let o=s.pending??this._exploreDir(s.path,s.depth),i=this.parents[this.parents.length-1];if(i&&!i.pending&&(i.pending=this._exploreDir(i.path,i.depth)),this.parent=await o,this.destroyed)return}}}catch(n){this.destroy(n)}finally{this.reading=!1}}}async _exploreDir(e,n){let r;try{r=await ai(e,this._rdOptions)}catch(s){this._onError(s)}return{files:r,depth:n,path:e}}_formatEntry(e,n){let r=this._isDirent?e.name:e,s=ui(n,r),o={path:s.slice(this._relStart),fullPath:s,basename:r};return this._isDirent?(o.dirent=e,o):this._stat(s).then(i=>(o.stats=i,o),i=>{this._onError(i)})}_onError(e){hi(e)&&!this.destroyed?this.emit("warn",e):this.destroy(e)}_getEntryType(e){if(!e||!(this._statsProp in e))return"";let n=e[this._statsProp];return n.isFile()?"file":n.isDirectory()?"directory":n.isSymbolicLink()?this._getSymlinkEntryType(e):""}async _getSymlinkEntryType(e){let n=e.fullPath;try{let r=await li(n),s=await Jr(r);if(s.isFile())return"file";if(s.isDirectory()){let o=r.length;if(n.startsWith(r)&&n[o]===Xr){let i=new Error(`Circular symlink detected: "${n}" points to "${r}"`);return i.code=es,this._onError(i),""}return"directory"}}catch(r){this._onError(r)}return""}_includeAsFile(e){let n=e&&e[this._statsProp];return n&&this._wantsEverything&&!n.isDirectory()}};function ts(t,e={}){let n=e.entryType||e.type;if(n==="both"&&(n=Pe.FILE_DIR_TYPE),t){if(typeof t!="string")throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");if(n&&!Kr.includes(n))throw new Error(`readdirp: Invalid type passed. Use one of ${Kr.join(", ")}`)}else throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");let r={...e,root:t};return n&&(r.type=n),new On(r)}import{watch as wi,unwatchFile as ns,watchFile as bi}from"node:fs";import{realpath as Nn,lstat as Si,open as ki,stat as ss}from"node:fs/promises";import{type as Ei}from"node:os";import*as ge from"node:path";var _i="data",Fn="end",os="close",on=()=>{};var an=process.platform,Ln=an==="win32",vi=an==="darwin",xi=an==="linux",Ci=an==="freebsd",is=Ei()==="OS400",he={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},je=he,Ti="watch",Ai={lstat:Si,stat:ss},rt="listeners",tn="errHandlers",dt="rawEmitters",Ii=[rt,tn,dt],Ri=new Set(["3dm","3ds","3g2","3gp","7z","a","aac","adp","afdesign","afphoto","afpub","ai","aif","aiff","alz","ape","apk","appimage","ar","arj","asf","au","avi","bak","baml","bh","bin","bk","bmp","btif","bz2","bzip2","cab","caf","cgm","class","cmx","cpio","cr2","cur","dat","dcm","deb","dex","djvu","dll","dmg","dng","doc","docm","docx","dot","dotm","dra","DS_Store","dsk","dts","dtshd","dvb","dwg","dxf","ecelp4800","ecelp7470","ecelp9600","egg","eol","eot","epub","exe","f4v","fbs","fh","fla","flac","flatpak","fli","flv","fpx","fst","fvt","g3","gh","gif","graffle","gz","gzip","h261","h263","h264","icns","ico","ief","img","ipa","iso","jar","jpeg","jpg","jpgv","jpm","jxr","key","ktx","lha","lib","lvp","lz","lzh","lzma","lzo","m3u","m4a","m4v","mar","mdi","mht","mid","midi","mj2","mka","mkv","mmr","mng","mobi","mov","movie","mp3","mp4","mp4a","mpeg","mpg","mpga","mxu","nef","npx","numbers","nupkg","o","odp","ods","odt","oga","ogg","ogv","otf","ott","pages","pbm","pcx","pdb","pdf","pea","pgm","pic","png","pnm","pot","potm","potx","ppa","ppam","ppm","pps","ppsm","ppsx","ppt","pptm","pptx","psd","pya","pyc","pyo","pyv","qt","rar","ras","raw","resources","rgb","rip","rlc","rmf","rmvb","rpm","rtf","rz","s3m","s7z","scpt","sgi","shar","snap","sil","sketch","slk","smv","snk","so","stl","suo","sub","swf","tar","tbz","tbz2","tga","tgz","thmx","tif","tiff","tlz","ttc","ttf","txz","udf","uvh","uvi","uvm","uvp","uvs","uvu","viv","vob","war","wav","wax","wbmp","wdp","weba","webm","webp","whl","wim","wm","wma","wmv","wmx","woff","woff2","wrm","wvx","xbm","xif","xla","xlam","xls","xlsb","xlsm","xlsx","xlt","xltm","xltx","xm","xmind","xpi","xpm","xwd","xz","z","zip","zipx"]),Di=t=>Ri.has(ge.extname(t).slice(1).toLowerCase()),jn=(t,e)=>{t instanceof Set?t.forEach(e):e(t)},Ct=(t,e,n)=>{let r=t[e];r instanceof Set||(t[e]=r=new Set([r])),r.add(n)},Pi=t=>e=>{let n=t[e];n instanceof Set?n.clear():delete t[e]},Tt=(t,e,n)=>{let r=t[e];r instanceof Set?r.delete(n):r===n&&delete t[e]},as=t=>t instanceof Set?t.size===0:!t,nn=new Map;function rs(t,e,n,r,s){let o=(i,l)=>{n(t),s(i,l,{watchedPath:t}),l&&t!==l&&rn(ge.resolve(t,l),rt,ge.join(t,l))};try{return wi(t,{persistent:e.persistent},o)}catch(i){r(i);return}}var rn=(t,e,n,r,s)=>{let o=nn.get(t);o&&jn(o[e],i=>{i(n,r,s)})},$i=(t,e,n,r)=>{let{listener:s,errHandler:o,rawEmitter:i}=r,l=nn.get(e),a;if(!n.persistent)return a=rs(t,n,s,o,i),a?a.close.bind(a):void 0;if(l)Ct(l,rt,s),Ct(l,tn,o),Ct(l,dt,i);else{if(a=rs(t,n,rn.bind(null,e,rt),o,rn.bind(null,e,dt)),!a)return;a.on(je.ERROR,async d=>{let u=rn.bind(null,e,tn);if(l&&(l.watcherUnusable=!0),Ln&&d.code==="EPERM")try{await(await ki(t,"r")).close(),u(d)}catch{}else u(d)}),l={listeners:s,errHandlers:o,rawEmitters:i,watcher:a},nn.set(e,l)}return()=>{Tt(l,rt,s),Tt(l,tn,o),Tt(l,dt,i),as(l.listeners)&&(l.watcher.close(),nn.delete(e),Ii.forEach(Pi(l)),l.watcher=void 0,Object.freeze(l))}},Un=new Map,Mi=(t,e,n,r)=>{let{listener:s,rawEmitter:o}=r,i=Un.get(e),l=i&&i.options;return l&&(l.persistent<n.persistent||l.interval>n.interval)&&(ns(e),i=void 0),i?(Ct(i,rt,s),Ct(i,dt,o)):(i={listeners:s,rawEmitters:o,options:n,watcher:bi(e,n,(a,d)=>{jn(i.rawEmitters,m=>{m(je.CHANGE,e,{curr:a,prev:d})});let u=a.mtimeMs;(a.size!==d.size||u>d.mtimeMs||u===0)&&jn(i.listeners,m=>m(t,a))})},Un.set(e,i)),()=>{Tt(i,rt,s),Tt(i,dt,o),as(i.listeners)&&(Un.delete(e),ns(e),i.options=i.watcher=void 0,Object.freeze(i))}},sn=class{fsw;_boundHandleError;constructor(e){this.fsw=e,this._boundHandleError=n=>e._handleError(n)}_watchWithNodeFs(e,n){let r=this.fsw.options,s=ge.dirname(e),o=ge.basename(e);this.fsw._getWatchedDir(s).add(o);let l=ge.resolve(e),a={persistent:r.persistent};n||(n=on);let d;if(r.usePolling){let u=r.interval!==r.binaryInterval;a.interval=u&&Di(o)?r.binaryInterval:r.interval,d=Mi(e,l,a,{listener:n,rawEmitter:this.fsw._emitRaw})}else d=$i(e,l,a,{listener:n,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return d}_handleFile(e,n,r){if(this.fsw.closed)return;let s=ge.dirname(e),o=ge.basename(e),i=this.fsw._getWatchedDir(s),l=n;if(i.has(o))return;let a=async(u,m)=>{if(this.fsw._throttle(Ti,e,5)){if(!m||m.mtimeMs===0)try{let g=await ss(e);if(this.fsw.closed)return;let p=g.atimeMs,y=g.mtimeMs;if((!p||p<=y||y!==l.mtimeMs)&&this.fsw._emit(je.CHANGE,e,g),(vi||xi||Ci)&&l.ino!==g.ino){this.fsw._closeFile(u),l=g;let f=this._watchWithNodeFs(e,a);f&&this.fsw._addPathCloser(u,f)}else l=g}catch{this.fsw._remove(s,o)}else if(i.has(o)){let g=m.atimeMs,p=m.mtimeMs;(!g||g<=p||p!==l.mtimeMs)&&this.fsw._emit(je.CHANGE,e,m),l=m}}},d=this._watchWithNodeFs(e,a);if(!(r&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(e)){if(!this.fsw._throttle(je.ADD,e,0))return;this.fsw._emit(je.ADD,e,n)}return d}async _handleSymlink(e,n,r,s){if(this.fsw.closed)return;let o=e.fullPath,i=this.fsw._getWatchedDir(n);if(!this.fsw.options.followSymlinks){this.fsw._incrReadyCount();let l;try{l=await Nn(r)}catch{return this.fsw._emitReady(),!0}return this.fsw.closed?void 0:(i.has(s)?this.fsw._symlinkPaths.get(o)!==l&&(this.fsw._symlinkPaths.set(o,l),this.fsw._emit(je.CHANGE,r,e.stats)):(i.add(s),this.fsw._symlinkPaths.set(o,l),this.fsw._emit(je.ADD,r,e.stats)),this.fsw._emitReady(),!0)}if(this.fsw._symlinkPaths.has(o))return!0;this.fsw._symlinkPaths.set(o,!0)}_handleRead(e,n,r,s,o,i,l){e=ge.join(e,"");let a=s?`${e}:${s}`:e;if(l=this.fsw._throttle("readdir",a,1e3),!l)return;let d=this.fsw._getWatchedDir(r.path),u=new Set,m=this.fsw._readdirp(e,{fileFilter:g=>r.filterPath(g),directoryFilter:g=>r.filterDir(g)});if(m)return m.on(_i,async g=>{if(this.fsw.closed){m=void 0;return}let p=g.path,y=ge.join(e,p);if(u.add(p),!(g.stats.isSymbolicLink()&&await this._handleSymlink(g,e,y,p))){if(this.fsw.closed){m=void 0;return}(p===s||!s&&!d.has(p))&&(this.fsw._incrReadyCount(),y=ge.join(o,ge.relative(o,y)),this._addToNodeFs(y,n,r,i+1))}}).on(je.ERROR,this._boundHandleError),new Promise((g,p)=>{if(!m)return p();m.once(Fn,()=>{if(this.fsw.closed){m=void 0;return}let y=l?l.clear():!1;g(void 0),d.getChildren().filter(f=>f!==e&&!u.has(f)).forEach(f=>{this.fsw._remove(e,f)}),m=void 0,y&&this._handleRead(e,!1,r,s,o,i,l)})})}async _handleDir(e,n,r,s,o,i,l){let a=this.fsw._getWatchedDir(ge.dirname(e)),d=a.has(ge.basename(e));!(r&&this.fsw.options.ignoreInitial)&&!o&&!d&&this.fsw._emit(je.ADD_DIR,e,n),a.add(ge.basename(e)),this.fsw._getWatchedDir(e);let u,m,g=this.fsw.options.depth;if((g==null||s<=g)&&!this.fsw._symlinkPaths.has(l)){if(!o&&(await this._handleRead(e,r,i,o,e,s,u),this.fsw.closed))return;m=this._watchWithNodeFs(e,(p,y)=>{y&&y.mtimeMs===0||this._handleRead(p,!1,i,o,e,s,u)})}return m}async _addToNodeFs(e,n,r,s,o){let i=this.fsw._emitReady;if(this.fsw._isIgnored(e)||this.fsw.closed)return i(),!1;let l=this.fsw._getWatchHelpers(e);r&&(l.filterPath=a=>r.filterPath(a),l.filterDir=a=>r.filterDir(a));try{let a=await Ai[l.statMethod](l.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(l.watchPath,a))return i(),!1;let d=this.fsw.options.followSymlinks,u;if(a.isDirectory()){let m=ge.resolve(e),g=d?await Nn(e):e;if(this.fsw.closed||(u=await this._handleDir(l.watchPath,a,n,s,o,l,g),this.fsw.closed))return;m!==g&&g!==void 0&&this.fsw._symlinkPaths.set(m,g)}else if(a.isSymbolicLink()){let m=d?await Nn(e):e;if(this.fsw.closed)return;let g=ge.dirname(l.watchPath);if(this.fsw._getWatchedDir(g).add(l.watchPath),this.fsw._emit(je.ADD,l.watchPath,a),u=await this._handleDir(g,a,n,s,e,l,m),this.fsw.closed)return;m!==void 0&&this.fsw._symlinkPaths.set(ge.resolve(e),m)}else u=this._handleFile(l.watchPath,a,n);return i(),u&&this.fsw._addPathCloser(e,u),!1}catch(a){if(this.fsw._handleError(a))return i(),e}}};var Hn="/",Fi="//",fs=".",Li="..",Hi="string",zi=/\\/g,ms=/\/\//g,qi=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,Bi=/^\.[/\\]/;function ln(t){return Array.isArray(t)?t:[t]}var zn=t=>typeof t=="object"&&t!==null&&!(t instanceof RegExp);function Wi(t){return typeof t=="function"?t:typeof t=="string"?e=>t===e:t instanceof RegExp?e=>t.test(e):typeof t=="object"&&t!==null?e=>{if(t.path===e)return!0;if(t.recursive){let n=re.relative(t.path,e);return n?!n.startsWith("..")&&!re.isAbsolute(n):!1}return!1}:()=>!1}function Vi(t){if(typeof t!="string")throw new Error("string expected");t=re.normalize(t),t=t.replace(/\\/g,"/");let e=!1;return t.startsWith("//")&&(e=!0),t=t.replace(ms,"/"),e&&(t="/"+t),t}function ls(t,e,n){let r=Vi(e);for(let s=0;s<t.length;s++){let o=t[s];if(o(r,n))return!0}return!1}function Yi(t,e){if(t==null)throw new TypeError("anymatch: specify first argument");let r=ln(t).map(s=>Wi(s));return e==null?(s,o)=>ls(r,s,o):ls(r,e)}var cs=t=>{let e=ln(t).flat();if(!e.every(n=>typeof n===Hi))throw new TypeError(`Non-string provided as watch path: ${e}`);return e.map(ps)},us=t=>{let e=t.replace(zi,Hn),n=!1;return e.startsWith(Fi)&&(n=!0),e=e.replace(ms,Hn),n&&(e=Hn+e),e},ps=t=>us(re.normalize(us(t))),ds=(t="")=>e=>typeof e=="string"?ps(re.isAbsolute(e)?e:re.join(t,e)):e,Gi=(t,e)=>re.isAbsolute(t)?t:re.join(e,t),Ji=Object.freeze(new Set),qn=class{path;_removeWatcher;items;constructor(e,n){this.path=e,this._removeWatcher=n,this.items=new Set}add(e){let{items:n}=this;n&&e!==fs&&e!==Li&&n.add(e)}async remove(e){let{items:n}=this;if(!n||(n.delete(e),n.size>0))return;let r=this.path;try{await Ui(r)}catch{this._removeWatcher&&this._removeWatcher(re.dirname(r),re.basename(r))}}has(e){let{items:n}=this;if(n)return n.has(e)}getChildren(){let{items:e}=this;return e?[...e.values()]:[]}dispose(){this.items.clear(),this.path="",this._removeWatcher=on,this.items=Ji,Object.freeze(this)}},Xi="stat",Ki="lstat",Bn=class{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(e,n,r){this.fsw=r;let s=e;this.path=e=e.replace(Bi,""),this.watchPath=s,this.fullWatchPath=re.resolve(s),this.dirParts=[],this.dirParts.forEach(o=>{o.length>1&&o.pop()}),this.followSymlinks=n,this.statMethod=n?Xi:Ki}entryPath(e){return re.join(this.watchPath,re.relative(this.watchPath,e.fullPath))}filterPath(e){let{stats:n}=e;if(n&&n.isSymbolicLink())return this.filterDir(e);let r=this.entryPath(e);return this.fsw._isntIgnored(r,n)&&this.fsw._hasReadPermissions(n)}filterDir(e){return this.fsw._isntIgnored(this.entryPath(e),e.stats)}},cn=class extends Oi{closed;options;_closers;_ignoredPaths;_throttled;_streams;_symlinkPaths;_watched;_pendingWrites;_pendingUnlinks;_readyCount;_emitReady;_closePromise;_userIgnored;_readyEmitted;_emitRaw;_boundRemove;_nodeFsHandler;constructor(e={}){super(),this.closed=!1,this._closers=new Map,this._ignoredPaths=new Set,this._throttled=new Map,this._streams=new Set,this._symlinkPaths=new Map,this._watched=new Map,this._pendingWrites=new Map,this._pendingUnlinks=new Map,this._readyCount=0,this._readyEmitted=!1;let n=e.awaitWriteFinish,r={stabilityThreshold:2e3,pollInterval:100},s={persistent:!0,ignoreInitial:!1,ignorePermissionErrors:!1,interval:100,binaryInterval:300,followSymlinks:!0,usePolling:!1,atomic:!0,...e,ignored:e.ignored?ln(e.ignored):ln([]),awaitWriteFinish:n===!0?r:typeof n=="object"?{...r,...n}:!1};is&&(s.usePolling=!0),s.atomic===void 0&&(s.atomic=!s.usePolling);let o=process.env.CHOKIDAR_USEPOLLING;if(o!==void 0){let a=o.toLowerCase();a==="false"||a==="0"?s.usePolling=!1:a==="true"||a==="1"?s.usePolling=!0:s.usePolling=!!a}let i=process.env.CHOKIDAR_INTERVAL;i&&(s.interval=Number.parseInt(i,10));let l=0;this._emitReady=()=>{l++,l>=this._readyCount&&(this._emitReady=on,this._readyEmitted=!0,process.nextTick(()=>this.emit(he.READY)))},this._emitRaw=(...a)=>this.emit(he.RAW,...a),this._boundRemove=this._remove.bind(this),this.options=s,this._nodeFsHandler=new sn(this),Object.freeze(s)}_addIgnoredPath(e){if(zn(e)){for(let n of this._ignoredPaths)if(zn(n)&&n.path===e.path&&n.recursive===e.recursive)return}this._ignoredPaths.add(e)}_removeIgnoredPath(e){if(this._ignoredPaths.delete(e),typeof e=="string")for(let n of this._ignoredPaths)zn(n)&&n.path===e&&this._ignoredPaths.delete(n)}add(e,n,r){let{cwd:s}=this.options;this.closed=!1,this._closePromise=void 0;let o=cs(e);return s&&(o=o.map(i=>Gi(i,s))),o.forEach(i=>{this._removeIgnoredPath(i)}),this._userIgnored=void 0,this._readyCount||(this._readyCount=0),this._readyCount+=o.length,Promise.all(o.map(async i=>{let l=await this._nodeFsHandler._addToNodeFs(i,!r,void 0,0,n);return l&&this._emitReady(),l})).then(i=>{this.closed||i.forEach(l=>{l&&this.add(re.dirname(l),re.basename(n||l))})}),this}unwatch(e){if(this.closed)return this;let n=cs(e),{cwd:r}=this.options;return n.forEach(s=>{!re.isAbsolute(s)&&!this._closers.has(s)&&(r&&(s=re.join(r,s)),s=re.resolve(s)),this._closePath(s),this._addIgnoredPath(s),this._watched.has(s)&&this._addIgnoredPath({path:s,recursive:!0}),this._userIgnored=void 0}),this}close(){if(this._closePromise)return this._closePromise;this.closed=!0,this.removeAllListeners();let e=[];return this._closers.forEach(n=>n.forEach(r=>{let s=r();s instanceof Promise&&e.push(s)})),this._streams.forEach(n=>n.destroy()),this._userIgnored=void 0,this._readyCount=0,this._readyEmitted=!1,this._watched.forEach(n=>n.dispose()),this._closers.clear(),this._watched.clear(),this._streams.clear(),this._symlinkPaths.clear(),this._throttled.clear(),this._closePromise=e.length?Promise.all(e).then(()=>{}):Promise.resolve(),this._closePromise}getWatched(){let e={};return this._watched.forEach((n,r)=>{let o=(this.options.cwd?re.relative(this.options.cwd,r):r)||fs;e[o]=n.getChildren().sort()}),e}emitWithAll(e,n){this.emit(e,...n),e!==he.ERROR&&this.emit(he.ALL,e,...n)}async _emit(e,n,r){if(this.closed)return;let s=this.options;Ln&&(n=re.normalize(n)),s.cwd&&(n=re.relative(s.cwd,n));let o=[n];r!=null&&o.push(r);let i=s.awaitWriteFinish,l;if(i&&(l=this._pendingWrites.get(n)))return l.lastChange=new Date,this;if(s.atomic){if(e===he.UNLINK)return this._pendingUnlinks.set(n,[e,...o]),setTimeout(()=>{this._pendingUnlinks.forEach((a,d)=>{this.emit(...a),this.emit(he.ALL,...a),this._pendingUnlinks.delete(d)})},typeof s.atomic=="number"?s.atomic:100),this;e===he.ADD&&this._pendingUnlinks.has(n)&&(e=he.CHANGE,this._pendingUnlinks.delete(n))}if(i&&(e===he.ADD||e===he.CHANGE)&&this._readyEmitted){let a=(d,u)=>{d?(e=he.ERROR,o[0]=d,this.emitWithAll(e,o)):u&&(o.length>1?o[1]=u:o.push(u),this.emitWithAll(e,o))};return this._awaitWriteFinish(n,i.stabilityThreshold,e,a),this}if(e===he.CHANGE&&!this._throttle(he.CHANGE,n,50))return this;if(s.alwaysStat&&r===void 0&&(e===he.ADD||e===he.ADD_DIR||e===he.CHANGE)){let a=s.cwd?re.join(s.cwd,n):n,d;try{d=await ji(a)}catch{}if(!d||this.closed)return;o.push(d)}return this.emitWithAll(e,o),this}_handleError(e){let n=e&&e.code;return e&&n!=="ENOENT"&&n!=="ENOTDIR"&&(!this.options.ignorePermissionErrors||n!=="EPERM"&&n!=="EACCES")&&this.emit(he.ERROR,e),e||this.closed}_throttle(e,n,r){this._throttled.has(e)||this._throttled.set(e,new Map);let s=this._throttled.get(e);if(!s)throw new Error("invalid throttle");let o=s.get(n);if(o)return o.count++,!1;let i,l=()=>{let d=s.get(n),u=d?d.count:0;return s.delete(n),clearTimeout(i),d&&clearTimeout(d.timeoutObject),u};i=setTimeout(l,r);let a={timeoutObject:i,clear:l,count:0};return s.set(n,a),a}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(e,n,r,s){let o=this.options.awaitWriteFinish;if(typeof o!="object")return;let i=o.pollInterval,l,a=e;this.options.cwd&&!re.isAbsolute(e)&&(a=re.join(this.options.cwd,e));let d=new Date,u=this._pendingWrites;function m(g){Ni(a,(p,y)=>{if(p||!u.has(e)){p&&p.code!=="ENOENT"&&s(p);return}let f=Number(new Date);g&&y.size!==g.size&&(u.get(e).lastChange=f);let w=u.get(e);f-w.lastChange>=n?(u.delete(e),s(void 0,y)):l=setTimeout(m,i,y)})}u.has(e)||(u.set(e,{lastChange:d,cancelWait:()=>(u.delete(e),clearTimeout(l),r)}),l=setTimeout(m,i))}_isIgnored(e,n){if(this.options.atomic&&qi.test(e))return!0;if(!this._userIgnored){let{cwd:r}=this.options,o=(this.options.ignored||[]).map(ds(r)),l=[...[...this._ignoredPaths].map(ds(r)),...o];this._userIgnored=Yi(l,void 0)}return this._userIgnored(e,n)}_isntIgnored(e,n){return!this._isIgnored(e,n)}_getWatchHelpers(e){return new Bn(e,this.options.followSymlinks,this)}_getWatchedDir(e){let n=re.resolve(e);return this._watched.has(n)||this._watched.set(n,new qn(n,this._boundRemove)),this._watched.get(n)}_hasReadPermissions(e){return this.options.ignorePermissionErrors?!0:!!(Number(e.mode)&256)}_remove(e,n,r){let s=re.join(e,n),o=re.resolve(s);if(r=r??(this._watched.has(s)||this._watched.has(o)),!this._throttle("remove",s,100))return;!r&&this._watched.size===1&&this.add(e,n,!0),this._getWatchedDir(s).getChildren().forEach(g=>this._remove(s,g));let a=this._getWatchedDir(e),d=a.has(n);a.remove(n),this._symlinkPaths.has(o)&&this._symlinkPaths.delete(o);let u=s;if(this.options.cwd&&(u=re.relative(this.options.cwd,s)),this.options.awaitWriteFinish&&this._pendingWrites.has(u)&&this._pendingWrites.get(u).cancelWait()===he.ADD)return;this._watched.delete(s),this._watched.delete(o);let m=r?he.UNLINK_DIR:he.UNLINK;d&&!this._isIgnored(s)&&this._emit(m,s),this._closePath(s)}_closePath(e){this._closeFile(e);let n=re.dirname(e);this._getWatchedDir(n).remove(re.basename(e))}_closeFile(e){let n=this._closers.get(e);n&&(n.forEach(r=>r()),this._closers.delete(e))}_addPathCloser(e,n){if(!n)return;let r=this._closers.get(e);r||(r=[],this._closers.set(e,r)),r.push(n)}_readdirp(e,n){if(this.closed)return;let r={type:he.ALL,alwaysStat:!0,lstat:!0,...n,depth:0},s=ts(e,r);return this._streams.add(s),s.once(os,()=>{s=void 0}),s.once(Fn,()=>{s&&(this._streams.delete(s),s=void 0)}),s}};function Zi(t,e={}){let n=new cn(e);return n.add(t),n}var gs={watch:Zi,FSWatcher:cn};var hs={fs:ta,path:na,sha256Hex:t=>Qi("sha256").update(t).digest("hex"),tmpTag:()=>process.pid,existsSync:ea,watch(t,e,n){let r=gs.watch(t,{ignoreInitial:!0,depth:e.depth,ignored:e.ignored});return r.on("change",n.change),r.on("add",n.add),r.on("unlink",n.unlink),r.on("unlinkDir",n.unlinkDir),r}};import{readdirSync as ra,lstatSync as sa,readFileSync as Wn,writeFileSync as oa,realpathSync as ys}from"node:fs";import{join as Yn,extname as ia,sep as aa}from"node:path";var Vn=300,ws=5*1024*1024,bs=20*1024*1024,la=50*1024*1024,ca=new Set(["node_modules"]),ua=new Set([".ts",".tsx",".jsx",".mts",".cts"]);function Ss(t,e){let n=[],r=0,s=(o,i)=>{for(let l of ra(o)){if(l.startsWith("."))continue;let a=Yn(o,l),d;try{d=sa(a)}catch{continue}if(d.isSymbolicLink())continue;let u=i?`${i}/${l}`:l;if(d.isDirectory()){ca.has(l)||s(a,u);continue}if(!d.isFile()||l.endsWith(".d.ts"))continue;if(n.length>=Vn)throw new Error(`\u6587\u4EF6\u6570\u8D85\u8FC7 ${Vn}\uFF0C\u8BF7\u7CBE\u7B80\u9879\u76EE\uFF08node_modules \u4E0E\u9690\u85CF\u6587\u4EF6\u5DF2\u81EA\u52A8\u8DF3\u8FC7\uFF09`);let m=ia(l).toLowerCase(),g,p=e.mimeOf(m)??"application/octet-stream";if(ua.has(m)){let y=e.transpile(Wn(a,"utf8"),m,u);g=Buffer.from(y??"","utf8"),p="text/javascript"}else g=Wn(a);if(g.length>ws)throw new Error(`\u5355\u6587\u4EF6\u8D85\u8FC7 5MB\uFF1A${u}`);if(r+=g.length,r>bs)throw new Error("\u9879\u76EE\u603B\u5927\u5C0F\u8D85\u8FC7 20MB\uFF0C\u65E0\u6CD5\u53D1\u5E03");n.push({path:u,content_b64:g.toString("base64"),content_type:p,size:g.length})}};if(s(t,""),!n.length)throw new Error("\u9879\u76EE\u4E3A\u7A7A\uFF0C\u6CA1\u6709\u53EF\u53D1\u5E03\u7684\u6587\u4EF6");return{files:n,totalBytes:r}}var ks=".forsion-connect.json";function Es(t){try{return JSON.parse(Wn(Yn(t,ks),"utf8"))}catch{return{}}}function _s(t,e){try{oa(Yn(t,ks),JSON.stringify(e,null,2)+`
2
- `,"utf8")}catch{}}function vs(t){let e={"/__forsion/chat":{method:"POST",path:"/api/chat/completions",auth:!0},"/__forsion/images":{method:"POST",path:"/api/images/generations",auth:!0},"/__forsion/user":{method:"GET",path:"/api/brain/users/me",auth:!0},"/__forsion/models":{method:"GET",path:"/api/models",auth:!1},"/__forsion/config":{method:"GET",path:"/api/connect/config",auth:!1},"/__forsion/agent":{method:"POST",path:"/api/agent/runs",auth:!0,agentRun:!0}};function n(r){if(e[r])return e[r];let s="/__forsion/agent-events/";if(r.startsWith(s)){let o=r.slice(s.length);if(/^[A-Za-z0-9-]{1,64}$/.test(o))return{method:"GET",path:`/api/agent/runs/${o}/events`,auth:!0,timeoutMs:9e5}}}return async(r,s)=>{let[o,i]=(r.url||"").split("?"),l=(y,f)=>{s.headersSent||(s.statusCode=y,s.setHeader("Content-Type","application/json")),s.end(JSON.stringify({detail:f}))},a=n(o);if(!a)return l(404,"unknown connect endpoint");if((r.method||"GET")!==a.method)return l(405,"method not allowed");let d="",u="";try{({base:d,token:u}=await t())}catch{}if(!d)return l(502,"\u672A\u914D\u7F6E Forsion \u4E91\u7AEF\u5730\u5740");if(a.auth&&!u)return l(401,"\u8BF7\u5148\u5728 Forsion Desktop \u4E2D\u767B\u5F55 Forsion \u8D26\u53F7");let m;if(a.method==="POST"){let y=[],f=0;try{for await(let w of r){if(f+=w.length,f>la)return r.destroy(),l(413,"\u8BF7\u6C42\u4F53\u8FC7\u5927");y.push(w)}}catch(w){return l(400,`\u8BF7\u6C42\u4F53\u8BFB\u53D6\u5931\u8D25\uFF1A${w?.message||String(w)}`)}m=Buffer.concat(y)}if(a.agentRun){let y;try{y=JSON.parse((m||Buffer.alloc(0)).toString("utf8")||"{}")}catch{return l(400,"agent \u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON")}m=Buffer.from(JSON.stringify({session_id:typeof y.session_id=="string"?y.session_id:"",message:typeof y.message=="string"?y.message:"",app_id:"connect",agent_config:{}}))}let g=new AbortController,p=setTimeout(()=>g.abort(new Error("proxy timeout")),a.timeoutMs??3e5);r.on("close",()=>g.abort());try{let y=await fetch(d+a.path+(i?`?${i}`:""),{method:a.method,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...u?{Authorization:`Bearer ${u}`}:{}},body:m&&m.length?new Uint8Array(m):void 0,signal:g.signal});if(s.statusCode=y.status,s.setHeader("Content-Type",y.headers.get("content-type")||"application/json"),s.setHeader("Cache-Control","no-store"),y.body)for await(let f of y.body)s.write(f);s.end()}catch(y){let f=`\u4E91\u7AEF\u8BF7\u6C42\u4E2D\u65AD\uFF1A${y?.message||String(y)}`;if(s.headersSent){try{s.write(`data: ${JSON.stringify({error:f})}
1
+ var tr=null;function Es(t){tr=t}function Se(){if(!tr)throw new Error("core host not set (call setCoreHost first)");return tr}var _s=new TextEncoder,ra=new TextDecoder("utf-8",{ignoreBOM:!0}),Nt=t=>_s.encode(t),rt=t=>ra.decode(t),nr=t=>typeof t=="string"?_s.encode(t).length:t.length;function Cs(t){let e="";for(let n=0;n<t.length;n+=32768)e+=String.fromCharCode(...t.subarray(n,n+32768));return btoa(e)}function gn(t){let e=t.replace(/-/g,"+").replace(/_/g,"/");return Uint8Array.from(atob(e.padEnd(Math.ceil(e.length/4)*4,"=")),n=>n.charCodeAt(0))}async function xs(t){let e=new Blob([t]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response(e).arrayBuffer())}function Ge(t,e){if(typeof e!="string"||!e.startsWith("/"))return null;let n=String(t||"").replace(/\/+$/,"").replace(/\/api$/,"");if(!n)return null;let r,s;try{r=new URL(n),s=new URL(n+"/api"+e)}catch{return null}return r.protocol!=="http:"&&r.protocol!=="https:"||s.origin!==r.origin||!s.pathname.startsWith("/api/")?null:s.toString()}function jt(t,e,n){return t.fetch?t.fetch(e,n):fetch(e,{...n,headers:{Authorization:`Bearer ${t.token}`,...n.headers}})}async function Ae(t,e,n,r,s=6e4){let o=await(t.fetch??fetch)(t.base+n,{method:e,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...t.token&&!t.fetch?{Authorization:`Bearer ${t.token}`}:{}},body:r===void 0?void 0:JSON.stringify(r),signal:AbortSignal.timeout(s)}),i=await o.json().catch(()=>({}));return{status:o.status,json:i}}var sa=50*1024*1024,oa=new Set(["type","source","name","summary","githubRepoUrl","npmPackage","version","readme","description","tags","minAppVersion","maxAppVersion","platforms"]);function ia(t){if(!t||typeof t!="object")return null;let e=t;if(e.id!==void 0&&(typeof e.id!="string"||!/^[a-zA-Z0-9_-]{1,128}$/.test(e.id))||!e.fields||typeof e.fields!="object"||Array.isArray(e.fields))return null;let n=new FormData,r=0;for(let[s,o]of Object.entries(e.fields)){if(!oa.has(s)||typeof o!="string"||(r+=o.length,r>25e4)||e.id&&!["summary","version","readme","description","tags","minAppVersion","maxAppVersion","platforms"].includes(s))return null;n.append(s,o)}if(e.zip!==void 0){if(!e.zip||typeof e.zip.name!="string"||!/\.zip$/i.test(e.zip.name)||!(e.zip.data instanceof Uint8Array)||!e.zip.data.byteLength||e.zip.data.byteLength>sa)return null;n.append("zip",new Blob([new Uint8Array(e.zip.data)],{type:"application/zip"}),e.zip.name.replace(/[\\/]/g,"_").slice(-255))}return{path:e.id?`/market/mine/${e.id}/update`:"/market/submit",body:n}}function Ts(t){t.handle("cloud:marketSubmit",async(e,n)=>{if(!t.isTrustedSender(e))return{status:0,error:"untrusted"};let r=ia(n);if(!r)return{status:400,json:{error:"invalid_request"}};let s=await t.getCloud();if(!s.token)return{status:401,error:"not_signed_in"};let o=Ge(s.base,r.path);if(!o)return{status:0,error:"no_cloud_url"};try{let i=await jt(s,o,{method:"POST",body:r.body,redirect:"error",signal:AbortSignal.timeout(12e4)});return{status:i.status,json:await i.json().catch(()=>null)}}catch(i){return{status:0,error:String(i?.message||i)}}})}async function As(t){if(!t.token)return"";try{let e=await Ae(t,"POST","/api/auth/handoff",{},5e3);if(e.status===200&&typeof e.json?.code=="string"&&e.json.code)return`code=${encodeURIComponent(e.json.code)}`;if((e.status===404||e.status===405)&&!t.fetch)return`token=${encodeURIComponent(t.token)}`}catch{}return""}var Is=["membership","credits","storefront"],Ps=["monthly","quarterly","yearly"],aa=/^[A-Za-z0-9_-]{1,64}$/;function Rs(t){let e={status:0,error:"untrusted"},n={ok:!1,error:"untrusted"};t.handle("auth:openAccountCenter",async(s,o)=>{if(!t.isTrustedSender(s))return n;let i=await t.getCloud(),l=i.base;if(!l)return{ok:!1};let a=o&&/^[a-z0-9-]+$/i.test(o)?`#${o}`:"",c=await As(i),u=`${l}/account${c?`?${c}`:""}${a}`;return i.signal?.throwIfAborted(),await t.openExternal(u),{ok:!0}}),t.handle("auth:openPayCenter",async(s,o,i,l)=>{if(!t.isTrustedSender(s))return n;if(o!==void 0&&!Is.includes(o))return{ok:!1,error:"invalid_tab"};if(i!==void 0&&(typeof i!="string"||!aa.test(i)))return{ok:!1,error:"invalid_plan"};if(l!==void 0&&!Ps.includes(l))return{ok:!1,error:"invalid_period"};let a=(o??"membership")==="membership"&&i?`&plan=${encodeURIComponent(i)}${l?`&period=${l}`:""}`:"",c=await t.getCloud(),u=c.base;if(!u)return{ok:!1};let f=await As(c),m=`${u}/pay?tab=${o??"membership"}${a}${f?`&${f}`:""}&redirect=${encodeURIComponent(`${u}/account`)}`;return c.signal?.throwIfAborted(),await t.openExternal(m),{ok:!0}}),t.handle("profile:publicOrigin",async s=>{if(!t.isTrustedSender(s))return n;let{base:o}=await t.getCloud();if(!o)return{ok:!1};try{let i=await fetch(`${o}/account`,{redirect:"manual",signal:AbortSignal.timeout(4e3)});i.body?.cancel().catch(()=>{});let l=i.status>=300&&i.status<400?i.headers.get("location"):null;return l&&/^https?:\/\//i.test(l)?{ok:!0,origin:new URL(l).origin}:{ok:!1}}catch{return{ok:!1}}});let r=()=>t.getCloud();t.handle("account:quota",async s=>{if(!t.isTrustedSender(s))return e;let o=await r();if(!o.token)return{status:401,json:null};try{return await Ae(o,"GET","/api/token-quota/my",void 0,15e3)}catch(i){return{status:0,json:{detail:String(i?.message||i)}}}}),t.handle("account:useResetCard",async(s,o)=>{if(!t.isTrustedSender(s))return e;let i=await r();if(!i.token)return{status:401,json:null};if(o!==void 0&&o!=="both")return{status:400,json:{error:"invalid_type",detail:`invalid reset card type: ${o}`}};let l=o??"both";try{return await Ae(i,"POST","/api/token-quota/reset-card/use",{type:l},15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),t.handle("account:bgConvert",async(s,o)=>{if(!t.isTrustedSender(s))return e;let i=await r();if(!i.token)return{status:401,json:null};if(!Number.isInteger(o)||o<1||o>100)return{status:400,json:{error:"invalid_percent"}};try{return await Ae(i,"POST","/api/token-quota/background/convert",{percent:o},15e3)}catch(l){return{status:0,json:{detail:String(l?.message||l)}}}}),t.handle("account:bgAutoMain",async(s,o)=>{if(!t.isTrustedSender(s))return e;let i=await r();if(!i.token)return{status:401,json:null};if(typeof o!="boolean")return{status:400,json:{error:"invalid_request"}};try{return await Ae(i,"POST","/api/token-quota/background/auto-main",{enabled:o},15e3)}catch(l){return{status:0,json:{detail:String(l?.message||l)}}}}),t.handle("feedback:submit",async(s,o)=>{if(!t.isTrustedSender(s))return n;let i=await t.getCloud();if(!i.base||!i.token)return{ok:!1,error:"not-logged-in"};let l=(o?.description||"").trim();if(!l)return{ok:!1,error:"empty"};if(l.length>1e4)return{ok:!1,error:"description-too-long"};let a=[],c=!1;if(o?.sessionLogJson){let u=Nt(o.sessionLogJson);if(u.length>5*1024*1024)return{ok:!1,error:"attachment-too-large"};a.push({filename:o.sessionLogName||"tangu-session.json",mime_type:"application/json",size:u.length,data_base64:Cs(u)})}try{let u=await jt(i,`${i.base}/api/feedback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({description:l,attachments:a}),signal:AbortSignal.timeout(2e4)});if(!u.ok){let m=`HTTP ${u.status}`;try{m=(await u.json())?.detail||m}catch{}return{ok:!1,error:m}}return{ok:!0,id:(await u.json().catch(()=>({})))?.id??null,attachmentSkipped:c}}catch(u){return{ok:!1,error:u?.message||String(u)}}}),t.handle("cloud:fetch",async(s,o)=>{if(!t.isTrustedSender(s))return{status:0,error:"untrusted"};let i=o??{},l=typeof i.path=="string"?i.path:"",a=i.projectSource===void 0?null:i.projectSource;if(a!==null&&(typeof a!="string"||!/^[a-z0-9][a-z0-9-]{0,63}$/.test(a)))return{status:0,error:"bad_project_source"};let c=Math.min(12e4,Math.max(1e3,Number(i.timeoutMs)||15e3)),u=typeof i.method=="string"?i.method.toUpperCase():"GET";if(!/^(GET|POST|PUT|PATCH|DELETE)$/.test(u))return{status:0,error:"bad_method"};if(!l.startsWith("/"))return{status:0,error:"bad_path"};let f=await t.getCloud();if(!String(f.base||""))return{status:0,error:"no_cloud_url"};let m=Ge(f.base,l);if(!m)return{status:0,error:"bad_path"};if(!f.token)return{status:401,error:"not_signed_in"};let h=i.body!==void 0&&u!=="GET"&&u!=="DELETE",g=new AbortController,p=setTimeout(()=>g.abort(),c);try{let y=await jt(f,m,{method:u,headers:{...h?{"Content-Type":"application/json"}:{},...a?{"X-Project-Source":a}:{}},body:h?JSON.stringify(i.body):void 0,signal:g.signal});return{status:y.status,json:await y.json().catch(()=>null)}}catch(y){return{status:0,error:String(y?.message||y)}}finally{clearTimeout(p)}}),Ts(t)}import{createHash as Qa}from"node:crypto";import{existsSync as el,promises as tl}from"node:fs";import nl from"node:path";import{EventEmitter as Na}from"node:events";import{stat as ja}from"node:fs";import{readdir as Ua,stat as Fa}from"node:fs/promises";import*as re from"node:path";import{lstat as Ds,readdir as la,realpath as ca,stat as ua}from"node:fs/promises";import{join as da,resolve as fa,sep as $s}from"node:path";import{Readable as ha}from"node:stream";var $e={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},vt={root:".",fileFilter:t=>!0,directoryFilter:t=>!0,type:$e.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:256};Object.freeze(vt);var js="READDIRP_RECURSIVE_ERROR",pa=new Set(["ENOENT","EPERM","EACCES","ELOOP",js]),Os=[$e.DIR_TYPE,$e.EVERYTHING_TYPE,$e.FILE_DIR_TYPE,$e.FILE_TYPE],ma=new Set([$e.DIR_TYPE,$e.EVERYTHING_TYPE,$e.FILE_DIR_TYPE]),ga=new Set([$e.EVERYTHING_TYPE,$e.FILE_DIR_TYPE,$e.FILE_TYPE]),ya=t=>pa.has(t.code),wa=process.platform==="win32",Ms=t=>!0,Ns=t=>{if(t===void 0)return Ms;if(typeof t=="function")return t;if(typeof t=="string"){let e=t.trim();return n=>n.basename===e}if(Array.isArray(t)){let e=t.map(n=>n.trim());return n=>e.some(r=>n.basename===r)}return Ms},rr=class extends ha{parents;reading;parent;_stat;_maxDepth;_wantsDir;_wantsFile;_wantsEverything;_root;_isDirent;_statsProp;_rdOptions;_fileFilter;_directoryFilter;_relStart;constructor(e={}){super({objectMode:!0,autoDestroy:!0,highWaterMark:e.highWaterMark??vt.highWaterMark});let n={...vt,...e},r=n.root??vt.root,s=n.type??vt.type;this._fileFilter=Ns(n.fileFilter),this._directoryFilter=Ns(n.directoryFilter);let o=n.lstat?Ds:ua;wa?this._stat=l=>o(l,{bigint:!0}):this._stat=o,this._maxDepth=n.depth!=null&&Number.isSafeInteger(n.depth)?n.depth:vt.depth,this._wantsDir=ma.has(s),this._wantsFile=ga.has(s),this._wantsEverything=s===$e.EVERYTHING_TYPE,this._root=fa(r),this._relStart=this._root.endsWith($s)?this._root.length:this._root.length+1,this._isDirent=!n.alwaysStat,this._statsProp=this._isDirent?"dirent":"stats",this._rdOptions={encoding:"utf8",withFileTypes:this._isDirent};let i={path:this._root,depth:1};i.pending=this._exploreDir(this._root,1),this.parents=[i],this.reading=!1,this.parent=void 0}async _read(e){if(!this.reading){this.reading=!0;try{for(;!this.destroyed&&e>0;){let n=this.parent,r=n&&n.files;if(r&&r.length>0){let{path:s,depth:o}=n,i=r.splice(0,e).map(a=>this._formatEntry(a,s)),l=this._isDirent?i:await Promise.all(i);for(let a of l){if(!a)continue;if(this.destroyed)return;let c=this._getEntryType(a);typeof c!="string"&&(c=await c),c==="directory"&&this._directoryFilter(a)?(o<=this._maxDepth&&this.parents.push({path:a.fullPath,depth:o+1}),this._wantsDir&&(this.push(a),e--)):(c==="file"||this._includeAsFile(a))&&this._fileFilter(a)&&this._wantsFile&&(this.push(a),e--)}}else{let s=this.parents.pop();if(!s){this.push(null);break}let o=s.pending??this._exploreDir(s.path,s.depth),i=this.parents[this.parents.length-1];if(i&&!i.pending&&(i.pending=this._exploreDir(i.path,i.depth)),this.parent=await o,this.destroyed)return}}}catch(n){this.destroy(n)}finally{this.reading=!1}}}async _exploreDir(e,n){let r;try{r=await la(e,this._rdOptions)}catch(s){this._onError(s)}return{files:r,depth:n,path:e}}_formatEntry(e,n){let r=this._isDirent?e.name:e,s=da(n,r),o={path:s.slice(this._relStart),fullPath:s,basename:r};return this._isDirent?(o.dirent=e,o):this._stat(s).then(i=>(o.stats=i,o),i=>{this._onError(i)})}_onError(e){ya(e)&&!this.destroyed?this.emit("warn",e):this.destroy(e)}_getEntryType(e){if(!e||!(this._statsProp in e))return"";let n=e[this._statsProp];return n.isFile()?"file":n.isDirectory()?"directory":n.isSymbolicLink()?this._getSymlinkEntryType(e):""}async _getSymlinkEntryType(e){let n=e.fullPath;try{let r=await ca(n),s=await Ds(r);if(s.isFile())return"file";if(s.isDirectory()){let o=r.length;if(n.startsWith(r)&&n[o]===$s){let i=new Error(`Circular symlink detected: "${n}" points to "${r}"`);return i.code=js,this._onError(i),""}return"directory"}}catch(r){this._onError(r)}return""}_includeAsFile(e){let n=e&&e[this._statsProp];return n&&this._wantsEverything&&!n.isDirectory()}};function Us(t,e={}){let n=e.entryType||e.type;if(n==="both"&&(n=$e.FILE_DIR_TYPE),t){if(typeof t!="string")throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");if(n&&!Os.includes(n))throw new Error(`readdirp: Invalid type passed. Use one of ${Os.join(", ")}`)}else throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");let r={...e,root:t};return n&&(r.type=n),new rr(r)}import{watch as ba,unwatchFile as Fs,watchFile as Sa}from"node:fs";import{realpath as sr,lstat as va,open as ka,stat as zs}from"node:fs/promises";import{type as Ea}from"node:os";import*as me from"node:path";var _a="data",ar="end",Hs="close",vn=()=>{};var kn=process.platform,lr=kn==="win32",Ca=kn==="darwin",xa=kn==="linux",Ta=kn==="freebsd",qs=Ea()==="OS400",ge={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},Fe=ge,Aa="watch",Ia={lstat:va,stat:zs},ft="listeners",yn="errHandlers",kt="rawEmitters",Pa=[ft,yn,kt],Ra=new Set(["3dm","3ds","3g2","3gp","7z","a","aac","adp","afdesign","afphoto","afpub","ai","aif","aiff","alz","ape","apk","appimage","ar","arj","asf","au","avi","bak","baml","bh","bin","bk","bmp","btif","bz2","bzip2","cab","caf","cgm","class","cmx","cpio","cr2","cur","dat","dcm","deb","dex","djvu","dll","dmg","dng","doc","docm","docx","dot","dotm","dra","DS_Store","dsk","dts","dtshd","dvb","dwg","dxf","ecelp4800","ecelp7470","ecelp9600","egg","eol","eot","epub","exe","f4v","fbs","fh","fla","flac","flatpak","fli","flv","fpx","fst","fvt","g3","gh","gif","graffle","gz","gzip","h261","h263","h264","icns","ico","ief","img","ipa","iso","jar","jpeg","jpg","jpgv","jpm","jxr","key","ktx","lha","lib","lvp","lz","lzh","lzma","lzo","m3u","m4a","m4v","mar","mdi","mht","mid","midi","mj2","mka","mkv","mmr","mng","mobi","mov","movie","mp3","mp4","mp4a","mpeg","mpg","mpga","mxu","nef","npx","numbers","nupkg","o","odp","ods","odt","oga","ogg","ogv","otf","ott","pages","pbm","pcx","pdb","pdf","pea","pgm","pic","png","pnm","pot","potm","potx","ppa","ppam","ppm","pps","ppsm","ppsx","ppt","pptm","pptx","psd","pya","pyc","pyo","pyv","qt","rar","ras","raw","resources","rgb","rip","rlc","rmf","rmvb","rpm","rtf","rz","s3m","s7z","scpt","sgi","shar","snap","sil","sketch","slk","smv","snk","so","stl","suo","sub","swf","tar","tbz","tbz2","tga","tgz","thmx","tif","tiff","tlz","ttc","ttf","txz","udf","uvh","uvi","uvm","uvp","uvs","uvu","viv","vob","war","wav","wax","wbmp","wdp","weba","webm","webp","whl","wim","wm","wma","wmv","wmx","woff","woff2","wrm","wvx","xbm","xif","xla","xlam","xls","xlsb","xlsm","xlsx","xlt","xltm","xltx","xm","xmind","xpi","xpm","xwd","xz","z","zip","zipx"]),Da=t=>Ra.has(me.extname(t).slice(1).toLowerCase()),ir=(t,e)=>{t instanceof Set?t.forEach(e):e(t)},Ut=(t,e,n)=>{let r=t[e];r instanceof Set||(t[e]=r=new Set([r])),r.add(n)},$a=t=>e=>{let n=t[e];n instanceof Set?n.clear():delete t[e]},Ft=(t,e,n)=>{let r=t[e];r instanceof Set?r.delete(n):r===n&&delete t[e]},Bs=t=>t instanceof Set?t.size===0:!t,wn=new Map;function Ls(t,e,n,r,s){let o=(i,l)=>{n(t),s(i,l,{watchedPath:t}),l&&t!==l&&bn(me.resolve(t,l),ft,me.join(t,l))};try{return ba(t,{persistent:e.persistent},o)}catch(i){r(i);return}}var bn=(t,e,n,r,s)=>{let o=wn.get(t);o&&ir(o[e],i=>{i(n,r,s)})},Oa=(t,e,n,r)=>{let{listener:s,errHandler:o,rawEmitter:i}=r,l=wn.get(e),a;if(!n.persistent)return a=Ls(t,n,s,o,i),a?a.close.bind(a):void 0;if(l)Ut(l,ft,s),Ut(l,yn,o),Ut(l,kt,i);else{if(a=Ls(t,n,bn.bind(null,e,ft),o,bn.bind(null,e,kt)),!a)return;a.on(Fe.ERROR,async c=>{let u=bn.bind(null,e,yn);if(l&&(l.watcherUnusable=!0),lr&&c.code==="EPERM")try{await(await ka(t,"r")).close(),u(c)}catch{}else u(c)}),l={listeners:s,errHandlers:o,rawEmitters:i,watcher:a},wn.set(e,l)}return()=>{Ft(l,ft,s),Ft(l,yn,o),Ft(l,kt,i),Bs(l.listeners)&&(l.watcher.close(),wn.delete(e),Pa.forEach($a(l)),l.watcher=void 0,Object.freeze(l))}},or=new Map,Ma=(t,e,n,r)=>{let{listener:s,rawEmitter:o}=r,i=or.get(e),l=i&&i.options;return l&&(l.persistent<n.persistent||l.interval>n.interval)&&(Fs(e),i=void 0),i?(Ut(i,ft,s),Ut(i,kt,o)):(i={listeners:s,rawEmitters:o,options:n,watcher:Sa(e,n,(a,c)=>{ir(i.rawEmitters,f=>{f(Fe.CHANGE,e,{curr:a,prev:c})});let u=a.mtimeMs;(a.size!==c.size||u>c.mtimeMs||u===0)&&ir(i.listeners,f=>f(t,a))})},or.set(e,i)),()=>{Ft(i,ft,s),Ft(i,kt,o),Bs(i.listeners)&&(or.delete(e),Fs(e),i.options=i.watcher=void 0,Object.freeze(i))}},Sn=class{fsw;_boundHandleError;constructor(e){this.fsw=e,this._boundHandleError=n=>e._handleError(n)}_watchWithNodeFs(e,n){let r=this.fsw.options,s=me.dirname(e),o=me.basename(e);this.fsw._getWatchedDir(s).add(o);let l=me.resolve(e),a={persistent:r.persistent};n||(n=vn);let c;if(r.usePolling){let u=r.interval!==r.binaryInterval;a.interval=u&&Da(o)?r.binaryInterval:r.interval,c=Ma(e,l,a,{listener:n,rawEmitter:this.fsw._emitRaw})}else c=Oa(e,l,a,{listener:n,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return c}_handleFile(e,n,r){if(this.fsw.closed)return;let s=me.dirname(e),o=me.basename(e),i=this.fsw._getWatchedDir(s),l=n;if(i.has(o))return;let a=async(u,f)=>{if(this.fsw._throttle(Aa,e,5)){if(!f||f.mtimeMs===0)try{let m=await zs(e);if(this.fsw.closed)return;let h=m.atimeMs,g=m.mtimeMs;if((!h||h<=g||g!==l.mtimeMs)&&this.fsw._emit(Fe.CHANGE,e,m),(Ca||xa||Ta)&&l.ino!==m.ino){this.fsw._closeFile(u),l=m;let p=this._watchWithNodeFs(e,a);p&&this.fsw._addPathCloser(u,p)}else l=m}catch{this.fsw._remove(s,o)}else if(i.has(o)){let m=f.atimeMs,h=f.mtimeMs;(!m||m<=h||h!==l.mtimeMs)&&this.fsw._emit(Fe.CHANGE,e,f),l=f}}},c=this._watchWithNodeFs(e,a);if(!(r&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(e)){if(!this.fsw._throttle(Fe.ADD,e,0))return;this.fsw._emit(Fe.ADD,e,n)}return c}async _handleSymlink(e,n,r,s){if(this.fsw.closed)return;let o=e.fullPath,i=this.fsw._getWatchedDir(n);if(!this.fsw.options.followSymlinks){this.fsw._incrReadyCount();let l;try{l=await sr(r)}catch{return this.fsw._emitReady(),!0}return this.fsw.closed?void 0:(i.has(s)?this.fsw._symlinkPaths.get(o)!==l&&(this.fsw._symlinkPaths.set(o,l),this.fsw._emit(Fe.CHANGE,r,e.stats)):(i.add(s),this.fsw._symlinkPaths.set(o,l),this.fsw._emit(Fe.ADD,r,e.stats)),this.fsw._emitReady(),!0)}if(this.fsw._symlinkPaths.has(o))return!0;this.fsw._symlinkPaths.set(o,!0)}_handleRead(e,n,r,s,o,i,l){e=me.join(e,"");let a=s?`${e}:${s}`:e;if(l=this.fsw._throttle("readdir",a,1e3),!l)return;let c=this.fsw._getWatchedDir(r.path),u=new Set,f=this.fsw._readdirp(e,{fileFilter:m=>r.filterPath(m),directoryFilter:m=>r.filterDir(m)});if(f)return f.on(_a,async m=>{if(this.fsw.closed){f=void 0;return}let h=m.path,g=me.join(e,h);if(u.add(h),!(m.stats.isSymbolicLink()&&await this._handleSymlink(m,e,g,h))){if(this.fsw.closed){f=void 0;return}(h===s||!s&&!c.has(h))&&(this.fsw._incrReadyCount(),g=me.join(o,me.relative(o,g)),this._addToNodeFs(g,n,r,i+1))}}).on(Fe.ERROR,this._boundHandleError),new Promise((m,h)=>{if(!f)return h();f.once(ar,()=>{if(this.fsw.closed){f=void 0;return}let g=l?l.clear():!1;m(void 0),c.getChildren().filter(p=>p!==e&&!u.has(p)).forEach(p=>{this.fsw._remove(e,p)}),f=void 0,g&&this._handleRead(e,!1,r,s,o,i,l)})})}async _handleDir(e,n,r,s,o,i,l){let a=this.fsw._getWatchedDir(me.dirname(e)),c=a.has(me.basename(e));!(r&&this.fsw.options.ignoreInitial)&&!o&&!c&&this.fsw._emit(Fe.ADD_DIR,e,n),a.add(me.basename(e)),this.fsw._getWatchedDir(e);let u,f,m=this.fsw.options.depth;if((m==null||s<=m)&&!this.fsw._symlinkPaths.has(l)){if(!o&&(await this._handleRead(e,r,i,o,e,s,u),this.fsw.closed))return;f=this._watchWithNodeFs(e,(h,g)=>{g&&g.mtimeMs===0||this._handleRead(h,!1,i,o,e,s,u)})}return f}async _addToNodeFs(e,n,r,s,o){let i=this.fsw._emitReady;if(this.fsw._isIgnored(e)||this.fsw.closed)return i(),!1;let l=this.fsw._getWatchHelpers(e);r&&(l.filterPath=a=>r.filterPath(a),l.filterDir=a=>r.filterDir(a));try{let a=await Ia[l.statMethod](l.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(l.watchPath,a))return i(),!1;let c=this.fsw.options.followSymlinks,u;if(a.isDirectory()){let f=me.resolve(e),m=c?await sr(e):e;if(this.fsw.closed||(u=await this._handleDir(l.watchPath,a,n,s,o,l,m),this.fsw.closed))return;f!==m&&m!==void 0&&this.fsw._symlinkPaths.set(f,m)}else if(a.isSymbolicLink()){let f=c?await sr(e):e;if(this.fsw.closed)return;let m=me.dirname(l.watchPath);if(this.fsw._getWatchedDir(m).add(l.watchPath),this.fsw._emit(Fe.ADD,l.watchPath,a),u=await this._handleDir(m,a,n,s,e,l,f),this.fsw.closed)return;f!==void 0&&this.fsw._symlinkPaths.set(me.resolve(e),f)}else u=this._handleFile(l.watchPath,a,n);return i(),u&&this.fsw._addPathCloser(e,u),!1}catch(a){if(this.fsw._handleError(a))return i(),e}}};var cr="/",La="//",Gs=".",za="..",Ha="string",qa=/\\/g,Xs=/\/\//g,Ba=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,Wa=/^\.[/\\]/;function En(t){return Array.isArray(t)?t:[t]}var ur=t=>typeof t=="object"&&t!==null&&!(t instanceof RegExp);function Va(t){return typeof t=="function"?t:typeof t=="string"?e=>t===e:t instanceof RegExp?e=>t.test(e):typeof t=="object"&&t!==null?e=>{if(t.path===e)return!0;if(t.recursive){let n=re.relative(t.path,e);return n?!n.startsWith("..")&&!re.isAbsolute(n):!1}return!1}:()=>!1}function Ya(t){if(typeof t!="string")throw new Error("string expected");t=re.normalize(t),t=t.replace(/\\/g,"/");let e=!1;return t.startsWith("//")&&(e=!0),t=t.replace(Xs,"/"),e&&(t="/"+t),t}function Ws(t,e,n){let r=Ya(e);for(let s=0;s<t.length;s++){let o=t[s];if(o(r,n))return!0}return!1}function Ja(t,e){if(t==null)throw new TypeError("anymatch: specify first argument");let r=En(t).map(s=>Va(s));return e==null?(s,o)=>Ws(r,s,o):Ws(r,e)}var Vs=t=>{let e=En(t).flat();if(!e.every(n=>typeof n===Ha))throw new TypeError(`Non-string provided as watch path: ${e}`);return e.map(Ks)},Ys=t=>{let e=t.replace(qa,cr),n=!1;return e.startsWith(La)&&(n=!0),e=e.replace(Xs,cr),n&&(e=cr+e),e},Ks=t=>Ys(re.normalize(Ys(t))),Js=(t="")=>e=>typeof e=="string"?Ks(re.isAbsolute(e)?e:re.join(t,e)):e,Ga=(t,e)=>re.isAbsolute(t)?t:re.join(e,t),Xa=Object.freeze(new Set),dr=class{path;_removeWatcher;items;constructor(e,n){this.path=e,this._removeWatcher=n,this.items=new Set}add(e){let{items:n}=this;n&&e!==Gs&&e!==za&&n.add(e)}async remove(e){let{items:n}=this;if(!n||(n.delete(e),n.size>0))return;let r=this.path;try{await Ua(r)}catch{this._removeWatcher&&this._removeWatcher(re.dirname(r),re.basename(r))}}has(e){let{items:n}=this;if(n)return n.has(e)}getChildren(){let{items:e}=this;return e?[...e.values()]:[]}dispose(){this.items.clear(),this.path="",this._removeWatcher=vn,this.items=Xa,Object.freeze(this)}},Ka="stat",Za="lstat",fr=class{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(e,n,r){this.fsw=r;let s=e;this.path=e=e.replace(Wa,""),this.watchPath=s,this.fullWatchPath=re.resolve(s),this.dirParts=[],this.dirParts.forEach(o=>{o.length>1&&o.pop()}),this.followSymlinks=n,this.statMethod=n?Ka:Za}entryPath(e){return re.join(this.watchPath,re.relative(this.watchPath,e.fullPath))}filterPath(e){let{stats:n}=e;if(n&&n.isSymbolicLink())return this.filterDir(e);let r=this.entryPath(e);return this.fsw._isntIgnored(r,n)&&this.fsw._hasReadPermissions(n)}filterDir(e){return this.fsw._isntIgnored(this.entryPath(e),e.stats)}},_n=class extends Na{closed;options;_closers;_ignoredPaths;_throttled;_streams;_symlinkPaths;_watched;_pendingWrites;_pendingUnlinks;_readyCount;_emitReady;_closePromise;_userIgnored;_readyEmitted;_emitRaw;_boundRemove;_nodeFsHandler;constructor(e={}){super(),this.closed=!1,this._closers=new Map,this._ignoredPaths=new Set,this._throttled=new Map,this._streams=new Set,this._symlinkPaths=new Map,this._watched=new Map,this._pendingWrites=new Map,this._pendingUnlinks=new Map,this._readyCount=0,this._readyEmitted=!1;let n=e.awaitWriteFinish,r={stabilityThreshold:2e3,pollInterval:100},s={persistent:!0,ignoreInitial:!1,ignorePermissionErrors:!1,interval:100,binaryInterval:300,followSymlinks:!0,usePolling:!1,atomic:!0,...e,ignored:e.ignored?En(e.ignored):En([]),awaitWriteFinish:n===!0?r:typeof n=="object"?{...r,...n}:!1};qs&&(s.usePolling=!0),s.atomic===void 0&&(s.atomic=!s.usePolling);let o=process.env.CHOKIDAR_USEPOLLING;if(o!==void 0){let a=o.toLowerCase();a==="false"||a==="0"?s.usePolling=!1:a==="true"||a==="1"?s.usePolling=!0:s.usePolling=!!a}let i=process.env.CHOKIDAR_INTERVAL;i&&(s.interval=Number.parseInt(i,10));let l=0;this._emitReady=()=>{l++,l>=this._readyCount&&(this._emitReady=vn,this._readyEmitted=!0,process.nextTick(()=>this.emit(ge.READY)))},this._emitRaw=(...a)=>this.emit(ge.RAW,...a),this._boundRemove=this._remove.bind(this),this.options=s,this._nodeFsHandler=new Sn(this),Object.freeze(s)}_addIgnoredPath(e){if(ur(e)){for(let n of this._ignoredPaths)if(ur(n)&&n.path===e.path&&n.recursive===e.recursive)return}this._ignoredPaths.add(e)}_removeIgnoredPath(e){if(this._ignoredPaths.delete(e),typeof e=="string")for(let n of this._ignoredPaths)ur(n)&&n.path===e&&this._ignoredPaths.delete(n)}add(e,n,r){let{cwd:s}=this.options;this.closed=!1,this._closePromise=void 0;let o=Vs(e);return s&&(o=o.map(i=>Ga(i,s))),o.forEach(i=>{this._removeIgnoredPath(i)}),this._userIgnored=void 0,this._readyCount||(this._readyCount=0),this._readyCount+=o.length,Promise.all(o.map(async i=>{let l=await this._nodeFsHandler._addToNodeFs(i,!r,void 0,0,n);return l&&this._emitReady(),l})).then(i=>{this.closed||i.forEach(l=>{l&&this.add(re.dirname(l),re.basename(n||l))})}),this}unwatch(e){if(this.closed)return this;let n=Vs(e),{cwd:r}=this.options;return n.forEach(s=>{!re.isAbsolute(s)&&!this._closers.has(s)&&(r&&(s=re.join(r,s)),s=re.resolve(s)),this._closePath(s),this._addIgnoredPath(s),this._watched.has(s)&&this._addIgnoredPath({path:s,recursive:!0}),this._userIgnored=void 0}),this}close(){if(this._closePromise)return this._closePromise;this.closed=!0,this.removeAllListeners();let e=[];return this._closers.forEach(n=>n.forEach(r=>{let s=r();s instanceof Promise&&e.push(s)})),this._streams.forEach(n=>n.destroy()),this._userIgnored=void 0,this._readyCount=0,this._readyEmitted=!1,this._watched.forEach(n=>n.dispose()),this._closers.clear(),this._watched.clear(),this._streams.clear(),this._symlinkPaths.clear(),this._throttled.clear(),this._closePromise=e.length?Promise.all(e).then(()=>{}):Promise.resolve(),this._closePromise}getWatched(){let e={};return this._watched.forEach((n,r)=>{let o=(this.options.cwd?re.relative(this.options.cwd,r):r)||Gs;e[o]=n.getChildren().sort()}),e}emitWithAll(e,n){this.emit(e,...n),e!==ge.ERROR&&this.emit(ge.ALL,e,...n)}async _emit(e,n,r){if(this.closed)return;let s=this.options;lr&&(n=re.normalize(n)),s.cwd&&(n=re.relative(s.cwd,n));let o=[n];r!=null&&o.push(r);let i=s.awaitWriteFinish,l;if(i&&(l=this._pendingWrites.get(n)))return l.lastChange=new Date,this;if(s.atomic){if(e===ge.UNLINK)return this._pendingUnlinks.set(n,[e,...o]),setTimeout(()=>{this._pendingUnlinks.forEach((a,c)=>{this.emit(...a),this.emit(ge.ALL,...a),this._pendingUnlinks.delete(c)})},typeof s.atomic=="number"?s.atomic:100),this;e===ge.ADD&&this._pendingUnlinks.has(n)&&(e=ge.CHANGE,this._pendingUnlinks.delete(n))}if(i&&(e===ge.ADD||e===ge.CHANGE)&&this._readyEmitted){let a=(c,u)=>{c?(e=ge.ERROR,o[0]=c,this.emitWithAll(e,o)):u&&(o.length>1?o[1]=u:o.push(u),this.emitWithAll(e,o))};return this._awaitWriteFinish(n,i.stabilityThreshold,e,a),this}if(e===ge.CHANGE&&!this._throttle(ge.CHANGE,n,50))return this;if(s.alwaysStat&&r===void 0&&(e===ge.ADD||e===ge.ADD_DIR||e===ge.CHANGE)){let a=s.cwd?re.join(s.cwd,n):n,c;try{c=await Fa(a)}catch{}if(!c||this.closed)return;o.push(c)}return this.emitWithAll(e,o),this}_handleError(e){let n=e&&e.code;return e&&n!=="ENOENT"&&n!=="ENOTDIR"&&(!this.options.ignorePermissionErrors||n!=="EPERM"&&n!=="EACCES")&&this.emit(ge.ERROR,e),e||this.closed}_throttle(e,n,r){this._throttled.has(e)||this._throttled.set(e,new Map);let s=this._throttled.get(e);if(!s)throw new Error("invalid throttle");let o=s.get(n);if(o)return o.count++,!1;let i,l=()=>{let c=s.get(n),u=c?c.count:0;return s.delete(n),clearTimeout(i),c&&clearTimeout(c.timeoutObject),u};i=setTimeout(l,r);let a={timeoutObject:i,clear:l,count:0};return s.set(n,a),a}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(e,n,r,s){let o=this.options.awaitWriteFinish;if(typeof o!="object")return;let i=o.pollInterval,l,a=e;this.options.cwd&&!re.isAbsolute(e)&&(a=re.join(this.options.cwd,e));let c=new Date,u=this._pendingWrites;function f(m){ja(a,(h,g)=>{if(h||!u.has(e)){h&&h.code!=="ENOENT"&&s(h);return}let p=Number(new Date);m&&g.size!==m.size&&(u.get(e).lastChange=p);let y=u.get(e);p-y.lastChange>=n?(u.delete(e),s(void 0,g)):l=setTimeout(f,i,g)})}u.has(e)||(u.set(e,{lastChange:c,cancelWait:()=>(u.delete(e),clearTimeout(l),r)}),l=setTimeout(f,i))}_isIgnored(e,n){if(this.options.atomic&&Ba.test(e))return!0;if(!this._userIgnored){let{cwd:r}=this.options,o=(this.options.ignored||[]).map(Js(r)),l=[...[...this._ignoredPaths].map(Js(r)),...o];this._userIgnored=Ja(l,void 0)}return this._userIgnored(e,n)}_isntIgnored(e,n){return!this._isIgnored(e,n)}_getWatchHelpers(e){return new fr(e,this.options.followSymlinks,this)}_getWatchedDir(e){let n=re.resolve(e);return this._watched.has(n)||this._watched.set(n,new dr(n,this._boundRemove)),this._watched.get(n)}_hasReadPermissions(e){return this.options.ignorePermissionErrors?!0:!!(Number(e.mode)&256)}_remove(e,n,r){let s=re.join(e,n),o=re.resolve(s);if(r=r??(this._watched.has(s)||this._watched.has(o)),!this._throttle("remove",s,100))return;!r&&this._watched.size===1&&this.add(e,n,!0),this._getWatchedDir(s).getChildren().forEach(m=>this._remove(s,m));let a=this._getWatchedDir(e),c=a.has(n);a.remove(n),this._symlinkPaths.has(o)&&this._symlinkPaths.delete(o);let u=s;if(this.options.cwd&&(u=re.relative(this.options.cwd,s)),this.options.awaitWriteFinish&&this._pendingWrites.has(u)&&this._pendingWrites.get(u).cancelWait()===ge.ADD)return;this._watched.delete(s),this._watched.delete(o);let f=r?ge.UNLINK_DIR:ge.UNLINK;c&&!this._isIgnored(s)&&this._emit(f,s),this._closePath(s)}_closePath(e){this._closeFile(e);let n=re.dirname(e);this._getWatchedDir(n).remove(re.basename(e))}_closeFile(e){let n=this._closers.get(e);n&&(n.forEach(r=>r()),this._closers.delete(e))}_addPathCloser(e,n){if(!n)return;let r=this._closers.get(e);r||(r=[],this._closers.set(e,r)),r.push(n)}_readdirp(e,n){if(this.closed)return;let r={type:ge.ALL,alwaysStat:!0,lstat:!0,...n,depth:0},s=Us(e,r);return this._streams.add(s),s.once(Hs,()=>{s=void 0}),s.once(ar,()=>{s&&(this._streams.delete(s),s=void 0)}),s}};function hr(t,e={}){let n=new _n(e);return n.add(t),n}var Zs={watch:hr,FSWatcher:_n};var Qs={fs:tl,path:nl,sha256Hex:t=>Qa("sha256").update(t).digest("hex"),tmpTag:()=>process.pid,existsSync:el,watch(t,e,n){let r=Zs.watch(t,{ignoreInitial:!0,depth:e.depth,ignored:e.ignored});return r.on("change",n.change),r.on("add",n.add),r.on("unlink",n.unlink),r.on("unlinkDir",n.unlinkDir),r}};import{readdirSync as rl,lstatSync as sl,readFileSync as pr,writeFileSync as ol,realpathSync as eo}from"node:fs";import{join as gr,extname as il,sep as al}from"node:path";var mr=300,to=5*1024*1024,no=20*1024*1024,ll=50*1024*1024,cl=new Set(["node_modules"]),ul=new Set([".ts",".tsx",".jsx",".mts",".cts"]);function ro(t,e){let n=[],r=0,s=(o,i)=>{for(let l of rl(o)){if(l.startsWith("."))continue;let a=gr(o,l),c;try{c=sl(a)}catch{continue}if(c.isSymbolicLink())continue;let u=i?`${i}/${l}`:l;if(c.isDirectory()){cl.has(l)||s(a,u);continue}if(!c.isFile()||l.endsWith(".d.ts"))continue;if(n.length>=mr)throw new Error(`\u6587\u4EF6\u6570\u8D85\u8FC7 ${mr}\uFF0C\u8BF7\u7CBE\u7B80\u9879\u76EE\uFF08node_modules \u4E0E\u9690\u85CF\u6587\u4EF6\u5DF2\u81EA\u52A8\u8DF3\u8FC7\uFF09`);let f=il(l).toLowerCase(),m,h=e.mimeOf(f)??"application/octet-stream";if(ul.has(f)){let g=e.transpile(pr(a,"utf8"),f,u);m=Buffer.from(g??"","utf8"),h="text/javascript"}else m=pr(a);if(m.length>to)throw new Error(`\u5355\u6587\u4EF6\u8D85\u8FC7 5MB\uFF1A${u}`);if(r+=m.length,r>no)throw new Error("\u9879\u76EE\u603B\u5927\u5C0F\u8D85\u8FC7 20MB\uFF0C\u65E0\u6CD5\u53D1\u5E03");n.push({path:u,content_b64:m.toString("base64"),content_type:h,size:m.length})}};if(s(t,""),!n.length)throw new Error("\u9879\u76EE\u4E3A\u7A7A\uFF0C\u6CA1\u6709\u53EF\u53D1\u5E03\u7684\u6587\u4EF6");return{files:n,totalBytes:r}}var so=".forsion-connect.json";function oo(t){try{return JSON.parse(pr(gr(t,so),"utf8"))}catch{return{}}}function io(t,e){try{ol(gr(t,so),JSON.stringify(e,null,2)+`
2
+ `,"utf8")}catch{}}function ao(t){let e={"/__forsion/chat":{method:"POST",path:"/api/chat/completions",auth:!0},"/__forsion/images":{method:"POST",path:"/api/images/generations",auth:!0},"/__forsion/user":{method:"GET",path:"/api/brain/users/me",auth:!0},"/__forsion/models":{method:"GET",path:"/api/models",auth:!1},"/__forsion/config":{method:"GET",path:"/api/connect/config",auth:!1},"/__forsion/agent":{method:"POST",path:"/api/agent/runs",auth:!0,agentRun:!0}};function n(r){if(e[r])return e[r];let s="/__forsion/agent-events/";if(r.startsWith(s)){let o=r.slice(s.length);if(/^[A-Za-z0-9-]{1,64}$/.test(o))return{method:"GET",path:`/api/agent/runs/${o}/events`,auth:!0,timeoutMs:9e5}}}return async(r,s)=>{let[o,i]=(r.url||"").split("?"),l=(g,p)=>{s.headersSent||(s.statusCode=g,s.setHeader("Content-Type","application/json")),s.end(JSON.stringify({detail:p}))},a=n(o);if(!a)return l(404,"unknown connect endpoint");if((r.method||"GET")!==a.method)return l(405,"method not allowed");let c="",u="";try{({base:c,token:u}=await t())}catch{}if(!c)return l(502,"\u672A\u914D\u7F6E Forsion \u4E91\u7AEF\u5730\u5740");if(a.auth&&!u)return l(401,"\u8BF7\u5148\u5728 Forsion Desktop \u4E2D\u767B\u5F55 Forsion \u8D26\u53F7");let f;if(a.method==="POST"){let g=[],p=0;try{for await(let y of r){if(p+=y.length,p>ll)return r.destroy(),l(413,"\u8BF7\u6C42\u4F53\u8FC7\u5927");g.push(y)}}catch(y){return l(400,`\u8BF7\u6C42\u4F53\u8BFB\u53D6\u5931\u8D25\uFF1A${y?.message||String(y)}`)}f=Buffer.concat(g)}if(a.agentRun){let g;try{g=JSON.parse((f||Buffer.alloc(0)).toString("utf8")||"{}")}catch{return l(400,"agent \u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON")}f=Buffer.from(JSON.stringify({session_id:typeof g.session_id=="string"?g.session_id:"",message:typeof g.message=="string"?g.message:"",app_id:"connect",agent_config:{}}))}let m=new AbortController,h=setTimeout(()=>m.abort(new Error("proxy timeout")),a.timeoutMs??3e5);r.on("close",()=>m.abort());try{let g=await fetch(c+a.path+(i?`?${i}`:""),{method:a.method,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...u?{Authorization:`Bearer ${u}`}:{}},body:f&&f.length?new Uint8Array(f):void 0,signal:m.signal});if(s.statusCode=g.status,s.setHeader("Content-Type",g.headers.get("content-type")||"application/json"),s.setHeader("Cache-Control","no-store"),g.body)for await(let p of g.body)s.write(p);s.end()}catch(g){let p=`\u4E91\u7AEF\u8BF7\u6C42\u4E2D\u65AD\uFF1A${g?.message||String(g)}`;if(s.headersSent){try{s.write(`data: ${JSON.stringify({error:p})}
3
3
 
4
- `)}catch{}s.end()}else l(502,f)}finally{clearTimeout(p)}}}var xs=`
4
+ `)}catch{}s.end()}else l(502,p)}finally{clearTimeout(h)}}}var lo=`
5
5
  (function () {
6
6
  'use strict';
7
7
  if (window.forsion) return;
@@ -190,7 +190,7 @@ var $n=null;function Lr(t){$n=t}function Se(){if(!$n)throw new Error("core host
190
190
  ai: { chat: chat, agent: agentRun, generateImage: generateImage }
191
191
  };
192
192
  })();
193
- `,da=t=>({transpile:(e,n,r)=>t.transpileForServe(e,n,r),mimeOf:e=>t.mimeOf(e)});function Gn(t){let e=t;return typeof e.projectsRoot=="function"&&typeof e.transpileForServe=="function"&&typeof e.mimeOf=="function"&&typeof e.setPreviewHooks=="function"}function Jn(t){t.setPreviewHooks({sdkJs:xs,proxy:vs(()=>t.getCloud())}),t.handle("connect:meta",(e,n)=>typeof n=="string"&&n?Es(n):{}),t.handle("connect:list",async()=>{let e=await t.getCloud();if(!e.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:n,json:r}=await Ae(e,"GET","/api/connect/apps");return n===401||n===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:n!==200?{ok:!1,code:"error",detail:r?.detail||`HTTP ${n}`}:{ok:!0,base:e.base,...r}}catch(n){return{ok:!1,code:"error",detail:n?.message||String(n)}}}),t.handle("connect:publish",async(e,n)=>{if(!n||typeof n.dir!="string"||!n.dir||!n.name||!n.slug||!n.entry)return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r;try{let o=ys(t.projectsRoot());if(r=ys(n.dir),r!==o&&!r.startsWith(o+aa))return{ok:!1,code:"error",detail:"\u53EA\u80FD\u53D1\u5E03 Coding Space \u9879\u76EE\u76EE\u5F55"}}catch{return{ok:!1,code:"error",detail:"\u9879\u76EE\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u8BBF\u95EE"}}let s=await t.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{files:o,totalBytes:i}=Ss(r,da(t));if(!o.some(d=>d.path===n.entry))return{ok:!1,code:"error",detail:`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728:${n.entry}`};let{status:l,json:a}=await Ae(s,"POST","/api/connect/apps",{slug:n.slug,name:n.name,entry:n.entry,files:o},3e5);return l===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:l!==200?{ok:!1,code:a?.code||"error",detail:a?.detail||`HTTP ${l}`,used:a?.used,limit:a?.limit}:(_s(r,{slug:String(a.slug)}),{ok:!0,slug:a.slug,handle:a.handle,url:`${s.base}${a.url}`,totalBytes:i})}catch(o){return{ok:!1,code:"error",detail:o?.message||String(o)}}}),t.handle("connect:unpublish",async(e,n)=>{if(!n||typeof n!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:s,json:o}=await Ae(r,"DELETE",`/api/connect/apps/${encodeURIComponent(n)}`);return s===401||s===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:s!==200&&s!==404?{ok:!1,code:"error",detail:o?.detail||`HTTP ${s}`}:{ok:!0}}catch(s){return{ok:!1,code:"error",detail:s?.message||String(s)}}}),t.handle("connect:listingApply",async(e,n)=>{if(!n||typeof n.slug!="string"||!n.slug||typeof n.summary!="string"||!n.summary.trim())return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:s,json:o}=await Ae(r,"PUT",`/api/connect/apps/${encodeURIComponent(n.slug)}/listing`,{summary:n.summary});return s===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:s!==200?{ok:!1,code:o?.code||"error",detail:o?.detail||`HTTP ${s}`}:{ok:!0,status:o.status}}catch(s){return{ok:!1,code:"error",detail:s?.message||String(s)}}}),t.handle("connect:listingWithdraw",async(e,n)=>{if(!n||typeof n!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:s,json:o}=await Ae(r,"DELETE",`/api/connect/apps/${encodeURIComponent(n)}/listing`);return s===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:s!==200&&s!==404?{ok:!1,code:"error",detail:o?.detail||`HTTP ${s}`}:{ok:!0}}catch(s){return{ok:!1,code:"error",detail:s?.message||String(s)}}}),t.handle("connect:store",async()=>{let e=await t.getCloud();try{let{status:n,json:r}=await Ae(e,"GET","/api/connect/store");return n!==200?{ok:!1,detail:r?.detail||`HTTP ${n}`}:{ok:!0,base:e.base,items:Array.isArray(r.items)?r.items:[]}}catch(n){return{ok:!1,detail:n?.message||String(n)}}}),t.log("[forsion-extend] connect handlers registered")}import{createHash as fa}from"node:crypto";import{hostname as ma}from"node:os";async function At(t,e){if(!t||!e)return{status:"offline"};let n=t.replace(/\/+$/,"");try{let r=await fetch(`${n}/api/brain/users/me`,{headers:{Authorization:`Bearer ${e}`},signal:AbortSignal.timeout(5e3)});if(r.status===401||r.status===403)return{status:(r.headers.get("content-type")||"").includes("application/json")?"expired":"offline"};if(!r.ok)return{status:"offline"};let s=await r.json();if(!s)return{status:"offline"};let o=s.avatar||s.avatarUrl||s.avatar_url||void 0;return o&&/^\/(?!\/)/.test(o)&&(o=n+o),{status:"ok",user:{username:s.username||s.nickname||void 0,nickname:s.nickname||void 0,avatar:o,membershipTier:s.membershipTier||s.membership_tier||void 0}}}catch{return{status:"offline"}}}var Cs=t=>`${t.seq}:${t.hash}`,un=(t=ma())=>{let e=t.replace(/\.local$/i,"").trim();return e?encodeURIComponent(e):null},pa=t=>fa("sha256").update(t).digest("hex");function Xn(t){if(t===null)return{baseSeq:0,baseHash:null};if(typeof t!="string")return;let e=t.indexOf(":"),n=Number(e===-1?t:t.slice(0,e));if(!Number.isInteger(n)||n<=0)return;let r=e===-1?"":t.slice(e+1);return{baseSeq:n,baseHash:/^[0-9a-f]{64}$/.test(r)?r:null}}function dn(t){let e=t.baseUrl.replace(/\/+$/,""),n=o=>`${e}/api/remotesync/vaults/${encodeURIComponent(t.vault)}${o}`,r=un(),s=async(o,i)=>{let l=t.getToken();if(!l)throw new Error("penzor-not-logged-in");let a=await fetch(o,{...i,headers:{...i.headers,Authorization:`Bearer ${l}`}});if(a.status===409){let d=await a.json().catch(()=>({}));throw new Error(`cas-conflict ${String(d.code??"")}: seq=${String(d.seq??"?")}`)}if(!a.ok){let d=await a.text().catch(()=>"");throw new Error(`penzor ${i.method??"GET"} ${a.status}: ${d.slice(0,200)}`)}return a};return{kind:"penzor",async walk(o){let i=await s(n("/manifest"),{method:"GET",signal:o}),{files:l}=await i.json();return l.map(a=>({key:a.path,size:a.size,mtimeMs:a.mtimeMs,id:Cs(a),hash:a.hash}))},async readFile(o,i){let a=await(await s(n(`/file?path=${encodeURIComponent(o)}`),{method:"GET",signal:i})).json(),d=await fetch(a.url,{signal:i});if(!d.ok)throw new Error(`penzor blob GET ${d.status}: ${o}`);let u=Buffer.from(await d.arrayBuffer());if(pa(u)!==a.hash)throw new Error(`penzor hash mismatch: ${o}`);return u},async writeFile(o,i,l,a,d){let u=Xn(d),m=new URLSearchParams({path:o,mtimeMs:String(Math.floor(l)||0)});u&&(m.set("baseSeq",String(u.baseSeq)),u.baseHash&&m.set("baseHash",u.baseHash));let p=await(await s(n(`/file?${m.toString()}`),{method:"PUT",body:new Uint8Array(i),headers:{"Content-Type":"application/octet-stream",...r?{"X-Forsion-Device":r}:{}},signal:a})).json();return{key:o,size:p.size,mtimeMs:p.mtimeMs,id:Cs(p)}},async rm(o,i,l){let a=Xn(l),d=new URLSearchParams({path:o});a&&a.baseSeq>0&&(d.set("baseSeq",String(a.baseSeq)),a.baseHash&&d.set("baseHash",a.baseHash)),await s(n(`/file?${d.toString()}`),{method:"DELETE",signal:i})},async check(){try{return await s(n("/manifest"),{method:"GET"}),{ok:!0}}catch(o){return{ok:!1,error:String(o?.message||o)}}}}}var fn="forsion-diagnostics",As=50*1024*1024,Ts=new Map;async function ga(t,e){let n=Ts.get(e);if(n)return{id:n};let r=await At(t,e);if(r.status==="offline")return{error:"penzor-offline"};if(r.status!=="ok")return{error:"penzor-not-logged-in"};let s=r.user?.username?.trim();return s?(Ts.set(e,s),{id:s}):{error:"penzor-auth-unverified"}}var Kn=t=>typeof t.registerRemoteSyncBackend=="function"&&typeof t.readCreds=="function";function Zn(t){t.registerRemoteSyncBackend("penzor",async e=>{let n=t.readCreds();if(!n.token||!n.cloudUrl)return{error:"penzor-not-logged-in"};let r=e?.vault,s=(typeof r=="string"?r:"default").trim()||"default";if(!/^[A-Za-z0-9_-]{1,64}$/.test(s)||s===fn)return{error:"penzor-bad-vault"};let o=await ga(n.cloudUrl,n.token);if("error"in o)return o;let i=n.token;return{remote:dn({baseUrl:n.cloudUrl,vault:s,getToken:()=>i}),fingerprint:`penzor:${n.cloudUrl.replace(/\/+$/,"")}|u:${o.id}|${s}`,maxFileBytes:As}}),t.log('[forsion-extend] remote-sync backend "penzor" registered')}import{createReadStream as ya}from"node:fs";import{access as wa,link as ba,lstat as Sa,mkdir as ka,open as Ea,readdir as _a,rename as va,stat as Os,unlink as tr}from"node:fs/promises";import{request as xa}from"node:http";import{request as Ca}from"node:https";import{homedir as Ta}from"node:os";import{basename as Ns,extname as Aa,isAbsolute as Ia,join as Rt}from"node:path";import{randomUUID as pn}from"node:crypto";var It=52428800;var Is=["bytes","signed","text"],Rs=/^[A-Za-z0-9_-]{1,64}$/,Ds=/^[a-z0-9][a-z0-9-]{0,63}$/;function mn(t){if(typeof t!="string")return null;let n=(t.split(/[\\/]/).pop()??"").replace(/[\u0000-\u001f<>:"|?*]/g,"").trim().slice(0,200);return n&&n!=="."&&n!==".."?n:null}var ha={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".heic":"image/heic",".svg":"image/svg+xml",".pdf":"application/pdf",".txt":"text/plain",".md":"text/markdown",".json":"application/json",".csv":"text/csv",".mp4":"video/mp4",".mov":"video/quicktime",".mp3":"audio/mpeg",".zip":"application/zip",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation"};function Ps(t){let e=t.lastIndexOf(".");return ha[e>0?t.slice(e).toLowerCase():""]??"application/octet-stream"}function $s(t,e,n,r){let s=n.replace(/[^\x20-\x7e]/g,"_").replace(/["\\]/g,"_")||"file",o=encodeURIComponent(n).replace(/['()*]/g,l=>`%${l.charCodeAt(0).toString(16).toUpperCase()}`),i="";for(let[l,a]of Object.entries(e))i+=`--${t}\r
193
+ `,dl=t=>({transpile:(e,n,r)=>t.transpileForServe(e,n,r),mimeOf:e=>t.mimeOf(e)});function yr(t){let e=t;return typeof e.projectsRoot=="function"&&typeof e.transpileForServe=="function"&&typeof e.mimeOf=="function"&&typeof e.setPreviewHooks=="function"}function wr(t){t.setPreviewHooks({sdkJs:lo,proxy:ao(()=>t.getCloud())}),t.handle("connect:meta",(e,n)=>typeof n=="string"&&n?oo(n):{}),t.handle("connect:list",async()=>{let e=await t.getCloud();if(!e.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:n,json:r}=await Ae(e,"GET","/api/connect/apps");return n===401||n===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:n!==200?{ok:!1,code:"error",detail:r?.detail||`HTTP ${n}`}:{ok:!0,base:e.base,...r}}catch(n){return{ok:!1,code:"error",detail:n?.message||String(n)}}}),t.handle("connect:publish",async(e,n)=>{if(!n||typeof n.dir!="string"||!n.dir||!n.name||!n.slug||!n.entry)return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r;try{let o=eo(t.projectsRoot());if(r=eo(n.dir),r!==o&&!r.startsWith(o+al))return{ok:!1,code:"error",detail:"\u53EA\u80FD\u53D1\u5E03 Coding Space \u9879\u76EE\u76EE\u5F55"}}catch{return{ok:!1,code:"error",detail:"\u9879\u76EE\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u8BBF\u95EE"}}let s=await t.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{files:o,totalBytes:i}=ro(r,dl(t));if(!o.some(c=>c.path===n.entry))return{ok:!1,code:"error",detail:`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728:${n.entry}`};let{status:l,json:a}=await Ae(s,"POST","/api/connect/apps",{slug:n.slug,name:n.name,entry:n.entry,files:o},3e5);return l===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:l!==200?{ok:!1,code:a?.code||"error",detail:a?.detail||`HTTP ${l}`,used:a?.used,limit:a?.limit}:(io(r,{slug:String(a.slug)}),{ok:!0,slug:a.slug,handle:a.handle,url:`${s.base}${a.url}`,totalBytes:i})}catch(o){return{ok:!1,code:"error",detail:o?.message||String(o)}}}),t.handle("connect:unpublish",async(e,n)=>{if(!n||typeof n!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:s,json:o}=await Ae(r,"DELETE",`/api/connect/apps/${encodeURIComponent(n)}`);return s===401||s===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:s!==200&&s!==404?{ok:!1,code:"error",detail:o?.detail||`HTTP ${s}`}:{ok:!0}}catch(s){return{ok:!1,code:"error",detail:s?.message||String(s)}}}),t.handle("connect:listingApply",async(e,n)=>{if(!n||typeof n.slug!="string"||!n.slug||typeof n.summary!="string"||!n.summary.trim())return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:s,json:o}=await Ae(r,"PUT",`/api/connect/apps/${encodeURIComponent(n.slug)}/listing`,{summary:n.summary});return s===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:s!==200?{ok:!1,code:o?.code||"error",detail:o?.detail||`HTTP ${s}`}:{ok:!0,status:o.status}}catch(s){return{ok:!1,code:"error",detail:s?.message||String(s)}}}),t.handle("connect:listingWithdraw",async(e,n)=>{if(!n||typeof n!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:s,json:o}=await Ae(r,"DELETE",`/api/connect/apps/${encodeURIComponent(n)}/listing`);return s===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:s!==200&&s!==404?{ok:!1,code:"error",detail:o?.detail||`HTTP ${s}`}:{ok:!0}}catch(s){return{ok:!1,code:"error",detail:s?.message||String(s)}}}),t.handle("connect:store",async()=>{let e=await t.getCloud();try{let{status:n,json:r}=await Ae(e,"GET","/api/connect/store");return n!==200?{ok:!1,detail:r?.detail||`HTTP ${n}`}:{ok:!0,base:e.base,items:Array.isArray(r.items)?r.items:[]}}catch(n){return{ok:!1,detail:n?.message||String(n)}}}),t.log("[forsion-extend] connect handlers registered")}import{createHash as fl}from"node:crypto";import{hostname as hl}from"node:os";async function Lt(t,e){if(!t||!e)return{status:"offline"};let n=t.replace(/\/+$/,"");try{let r=await fetch(`${n}/api/brain/users/me`,{headers:{Authorization:`Bearer ${e}`},signal:AbortSignal.timeout(5e3)});if(r.status===401||r.status===403)return{status:(r.headers.get("content-type")||"").includes("application/json")?"expired":"offline"};if(!r.ok)return{status:"offline"};let s=await r.json();if(!s)return{status:"offline"};let o=s.avatar||s.avatarUrl||s.avatar_url||void 0;return o&&/^\/(?!\/)/.test(o)&&(o=n+o),{status:"ok",user:{username:s.username||s.nickname||void 0,nickname:s.nickname||void 0,avatar:o,membershipTier:s.membershipTier||s.membership_tier||void 0}}}catch{return{status:"offline"}}}var co=t=>`${t.seq}:${t.hash}`,Cn=(t=hl())=>{let e=t.replace(/\.local$/i,"").trim();return e?encodeURIComponent(e):null},pl=t=>fl("sha256").update(t).digest("hex");function br(t){if(t===null)return{baseSeq:0,baseHash:null};if(typeof t!="string")return;let e=t.indexOf(":"),n=Number(e===-1?t:t.slice(0,e));if(!Number.isInteger(n)||n<=0)return;let r=e===-1?"":t.slice(e+1);return{baseSeq:n,baseHash:/^[0-9a-f]{64}$/.test(r)?r:null}}function xn(t){let e=t.baseUrl.replace(/\/+$/,""),n=o=>`${e}/api/remotesync/vaults/${encodeURIComponent(t.vault)}${o}`,r=Cn(),s=async(o,i)=>{let l=t.getToken();if(!l)throw new Error("penzor-not-logged-in");let a=await fetch(o,{...i,headers:{...i.headers,Authorization:`Bearer ${l}`}});if(a.status===409){let c=await a.json().catch(()=>({}));throw new Error(`cas-conflict ${String(c.code??"")}: seq=${String(c.seq??"?")}`)}if(!a.ok){let c=await a.text().catch(()=>"");throw new Error(`penzor ${i.method??"GET"} ${a.status}: ${c.slice(0,200)}`)}return a};return{kind:"penzor",async walk(o){let i=await s(n("/manifest"),{method:"GET",signal:o}),{files:l}=await i.json();return l.map(a=>({key:a.path,size:a.size,mtimeMs:a.mtimeMs,id:co(a),hash:a.hash}))},async readFile(o,i){let a=await(await s(n(`/file?path=${encodeURIComponent(o)}`),{method:"GET",signal:i})).json(),c=await fetch(a.url,{signal:i});if(!c.ok)throw new Error(`penzor blob GET ${c.status}: ${o}`);let u=Buffer.from(await c.arrayBuffer());if(pl(u)!==a.hash)throw new Error(`penzor hash mismatch: ${o}`);return u},async writeFile(o,i,l,a,c){let u=br(c),f=new URLSearchParams({path:o,mtimeMs:String(Math.floor(l)||0)});u&&(f.set("baseSeq",String(u.baseSeq)),u.baseHash&&f.set("baseHash",u.baseHash));let h=await(await s(n(`/file?${f.toString()}`),{method:"PUT",body:new Uint8Array(i),headers:{"Content-Type":"application/octet-stream",...r?{"X-Forsion-Device":r}:{}},signal:a})).json();return{key:o,size:h.size,mtimeMs:h.mtimeMs,id:co(h)}},async rm(o,i,l){let a=br(l),c=new URLSearchParams({path:o});a&&a.baseSeq>0&&(c.set("baseSeq",String(a.baseSeq)),a.baseHash&&c.set("baseHash",a.baseHash)),await s(n(`/file?${c.toString()}`),{method:"DELETE",signal:i})},async check(){try{return await s(n("/manifest"),{method:"GET"}),{ok:!0}}catch(o){return{ok:!1,error:String(o?.message||o)}}}}}var Tn="forsion-diagnostics",fo=50*1024*1024,uo=new Map;async function ml(t,e){let n=uo.get(e);if(n)return{id:n};let r=await Lt(t,e);if(r.status==="offline")return{error:"penzor-offline"};if(r.status!=="ok")return{error:"penzor-not-logged-in"};let s=r.user?.username?.trim();return s?(uo.set(e,s),{id:s}):{error:"penzor-auth-unverified"}}var Sr=t=>typeof t.registerRemoteSyncBackend=="function"&&typeof t.readCreds=="function";function vr(t){t.registerRemoteSyncBackend("penzor",async e=>{let n=t.readCreds();if(!n.token||!n.cloudUrl)return{error:"penzor-not-logged-in"};let r=e?.vault,s=(typeof r=="string"?r:"default").trim()||"default";if(!/^[A-Za-z0-9_-]{1,64}$/.test(s)||s===Tn)return{error:"penzor-bad-vault"};let o=await ml(n.cloudUrl,n.token);if("error"in o)return o;let i=n.token;return{remote:xn({baseUrl:n.cloudUrl,vault:s,getToken:()=>i}),fingerprint:`penzor:${n.cloudUrl.replace(/\/+$/,"")}|u:${o.id}|${s}`,maxFileBytes:fo}}),t.log('[forsion-extend] remote-sync backend "penzor" registered')}import{createReadStream as yl}from"node:fs";import{access as wl,link as bl,lstat as Sl,mkdir as vl,open as kl,readdir as El,rename as _l,stat as bo,unlink as _r}from"node:fs/promises";import{request as Cl}from"node:http";import{request as xl}from"node:https";import{homedir as Tl}from"node:os";import{basename as So,extname as Al,isAbsolute as Il,join as Ht}from"node:path";import{randomUUID as In}from"node:crypto";var zt=52428800;var ho=["bytes","signed","text"],po=/^[A-Za-z0-9_-]{1,64}$/,mo=/^[a-z0-9][a-z0-9-]{0,63}$/;function An(t){if(typeof t!="string")return null;let n=(t.split(/[\\/]/).pop()??"").replace(/[\u0000-\u001f<>:"|?*]/g,"").trim().slice(0,200);return n&&n!=="."&&n!==".."?n:null}var gl={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".heic":"image/heic",".svg":"image/svg+xml",".pdf":"application/pdf",".txt":"text/plain",".md":"text/markdown",".json":"application/json",".csv":"text/csv",".mp4":"video/mp4",".mov":"video/quicktime",".mp3":"audio/mpeg",".zip":"application/zip",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation"};function go(t){let e=t.lastIndexOf(".");return gl[e>0?t.slice(e).toLowerCase():""]??"application/octet-stream"}function yo(t,e,n,r){let s=n.replace(/[^\x20-\x7e]/g,"_").replace(/["\\]/g,"_")||"file",o=encodeURIComponent(n).replace(/['()*]/g,l=>`%${l.charCodeAt(0).toString(16).toUpperCase()}`),i="";for(let[l,a]of Object.entries(e))i+=`--${t}\r
194
194
  Content-Disposition: form-data; name="${l}"\r
195
195
  \r
196
196
  ${a}\r
@@ -200,56 +200,57 @@ Content-Type: ${r}\r
200
200
  \r
201
201
  `,{head:i,tail:`\r
202
202
  --${t}--\r
203
- `}}function Qn(t,e){let n=t.filter(([l])=>e-l<=3e3);if(n.length<2)return 0;let[r,s]=n[0],[o,i]=n[n.length-1];return o>r?Math.max(0,(i-s)/(o-r)*1e3):0}function er(t,e){let n=e??{};return t===401?"not_signed_in":n.code==="STORAGE_QUOTA_EXCEEDED"?"quota":n.code==="STORAGE_BUSY"||n.code==="STORAGE_RECONCILIATION_REQUIRED"?"storage_unavailable":n.code==="FILE_TOO_LARGE"||t===413?"too_large":typeof n.detail=="string"&&/quota exceeded/i.test(n.detail)?"quota":n.code==="STORAGE_NOT_CONFIGURED"?"storage_unavailable":`http_${t}`}var Ra=3,nr=6e4,Da=200,Pa=Is;function Us(t,e,n,r){let{head:s,tail:o}=$s(t,e,n,r);return{head:Buffer.from(s,"utf8"),tail:Buffer.from(o,"utf8")}}function $a(t,e,n,r,s,o,i,l){return new Promise((a,d)=>{let u=new URL(t),m=(u.protocol==="https:"?Ca:xa)(u,{method:"POST",headers:{...e,"Content-Length":String(n.length+s+o.length)}},p=>{let y=[];p.on("data",f=>y.push(f)),p.on("end",()=>{let f=null;try{f=JSON.parse(Buffer.concat(y).toString("utf8"))}catch{}a({status:p.statusCode??0,body:f})}),p.on("error",d)}),g=()=>{m.destroy(new Error("aborted"))};if(l.aborted)return g();l.addEventListener("abort",g,{once:!0}),m.setTimeout(nr,()=>m.destroy(new Error("timeout"))),m.on("error",p=>{l.removeEventListener("abort",g),d(p)}),(async()=>{try{m.write(n);let p=0;for await(let y of ya(r)){let f=y;if(p+=f.length,p>s)throw new Error("changed");m.write(f)||await new Promise(w=>m.once("drain",w)),i(p)}if(p!==s)throw new Error("changed");m.end(o)}catch(p){m.destroy(p)}})()})}function rr(t,e={}){let n=e.downloadsDir??(()=>Rt(Ta(),"Downloads")),r=e.post??$a,s=e.now??Date.now,o=[],i=new Map,l=Promise.resolve(),a=async()=>{let h=await t.getCloud(),v=typeof t.accountId=="function"?t.accountId():null;return{...h,account:v||`${h.base}|${h.token}`}},d=h=>{let{account:v,attempt:b,relDir:A,abort:N,samples:B,dl:G,...se}=h;return{...se,speed:h.state==="active"?Qn(B,s()):0}},u=(h,v,b=null)=>{h.state=v,h.error=b,h.abort=null,h.finishedAt=s(),h.samples=[];let A=o.filter(N=>N.state==="done"||N.state==="canceled");for(let N of A.slice(0,Math.max(0,A.length-Da)))o.splice(o.indexOf(N),1);m()};function m(){for(let h of["up","down"]){let v=o.filter(b=>b.kind===h&&b.state==="active").length;for(let b of o){if(v>=Ra)break;if(b.kind!==h||b.state!=="queued")continue;v++,b.state="active",b.startedAt=s(),b.done=0,b.samples=[[s(),0]],b.abort=new AbortController;let A=++b.attempt,N=()=>b.attempt===A&&b.state==="active";(h==="up"?P(b,N):T(b,N)).catch(B=>{N()&&u(b,"failed",g(B))})}}}let g=h=>{let v=String(h?.message||h);return v==="changed"||v==="too_large"||v==="quota"||v==="account_changed"||v==="not_signed_in"||v.startsWith("http_")||v==="bad_response"||v==="gone"?v:"network"},p=(h,v)=>{h.done=v;let b=s(),A=h.samples[h.samples.length-1];for((!A||b-A[0]>=200)&&h.samples.push([b,v]);h.samples.length>2&&b-h.samples[0][0]>3500;)h.samples.shift()};async function y(h){let v=await a();if(v.account!==h.account)throw new Error("account_changed");if(!v.token)throw new Error("not_signed_in");return v}async function f(h,v,b,A){let N=We(h,b);if(!N)throw new Error("bad_path");let B=await fetch(N,{method:A.method??"GET",headers:{Authorization:`Bearer ${v}`,...A.body!==void 0?{"Content-Type":"application/json"}:{},...A.projectSource?{"X-Project-Source":A.projectSource}:{}},body:A.body!==void 0?JSON.stringify(A.body):void 0,signal:AbortSignal.timeout(3e4)});return{status:B.status,json:await B.json().catch(()=>null)}}function w(h,v,b){if(!h.relDir.length)return Promise.resolve(h.targetId);let A=i.get(h.batch);A||i.set(h.batch,A=new Map);let N=A,B=G=>{if(G===0)return Promise.resolve(h.targetId);let se=h.relDir.slice(0,G).join("/"),pe=N.get(se);return pe||(pe=B(G-1).then(async X=>{let de=h.relDir[G-1],Z=await f(v,b,"/files",{method:"POST",body:{type:"directory",parentId:X,name:de},projectSource:h.projectSource});if(Z.status===201&&typeof Z.json?.id=="string")return Z.json.id;if(Z.status===409){let Ee=await f(v,b,`/files${X==="ROOT"?"":`?parentId=${encodeURIComponent(X)}`}`,{projectSource:h.projectSource}),oe=Array.isArray(Ee.json)?Ee.json.find(_e=>_e?.fileType==="directory"&&_e?.name===de):null;if(oe?.id)return String(oe.id)}throw new Error(Z.status===401?"not_signed_in":`http_${Z.status}`)}),pe.catch(()=>N.delete(se)),N.set(se,pe)),pe};return B(h.relDir.length)}async function P(h,v){let{base:b,token:A}=await y(h),N=await Os(h.localPath).catch(()=>null);if(!N?.isFile())throw new Error("gone");if(N.size>52428800)throw new Error("too_large");h.size=N.size;let B=await w(h,b,A);if(!v())return;h.parentId=B;let G=We(b,"/files/upload");if(!G)throw new Error("bad_path");let se=`----penzor${pn().replace(/-/g,"")}`,{head:pe,tail:X}=Us(se,{parentId:B,autoRename:"true"},h.name,Ps(h.name)),de=await r(G,{Authorization:`Bearer ${A}`,"Content-Type":`multipart/form-data; boundary=${se}`,...h.projectSource?{"X-Project-Source":h.projectSource}:{}},pe,h.localPath,N.size,X,Z=>{v()&&p(h,Z)},h.abort.signal);v()&&(de.status===201||de.status===200?(h.fileId=typeof de.body?.id=="string"?de.body.id:null,p(h,h.size),u(h,"done")):u(h,"failed",er(de.status,de.body)))}function H(h,v,b,A){let N=async()=>{let G=Aa(b),se=G?b.slice(0,-G.length):b;for(let pe=0;pe<1e3;pe++){if(!A())throw new Error("aborted");let X=Rt(v,pe===0?b:`${se} (${pe})${G}`);try{await ba(h,X)}catch(de){let Z=de.code;if(Z==="EEXIST")continue;if(Z!=="EPERM"&&Z!=="ENOTSUP"&&Z!=="EOPNOTSUPP"&&Z!=="ENOSYS"&&Z!=="EXDEV")throw de;if(await wa(X).then(()=>!0,()=>!1))continue;await va(h,X)}if(!A())throw await tr(X).catch(()=>{}),new Error("aborted");return await tr(h).catch(()=>{}),X}throw new Error("too many duplicates")},B=l.then(N,N);return l=B.catch(()=>{}),B}async function T(h,v){let b=h.dl,{base:A,token:N}=await y(h);if(!v())return;let B=We(A,b.path);if(!B)throw new Error("bad_path");let G=h.abort.signal,se=b.subdir?Rt(n(),b.subdir):n();await ka(se,{recursive:!0});let pe=Rt(se,`.${h.id}-${h.attempt}.penzor-part`),X=await Ea(pe,"wx"),de=!1;try{let Z=new AbortController,Ee=setTimeout(()=>Z.abort(),nr),oe=()=>{clearTimeout(Ee),Ee=setTimeout(()=>Z.abort(),nr)},_e=AbortSignal.any([G,Z.signal]);try{let fe=await fetch(B,{headers:{Authorization:`Bearer ${N}`},signal:_e});if(!fe.ok)throw new Error(fe.status===401?"not_signed_in":`http_${fe.status}`);let ye=fe.body,ae=Number(fe.headers.get("content-length"))||h.size;if(b.mode!=="bytes"){let be=await fe.json().catch(()=>null);if(b.mode==="text"){if(typeof be?.content!="string")throw new Error("bad_response");let _=Buffer.from(be.content,"utf8");await X.writeFile(_),h.size=_.length,p(h,_.length),ye=null}else{if(typeof be?.url!="string"||!/^https?:\/\//i.test(be.url))throw new Error("bad_response");let _=await fetch(be.url,{signal:_e});if(!_.ok)throw new Error(`http_${_.status}`);ye=_.body,ae=Number(_.headers.get("content-length"))||h.size}}if(ye){h.size=ae;let be=0;for await(let _ of ye){oe();for(let I=0;I<_.length;){let{bytesWritten:x}=await X.write(_,I,_.length-I);if(x<=0)throw new Error("short_write");I+=x}if(be+=_.length,!v())throw new Error("aborted");p(h,be)}be>h.size&&(h.size=be)}}finally{clearTimeout(Ee)}if(await X.close(),!v()||(h.localPath=await H(pe,se,b.name,v),de=!0,!v()))return;u(h,"done")}finally{de||(await X.close().catch(()=>{}),await tr(pe).catch(()=>{}))}}let U=(h,v)=>{let b={...h,id:pn(),attempt:0,done:0,state:v?"failed":"queued",error:v??null,abort:null,samples:[],speed:0,startedAt:null,finishedAt:v?s():null};return o.push(b),b};async function z(h){let v=[],b=async(A,N)=>{if(N.length>32)return!0;let B=await(N.length?Sa(A):Os(A)).catch(()=>null);if(!B)return!0;if(B.isFile())return v.push({path:A,size:B.size,relDir:N}),v.length<=2e3;if(!B.isDirectory())return!0;let G=(await _a(A).catch(()=>[])).filter(se=>!se.startsWith(".")).sort();for(let se of G)if(!await b(Rt(A,se),[...N,Ns(A)]))return!1;return!0};for(let A of h)if(!await b(A,[]))return"too_many";return v}return t.handle("penzor:device",h=>{if(!t.isTrustedSender(h))return{ok:!1,error:"untrusted"};let v=un();return{ok:!0,name:v?decodeURIComponent(v):null}}),t.handle("penzor:upload",async(h,v)=>{if(!t.isTrustedSender(h))return{ok:!1,error:"untrusted"};let b=v??{},A=Array.isArray(b.paths)?b.paths.filter(oe=>typeof oe=="string"&&Ia(oe)):[],N=typeof b.parentId=="string"&&Rs.test(b.parentId)?b.parentId:null,B=typeof b.projectSource=="string"&&Ds.test(b.projectSource)?b.projectSource:null;if(!A.length)return{ok:!1,error:"no_files"};if(!N||!B)return{ok:!1,error:"bad_target"};let{base:G,token:se,account:pe}=await a();if(!se)return{ok:!1,error:"not_signed_in"};let X=await z(A);if(X==="too_many")return{ok:!1,error:"too_many",max:2e3};if(!X.length)return{ok:!1,error:"no_files"};let de=X.filter(oe=>oe.size<=52428800).reduce((oe,_e)=>oe+_e.size,0);try{let oe=await f(G,se,"/storage/quota",{}),_e=Number(oe.json?.used),fe=Number(oe.json?.quota);if(oe.status===200&&fe>0&&_e+de>fe)return{ok:!1,error:"quota",short:_e+de-fe}}catch{}if((await a()).account!==pe)return{ok:!1,error:"account_changed"};let Z=pn(),Ee=X.map(oe=>U({kind:"up",name:Ns(oe.path),size:oe.size,projectSource:B,parentId:oe.relDir.length?null:N,targetId:N,fileId:null,localPath:oe.path,batch:Z,account:pe,relDir:oe.relDir},oe.size>52428800?"too_large":void 0).id);return m(),{ok:!0,ids:Ee,batch:Z}}),t.handle("penzor:download",async(h,v)=>{if(!t.isTrustedSender(h))return{ok:!1,error:"untrusted"};let b=v??{},A=Pa.includes(b.mode)?b.mode:null,N=mn(b.name);if(!A)return{ok:!1,error:"bad_mode"};if(!N)return{ok:!1,error:"bad_name"};let{base:B,token:G,account:se}=await a();if(typeof b.path!="string"||!We(B,b.path))return{ok:!1,error:"bad_path"};if(!G)return{ok:!1,error:"not_signed_in"};let pe=b.subdir==null?null:mn(b.subdir),X=U({kind:"down",name:N,size:Math.max(0,Number(b.size)||0),localPath:null,batch:typeof b.batch=="string"&&b.batch.length<=64?b.batch:pn(),account:se,relDir:[],dl:{path:b.path,mode:A,name:N,subdir:pe}});return m(),{ok:!0,id:X.id}}),t.handle("penzor:transfers",h=>t.isTrustedSender(h)?{ok:!0,items:o.map(d)}:{ok:!1,error:"untrusted"}),t.handle("penzor:transfer",(h,v)=>{if(!t.isTrustedSender(h))return{ok:!1,error:"untrusted"};let b=v??{},A=o.find(B=>B.id===b.id);if(!A)return{ok:!1,error:"not_found"};let N=()=>{A.abort?.abort(),A.abort=null,A.done=0,A.samples=[]};switch(b.op){case"pause":(A.state==="active"||A.state==="queued")&&(N(),A.state="paused",m());break;case"resume":A.state==="paused"&&(A.state="queued",m());break;case"cancel":(A.state==="active"||A.state==="queued"||A.state==="paused")&&(N(),u(A,"canceled"));break;case"retry":(A.state==="failed"||A.state==="canceled")&&(A.state="queued",A.error=null,A.finishedAt=null,A.done=0,m());break;case"dismiss":A.state!=="active"&&A.state!=="queued"&&o.splice(o.indexOf(A),1);break;default:return{ok:!1,error:"bad_op"}}return{ok:!0}}),t.handle("penzor:transfers:clear",(h,v)=>{if(!t.isTrustedSender(h))return{ok:!1,error:"untrusted"};let b=v?.which==="all";for(let A of[...o])(A.state==="done"||A.state==="canceled"||b&&A.state==="failed")&&o.splice(o.indexOf(A),1);return{ok:!0}}),t.addQuitGuard?.(h=>{let v=o.filter(b=>b.state==="active"||b.state==="queued"||b.state==="paused").length;return v?h==="zh"?{message:`\u8FD8\u6709 ${v} \u4E2A\u6587\u4EF6\u6CA1\u4F20\u5B8C`,detail:"\u73B0\u5728\u9000\u51FA\u4F1A\u4E2D\u65AD\uFF0C\u4E0B\u6B21\u6253\u5F00\u8981\u91CD\u65B0\u4F20\u3002"}:{message:v===1?"1 file hasn't finished transferring":`${v} files haven't finished transferring`,detail:"Quitting now stops them. You will need to start them again next time."}:null}),{list:()=>o.map(d)}}import{readFileSync as Na,writeFileSync as Ua,mkdirSync as ja,chmodSync as Fa,renameSync as La}from"node:fs";import{join as Ha}from"node:path";function $e(t,e){try{let n=new URL(t);if(n.protocol!=="https:"&&n.protocol!=="http:")return null;let r=e.split(".")[1];if(!r)return null;let s=r.replace(/-/g,"+").replace(/_/g,"/"),o=Uint8Array.from(atob(s),a=>a.charCodeAt(0)),i=JSON.parse(new TextDecoder().decode(o)),l=i.userId??i.sub;return typeof l!="string"&&typeof l!="number"||!String(l).trim()?null:`${n.origin}${n.pathname.replace(/\/+$/,"")}::${String(l)}`}catch{return null}}function sr(t){try{let e=t.split(".")[1];if(!e)return null;let n=JSON.parse(Ke(en(e)));return n&&typeof n=="object"?n:null}catch{return null}}function or(t,e=Date.now()){let n=sr(t)?.iat;return typeof n=="number"?e-n*1e3:1/0}function js(t,e=Date.now()){let n=sr(t)?.exp;return typeof n=="number"?n*1e3-e:1/0}var Ma=36e5;function gn(t,e=Date.now()){return!!t&&or(t,e)>=Ma}async function hn(t,e,n=8e3,r){if(!t||!e)return null;let s=t.replace(/\/+$/,"");try{let o=await fetch(`${s}/api/auth/refresh`,{method:"POST",headers:{Authorization:`Bearer ${e}`,...r?{"X-Forsion-Client":r}:{}},signal:AbortSignal.timeout(n)});if(!o.ok)return null;let i=await o.json().catch(()=>null),l=typeof i?.token=="string"?i.token:"";return l&&l!==e?l:null}catch{return null}}var Dt=(t,e)=>`${t.replace(/\/+$/,"")}\0${e}`,Oa=(t,e)=>new Promise((n,r)=>{let s=()=>{clearTimeout(o),r(new Error("Sign-in cancelled."))},o=setTimeout(()=>{e.removeEventListener("abort",s),n()},t);e.aborted?s():e.addEventListener("abort",s,{once:!0})});function Fs(t,e){let n=m=>e.write(JSON.stringify(m,null,2)),r=()=>{try{let m=JSON.parse(e.read()??"");return Array.isArray(m.accounts)?m.accounts.filter(g=>g&&typeof g.token=="string"&&g.id===$e(g.cloudUrl,g.token)):[]}catch{return[]}},s=(m,g)=>{let p=$e(m.cloudUrl||"",m.token||"");if(!p||!m.token||!m.cloudUrl)return;let y=r(),f=y.find(H=>H.id===p),w=sr(m.token),P={...f,id:p,cloudUrl:m.cloudUrl.replace(/\/+$/,""),token:m.token,username:g?.username||f?.username||w?.username,nickname:g?.nickname||f?.nickname};JSON.stringify(f)!==JSON.stringify(P)&&n({version:1,accounts:[...y.filter(H=>H.id!==p),P]})},o=()=>{let m=t.readCreds();s(m);let g=$e(m.cloudUrl,m.token);return r().map(({token:p,...y})=>({...y,active:y.id===g}))},i=m=>{let g=r().find(p=>p.id===m);if(!g)throw new Error("Account is no longer signed in. Sign in again.");return{cloudUrl:g.cloudUrl,token:g.token}},l=m=>{let g=$e(m.cloudUrl||"",m.token||"");g&&n({version:1,accounts:r().filter(p=>p.id!==g)})},a=null;return{rememberForsionAccount:s,forsionAccounts:o,savedForsionAccount:i,forgetForsionAccount:l,cancelForsionLogin:()=>{a?.abort(),a=null},forsionDeviceLogin:async(m,g,p)=>{if(a)throw new Error("A sign-in is already in progress.");if(!m)throw new Error("\u8BF7\u5148\u586B\u5199 Forsion \u4E91\u7AEF\u5730\u5740(\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF TANGU_CLOUD_URL)");let y=new AbortController;a=y;let f=()=>{if(y.signal.aborted||a!==y)throw new Error("Sign-in cancelled.")};try{let w=m.replace(/\/+$/,""),P;try{P=await fetch(`${w}/api/auth/cli/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:"{}",signal:AbortSignal.any([y.signal,AbortSignal.timeout(15e3)])}).then(v=>v.json())}catch(v){throw new Error(`\u65E0\u6CD5\u8FDE\u63A5 ${w}:${v?.message||v}`)}if(f(),!P?.device_code)throw new Error("\u4E91\u7AEF\u4E0D\u652F\u6301 CLI \u767B\u5F55(/api/auth/cli/start \u8FD4\u56DE\u5F02\u5E38)");let H=P.verification_uri_complete||`${P.verification_uri}?code=${P.user_code}`,T=new URL(`${w}/auth`);T.searchParams.set("logout","1"),T.searchParams.set("app","forsion-desktop"),T.searchParams.set("redirect",H);let U=T.toString();g?.({url:U,userCode:String(P.user_code||"")}),t.openExternal(U);let z=Date.now()+(P.expires_in||600)*1e3,h=(P.interval||2)*1e3;for(;Date.now()<z;){await Oa(h,y.signal),f();let v=null;try{v=await fetch(`${w}/api/auth/cli/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_code:P.device_code}),signal:AbortSignal.any([y.signal,AbortSignal.timeout(15e3)])})}catch{f();continue}if(f(),v.status===410)throw new Error("\u767B\u5F55\u7801\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u53D1\u8D77\u767B\u5F55");let b=await v.json().catch(()=>({status:"pending"}));if(f(),b.status==="approved"&&b.token){let A={cloudUrl:w,token:b.token};return await p(A,f),f(),{token:b.token,cloudUrl:w}}}throw new Error("\u767B\u5F55\u8D85\u65F6,\u8BF7\u91CD\u8BD5")}finally{a===y&&(a=null)}},readAccounts:r}}function za(t){let e=()=>Ha(t(),"auth-accounts.json");return{read:()=>Na(e(),"utf8"),write:n=>{ja(t(),{recursive:!0});let r=`${e()}.tmp`;Ua(r,n,{encoding:"utf8",mode:384}),Fa(r,384),La(r,e())}}}var Hs=t=>Fs(t,za(()=>t.homeDir())),zs=["homeDir","appVersion","broadcast","accountBackendState","accountTransition","accountCommit","accountClear","writeCreds","onExternalCredsChange","setTokenRefresher","readCreds"],ir=t=>zs.every(e=>typeof t[e]=="function");function ar(t){let e={ok:!1,error:"untrusted"},n={loggedIn:!1,error:"untrusted"},r=Hs(t),s=0,o=()=>{let l=t.readCreds();return Dt(l.cloudUrl,l.token)},i=null;t.handle("auth:status",async l=>{if(!t.isTrustedSender(l))return n;let a=s,d=o(),{base:u}=await t.getCloud(),m=t.readCreds().token,g=m?await At(u,m):null,p=await t.accountBackendState(),{base:y}=await t.getCloud(),f=t.readCreds(),w=Dt(y,f.token)!==Dt(u,m),P=Dt(u,m);!w&&g?.status==="ok"&&g.user&&(i={key:P,user:g.user},r.rememberForsionAccount({...f,cloudUrl:u},g.user));let H=w?void 0:g?.status==="ok"?g.user:g?.status==="offline"&&i?.key===P?i.user:void 0;if(w)return{loggedIn:!!f.token,tokenValid:null,cloudUrl:y,accountId:$e(y,f.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:f.token?"tangu-login":null,backendState:p};if(g?.status==="expired"){await t.accountTransition(async()=>{if(a!==s||o()!==d)return;let U=()=>{if(a!==s||o()!==d)throw Ls};try{await t.accountClear(U,()=>{t.log("[auth] token \u5DF2\u5931\u6548(\u670D\u52A1\u7AEF 401/403),\u81EA\u52A8\u767B\u51FA"),++s,r.cancelForsionLogin(),r.forgetForsionAccount(t.readCreds()),i=null})}catch(z){if(z!==Ls)throw z}});let T=t.readCreds();return{loggedIn:!!T.token,tokenValid:null,cloudUrl:T.cloudUrl||u,accountId:$e(T.cloudUrl||u,T.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:T.token?"tangu-login":null,backendState:p}}return{loggedIn:!!m,tokenValid:g&&g.status==="ok"?!0:null,cloudUrl:u,accountId:$e(u,m),username:H?.username||null,nickname:H?.nickname||null,avatar:H?.avatar||null,membershipTier:H?.membershipTier||null,tokenSource:m?"tangu-login":null,backendState:p}}),t.handle("auth:accounts",l=>t.isTrustedSender(l)?r.forsionAccounts():[]),t.handle("auth:switchAccount",async(l,a)=>{if(!t.isTrustedSender(l))return e;if(typeof a!="string")throw new Error("Invalid account.");let d=++s;return r.cancelForsionLogin(),t.accountTransition(async()=>{let u=r.savedForsionAccount(a);return await t.accountCommit(u,()=>{if(d!==s)throw new Error("Account switch cancelled.")},()=>{r.rememberForsionAccount(u),i=null}),{ok:!0,cloudUrl:u.cloudUrl||""}})}),t.handle("auth:forsionLogin",async(l,a)=>{if(!t.isTrustedSender(l))return e;let d=++s;r.cancelForsionLogin();let{base:u}=await t.getCloud();if(d!==s)throw new Error("Sign-in cancelled.");let m=(a||u||"").trim();return{ok:!0,cloudUrl:(await r.forsionDeviceLogin(m,p=>t.broadcast("auth:device",p),(p,y)=>t.accountTransition(()=>t.accountCommit(p,()=>{if(y(),d!==s)throw new Error("Sign-in cancelled.")},()=>{r.rememberForsionAccount(p),i=null})))).cloudUrl}}),t.handle("auth:logout",async l=>t.isTrustedSender(l)?(++s,r.cancelForsionLogin(),t.accountTransition(async()=>{let{base:a}=await t.getCloud(),d=t.readCreds();return await t.accountClear(void 0,()=>{r.forgetForsionAccount(d),i=null,a&&d.token&&fetch(`${a}/api/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${d.token}`},signal:AbortSignal.timeout(5e3)}).catch(()=>{})}),{ok:!0}})):e),t.onExternalCredsChange(({previous:l,current:a})=>{++s,r.cancelForsionLogin(),l.token&&!a.token&&r.forgetForsionAccount(l),i=null,r.rememberForsionAccount(a)}),t.setTokenRefresher(async l=>{let a=s,d=o(),u=t.readCreds().token;if(!gn(u))return;let{base:m}=await t.getCloud(),g=await hn(m,u,l,`desktop/${t.appVersion()}`);if(!g){t.log("[auth] \u6ED1\u52A8\u7EED\u671F\u672A\u6210\u529F(\u79BB\u7EBF/\u8001\u7248\u672C server/\u8FD9\u679A\u5DF2\u5931\u6548),\u7EE7\u7EED\u7528\u65E7 token");return}a!==s||o()!==d||(r.rememberForsionAccount({cloudUrl:m,token:g}),t.writeCreds({cloudUrl:m,token:g}),t.log("[auth] \u767B\u5F55\u6001\u5DF2\u6ED1\u52A8\u7EED\u671F(\u6709\u6548\u671F\u91CD\u65B0\u8BA1\u6EE1 2 \u5468)"))}),t.log("[forsion-extend] account core registered")}var Ls=Symbol("stale-auth-intent");import{promises as ht}from"node:fs";import st from"node:path";import{execFile as ul}from"node:child_process";import dl from"node:os";var lr=null;function qs(t){lr=t}function Ie(){if(!lr)throw new Error("amadeus sync env not set (registerAmadeus factory has not run)");return lr}var Te=()=>Ie().accountId();function Pt(t=Te()){return t?Se().sha256Hex(t):"signed-out"}var Me=(t=Te())=>Ie().readConfig(t),Ve=(t,e=Te())=>Ie().writeConfig(t,e),ft=(t,e=Te())=>Ie().updateConfig(t,e),Ze=(t=Te())=>Ie().cloudVaultDir(t),yn=t=>Ie().isManagedCloudVault(t);function qa(t,e){let n=Object.create(null);for(let o=0;o<e.length;o++){let i=e[o];n[i]?n[i].push(o):n[i]=[o]}let s=[{buffer1index:-1,buffer2index:-1,chain:null}];for(let o=0;o<t.length;o++){let i=t[o],l=n[i]||[],a=0,d=s[0];for(let u of l){let m;for(m=a;m<s.length&&!(s[m].buffer2index<u&&(m===s.length-1||s[m+1].buffer2index>u));m++);if(m<s.length){let g={buffer1index:o,buffer2index:u,chain:s[m]};if(a===s.length?s.push(d):s[a]=d,a=m+1,d=g,a===s.length)break}}s[a]=d}return s[s.length-1]}function Bs(t,e){let n=qa(t,e),r=[],s=t.length,o=e.length;for(let i=n;i!==null;i=i.chain){let l=s-i.buffer1index-1,a=o-i.buffer2index-1;s=i.buffer1index,o=i.buffer2index,(l||a)&&r.push({buffer1:[s+1,l],buffer1Content:t.slice(s+1,s+1+l),buffer2:[o+1,a],buffer2Content:e.slice(o+1,o+1+a)})}return r.reverse(),r}function Ba(t,e,n){let r=[];function s(a,d){r.push({ab:d,oStart:a.buffer1[0],oLength:a.buffer1[1],abStart:a.buffer2[0],abLength:a.buffer2[1]})}Bs(e,t).forEach(a=>s(a,"a")),Bs(e,n).forEach(a=>s(a,"b")),r.sort((a,d)=>a.oStart-d.oStart);let o=[],i=0;function l(a){a>i&&(o.push({stable:!0,buffer:"o",bufferStart:i,bufferLength:a-i,bufferContent:e.slice(i,a)}),i=a)}for(;r.length;){let a=r.shift(),d=a.oStart,u=a.oStart+a.oLength,m=[a];for(l(d);r.length;){let g=r[0],p=g.oStart;if(p>u)break;u=Math.max(u,p+g.oLength),m.push(r.shift())}if(m.length===1){if(a.abLength>0){let g=a.ab==="a"?t:n;o.push({stable:!0,buffer:a.ab,bufferStart:a.abStart,bufferLength:a.abLength,bufferContent:g.slice(a.abStart,a.abStart+a.abLength)})}}else{let g={a:[t.length,-1,e.length,-1],b:[n.length,-1,e.length,-1]};for(;m.length;){a=m.shift();let H=a.oStart,T=H+a.oLength,U=a.abStart,z=U+a.abLength,h=g[a.ab];h[0]=Math.min(U,h[0]),h[1]=Math.max(z,h[1]),h[2]=Math.min(H,h[2]),h[3]=Math.max(T,h[3])}let p=g.a[0]+(d-g.a[2]),y=g.a[1]+(u-g.a[3]),f=g.b[0]+(d-g.b[2]),w=g.b[1]+(u-g.b[3]),P={stable:!1,aStart:p,aLength:y-p,aContent:t.slice(p,y),oStart:d,oLength:u-d,oContent:e.slice(d,u),bStart:f,bLength:w-f,bContent:n.slice(f,w)};o.push(P)}i=u}return l(e.length),o}function Ws(t,e,n,r){r=Object.assign({excludeFalseConflicts:!0,stringSeparator:/\s+/},r),typeof t=="string"&&(t=t.split(r.stringSeparator)),typeof e=="string"&&(e=e.split(r.stringSeparator)),typeof n=="string"&&(n=n.split(r.stringSeparator));let o=[],i=Ba(t,e,n),l=[];function a(){l.length&&o.push({ok:l}),l=[]}function d(u,m){if(u.length!==m.length)return!1;for(let g=0;g<u.length;g++)if(u[g]!==m[g])return!1;return!0}return i.forEach(u=>{u.stable?l.push(...u.bufferContent):r.excludeFalseConflicts&&d(u.aContent,u.bContent)?l.push(...u.aContent):(a(),o.push({conflict:{a:u.aContent,aIndex:u.aStart,o:u.oContent,oIndex:u.oStart,b:u.bContent,bIndex:u.bStart}}))}),a(),o}function wn(t,e){let n=t.lastIndexOf("/"),r=n<0?"":t.slice(0,n+1),s=n<0?t:t.slice(n+1),o=s.lastIndexOf("."),i=o>0?s.slice(0,o):s,l=o>0?s.slice(o):"",a=u=>String(u).padStart(2,"0"),d=`${e.getFullYear()}-${a(e.getMonth()+1)}-${a(e.getDate())} ${a(e.getHours())}${a(e.getMinutes())}`;return`${r}${i} (conflict ${d})${l}`}function Wa(t,e){if(e<2)return t;let n=t.lastIndexOf("."),r=n>t.lastIndexOf("/")&&n>t.lastIndexOf(")"),s=r?t.slice(0,n):t,o=r?t.slice(n):"";return`${s}-${e}${o}`}function Va(t){let e=3735928559,n=1103547991;for(let s=0;s<t.length;s++){let o=t.charCodeAt(s);e=Math.imul(e^o,2654435761),n=Math.imul(n^o,1597334677)}e=Math.imul(e^e>>>16,2246822507)^Math.imul(n^n>>>13,3266489909),n=Math.imul(n^n>>>16,2246822507)^Math.imul(e^e>>>13,3266489909);let r=4294967296*(2097151&n)+(e>>>0);return`${t.length.toString(36)}-${r.toString(36)}`}function bn(t,e,n){if(t===null&&e===null&&n===null)return{kind:"none"};if(n===null)return t===null?e?{kind:"dropShadow"}:{kind:"none"}:e?t===e.hash?{kind:"deleteLocal"}:{kind:"pushCreate"}:{kind:"pushCreate"};if(t===null)return e?n.seq===e.seq?{kind:"pushDelete"}:{kind:"pull"}:{kind:"pull"};if(!e)return t===n.hash?{kind:"adopt"}:{kind:"conflict"};let r=t!==e.hash,s=n.seq!==e.seq;return!r&&!s?{kind:"none"}:r?s?t===n.hash?{kind:"adopt"}:n.hash===e.hash?{kind:"push",baseSeq:n.seq}:{kind:"conflict"}:{kind:"push",baseSeq:e.seq}:{kind:"pull"}}function Vs(t,e,n){let r=Ws(t.split(`
203
+ `}}function kr(t,e){let n=t.filter(([l])=>e-l<=3e3);if(n.length<2)return 0;let[r,s]=n[0],[o,i]=n[n.length-1];return o>r?Math.max(0,(i-s)/(o-r)*1e3):0}function Er(t,e){let n=e??{};return t===401?"not_signed_in":n.code==="STORAGE_QUOTA_EXCEEDED"?"quota":n.code==="STORAGE_BUSY"||n.code==="STORAGE_RECONCILIATION_REQUIRED"?"storage_unavailable":n.code==="FILE_TOO_LARGE"||t===413?"too_large":typeof n.detail=="string"&&/quota exceeded/i.test(n.detail)?"quota":n.code==="STORAGE_NOT_CONFIGURED"?"storage_unavailable":`http_${t}`}var Pl=3,Cr=6e4,Rl=200,Dl=ho;function vo(t,e,n,r){let{head:s,tail:o}=yo(t,e,n,r);return{head:Buffer.from(s,"utf8"),tail:Buffer.from(o,"utf8")}}function $l(t,e,n,r,s,o,i,l){return new Promise((a,c)=>{let u=new URL(t),f=(u.protocol==="https:"?xl:Cl)(u,{method:"POST",headers:{...e,"Content-Length":String(n.length+s+o.length)}},h=>{let g=[];h.on("data",p=>g.push(p)),h.on("end",()=>{let p=null;try{p=JSON.parse(Buffer.concat(g).toString("utf8"))}catch{}a({status:h.statusCode??0,body:p})}),h.on("error",c)}),m=()=>{f.destroy(new Error("aborted"))};if(l.aborted)return m();l.addEventListener("abort",m,{once:!0}),f.setTimeout(Cr,()=>f.destroy(new Error("timeout"))),f.on("error",h=>{l.removeEventListener("abort",m),c(h)}),(async()=>{try{f.write(n);let h=0;for await(let g of yl(r)){let p=g;if(h+=p.length,h>s)throw new Error("changed");f.write(p)||await new Promise(y=>f.once("drain",y)),i(h)}if(h!==s)throw new Error("changed");f.end(o)}catch(h){f.destroy(h)}})()})}function xr(t,e={}){let n=e.downloadsDir??(()=>Ht(Tl(),"Downloads")),r=e.post??$l,s=e.now??Date.now,o=[],i=new Map,l=Promise.resolve(),a=async()=>{let w=await t.getCloud(),x=typeof t.accountId=="function"?t.accountId():null;return{...w,account:x||`${w.base}|${w.token}`}},c=w=>{let{account:x,attempt:b,relDir:I,abort:U,samples:B,dl:J,...se}=w;return{...se,speed:w.state==="active"?kr(B,s()):0}},u=(w,x,b=null)=>{w.state=x,w.error=b,w.abort=null,w.finishedAt=s(),w.samples=[];let I=o.filter(U=>U.state==="done"||U.state==="canceled");for(let U of I.slice(0,Math.max(0,I.length-Rl)))o.splice(o.indexOf(U),1);f()};function f(){for(let w of["up","down"]){let x=o.filter(b=>b.kind===w&&b.state==="active").length;for(let b of o){if(x>=Pl)break;if(b.kind!==w||b.state!=="queued")continue;x++,b.state="active",b.startedAt=s(),b.done=0,b.samples=[[s(),0]],b.abort=new AbortController;let I=++b.attempt,U=()=>b.attempt===I&&b.state==="active";(w==="up"?E(b,U):C(b,U)).catch(B=>{U()&&u(b,"failed",m(B))})}}}let m=w=>{let x=String(w?.message||w);return x==="changed"||x==="too_large"||x==="quota"||x==="account_changed"||x==="not_signed_in"||x.startsWith("http_")||x==="bad_response"||x==="gone"?x:"network"},h=(w,x)=>{w.done=x;let b=s(),I=w.samples[w.samples.length-1];for((!I||b-I[0]>=200)&&w.samples.push([b,x]);w.samples.length>2&&b-w.samples[0][0]>3500;)w.samples.shift()};async function g(w){let x=await a();if(x.account!==w.account)throw new Error("account_changed");if(!x.token)throw new Error("not_signed_in");return x}async function p(w,x,b,I){let U=Ge(w,b);if(!U)throw new Error("bad_path");let B=await fetch(U,{method:I.method??"GET",headers:{Authorization:`Bearer ${x}`,...I.body!==void 0?{"Content-Type":"application/json"}:{},...I.projectSource?{"X-Project-Source":I.projectSource}:{}},body:I.body!==void 0?JSON.stringify(I.body):void 0,signal:AbortSignal.timeout(3e4)});return{status:B.status,json:await B.json().catch(()=>null)}}function y(w,x,b){if(!w.relDir.length)return Promise.resolve(w.targetId);let I=i.get(w.batch);I||i.set(w.batch,I=new Map);let U=I,B=J=>{if(J===0)return Promise.resolve(w.targetId);let se=w.relDir.slice(0,J).join("/"),pe=U.get(se);return pe||(pe=B(J-1).then(async X=>{let de=w.relDir[J-1],Z=await p(x,b,"/files",{method:"POST",body:{type:"directory",parentId:X,name:de},projectSource:w.projectSource});if(Z.status===201&&typeof Z.json?.id=="string")return Z.json.id;if(Z.status===409){let ke=await p(x,b,`/files${X==="ROOT"?"":`?parentId=${encodeURIComponent(X)}`}`,{projectSource:w.projectSource}),oe=Array.isArray(ke.json)?ke.json.find(Ee=>Ee?.fileType==="directory"&&Ee?.name===de):null;if(oe?.id)return String(oe.id)}throw new Error(Z.status===401?"not_signed_in":`http_${Z.status}`)}),pe.catch(()=>U.delete(se)),U.set(se,pe)),pe};return B(w.relDir.length)}async function E(w,x){let{base:b,token:I}=await g(w),U=await bo(w.localPath).catch(()=>null);if(!U?.isFile())throw new Error("gone");if(U.size>52428800)throw new Error("too_large");w.size=U.size;let B=await y(w,b,I);if(!x())return;w.parentId=B;let J=Ge(b,"/files/upload");if(!J)throw new Error("bad_path");let se=`----penzor${In().replace(/-/g,"")}`,{head:pe,tail:X}=vo(se,{parentId:B,autoRename:"true"},w.name,go(w.name)),de=await r(J,{Authorization:`Bearer ${I}`,"Content-Type":`multipart/form-data; boundary=${se}`,...w.projectSource?{"X-Project-Source":w.projectSource}:{}},pe,w.localPath,U.size,X,Z=>{x()&&h(w,Z)},w.abort.signal);x()&&(de.status===201||de.status===200?(w.fileId=typeof de.body?.id=="string"?de.body.id:null,h(w,w.size),u(w,"done")):u(w,"failed",Er(de.status,de.body)))}function O(w,x,b,I){let U=async()=>{let J=Al(b),se=J?b.slice(0,-J.length):b;for(let pe=0;pe<1e3;pe++){if(!I())throw new Error("aborted");let X=Ht(x,pe===0?b:`${se} (${pe})${J}`);try{await bl(w,X)}catch(de){let Z=de.code;if(Z==="EEXIST")continue;if(Z!=="EPERM"&&Z!=="ENOTSUP"&&Z!=="EOPNOTSUPP"&&Z!=="ENOSYS"&&Z!=="EXDEV")throw de;if(await wl(X).then(()=>!0,()=>!1))continue;await _l(w,X)}if(!I())throw await _r(X).catch(()=>{}),new Error("aborted");return await _r(w).catch(()=>{}),X}throw new Error("too many duplicates")},B=l.then(U,U);return l=B.catch(()=>{}),B}async function C(w,x){let b=w.dl,{base:I,token:U}=await g(w);if(!x())return;let B=Ge(I,b.path);if(!B)throw new Error("bad_path");let J=w.abort.signal,se=b.subdir?Ht(n(),b.subdir):n();await vl(se,{recursive:!0});let pe=Ht(se,`.${w.id}-${w.attempt}.penzor-part`),X=await kl(pe,"wx"),de=!1;try{let Z=new AbortController,ke=setTimeout(()=>Z.abort(),Cr),oe=()=>{clearTimeout(ke),ke=setTimeout(()=>Z.abort(),Cr)},Ee=AbortSignal.any([J,Z.signal]);try{let fe=await fetch(B,{headers:{Authorization:`Bearer ${U}`},signal:Ee});if(!fe.ok)throw new Error(fe.status===401?"not_signed_in":`http_${fe.status}`);let ye=fe.body,ae=Number(fe.headers.get("content-length"))||w.size;if(b.mode!=="bytes"){let be=await fe.json().catch(()=>null);if(b.mode==="text"){if(typeof be?.content!="string")throw new Error("bad_response");let _=Buffer.from(be.content,"utf8");await X.writeFile(_),w.size=_.length,h(w,_.length),ye=null}else{if(typeof be?.url!="string"||!/^https?:\/\//i.test(be.url))throw new Error("bad_response");let _=await fetch(be.url,{signal:Ee});if(!_.ok)throw new Error(`http_${_.status}`);ye=_.body,ae=Number(_.headers.get("content-length"))||w.size}}if(ye){w.size=ae;let be=0;for await(let _ of ye){oe();for(let P=0;P<_.length;){let{bytesWritten:T}=await X.write(_,P,_.length-P);if(T<=0)throw new Error("short_write");P+=T}if(be+=_.length,!x())throw new Error("aborted");h(w,be)}be>w.size&&(w.size=be)}}finally{clearTimeout(ke)}if(await X.close(),!x()||(w.localPath=await O(pe,se,b.name,x),de=!0,!x()))return;u(w,"done")}finally{de||(await X.close().catch(()=>{}),await _r(pe).catch(()=>{}))}}let M=(w,x)=>{let b={...w,id:In(),attempt:0,done:0,state:x?"failed":"queued",error:x??null,abort:null,samples:[],speed:0,startedAt:null,finishedAt:x?s():null};return o.push(b),b};async function H(w){let x=[],b=async(I,U)=>{if(U.length>32)return!0;let B=await(U.length?Sl(I):bo(I)).catch(()=>null);if(!B)return!0;if(B.isFile())return x.push({path:I,size:B.size,relDir:U}),x.length<=2e3;if(!B.isDirectory())return!0;let J=(await El(I).catch(()=>[])).filter(se=>!se.startsWith(".")).sort();for(let se of J)if(!await b(Ht(I,se),[...U,So(I)]))return!1;return!0};for(let I of w)if(!await b(I,[]))return"too_many";return x}return t.handle("penzor:device",w=>{if(!t.isTrustedSender(w))return{ok:!1,error:"untrusted"};let x=Cn();return{ok:!0,name:x?decodeURIComponent(x):null}}),t.handle("penzor:upload",async(w,x)=>{if(!t.isTrustedSender(w))return{ok:!1,error:"untrusted"};let b=x??{},I=Array.isArray(b.paths)?b.paths.filter(oe=>typeof oe=="string"&&Il(oe)):[],U=typeof b.parentId=="string"&&po.test(b.parentId)?b.parentId:null,B=typeof b.projectSource=="string"&&mo.test(b.projectSource)?b.projectSource:null;if(!I.length)return{ok:!1,error:"no_files"};if(!U||!B)return{ok:!1,error:"bad_target"};let{base:J,token:se,account:pe}=await a();if(!se)return{ok:!1,error:"not_signed_in"};let X=await H(I);if(X==="too_many")return{ok:!1,error:"too_many",max:2e3};if(!X.length)return{ok:!1,error:"no_files"};let de=X.filter(oe=>oe.size<=52428800).reduce((oe,Ee)=>oe+Ee.size,0);try{let oe=await p(J,se,"/storage/quota",{}),Ee=Number(oe.json?.used),fe=Number(oe.json?.quota);if(oe.status===200&&fe>0&&Ee+de>fe)return{ok:!1,error:"quota",short:Ee+de-fe}}catch{}if((await a()).account!==pe)return{ok:!1,error:"account_changed"};let Z=In(),ke=X.map(oe=>M({kind:"up",name:So(oe.path),size:oe.size,projectSource:B,parentId:oe.relDir.length?null:U,targetId:U,fileId:null,localPath:oe.path,batch:Z,account:pe,relDir:oe.relDir},oe.size>52428800?"too_large":void 0).id);return f(),{ok:!0,ids:ke,batch:Z}}),t.handle("penzor:download",async(w,x)=>{if(!t.isTrustedSender(w))return{ok:!1,error:"untrusted"};let b=x??{},I=Dl.includes(b.mode)?b.mode:null,U=An(b.name);if(!I)return{ok:!1,error:"bad_mode"};if(!U)return{ok:!1,error:"bad_name"};let{base:B,token:J,account:se}=await a();if(typeof b.path!="string"||!Ge(B,b.path))return{ok:!1,error:"bad_path"};if(!J)return{ok:!1,error:"not_signed_in"};let pe=b.subdir==null?null:An(b.subdir),X=M({kind:"down",name:U,size:Math.max(0,Number(b.size)||0),localPath:null,batch:typeof b.batch=="string"&&b.batch.length<=64?b.batch:In(),account:se,relDir:[],dl:{path:b.path,mode:I,name:U,subdir:pe}});return f(),{ok:!0,id:X.id}}),t.handle("penzor:transfers",w=>t.isTrustedSender(w)?{ok:!0,items:o.map(c)}:{ok:!1,error:"untrusted"}),t.handle("penzor:transfer",(w,x)=>{if(!t.isTrustedSender(w))return{ok:!1,error:"untrusted"};let b=x??{},I=o.find(B=>B.id===b.id);if(!I)return{ok:!1,error:"not_found"};let U=()=>{I.abort?.abort(),I.abort=null,I.done=0,I.samples=[]};switch(b.op){case"pause":(I.state==="active"||I.state==="queued")&&(U(),I.state="paused",f());break;case"resume":I.state==="paused"&&(I.state="queued",f());break;case"cancel":(I.state==="active"||I.state==="queued"||I.state==="paused")&&(U(),u(I,"canceled"));break;case"retry":(I.state==="failed"||I.state==="canceled")&&(I.state="queued",I.error=null,I.finishedAt=null,I.done=0,f());break;case"dismiss":I.state!=="active"&&I.state!=="queued"&&o.splice(o.indexOf(I),1);break;default:return{ok:!1,error:"bad_op"}}return{ok:!0}}),t.handle("penzor:transfers:clear",(w,x)=>{if(!t.isTrustedSender(w))return{ok:!1,error:"untrusted"};let b=x?.which==="all";for(let I of[...o])(I.state==="done"||I.state==="canceled"||b&&I.state==="failed")&&o.splice(o.indexOf(I),1);return{ok:!0}}),t.addQuitGuard?.(w=>{let x=o.filter(b=>b.state==="active"||b.state==="queued"||b.state==="paused").length;return x?w==="zh"?{message:`\u8FD8\u6709 ${x} \u4E2A\u6587\u4EF6\u6CA1\u4F20\u5B8C`,detail:"\u73B0\u5728\u9000\u51FA\u4F1A\u4E2D\u65AD\uFF0C\u4E0B\u6B21\u6253\u5F00\u8981\u91CD\u65B0\u4F20\u3002"}:{message:x===1?"1 file hasn't finished transferring":`${x} files haven't finished transferring`,detail:"Quitting now stops them. You will need to start them again next time."}:null}),{list:()=>o.map(c)}}import{readFileSync as Nl,writeFileSync as jl,mkdirSync as Ul,chmodSync as Fl,renameSync as Ll}from"node:fs";import{join as zl}from"node:path";function Oe(t,e){try{let n=new URL(t);if(n.protocol!=="https:"&&n.protocol!=="http:")return null;let r=e.split(".")[1];if(!r)return null;let s=r.replace(/-/g,"+").replace(/_/g,"/"),o=Uint8Array.from(atob(s),a=>a.charCodeAt(0)),i=JSON.parse(new TextDecoder().decode(o)),l=i.userId??i.sub;return typeof l!="string"&&typeof l!="number"||!String(l).trim()?null:`${n.origin}${n.pathname.replace(/\/+$/,"")}::${String(l)}`}catch{return null}}function Tr(t){try{let e=t.split(".")[1];if(!e)return null;let n=JSON.parse(rt(gn(e)));return n&&typeof n=="object"?n:null}catch{return null}}function Ar(t,e=Date.now()){let n=Tr(t)?.iat;return typeof n=="number"?e-n*1e3:1/0}function ko(t,e=Date.now()){let n=Tr(t)?.exp;return typeof n=="number"?n*1e3-e:1/0}var Ol=36e5;function Pn(t,e=Date.now()){return!!t&&Ar(t,e)>=Ol}async function Rn(t,e,n=8e3,r){if(!t||!e)return null;let s=t.replace(/\/+$/,"");try{let o=await fetch(`${s}/api/auth/refresh`,{method:"POST",headers:{Authorization:`Bearer ${e}`,...r?{"X-Forsion-Client":r}:{}},signal:AbortSignal.timeout(n)});if(!o.ok)return null;let i=await o.json().catch(()=>null),l=typeof i?.token=="string"?i.token:"";return l&&l!==e?l:null}catch{return null}}var qt=(t,e)=>`${t.replace(/\/+$/,"")}\0${e}`,Ml=(t,e)=>new Promise((n,r)=>{let s=()=>{clearTimeout(o),r(new Error("Sign-in cancelled."))},o=setTimeout(()=>{e.removeEventListener("abort",s),n()},t);e.aborted?s():e.addEventListener("abort",s,{once:!0})});function Eo(t,e){let n=f=>e.write(JSON.stringify(f,null,2)),r=()=>{try{let f=JSON.parse(e.read()??"");return Array.isArray(f.accounts)?f.accounts.filter(m=>m&&typeof m.token=="string"&&m.id===Oe(m.cloudUrl,m.token)):[]}catch{return[]}},s=(f,m)=>{let h=Oe(f.cloudUrl||"",f.token||"");if(!h||!f.token||!f.cloudUrl)return;let g=r(),p=g.find(O=>O.id===h),y=Tr(f.token),E={...p,id:h,cloudUrl:f.cloudUrl.replace(/\/+$/,""),token:f.token,username:m?.username||p?.username||y?.username,nickname:m?.nickname||p?.nickname};JSON.stringify(p)!==JSON.stringify(E)&&n({version:1,accounts:[...g.filter(O=>O.id!==h),E]})},o=()=>{let f=t.readCreds();s(f);let m=Oe(f.cloudUrl,f.token);return r().map(({token:h,...g})=>({...g,active:g.id===m}))},i=f=>{let m=r().find(h=>h.id===f);if(!m)throw new Error("Account is no longer signed in. Sign in again.");return{cloudUrl:m.cloudUrl,token:m.token}},l=f=>{let m=Oe(f.cloudUrl||"",f.token||"");m&&n({version:1,accounts:r().filter(h=>h.id!==m)})},a=null;return{rememberForsionAccount:s,forsionAccounts:o,savedForsionAccount:i,forgetForsionAccount:l,cancelForsionLogin:()=>{a?.abort(),a=null},forsionDeviceLogin:async(f,m,h)=>{if(a)throw new Error("A sign-in is already in progress.");if(!f)throw new Error("\u8BF7\u5148\u586B\u5199 Forsion \u4E91\u7AEF\u5730\u5740(\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF TANGU_CLOUD_URL)");let g=new AbortController;a=g;let p=()=>{if(g.signal.aborted||a!==g)throw new Error("Sign-in cancelled.")};try{let y=f.replace(/\/+$/,""),E;try{E=await fetch(`${y}/api/auth/cli/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:"{}",signal:AbortSignal.any([g.signal,AbortSignal.timeout(15e3)])}).then(x=>x.json())}catch(x){throw new Error(`\u65E0\u6CD5\u8FDE\u63A5 ${y}:${x?.message||x}`)}if(p(),!E?.device_code)throw new Error("\u4E91\u7AEF\u4E0D\u652F\u6301 CLI \u767B\u5F55(/api/auth/cli/start \u8FD4\u56DE\u5F02\u5E38)");let O=E.verification_uri_complete||`${E.verification_uri}?code=${E.user_code}`,C=new URL(`${y}/auth`);C.searchParams.set("logout","1"),C.searchParams.set("app","forsion-desktop"),C.searchParams.set("redirect",O);let M=C.toString();m?.({url:M,userCode:String(E.user_code||"")}),t.openExternal(M);let H=Date.now()+(E.expires_in||600)*1e3,w=(E.interval||2)*1e3;for(;Date.now()<H;){await Ml(w,g.signal),p();let x=null;try{x=await fetch(`${y}/api/auth/cli/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_code:E.device_code}),signal:AbortSignal.any([g.signal,AbortSignal.timeout(15e3)])})}catch{p();continue}if(p(),x.status===410)throw new Error("\u767B\u5F55\u7801\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u53D1\u8D77\u767B\u5F55");let b=await x.json().catch(()=>({status:"pending"}));if(p(),b.status==="approved"&&b.token){let I={cloudUrl:y,token:b.token};return await h(I,p),p(),{token:b.token,cloudUrl:y}}}throw new Error("\u767B\u5F55\u8D85\u65F6,\u8BF7\u91CD\u8BD5")}finally{a===g&&(a=null)}},readAccounts:r}}function Hl(t){let e=()=>zl(t(),"auth-accounts.json");return{read:()=>Nl(e(),"utf8"),write:n=>{Ul(t(),{recursive:!0});let r=`${e()}.tmp`;jl(r,n,{encoding:"utf8",mode:384}),Fl(r,384),Ll(r,e())}}}var Co=t=>Eo(t,Hl(()=>t.homeDir())),xo=["homeDir","appVersion","broadcast","accountBackendState","accountTransition","accountCommit","accountClear","writeCreds","onExternalCredsChange","setTokenRefresher","readCreds"],Ir=t=>xo.every(e=>typeof t[e]=="function");function Pr(t){let e={ok:!1,error:"untrusted"},n={loggedIn:!1,error:"untrusted"},r=Co(t),s=0,o=()=>{let l=t.readCreds();return qt(l.cloudUrl,l.token)},i=null;t.handle("auth:status",async l=>{if(!t.isTrustedSender(l))return n;let a=s,c=o(),{base:u}=await t.getCloud(),f=t.readCreds().token,m=f?await Lt(u,f):null,h=await t.accountBackendState(),{base:g}=await t.getCloud(),p=t.readCreds(),y=qt(g,p.token)!==qt(u,f),E=qt(u,f);!y&&m?.status==="ok"&&m.user&&(i={key:E,user:m.user},r.rememberForsionAccount({...p,cloudUrl:u},m.user));let O=y?void 0:m?.status==="ok"?m.user:m?.status==="offline"&&i?.key===E?i.user:void 0;if(y)return{loggedIn:!!p.token,tokenValid:null,cloudUrl:g,accountId:Oe(g,p.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:p.token?"tangu-login":null,backendState:h};if(m?.status==="expired"){await t.accountTransition(async()=>{if(a!==s||o()!==c)return;let M=()=>{if(a!==s||o()!==c)throw _o};try{await t.accountClear(M,()=>{t.log("[auth] token \u5DF2\u5931\u6548(\u670D\u52A1\u7AEF 401/403),\u81EA\u52A8\u767B\u51FA"),++s,r.cancelForsionLogin(),r.forgetForsionAccount(t.readCreds()),i=null})}catch(H){if(H!==_o)throw H}});let C=t.readCreds();return{loggedIn:!!C.token,tokenValid:null,cloudUrl:C.cloudUrl||u,accountId:Oe(C.cloudUrl||u,C.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:C.token?"tangu-login":null,backendState:h}}return{loggedIn:!!f,tokenValid:m&&m.status==="ok"?!0:null,cloudUrl:u,accountId:Oe(u,f),username:O?.username||null,nickname:O?.nickname||null,avatar:O?.avatar||null,membershipTier:O?.membershipTier||null,tokenSource:f?"tangu-login":null,backendState:h}}),t.handle("auth:accounts",l=>t.isTrustedSender(l)?r.forsionAccounts():[]),t.handle("auth:switchAccount",async(l,a)=>{if(!t.isTrustedSender(l))return e;if(typeof a!="string")throw new Error("Invalid account.");let c=++s;return r.cancelForsionLogin(),t.accountTransition(async()=>{let u=r.savedForsionAccount(a);return await t.accountCommit(u,()=>{if(c!==s)throw new Error("Account switch cancelled.")},()=>{r.rememberForsionAccount(u),i=null}),{ok:!0,cloudUrl:u.cloudUrl||""}})}),t.handle("auth:forsionLogin",async(l,a)=>{if(!t.isTrustedSender(l))return e;let c=++s;r.cancelForsionLogin();let{base:u}=await t.getCloud();if(c!==s)throw new Error("Sign-in cancelled.");let f=(a||u||"").trim();return{ok:!0,cloudUrl:(await r.forsionDeviceLogin(f,h=>t.broadcast("auth:device",h),(h,g)=>t.accountTransition(()=>t.accountCommit(h,()=>{if(g(),c!==s)throw new Error("Sign-in cancelled.")},()=>{r.rememberForsionAccount(h),i=null})))).cloudUrl}}),t.handle("auth:logout",async l=>t.isTrustedSender(l)?(++s,r.cancelForsionLogin(),t.accountTransition(async()=>{let{base:a}=await t.getCloud(),c=t.readCreds();return await t.accountClear(void 0,()=>{r.forgetForsionAccount(c),i=null,a&&c.token&&fetch(`${a}/api/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${c.token}`},signal:AbortSignal.timeout(5e3)}).catch(()=>{})}),{ok:!0}})):e),t.onExternalCredsChange(({previous:l,current:a})=>{++s,r.cancelForsionLogin(),l.token&&!a.token&&r.forgetForsionAccount(l),i=null,r.rememberForsionAccount(a)}),t.setTokenRefresher(async l=>{let a=s,c=o(),u=t.readCreds().token;if(!Pn(u))return;let{base:f}=await t.getCloud(),m=await Rn(f,u,l,`desktop/${t.appVersion()}`);if(!m){t.log("[auth] \u6ED1\u52A8\u7EED\u671F\u672A\u6210\u529F(\u79BB\u7EBF/\u8001\u7248\u672C server/\u8FD9\u679A\u5DF2\u5931\u6548),\u7EE7\u7EED\u7528\u65E7 token");return}a!==s||o()!==c||(r.rememberForsionAccount({cloudUrl:f,token:m}),t.writeCreds({cloudUrl:f,token:m}),t.log("[auth] \u767B\u5F55\u6001\u5DF2\u6ED1\u52A8\u7EED\u671F(\u6709\u6548\u671F\u91CD\u65B0\u8BA1\u6EE1 2 \u5468)"))}),t.log("[forsion-extend] account core registered")}var _o=Symbol("stale-auth-intent");import{promises as Tt}from"node:fs";import ht from"node:path";import{execFile as uc}from"node:child_process";import dc from"node:os";var Rr=null;function To(t){Rr=t}function Ie(){if(!Rr)throw new Error("amadeus sync env not set (registerAmadeus factory has not run)");return Rr}var Te=()=>Ie().accountId();function Bt(t=Te()){return t?Se().sha256Hex(t):"signed-out"}var Me=(t=Te())=>Ie().readConfig(t),Xe=(t,e=Te())=>Ie().writeConfig(t,e),Et=(t,e=Te())=>Ie().updateConfig(t,e),st=(t=Te())=>Ie().cloudVaultDir(t),Dn=t=>Ie().isManagedCloudVault(t);function ql(t,e){let n=Object.create(null);for(let o=0;o<e.length;o++){let i=e[o];n[i]?n[i].push(o):n[i]=[o]}let s=[{buffer1index:-1,buffer2index:-1,chain:null}];for(let o=0;o<t.length;o++){let i=t[o],l=n[i]||[],a=0,c=s[0];for(let u of l){let f;for(f=a;f<s.length&&!(s[f].buffer2index<u&&(f===s.length-1||s[f+1].buffer2index>u));f++);if(f<s.length){let m={buffer1index:o,buffer2index:u,chain:s[f]};if(a===s.length?s.push(c):s[a]=c,a=f+1,c=m,a===s.length)break}}s[a]=c}return s[s.length-1]}function Ao(t,e){let n=ql(t,e),r=[],s=t.length,o=e.length;for(let i=n;i!==null;i=i.chain){let l=s-i.buffer1index-1,a=o-i.buffer2index-1;s=i.buffer1index,o=i.buffer2index,(l||a)&&r.push({buffer1:[s+1,l],buffer1Content:t.slice(s+1,s+1+l),buffer2:[o+1,a],buffer2Content:e.slice(o+1,o+1+a)})}return r.reverse(),r}function Bl(t,e,n){let r=[];function s(a,c){r.push({ab:c,oStart:a.buffer1[0],oLength:a.buffer1[1],abStart:a.buffer2[0],abLength:a.buffer2[1]})}Ao(e,t).forEach(a=>s(a,"a")),Ao(e,n).forEach(a=>s(a,"b")),r.sort((a,c)=>a.oStart-c.oStart);let o=[],i=0;function l(a){a>i&&(o.push({stable:!0,buffer:"o",bufferStart:i,bufferLength:a-i,bufferContent:e.slice(i,a)}),i=a)}for(;r.length;){let a=r.shift(),c=a.oStart,u=a.oStart+a.oLength,f=[a];for(l(c);r.length;){let m=r[0],h=m.oStart;if(h>u)break;u=Math.max(u,h+m.oLength),f.push(r.shift())}if(f.length===1){if(a.abLength>0){let m=a.ab==="a"?t:n;o.push({stable:!0,buffer:a.ab,bufferStart:a.abStart,bufferLength:a.abLength,bufferContent:m.slice(a.abStart,a.abStart+a.abLength)})}}else{let m={a:[t.length,-1,e.length,-1],b:[n.length,-1,e.length,-1]};for(;f.length;){a=f.shift();let O=a.oStart,C=O+a.oLength,M=a.abStart,H=M+a.abLength,w=m[a.ab];w[0]=Math.min(M,w[0]),w[1]=Math.max(H,w[1]),w[2]=Math.min(O,w[2]),w[3]=Math.max(C,w[3])}let h=m.a[0]+(c-m.a[2]),g=m.a[1]+(u-m.a[3]),p=m.b[0]+(c-m.b[2]),y=m.b[1]+(u-m.b[3]),E={stable:!1,aStart:h,aLength:g-h,aContent:t.slice(h,g),oStart:c,oLength:u-c,oContent:e.slice(c,u),bStart:p,bLength:y-p,bContent:n.slice(p,y)};o.push(E)}i=u}return l(e.length),o}function Io(t,e,n,r){r=Object.assign({excludeFalseConflicts:!0,stringSeparator:/\s+/},r),typeof t=="string"&&(t=t.split(r.stringSeparator)),typeof e=="string"&&(e=e.split(r.stringSeparator)),typeof n=="string"&&(n=n.split(r.stringSeparator));let o=[],i=Bl(t,e,n),l=[];function a(){l.length&&o.push({ok:l}),l=[]}function c(u,f){if(u.length!==f.length)return!1;for(let m=0;m<u.length;m++)if(u[m]!==f[m])return!1;return!0}return i.forEach(u=>{u.stable?l.push(...u.bufferContent):r.excludeFalseConflicts&&c(u.aContent,u.bContent)?l.push(...u.aContent):(a(),o.push({conflict:{a:u.aContent,aIndex:u.aStart,o:u.oContent,oIndex:u.oStart,b:u.bContent,bIndex:u.bStart}}))}),a(),o}function $n(t,e){let n=t.lastIndexOf("/"),r=n<0?"":t.slice(0,n+1),s=n<0?t:t.slice(n+1),o=s.lastIndexOf("."),i=o>0?s.slice(0,o):s,l=o>0?s.slice(o):"",a=u=>String(u).padStart(2,"0"),c=`${e.getFullYear()}-${a(e.getMonth()+1)}-${a(e.getDate())} ${a(e.getHours())}${a(e.getMinutes())}`;return`${r}${i} (conflict ${c})${l}`}function Wl(t,e){if(e<2)return t;let n=t.lastIndexOf("."),r=n>t.lastIndexOf("/")&&n>t.lastIndexOf(")"),s=r?t.slice(0,n):t,o=r?t.slice(n):"";return`${s}-${e}${o}`}function Vl(t){let e=3735928559,n=1103547991;for(let s=0;s<t.length;s++){let o=t.charCodeAt(s);e=Math.imul(e^o,2654435761),n=Math.imul(n^o,1597334677)}e=Math.imul(e^e>>>16,2246822507)^Math.imul(n^n>>>13,3266489909),n=Math.imul(n^n>>>16,2246822507)^Math.imul(e^e>>>13,3266489909);let r=4294967296*(2097151&n)+(e>>>0);return`${t.length.toString(36)}-${r.toString(36)}`}function On(t,e,n){if(t===null&&e===null&&n===null)return{kind:"none"};if(n===null)return t===null?e?{kind:"dropShadow"}:{kind:"none"}:e?t===e.hash?{kind:"deleteLocal"}:{kind:"pushCreate"}:{kind:"pushCreate"};if(t===null)return e?n.seq===e.seq?{kind:"pushDelete"}:{kind:"pull"}:{kind:"pull"};if(!e)return t===n.hash?{kind:"adopt"}:{kind:"conflict"};let r=t!==e.hash,s=n.seq!==e.seq;return!r&&!s?{kind:"none"}:r?s?t===n.hash?{kind:"adopt"}:n.hash===e.hash?{kind:"push",baseSeq:n.seq}:{kind:"conflict"}:{kind:"push",baseSeq:e.seq}:{kind:"pull"}}function Po(t,e,n){let r=Io(t.split(`
204
204
  `),e.split(`
205
205
  `),n.split(`
206
206
  `),{excludeFalseConflicts:!0}),s=[];for(let o of r){if(o.conflict)return null;o.ok&&s.push(...o.ok)}return s.join(`
207
- `)}function cr(t,e,n=200){return t>=n||e>=5&&t>=Math.max(5,Math.ceil(e/2))}var Ya=/[\u0000-\u001f\u007f]/;function mt(t){let e=t.replace(/\\/g,"/").normalize("NFC").trim();if(e=e.replace(/\/+$/,""),!e||e.length>512||e.startsWith("/")||Ya.test(e))return null;let n=e.split("/");for(let r of n)if(!r||r==="."||r==="..")return null;return n.join("/")}function ur(t,e){let n=t.replace(/\\/g,"/").normalize("NFC");return e===""?mt(n):n.startsWith(`${e}/`)?mt(n.slice(e.length+1)):null}function Ys(t,e){return e===""?t:`${e}/${t}`}function $t(t){return!!(t===".DS_Store"||t==="Icon\r"||t===".sync-trash"||/\.tmp-\d+-\d+-\d+$/.test(t)||/^\..+\.lock$/.test(t))}function Le(t){return/\.md$/i.test(t)?"page":/\.db$/i.test(t)?"db":"binary"}var Qe=t=>t==="page"||t==="db";var Ga=1024,xe=class extends Error{status;body;constructor(e,n,r){super(`cloud http ${e} on ${r}`),this.status=e,this.body=n}},Gs=t=>12e4+Math.ceil(t/256);function Js(t){let e=`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus`,n=async(s,o,i)=>{let l={Authorization:`Bearer ${t.token}`,...i?.headers};s!=="GET"&&(l["X-Amadeus-Client"]=t.clientId);let a;i?.json!==void 0?(l["Content-Type"]="application/json",a=JSON.stringify(i.json),a.length>=Ga&&(l["Content-Encoding"]="gzip",a=await qr(a))):i?.form&&(a=i.form);let d=await fetch(o,{method:s,headers:l,body:a,signal:AbortSignal.timeout(i?.timeoutMs??3e4)});if(!d.ok){let u=null;try{u=await d.json()}catch{}throw new xe(d.status,u,o)}return d.json()},r=s=>new URLSearchParams(s).toString();return{clientId:t.clientId,async listVaults(){return((await n("GET",`${e}/vaults`)).vaults??[]).map(o=>({id:String(o.id),name:String(o.name),lastChangeSeq:Number(o.lastChangeSeq??0)}))},async tree(s){let o=await n("GET",`${e}/vaults/${s}/tree`);if(!Array.isArray(o.entries))throw new Error("server too old: tree has no entries[] (deploy the amadeus microserver update)");return{folders:o.folders??[],seq:Number(o.seq??0),maxFileBytes:Number.isInteger(o.maxFileBytes)&&o.maxFileBytes>0?o.maxFileBytes:void 0,entries:o.entries.map(i=>({path:String(i.path),kind:i.kind,seq:Number(i.seq??0),hash:i.hash??null,size:Number(i.size??0)}))}},async getFile(s,o){let i=await n("GET",`${e}/vaults/${s}/file?${r({path:o})}`);return{content:String(i.content??""),seq:Number(i.seq??0),hash:i.hash??null}},putFile(s,o,i,l,a=!1){return n("PUT",`${e}/vaults/${s}/file`,{json:{path:o,content:i,baseSeq:l,...a?{force:!0}:{}}})},async deleteFile(s,o,i,l){let a={path:o};i!==void 0&&(a.baseSeq=String(i)),await n("DELETE",`${e}/vaults/${s}/file?${r(a)}`,l?.confirmed?{headers:{"X-Amadeus-Delete-Confirmed":"1"}}:void 0)},move(s,o,i){return n("POST",`${e}/vaults/${s}/move`,{json:{from:o,to:i}})},renameFolder(s,o,i){return n("POST",`${e}/vaults/${s}/folders/rename`,{json:{path:o,newName:i}})},moveFolder(s,o,i){return n("POST",`${e}/vaults/${s}/folders/move`,{json:{path:o,dest:i}})},async deleteFolder(s,o){await n("DELETE",`${e}/vaults/${s}/folders?${r({path:o})}`)},putBinary(s,o,i,l){let a=new FormData;return a.set("path",o),l?.ifAbsent&&a.set("ifAbsent","true"),l?.baseSeq!==void 0&&a.set("baseSeq",String(l.baseSeq)),a.set("file",new Blob([new Uint8Array(i)]),o.split("/").pop()||"file"),n("POST",`${e}/vaults/${s}/binary`,{form:a,timeoutMs:Gs(i.length)})},async listVersions(s,o){return((await n("GET",`${e}/vaults/${s}/file/versions?${r({path:o})}`)).versions??[]).map(l=>({id:String(l.id),seq:Number(l.seq??0)}))},async getVersion(s,o){let i=await n("GET",`${e}/vaults/${s}/file/versions/${o}`);return String(i.content??"")},async getAsset(s,o){let i=new AbortController,l=setTimeout(()=>i.abort(),12e4);try{let a=await fetch(`${e}/vaults/${s}/asset?${r({ref:o})}`,{headers:{Authorization:`Bearer ${t.token}`},signal:i.signal});if(!a.ok)throw new xe(a.redirected&&(a.status===401||a.status===403)?502:a.status,null,"asset:"+o);return clearTimeout(l),l=setTimeout(()=>i.abort(),Gs(Number(a.headers.get("content-length"))||0)),new Uint8Array(await a.arrayBuffer())}finally{clearTimeout(l)}},async changes(s,o){let i=await n("GET",`${e}/vaults/${s}/changes?${r({since:String(o)})}`);return{changes:i.changes??[],seq:Number(i.seq??0)}}}}function Xs(t,e){let n=!1,r=0,s=null,o=null,i=()=>`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus/vaults/${t.vaultId}/events?since=${e.getSince()}`,l=d=>{if(n)return;e.onDown(d);let u=Math.min(3e4,1e3*2**r)*(.7+Math.random()*.6);r++,o=setTimeout(()=>void a(),u)},a=async()=>{if(n)return;s=new AbortController;let d;try{d=await fetch(i(),{headers:{Authorization:`Bearer ${t.token}`,Accept:"text/event-stream"},signal:s.signal})}catch(w){l(w);return}if(!d.ok||!d.body){l(new Error(`sse http ${d.status}`));return}r=0,e.onOpen();let u=d.body.getReader(),m=new TextDecoder,g="",p="",y=[],f=()=>{if(!y.length&&!p)return;let w=y.join(`
208
- `),P=p||"message";p="",y=[];let H=null;try{H=w?JSON.parse(w):null}catch{return}P==="hello"?e.onHello(Number(H?.seq??0)):P==="change"?e.onChange(H):P==="reset"?e.onReset():P==="presence"?e.onPresence?.(H):P==="presence-roster"&&e.onPresenceRoster?.(H)};try{for(;;){let{done:w,value:P}=await u.read();if(w)break;for(g+=m.decode(P,{stream:!0});;){let H=g.indexOf(`
209
- `);if(H<0)break;let T=g.slice(0,H).replace(/\r$/,"");if(g=g.slice(H+1),T==="")f();else{if(T.startsWith(":"))continue;T.startsWith("event:")?p=T.slice(6).trim():T.startsWith("data:")&&y.push(T.slice(5).replace(/^ /,""))}}}}catch(w){n||l(w);return}l(new Error("sse stream ended"))};return a(),{stop:()=>{n=!0,o&&clearTimeout(o),s?.abort()}}}var Mt=t=>Se().path.join(Ie().userDataDir(),Ie().isDevMode()?`${t}.dev.json`:`${t}.json`),dr=Mt;async function fr(t){try{let e=JSON.parse(await Se().fs.readFile(dr(t),"utf8"));return!e||typeof e.vaultRoot!="string"||typeof e.vaultId!="string"?null:(e.files=e.files??{},e.cursor=Number(e.cursor??0),e.lastSyncAt=e.lastSyncAt??null,e)}catch{return null}}function Ks(t){let e=null,n=null,r=Promise.resolve(),s=null,o=()=>{if(!e)return r;let i=e,l=JSON.stringify(e);return e=null,r=r.then(async()=>{try{let a=dr(t),d=`${a}.tmp-${Se().tmpTag()}-${Date.now()}-0`;await Se().fs.writeFile(d,l,"utf8"),await Se().fs.rename(d,a),s=null}catch(a){e??=i,s=a}}),r};return{save(i){e=i,!n&&(n=setTimeout(()=>{n=null,o()},500))},async flush(i=!1){if(n&&(clearTimeout(n),n=null),await o(),i&&s)throw s}}}async function Zs(t){try{await Se().fs.unlink(dr(t))}catch{}}var Ja=5*1024*1024,Xa=5*1024*1024,Ka=3e4,Za=2500,Qa=3e3,el=5,tl=256*1024,nl=5,Qs=1024*1024,eo=200,rl=6e4,sl=50,ol=".sync-trash",pt=t=>Se().sha256Hex(t);function Ot(t,e={localRoot:Ze(),shadowName:`amadeus-sync-${Pt()}`,vaultId:"first",serverDir:"",excludePrefixes:["\u4E0E\u6211\u5171\u4EAB/"]}){let n=c=>{let S=ur(c,"");if(!S)return null;for(let k of e.excludePrefixes??[])if(S===k.replace(/\/$/,"")||S.startsWith(k))return null;if(e.ignoreNames?.length&&S.split("/").some(k=>e.ignoreNames.includes(k)))return null;let E=e.serverDir?`${e.serverDir}/${S}`:S;return e.inScope&&!e.inScope(E,Le(E))?null:E},r=c=>{let S;if(e.serverDir){if(!c.startsWith(`${e.serverDir}/`))return null;S=c.slice(e.serverDir.length+1)}else{for(let E of e.excludePrefixes??[])if(c.startsWith(E))return null;S=c}return S.split("/").some(E=>$t(E)||!!e.ignoreNames?.includes(E))?null:S},s=(c,S)=>!e.inScope||e.inScope(c,S),o=e.accountId??Te(),{fs:i,path:l}=Se(),a=c=>i.access(c).then(()=>!0,()=>!1),d=!1,u=0,m=Promise.resolve(),g=new Set,p="disabled",y=null,f=null,w=null,P=null,H=null,T=null,U=0,z=new Map,h=null,v=Ks(e.shadowName),b=new Map,A=!1,N=!1,B=[],G=()=>{f&&(f.pending=b.size?Object.fromEntries(b):void 0,v.save(f))},se=()=>{N=!1,B.length=0},pe=()=>{if(N)return!0;let c=Date.now();for(;B.length&&c-B[0]>rl;)B.shift();return B.length>=sl?(N=!0,!0):!1},X=[],de=new Set,Z=!1,Ee=null,oe=null,_e=null,fe=()=>{!d||_e||(_e=setTimeout(()=>{_e=null,t.onStatus(nt())},200))},ye=(c,S)=>{p=c,S!==void 0&&(y=S),fe()},ae=(c,S=!1)=>{if(d){if(c.key){if(de.has(c.key))return;de.add(c.key)}S?X.unshift(c):X.push(c),L()}},be=new Map,_=c=>{if(!d)return;let S=(f?.files[c]?.size??0)>tl,E=(e.pushQuietMs??Qa)*(S?nl:1),k=Date.now(),R=be.get(c);R&&clearTimeout(R.timer);let F=R?.since??k,q=Math.max(0,Math.min(E,F+E*el-k)),j=setTimeout(()=>{be.delete(c),ae({key:c,run:()=>ve(c,!0)})},q);be.set(c,{timer:j,since:F}),fe()},I=()=>{for(let{timer:c}of be.values())clearTimeout(c);be.clear()},x=c=>!(c instanceof xe)||c.status>=500||c.status===0,C=c=>c instanceof xe&&(c.status===401||c.status===403),L=async()=>{if(!Z){Z=!0;try{for(;X.length;){(p==="idle"||p==="starting")&&ye("syncing");let c=X.shift();c.key&&de.delete(c.key);try{await c.run()}catch(S){if(!d)return;if(C(S)){X.length=0,de.clear(),Kt(),ye("auth-required","login-expired");return}if(x(S)){ae(c,!0),Kt(),ye("offline",S?.message||"network error"),D();return}let E=c.key??"(op)";z.set(E,S?.body?.code||`http ${S?.status}`),fe()}}d&&p==="syncing"&&(f&&(f.lastSyncAt=Date.now(),v.save(f)),ye("idle",null))}finally{Z=!1;for(let c of g)c();g.clear()}}},D=()=>{!d||Ee||(Ee=setTimeout(()=>{Ee=null,_t()},Ka))},$=c=>{if(!T||!f)throw new Error("engine not bound");let S=r(c);if(S===null)throw new Error("path outside binding: "+c);let E=l.resolve(T,Ys(S,f.folder)),k=l.relative(T,E);if(k.startsWith("..")||l.isAbsolute(k))throw new Error("path escapes vault: "+c);return E},M=c=>({size:c,mtimeMs:-1}),Y=async c=>{try{let S=await i.stat(c);return S.isFile()?{size:S.size,mtimeMs:Math.floor(S.mtimeMs)}:null}catch{return null}},W=0,J=async(c,S,E=()=>!0)=>{await i.mkdir(l.dirname(c),{recursive:!0});let k=`${c}.tmp-${Se().tmpTag()}-${Date.now()}-${W++}`;await i.writeFile(k,S);let R=await Y(k)??M(Mn(S));return E()?(await i.rename(k,c),R):(await i.rm(k,{force:!0}),null)},le=async c=>{let S;try{S=await i.readdir(c,{withFileTypes:!0})}catch{return}for(let E of S)E.isDirectory()&&await le(l.join(c,E.name));try{await i.rmdir(c)}catch{}},ie=async c=>{let S=$(c),E=await Y(S),k;try{k=await i.readFile(S)}catch{return null}return{hash:Qe(Le(c))?pt(Ke(k)):pt(k),size:E?.size??k.length,mtimeMs:E?.mtimeMs??-1,buf:k}},me=async(c,S,E,k)=>{f&&(f.files[c]={seq:S,hash:E,size:k.size,mtimeMs:k.mtimeMs},v.save(f))},ce=c=>{f&&c in f.files&&(delete f.files[c],v.save(f))},ue=async(c,S)=>{if(!w||!f||Ne(c))return;let E=we,k=Le(c),R,F,q;if(Qe(k)){let K;try{K=await w.getFile(f.vaultId,c)}catch(te){if(te instanceof xe&&te.status===404){await Re(c);return}throw te}R=K.content,F=K.seq,q=K.hash??pt(K.content)}else{let K;try{K=await w.getAsset(f.vaultId,c)}catch(te){if(te instanceof xe&&te.status===404){z.set(c,"ASSET_404"),fe();return}throw te}R=K,F=S??0,q=pt(K)}let j=await ie(c);if(E!==we||Ne(c))return;if(j&&j.hash===q){await me(c,F,q,j);return}let V=f.files[c];if(j&&V&&q===V.hash&&j.hash!==V.hash){await me(c,F,q,M(V.size)),ae({key:c,run:()=>ve(c)});return}if(j&&(!V||j.hash!==V.hash)&&(V&&k==="page"&&typeof R=="string"&&await Ue(c,V,j,R,F,q,()=>E===we&&!Ne(c))||E!==we||Ne(c)||!await it(c,()=>E===we&&!Ne(c))))return;let O=await J($(c),R,()=>E===we&&!Ne(c));O&&await me(c,F,q,O)},Ue=async(c,S,E,k,R,F,q)=>{try{if(!w||!f||E.buf.length>Qs||k.length>Qs)return!1;let V=(await w.listVersions(f.vaultId,c)).find(te=>te.seq===S.seq);if(!V)return!1;let O=await w.getVersion(f.vaultId,V.id);if(pt(O)!==S.hash)return!1;let K=Vs(Ke(E.buf),O,k);return K===null?!1:(await J($(c),K,q)&&(await me(c,R,F,M(Mn(K))),ae({key:c,run:()=>ve(c)})),!0)}catch{return!1}},it=async(c,S)=>{let E=mt(wn(c,new Date));if(!E)return!0;let k=E.lastIndexOf("."),R=k>E.lastIndexOf("/"),F=R?E.slice(0,k):E,q=R?E.slice(k):"",j=E,V=Se().existsSync;if(V)for(let O=2;V($(j));O++)j=`${F}-${O}${q}`;else for(let O=2;await a($(j));O++)j=`${F}-${O}${q}`;if(!S())return!1;try{await i.rename($(c),$(j))}catch(O){if(O?.code==="ENOENT")return!0;throw O}return U++,ae({key:j,run:()=>ve(j)}),fe(),!0},at=async c=>{if(!T)return;let S=$(c),E=r(c)??c,k=l.join(T,ol,new Date().toISOString().slice(0,10),...E.split("/")),R=await a(k)?`${k}.${Date.now()}`:k;try{await i.mkdir(l.dirname(R),{recursive:!0}),await i.rename(S,R)}catch(F){if(F?.code==="ENOENT")return;throw new Error(`\u8F6F\u5220\u5931\u8D25,\u4FDD\u7559\u672C\u5730\u6587\u4EF6 ${S}: ${F?.message??String(F)}`)}},Re=async c=>{if(!f)return;let S=await ie(c);if(Ne(c))return;let E=f.files[c]??null,k=bn(S?.hash??null,E,null);if(k.kind==="deleteLocal"){if(!A&&pe()){b.set(c,"local"),G(),fe();return}B.push(Date.now()),await at(c),ce(c)}else k.kind==="pushCreate"?(ce(c),ae({key:c,run:()=>ve(c)})):ce(c)},Dr=(c,S)=>{if(f){for(let E of Object.keys(f.files))if(E===c||E.startsWith(`${c}/`)){let k=S+E.slice(c.length);f.files[k]=f.files[E],delete f.files[E]}v.save(f)}},Pr=async c=>{if(!w||!f||c.seq<=f.cursor||!await Gt())return;if(c.origin.client&&w.clientId===c.origin.client){f.cursor=c.seq,v.save(f);return}let S=c.type==="structure"?"folder":c.type,E=R=>r(R)!==null&&s(R,S);if(!E(c.path)&&!(c.newPath&&E(c.newPath))){f.cursor=c.seq,v.save(f);return}let k=c.path;switch(c.op){case"write":await ue(k,c.fileSeq);break;case"delete":await Re(k);break;case"move":{let R=c.newPath;if(!R)break;let F=f.files[k];if(await ie(k)&&F)try{await i.mkdir(l.dirname($(R)),{recursive:!0}),await i.rename($(k),$(R)),f.files[R]={...F,seq:c.fileSeq??F.seq},delete f.files[k],v.save(f)}catch{await ue(R,c.fileSeq)}else ce(k),await ue(R,c.fileSeq);break}case"mkdir":await i.mkdir($(k),{recursive:!0});break;case"rename-folder":case"move-folder":{let R=c.newPath;if(!R)break;try{await i.mkdir(l.dirname($(R)),{recursive:!0}),await i.rename($(k),$(R))}catch{}Dr(k,R);break}case"delete-folder":{let R=`${k}/`;for(let F of Object.keys(f.files))(F===k||F.startsWith(R))&&await Re(F);await le($(k));break}}if(f.cursor=c.seq,v.save(f),c.op==="move"||c.op==="rename-folder"||c.op==="move-folder"||c.op==="delete"||c.op==="delete-folder")try{await t.onRemoteApplied?.(c)}catch{}},Jo=async(c,S,E)=>{let k=Number(S?.seq??0),R=S?.content??null;if(R!==null&&pt(R)===E.hash){await me(c,k,E.hash,E);return}if(R===null&&k===0){if(!f?.files[c]){z.set(c,S?.code||"EXISTS"),fe();return}ce(c),ae({key:c,run:()=>ve(c)});return}await ue(c,k)},Vt=async(c,S)=>{if(!w||!f)return;let E=await ie(c);if(!E){ae({key:c,run:()=>ve(c)});return}if(E.size>Ja){z.set(c,"TOO_LARGE"),fe();return}let k=Ke(E.buf);try{let R=await w.putFile(f.vaultId,c,k,S);z.delete(c),await me(c,R.seq,R.hash??E.hash,E)}catch(R){if(R instanceof xe&&R.status===409){await Jo(c,R.body,E);return}throw R}},Yt=async(c,S)=>{if(!w||!f)return;let E=await ie(c);if(!E){ae({key:c,run:()=>ve(c)});return}if(E.size>(h??Xa)){z.set(c,"TOO_LARGE"),fe();return}try{let k=await w.putBinary(f.vaultId,c,E.buf,{baseSeq:S});z.delete(c),await me(c,k.seq,E.hash,E)}catch(k){if(k instanceof xe&&k.status===409){let R=Number(k.body?.seq??0),F=k.body?.hash??null;if(F!==null&&F===E.hash){await me(c,R,E.hash,E);return}if(R===0){if(!f.files[c]){z.set(c,k.body?.code||"EXISTS"),fe();return}ce(c),ae({key:c,run:()=>ve(c)});return}await ue(c,R);return}throw k}},$r=async c=>{if(!w||!f||Ne(c))return;let S=we,E=f.files[c];if(E){if(Qe(Le(c)))try{let k=await w.getFile(f.vaultId,c);if(k.seq!==E.seq){await ue(c,k.seq);return}}catch(k){if(k instanceof xe&&k.status===404){ce(c);return}throw k}if(!(S!==we||Ne(c))){try{await w.deleteFile(f.vaultId,c,E.seq,{confirmed:A})}catch(k){if(k instanceof xe&&k.status===409){await ue(c,Number(k.body?.seq??0)||null);return}if(k instanceof xe&&k.status===429&&k.body?.code==="MASS_DELETE_BLOCKED"){b.set(c,"remote"),N=!0,G(),fe();return}throw k}ce(c)}}},Gt=async()=>T?await i.stat(T).then(S=>S.isDirectory()).catch(()=>!1)||!e.requireRootExists&&!Object.keys(f?.files??{}).length?!0:(ye("error",`vault-missing: ${T}`),D(),!1):!1,we=0,Jt=new Set,Xt=new Map,De=c=>JSON.stringify([c.from,c.to]),Xe=(c,S)=>c===S||c.startsWith(`${S}/`),Ne=c=>[...f?.moves??[],...Jt].some(S=>Xe(c,S.from)||Xe(c,S.to)),Be=()=>!!(f?.moves?.length||Jt.size),Dn=async c=>{if(!w||!f)return;let{from:S,to:E,kind:k}=c;if(r(S)===null||r(E)===null)throw new Error("Invalid queued cloud move");c.hashes??=Object.fromEntries(Object.entries(f.files).filter(([j])=>Xe(j,S)).map(([j,V])=>[j.slice(S.length),V.hash])),v.save(f),await v.flush(!0);let R,F=!1;try{if(k==="folder"){let j=l.posix.dirname(S)==="."?"":l.posix.dirname(S),V=l.posix.dirname(E)==="."?"":l.posix.dirname(E);j===V?await w.renameFolder(f.vaultId,S,l.posix.basename(E)):await w.moveFolder(f.vaultId,S,V)}else{let j=await w.move(f.vaultId,S,E);R=Number(j.seq)}}catch(j){if(!(j instanceof xe)||j.status!==404)throw j;let V=await w.tree(f.vaultId);if(V.entries.some(te=>Xe(te.path,S))||V.folders.some(te=>Xe(te,S)))throw j;let K=V.entries.find(te=>te.path===E);if(R=K?.seq,F=!K&&!V.entries.some(te=>Xe(te.path,E))&&!V.folders.some(te=>Xe(te,E)),!F){let te=Object.entries(c.hashes);if(!(te.length>0&&te.every(([Fe,lt])=>V.entries.some(ct=>ct.path===E+Fe&&ct.hash===lt))))throw new xe(409,{code:"MOVE_DESTINATION_CHANGED"},"local-move")}}if(F)for(let j of Object.keys(f.files))Xe(j,S)&&delete f.files[j];else Dr(S,E),R!==void 0&&f.files[E]&&(f.files[E].seq=R);f.moves=(f.moves??[]).filter(j=>De(j)!==De(c)),v.save(f);try{await v.flush(!0)}catch(j){throw f.moves.unshift(c),v.save(f),j}let q=Xt.get(De(c));Xt.delete(De(c)),q?.(),Ne(E)||(k==="folder"?await Pn():await ve(E))},ve=async(c,S=!1)=>{if(!f||Ne(c))return;if(!s(c,Le(c))){ce(c);return}if(!await Gt())return;let E=await ie(c);if(Ne(c))return;let k=f.files[c]??null,R=bn(E?.hash??null,k,k?{seq:k.seq,hash:k.hash}:null);switch(R.kind){case"push":Qe(Le(c))?await Vt(c,R.baseSeq):await Yt(c,R.baseSeq);break;case"pushCreate":Qe(Le(c))?await Vt(c,0):await Yt(c,0);break;case"pushDelete":if(S){Qt();break}if(!A&&(b.has(c)||pe())){b.set(c,"remote"),G(),fe();break}B.push(Date.now()),await $r(c);break;case"dropShadow":ce(c);break;default:E&&k&&E.hash===k.hash&&E.mtimeMs>=0&&(k.size!==E.size||k.mtimeMs!==E.mtimeMs)&&await me(c,k.seq,k.hash,E);break}},Mr=async()=>{let c=new Map;if(!T||!f)return c;let S=T,E=null,k=async R=>{if(E)return;let F;try{F=await i.readdir(R,{withFileTypes:!0})}catch(q){E=`${R}: ${q?.message??String(q)}`;return}for(let q of F){if($t(q.name)||q.isDirectory()&&e.ignoreNames?.includes(q.name))continue;let j=l.join(R,q.name);if(q.isDirectory())await k(j);else if(q.isFile()){let V=l.relative(S,j).split(l.sep).join("/"),O=n(V);if(!O)continue;try{let K=await i.stat(j);if(!K.isFile())continue;c.set(O,{size:K.size,mtimeMs:Math.floor(K.mtimeMs)})}catch(K){if(K?.code==="ENOENT")continue;E=`${j}: ${K?.message??String(K)}`;return}}}};return await k(S),E?(ye("error",`scan-failed: ${E}`),D(),null):c},Pn=async()=>{let c=we;if(Be()||c!==we||!f||!await Gt())return;let S=await Mr();if(!S||Be()||c!==we)return;let E=!1;for(let[F,q]of[...b])(q==="remote"&&S.has(F)||q==="local"&&!S.has(F))&&(b.delete(F),E=!0);b.size||se();for(let[F,q]of S){let j=f.files[F];j&&j.size===q.size&&j.mtimeMs===q.mtimeMs||ae({key:F,run:()=>ve(F)})}let k=Object.keys(f.files),R=k.filter(F=>!S.has(F));if(R.length&&!A&&(N||cr(R.length,k.length,eo))){N=!0;for(let F of R)b.set(F,"remote");G(),fe();return}E&&(G(),fe());for(let F of R)b.has(F)||ae({key:F,run:()=>ve(F)})},kt=async()=>{let c=we;if(Be()||c!==we||!w||!f||!T||!await Gt())return;let S=await w.tree(f.vaultId);if(S.maxFileBytes!==void 0&&S.maxFileBytes!==h&&(h=S.maxFileBytes,fe()),Be()||c!==we)return;let E=new Map;for(let O of S.entries)r(O.path)===null||!s(O.path,O.kind)||E.set(O.path,O);let k=await Mr();if(!k||Be()||c!==we)return;let R=new Set([...E.keys(),...k.keys(),...Object.keys(f.files)]),F=Object.keys(f.files).length,q=[];for(let O of R){if(Be()||c!==we)return;let K=f.files[O]??null,te=E.get(O)??null,Ce=k.get(O)??null,Fe=null,lt=M(Ce?.size??0);if(Ce)if(K&&K.size===Ce.size&&K.mtimeMs===Ce.mtimeMs)Fe=K.hash,lt=Ce;else{let ct=await ie(O);ct&&(Fe=ct.hash,lt=ct)}q.push({sp:O,d:bn(Fe,K,te?{seq:te.seq,hash:te.hash}:null),rSeq:te?.seq??null,localHash:Fe,localStat:lt})}if(Be()||c!==we)return;let j=q.filter(O=>O.d.kind==="deleteLocal"||O.d.kind==="pushDelete").length,V=!A&&(N||cr(j,F,eo));V&&j&&(N=!0),b.clear();for(let{sp:O,d:K,rSeq:te,localHash:Ce,localStat:Fe}of q){if(Be()||c!==we)return;if(V&&(K.kind==="deleteLocal"||K.kind==="pushDelete")){b.set(O,K.kind==="deleteLocal"?"local":"remote");continue}if((K.kind==="deleteLocal"||K.kind==="pushDelete")&&((await ie(O))?.hash??null)!==Ce){ae({key:O,run:()=>ve(O)});continue}if(Be()||c!==we)return;switch(K.kind){case"adopt":await me(O,te,Ce,Fe);break;case"pull":await ue(O,te);break;case"push":Qe(Le(O))?await Vt(O,K.baseSeq):await Yt(O,K.baseSeq);break;case"pushCreate":Qe(Le(O))?await Vt(O,0):await Yt(O,0);break;case"pushDelete":await $r(O);break;case"deleteLocal":await at(O),ce(O);break;case"conflict":await ue(O,te);break;case"dropShadow":ce(O);break;case"none":break}}A&&(A=!1,B.length=0),b.size||se(),G(),V&&fe();for(let O of S.folders)if(!(r(O)===null||!s(O,"folder")))try{await i.mkdir($(O),{recursive:!0})}catch{}f.cursor=S.seq,f.lastSyncAt=Date.now(),v.save(f)},Xo=async()=>{if(!w||!f)return;let c=f.cursor,S=await w.changes(f.vaultId,c);if(S.changes.length===0&&S.seq>c||S.changes.length>0&&S.changes[0].seq!==c+1){await kt();return}for(let k of S.changes)await Pr(k)},Et=null,Or=[],Nr=()=>{Et&&Or.push(Et.close()),Et=null},Ko=()=>{if(!d||Et||!T)return;let c=Se();if(!c.watch)return;let S=E=>{if(!T)return;let k=l.relative(T,E);if(!k||k.startsWith(".."))return;let R=n(k);R&&_(R)};Et=c.watch(T,{depth:12,ignored:E=>{let k=l.basename(E);return $t(k)||!!e.ignoreNames?.includes(k)}},{change:S,add:S,unlink:()=>Qt(),unlinkDir:()=>Qt()})},Kt=()=>{P?.stop(),P=null},Zo=()=>{if(!d||!w||!f||P)return;let c=H;c&&(P=Xs({baseUrl:c.cloudUrl,vaultId:f.vaultId,token:c.token},{getSince:()=>f?.cursor??0,onHello:S=>{f&&S>f.cursor&&ae({run:Xo})},onChange:S=>{ae({run:()=>Pr(S)})},onReset:()=>{ae({run:kt})},onOpen:()=>{(p==="offline"||p==="starting")&&ye("idle",null),ae({run:Pn})},onDown:()=>{(p==="idle"||p==="syncing")&&ye("offline")},onPresence:S=>t.onPresence?.(f?.vaultId??"",S),onPresenceRoster:S=>t.onPresenceRoster?.(f?.vaultId??"",S)}))},Qo=async()=>{let c=await Me(o);if(c.cloudSync?.deviceId)return c.cloudSync.deviceId;let S=`desk-${Math.random().toString(36).slice(2,10)}${Date.now().toString(36)}`;return await Ve({cloudSync:{...c.cloudSync??{},deviceId:S}},o),S},ei=async c=>{Kt(),Nr(),X.length=0,de.clear(),b.clear(),A=!1,N=!1,B.length=0;let S=await Me(o);if(c!==u)return;let E=S.cloudSync;if(E?.enabled===!1){T=null,w=null,ye("disabled",null);return}if(!o||o!==Te()){ye("auth-required","not-logged-in");return}if(T=e.localRoot,e.requireRootExists){let q=await i.stat(T).then(j=>j.isDirectory()).catch(()=>!1);if(c!==u)return;if(!q){ye("error",`vault-missing: ${T}`),D();return}}if(c!==u)return;let k=t.loadCreds();if(!k.cloudUrl||!k.token){w=null,ye("auth-required","not-logged-in");return}ye("starting",null);let R=E?.deviceId??await Qo();if(c!==u)return;let F=e.clientIdSuffix?`${R}#${e.clientIdSuffix}`:R;H={cloudUrl:k.cloudUrl,token:k.token},w=Js({baseUrl:k.cloudUrl,token:k.token,clientId:F});try{let q=e.vaultId==="first"?E?.vaultId:e.vaultId;if(!q){let V=await w.listVaults();if(c!==u)return;if(!V.length)throw new Error("\u4E91\u7AEF\u65E0\u53EF\u7528 vault");q=V[0].id,await Ve({cloudSync:{...E??{},vaultId:q}},o)}if(c!==u)return;let j=await fr(e.shadowName);if(c!==u||(f=j&&j.vaultRoot===T&&j.vaultId===q&&j.folder===""?j:{vaultRoot:T,folder:"",vaultId:q,cursor:0,lastSyncAt:null,files:{}},c!==u))return;for(let[V,O]of Object.entries(f.pending??{}))b.set(V,O);if(b.size&&(N=!0),!e.requireRootExists){let V=await i.stat(T).then(O=>O.isDirectory()).catch(()=>!1);if(c!==u)return;if(!V){if(Object.keys(f.files).length){ye("error",`mirror-missing: ${T}`),D();return}if(await i.mkdir(T,{recursive:!0}),c!==u)return}}Ko();for(let V of f.moves??[])ae({key:`move:${De(V)}`,run:()=>Dn(V)});ae({run:kt}),ae({run:async()=>{Zo()}})}catch(q){if(c!==u)return;C(q)?ye("auth-required","login-expired"):(ye("offline",q?.message||String(q)),D())}},Ur=()=>{d=!1,Kt(),Nr(),X.length=0,de.clear(),I();for(let c of[Ee,oe,_e])c&&clearTimeout(c);Ee=oe=_e=null},jr=async()=>{Z&&await new Promise(c=>g.add(c)),await Promise.all(Or.splice(0)),await v.flush(),f=null,w=null,H=null,T=null,U=0,z.clear(),h=null,b.clear(),A=!1,N=!1,B.length=0,p="disabled",y=null},ti=()=>{Fr()},Zt=null,_t=()=>{Zt?.(),Zt=Ie().onBeforeQuit(ti);let c=++u;Ur();let S=m.catch(()=>{}).then(async()=>{await jr(),c===u&&(d=!0,await ei(c))});return m=S,S},Fr=()=>{Zt?.(),Zt=null,++u,Ur();let c=m.catch(()=>{}).then(jr);return m=c,c},nt=()=>({enabled:p!=="disabled",state:p==="idle"&&be.size?"syncing":p,lastSyncAt:f?.lastSyncAt??null,pending:X.length+be.size,conflicts:U,skipped:[...z].map(([c,S])=>({path:c,reason:S})),error:y,pendingDeletions:b.size,maxFileBytes:h});return{getStatus:nt,start(){_t()},notifyLocal(c,S,E){if(!f||p==="disabled"||p==="auth-required")return;let k=n(c),R=E?n(E):null;if(S==="write"&&k){$t(k.split("/").pop()||"")||_(k);return}if(S==="remove"){if(!k)return;let F=`${k}/`,q=!1;for(let j of Object.keys(f.files))(j===k||j.startsWith(F))&&(q=!0,ae({key:j,run:()=>ve(j)}));!q&&k&&ae({key:k,run:()=>ve(k)})}},holdLocalMove(c,S){let E=R=>e.serverDir?`${e.serverDir}/${R.replace(/\\/g,"/").normalize("NFC")}`:R.replace(/\\/g,"/").normalize("NFC"),k={from:E(c),to:E(S)};return++we,Jt.add(k),()=>{Jt.delete(k)}},async notifyLocalMove(c,S,E,k){let R=n(c),F=n(S),q=f??await fr(e.shadowName),j=ur(c,""),V=j&&(e.serverDir?`${e.serverDir}/${j}`:j);if(!R&&F&&V&&q&&Object.keys(q.files).some(O=>O===V||O.startsWith(`${V}/`))&&(R=V),!R&&!F){E?.();return}if(R&&F){let O=f??q;if(!O){E?.();return}let K=k??(Object.keys(O.files).some(Ce=>Ce.startsWith(`${R}/`))?"folder":"file"),te={from:R,to:F,kind:K};O.moves??=[],O.moves.some(Ce=>De(Ce)===De(te))||(O.moves.push(te),++we),E&&Xt.set(De(te),E),v.save(O);try{await v.flush(!0)}catch(Ce){throw O.moves=O.moves.filter(Fe=>De(Fe)!==De(te)),Xt.delete(De(te)),v.save(O),Ce}f===O&&d&&p!=="disabled"&&p!=="auth-required"&&ae({key:`move:${De(te)}`,run:()=>Dn(te)});return}R&&this.notifyLocal(c,"remove"),F&&(ae({key:F,run:()=>ve(F)}),Qt()),E?.()},async setEnabled(c){let S=await Me(o);return await Ve({cloudSync:{...S.cloudSync??{},enabled:c}},o),await _t(),nt()},async restart(){return await _t(),nt()},async syncNow(){if(z.clear(),p==="disabled"||p==="auth-required"||!w)await _t();else{for(let c of f?.moves??[])ae({key:`move:${De(c)}`,run:()=>Dn(c)});ae({run:kt})}return nt()},confirmMassDeletions(){return b.size&&(A=!0,N=!1,b.clear(),B.length=0,G(),ae({run:kt})),nt()},stop:Fr};function Qt(){d&&(oe&&clearTimeout(oe),oe=setTimeout(()=>{oe=null,ae({run:Pn})},Za))}}function to(t){let e=t.replace(/\.md$/i,""),n=t.lastIndexOf("/"),r=n<0?"":t.slice(0,n);return{root:t,fdPrefix:`${e}.fd/`,assetPrefix:r?`${r}/.amadeus/`:".amadeus/"}}function no(t,e,n){return!!(e===t.root||e.startsWith(t.fdPrefix)||`${e}/`===t.fdPrefix||n==="binary"&&e.startsWith(t.assetPrefix)||n==="folder"&&(`${e}/`===t.assetPrefix||e.startsWith(t.assetPrefix)))}var il=t=>Se().sha256Hex(t).slice(0,8),al=t=>t.replace(/[\\/:*?"<>|]/g," ").trim().slice(0,40)||"shared",Sn="\u4E0E\u6211\u5171\u4EAB";function mr(t){let e=il(`${t.vaultId}:${t.path}`),n=to(t.path),r=t.path.includes("/")?t.path.slice(0,t.path.lastIndexOf("/")):"";return{key:e,vaultId:t.vaultId,rootPath:t.path,title:t.title,localRelDir:`${Sn}/${al(t.title)}-${e}`,serverDir:r,inScope:(s,o)=>no(n,s,o)}}function pr(){let t=Ie().readCreds(),e=$e(t.cloudUrl??"",t.token??""),n=new AbortController,r=()=>{let m=Ie().readCreds();if(n.signal.aborted||!e||$e(m.cloudUrl??"",m.token??"")!==e)throw Object.assign(new Error("Cloud account changed; retry from the current account"),{status:401});return m},s=()=>{let m=r();if(!m.cloudUrl||!m.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});return m.cloudUrl.replace(/\/+$/,"")},o=async(m,g,p)=>{let y=r();if(!y.cloudUrl||!y.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});let f=await fetch(`${y.cloudUrl.replace(/\/+$/,"")}/api/amadeus${g}`,{method:m,headers:{Authorization:`Bearer ${y.token}`,...p!==void 0?{"Content-Type":"application/json"}:{}},body:p!==void 0?JSON.stringify(p):void 0,signal:AbortSignal.any([n.signal,AbortSignal.timeout(2e4)])});if(!f.ok){let P=null;try{P=await f.json()}catch{}throw Object.assign(new Error(P?.detail||`http ${f.status}`),{status:f.status,code:P?.code})}let w=await f.json();return r(),w},i=null,l=async()=>(r(),i||(i=(await o("GET","/vaults")).vaults[0]?.id??"default",i)),a=()=>{try{let m=(r().token??"").split(".")[1],g=JSON.parse(Ke(en(m)));return typeof g.userId=="string"?g.userId:null}catch{return null}},d=async()=>(await o("GET","/shared-with-me")).items.map(g=>{let p=mr(g),y=g.path.split("/").pop()??g.path;return{...g,localPath:`${p.localRelDir}/${y}`}}),u=null;return{stop:()=>n.abort(),call:o,ensureOwnVault:l,myUserId:a,sharedWithMe:d,linkBase:async()=>{if(r(),u)return u;try{u=((await o("GET","/collab/link-base")).webOrigin??"").trim().replace(/\/+$/,"")||s()}catch{u=s()}return u},async heartbeat(m,g){let p=(m??"").replace(/\\/g,"/"),y,f=null,w=g.find(P=>p.startsWith(`${P.localRelDir}/`));w?(y=w.vaultId,f=w.serverDir?`${w.serverDir}/${p.slice(w.localRelDir.length+1)}`:p.slice(w.localRelDir.length+1)):(y=await l(),f=p||null),await o("POST",`/vaults/${encodeURIComponent(y)}/presence`,{page:f})}}}import{promises as oo}from"node:fs";import ll from"node:path";var gr=".forsion-vault.md",ro=t=>`${t}/${gr}`;function kn(t){let e=/^devices:\s*(\[.*\])\s*$/m.exec(t??"");if(!e)return null;try{let n=JSON.parse(e[1]);return Array.isArray(n)?n.filter(r=>!!r&&typeof r.id=="string"&&typeof r.name=="string").map(r=>({id:r.id,name:r.name,...typeof r.since=="string"?{since:r.since}:{}})):null}catch{return null}}var so=t=>`---
207
+ `)}function Dr(t,e,n=200){return t>=n||e>=5&&t>=Math.max(5,Math.ceil(e/2))}var Yl=/[\u0000-\u001f\u007f]/;function _t(t){let e=t.replace(/\\/g,"/").normalize("NFC").trim();if(e=e.replace(/\/+$/,""),!e||e.length>512||e.startsWith("/")||Yl.test(e))return null;let n=e.split("/");for(let r of n)if(!r||r==="."||r==="..")return null;return n.join("/")}function $r(t,e){let n=t.replace(/\\/g,"/").normalize("NFC");return e===""?_t(n):n.startsWith(`${e}/`)?_t(n.slice(e.length+1)):null}function Ro(t,e){return e===""?t:`${e}/${t}`}function Wt(t){return!!(t===".DS_Store"||t==="Icon\r"||t===".sync-trash"||/\.tmp-\d+-\d+-\d+$/.test(t)||/^\..+\.lock$/.test(t))}function ze(t){return/\.md$/i.test(t)?"page":/\.db$/i.test(t)?"db":"binary"}var ot=t=>t==="page"||t==="db";var Jl=1024,Ce=class extends Error{status;body;constructor(e,n,r){super(`cloud http ${e} on ${r}`),this.status=e,this.body=n}},Do=t=>12e4+Math.ceil(t/256);function $o(t){let e=`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus`,n=async(s,o,i)=>{let l={Authorization:`Bearer ${t.token}`,...i?.headers};s!=="GET"&&(l["X-Amadeus-Client"]=t.clientId);let a;i?.json!==void 0?(l["Content-Type"]="application/json",a=JSON.stringify(i.json),a.length>=Jl&&(l["Content-Encoding"]="gzip",a=await xs(a))):i?.form&&(a=i.form);let c=await fetch(o,{method:s,headers:l,body:a,signal:AbortSignal.timeout(i?.timeoutMs??3e4)});if(!c.ok){let u=null;try{u=await c.json()}catch{}throw new Ce(c.status,u,o)}return c.json()},r=s=>new URLSearchParams(s).toString();return{clientId:t.clientId,async listVaults(){return((await n("GET",`${e}/vaults`)).vaults??[]).map(o=>({id:String(o.id),name:String(o.name),lastChangeSeq:Number(o.lastChangeSeq??0)}))},async tree(s){let o=await n("GET",`${e}/vaults/${s}/tree`);if(!Array.isArray(o.entries))throw new Error("server too old: tree has no entries[] (deploy the amadeus microserver update)");return{folders:o.folders??[],seq:Number(o.seq??0),maxFileBytes:Number.isInteger(o.maxFileBytes)&&o.maxFileBytes>0?o.maxFileBytes:void 0,entries:o.entries.map(i=>({path:String(i.path),kind:i.kind,seq:Number(i.seq??0),hash:i.hash??null,size:Number(i.size??0)}))}},async getFile(s,o){let i=await n("GET",`${e}/vaults/${s}/file?${r({path:o})}`);return{content:String(i.content??""),seq:Number(i.seq??0),hash:i.hash??null}},putFile(s,o,i,l,a=!1){return n("PUT",`${e}/vaults/${s}/file`,{json:{path:o,content:i,baseSeq:l,...a?{force:!0}:{}}})},async deleteFile(s,o,i,l){let a={path:o};i!==void 0&&(a.baseSeq=String(i)),await n("DELETE",`${e}/vaults/${s}/file?${r(a)}`,l?.confirmed?{headers:{"X-Amadeus-Delete-Confirmed":"1"}}:void 0)},move(s,o,i){return n("POST",`${e}/vaults/${s}/move`,{json:{from:o,to:i}})},renameFolder(s,o,i){return n("POST",`${e}/vaults/${s}/folders/rename`,{json:{path:o,newName:i}})},moveFolder(s,o,i){return n("POST",`${e}/vaults/${s}/folders/move`,{json:{path:o,dest:i}})},async deleteFolder(s,o){await n("DELETE",`${e}/vaults/${s}/folders?${r({path:o})}`)},putBinary(s,o,i,l){let a=new FormData;return a.set("path",o),l?.ifAbsent&&a.set("ifAbsent","true"),l?.baseSeq!==void 0&&a.set("baseSeq",String(l.baseSeq)),a.set("file",new Blob([new Uint8Array(i)]),o.split("/").pop()||"file"),n("POST",`${e}/vaults/${s}/binary`,{form:a,timeoutMs:Do(i.length)})},async listVersions(s,o){return((await n("GET",`${e}/vaults/${s}/file/versions?${r({path:o})}`)).versions??[]).map(l=>({id:String(l.id),seq:Number(l.seq??0)}))},async getVersion(s,o){let i=await n("GET",`${e}/vaults/${s}/file/versions/${o}`);return String(i.content??"")},async getAsset(s,o){let i=new AbortController,l=setTimeout(()=>i.abort(),12e4);try{let a=await fetch(`${e}/vaults/${s}/asset?${r({ref:o})}`,{headers:{Authorization:`Bearer ${t.token}`},signal:i.signal});if(!a.ok)throw new Ce(a.redirected&&(a.status===401||a.status===403)?502:a.status,null,"asset:"+o);return clearTimeout(l),l=setTimeout(()=>i.abort(),Do(Number(a.headers.get("content-length"))||0)),new Uint8Array(await a.arrayBuffer())}finally{clearTimeout(l)}},async changes(s,o){let i=await n("GET",`${e}/vaults/${s}/changes?${r({since:String(o)})}`);return{changes:i.changes??[],seq:Number(i.seq??0)}}}}function Oo(t,e){let n=!1,r=0,s=null,o=null,i=()=>`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus/vaults/${t.vaultId}/events?since=${e.getSince()}`,l=c=>{if(n)return;e.onDown(c);let u=Math.min(3e4,1e3*2**r)*(.7+Math.random()*.6);r++,o=setTimeout(()=>void a(),u)},a=async()=>{if(n)return;s=new AbortController;let c;try{c=await fetch(i(),{headers:{Authorization:`Bearer ${t.token}`,Accept:"text/event-stream"},signal:s.signal})}catch(y){l(y);return}if(!c.ok||!c.body){l(new Error(`sse http ${c.status}`));return}r=0,e.onOpen();let u=c.body.getReader(),f=new TextDecoder,m="",h="",g=[],p=()=>{if(!g.length&&!h)return;let y=g.join(`
208
+ `),E=h||"message";h="",g=[];let O=null;try{O=y?JSON.parse(y):null}catch{return}E==="hello"?e.onHello(Number(O?.seq??0)):E==="change"?e.onChange(O):E==="reset"?e.onReset():E==="presence"?e.onPresence?.(O):E==="presence-roster"&&e.onPresenceRoster?.(O)};try{for(;;){let{done:y,value:E}=await u.read();if(y)break;for(m+=f.decode(E,{stream:!0});;){let O=m.indexOf(`
209
+ `);if(O<0)break;let C=m.slice(0,O).replace(/\r$/,"");if(m=m.slice(O+1),C==="")p();else{if(C.startsWith(":"))continue;C.startsWith("event:")?h=C.slice(6).trim():C.startsWith("data:")&&g.push(C.slice(5).replace(/^ /,""))}}}}catch(y){n||l(y);return}l(new Error("sse stream ended"))};return a(),{stop:()=>{n=!0,o&&clearTimeout(o),s?.abort()}}}var Vt=t=>Se().path.join(Ie().userDataDir(),Ie().isDevMode()?`${t}.dev.json`:`${t}.json`),Or=Vt;async function Mr(t){try{let e=JSON.parse(await Se().fs.readFile(Or(t),"utf8"));return!e||typeof e.vaultRoot!="string"||typeof e.vaultId!="string"?null:(e.files=e.files??{},e.cursor=Number(e.cursor??0),e.lastSyncAt=e.lastSyncAt??null,e)}catch{return null}}function Mo(t){let e=null,n=null,r=Promise.resolve(),s=null,o=()=>{if(!e)return r;let i=e,l=JSON.stringify(e);return e=null,r=r.then(async()=>{try{let a=Or(t),c=`${a}.tmp-${Se().tmpTag()}-${Date.now()}-0`;await Se().fs.writeFile(c,l,"utf8"),await Se().fs.rename(c,a),s=null}catch(a){e??=i,s=a}}),r};return{save(i){e=i,!n&&(n=setTimeout(()=>{n=null,o()},500))},async flush(i=!1){if(n&&(clearTimeout(n),n=null),await o(),i&&s)throw s}}}async function No(t){try{await Se().fs.unlink(Or(t))}catch{}}var Gl=5*1024*1024,Xl=5*1024*1024,Kl=3e4,Zl=2500,Ql=3e3,ec=5,tc=256*1024,nc=5,jo=1024*1024,Uo=200,rc=6e4,sc=50,oc=".sync-trash",Ct=t=>Se().sha256Hex(t);function Yt(t,e={localRoot:st(),shadowName:`amadeus-sync-${Bt()}`,vaultId:"first",serverDir:"",excludePrefixes:["\u4E0E\u6211\u5171\u4EAB/"]}){let n=d=>{let S=$r(d,"");if(!S)return null;for(let v of e.excludePrefixes??[])if(S===v.replace(/\/$/,"")||S.startsWith(v))return null;if(e.ignoreNames?.length&&S.split("/").some(v=>e.ignoreNames.includes(v)))return null;let k=e.serverDir?`${e.serverDir}/${S}`:S;return e.inScope&&!e.inScope(k,ze(k))?null:k},r=d=>{let S;if(e.serverDir){if(!d.startsWith(`${e.serverDir}/`))return null;S=d.slice(e.serverDir.length+1)}else{for(let k of e.excludePrefixes??[])if(d.startsWith(k))return null;S=d}return S.split("/").some(k=>Wt(k)||!!e.ignoreNames?.includes(k))?null:S},s=(d,S)=>!e.inScope||e.inScope(d,S),o=e.accountId??Te(),{fs:i,path:l}=Se(),a=d=>i.access(d).then(()=>!0,()=>!1),c=!1,u=0,f=Promise.resolve(),m=new Set,h="disabled",g=null,p=null,y=null,E=null,O=null,C=null,M=0,H=new Map,w=null,x=Mo(e.shadowName),b=new Map,I=!1,U=!1,B=[],J=()=>{p&&(p.pending=b.size?Object.fromEntries(b):void 0,x.save(p))},se=()=>{U=!1,B.length=0},pe=()=>{if(U)return!0;let d=Date.now();for(;B.length&&d-B[0]>rc;)B.shift();return B.length>=sc?(U=!0,!0):!1},X=[],de=new Set,Z=!1,ke=null,oe=null,Ee=null,fe=()=>{!c||Ee||(Ee=setTimeout(()=>{Ee=null,t.onStatus(dt())},200))},ye=(d,S)=>{h=d,S!==void 0&&(g=S),fe()},ae=(d,S=!1)=>{if(c){if(d.key){if(de.has(d.key))return;de.add(d.key)}S?X.unshift(d):X.push(d),z()}},be=new Map,_=d=>{if(!c)return;let S=(p?.files[d]?.size??0)>tc,k=(e.pushQuietMs??Ql)*(S?nc:1),v=Date.now(),R=be.get(d);R&&clearTimeout(R.timer);let L=R?.since??v,q=Math.max(0,Math.min(k,L+k*ec-v)),F=setTimeout(()=>{be.delete(d),ae({key:d,run:()=>_e(d,!0)})},q);be.set(d,{timer:F,since:L}),fe()},P=()=>{for(let{timer:d}of be.values())clearTimeout(d);be.clear()},T=d=>!(d instanceof Ce)||d.status>=500||d.status===0,A=d=>d instanceof Ce&&(d.status===401||d.status===403),z=async()=>{if(!Z){Z=!0;try{for(;X.length;){(h==="idle"||h==="starting")&&ye("syncing");let d=X.shift();d.key&&de.delete(d.key);try{await d.run()}catch(S){if(!c)return;if(A(S)){X.length=0,de.clear(),hn(),ye("auth-required","login-expired");return}if(T(S)){ae(d,!0),hn(),ye("offline",S?.message||"network error"),D();return}let k=d.key??"(op)";H.set(k,S?.body?.code||`http ${S?.status}`),fe()}}c&&h==="syncing"&&(p&&(p.lastSyncAt=Date.now(),x.save(p)),ye("idle",null))}finally{Z=!1;for(let d of m)d();m.clear()}}},D=()=>{!c||ke||(ke=setTimeout(()=>{ke=null,Mt()},Kl))},$=d=>{if(!C||!p)throw new Error("engine not bound");let S=r(d);if(S===null)throw new Error("path outside binding: "+d);let k=l.resolve(C,Ro(S,p.folder)),v=l.relative(C,k);if(v.startsWith("..")||l.isAbsolute(v))throw new Error("path escapes vault: "+d);return k},N=d=>({size:d,mtimeMs:-1}),Y=async d=>{try{let S=await i.stat(d);return S.isFile()?{size:S.size,mtimeMs:Math.floor(S.mtimeMs)}:null}catch{return null}},W=0,G=async(d,S,k=()=>!0)=>{await i.mkdir(l.dirname(d),{recursive:!0});let v=`${d}.tmp-${Se().tmpTag()}-${Date.now()}-${W++}`;await i.writeFile(v,S);let R=await Y(v)??N(nr(S));return k()?(await i.rename(v,d),R):(await i.rm(v,{force:!0}),null)},le=async d=>{let S;try{S=await i.readdir(d,{withFileTypes:!0})}catch{return}for(let k of S)k.isDirectory()&&await le(l.join(d,k.name));try{await i.rmdir(d)}catch{}},ie=async d=>{let S=$(d),k=await Y(S),v;try{v=await i.readFile(S)}catch{return null}return{hash:ot(ze(d))?Ct(rt(v)):Ct(v),size:k?.size??v.length,mtimeMs:k?.mtimeMs??-1,buf:v}},he=async(d,S,k,v)=>{p&&(p.files[d]={seq:S,hash:k,size:v.size,mtimeMs:v.mtimeMs},x.save(p))},ce=d=>{p&&d in p.files&&(delete p.files[d],x.save(p))},ue=async(d,S)=>{if(!y||!p||je(d))return;let k=we,v=ze(d),R,L,q;if(ot(v)){let K;try{K=await y.getFile(p.vaultId,d)}catch(te){if(te instanceof Ce&&te.status===404){await Re(d);return}throw te}R=K.content,L=K.seq,q=K.hash??Ct(K.content)}else{let K;try{K=await y.getAsset(p.vaultId,d)}catch(te){if(te instanceof Ce&&te.status===404){H.set(d,"ASSET_404"),fe();return}throw te}R=K,L=S??0,q=Ct(K)}let F=await ie(d);if(k!==we||je(d))return;if(F&&F.hash===q){await he(d,L,q,F);return}let V=p.files[d];if(F&&V&&q===V.hash&&F.hash!==V.hash){await he(d,L,q,N(V.size)),ae({key:d,run:()=>_e(d)});return}if(F&&(!V||F.hash!==V.hash)&&(V&&v==="page"&&typeof R=="string"&&await Ue(d,V,F,R,L,q,()=>k===we&&!je(d))||k!==we||je(d)||!await yt(d,()=>k===we&&!je(d))))return;let j=await G($(d),R,()=>k===we&&!je(d));j&&await he(d,L,q,j)},Ue=async(d,S,k,v,R,L,q)=>{try{if(!y||!p||k.buf.length>jo||v.length>jo)return!1;let V=(await y.listVersions(p.vaultId,d)).find(te=>te.seq===S.seq);if(!V)return!1;let j=await y.getVersion(p.vaultId,V.id);if(Ct(j)!==S.hash)return!1;let K=Po(rt(k.buf),j,v);return K===null?!1:(await G($(d),K,q)&&(await he(d,R,L,N(nr(K))),ae({key:d,run:()=>_e(d)})),!0)}catch{return!1}},yt=async(d,S)=>{let k=_t($n(d,new Date));if(!k)return!0;let v=k.lastIndexOf("."),R=v>k.lastIndexOf("/"),L=R?k.slice(0,v):k,q=R?k.slice(v):"",F=k,V=Se().existsSync;if(V)for(let j=2;V($(F));j++)F=`${L}-${j}${q}`;else for(let j=2;await a($(F));j++)F=`${L}-${j}${q}`;if(!S())return!1;try{await i.rename($(d),$(F))}catch(j){if(j?.code==="ENOENT")return!0;throw j}return M++,ae({key:F,run:()=>_e(F)}),fe(),!0},wt=async d=>{if(!C)return;let S=$(d),k=r(d)??d,v=l.join(C,oc,new Date().toISOString().slice(0,10),...k.split("/")),R=await a(v)?`${v}.${Date.now()}`:v;try{await i.mkdir(l.dirname(R),{recursive:!0}),await i.rename(S,R)}catch(L){if(L?.code==="ENOENT")return;throw new Error(`\u8F6F\u5220\u5931\u8D25,\u4FDD\u7559\u672C\u5730\u6587\u4EF6 ${S}: ${L?.message??String(L)}`)}},Re=async d=>{if(!p)return;let S=await ie(d);if(je(d))return;let k=p.files[d]??null,v=On(S?.hash??null,k,null);if(v.kind==="deleteLocal"){if(!I&&pe()){b.set(d,"local"),J(),fe();return}B.push(Date.now()),await wt(d),ce(d)}else v.kind==="pushCreate"?(ce(d),ae({key:d,run:()=>_e(d)})):ce(d)},ps=(d,S)=>{if(p){for(let k of Object.keys(p.files))if(k===d||k.startsWith(`${d}/`)){let v=S+k.slice(d.length);p.files[v]=p.files[k],delete p.files[k]}x.save(p)}},ms=async d=>{if(!y||!p||d.seq<=p.cursor||!await un())return;if(d.origin.client&&y.clientId===d.origin.client){p.cursor=d.seq,x.save(p);return}let S=d.type==="structure"?"folder":d.type,k=R=>r(R)!==null&&s(R,S);if(!k(d.path)&&!(d.newPath&&k(d.newPath))){p.cursor=d.seq,x.save(p);return}let v=d.path;switch(d.op){case"write":await ue(v,d.fileSeq);break;case"delete":await Re(v);break;case"move":{let R=d.newPath;if(!R)break;let L=p.files[v];if(await ie(v)&&L)try{await i.mkdir(l.dirname($(R)),{recursive:!0}),await i.rename($(v),$(R)),p.files[R]={...L,seq:d.fileSeq??L.seq},delete p.files[v],x.save(p)}catch{await ue(R,d.fileSeq)}else ce(v),await ue(R,d.fileSeq);break}case"mkdir":await i.mkdir($(v),{recursive:!0});break;case"rename-folder":case"move-folder":{let R=d.newPath;if(!R)break;try{await i.mkdir(l.dirname($(R)),{recursive:!0}),await i.rename($(v),$(R))}catch{}ps(v,R);break}case"delete-folder":{let R=`${v}/`;for(let L of Object.keys(p.files))(L===v||L.startsWith(R))&&await Re(L);await le($(v));break}}if(p.cursor=d.seq,x.save(p),d.op==="move"||d.op==="rename-folder"||d.op==="move-folder"||d.op==="delete"||d.op==="delete-folder")try{await t.onRemoteApplied?.(d)}catch{}},Xi=async(d,S,k)=>{let v=Number(S?.seq??0),R=S?.content??null;if(R!==null&&Ct(R)===k.hash){await he(d,v,k.hash,k);return}if(R===null&&v===0){if(!p?.files[d]){H.set(d,S?.code||"EXISTS"),fe();return}ce(d),ae({key:d,run:()=>_e(d)});return}await ue(d,v)},ln=async(d,S)=>{if(!y||!p)return;let k=await ie(d);if(!k){ae({key:d,run:()=>_e(d)});return}if(k.size>Gl){H.set(d,"TOO_LARGE"),fe();return}let v=rt(k.buf);try{let R=await y.putFile(p.vaultId,d,v,S);H.delete(d),await he(d,R.seq,R.hash??k.hash,k)}catch(R){if(R instanceof Ce&&R.status===409){await Xi(d,R.body,k);return}throw R}},cn=async(d,S)=>{if(!y||!p)return;let k=await ie(d);if(!k){ae({key:d,run:()=>_e(d)});return}if(k.size>(w??Xl)){H.set(d,"TOO_LARGE"),fe();return}try{let v=await y.putBinary(p.vaultId,d,k.buf,{baseSeq:S});H.delete(d),await he(d,v.seq,k.hash,k)}catch(v){if(v instanceof Ce&&v.status===409){let R=Number(v.body?.seq??0),L=v.body?.hash??null;if(L!==null&&L===k.hash){await he(d,R,k.hash,k);return}if(R===0){if(!p.files[d]){H.set(d,v.body?.code||"EXISTS"),fe();return}ce(d),ae({key:d,run:()=>_e(d)});return}await ue(d,R);return}throw v}},gs=async d=>{if(!y||!p||je(d))return;let S=we,k=p.files[d];if(k){if(ot(ze(d)))try{let v=await y.getFile(p.vaultId,d);if(v.seq!==k.seq){await ue(d,v.seq);return}}catch(v){if(v instanceof Ce&&v.status===404){ce(d);return}throw v}if(!(S!==we||je(d))){try{await y.deleteFile(p.vaultId,d,k.seq,{confirmed:I})}catch(v){if(v instanceof Ce&&v.status===409){await ue(d,Number(v.body?.seq??0)||null);return}if(v instanceof Ce&&v.status===429&&v.body?.code==="MASS_DELETE_BLOCKED"){b.set(d,"remote"),U=!0,J(),fe();return}throw v}ce(d)}}},un=async()=>C?await i.stat(C).then(S=>S.isDirectory()).catch(()=>!1)||!e.requireRootExists&&!Object.keys(p?.files??{}).length?!0:(ye("error",`vault-missing: ${C}`),D(),!1):!1,we=0,dn=new Set,fn=new Map,De=d=>JSON.stringify([d.from,d.to]),nt=(d,S)=>d===S||d.startsWith(`${S}/`),je=d=>[...p?.moves??[],...dn].some(S=>nt(d,S.from)||nt(d,S.to)),Je=()=>!!(p?.moves?.length||dn.size),Qn=async d=>{if(!y||!p)return;let{from:S,to:k,kind:v}=d;if(r(S)===null||r(k)===null)throw new Error("Invalid queued cloud move");d.hashes??=Object.fromEntries(Object.entries(p.files).filter(([F])=>nt(F,S)).map(([F,V])=>[F.slice(S.length),V.hash])),x.save(p),await x.flush(!0);let R,L=!1;try{if(v==="folder"){let F=l.posix.dirname(S)==="."?"":l.posix.dirname(S),V=l.posix.dirname(k)==="."?"":l.posix.dirname(k);F===V?await y.renameFolder(p.vaultId,S,l.posix.basename(k)):await y.moveFolder(p.vaultId,S,V)}else{let F=await y.move(p.vaultId,S,k);R=Number(F.seq)}}catch(F){if(!(F instanceof Ce)||F.status!==404)throw F;let V=await y.tree(p.vaultId);if(V.entries.some(te=>nt(te.path,S))||V.folders.some(te=>nt(te,S)))throw F;let K=V.entries.find(te=>te.path===k);if(R=K?.seq,L=!K&&!V.entries.some(te=>nt(te.path,k))&&!V.folders.some(te=>nt(te,k)),!L){let te=Object.entries(d.hashes);if(!(te.length>0&&te.every(([Le,bt])=>V.entries.some(St=>St.path===k+Le&&St.hash===bt))))throw new Ce(409,{code:"MOVE_DESTINATION_CHANGED"},"local-move")}}if(L)for(let F of Object.keys(p.files))nt(F,S)&&delete p.files[F];else ps(S,k),R!==void 0&&p.files[k]&&(p.files[k].seq=R);p.moves=(p.moves??[]).filter(F=>De(F)!==De(d)),x.save(p);try{await x.flush(!0)}catch(F){throw p.moves.unshift(d),x.save(p),F}let q=fn.get(De(d));fn.delete(De(d)),q?.(),je(k)||(v==="folder"?await er():await _e(k))},_e=async(d,S=!1)=>{if(!p||je(d))return;if(!s(d,ze(d))){ce(d);return}if(!await un())return;let k=await ie(d);if(je(d))return;let v=p.files[d]??null,R=On(k?.hash??null,v,v?{seq:v.seq,hash:v.hash}:null);switch(R.kind){case"push":ot(ze(d))?await ln(d,R.baseSeq):await cn(d,R.baseSeq);break;case"pushCreate":ot(ze(d))?await ln(d,0):await cn(d,0);break;case"pushDelete":if(S){mn();break}if(!I&&(b.has(d)||pe())){b.set(d,"remote"),J(),fe();break}B.push(Date.now()),await gs(d);break;case"dropShadow":ce(d);break;default:k&&v&&k.hash===v.hash&&k.mtimeMs>=0&&(v.size!==k.size||v.mtimeMs!==k.mtimeMs)&&await he(d,v.seq,v.hash,k);break}},ys=async()=>{let d=new Map;if(!C||!p)return d;let S=C,k=null,v=async R=>{if(k)return;let L;try{L=await i.readdir(R,{withFileTypes:!0})}catch(q){k=`${R}: ${q?.message??String(q)}`;return}for(let q of L){if(Wt(q.name)||q.isDirectory()&&e.ignoreNames?.includes(q.name))continue;let F=l.join(R,q.name);if(q.isDirectory())await v(F);else if(q.isFile()){let V=l.relative(S,F).split(l.sep).join("/"),j=n(V);if(!j)continue;try{let K=await i.stat(F);if(!K.isFile())continue;d.set(j,{size:K.size,mtimeMs:Math.floor(K.mtimeMs)})}catch(K){if(K?.code==="ENOENT")continue;k=`${F}: ${K?.message??String(K)}`;return}}}};return await v(S),k?(ye("error",`scan-failed: ${k}`),D(),null):d},er=async()=>{let d=we;if(Je()||d!==we||!p||!await un())return;let S=await ys();if(!S||Je()||d!==we)return;let k=!1;for(let[L,q]of[...b])(q==="remote"&&S.has(L)||q==="local"&&!S.has(L))&&(b.delete(L),k=!0);b.size||se();for(let[L,q]of S){let F=p.files[L];F&&F.size===q.size&&F.mtimeMs===q.mtimeMs||ae({key:L,run:()=>_e(L)})}let v=Object.keys(p.files),R=v.filter(L=>!S.has(L));if(R.length&&!I&&(U||Dr(R.length,v.length,Uo))){U=!0;for(let L of R)b.set(L,"remote");J(),fe();return}k&&(J(),fe());for(let L of R)b.has(L)||ae({key:L,run:()=>_e(L)})},$t=async()=>{let d=we;if(Je()||d!==we||!y||!p||!C||!await un())return;let S=await y.tree(p.vaultId);if(S.maxFileBytes!==void 0&&S.maxFileBytes!==w&&(w=S.maxFileBytes,fe()),Je()||d!==we)return;let k=new Map;for(let j of S.entries)r(j.path)===null||!s(j.path,j.kind)||k.set(j.path,j);let v=await ys();if(!v||Je()||d!==we)return;let R=new Set([...k.keys(),...v.keys(),...Object.keys(p.files)]),L=Object.keys(p.files).length,q=[];for(let j of R){if(Je()||d!==we)return;let K=p.files[j]??null,te=k.get(j)??null,xe=v.get(j)??null,Le=null,bt=N(xe?.size??0);if(xe)if(K&&K.size===xe.size&&K.mtimeMs===xe.mtimeMs)Le=K.hash,bt=xe;else{let St=await ie(j);St&&(Le=St.hash,bt=St)}q.push({sp:j,d:On(Le,K,te?{seq:te.seq,hash:te.hash}:null),rSeq:te?.seq??null,localHash:Le,localStat:bt})}if(Je()||d!==we)return;let F=q.filter(j=>j.d.kind==="deleteLocal"||j.d.kind==="pushDelete").length,V=!I&&(U||Dr(F,L,Uo));V&&F&&(U=!0),b.clear();for(let{sp:j,d:K,rSeq:te,localHash:xe,localStat:Le}of q){if(Je()||d!==we)return;if(V&&(K.kind==="deleteLocal"||K.kind==="pushDelete")){b.set(j,K.kind==="deleteLocal"?"local":"remote");continue}if((K.kind==="deleteLocal"||K.kind==="pushDelete")&&((await ie(j))?.hash??null)!==xe){ae({key:j,run:()=>_e(j)});continue}if(Je()||d!==we)return;switch(K.kind){case"adopt":await he(j,te,xe,Le);break;case"pull":await ue(j,te);break;case"push":ot(ze(j))?await ln(j,K.baseSeq):await cn(j,K.baseSeq);break;case"pushCreate":ot(ze(j))?await ln(j,0):await cn(j,0);break;case"pushDelete":await gs(j);break;case"deleteLocal":await wt(j),ce(j);break;case"conflict":await ue(j,te);break;case"dropShadow":ce(j);break;case"none":break}}I&&(I=!1,B.length=0),b.size||se(),J(),V&&fe();for(let j of S.folders)if(!(r(j)===null||!s(j,"folder")))try{await i.mkdir($(j),{recursive:!0})}catch{}p.cursor=S.seq,p.lastSyncAt=Date.now(),x.save(p)},Ki=async()=>{if(!y||!p)return;let d=p.cursor,S=await y.changes(p.vaultId,d);if(S.changes.length===0&&S.seq>d||S.changes.length>0&&S.changes[0].seq!==d+1){await $t();return}for(let v of S.changes)await ms(v)},Ot=null,ws=[],bs=()=>{Ot&&ws.push(Ot.close()),Ot=null},Zi=()=>{if(!c||Ot||!C)return;let d=Se();if(!d.watch)return;let S=k=>{if(!C)return;let v=l.relative(C,k);if(!v||v.startsWith(".."))return;let R=n(v);R&&_(R)};Ot=d.watch(C,{depth:12,ignored:k=>{let v=l.basename(k);return Wt(v)||!!e.ignoreNames?.includes(v)}},{change:S,add:S,unlink:()=>mn(),unlinkDir:()=>mn()})},hn=()=>{E?.stop(),E=null},Qi=()=>{if(!c||!y||!p||E)return;let d=O;d&&(E=Oo({baseUrl:d.cloudUrl,vaultId:p.vaultId,token:d.token},{getSince:()=>p?.cursor??0,onHello:S=>{p&&S>p.cursor&&ae({run:Ki})},onChange:S=>{ae({run:()=>ms(S)})},onReset:()=>{ae({run:$t})},onOpen:()=>{(h==="offline"||h==="starting")&&ye("idle",null),ae({run:er})},onDown:()=>{(h==="idle"||h==="syncing")&&ye("offline")},onPresence:S=>t.onPresence?.(p?.vaultId??"",S),onPresenceRoster:S=>t.onPresenceRoster?.(p?.vaultId??"",S)}))},ea=async()=>{let d=await Me(o);if(d.cloudSync?.deviceId)return d.cloudSync.deviceId;let S=`desk-${Math.random().toString(36).slice(2,10)}${Date.now().toString(36)}`;return await Xe({cloudSync:{...d.cloudSync??{},deviceId:S}},o),S},ta=async d=>{hn(),bs(),X.length=0,de.clear(),b.clear(),I=!1,U=!1,B.length=0;let S=await Me(o);if(d!==u)return;let k=S.cloudSync;if(k?.enabled===!1){C=null,y=null,ye("disabled",null);return}if(!o||o!==Te()){ye("auth-required","not-logged-in");return}if(C=e.localRoot,e.requireRootExists){let q=await i.stat(C).then(F=>F.isDirectory()).catch(()=>!1);if(d!==u)return;if(!q){ye("error",`vault-missing: ${C}`),D();return}}if(d!==u)return;let v=t.loadCreds();if(!v.cloudUrl||!v.token){y=null,ye("auth-required","not-logged-in");return}ye("starting",null);let R=k?.deviceId??await ea();if(d!==u)return;let L=e.clientIdSuffix?`${R}#${e.clientIdSuffix}`:R;O={cloudUrl:v.cloudUrl,token:v.token},y=$o({baseUrl:v.cloudUrl,token:v.token,clientId:L});try{let q=e.vaultId==="first"?k?.vaultId:e.vaultId;if(!q){let V=await y.listVaults();if(d!==u)return;if(!V.length)throw new Error("\u4E91\u7AEF\u65E0\u53EF\u7528 vault");q=V[0].id,await Xe({cloudSync:{...k??{},vaultId:q}},o)}if(d!==u)return;let F=await Mr(e.shadowName);if(d!==u||(p=F&&F.vaultRoot===C&&F.vaultId===q&&F.folder===""?F:{vaultRoot:C,folder:"",vaultId:q,cursor:0,lastSyncAt:null,files:{}},d!==u))return;for(let[V,j]of Object.entries(p.pending??{}))b.set(V,j);if(b.size&&(U=!0),!e.requireRootExists){let V=await i.stat(C).then(j=>j.isDirectory()).catch(()=>!1);if(d!==u)return;if(!V){if(Object.keys(p.files).length){ye("error",`mirror-missing: ${C}`),D();return}if(await i.mkdir(C,{recursive:!0}),d!==u)return}}Zi();for(let V of p.moves??[])ae({key:`move:${De(V)}`,run:()=>Qn(V)});ae({run:$t}),ae({run:async()=>{Qi()}})}catch(q){if(d!==u)return;A(q)?ye("auth-required","login-expired"):(ye("offline",q?.message||String(q)),D())}},Ss=()=>{c=!1,hn(),bs(),X.length=0,de.clear(),P();for(let d of[ke,oe,Ee])d&&clearTimeout(d);ke=oe=Ee=null},vs=async()=>{Z&&await new Promise(d=>m.add(d)),await Promise.all(ws.splice(0)),await x.flush(),p=null,y=null,O=null,C=null,M=0,H.clear(),w=null,b.clear(),I=!1,U=!1,B.length=0,h="disabled",g=null},na=()=>{ks()},pn=null,Mt=()=>{pn?.(),pn=Ie().onBeforeQuit(na);let d=++u;Ss();let S=f.catch(()=>{}).then(async()=>{await vs(),d===u&&(c=!0,await ta(d))});return f=S,S},ks=()=>{pn?.(),pn=null,++u,Ss();let d=f.catch(()=>{}).then(vs);return f=d,d},dt=()=>({enabled:h!=="disabled",state:h==="idle"&&be.size?"syncing":h,lastSyncAt:p?.lastSyncAt??null,pending:X.length+be.size,conflicts:M,skipped:[...H].map(([d,S])=>({path:d,reason:S})),error:g,pendingDeletions:b.size,maxFileBytes:w});return{getStatus:dt,start(){Mt()},notifyLocal(d,S,k){if(!p||h==="disabled"||h==="auth-required")return;let v=n(d),R=k?n(k):null;if(S==="write"&&v){Wt(v.split("/").pop()||"")||_(v);return}if(S==="remove"){if(!v)return;let L=`${v}/`,q=!1;for(let F of Object.keys(p.files))(F===v||F.startsWith(L))&&(q=!0,ae({key:F,run:()=>_e(F)}));!q&&v&&ae({key:v,run:()=>_e(v)})}},holdLocalMove(d,S){let k=R=>e.serverDir?`${e.serverDir}/${R.replace(/\\/g,"/").normalize("NFC")}`:R.replace(/\\/g,"/").normalize("NFC"),v={from:k(d),to:k(S)};return++we,dn.add(v),()=>{dn.delete(v)}},async notifyLocalMove(d,S,k,v){let R=n(d),L=n(S),q=p??await Mr(e.shadowName),F=$r(d,""),V=F&&(e.serverDir?`${e.serverDir}/${F}`:F);if(!R&&L&&V&&q&&Object.keys(q.files).some(j=>j===V||j.startsWith(`${V}/`))&&(R=V),!R&&!L){k?.();return}if(R&&L){let j=p??q;if(!j){k?.();return}let K=v??(Object.keys(j.files).some(xe=>xe.startsWith(`${R}/`))?"folder":"file"),te={from:R,to:L,kind:K};j.moves??=[],j.moves.some(xe=>De(xe)===De(te))||(j.moves.push(te),++we),k&&fn.set(De(te),k),x.save(j);try{await x.flush(!0)}catch(xe){throw j.moves=j.moves.filter(Le=>De(Le)!==De(te)),fn.delete(De(te)),x.save(j),xe}p===j&&c&&h!=="disabled"&&h!=="auth-required"&&ae({key:`move:${De(te)}`,run:()=>Qn(te)});return}R&&this.notifyLocal(d,"remove"),L&&(ae({key:L,run:()=>_e(L)}),mn()),k?.()},async setEnabled(d){let S=await Me(o);return await Xe({cloudSync:{...S.cloudSync??{},enabled:d}},o),await Mt(),dt()},async restart(){return await Mt(),dt()},async syncNow(){if(H.clear(),h==="disabled"||h==="auth-required"||!y)await Mt();else{for(let d of p?.moves??[])ae({key:`move:${De(d)}`,run:()=>Qn(d)});ae({run:$t})}return dt()},confirmMassDeletions(){return b.size&&(I=!0,U=!1,b.clear(),B.length=0,J(),ae({run:$t})),dt()},stop:ks};function mn(){c&&(oe&&clearTimeout(oe),oe=setTimeout(()=>{oe=null,ae({run:er})},Zl))}}function Fo(t){let e=t.replace(/\.md$/i,""),n=t.lastIndexOf("/"),r=n<0?"":t.slice(0,n);return{root:t,fdPrefix:`${e}.fd/`,assetPrefix:r?`${r}/.amadeus/`:".amadeus/"}}function Lo(t,e,n){return!!(e===t.root||e.startsWith(t.fdPrefix)||`${e}/`===t.fdPrefix||n==="binary"&&e.startsWith(t.assetPrefix)||n==="folder"&&(`${e}/`===t.assetPrefix||e.startsWith(t.assetPrefix)))}var ic=t=>Se().sha256Hex(t).slice(0,8),ac=t=>t.replace(/[\\/:*?"<>|]/g," ").trim().slice(0,40)||"shared",Mn="\u4E0E\u6211\u5171\u4EAB";function Nr(t){let e=ic(`${t.vaultId}:${t.path}`),n=Fo(t.path),r=t.path.includes("/")?t.path.slice(0,t.path.lastIndexOf("/")):"";return{key:e,vaultId:t.vaultId,rootPath:t.path,title:t.title,localRelDir:`${Mn}/${ac(t.title)}-${e}`,serverDir:r,inScope:(s,o)=>Lo(n,s,o)}}function jr(){let t=Ie().readCreds(),e=Oe(t.cloudUrl??"",t.token??""),n=new AbortController,r=()=>{let f=Ie().readCreds();if(n.signal.aborted||!e||Oe(f.cloudUrl??"",f.token??"")!==e)throw Object.assign(new Error("Cloud account changed; retry from the current account"),{status:401});return f},s=()=>{let f=r();if(!f.cloudUrl||!f.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});return f.cloudUrl.replace(/\/+$/,"")},o=async(f,m,h)=>{let g=r();if(!g.cloudUrl||!g.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});let p=await fetch(`${g.cloudUrl.replace(/\/+$/,"")}/api/amadeus${m}`,{method:f,headers:{Authorization:`Bearer ${g.token}`,...h!==void 0?{"Content-Type":"application/json"}:{}},body:h!==void 0?JSON.stringify(h):void 0,signal:AbortSignal.any([n.signal,AbortSignal.timeout(2e4)])});if(!p.ok){let E=null;try{E=await p.json()}catch{}throw Object.assign(new Error(E?.detail||`http ${p.status}`),{status:p.status,code:E?.code})}let y=await p.json();return r(),y},i=null,l=async()=>(r(),i||(i=(await o("GET","/vaults")).vaults[0]?.id??"default",i)),a=()=>{try{let f=(r().token??"").split(".")[1],m=JSON.parse(rt(gn(f)));return typeof m.userId=="string"?m.userId:null}catch{return null}},c=async()=>(await o("GET","/shared-with-me")).items.map(m=>{let h=Nr(m),g=m.path.split("/").pop()??m.path;return{...m,localPath:`${h.localRelDir}/${g}`}}),u=null;return{stop:()=>n.abort(),call:o,ensureOwnVault:l,myUserId:a,sharedWithMe:c,linkBase:async()=>{if(r(),u)return u;try{u=((await o("GET","/collab/link-base")).webOrigin??"").trim().replace(/\/+$/,"")||s()}catch{u=s()}return u},async heartbeat(f,m){let h=(f??"").replace(/\\/g,"/"),g,p=null,y=m.find(E=>h.startsWith(`${E.localRelDir}/`));y?(g=y.vaultId,p=y.serverDir?`${y.serverDir}/${h.slice(y.localRelDir.length+1)}`:h.slice(y.localRelDir.length+1)):(g=await l(),p=h||null),await o("POST",`/vaults/${encodeURIComponent(g)}/presence`,{page:p})}}}import{promises as qo}from"node:fs";import lc from"node:path";var Ur=".forsion-vault.md",zo=t=>`${t}/${Ur}`;function Nn(t){let e=/^devices:\s*(\[.*\])\s*$/m.exec(t??"");if(!e)return null;try{let n=JSON.parse(e[1]);return Array.isArray(n)?n.filter(r=>!!r&&typeof r.id=="string"&&typeof r.name=="string").map(r=>({id:r.id,name:r.name,...typeof r.since=="string"?{since:r.since}:{}})):null}catch{return null}}var Ho=t=>`---
210
210
  devices: ${JSON.stringify(t.map(e=>({id:e.id,name:e.name,...e.since?{since:e.since}:{}})))}
211
211
  ---
212
- `;var Oe=t=>t.replace(/\\/g,"/").normalize("NFC");function hr(t){let e=Oe(t.path);return e?t.kind==="folder"?`${e}/`:t.kind==="page"?`${e.replace(/\.md$/i,"")}.fd/`:null:null}function gt(t,e,n){let r=Oe(n);if(!r)return!1;if(t.some(s=>Oe(s.path)===r))return!0;for(let s of e??[]){let o=Oe(s);if(!o)continue;let i=`${o.replace(/\.md$/i,"")}.fd`;if(r===o||r.startsWith(`${o}/`)||r===i||r.startsWith(`${i}/`))return!1}return t.some(s=>{let o=hr(s);return!!o&&r.startsWith(o)})}function yr(t,e,n){let r=Oe(t),s=Oe(e);return r===s?Oe(n):r.startsWith(`${s}/`)?Oe(n)+r.slice(s.length):null}function Nt(t,e,n){let r=!1,s=t.map(o=>{let i=yr(o,e,n);return i===null?o:(r=!0,i)});return{changed:r,next:s}}async function io(t){let e=await oo.readdir(t,{withFileTypes:!0}).catch(()=>[]),n=[],r=Object.create(null);for(let s of e){if(!s.isDirectory()||s.name.startsWith("."))continue;let o=await oo.readFile(ll.join(t,s.name,gr),"utf8").catch(()=>null);if(o===null)continue;n.push(s.name);let i=kn(o);i?.length&&(r[s.name]=i)}return{names:n.sort(),devices:r}}var ke={get:"amadeus:sync:get",setEnabled:"amadeus:sync:set-enabled",syncNow:"amadeus:sync:now",confirmDeletions:"amadeus:sync:confirm-deletions",status:"amadeus:sync:status",switchSide:"amadeus:sync:switch-side",collabCall:"amadeus:collab:call",presence:"amadeus:collab:presence",entryGet:"amadeus:entry-sync:get",entryEnable:"amadeus:entry-sync:enable",entryDisable:"amadeus:entry-sync:disable",entryMark:"amadeus:entry-sync:mark",entryClosure:"amadeus:entry-sync:closure",entryChange:"amadeus:entry-sync:change",otherSideDbs:"amadeus:entry-sync:other-side-dbs"};var En=t=>Se().sha256Hex(t).slice(0,8);function ao(t){return t.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}\)(?=(?:\.[^./]+)?$)/,"")}function et(t,e=[]){let n=[],r=[];for(let s of t){let o=Oe(s.path);if(!o)continue;r.push(o);let i=hr(s);i&&n.push(i)}return{entries:t,exclude:e,prefixes:n,paths:r}}function lo(t,e){let n=ao(Oe(e));if(!n)return!1;if(gt(t.entries,t.exclude,n))return!0;let r=`${n}/`;for(let s of t.paths)if(s.startsWith(r))return!0;for(let s of t.prefixes)if(s.startsWith(r))return!0;return!1}function Ut(t,e,n){let r=!1,s=t.map(o=>{let i=yr(o.path,e,n);return i===null?o:(r=!0,{...o,path:i})});return{changed:r,next:s}}function co(t,e,n,r){if(e==="delete"||e==="delete-folder"){let s=Oe(n),o=t.filter(i=>{let l=Oe(i.path);return!(l===s||e==="delete-folder"&&l.startsWith(`${s}/`))});return{changed:o.length!==t.length,next:o}}return r?Ut(t,n,r):{changed:!1,next:t}}function wr(t,e){let n=mt(t);return!n||n!==t.normalize("NFC").trim()?"\u540D\u79F0\u4E0D\u5408\u6CD5":n.includes("/")?"\u540D\u79F0\u4E0D\u80FD\u5305\u542B /":n===Sn?`\u300C${Sn}\u300D\u662F\u4FDD\u7559\u540D\u79F0`:e.includes(n)?"\u8BE5\u540D\u79F0\u5DF2\u88AB\u5176\u4ED6\u667A\u5E93\u7684\u4E91\u540C\u6B65\u5360\u7528":null}import{constants as cl,promises as uo}from"node:fs";async function fo(t,e){try{await uo.copyFile(Mt(t),Mt(e),cl.COPYFILE_EXCL)}catch(n){let r=n?.code;if(r==="EEXIST"||r==="ENOENT")return!1;throw n}return await uo.unlink(Mt(t)).catch(()=>{}),!0}var mo=["setAmadeusSyncFactory","readCreds","accountId","homeDir"],br=t=>mo.every(e=>typeof t[e]=="function"),fl=()=>({enabled:!1,state:"disabled",lastSyncAt:null,pending:0,conflicts:0,skipped:[],error:null,pendingDeletions:0,maxFileBytes:null,side:"local"});function Sr(t){let e=null,n=()=>{if(!e)throw new Error("Cloud sync is not ready");return e};t.handle(ke.get,()=>e?e.get():fl()),t.handle(ke.setEnabled,(r,s)=>n().setEnabled(s)),t.handle(ke.syncNow,()=>n().syncNow()),t.handle(ke.confirmDeletions,()=>n().confirmDeletions()),t.handle(ke.entryGet,()=>n().entryGet()),t.handle(ke.otherSideDbs,()=>n().otherSideDbs()),t.handle(ke.entryEnable,(r,s)=>n().entryEnable(s)),t.handle(ke.entryDisable,(r,s)=>n().entryDisable(s)),t.handle(ke.entryMark,(r,s,o)=>n().entryMark(s,o)),t.handle(ke.entryClosure,(r,s,o)=>n().entryClosure(s,o)),t.handle(ke.collabCall,(r,s,o)=>n().collabCall(s,o)),t.handle(ke.switchSide,(r,s)=>n().switchSide(r.sender.id,s)),t.setAmadeusSyncFactory(r=>{qs(r);let s=po(r);return e=s.handlers,s.instance}),t.log("[forsion-extend] amadeus cloud sync registered")}function po(t){let e=t.notifyAll,n=()=>t.vaultRoot(),r=0,s=!1,o=pr(),i=new Map,l=()=>{let _=Date.now();for(let[I,x]of i)_-x.at>7e4&&i.delete(I);e(ke.presence,[...i.values()])},a={loadCreds:()=>t.readCreds(),onStatus:_=>e(ke.status,{..._,pendingDeletions:Ee(),side:y()?"cloud":"local"}),onPresence:(_,I)=>{let x=I;x?.userId&&(i.set(x.userId,{userId:x.userId,username:String(x.username??"user"),page:x.page??null,at:Number(x.at)||Date.now()}),l())},onPresenceRoster:(_,I)=>{if(Array.isArray(I)){for(let x of I){let C=x;C?.userId&&i.set(C.userId,{userId:C.userId,username:String(C.username??"user"),page:C.page??null,at:Number(C.at)||Date.now()})}l()}}},d=()=>{let _=r;return{...a,onStatus:I=>{_===r&&a.onStatus(I)},onPresence:(I,x)=>{_===r&&a.onPresence(I,x)},onPresenceRoster:(I,x)=>{_===r&&a.onPresenceRoster(I,x)}}},u=Ot(d()),m=new Map,g=[],p=async()=>{if(!s||!Te())return;let _=r,I=o,x;try{x=await I.sharedWithMe()}catch{return}if(_!==r||!s)return;let C=x.map(D=>mr(D));g=C;let L=new Set(C.map(D=>D.key));for(let[D,$]of m)if(!L.has(D)){if(await $.engine.stop(),_!==r)return;m.delete(D)}for(let D of C){if(m.has(D.key))continue;let $=Ot(d(),{localRoot:st.join(Ze(),...D.localRelDir.split("/")),shadowName:`amadeus-sync-${Pt()}-share-${D.key}`,vaultId:D.vaultId,serverDir:D.serverDir,inScope:D.inScope});m.set(D.key,{engine:$,plan:D}),$.start()}},y=()=>n()===Ze(),f=(_,I=_.base)=>{_.base=I;let x=[I,..._.pendingMoves];_.scope.current=et(x.flatMap(C=>C.entries),x.flatMap(C=>C.exclude))},w=new Map,P=new Set,H=new Set,T=null,U=()=>T??=new Promise(_=>{let I=()=>dl.hostname().replace(/\.(local|lan|home)$/i,"")||"Desktop";if(process.platform!=="darwin")return _(I());ul("scutil",["--get","ComputerName"],{timeout:1500},(x,C)=>_(!x&&String(C).trim()||I()))}),z=async()=>{let _=(await Me()).cloudSync?.deviceId;return _?{id:_,name:await U()}:null},h=new Map,v=(_,I,x)=>{let C=r,L=(h.get(_)??Promise.resolve()).catch(()=>{}).then(async()=>{C!==r||x&&!await x()||C!==r||await b(_,I,C)});return h.set(_,L),L.finally(()=>{h.get(_)===L&&h.delete(_)}).catch(()=>{}),L},b=async(_,I,x)=>{let C=o,L=encodeURIComponent(await C.ensureOwnVault()),D=ro(_);for(let $=0;$<3;$++){let M=null;try{M=await C.call("GET",`/vaults/${L}/file?path=${encodeURIComponent(D)}`)}catch(W){if(W?.status!==404)throw W}let Y=I(!!M,M?kn(M.content):null);if(Y===void 0||x!==r)return;try{if(Y===null){M&&await C.call("DELETE",`/vaults/${L}/file?path=${encodeURIComponent(D)}&baseSeq=${M.seq}`);return}await C.call("PUT",`/vaults/${L}/file`,{path:D,content:so(Y),baseSeq:M?.seq??0});return}catch(W){if(W?.status!==409)throw W}}throw Object.assign(new Error("marker write kept conflicting"),{status:409})},A=async _=>!!(await Me()).entrySync?.some(I=>I.cloudName===_&&I.entries.length>0),N=(_,I)=>v(_,(x,C)=>{let L=C?.find($=>$.id===I.id);if(L&&L.name===I.name)return;let D=L?.since??new Date().toISOString().slice(0,10);return[...(C??[]).filter($=>$.id!==I.id),{...I,since:D}]},()=>A(_)),B=(_,I)=>v(_,(x,C)=>{if(!x||!C?.some(D=>D.id===I))return;let L=C.filter(D=>D.id!==I);return L.length?L:null},async()=>!await A(_)),G=()=>{e(ke.entryChange)},se=async(_,I)=>{let x=w.get(_);if(!x)return;let C=$=>$&&$.startsWith(`${x.cloudName}/`)?$.slice(x.cloudName.length+1):null,L=C(I.path);if(!L)return;let D=!1;await ft($=>{if(w.get(_)!==x)return!1;let M=($.entrySync??[]).find(ie=>ie.vaultRoot===_);if(!M)return!1;let Y=I.op,W=C(I.newPath),J=co(M.entries,Y,L,W),le=W?Nt(M.exclude??[],L,W):{changed:!1,next:M.exclude??[]};if(!J.changed&&!le.changed)return!1;D=!0,M.entries=J.next,le.changed&&(M.exclude=le.next),f(x,et(M.entries,M.exclude??[]))}),D&&w.get(_)===x&&G()},pe=_=>{let I=r;return{...d(),onStatus:x=>{I===r&&e(ke.status,{...x,pendingDeletions:Ee(),side:"local",binding:_})},onRemoteApplied:async x=>{I===r&&await se(_,x)}}},X=async()=>{let _=Te();if(!s||!_)return;let I=r,x=o,C=Pt(_);await t.adoptLegacyCloudState(_,fo);let L=await Me(_),D=L.entrySync??[];if(I!==r||!s||_!==Te())return;let $=new Map(D.map(M=>[M.vaultRoot,M]));for(let[M,Y]of w){let W=$.get(M);if(!(W&&W.cloudName===Y.cloudName)&&(await Y.engine.stop(),I!==r||(w.delete(M),W&&await Zs(`amadeus-sync-${C}-entry-${En(M)}`),I!==r)))return}for(let M of D){let Y=w.get(M.vaultRoot);if(Y){f(Y,et(M.entries,M.exclude??[]));continue}let W={current:et(M.entries,M.exclude??[])},J=M.cloudName,le=Ot(pe(M.vaultRoot),{accountId:_,localRoot:M.vaultRoot,shadowName:`amadeus-sync-${C}-entry-${En(M.vaultRoot)}`,vaultId:"first",serverDir:J,clientIdSuffix:`entry-${En(M.vaultRoot)}`,requireRootExists:!0,ignoreNames:[".git","node_modules",".trash"],inScope:ie=>ie===J?!0:ie.startsWith(`${J}/`)?lo(W.current,ie.slice(J.length+1)):!1});w.set(M.vaultRoot,{engine:le,scope:W,cloudName:J,base:W.current,pendingMoves:new Set}),le.start()}if(L.cloudSync?.enabled!==!1)for(let M of D){let Y=M.entries.length>0,W=Y?P:H;W.has(M.cloudName)||((Y?H:P).delete(M.cloudName),(async()=>{try{let J=await z();if(!J||I!==r||(await(Y?N(M.cloudName,J):B(M.cloudName,J.id)),I!==r))return;W.add(M.cloudName),(Y?H:P).delete(M.cloudName)}catch{}})())}},de=async(_,I,x,C,L)=>{let D=I.replace(/\\/g,"/").normalize("NFC"),$=x.replace(/\\/g,"/").normalize("NFC"),M=!1,Y,W,J,le=L??"file";try{await ft(async ie=>{if(w.get(_)!==C)return!1;let me=(ie.entrySync??[]).find(Re=>Re.vaultRoot===_);if(!me)return!1;let ce=Ut(me.entries,D,$),ue=Nt(me.exclude??[],D,$),Ue=gt(me.entries,me.exclude,D);!L&&await ht.stat(st.join(_,...$.split("/"))).then(Re=>Re.isDirectory(),()=>!1)&&(le="folder");let it=le==="folder"?"folder":/\.md$/i.test($)?"page":"asset";Ue&&!gt(ce.next,ue.next,$)&&(ce.next.push({path:$,kind:it}),ce.changed=!0),M=ce.changed||ue.changed;let at=me.entries.filter(Re=>Ut([Re],D,$).changed);return Ue&&!at.some(Re=>Re.path===D)&&at.push({path:D,kind:it}),Y=et(at,(me.exclude??[]).filter(Re=>Nt([Re],D,$).changed)),W=C.base,C.pendingMoves.add(Y),me.entries=ce.next,me.exclude=ue.next,J=et(me.entries,me.exclude),f(C,J),M})}catch(ie){throw Y&&C.pendingMoves.delete(Y),f(C,C.base===J&&W?W:C.base),ie}try{Y&&await C.engine.notifyLocalMove(D,$,()=>{C.pendingMoves.delete(Y),f(C)},le)}catch(ie){throw Y&&C.pendingMoves.delete(Y),await ft(me=>{let ce=me.entrySync?.find(ue=>ue.vaultRoot===_);if(!ce)return!1;ce.entries=Ut(ce.entries,$,D).next,ce.exclude=Nt(ce.exclude??[],$,D).next,f(C,et(ce.entries,ce.exclude))}),ie}M&&w.get(_)===C&&G()},Z=_=>{let I=_.replace(/\\/g,"/");for(let{engine:x,plan:C}of m.values())if(I.startsWith(`${C.localRelDir}/`))return{engine:x,rel:I.slice(C.localRelDir.length+1)};return{engine:u,rel:I}};t.setMutationHooks((_,I)=>{if(y()){let x=Z(_);x.engine.notifyLocal(x.rel,I);return}w.get(n()??"")?.engine.notifyLocal(_,I)},(_,I,x)=>{if(y()){let D=Z(_),$=Z(I);if(D.engine===$.engine)return D.engine.notifyLocalMove(D.rel,$.rel,void 0,x);D.engine.notifyLocal(D.rel,"remove"),$.engine.notifyLocal($.rel,"write");return}let C=n()??"",L=w.get(C);if(L)return de(C,_,I,L,x)},(_,I)=>{if(y()){let x=Z(_),C=Z(I),L=[x.engine.holdLocalMove(x.rel,C.rel)];return x.engine!==C.engine&&L.push(C.engine.holdLocalMove(x.rel,C.rel)),()=>{for(let D of L)D()}}return w.get(n()??"")?.engine.holdLocalMove(_,I)});let Ee=()=>{let _=u.getStatus().pendingDeletions;for(let{engine:I}of m.values())_+=I.getStatus().pendingDeletions;for(let{engine:I}of w.values())_+=I.getStatus().pendingDeletions;return _},oe=_=>({..._,pendingDeletions:Ee(),side:y()?"cloud":"local"}),_e=()=>{if(!s)return Promise.resolve(u.getStatus());p();for(let{engine:_}of m.values())_.syncNow();for(let{engine:_}of w.values())_.syncNow();return u.syncNow()},fe=async()=>{++r,s=!1,o.stop();let _=[u.stop(),...[...m.values()].map(({engine:x})=>x.stop()),...[...w.values()].map(({engine:x})=>x.stop())];m.clear(),w.clear(),g=[],P.clear(),H.clear(),i.clear(),l(),await Promise.all(_),await t.awaitPendingVaultWrites();let I=n();if(I&&yn(I)){let x=await Me(),C=x.localVault&&!yn(x.localVault)?x.localVault:st.join(t.workspaceDir(),"Amadeus");await ht.mkdir(C,{recursive:!0}),await Ve({lastVault:C,localVault:C,lastPage:void 0}),await t.activateRoot(C,!1)}G()};return{handlers:{get:()=>oe(u.getStatus()),setEnabled:async _=>{if(!s)throw new Error("Cloud account is changing");let I=r;return await u.setEnabled(_),I!==r?u.getStatus():(await Promise.all([...m.values(),...w.values()].map(({engine:x})=>x.restart())),oe(u.getStatus()))},syncNow:()=>_e(),confirmDeletions:()=>{for(let{engine:_}of m.values())_.confirmMassDeletions();for(let{engine:_}of w.values())_.confirmMassDeletions();return oe(u.confirmMassDeletions())},entryGet:async()=>{let _=await Me(),I=Ze(),x=await io(I);return{vaults:_.entrySync??[],activeRoot:n(),cloudRoot:I,mirrorVaults:x.names,mirrorVaultDevices:x.devices,deviceId:_.cloudSync?.deviceId??null}},otherSideDbs:async()=>{let _=n();if(!_)return null;let I=Ze(),x=await Me(),C=_===I?x.localVault&&x.localVault!==I?x.localVault:null:I;if(!C)return null;let L=[],D=500,$=async(M,Y)=>{if(L.length>=D)return;let W;try{W=await ht.readdir(M,{withFileTypes:!0})}catch{return}for(let J of W){if(L.length>=D)break;if(J.name.startsWith(".")||J.isSymbolicLink())continue;let le=Y?`${Y}/${J.name}`:J.name;if(J.isDirectory())await $(st.join(M,J.name),le);else if(J.isFile()&&/\.db$/i.test(J.name))try{L.push({rel:le,source:await ht.readFile(st.join(M,J.name),"utf8")})}catch{}}};return await $(C,""),{root:C,vaultName:C===I?"\u4E91\u7AEF":st.basename(C),dbs:L}},entryEnable:async _=>{let I=r,x=o;if(!s||!Te())return{error:"Sign in to enable cloud sync"};let C=n();if(!C||y())return{error:"\u4EC5\u672C\u5730 vault \u53EF\u5F00\u542F\u4E91\u540C\u6B65"};let L=await Me(),D=L.entrySync??[],$=D.find(M=>M.vaultRoot===C);if(!$){let M=(_.cloudName??st.basename(C)).normalize("NFC").trim(),Y=wr(M,D.map(W=>W.cloudName));if(Y)return{error:Y};if(!_.merge)try{let W=await x.ensureOwnVault(),J=await x.call("GET",`/vaults/${encodeURIComponent(W)}/tree`);if((J.folders??[]).some(ie=>ie===M||ie.startsWith(`${M}/`))||(J.entries??[]).some(ie=>ie.path===M||ie.path.startsWith(`${M}/`)))return{conflict:M}}catch(W){return{error:W?.message||"\u65E0\u6CD5\u8FDE\u63A5\u4E91\u7AEF(\u9996\u6B21\u5F00\u542F\u9700\u8981\u5728\u7EBF)"}}$={vaultRoot:C,cloudName:M,entries:[]},D.push($)}return I!==r||!s?{error:"Cloud account changed; retry from the current account"}:(await ft(M=>{if(I!==r||!s)return!1;let Y=M.entrySync??[],W=Y.find(ue=>ue.vaultRoot===C);if(!W){let ue=wr($.cloudName,Y.map(Ue=>Ue.cloudName));if(ue)throw new Error(ue);W={vaultRoot:C,cloudName:$.cloudName,entries:[]},Y.push(W)}let J=ue=>String(ue??"").replace(/\\/g,"/").normalize("NFC"),le=new Set;for(let ue of _.entries??[]){let Ue=J(ue.path);Ue&&(le.add(Ue),!W.entries.some(it=>it.path===Ue)&&W.entries.push({path:Ue,kind:ue.kind==="folder"||ue.kind==="asset"?ue.kind:"page"}))}let ie=(_.exclude??[]).map(J).filter(Boolean),me=new Set([...le,...(_.include??[]).map(J).filter(Boolean)]);W.exclude=[...new Set([...(W.exclude??[]).filter(ue=>!me.has(ue)),...ie])];let ce=new Set(ie);W.entries=W.entries.filter(ue=>!ce.has(ue.path)),M.entrySync=Y,$=W},L.cloudAccountId),I!==r?{error:"Cloud account changed; retry from the current account"}:(await X(),w.get(C)?.engine.syncNow(),G(),{ok:!0,cloudName:$.cloudName}))},entryDisable:async _=>{let I=n(),x=!1,C=r;return await ft(L=>{if(C!==r||!s)return!1;let D=(L.entrySync??[]).find(Y=>Y.vaultRoot===I);if(!I||!D)return!1;let $=String(_??"").replace(/\\/g,"/").normalize("NFC"),M=D.entries.length;if(D.entries=D.entries.filter(Y=>Y.path!==$),gt(D.entries,D.exclude,$))D.exclude=[...new Set([...D.exclude??[],$])];else if(D.entries.length===M)return!1;x=!0}),!x||C!==r?{ok:!1}:(await X(),G(),{ok:!0})},entryMark:async(_,I)=>{let x=String(_??"").normalize("NFC");if(!x||x.includes("/")||x.startsWith("."))return{error:"invalid name"};if(!s||!Te())return{error:"Sign in first"};try{await v(x,C=>I?C?void 0:[]:C?null:void 0)}catch(C){return{error:C?.message||String(C)}}return u.syncNow(),{ok:!0}},entryClosure:(_,I)=>t.relatedClosure(String(_??""),I==="folder"?"folder":"page"),collabCall:async(_,I)=>{let x=o,C=async()=>x.ensureOwnVault(),L=$=>String((I??[])[$]??""),D=$=>(I??[])[$]??{};switch(_){case"listVaults":return(await x.call("GET","/vaults")).vaults;case"activeVaultId":return C();case"pageShare":return x.call("GET",`/vaults/${encodeURIComponent(await C())}/page-shares?path=${encodeURIComponent(L(0))}`);case"createPageShare":return x.call("POST",`/vaults/${encodeURIComponent(await C())}/page-shares`,{path:L(0),...D(1)});case"updatePageShare":return x.call("PATCH",`/vaults/${encodeURIComponent(await C())}/page-shares/${encodeURIComponent(L(0))}`,D(1));case"revokePageShare":return x.call("DELETE",`/vaults/${encodeURIComponent(await C())}/page-shares/${encodeURIComponent(L(0))}`);case"setParticipantRole":return x.call("PATCH",`/vaults/${encodeURIComponent(await C())}/page-shares/${encodeURIComponent(L(0))}/members/${encodeURIComponent(L(1))}`,{role:L(2)});case"removeParticipant":return x.call("DELETE",`/vaults/${encodeURIComponent(await C())}/page-shares/${encodeURIComponent(L(0))}/members/${encodeURIComponent(L(1))}`);case"sharedWithMe":{let $=await x.sharedWithMe();return p(),$}case"leaveShare":{let $=x.myUserId();if(!$)throw new Error("\u672A\u767B\u5F55");return x.call("DELETE",`/vaults/${encodeURIComponent(await C())}/page-shares/${encodeURIComponent(L(0))}/members/${encodeURIComponent($)}`)}case"publishes":return x.call("GET",`/vaults/${encodeURIComponent(await C())}/shares`);case"listAllShares":{let $=(await x.call("GET","/vaults")).vaults||[],M=x.myUserId(),Y=[],W=[];for(let J of $){try{let le=await x.call("GET",`/vaults/${encodeURIComponent(J.id)}/shares`);for(let ie of le.shares||[])Y.push({...ie,vaultId:J.id,vaultName:J.name||""})}catch(le){t.log(`[connect] listAllShares publishes vault ${J.id} failed: ${le?.message}`)}try{let le=await x.call("GET",`/vaults/${encodeURIComponent(J.id)}/page-shares`),ie=le?.shares||le?.pageShares||(Array.isArray(le)?le:[]);for(let me of ie){let ce=me.created_by??me.createdBy;(!M||!ce||ce===M)&&W.push({...me,vaultId:J.id,vaultName:J.name||""})}}catch(le){t.log(`[connect] listAllShares pageShares vault ${J.id} failed: ${le?.message}`)}}return{publishes:Y,pageShares:W,linkBase:await x.linkBase()}}case"createPublish":{let $=await x.call("POST",`/vaults/${encodeURIComponent(await C())}/shares`,{mode:L(0),path:L(1)});return{...$,url:`${await x.linkBase()}/share/${$.token}`}}case"revokePublish":return x.call("DELETE",`/vaults/${encodeURIComponent(await C())}/shares/${encodeURIComponent(L(0))}`);case"revokePublishIn":return x.call("DELETE",`/vaults/${encodeURIComponent(L(0))}/shares/${encodeURIComponent(L(1))}`);case"revokePageShareIn":return x.call("DELETE",`/vaults/${encodeURIComponent(L(0))}/page-shares/${encodeURIComponent(L(1))}`);case"myUserId":return x.myUserId();case"linkBase":return x.linkBase();case"heartbeat":return x.heartbeat((I??[])[0]??null,g);default:throw new Error(`unknown collab fn: ${_}`)}},switchSide:async(_,I)=>{let x=await Me();if(I==="cloud"){if(!s||!Te())throw new Error("Sign in to open cloud notes");let D=Ze();await ht.mkdir(D,{recursive:!0}),x.lastVault&&!yn(x.lastVault)&&await Ve({localVault:x.lastVault}),await Ve({lastVault:D});let $=await t.activateRoot(D,!1);return t.bindRenderer(_,D),{...$,side:"cloud"}}let C=x.localVault&&await ht.stat(x.localVault).then(D=>D.isDirectory()).catch(()=>!1)?x.localVault:null;if(!C){let D=await t.ensureDefaultVault();return t.bindRenderer(_,D.root),{...D,side:"local"}}await Ve({lastVault:C});let L=await t.activateRoot(C,!1);return t.bindRenderer(_,C),{...L,side:"local"}}},instance:{start:()=>{s=!0,u.start(),p(),X()},stopAllSync:fe,restartAllSync:async()=>{await fe(),o=pr(),u=Ot(d()),s=!0,await Promise.all([u.restart(),p(),X()]),G(),e(ke.status,oe(u.getStatus()))}}}}import{hostname as ml}from"node:os";var pl=256*1024;function go(t,e,n){if(n?.hasSecHeaders&&!n.gatewayStreamsSecHeaders)return!1;if(t.includes("text/event-stream"))return!0;let r=Number(e||NaN);return!Number.isFinite(r)||r>pl}var kr=45e3,gl=3e3,hl=16*1024,yl=6e4,_n=t=>`${t.replace(/\/+$/,"")}/api`,jt=class{deps;ctrl=null;conn=null;wake=null;redialNow=!1;inflight=new Map;connected=!1;lastError=null;hubCaps=new Set;constructor(e){this.deps=e}hubFetch(e,n){return(this.deps.hubFetch??fetch)(e,n)}get requestTimeoutMs(){return this.deps.requestTimeoutMs??yl}status(){return{running:!!this.ctrl,connected:this.connected,unitId:this.deps.getPairing()?.unitId??null,lastError:this.lastError}}start(){if(this.ctrl)return;let e=new AbortController;this.ctrl=e,this.loop(e)}stop(){this.ctrl?.abort(),this.ctrl=null,this.markDown(),this.abortEnvelopes(),this.wake?.()}reconnect(e){this.ctrl&&(this.deps.log(`[unit-host] \u7ACB\u5373\u91CD\u8FDE\u901A\u9053(${e})`),this.redialNow=!0,this.conn?.abort(),this.wake?.())}markDown(){this.connected=!1,this.hook(this.deps.onChannelDown)}hook(e){try{e?.()}catch(n){this.deps.log(`[unit-host] \u901A\u9053\u56DE\u8C03\u51FA\u9519(\u5DF2\u5FFD\u7565): ${n?.message||n}`)}}abortEnvelope(e){let n=this.inflight.get(e);return n?(this.inflight.delete(e),n.ctrl.abort(),!0):!1}abortEnvelopes(e){for(let[n,r]of[...this.inflight])e&&r.conn!==e||(this.inflight.delete(n),r.ctrl.abort())}sleep(e){return new Promise(n=>{let r=setTimeout(s,e);function s(){clearTimeout(r),n()}this.wake=()=>{this.wake=null,s()}})}async loop(e){let n=1e3;for(;!e.signal.aborted;){let r=new AbortController,s=()=>r.abort();e.signal.addEventListener("abort",s,{once:!0}),this.conn=r;try{let{cloudUrl:o,token:i}=this.deps.getCreds();if(!i)throw new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7");let l=this.deps.getPairing();if(!l){if(l=await this.register(o,i,r),r.signal.aborted)throw new Error("\u5165\u518C\u671F\u95F4\u901A\u9053\u5DF2\u88AB\u505C\u7528");await this.deps.savePairing(l),this.deps.log(`[unit-host] \u5DF2\u5165\u518C\u4E3A\u8BBE\u5907 ${l.unitId}`)}let a=this.deps.getLanUrl();this.hubCaps=new Set;let d=this.deps.readIdleMs??kr,u=d?setTimeout(()=>{this.deps.log(`[unit-host] \u901A\u9053 ${Math.round(d/1e3)}s \u672A\u6536\u5230\u54CD\u5E94\u5934,\u5224\u5B9A\u5DF2\u65AD,\u91CD\u8FDE`),r.abort()},d):null,m;try{m=await this.hubFetch(`${_n(o)}/units/${l.unitId}/channel`,{headers:{Authorization:`Bearer ${i}`,"X-Unit-Secret":l.secret,...a?{"X-Unit-Lan-Url":a}:{}},signal:r.signal})}finally{u&&clearTimeout(u)}if(m.status===403||m.status===404){let g=Number(m.headers.get("content-length"))>hl,p=setTimeout(()=>r.abort(),g?0:gl),y=await m.json().then(f=>f?.code,()=>null);throw clearTimeout(p),y==="UNIT_NOT_FOUND"||y==="UNIT_SECRET_MISMATCH"?(await this.deps.clearPairing(),new Error(`\u901A\u9053\u88AB\u62D2(${m.status} ${y}),\u5DF2\u6E05\u9664\u914D\u5BF9\u5F85\u91CD\u65B0\u5165\u518C`)):new Error(`channel HTTP ${m.status} (not a hub verdict; keeping pairing and retrying)`)}if(!m.ok||!m.body)throw new Error(`channel HTTP ${m.status}`);this.connected=!0,this.lastError=null,n=1e3,this.deps.log("[unit-host] \u901A\u9053\u5DF2\u8FDE\u63A5"),await this.consume(m.body,r),this.markDown(),this.deps.log("[unit-host] \u901A\u9053\u65AD\u5F00,\u51C6\u5907\u91CD\u8FDE")}catch(o){if(this.markDown(),e.signal.aborted)return;this.lastError=r.signal.aborted?"\u901A\u9053\u88AB\u672C\u673A\u65AD\u5F00(\u770B\u95E8\u72D7 / \u91CD\u8FDE)":String(o?.message||o),this.deps.log(`[unit-host] ${this.lastError};${this.redialNow?"\u7ACB\u5373":`${Math.round(n/1e3)}s \u540E`}\u91CD\u8BD5`)}finally{e.signal.removeEventListener("abort",s),this.conn===r&&(this.conn=null),r.abort(),this.abortEnvelopes(r)}if(e.signal.aborted)return;if(this.redialNow){this.redialNow=!1,n=1e3;continue}if(await this.sleep(n),this.redialNow){this.redialNow=!1,n=1e3;continue}n=Math.min(n*2,3e4)}}async register(e,n,r){let s=this.deps.readIdleMs??kr,o=s?setTimeout(()=>{this.deps.log(`[unit-host] \u8BBE\u5907\u5165\u518C ${Math.round(s/1e3)}s \u672A\u8FD4\u56DE,\u4E2D\u6B62\u91CD\u8BD5`),r.abort()},s):null;try{let i=await this.hubFetch(`${_n(e)}/units/register`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({name:ml(),platform:process.platform}),signal:r.signal});if(!i.ok)throw new Error(`\u8BBE\u5907\u5165\u518C\u5931\u8D25 HTTP ${i.status}`);let l=await i.json();if(!l.unitId||!l.secret)throw new Error("\u8BBE\u5907\u5165\u518C\u54CD\u5E94\u7F3A\u5B57\u6BB5");return{unitId:l.unitId,secret:l.secret}}finally{o&&clearTimeout(o)}}async consume(e,n){let r=e.getReader(),s=new TextDecoder,o="",i=this.deps.readIdleMs??kr,l=null,a=()=>{i&&(l&&clearTimeout(l),l=setTimeout(()=>{this.deps.log(`[unit-host] \u901A\u9053 ${Math.round(i/1e3)}s \u65E0\u4EFB\u4F55\u5B57\u8282(\u7F51\u5173 15s \u4E00\u6B21\u5FC3\u8DF3),\u5224\u5B9A\u5DF2\u65AD,\u91CD\u8FDE`),n.abort(),r.cancel().catch(()=>{})},i))};a();try{for(;;){let{done:d,value:u}=await r.read();if(d||n.signal.aborted)return;a(),o=this.parseFrames(o+s.decode(u,{stream:!0}),n)}}finally{l&&clearTimeout(l)}}parseFrames(e,n){let r=e,s;for(;(s=r.indexOf(`
212
+ `;var Ne=t=>t.replace(/\\/g,"/").normalize("NFC");function Fr(t){let e=Ne(t.path);return e?t.kind==="folder"?`${e}/`:t.kind==="page"?`${e.replace(/\.md$/i,"")}.fd/`:null:null}function xt(t,e,n){let r=Ne(n);if(!r)return!1;if(t.some(s=>Ne(s.path)===r))return!0;for(let s of e??[]){let o=Ne(s);if(!o)continue;let i=`${o.replace(/\.md$/i,"")}.fd`;if(r===o||r.startsWith(`${o}/`)||r===i||r.startsWith(`${i}/`))return!1}return t.some(s=>{let o=Fr(s);return!!o&&r.startsWith(o)})}function Lr(t,e,n){let r=Ne(t),s=Ne(e);return r===s?Ne(n):r.startsWith(`${s}/`)?Ne(n)+r.slice(s.length):null}function Jt(t,e,n){let r=!1,s=t.map(o=>{let i=Lr(o,e,n);return i===null?o:(r=!0,i)});return{changed:r,next:s}}async function Bo(t){let e=await qo.readdir(t,{withFileTypes:!0}).catch(()=>[]),n=[],r=Object.create(null);for(let s of e){if(!s.isDirectory()||s.name.startsWith("."))continue;let o=await qo.readFile(lc.join(t,s.name,Ur),"utf8").catch(()=>null);if(o===null)continue;n.push(s.name);let i=Nn(o);i?.length&&(r[s.name]=i)}return{names:n.sort(),devices:r}}var ve={get:"amadeus:sync:get",setEnabled:"amadeus:sync:set-enabled",syncNow:"amadeus:sync:now",confirmDeletions:"amadeus:sync:confirm-deletions",status:"amadeus:sync:status",switchSide:"amadeus:sync:switch-side",collabCall:"amadeus:collab:call",presence:"amadeus:collab:presence",entryGet:"amadeus:entry-sync:get",entryEnable:"amadeus:entry-sync:enable",entryDisable:"amadeus:entry-sync:disable",entryMark:"amadeus:entry-sync:mark",entryClosure:"amadeus:entry-sync:closure",entryChange:"amadeus:entry-sync:change",otherSideDbs:"amadeus:entry-sync:other-side-dbs"};var jn=t=>Se().sha256Hex(t).slice(0,8);function Wo(t){return t.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}\)(?=(?:\.[^./]+)?$)/,"")}function it(t,e=[]){let n=[],r=[];for(let s of t){let o=Ne(s.path);if(!o)continue;r.push(o);let i=Fr(s);i&&n.push(i)}return{entries:t,exclude:e,prefixes:n,paths:r}}function Vo(t,e){let n=Wo(Ne(e));if(!n)return!1;if(xt(t.entries,t.exclude,n))return!0;let r=`${n}/`;for(let s of t.paths)if(s.startsWith(r))return!0;for(let s of t.prefixes)if(s.startsWith(r))return!0;return!1}function Gt(t,e,n){let r=!1,s=t.map(o=>{let i=Lr(o.path,e,n);return i===null?o:(r=!0,{...o,path:i})});return{changed:r,next:s}}function Yo(t,e,n,r){if(e==="delete"||e==="delete-folder"){let s=Ne(n),o=t.filter(i=>{let l=Ne(i.path);return!(l===s||e==="delete-folder"&&l.startsWith(`${s}/`))});return{changed:o.length!==t.length,next:o}}return r?Gt(t,n,r):{changed:!1,next:t}}function zr(t,e){let n=_t(t);return!n||n!==t.normalize("NFC").trim()?"\u540D\u79F0\u4E0D\u5408\u6CD5":n.includes("/")?"\u540D\u79F0\u4E0D\u80FD\u5305\u542B /":n===Mn?`\u300C${Mn}\u300D\u662F\u4FDD\u7559\u540D\u79F0`:e.includes(n)?"\u8BE5\u540D\u79F0\u5DF2\u88AB\u5176\u4ED6\u667A\u5E93\u7684\u4E91\u540C\u6B65\u5360\u7528":null}import{constants as cc,promises as Jo}from"node:fs";async function Go(t,e){try{await Jo.copyFile(Vt(t),Vt(e),cc.COPYFILE_EXCL)}catch(n){let r=n?.code;if(r==="EEXIST"||r==="ENOENT")return!1;throw n}return await Jo.unlink(Vt(t)).catch(()=>{}),!0}var Xo=["setAmadeusSyncFactory","readCreds","accountId","homeDir"],Hr=t=>Xo.every(e=>typeof t[e]=="function"),fc=()=>({enabled:!1,state:"disabled",lastSyncAt:null,pending:0,conflicts:0,skipped:[],error:null,pendingDeletions:0,maxFileBytes:null,side:"local"});function qr(t){let e=null,n=()=>{if(!e)throw new Error("Cloud sync is not ready");return e};t.handle(ve.get,()=>e?e.get():fc()),t.handle(ve.setEnabled,(r,s)=>n().setEnabled(s)),t.handle(ve.syncNow,()=>n().syncNow()),t.handle(ve.confirmDeletions,()=>n().confirmDeletions()),t.handle(ve.entryGet,()=>n().entryGet()),t.handle(ve.otherSideDbs,()=>n().otherSideDbs()),t.handle(ve.entryEnable,(r,s)=>n().entryEnable(s)),t.handle(ve.entryDisable,(r,s)=>n().entryDisable(s)),t.handle(ve.entryMark,(r,s,o)=>n().entryMark(s,o)),t.handle(ve.entryClosure,(r,s,o)=>n().entryClosure(s,o)),t.handle(ve.collabCall,(r,s,o)=>n().collabCall(s,o)),t.handle(ve.switchSide,(r,s)=>n().switchSide(r.sender.id,s)),t.setAmadeusSyncFactory(r=>{To(r);let s=Ko(r);return e=s.handlers,s.instance}),t.log("[forsion-extend] amadeus cloud sync registered")}function Ko(t){let e=t.notifyAll,n=()=>t.vaultRoot(),r=0,s=!1,o=jr(),i=new Map,l=()=>{let _=Date.now();for(let[P,T]of i)_-T.at>7e4&&i.delete(P);e(ve.presence,[...i.values()])},a={loadCreds:()=>t.readCreds(),onStatus:_=>e(ve.status,{..._,pendingDeletions:ke(),side:g()?"cloud":"local"}),onPresence:(_,P)=>{let T=P;T?.userId&&(i.set(T.userId,{userId:T.userId,username:String(T.username??"user"),page:T.page??null,at:Number(T.at)||Date.now()}),l())},onPresenceRoster:(_,P)=>{if(Array.isArray(P)){for(let T of P){let A=T;A?.userId&&i.set(A.userId,{userId:A.userId,username:String(A.username??"user"),page:A.page??null,at:Number(A.at)||Date.now()})}l()}}},c=()=>{let _=r;return{...a,onStatus:P=>{_===r&&a.onStatus(P)},onPresence:(P,T)=>{_===r&&a.onPresence(P,T)},onPresenceRoster:(P,T)=>{_===r&&a.onPresenceRoster(P,T)}}},u=Yt(c()),f=new Map,m=[],h=async()=>{if(!s||!Te())return;let _=r,P=o,T;try{T=await P.sharedWithMe()}catch{return}if(_!==r||!s)return;let A=T.map(D=>Nr(D));m=A;let z=new Set(A.map(D=>D.key));for(let[D,$]of f)if(!z.has(D)){if(await $.engine.stop(),_!==r)return;f.delete(D)}for(let D of A){if(f.has(D.key))continue;let $=Yt(c(),{localRoot:ht.join(st(),...D.localRelDir.split("/")),shadowName:`amadeus-sync-${Bt()}-share-${D.key}`,vaultId:D.vaultId,serverDir:D.serverDir,inScope:D.inScope});f.set(D.key,{engine:$,plan:D}),$.start()}},g=()=>n()===st(),p=(_,P=_.base)=>{_.base=P;let T=[P,..._.pendingMoves];_.scope.current=it(T.flatMap(A=>A.entries),T.flatMap(A=>A.exclude))},y=new Map,E=new Set,O=new Set,C=null,M=()=>C??=new Promise(_=>{let P=()=>dc.hostname().replace(/\.(local|lan|home)$/i,"")||"Desktop";if(process.platform!=="darwin")return _(P());uc("scutil",["--get","ComputerName"],{timeout:1500},(T,A)=>_(!T&&String(A).trim()||P()))}),H=async()=>{let _=(await Me()).cloudSync?.deviceId;return _?{id:_,name:await M()}:null},w=new Map,x=(_,P,T)=>{let A=r,z=(w.get(_)??Promise.resolve()).catch(()=>{}).then(async()=>{A!==r||T&&!await T()||A!==r||await b(_,P,A)});return w.set(_,z),z.finally(()=>{w.get(_)===z&&w.delete(_)}).catch(()=>{}),z},b=async(_,P,T)=>{let A=o,z=encodeURIComponent(await A.ensureOwnVault()),D=zo(_);for(let $=0;$<3;$++){let N=null;try{N=await A.call("GET",`/vaults/${z}/file?path=${encodeURIComponent(D)}`)}catch(W){if(W?.status!==404)throw W}let Y=P(!!N,N?Nn(N.content):null);if(Y===void 0||T!==r)return;try{if(Y===null){N&&await A.call("DELETE",`/vaults/${z}/file?path=${encodeURIComponent(D)}&baseSeq=${N.seq}`);return}await A.call("PUT",`/vaults/${z}/file`,{path:D,content:Ho(Y),baseSeq:N?.seq??0});return}catch(W){if(W?.status!==409)throw W}}throw Object.assign(new Error("marker write kept conflicting"),{status:409})},I=async _=>!!(await Me()).entrySync?.some(P=>P.cloudName===_&&P.entries.length>0),U=(_,P)=>x(_,(T,A)=>{let z=A?.find($=>$.id===P.id);if(z&&z.name===P.name)return;let D=z?.since??new Date().toISOString().slice(0,10);return[...(A??[]).filter($=>$.id!==P.id),{...P,since:D}]},()=>I(_)),B=(_,P)=>x(_,(T,A)=>{if(!T||!A?.some(D=>D.id===P))return;let z=A.filter(D=>D.id!==P);return z.length?z:null},async()=>!await I(_)),J=()=>{e(ve.entryChange)},se=async(_,P)=>{let T=y.get(_);if(!T)return;let A=$=>$&&$.startsWith(`${T.cloudName}/`)?$.slice(T.cloudName.length+1):null,z=A(P.path);if(!z)return;let D=!1;await Et($=>{if(y.get(_)!==T)return!1;let N=($.entrySync??[]).find(ie=>ie.vaultRoot===_);if(!N)return!1;let Y=P.op,W=A(P.newPath),G=Yo(N.entries,Y,z,W),le=W?Jt(N.exclude??[],z,W):{changed:!1,next:N.exclude??[]};if(!G.changed&&!le.changed)return!1;D=!0,N.entries=G.next,le.changed&&(N.exclude=le.next),p(T,it(N.entries,N.exclude??[]))}),D&&y.get(_)===T&&J()},pe=_=>{let P=r;return{...c(),onStatus:T=>{P===r&&e(ve.status,{...T,pendingDeletions:ke(),side:"local",binding:_})},onRemoteApplied:async T=>{P===r&&await se(_,T)}}},X=async()=>{let _=Te();if(!s||!_)return;let P=r,T=o,A=Bt(_);await t.adoptLegacyCloudState(_,Go);let z=await Me(_),D=z.entrySync??[];if(P!==r||!s||_!==Te())return;let $=new Map(D.map(N=>[N.vaultRoot,N]));for(let[N,Y]of y){let W=$.get(N);if(!(W&&W.cloudName===Y.cloudName)&&(await Y.engine.stop(),P!==r||(y.delete(N),W&&await No(`amadeus-sync-${A}-entry-${jn(N)}`),P!==r)))return}for(let N of D){let Y=y.get(N.vaultRoot);if(Y){p(Y,it(N.entries,N.exclude??[]));continue}let W={current:it(N.entries,N.exclude??[])},G=N.cloudName,le=Yt(pe(N.vaultRoot),{accountId:_,localRoot:N.vaultRoot,shadowName:`amadeus-sync-${A}-entry-${jn(N.vaultRoot)}`,vaultId:"first",serverDir:G,clientIdSuffix:`entry-${jn(N.vaultRoot)}`,requireRootExists:!0,ignoreNames:[".git","node_modules",".trash"],inScope:ie=>ie===G?!0:ie.startsWith(`${G}/`)?Vo(W.current,ie.slice(G.length+1)):!1});y.set(N.vaultRoot,{engine:le,scope:W,cloudName:G,base:W.current,pendingMoves:new Set}),le.start()}if(z.cloudSync?.enabled!==!1)for(let N of D){let Y=N.entries.length>0,W=Y?E:O;W.has(N.cloudName)||((Y?O:E).delete(N.cloudName),(async()=>{try{let G=await H();if(!G||P!==r||(await(Y?U(N.cloudName,G):B(N.cloudName,G.id)),P!==r))return;W.add(N.cloudName),(Y?O:E).delete(N.cloudName)}catch{}})())}},de=async(_,P,T,A,z)=>{let D=P.replace(/\\/g,"/").normalize("NFC"),$=T.replace(/\\/g,"/").normalize("NFC"),N=!1,Y,W,G,le=z??"file";try{await Et(async ie=>{if(y.get(_)!==A)return!1;let he=(ie.entrySync??[]).find(Re=>Re.vaultRoot===_);if(!he)return!1;let ce=Gt(he.entries,D,$),ue=Jt(he.exclude??[],D,$),Ue=xt(he.entries,he.exclude,D);!z&&await Tt.stat(ht.join(_,...$.split("/"))).then(Re=>Re.isDirectory(),()=>!1)&&(le="folder");let yt=le==="folder"?"folder":/\.md$/i.test($)?"page":"asset";Ue&&!xt(ce.next,ue.next,$)&&(ce.next.push({path:$,kind:yt}),ce.changed=!0),N=ce.changed||ue.changed;let wt=he.entries.filter(Re=>Gt([Re],D,$).changed);return Ue&&!wt.some(Re=>Re.path===D)&&wt.push({path:D,kind:yt}),Y=it(wt,(he.exclude??[]).filter(Re=>Jt([Re],D,$).changed)),W=A.base,A.pendingMoves.add(Y),he.entries=ce.next,he.exclude=ue.next,G=it(he.entries,he.exclude),p(A,G),N})}catch(ie){throw Y&&A.pendingMoves.delete(Y),p(A,A.base===G&&W?W:A.base),ie}try{Y&&await A.engine.notifyLocalMove(D,$,()=>{A.pendingMoves.delete(Y),p(A)},le)}catch(ie){throw Y&&A.pendingMoves.delete(Y),await Et(he=>{let ce=he.entrySync?.find(ue=>ue.vaultRoot===_);if(!ce)return!1;ce.entries=Gt(ce.entries,$,D).next,ce.exclude=Jt(ce.exclude??[],$,D).next,p(A,it(ce.entries,ce.exclude))}),ie}N&&y.get(_)===A&&J()},Z=_=>{let P=_.replace(/\\/g,"/");for(let{engine:T,plan:A}of f.values())if(P.startsWith(`${A.localRelDir}/`))return{engine:T,rel:P.slice(A.localRelDir.length+1)};return{engine:u,rel:P}};t.setMutationHooks((_,P)=>{if(g()){let T=Z(_);T.engine.notifyLocal(T.rel,P);return}y.get(n()??"")?.engine.notifyLocal(_,P)},(_,P,T)=>{if(g()){let D=Z(_),$=Z(P);if(D.engine===$.engine)return D.engine.notifyLocalMove(D.rel,$.rel,void 0,T);D.engine.notifyLocal(D.rel,"remove"),$.engine.notifyLocal($.rel,"write");return}let A=n()??"",z=y.get(A);if(z)return de(A,_,P,z,T)},(_,P)=>{if(g()){let T=Z(_),A=Z(P),z=[T.engine.holdLocalMove(T.rel,A.rel)];return T.engine!==A.engine&&z.push(A.engine.holdLocalMove(T.rel,A.rel)),()=>{for(let D of z)D()}}return y.get(n()??"")?.engine.holdLocalMove(_,P)});let ke=()=>{let _=u.getStatus().pendingDeletions;for(let{engine:P}of f.values())_+=P.getStatus().pendingDeletions;for(let{engine:P}of y.values())_+=P.getStatus().pendingDeletions;return _},oe=_=>({..._,pendingDeletions:ke(),side:g()?"cloud":"local"}),Ee=()=>{if(!s)return Promise.resolve(u.getStatus());h();for(let{engine:_}of f.values())_.syncNow();for(let{engine:_}of y.values())_.syncNow();return u.syncNow()},fe=async()=>{++r,s=!1,o.stop();let _=[u.stop(),...[...f.values()].map(({engine:T})=>T.stop()),...[...y.values()].map(({engine:T})=>T.stop())];f.clear(),y.clear(),m=[],E.clear(),O.clear(),i.clear(),l(),await Promise.all(_),await t.awaitPendingVaultWrites();let P=n();if(P&&Dn(P)){let T=await Me(),A=T.localVault&&!Dn(T.localVault)?T.localVault:ht.join(t.workspaceDir(),"Amadeus");await Tt.mkdir(A,{recursive:!0}),await Xe({lastVault:A,localVault:A,lastPage:void 0}),await t.activateRoot(A,!1)}J()};return{handlers:{get:()=>oe(u.getStatus()),setEnabled:async _=>{if(!s)throw new Error("Cloud account is changing");let P=r;return await u.setEnabled(_),P!==r?u.getStatus():(await Promise.all([...f.values(),...y.values()].map(({engine:T})=>T.restart())),oe(u.getStatus()))},syncNow:()=>Ee(),confirmDeletions:()=>{for(let{engine:_}of f.values())_.confirmMassDeletions();for(let{engine:_}of y.values())_.confirmMassDeletions();return oe(u.confirmMassDeletions())},entryGet:async()=>{let _=await Me(),P=st(),T=await Bo(P);return{vaults:_.entrySync??[],activeRoot:n(),cloudRoot:P,mirrorVaults:T.names,mirrorVaultDevices:T.devices,deviceId:_.cloudSync?.deviceId??null}},otherSideDbs:async()=>{let _=n();if(!_)return null;let P=st(),T=await Me(),A=_===P?T.localVault&&T.localVault!==P?T.localVault:null:P;if(!A)return null;let z=[],D=500,$=async(N,Y)=>{if(z.length>=D)return;let W;try{W=await Tt.readdir(N,{withFileTypes:!0})}catch{return}for(let G of W){if(z.length>=D)break;if(G.name.startsWith(".")||G.isSymbolicLink())continue;let le=Y?`${Y}/${G.name}`:G.name;if(G.isDirectory())await $(ht.join(N,G.name),le);else if(G.isFile()&&/\.db$/i.test(G.name))try{z.push({rel:le,source:await Tt.readFile(ht.join(N,G.name),"utf8")})}catch{}}};return await $(A,""),{root:A,vaultName:A===P?"\u4E91\u7AEF":ht.basename(A),dbs:z}},entryEnable:async _=>{let P=r,T=o;if(!s||!Te())return{error:"Sign in to enable cloud sync"};let A=n();if(!A||g())return{error:"\u4EC5\u672C\u5730 vault \u53EF\u5F00\u542F\u4E91\u540C\u6B65"};let z=await Me(),D=z.entrySync??[],$=D.find(N=>N.vaultRoot===A);if(!$){let N=(_.cloudName??ht.basename(A)).normalize("NFC").trim(),Y=zr(N,D.map(W=>W.cloudName));if(Y)return{error:Y};if(!_.merge)try{let W=await T.ensureOwnVault(),G=await T.call("GET",`/vaults/${encodeURIComponent(W)}/tree`);if((G.folders??[]).some(ie=>ie===N||ie.startsWith(`${N}/`))||(G.entries??[]).some(ie=>ie.path===N||ie.path.startsWith(`${N}/`)))return{conflict:N}}catch(W){return{error:W?.message||"\u65E0\u6CD5\u8FDE\u63A5\u4E91\u7AEF(\u9996\u6B21\u5F00\u542F\u9700\u8981\u5728\u7EBF)"}}$={vaultRoot:A,cloudName:N,entries:[]},D.push($)}return P!==r||!s?{error:"Cloud account changed; retry from the current account"}:(await Et(N=>{if(P!==r||!s)return!1;let Y=N.entrySync??[],W=Y.find(ue=>ue.vaultRoot===A);if(!W){let ue=zr($.cloudName,Y.map(Ue=>Ue.cloudName));if(ue)throw new Error(ue);W={vaultRoot:A,cloudName:$.cloudName,entries:[]},Y.push(W)}let G=ue=>String(ue??"").replace(/\\/g,"/").normalize("NFC"),le=new Set;for(let ue of _.entries??[]){let Ue=G(ue.path);Ue&&(le.add(Ue),!W.entries.some(yt=>yt.path===Ue)&&W.entries.push({path:Ue,kind:ue.kind==="folder"||ue.kind==="asset"?ue.kind:"page"}))}let ie=(_.exclude??[]).map(G).filter(Boolean),he=new Set([...le,...(_.include??[]).map(G).filter(Boolean)]);W.exclude=[...new Set([...(W.exclude??[]).filter(ue=>!he.has(ue)),...ie])];let ce=new Set(ie);W.entries=W.entries.filter(ue=>!ce.has(ue.path)),N.entrySync=Y,$=W},z.cloudAccountId),P!==r?{error:"Cloud account changed; retry from the current account"}:(await X(),y.get(A)?.engine.syncNow(),J(),{ok:!0,cloudName:$.cloudName}))},entryDisable:async _=>{let P=n(),T=!1,A=r;return await Et(z=>{if(A!==r||!s)return!1;let D=(z.entrySync??[]).find(Y=>Y.vaultRoot===P);if(!P||!D)return!1;let $=String(_??"").replace(/\\/g,"/").normalize("NFC"),N=D.entries.length;if(D.entries=D.entries.filter(Y=>Y.path!==$),xt(D.entries,D.exclude,$))D.exclude=[...new Set([...D.exclude??[],$])];else if(D.entries.length===N)return!1;T=!0}),!T||A!==r?{ok:!1}:(await X(),J(),{ok:!0})},entryMark:async(_,P)=>{let T=String(_??"").normalize("NFC");if(!T||T.includes("/")||T.startsWith("."))return{error:"invalid name"};if(!s||!Te())return{error:"Sign in first"};try{await x(T,A=>P?A?void 0:[]:A?null:void 0)}catch(A){return{error:A?.message||String(A)}}return u.syncNow(),{ok:!0}},entryClosure:(_,P)=>t.relatedClosure(String(_??""),P==="folder"?"folder":"page"),collabCall:async(_,P)=>{let T=o,A=async()=>T.ensureOwnVault(),z=$=>String((P??[])[$]??""),D=$=>(P??[])[$]??{};switch(_){case"listVaults":return(await T.call("GET","/vaults")).vaults;case"activeVaultId":return A();case"pageShare":return T.call("GET",`/vaults/${encodeURIComponent(await A())}/page-shares?path=${encodeURIComponent(z(0))}`);case"createPageShare":return T.call("POST",`/vaults/${encodeURIComponent(await A())}/page-shares`,{path:z(0),...D(1)});case"updatePageShare":return T.call("PATCH",`/vaults/${encodeURIComponent(await A())}/page-shares/${encodeURIComponent(z(0))}`,D(1));case"revokePageShare":return T.call("DELETE",`/vaults/${encodeURIComponent(await A())}/page-shares/${encodeURIComponent(z(0))}`);case"setParticipantRole":return T.call("PATCH",`/vaults/${encodeURIComponent(await A())}/page-shares/${encodeURIComponent(z(0))}/members/${encodeURIComponent(z(1))}`,{role:z(2)});case"removeParticipant":return T.call("DELETE",`/vaults/${encodeURIComponent(await A())}/page-shares/${encodeURIComponent(z(0))}/members/${encodeURIComponent(z(1))}`);case"sharedWithMe":{let $=await T.sharedWithMe();return h(),$}case"leaveShare":{let $=T.myUserId();if(!$)throw new Error("\u672A\u767B\u5F55");return T.call("DELETE",`/vaults/${encodeURIComponent(await A())}/page-shares/${encodeURIComponent(z(0))}/members/${encodeURIComponent($)}`)}case"publishes":return T.call("GET",`/vaults/${encodeURIComponent(await A())}/shares`);case"listAllShares":{let $=(await T.call("GET","/vaults")).vaults||[],N=T.myUserId(),Y=[],W=[];for(let G of $){try{let le=await T.call("GET",`/vaults/${encodeURIComponent(G.id)}/shares`);for(let ie of le.shares||[])Y.push({...ie,vaultId:G.id,vaultName:G.name||""})}catch(le){t.log(`[connect] listAllShares publishes vault ${G.id} failed: ${le?.message}`)}try{let le=await T.call("GET",`/vaults/${encodeURIComponent(G.id)}/page-shares`),ie=le?.shares||le?.pageShares||(Array.isArray(le)?le:[]);for(let he of ie){let ce=he.created_by??he.createdBy;(!N||!ce||ce===N)&&W.push({...he,vaultId:G.id,vaultName:G.name||""})}}catch(le){t.log(`[connect] listAllShares pageShares vault ${G.id} failed: ${le?.message}`)}}return{publishes:Y,pageShares:W,linkBase:await T.linkBase()}}case"createPublish":{let $=await T.call("POST",`/vaults/${encodeURIComponent(await A())}/shares`,{mode:z(0),path:z(1)});return{...$,url:`${await T.linkBase()}/share/${$.token}`}}case"revokePublish":return T.call("DELETE",`/vaults/${encodeURIComponent(await A())}/shares/${encodeURIComponent(z(0))}`);case"revokePublishIn":return T.call("DELETE",`/vaults/${encodeURIComponent(z(0))}/shares/${encodeURIComponent(z(1))}`);case"revokePageShareIn":return T.call("DELETE",`/vaults/${encodeURIComponent(z(0))}/page-shares/${encodeURIComponent(z(1))}`);case"myUserId":return T.myUserId();case"linkBase":return T.linkBase();case"heartbeat":return T.heartbeat((P??[])[0]??null,m);default:throw new Error(`unknown collab fn: ${_}`)}},switchSide:async(_,P)=>{let T=await Me();if(P==="cloud"){if(!s||!Te())throw new Error("Sign in to open cloud notes");let D=st();await Tt.mkdir(D,{recursive:!0}),T.lastVault&&!Dn(T.lastVault)&&await Xe({localVault:T.lastVault}),await Xe({lastVault:D});let $=await t.activateRoot(D,!1);return t.bindRenderer(_,D),{...$,side:"cloud"}}let A=T.localVault&&await Tt.stat(T.localVault).then(D=>D.isDirectory()).catch(()=>!1)?T.localVault:null;if(!A){let D=await t.ensureDefaultVault();return t.bindRenderer(_,D.root),{...D,side:"local"}}await Xe({lastVault:A});let z=await t.activateRoot(A,!1);return t.bindRenderer(_,A),{...z,side:"local"}}},instance:{start:()=>{s=!0,u.start(),h(),X()},stopAllSync:fe,restartAllSync:async()=>{await fe(),o=jr(),u=Yt(c()),s=!0,await Promise.all([u.restart(),h(),X()]),J(),e(ve.status,oe(u.getStatus()))}}}}import{hostname as hc}from"node:os";var pc=256*1024;function Zo(t,e,n){if(n?.hasSecHeaders&&!n.gatewayStreamsSecHeaders)return!1;if(t.includes("text/event-stream"))return!0;let r=Number(e||NaN);return!Number.isFinite(r)||r>pc}var Br=45e3,mc=3e3,gc=16*1024,yc=6e4,Un=t=>`${t.replace(/\/+$/,"")}/api`,Xt=class{deps;ctrl=null;conn=null;wake=null;redialNow=!1;inflight=new Map;connected=!1;lastError=null;hubCaps=new Set;constructor(e){this.deps=e}hubFetch(e,n){return(this.deps.hubFetch??fetch)(e,n)}get requestTimeoutMs(){return this.deps.requestTimeoutMs??yc}status(){return{running:!!this.ctrl,connected:this.connected,unitId:this.deps.getPairing()?.unitId??null,lastError:this.lastError}}start(){if(this.ctrl)return;let e=new AbortController;this.ctrl=e,this.loop(e)}stop(){this.ctrl?.abort(),this.ctrl=null,this.markDown(),this.abortEnvelopes(),this.wake?.()}reconnect(e){this.ctrl&&(this.deps.log(`[unit-host] \u7ACB\u5373\u91CD\u8FDE\u901A\u9053(${e})`),this.redialNow=!0,this.conn?.abort(),this.wake?.())}markDown(){this.connected=!1,this.hook(this.deps.onChannelDown)}hook(e){try{e?.()}catch(n){this.deps.log(`[unit-host] \u901A\u9053\u56DE\u8C03\u51FA\u9519(\u5DF2\u5FFD\u7565): ${n?.message||n}`)}}abortEnvelope(e){let n=this.inflight.get(e);return n?(this.inflight.delete(e),n.ctrl.abort(),!0):!1}abortEnvelopes(e){for(let[n,r]of[...this.inflight])e&&r.conn!==e||(this.inflight.delete(n),r.ctrl.abort())}sleep(e){return new Promise(n=>{let r=setTimeout(s,e);function s(){clearTimeout(r),n()}this.wake=()=>{this.wake=null,s()}})}async loop(e){let n=1e3;for(;!e.signal.aborted;){let r=new AbortController,s=()=>r.abort();e.signal.addEventListener("abort",s,{once:!0}),this.conn=r;try{let{cloudUrl:o,token:i}=this.deps.getCreds();if(!i)throw new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7");let l=this.deps.getPairing();if(!l){if(l=await this.register(o,i,r),r.signal.aborted)throw new Error("\u5165\u518C\u671F\u95F4\u901A\u9053\u5DF2\u88AB\u505C\u7528");await this.deps.savePairing(l),this.deps.log(`[unit-host] \u5DF2\u5165\u518C\u4E3A\u8BBE\u5907 ${l.unitId}`)}let a=this.deps.getLanUrl();this.hubCaps=new Set;let c=this.deps.readIdleMs??Br,u=c?setTimeout(()=>{this.deps.log(`[unit-host] \u901A\u9053 ${Math.round(c/1e3)}s \u672A\u6536\u5230\u54CD\u5E94\u5934,\u5224\u5B9A\u5DF2\u65AD,\u91CD\u8FDE`),r.abort()},c):null,f;try{f=await this.hubFetch(`${Un(o)}/units/${l.unitId}/channel`,{headers:{Authorization:`Bearer ${i}`,"X-Unit-Secret":l.secret,...a?{"X-Unit-Lan-Url":a}:{}},signal:r.signal})}finally{u&&clearTimeout(u)}if(f.status===403||f.status===404){let m=Number(f.headers.get("content-length"))>gc,h=setTimeout(()=>r.abort(),m?0:mc),g=await f.json().then(p=>p?.code,()=>null);throw clearTimeout(h),g==="UNIT_NOT_FOUND"||g==="UNIT_SECRET_MISMATCH"?(await this.deps.clearPairing(),new Error(`\u901A\u9053\u88AB\u62D2(${f.status} ${g}),\u5DF2\u6E05\u9664\u914D\u5BF9\u5F85\u91CD\u65B0\u5165\u518C`)):new Error(`channel HTTP ${f.status} (not a hub verdict; keeping pairing and retrying)`)}if(!f.ok||!f.body)throw new Error(`channel HTTP ${f.status}`);this.connected=!0,this.lastError=null,n=1e3,this.deps.log("[unit-host] \u901A\u9053\u5DF2\u8FDE\u63A5"),await this.consume(f.body,r),this.markDown(),this.deps.log("[unit-host] \u901A\u9053\u65AD\u5F00,\u51C6\u5907\u91CD\u8FDE")}catch(o){if(this.markDown(),e.signal.aborted)return;this.lastError=r.signal.aborted?"\u901A\u9053\u88AB\u672C\u673A\u65AD\u5F00(\u770B\u95E8\u72D7 / \u91CD\u8FDE)":String(o?.message||o),this.deps.log(`[unit-host] ${this.lastError};${this.redialNow?"\u7ACB\u5373":`${Math.round(n/1e3)}s \u540E`}\u91CD\u8BD5`)}finally{e.signal.removeEventListener("abort",s),this.conn===r&&(this.conn=null),r.abort(),this.abortEnvelopes(r)}if(e.signal.aborted)return;if(this.redialNow){this.redialNow=!1,n=1e3;continue}if(await this.sleep(n),this.redialNow){this.redialNow=!1,n=1e3;continue}n=Math.min(n*2,3e4)}}async register(e,n,r){let s=this.deps.readIdleMs??Br,o=s?setTimeout(()=>{this.deps.log(`[unit-host] \u8BBE\u5907\u5165\u518C ${Math.round(s/1e3)}s \u672A\u8FD4\u56DE,\u4E2D\u6B62\u91CD\u8BD5`),r.abort()},s):null;try{let i=await this.hubFetch(`${Un(e)}/units/register`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({name:hc(),platform:process.platform}),signal:r.signal});if(!i.ok)throw new Error(`\u8BBE\u5907\u5165\u518C\u5931\u8D25 HTTP ${i.status}`);let l=await i.json();if(!l.unitId||!l.secret)throw new Error("\u8BBE\u5907\u5165\u518C\u54CD\u5E94\u7F3A\u5B57\u6BB5");return{unitId:l.unitId,secret:l.secret}}finally{o&&clearTimeout(o)}}async consume(e,n){let r=e.getReader(),s=new TextDecoder,o="",i=this.deps.readIdleMs??Br,l=null,a=()=>{i&&(l&&clearTimeout(l),l=setTimeout(()=>{this.deps.log(`[unit-host] \u901A\u9053 ${Math.round(i/1e3)}s \u65E0\u4EFB\u4F55\u5B57\u8282(\u7F51\u5173 15s \u4E00\u6B21\u5FC3\u8DF3),\u5224\u5B9A\u5DF2\u65AD,\u91CD\u8FDE`),n.abort(),r.cancel().catch(()=>{})},i))};a();try{for(;;){let{done:c,value:u}=await r.read();if(c||n.signal.aborted)return;a(),o=this.parseFrames(o+s.decode(u,{stream:!0}),n)}}finally{l&&clearTimeout(l)}}parseFrames(e,n){let r=e,s;for(;(s=r.indexOf(`
213
213
 
214
214
  `))>=0;){let o=r.slice(0,s);if(r=r.slice(s+2),o.includes("event: ready")){let l=o.split(`
215
215
  `).find(a=>a.startsWith("data: "))?.slice(6);try{let a=JSON.parse(l||"{}").caps;this.hubCaps=new Set(Array.isArray(a)?a.map(String):[])}catch{this.hubCaps=new Set}n.signal.aborted||this.hook(this.deps.onChannelReady);continue}if(!o.includes("event: dispatch"))continue;let i=o.split(`
216
- `).find(l=>l.startsWith("data: "))?.slice(6);if(i)try{let l=JSON.parse(i);this.dispatch(l,n).catch(a=>this.deps.log(`[unit-host] \u6D3E\u53D1\u5904\u7406\u5931\u8D25: ${a?.message||a}`))}catch{}}return r}async dispatch(e,n){let r=new AbortController;if(n.signal.aborted)return;this.inflight.get(e.id)?.ctrl.abort();let s={ctrl:r,conn:n};this.inflight.set(e.id,s);try{await this.handle(e,r)}finally{this.inflight.get(e.id)===s&&this.inflight.delete(e.id)}}async handle(e,n){let r=this.deps.getUnitWeb();if(!r.url){await this.respond(e.id,503,"application/json",Buffer.from(JSON.stringify({detail:"\u672C\u673A\u4E92\u8054\u670D\u52A1\u672A\u5C31\u7EEA",code:"UNIT_WEB_NOT_READY"})),void 0,n.signal);return}let s={"x-unit-internal":r.internalSecret};e.ct&&(s["Content-Type"]=e.ct),e.accept&&(s.Accept=e.accept);let o;try{let u=new URL(`${r.url}${e.path}`);Object.assign(s,this.deps.callerHeaders({dispatchId:e.id,method:e.method,target:u,proxyCaller:e.proxyCaller})),o=await fetch(u,{method:e.method,headers:s,body:e.body??void 0,signal:n.signal})}catch(u){if(n.signal.aborted)return;await this.respond(e.id,502,"application/json",Buffer.from(JSON.stringify({detail:`\u672C\u673A\u4E92\u8054\u670D\u52A1\u4E0D\u53EF\u8FBE: ${u?.message||u}`})),void 0,n.signal);return}let i=o.headers.get("content-type")||"",l={};for(let u of["content-security-policy","x-content-type-options"]){let m=o.headers.get(u);m&&(l[u]=m)}let a=i||"application/octet-stream";o.body&&go(i,o.headers.get("content-length"),{hasSecHeaders:Object.keys(l).length>0,gatewayStreamsSecHeaders:this.hubCaps.has("stream-sec-headers")})?await this.streamBack(e.id,o,n,a,l):await this.respond(e.id,o.status,a,Buffer.from(await o.arrayBuffer()),l,n.signal)}async respond(e,n,r,s,o,i){if(i?.aborted)return;let{cloudUrl:l,token:a}=this.deps.getCreds(),d=this.deps.getPairing();if(!d)return;let u=this.requestTimeoutMs*2,m=[...u?[AbortSignal.timeout(u)]:[],...i?[i]:[]],g=m.length>1?AbortSignal.any(m):m[0];await this.hubFetch(`${_n(l)}/units/${d.unitId}/resp/${e}`,{method:"POST",headers:{Authorization:`Bearer ${a}`,"X-Unit-Secret":d.secret,"Content-Type":"application/json"},body:JSON.stringify({status:n,headers:{"content-type":r,...o},bodyB64:s.toString("base64")}),...g?{signal:g}:{}}).then(p=>{p.body?.cancel().catch(()=>{})}).catch(p=>{i?.aborted||this.deps.log(`[unit-host] \u56DE\u5305\u5931\u8D25: ${p?.name==="TimeoutError"?`${Math.round(u/1e3)}s \u672A\u5B8C\u6210`:p?.message||p}`)})}async streamBack(e,n,r,s,o){let{cloudUrl:i,token:l}=this.deps.getCreds(),a=this.deps.getPairing();if(!a)return;let d=o?.["content-security-policy"],u=o?.["x-content-type-options"],m=`${_n(i)}/units/${a.unitId}/stream/${e}?status=${n.status}&ct=${encodeURIComponent(s)}`+(d?`&csp=${encodeURIComponent(d)}`:"")+(u?`&xcto=${encodeURIComponent(u)}`:""),g=n.body;if(!g)return;let p=g.getReader(),y=0,f=this.requestTimeoutMs,w=f?setTimeout(()=>{y>=2||(this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20 ${Math.round(f/1e3)}s \u672A\u628A\u9996\u5757\u5199\u7ED9\u7F51\u5173,\u4E2D\u6B62\u672C\u6B21\u6D3E\u53D1`),r.abort())},f):null,P=new ReadableStream({async pull(H){++y===2&&w&&clearTimeout(w);let{done:T,value:U}=await p.read();T?H.close():H.enqueue(U)},cancel(H){return p.cancel(H)}},{highWaterMark:0});try{await this.hubFetch(m,{method:"POST",headers:{Authorization:`Bearer ${l}`,"X-Unit-Secret":a.secret,"Content-Type":"application/octet-stream"},body:P,signal:r.signal,duplex:"half"})}catch(H){this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20\u4E2D\u65AD: ${H?.message||H}`);try{await p.cancel()}catch{}}finally{w&&clearTimeout(w)}}};var Ft=class{d;up=!1;gen=0;lastSent=null;disabled=!1;inflight=!1;again=!1;timer=null;warned=new Set;constructor(e){this.d=e}channelReady(){this.gen++,this.up=!0,this.lastSent=null,this.disabled=!1,this.clearTimer(),this.again=!1,this.flush()}channelDown(){this.gen++,this.up=!1,this.lastSent=null,this.again=!1,this.clearTimer()}engineChanged(){!this.up||this.disabled||(this.clearTimer(),this.timer=setTimeout(()=>{this.timer=null,this.flush()},this.d.debounceMs??500))}clearTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null)}async flush(){if(!this.up||this.disabled)return;if(this.inflight){this.again=!0;return}let e;try{e=this.d.current()}catch(l){this.d.log(`[unit-caps] \u8BFB\u5F15\u64CE\u6001\u5931\u8D25:${l?.message||l}`);return}if(e===this.lastSent)return;let n=this.d.getPairing(),r;try{r=this.d.getCreds()}catch{return}if(!n||!r.token||!r.cloudUrl)return;let s=this.gen;this.inflight=!0;let o=new AbortController,i=setTimeout(()=>o.abort(),this.d.timeoutMs??1e4);try{let l=`${r.cloudUrl.replace(/\/+$/,"")}/api/units/${encodeURIComponent(n.unitId)}/caps`,a=await(this.d.hubFetch??fetch)(l,{method:"POST",headers:{Authorization:`Bearer ${r.token}`,"X-Unit-Secret":n.secret,"Content-Type":"application/json"},body:JSON.stringify({engine:e,tools:[]}),signal:o.signal});try{await a.text()}catch{}if(s!==this.gen)return;a.ok?(this.lastSent=e,this.d.log(`[unit-caps] \u5DF2\u4E0A\u62A5\u5F15\u64CE\u6001 ${e}`)):a.status===404||a.status===405?(this.disabled=!0,this.d.log(`[unit-caps] \u7F51\u5173\u4E0D\u6536 caps(HTTP ${a.status},\u8001\u7248\u672C),\u672C\u8FDE\u63A5\u5185\u4E0D\u518D\u4E0A\u62A5`)):a.status===400||a.status===401||a.status===403?this.warned.has(a.status)||(this.warned.add(a.status),this.d.log(`[unit-caps] \u4E0A\u62A5\u88AB\u62D2 HTTP ${a.status}`)):this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25 HTTP ${a.status},\u7B49\u4E0B\u6B21\u53D8\u5316 / \u91CD\u8FDE\u518D\u62A5`)}catch(l){s===this.gen&&this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25:${o.signal.aborted?"\u8D85\u65F6":l?.message||l}`)}finally{clearTimeout(i),this.inflight=!1,this.again&&this.up&&!this.disabled&&(this.again=!1,this.flush())}}};var ho=["setUnitHubFactory"],Er=t=>ho.every(e=>typeof t[e]=="function");function yo(t){let e=new Ft({getCreds:()=>t.getCreds(),getPairing:()=>t.getPairing(),current:()=>t.engineCaps(),log:r=>t.log(r)}),n=new jt({onChannelReady:()=>e.channelReady(),onChannelDown:()=>e.channelDown(),getCreds:()=>t.getCreds(),getUnitWeb:()=>t.getUnitWeb(),callerHeaders:r=>t.callerHeaders(r),getLanUrl:()=>t.getLanUrl(),getPairing:()=>t.getPairing(),savePairing:r=>t.savePairing(r),clearPairing:()=>t.clearPairing(),log:r=>t.log(r)});return{start:()=>n.start(),stop:()=>n.stop(),reconnect:r=>n.reconnect(r),status:()=>n.status(),engineChanged:()=>e.engineChanged()}}function _r(t){let e=async(n,r,s)=>{let{base:o,token:i}=await t.getCloud();if(!i)return{status:401,json:{detail:"\u672A\u767B\u5F55 Forsion \u8D26\u53F7"}};try{let l=await fetch(`${o}/api${r}`,{method:n,headers:{Authorization:`Bearer ${i}`,...s!==void 0?{"Content-Type":"application/json"}:{}},body:s!==void 0?JSON.stringify(s):void 0});return{status:l.status,json:await l.json().catch(()=>null)}}catch(l){return{status:0,json:{detail:String(l?.message||l)}}}};t.handle("units:list",()=>e("GET","/units")),t.handle("units:update",(n,r,s)=>e("PATCH",`/units/${encodeURIComponent(String(r))}`,{name:s?.name,icon:s?.icon})),t.handle("units:remove",(n,r)=>e("DELETE",`/units/${encodeURIComponent(String(r))}`)),t.handle("units:openInBrowser",async(n,r)=>{if(typeof r!="string"||!/^[0-9a-zA-Z-]{8,64}$/.test(r))throw new Error("\u53C2\u6570\u4E0D\u5B8C\u6574");let{base:s,token:o}=await t.getCloud();await t.openExternal(`${s}/api/units/${r}/open${o?`#token=${encodeURIComponent(o)}`:""}`)}),t.setUnitHubFactory(yo),t.log("[forsion-extend] unit hub registered")}import{createHash as Rl}from"node:crypto";import{constants as xo,mkdirSync as Dl,readFileSync as Pl,renameSync as $l,writeFileSync as Ml}from"node:fs";import{lstat as Je,open as jo,readFile as Ol,readdir as Fo,statfs as Nl}from"node:fs/promises";import{cpus as Ul,freemem as jl,homedir as Co,hostname as Lo,release as Fl,totalmem as Ll}from"node:os";import{basename as Ho,join as ne}from"node:path";var wl=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i,Lt=class t extends Date{#t=!1;#n=!1;#e=null;constructor(e){let n=!0,r=!0,s="Z";if(typeof e=="string"){let o=e.match(wl);o?(o[1]||(n=!1,e=`0000-01-01T${e}`),r=!!o[2],r&&e[10]===" "&&(e=e.replace(" ","T")),o[2]&&+o[2]>23?e="":(s=o[3]||null,e=e.toUpperCase(),!s&&r&&(e+="Z"))):e=""}super(e),isNaN(this.getTime())||(this.#t=n,this.#n=r,this.#e=s)}isDateTime(){return this.#t&&this.#n}isLocal(){return!this.#t||!this.#n||!this.#e}isDate(){return this.#t&&!this.#n}isTime(){return this.#n&&!this.#t}isValid(){return this.#t||this.#n}toISOString(){let e=super.toISOString();if(this.isDate())return e.slice(0,10);if(this.isTime())return e.slice(11,23);if(this.#e===null)return e.slice(0,-1);if(this.#e==="Z")return e;let n=+this.#e.slice(1,3)*60+ +this.#e.slice(4,6);return n=this.#e[0]==="-"?n:-n,new Date(this.getTime()-n*6e4).toISOString().slice(0,-1)+this.#e}static wrapAsOffsetDateTime(e,n="Z"){let r=new t(e);return r.#e=n,r}static wrapAsLocalDateTime(e){let n=new t(e);return n.#e=null,n}static wrapAsLocalDate(e){let n=new t(e);return n.#n=!1,n.#e=null,n}static wrapAsLocalTime(e){let n=new t(e);return n.#t=!1,n.#e=null,n}};function bl(t,e){let n=t.slice(0,e).split(/\r\n|\n|\r/g);return[n.length,n.pop().length+1]}function Sl(t,e,n){let r=t.split(/\r\n|\n|\r/g),s="",o=(Math.log10(e+1)|0)+1;for(let i=e-1;i<=e+1;i++){let l=r[i-1];l&&(s+=i.toString().padEnd(o," "),s+=": ",s+=l,s+=`
216
+ `).find(l=>l.startsWith("data: "))?.slice(6);if(i)try{let l=JSON.parse(i);this.dispatch(l,n).catch(a=>this.deps.log(`[unit-host] \u6D3E\u53D1\u5904\u7406\u5931\u8D25: ${a?.message||a}`))}catch{}}return r}async dispatch(e,n){let r=new AbortController;if(n.signal.aborted)return;this.inflight.get(e.id)?.ctrl.abort();let s={ctrl:r,conn:n};this.inflight.set(e.id,s);try{await this.handle(e,r)}finally{this.inflight.get(e.id)===s&&this.inflight.delete(e.id)}}async handle(e,n){let r=this.deps.getUnitWeb();if(!r.url){await this.respond(e.id,503,"application/json",Buffer.from(JSON.stringify({detail:"\u672C\u673A\u4E92\u8054\u670D\u52A1\u672A\u5C31\u7EEA",code:"UNIT_WEB_NOT_READY"})),void 0,n.signal);return}let s={"x-unit-internal":r.internalSecret};e.ct&&(s["Content-Type"]=e.ct),e.accept&&(s.Accept=e.accept);let o;try{let u=new URL(`${r.url}${e.path}`);Object.assign(s,this.deps.callerHeaders({dispatchId:e.id,method:e.method,target:u,proxyCaller:e.proxyCaller})),o=await fetch(u,{method:e.method,headers:s,body:e.body??void 0,signal:n.signal})}catch(u){if(n.signal.aborted)return;await this.respond(e.id,502,"application/json",Buffer.from(JSON.stringify({detail:`\u672C\u673A\u4E92\u8054\u670D\u52A1\u4E0D\u53EF\u8FBE: ${u?.message||u}`})),void 0,n.signal);return}let i=o.headers.get("content-type")||"",l={};for(let u of["content-security-policy","x-content-type-options"]){let f=o.headers.get(u);f&&(l[u]=f)}let a=i||"application/octet-stream";o.body&&Zo(i,o.headers.get("content-length"),{hasSecHeaders:Object.keys(l).length>0,gatewayStreamsSecHeaders:this.hubCaps.has("stream-sec-headers")})?await this.streamBack(e.id,o,n,a,l):await this.respond(e.id,o.status,a,Buffer.from(await o.arrayBuffer()),l,n.signal)}async respond(e,n,r,s,o,i){if(i?.aborted)return;let{cloudUrl:l,token:a}=this.deps.getCreds(),c=this.deps.getPairing();if(!c)return;let u=this.requestTimeoutMs*2,f=[...u?[AbortSignal.timeout(u)]:[],...i?[i]:[]],m=f.length>1?AbortSignal.any(f):f[0];await this.hubFetch(`${Un(l)}/units/${c.unitId}/resp/${e}`,{method:"POST",headers:{Authorization:`Bearer ${a}`,"X-Unit-Secret":c.secret,"Content-Type":"application/json"},body:JSON.stringify({status:n,headers:{"content-type":r,...o},bodyB64:s.toString("base64")}),...m?{signal:m}:{}}).then(h=>{h.body?.cancel().catch(()=>{})}).catch(h=>{i?.aborted||this.deps.log(`[unit-host] \u56DE\u5305\u5931\u8D25: ${h?.name==="TimeoutError"?`${Math.round(u/1e3)}s \u672A\u5B8C\u6210`:h?.message||h}`)})}async streamBack(e,n,r,s,o){let{cloudUrl:i,token:l}=this.deps.getCreds(),a=this.deps.getPairing();if(!a)return;let c=o?.["content-security-policy"],u=o?.["x-content-type-options"],f=`${Un(i)}/units/${a.unitId}/stream/${e}?status=${n.status}&ct=${encodeURIComponent(s)}`+(c?`&csp=${encodeURIComponent(c)}`:"")+(u?`&xcto=${encodeURIComponent(u)}`:""),m=n.body;if(!m)return;let h=m.getReader(),g=0,p=this.requestTimeoutMs,y=p?setTimeout(()=>{g>=2||(this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20 ${Math.round(p/1e3)}s \u672A\u628A\u9996\u5757\u5199\u7ED9\u7F51\u5173,\u4E2D\u6B62\u672C\u6B21\u6D3E\u53D1`),r.abort())},p):null,E=new ReadableStream({async pull(O){++g===2&&y&&clearTimeout(y);let{done:C,value:M}=await h.read();C?O.close():O.enqueue(M)},cancel(O){return h.cancel(O)}},{highWaterMark:0});try{await this.hubFetch(f,{method:"POST",headers:{Authorization:`Bearer ${l}`,"X-Unit-Secret":a.secret,"Content-Type":"application/octet-stream"},body:E,signal:r.signal,duplex:"half"})}catch(O){this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20\u4E2D\u65AD: ${O?.message||O}`);try{await h.cancel()}catch{}}finally{y&&clearTimeout(y)}}};var Kt=class{d;up=!1;gen=0;lastSent=null;disabled=!1;inflight=!1;again=!1;timer=null;warned=new Set;constructor(e){this.d=e}channelReady(){this.gen++,this.up=!0,this.lastSent=null,this.disabled=!1,this.clearTimer(),this.again=!1,this.flush()}channelDown(){this.gen++,this.up=!1,this.lastSent=null,this.again=!1,this.clearTimer()}engineChanged(){!this.up||this.disabled||(this.clearTimer(),this.timer=setTimeout(()=>{this.timer=null,this.flush()},this.d.debounceMs??500))}clearTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null)}async flush(){if(!this.up||this.disabled)return;if(this.inflight){this.again=!0;return}let e;try{e=this.d.current()}catch(l){this.d.log(`[unit-caps] \u8BFB\u5F15\u64CE\u6001\u5931\u8D25:${l?.message||l}`);return}if(e===this.lastSent)return;let n=this.d.getPairing(),r;try{r=this.d.getCreds()}catch{return}if(!n||!r.token||!r.cloudUrl)return;let s=this.gen;this.inflight=!0;let o=new AbortController,i=setTimeout(()=>o.abort(),this.d.timeoutMs??1e4);try{let l=`${r.cloudUrl.replace(/\/+$/,"")}/api/units/${encodeURIComponent(n.unitId)}/caps`,a=await(this.d.hubFetch??fetch)(l,{method:"POST",headers:{Authorization:`Bearer ${r.token}`,"X-Unit-Secret":n.secret,"Content-Type":"application/json"},body:JSON.stringify({engine:e,tools:[]}),signal:o.signal});try{await a.text()}catch{}if(s!==this.gen)return;a.ok?(this.lastSent=e,this.d.log(`[unit-caps] \u5DF2\u4E0A\u62A5\u5F15\u64CE\u6001 ${e}`)):a.status===404||a.status===405?(this.disabled=!0,this.d.log(`[unit-caps] \u7F51\u5173\u4E0D\u6536 caps(HTTP ${a.status},\u8001\u7248\u672C),\u672C\u8FDE\u63A5\u5185\u4E0D\u518D\u4E0A\u62A5`)):a.status===400||a.status===401||a.status===403?this.warned.has(a.status)||(this.warned.add(a.status),this.d.log(`[unit-caps] \u4E0A\u62A5\u88AB\u62D2 HTTP ${a.status}`)):this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25 HTTP ${a.status},\u7B49\u4E0B\u6B21\u53D8\u5316 / \u91CD\u8FDE\u518D\u62A5`)}catch(l){s===this.gen&&this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25:${o.signal.aborted?"\u8D85\u65F6":l?.message||l}`)}finally{clearTimeout(i),this.inflight=!1,this.again&&this.up&&!this.disabled&&(this.again=!1,this.flush())}}};var Qo=["setUnitHubFactory"],Wr=t=>Qo.every(e=>typeof t[e]=="function");function ei(t){let e=new Kt({getCreds:()=>t.getCreds(),getPairing:()=>t.getPairing(),current:()=>t.engineCaps(),log:r=>t.log(r)}),n=new Xt({onChannelReady:()=>e.channelReady(),onChannelDown:()=>e.channelDown(),getCreds:()=>t.getCreds(),getUnitWeb:()=>t.getUnitWeb(),callerHeaders:r=>t.callerHeaders(r),getLanUrl:()=>t.getLanUrl(),getPairing:()=>t.getPairing(),savePairing:r=>t.savePairing(r),clearPairing:()=>t.clearPairing(),log:r=>t.log(r)});return{start:()=>n.start(),stop:()=>n.stop(),reconnect:r=>n.reconnect(r),status:()=>n.status(),engineChanged:()=>e.engineChanged()}}function Vr(t){let e=async(n,r,s)=>{let{base:o,token:i}=await t.getCloud();if(!i)return{status:401,json:{detail:"\u672A\u767B\u5F55 Forsion \u8D26\u53F7"}};try{let l=await fetch(`${o}/api${r}`,{method:n,headers:{Authorization:`Bearer ${i}`,...s!==void 0?{"Content-Type":"application/json"}:{}},body:s!==void 0?JSON.stringify(s):void 0});return{status:l.status,json:await l.json().catch(()=>null)}}catch(l){return{status:0,json:{detail:String(l?.message||l)}}}};t.handle("units:list",()=>e("GET","/units")),t.handle("units:update",(n,r,s)=>e("PATCH",`/units/${encodeURIComponent(String(r))}`,{name:s?.name,icon:s?.icon})),t.handle("units:remove",(n,r)=>e("DELETE",`/units/${encodeURIComponent(String(r))}`)),t.handle("units:openInBrowser",async(n,r)=>{if(typeof r!="string"||!/^[0-9a-zA-Z-]{8,64}$/.test(r))throw new Error("\u53C2\u6570\u4E0D\u5B8C\u6574");let{base:s,token:o}=await t.getCloud();await t.openExternal(`${s}/api/units/${r}/open${o?`#token=${encodeURIComponent(o)}`:""}`)}),t.setUnitHubFactory(ei),t.log("[forsion-extend] unit hub registered")}import{createHash as Pc}from"node:crypto";import{constants as li,mkdirSync as Rc,readFileSync as Dc,renameSync as $c,writeFileSync as Oc}from"node:fs";import{lstat as Qe,open as vi,readFile as Mc,readdir as ki,statfs as Nc}from"node:fs/promises";import{cpus as jc,freemem as Uc,homedir as ci,hostname as Ei,release as Fc,totalmem as Lc}from"node:os";import{basename as _i,join as ne}from"node:path";var wc=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i,Zt=class t extends Date{#t=!1;#n=!1;#e=null;constructor(e){let n=!0,r=!0,s="Z";if(typeof e=="string"){let o=e.match(wc);o?(o[1]||(n=!1,e=`0000-01-01T${e}`),r=!!o[2],r&&e[10]===" "&&(e=e.replace(" ","T")),o[2]&&+o[2]>23?e="":(s=o[3]||null,e=e.toUpperCase(),!s&&r&&(e+="Z"))):e=""}super(e),isNaN(this.getTime())||(this.#t=n,this.#n=r,this.#e=s)}isDateTime(){return this.#t&&this.#n}isLocal(){return!this.#t||!this.#n||!this.#e}isDate(){return this.#t&&!this.#n}isTime(){return this.#n&&!this.#t}isValid(){return this.#t||this.#n}toISOString(){let e=super.toISOString();if(this.isDate())return e.slice(0,10);if(this.isTime())return e.slice(11,23);if(this.#e===null)return e.slice(0,-1);if(this.#e==="Z")return e;let n=+this.#e.slice(1,3)*60+ +this.#e.slice(4,6);return n=this.#e[0]==="-"?n:-n,new Date(this.getTime()-n*6e4).toISOString().slice(0,-1)+this.#e}static wrapAsOffsetDateTime(e,n="Z"){let r=new t(e);return r.#e=n,r}static wrapAsLocalDateTime(e){let n=new t(e);return n.#e=null,n}static wrapAsLocalDate(e){let n=new t(e);return n.#n=!1,n.#e=null,n}static wrapAsLocalTime(e){let n=new t(e);return n.#t=!1,n.#e=null,n}};function bc(t,e){let n=t.slice(0,e).split(/\r\n|\n|\r/g);return[n.length,n.pop().length+1]}function Sc(t,e,n){let r=t.split(/\r\n|\n|\r/g),s="",o=(Math.log10(e+1)|0)+1;for(let i=e-1;i<=e+1;i++){let l=r[i-1];l&&(s+=i.toString().padEnd(o," "),s+=": ",s+=l,s+=`
217
217
  `,i===e&&(s+=" ".repeat(o+n+2),s+=`^
218
- `))}return s}var Q=class extends Error{line;column;codeblock;constructor(e,n){let[r,s]=bl(n.toml,n.ptr),o=Sl(n.toml,r,s);super(`Invalid TOML document: ${e}
218
+ `))}return s}var Q=class extends Error{line;column;codeblock;constructor(e,n){let[r,s]=bc(n.toml,n.ptr),o=Sc(n.toml,r,s);super(`Invalid TOML document: ${e}
219
219
 
220
- ${o}`,n),this.line=r,this.column=s,this.codeblock=o}};var kl=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,El=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,_l=/^[+-]?0[0-9_]/;function vn(t,e){let n=t[e++],r=n,s=n==="'",o=n===t[e]&&n===t[e+1];o&&(t[e+=2]===`
220
+ ${o}`,n),this.line=r,this.column=s,this.codeblock=o}};var vc=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,kc=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,Ec=/^[+-]?0[0-9_]/;function Fn(t,e){let n=t[e++],r=n,s=n==="'",o=n===t[e]&&n===t[e+1];o&&(t[e+=2]===`
221
221
  `?e++:t[e]==="\r"&&t[e+1]===`
222
- `&&(e+=2));let i="",l=e,a=0;for(let d=e;d<t.length;d++)if(n=t[d],o&&(n===`
223
- `||n==="\r"&&t[d+1]===`
224
- `))a=a&&3;else{if(n<" "&&n!==" "||n==="\x7F")throw new Q("control characters are not allowed in strings",{toml:t,ptr:d});if((!a||a===3)&&n===r&&(!o||t[d+1]===r&&t[d+2]===r))return o&&(t[d+3]===r&&d++,t[d+3]===r&&d++),[a?i:i+t.slice(l,d),d+(o?3:1)];if(!a)!s&&n==="\\"&&(i+=t.slice(l,l=d),a=1);else if(a===1)if(n==="x"||n==="u"||n==="U"){let u=0,m=n==="x"?2:n==="u"?4:8;for(let g=0;g<m;g++,d++){let p=t.charCodeAt(d+1),y=p>=48&&p<=57?p-48:p>=65&&p<=70?p-65+10:p>=97&&p<=102?p-97+10:-1;if(y<0)throw new Q("invalid non-hex character in unicode escape",{toml:t,ptr:d+1});u=u<<4|y}if(u<0||u>1114111||u>=55296&&u<=57343)throw new Q("invalid unicode escape",{toml:t,ptr:d});i+=String.fromCodePoint(u),l=d+1,a=0}else if(n===" "||n===" ")a=2;else{if(n==="b")i+="\b";else if(n==="t")i+=" ";else if(n==="n")i+=`
225
- `;else if(n==="f")i+="\f";else if(n==="r")i+="\r";else if(n==="e")i+="\x1B";else if(n==='"')i+='"';else if(n==="\\")i+="\\";else throw new Q("unrecognized escape sequence",{toml:t,ptr:d});l=d+1,a=0}else if(n!==" "&&n!==" "){if(a===2)throw new Q("invalid escape: only line-ending whitespace may be escaped",{toml:t,ptr:l});a=!s&&n==="\\"?1:0,l=d}}throw new Q("unfinished string",{toml:t,ptr:e})}function wo(t,e,n,r){if(t==="true")return!0;if(t==="false")return!1;if(t==="-inf")return-1/0;if(t==="inf"||t==="+inf")return 1/0;if(t==="nan"||t==="+nan"||t==="-nan")return NaN;if(t==="-0")return r?0n:0;let s=kl.test(t);if(s||El.test(t)){if(_l.test(t))throw new Q("leading zeroes are not allowed",{toml:e,ptr:n});t=t.replace(/_/g,"");let i=+t;if(isNaN(i))throw new Q("invalid number",{toml:e,ptr:n});if(s){if((s=!Number.isSafeInteger(i))&&!r)throw new Q("integer value cannot be represented losslessly",{toml:e,ptr:n});(s||r===!0)&&(i=BigInt(t))}return i}let o=new Lt(t);if(!o.isValid())throw new Q("invalid value",{toml:e,ptr:n});return o}function xn(t,e=0,n=t.length){let r=t.indexOf(`
226
- `,e);return t[r-1]==="\r"&&r--,r<=n?r:-1}function yt(t,e){for(let n=e;n<t.length;n++){let r=t[n];if(r===`
222
+ `&&(e+=2));let i="",l=e,a=0;for(let c=e;c<t.length;c++)if(n=t[c],o&&(n===`
223
+ `||n==="\r"&&t[c+1]===`
224
+ `))a=a&&3;else{if(n<" "&&n!==" "||n==="\x7F")throw new Q("control characters are not allowed in strings",{toml:t,ptr:c});if((!a||a===3)&&n===r&&(!o||t[c+1]===r&&t[c+2]===r))return o&&(t[c+3]===r&&c++,t[c+3]===r&&c++),[a?i:i+t.slice(l,c),c+(o?3:1)];if(!a)!s&&n==="\\"&&(i+=t.slice(l,l=c),a=1);else if(a===1)if(n==="x"||n==="u"||n==="U"){let u=0,f=n==="x"?2:n==="u"?4:8;for(let m=0;m<f;m++,c++){let h=t.charCodeAt(c+1),g=h>=48&&h<=57?h-48:h>=65&&h<=70?h-65+10:h>=97&&h<=102?h-97+10:-1;if(g<0)throw new Q("invalid non-hex character in unicode escape",{toml:t,ptr:c+1});u=u<<4|g}if(u<0||u>1114111||u>=55296&&u<=57343)throw new Q("invalid unicode escape",{toml:t,ptr:c});i+=String.fromCodePoint(u),l=c+1,a=0}else if(n===" "||n===" ")a=2;else{if(n==="b")i+="\b";else if(n==="t")i+=" ";else if(n==="n")i+=`
225
+ `;else if(n==="f")i+="\f";else if(n==="r")i+="\r";else if(n==="e")i+="\x1B";else if(n==='"')i+='"';else if(n==="\\")i+="\\";else throw new Q("unrecognized escape sequence",{toml:t,ptr:c});l=c+1,a=0}else if(n!==" "&&n!==" "){if(a===2)throw new Q("invalid escape: only line-ending whitespace may be escaped",{toml:t,ptr:l});a=!s&&n==="\\"?1:0,l=c}}throw new Q("unfinished string",{toml:t,ptr:e})}function ti(t,e,n,r){if(t==="true")return!0;if(t==="false")return!1;if(t==="-inf")return-1/0;if(t==="inf"||t==="+inf")return 1/0;if(t==="nan"||t==="+nan"||t==="-nan")return NaN;if(t==="-0")return r?0n:0;let s=vc.test(t);if(s||kc.test(t)){if(Ec.test(t))throw new Q("leading zeroes are not allowed",{toml:e,ptr:n});t=t.replace(/_/g,"");let i=+t;if(isNaN(i))throw new Q("invalid number",{toml:e,ptr:n});if(s){if((s=!Number.isSafeInteger(i))&&!r)throw new Q("integer value cannot be represented losslessly",{toml:e,ptr:n});(s||r===!0)&&(i=BigInt(t))}return i}let o=new Zt(t);if(!o.isValid())throw new Q("invalid value",{toml:e,ptr:n});return o}function Ln(t,e=0,n=t.length){let r=t.indexOf(`
226
+ `,e);return t[r-1]==="\r"&&r--,r<=n?r:-1}function At(t,e){for(let n=e;n<t.length;n++){let r=t[n];if(r===`
227
227
  `)return n;if(r==="\r"&&t[n+1]===`
228
228
  `)return n+1;if(r<" "&&r!==" "||r==="\x7F")throw new Q("control characters are not allowed in comments",{toml:t,ptr:e})}return t.length}function He(t,e,n,r){let s;for(;;){for(;(s=t[e])===" "||s===" "||!n&&(s===`
229
229
  `||s==="\r"&&t[e+1]===`
230
- `);)e++;if(r||s!=="#")break;e=yt(t,e)}return e}function bo(t,e,n,r,s=!1){if(!r)return e=xn(t,e),e<0?t.length:e;for(let o=e;o<t.length;o++){let i=t[o];if(i==="#")o=xn(t,o);else{if(i===n)return o+1;if(i===r||s&&(i===`
230
+ `);)e++;if(r||s!=="#")break;e=At(t,e)}return e}function ni(t,e,n,r,s=!1){if(!r)return e=Ln(t,e),e<0?t.length:e;for(let o=e;o<t.length;o++){let i=t[o];if(i==="#")o=Ln(t,o);else{if(i===n)return o+1;if(i===r||s&&(i===`
231
231
  `||i==="\r"&&t[o+1]===`
232
- `))return o}}throw new Q("cannot find end of structure",{toml:t,ptr:e})}function vl(t,e,n){let r=t.slice(e,n),s=r.indexOf("#");return s>-1&&(yt(t,s),r=r.slice(0,s)),[r.trimEnd(),s]}function Ht(t,e,n,r,s){if(r===0)throw new Q("document contains excessively nested structures. aborting.",{toml:t,ptr:e});let o=t[e];if(o==="["||o==="{"){let[a,d]=o==="["?ko(t,e,r,s):So(t,e,r,s);if(n){if(d=He(t,d),t[d]===",")d++;else if(t[d]!==n)throw new Q("expected comma or end of structure",{toml:t,ptr:d})}return[a,d]}if(o==='"'||o==="'"){let[a,d]=vn(t,e);if(n){if(d=He(t,d),t[d]&&t[d]!==","&&t[d]!==n&&t[d]!==`
233
- `&&t[d]!=="\r")throw new Q("unexpected character encountered",{toml:t,ptr:d});t[d]===","&&d++}return[a,d]}let i=bo(t,e,",",n),l=vl(t,e,i-(t[i-1]===","?1:0));if(!l[0])throw new Q("incomplete key-value declaration: no value specified",{toml:t,ptr:e});return n&&l[1]>-1&&(i=He(t,e+l[1]),t[i]===","&&i++),[wo(l[0],t,e,s),i]}var xl=/^[a-zA-Z0-9-_]+[ \t]*$/;function Cn(t,e,n="="){let r=e-1,s=[],o=t.indexOf(n,e);if(o<0)throw new Q("incomplete key-value: cannot find end of key",{toml:t,ptr:e});do{let i=t[e=++r];if(i!==" "&&i!==" ")if(i==='"'||i==="'"){if(i===t[e+1]&&i===t[e+2])throw new Q("multiline strings are not allowed in keys",{toml:t,ptr:e});let[l,a]=vn(t,e);r=t.indexOf(".",a);let d=t.slice(a,r<0||r>o?o:r),u=xn(d);if(u>-1)throw new Q("newlines are not allowed in keys",{toml:t,ptr:e+r+u});if(d.trimStart())throw new Q("found extra tokens after the string part",{toml:t,ptr:a});if(o<a&&(o=t.indexOf(n,a),o<0))throw new Q("incomplete key-value: cannot find end of key",{toml:t,ptr:e});s.push(l)}else{r=t.indexOf(".",e);let l=t.slice(e,r<0||r>o?o:r);if(!xl.test(l))throw new Q("only letter, numbers, dashes and underscores are allowed in keys",{toml:t,ptr:e});s.push(l.trimEnd())}}while(r+1&&r<o);return[s,He(t,o+1,!0,!0)]}function So(t,e,n,r){let s={},o=new Set,i;for(e++;(i=t[e++])!=="}"&&i;){if(i===",")throw new Q("expected value, found comma",{toml:t,ptr:e-1});if(i==="#")e=yt(t,e);else if(i!==" "&&i!==" "&&i!==`
234
- `&&i!=="\r"){let l,a=s,d=!1,[u,m]=Cn(t,e-1);for(let y=0;y<u.length;y++){if(y&&(a=d?a[l]:a[l]={}),l=u[y],(d=Object.hasOwn(a,l))&&(typeof a[l]!="object"||o.has(a[l])))throw new Q("trying to redefine an already defined value",{toml:t,ptr:e});!d&&l==="__proto__"&&Object.defineProperty(a,l,{enumerable:!0,configurable:!0,writable:!0})}if(d)throw new Q("trying to redefine an already defined value",{toml:t,ptr:e});let[g,p]=Ht(t,m,"}",n-1,r);o.add(g),a[l]=g,e=p}}if(!i)throw new Q("unfinished table encountered",{toml:t,ptr:e});return[s,e]}function ko(t,e,n,r){let s=[],o;for(e++;(o=t[e++])!=="]"&&o;){if(o===",")throw new Q("expected value, found comma",{toml:t,ptr:e-1});if(o==="#")e=yt(t,e);else if(o!==" "&&o!==" "&&o!==`
235
- `&&o!=="\r"){let i=Ht(t,e-1,"]",n-1,r);s.push(i[0]),e=i[1]}}if(!o)throw new Q("unfinished array encountered",{toml:t,ptr:e});return[s,e]}function Eo(t,e,n,r){let s=e,o=n,i,l=!1,a;for(let d=0;d<t.length;d++){if(d){if(s=l?s[i]:s[i]={},o=(a=o[i]).c,r===0&&(a.t===1||a.t===2))return null;if(a.t===2){let u=s.length-1;s=s[u],o=o[u].c}}if(i=t[d],(l=Object.hasOwn(s,i))&&o[i]?.t===0&&o[i]?.d)return null;l||(i==="__proto__"&&(Object.defineProperty(s,i,{enumerable:!0,configurable:!0,writable:!0}),Object.defineProperty(o,i,{enumerable:!0,configurable:!0,writable:!0})),o[i]={t:d<t.length-1&&r===2?3:r,d:!1,i:0,c:{}})}if(a=o[i],a.t!==r&&!(r===1&&a.t===3)||(r===2&&(a.d||(a.d=!0,s[i]=[]),s[i].push(s={}),a.c[a.i++]=a={t:1,d:!1,i:0,c:{}}),a.d))return null;if(a.d=!0,r===1)s=l?s[i]:s[i]={};else if(r===0&&l)return null;return[i,s,a.c]}function Tn(t,{maxDepth:e=1e3,integersAsBigInt:n}={}){let r={},s={},o=r,i=s;for(let l=He(t,0);l<t.length;){if(t[l]==="["){let a=t[++l]==="[",d=Cn(t,l+=+a,"]");if(a){if(t[d[1]-1]!=="]")throw new Q("expected end of table declaration",{toml:t,ptr:d[1]-1});d[1]++}let u=Eo(d[0],r,s,a?2:1);if(!u)throw new Q("trying to redefine an already defined table or value",{toml:t,ptr:l});i=u[2],o=u[1],l=d[1]}else{let a=Cn(t,l),d=Eo(a[0],o,i,0);if(!d)throw new Q("trying to redefine an already defined table or value",{toml:t,ptr:l});let u=Ht(t,a[1],void 0,e,n);d[1][d[0]]=u[0],l=u[1]}if(l=He(t,l,!0),t[l]&&t[l]!==`
236
- `&&t[l]!=="\r")throw new Q("each key-value declaration must be followed by an end-of-line",{toml:t,ptr:l});l=He(t,l)}return r}var In=14,Cl=1440*6e4,Tl=12e4,Al=15e3,vr=1792*1024,Il=7,Ye=t=>t.toISOString().slice(0,10),ze=t=>Date.parse(Ye(t))-(Il-1)*Cl,_o=["sessions","activity"],An=t=>typeof t=="number"&&Number.isFinite(t)?t:void 0;function xr(t,e,n){let r=t?.day===Ye(n)?t:void 0;return Object.fromEntries(_o.map(s=>[s,An(r?.[s])??Math.min(Math.max(An(e[s])??0,ze(n)),n.getTime())]))}function Cr(t,e,n,r,s,o){let i=e?.day===Ye(r)?e:void 0,l={sent:{...t},file:{day:Ye(r)}};for(let a of _o){let d=a in s&&!o.includes(a)&&!(`${a}Error`in s),u=An(i?.[a]);d?(l.file[a]=n[a],l.sent[a]=r.getTime()):u!==void 0&&(l.sent[a]=Math.min(An(t[a])??u,u))}return l}function vo(t,e=[]){let n={...t},r=vt(JSON.stringify(n));for(let s of["activity","sessions","memory","runs","engine"]){if(r.length<=vr)break;s in n&&(delete n[s],e.push(s),r=vt(JSON.stringify({...n,truncated:e})))}return r.length>vr?null:r}async function Tr(t,e,n,r=new Date){let s=AbortSignal.timeout(Tl);await t.writeFile(`${e}/${Ye(r)}.json`,n,r.getTime(),s);try{let o=Ye(new Date(r.getTime()-In*24*60*6e4));for(let i of await t.walk(s)){let l=/^([^/]+)\/(\d{4}-\d{2}-\d{2})\.json$/.exec(i.key);l&&l[1]===e&&l[2]<o&&await t.rm(i.key,s)}}catch{}}var Ar={mode:"scheduled",intervalHours:24,requestedAt:0};function zt(t){let e=t&&typeof t=="object"?t:{},n=Number(e.intervalHours),r=Number(e.requestedAt);return{mode:e.mode==="manual"?"manual":"scheduled",intervalHours:Number.isInteger(n)&&n>=1&&n<=720?n:Ar.intervalHours,requestedAt:Number.isFinite(r)&&r>0?r:0}}async function Ir(t){try{let e=await fetch(`${t.cloudUrl.replace(/\/+$/,"")}/api/remotesync/diagnostics/policy`,{headers:{Authorization:`Bearer ${t.token}`},signal:AbortSignal.timeout(Al)});return e.status===404?{...Ar}:e.ok?zt(await e.json()):null}catch{return null}}var Hl=(t,e=[])=>{let n=vo(t,e);return n&&Buffer.from(n.buffer,n.byteOffset,n.byteLength)},zo=60*6e4,zl=2*6e4,ql=10*6e4,To=zo,Bl=4*1024*1024,Wl=256*1024,Ao=["user","teamwork","discussion","delegate"],Vl=/^(?:New remarks in the team chat:|You are activated now \()/,qo={totalBytes:1024*1024,sessionBytes:256*1024,textChars:8e3,sessions:300,messages:400},Yl=t=>t.replace(/\b[a-z][a-z0-9+.-]*:\/\/[^\s"'`<>]+|(?:~|\b[A-Za-z]:|\\)?(?:[\\/][^\s"'`<>:*?|\\/()[\]{},;]+){2,}[\\/]?/gi,e=>/^(?:[a-z][a-z0-9+.-]*:\/\/|\/(?:v\d+|api)\/)/i.test(e)?e:"[path]"),Wt=4e3,Rn=(t,e)=>typeof t=="string"&&t?Ge(Yl(tt(t.slice(0,Wt))),e):void 0,Gl={runs:200,totalBytes:128*1024,errorChars:300,events:2e3,tools:40},Jl=64*1024,Rr=500,Xl={totalBytes:256*1024,fileChars:24e3,logChars:12e3,activity:300,detailChars:300},Kl=256*1024,Io=["SOUL.md","MEMORY.md",".memory-raw.md","HARNESS.md",".harness-raw.md",".harness-refinements.jsonl","HUMAN.md"],Zl=["description","developer_instructions"],Ql=["memory","harness","project_memory","human","dream","log_appended"],ec=["homeDir","readCreds","accountId","appVersion"],Bo=t=>ec.every(e=>typeof t[e]=="function"),Ro=Co().length>3?Co():null;function tt(t){return typeof t=="string"?(Ro?t.split(Ro).join("~"):t).replace(/\bBearer\s+[A-Za-z0-9._~+\/-]+=*/gi,"Bearer [redacted]").replace(/\b(sk-[a-zA-Z0-9_-]{12,})\b/g,"[redacted]").replace(/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g,"[redacted]").replace(/\b(?:gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|AKIA[0-9A-Z]{16}|LTAI[0-9A-Za-z]{12,}|xox[abeprs]-[A-Za-z0-9-]{10,}|AIza[0-9A-Za-z_-]{30,})/g,"[redacted]").replace(/-{5}BEGIN [A-Z ]*PRIVATE KEY-{5}[\s\S]*?(?:-{5}END [A-Z ]*PRIVATE KEY-{5}|$)/g,"[redacted]").replace(/\b[a-fA-F0-9]{32,}\b/g,(e,n,r)=>/^[a-f0-9]{48}$/.test(e)&&/(?:^|[^\w-])pr-$/.test(r.slice(Math.max(0,n-4),n))?e:`[hex:${e.length}]`).replace(/((?:["']?)(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|password|secret|authorization|cookie)(?:["']?)\s*[:=]\s*)("[^"\n]*"|'[^'\n]*'|\[[^\]\n]*\]|[^\s,"';&}]+)/gi,"$1[redacted]"):Array.isArray(t)?t.map(tt):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).map(([e,n])=>[e,/^(?:token|.*api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret|authorization|cookie|set-cookie)$/i.test(e)?"[redacted]":tt(n)])):t}var tc=/^(?:model|modelId|voice|mode|backend|notify|escalateTo|realtimeModel|realtimeVoice|vision|background)$/,ee=(t,e=120)=>typeof t=="string"&&t.length<=e?t:void 0,nc=(t,e)=>/^[A-Za-z_][\w.-]{0,63}$/.test(t)?t:`[key:${e}]`;function wt(t,e=0){if(typeof t=="boolean"||typeof t=="number"||t===null||t===void 0)return t??null;if(typeof t=="string")return`[string:${t.length}]`;if(Array.isArray(t))return`[array:${t.length}]`;if(typeof t!="object"||e>=4)return"[object]";let n={};for(let[r,[s,o]]of Object.entries(t).slice(0,100).entries())n[nc(s,r)]=tc.test(s)&&ee(o,80)!==void 0?o:wt(o,e+1);return n}var rc={"":/^(?:name|version|description|model|model_reasoning_effort|approval_mode|max_iterations|tools|enabled_skill_ids|enabled_mcp_servers|library_order|apps|avatar|share_default_memory|cloud_sync|activity_access|tools_strict|tools_mode|tools_list|created_by|created_at|developer_instructions|compaction|lead|slug|members|mode|max_rounds)$/,compaction:/^(?:enabled|reserveTokens|thresholdPercent|keepRecentTokens|summaryMaxTokens|thinking|model|instructions|prompt)$/,members:/^(?:slug|role)$/},Do={"":/^(?:name|version|model|model_reasoning_effort|approval_mode|created_by|created_at|avatar|lead|slug)$/,compaction:/^model$/,members:/^slug$/},sc=/^(?:apps|enabled_skill_ids)$/,Po=t=>!!t&&typeof t=="object"&&!Array.isArray(t)&&!(t instanceof Date);function oc(t){try{let e=Tn(t),n=[],r=[],s=8192,o=(a,d)=>s<=0?!1:(s-=d.length+1,a.push(d),!0),i=(a,d,u)=>{let m=rc[a].test(d)?d:`[key:${d.length}]`,g=Do[a].test(d),p;return typeof u=="boolean"||typeof u=="number"?p=String(u):g&&typeof u=="string"&&!/[\r\n]/.test(u)&&JSON.stringify(u).length<=120?p=JSON.stringify(u):g&&u instanceof Date?p=u.toISOString():a===""&&sc.test(d)&&Array.isArray(u)&&u.every(y=>typeof y=="string"&&!/[\r\n]/.test(y))&&JSON.stringify(u).length<=2e3&&(p=`[${u.map(y=>JSON.stringify(y)).join(", ")}]`),`${m} = ${p??`"[text:${typeof u=="string"?u.length:JSON.stringify(u).length}]"`}`},l=(a,d,u)=>{if(o(r,d)){for(let[m,g]of Object.entries(u))if(!o(r,i(a,m,g)))return}};for(let[a,d]of Object.entries(e)){let u=a!==""&&Object.hasOwn(Do,a);if(u&&Po(d))l(a,`[${a}]`,d);else if(u&&Array.isArray(d)&&d.length>0&&d.every(Po))for(let m of d)l(a,`[[${a}]]`,m);else o(n,i("",a,d));if(s<=0)break}return[...n,...r].join(`
237
- `)}catch{return`[unparsed:${t.length}]`}}var Wo=async t=>{try{return(await Je(t)).isFile()?await Ol(t,"utf8"):null}catch{return null}},Bt=t=>Je(t).then(e=>e.isDirectory(),()=>!1),bt=async t=>{try{return JSON.parse(await Wo(t)??"null")}catch{return null}},qe=async(t,e=200)=>{try{return(await Fo(t)).filter(n=>!n.startsWith(".")&&n.length<=120).sort().slice(0,e)}catch{return[]}};async function ic(t,e){if(!(await Je(t)).isFile())return"";let n=await jo(t,"r");try{let{size:r}=await n.stat(),s=Math.max(0,r-e),o=Buffer.alloc(r-s);await n.read(o,0,o.length,s);let i=o.toString("utf8");return s>0?i.slice(i.indexOf(`
238
- `)+1):i}finally{await n.close()}}function ac(t){if(!t||typeof t!="object")return{};let e=n=>n&&typeof n=="object"?Object.entries(n).slice(0,100):[];return{defaultModel:ee(t.cloud?.defaultModel)??null,models:wt(t.models),tts:wt(t.tts),asr:wt(t.asr),specialAgents:wt(t.specialAgents),pluginSettings:wt(t.plugins?.global),providers:(Array.isArray(t.providers)?t.providers:[]).slice(0,50).map(n=>({providerId:ee(n?.providerId)??null,models:(Array.isArray(n?.modelIds)?n.modelIds:[]).filter(r=>ee(r)!==void 0).slice(0,100)})),mcpServers:e(t.mcp?.mcpServers).map(([n,r])=>({name:ee(n,64)??"[name]",enabled:r?.enabled!==!1})),channels:e(t.channels).map(([n,r])=>({name:ee(n,64)??"[name]",enabled:r?.enabled===!0}))}}var lc=new Set(["config.toml","SOUL.md","MEMORY.md","HARNESS.md","HUMAN.md","Library","LOG","skills","plugins","Space","SCHEDULE.db","triggers.json"]);async function $o(t){let e=[];for(let n of await qe(t,100)){let r=ne(t,n);if(!await Bt(r))continue;let s=await Wo(ne(r,"config.toml"));e.push({id:n,config:s===null?null:oc(s).slice(0,4096),files:(await qe(r,400)).filter(o=>lc.has(o))})}return e}async function Mo(t){let e=[];for(let n of await qe(t,300)){let r=await bt(ne(t,n,"manifest.json"));r&&e.push({id:ee(r.id)??n,version:ee(r.version,40)??null,name:ee(r.nameEn)??ee(r.name)??null})}return e}var ot=t=>String(t?.code||t?.message||t).slice(0,120);async function cc(t,e,n,r=Wl){let s=g=>String(g).padStart(2,"0"),o=g=>{let p=new Date(g);return`${p.getFullYear()}${s(p.getMonth()+1)}${s(p.getDate())}${s(p.getHours())}${s(p.getMinutes())}`},i=g=>`${g.slice(0,4)}-${g.slice(4,6)}-${g.slice(6,8)}.log`,l=o(n),a=o(e.getTime()),d=[],u=r,m=!1;try{let g=(await Fo(t)).filter(p=>/^\d{4}-\d{2}-\d{2}\.log$/.test(p)&&p>=i(l)&&p<=i(a)).sort().reverse();for(let p of g){if(m)break;let f=(await ic(ne(t,p),Bl).catch(P=>{if(P?.code==="ENOENT")return"";throw P})).split(`
239
- `).filter(P=>/^\d{12} /.test(P)&&P.slice(0,12)>=l&&P.slice(0,12)<a),w=f.length;for(;w>0&&Buffer.byteLength(f[w-1])+1<=u;)u-=Buffer.byteLength(f[--w])+1;w>0&&(m=!0),w<f.length&&d.push({date:p.slice(0,10),log:f.slice(w).join(`
240
- `)})}}catch(g){return g?.code==="ENOENT"?{activity:[]}:{activity:[],activityError:ot(g)}}return{activity:d.reverse(),...m?{activityTruncated:!0}:{}}}var Ge=(t,e)=>{if(!(typeof t!="string"||!t))return t.length>e?`${t.slice(0,e)}\u2026[+${t.length-e}]`:t},Oo=t=>{try{let e=typeof t=="string"?JSON.parse(t):t;return Array.isArray(e)?e:[]}catch{return[]}},St=t=>new Date(t).toISOString().slice(0,19).replace("T"," ");async function uc(t,e,n=qo,r=ze(e)){let s=ne(t,"tangu","state.db"),o=await Je(s).then(l=>l.isFile(),l=>l?.code==="ENOENT"?!1:ot(l));if(o!==!0)return o===!1?{sessions:[]}:{sessions:[],sessionsError:o};let i;try{let{DatabaseSync:l}=await import("node:sqlite");i=new l(s,{readOnly:!0}),i.exec("PRAGMA busy_timeout = 1500");let d="m.updated_at >= ? AND m.updated_at < ? AND m.timestamp >= ?",u=[St(r),St(e.getTime()),ze(e)],m=i.prepare(`SELECT s.id, s.kind, s.parent_session_id, s.app_id, s.title, s.model_id, s.project_name, s.archived, s.created_at, s.updated_at, MAX(m.updated_at) AS changed_at
232
+ `))return o}}throw new Q("cannot find end of structure",{toml:t,ptr:e})}function _c(t,e,n){let r=t.slice(e,n),s=r.indexOf("#");return s>-1&&(At(t,s),r=r.slice(0,s)),[r.trimEnd(),s]}function Qt(t,e,n,r,s){if(r===0)throw new Q("document contains excessively nested structures. aborting.",{toml:t,ptr:e});let o=t[e];if(o==="["||o==="{"){let[a,c]=o==="["?si(t,e,r,s):ri(t,e,r,s);if(n){if(c=He(t,c),t[c]===",")c++;else if(t[c]!==n)throw new Q("expected comma or end of structure",{toml:t,ptr:c})}return[a,c]}if(o==='"'||o==="'"){let[a,c]=Fn(t,e);if(n){if(c=He(t,c),t[c]&&t[c]!==","&&t[c]!==n&&t[c]!==`
233
+ `&&t[c]!=="\r")throw new Q("unexpected character encountered",{toml:t,ptr:c});t[c]===","&&c++}return[a,c]}let i=ni(t,e,",",n),l=_c(t,e,i-(t[i-1]===","?1:0));if(!l[0])throw new Q("incomplete key-value declaration: no value specified",{toml:t,ptr:e});return n&&l[1]>-1&&(i=He(t,e+l[1]),t[i]===","&&i++),[ti(l[0],t,e,s),i]}var Cc=/^[a-zA-Z0-9-_]+[ \t]*$/;function zn(t,e,n="="){let r=e-1,s=[],o=t.indexOf(n,e);if(o<0)throw new Q("incomplete key-value: cannot find end of key",{toml:t,ptr:e});do{let i=t[e=++r];if(i!==" "&&i!==" ")if(i==='"'||i==="'"){if(i===t[e+1]&&i===t[e+2])throw new Q("multiline strings are not allowed in keys",{toml:t,ptr:e});let[l,a]=Fn(t,e);r=t.indexOf(".",a);let c=t.slice(a,r<0||r>o?o:r),u=Ln(c);if(u>-1)throw new Q("newlines are not allowed in keys",{toml:t,ptr:e+r+u});if(c.trimStart())throw new Q("found extra tokens after the string part",{toml:t,ptr:a});if(o<a&&(o=t.indexOf(n,a),o<0))throw new Q("incomplete key-value: cannot find end of key",{toml:t,ptr:e});s.push(l)}else{r=t.indexOf(".",e);let l=t.slice(e,r<0||r>o?o:r);if(!Cc.test(l))throw new Q("only letter, numbers, dashes and underscores are allowed in keys",{toml:t,ptr:e});s.push(l.trimEnd())}}while(r+1&&r<o);return[s,He(t,o+1,!0,!0)]}function ri(t,e,n,r){let s={},o=new Set,i;for(e++;(i=t[e++])!=="}"&&i;){if(i===",")throw new Q("expected value, found comma",{toml:t,ptr:e-1});if(i==="#")e=At(t,e);else if(i!==" "&&i!==" "&&i!==`
234
+ `&&i!=="\r"){let l,a=s,c=!1,[u,f]=zn(t,e-1);for(let g=0;g<u.length;g++){if(g&&(a=c?a[l]:a[l]={}),l=u[g],(c=Object.hasOwn(a,l))&&(typeof a[l]!="object"||o.has(a[l])))throw new Q("trying to redefine an already defined value",{toml:t,ptr:e});!c&&l==="__proto__"&&Object.defineProperty(a,l,{enumerable:!0,configurable:!0,writable:!0})}if(c)throw new Q("trying to redefine an already defined value",{toml:t,ptr:e});let[m,h]=Qt(t,f,"}",n-1,r);o.add(m),a[l]=m,e=h}}if(!i)throw new Q("unfinished table encountered",{toml:t,ptr:e});return[s,e]}function si(t,e,n,r){let s=[],o;for(e++;(o=t[e++])!=="]"&&o;){if(o===",")throw new Q("expected value, found comma",{toml:t,ptr:e-1});if(o==="#")e=At(t,e);else if(o!==" "&&o!==" "&&o!==`
235
+ `&&o!=="\r"){let i=Qt(t,e-1,"]",n-1,r);s.push(i[0]),e=i[1]}}if(!o)throw new Q("unfinished array encountered",{toml:t,ptr:e});return[s,e]}function oi(t,e,n,r){let s=e,o=n,i,l=!1,a;for(let c=0;c<t.length;c++){if(c){if(s=l?s[i]:s[i]={},o=(a=o[i]).c,r===0&&(a.t===1||a.t===2))return null;if(a.t===2){let u=s.length-1;s=s[u],o=o[u].c}}if(i=t[c],(l=Object.hasOwn(s,i))&&o[i]?.t===0&&o[i]?.d)return null;l||(i==="__proto__"&&(Object.defineProperty(s,i,{enumerable:!0,configurable:!0,writable:!0}),Object.defineProperty(o,i,{enumerable:!0,configurable:!0,writable:!0})),o[i]={t:c<t.length-1&&r===2?3:r,d:!1,i:0,c:{}})}if(a=o[i],a.t!==r&&!(r===1&&a.t===3)||(r===2&&(a.d||(a.d=!0,s[i]=[]),s[i].push(s={}),a.c[a.i++]=a={t:1,d:!1,i:0,c:{}}),a.d))return null;if(a.d=!0,r===1)s=l?s[i]:s[i]={};else if(r===0&&l)return null;return[i,s,a.c]}function Hn(t,{maxDepth:e=1e3,integersAsBigInt:n}={}){let r={},s={},o=r,i=s;for(let l=He(t,0);l<t.length;){if(t[l]==="["){let a=t[++l]==="[",c=zn(t,l+=+a,"]");if(a){if(t[c[1]-1]!=="]")throw new Q("expected end of table declaration",{toml:t,ptr:c[1]-1});c[1]++}let u=oi(c[0],r,s,a?2:1);if(!u)throw new Q("trying to redefine an already defined table or value",{toml:t,ptr:l});i=u[2],o=u[1],l=c[1]}else{let a=zn(t,l),c=oi(a[0],o,i,0);if(!c)throw new Q("trying to redefine an already defined table or value",{toml:t,ptr:l});let u=Qt(t,a[1],void 0,e,n);c[1][c[0]]=u[0],l=u[1]}if(l=He(t,l,!0),t[l]&&t[l]!==`
236
+ `&&t[l]!=="\r")throw new Q("each key-value declaration must be followed by an end-of-line",{toml:t,ptr:l});l=He(t,l)}return r}var Bn=14,xc=1440*6e4,Tc=12e4,Ac=15e3,Yr=1792*1024,Ic=7,Ke=t=>t.toISOString().slice(0,10),qe=t=>Date.parse(Ke(t))-(Ic-1)*xc,ii=["sessions","activity"],qn=t=>typeof t=="number"&&Number.isFinite(t)?t:void 0;function Jr(t,e,n){let r=t?.day===Ke(n)?t:void 0;return Object.fromEntries(ii.map(s=>[s,qn(r?.[s])??Math.min(Math.max(qn(e[s])??0,qe(n)),n.getTime())]))}function Gr(t,e,n,r,s,o){let i=e?.day===Ke(r)?e:void 0,l={sent:{...t},file:{day:Ke(r)}};for(let a of ii){let c=a in s&&!o.includes(a)&&!(`${a}Error`in s),u=qn(i?.[a]);c?(l.file[a]=n[a],l.sent[a]=r.getTime()):u!==void 0&&(l.sent[a]=Math.min(qn(t[a])??u,u))}return l}function ai(t,e=[]){let n={...t},r=Nt(JSON.stringify(n));for(let s of["activity","sessions","memory","runs","engine"]){if(r.length<=Yr)break;s in n&&(delete n[s],e.push(s),r=Nt(JSON.stringify({...n,truncated:e})))}return r.length>Yr?null:r}async function Xr(t,e,n,r=new Date){let s=AbortSignal.timeout(Tc);await t.writeFile(`${e}/${Ke(r)}.json`,n,r.getTime(),s);try{let o=Ke(new Date(r.getTime()-Bn*24*60*6e4));for(let i of await t.walk(s)){let l=/^([^/]+)\/(\d{4}-\d{2}-\d{2})\.json$/.exec(i.key);l&&l[1]===e&&l[2]<o&&await t.rm(i.key,s)}}catch{}}var Kr={mode:"scheduled",intervalHours:24,requestedAt:0};function en(t){let e=t&&typeof t=="object"?t:{},n=Number(e.intervalHours),r=Number(e.requestedAt);return{mode:e.mode==="manual"?"manual":"scheduled",intervalHours:Number.isInteger(n)&&n>=1&&n<=720?n:Kr.intervalHours,requestedAt:Number.isFinite(r)&&r>0?r:0}}async function Zr(t){try{let e=await fetch(`${t.cloudUrl.replace(/\/+$/,"")}/api/remotesync/diagnostics/policy`,{headers:{Authorization:`Bearer ${t.token}`},signal:AbortSignal.timeout(Ac)});return e.status===404?{...Kr}:e.ok?en(await e.json()):null}catch{return null}}var zc=(t,e=[])=>{let n=ai(t,e);return n&&Buffer.from(n.buffer,n.byteOffset,n.byteLength)},Ci=60*6e4,Hc=2*6e4,qc=10*6e4,ui=Ci,Bc=4*1024*1024,Wc=256*1024,di=["user","teamwork","discussion","delegate"],Vc=/^(?:New remarks in the team chat:|You are activated now \()/,xi={totalBytes:1024*1024,sessionBytes:256*1024,textChars:8e3,sessions:300,messages:400},Yc=t=>t.replace(/\b[a-z][a-z0-9+.-]*:\/\/[^\s"'`<>]+|(?:~|\b[A-Za-z]:|\\)?(?:[\\/][^\s"'`<>:*?|\\/()[\]{},;]+){2,}[\\/]?/gi,e=>/^(?:[a-z][a-z0-9+.-]*:\/\/|\/(?:v\d+|api)\/)/i.test(e)?e:"[path]"),rn=4e3,Wn=(t,e)=>typeof t=="string"&&t?Ze(Yc(at(t.slice(0,rn))),e):void 0,Jc={runs:200,totalBytes:128*1024,errorChars:300,events:2e3,tools:40},Gc=64*1024,Qr=500,Xc={totalBytes:256*1024,fileChars:24e3,logChars:12e3,activity:300,detailChars:300},Kc=256*1024,fi=["SOUL.md","MEMORY.md",".memory-raw.md","HARNESS.md",".harness-raw.md",".harness-refinements.jsonl","HUMAN.md"],Zc=["description","developer_instructions"],Qc=["memory","harness","project_memory","human","dream","log_appended"],eu=["homeDir","readCreds","accountId","appVersion"],Ti=t=>eu.every(e=>typeof t[e]=="function"),hi=ci().length>3?ci():null;function at(t){return typeof t=="string"?(hi?t.split(hi).join("~"):t).replace(/\bBearer\s+[A-Za-z0-9._~+\/-]+=*/gi,"Bearer [redacted]").replace(/\b(sk-[a-zA-Z0-9_-]{12,})\b/g,"[redacted]").replace(/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g,"[redacted]").replace(/\b(?:gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|AKIA[0-9A-Z]{16}|LTAI[0-9A-Za-z]{12,}|xox[abeprs]-[A-Za-z0-9-]{10,}|AIza[0-9A-Za-z_-]{30,})/g,"[redacted]").replace(/-{5}BEGIN [A-Z ]*PRIVATE KEY-{5}[\s\S]*?(?:-{5}END [A-Z ]*PRIVATE KEY-{5}|$)/g,"[redacted]").replace(/\b[a-fA-F0-9]{32,}\b/g,(e,n,r)=>/^[a-f0-9]{48}$/.test(e)&&/(?:^|[^\w-])pr-$/.test(r.slice(Math.max(0,n-4),n))?e:`[hex:${e.length}]`).replace(/((?:["']?)(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|password|secret|authorization|cookie)(?:["']?)\s*[:=]\s*)("[^"\n]*"|'[^'\n]*'|\[[^\]\n]*\]|[^\s,"';&}]+)/gi,"$1[redacted]"):Array.isArray(t)?t.map(at):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).map(([e,n])=>[e,/^(?:token|.*api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret|authorization|cookie|set-cookie)$/i.test(e)?"[redacted]":at(n)])):t}var tu=/^(?:model|modelId|voice|mode|backend|notify|escalateTo|realtimeModel|realtimeVoice|vision|background)$/,ee=(t,e=120)=>typeof t=="string"&&t.length<=e?t:void 0,nu=(t,e)=>/^[A-Za-z_][\w.-]{0,63}$/.test(t)?t:`[key:${e}]`;function It(t,e=0){if(typeof t=="boolean"||typeof t=="number"||t===null||t===void 0)return t??null;if(typeof t=="string")return`[string:${t.length}]`;if(Array.isArray(t))return`[array:${t.length}]`;if(typeof t!="object"||e>=4)return"[object]";let n={};for(let[r,[s,o]]of Object.entries(t).slice(0,100).entries())n[nu(s,r)]=tu.test(s)&&ee(o,80)!==void 0?o:It(o,e+1);return n}var ru={"":/^(?:name|version|description|model|model_reasoning_effort|approval_mode|max_iterations|tools|enabled_skill_ids|enabled_mcp_servers|library_order|apps|avatar|share_default_memory|cloud_sync|activity_access|tools_strict|tools_mode|tools_list|created_by|created_at|developer_instructions|compaction|lead|slug|members|mode|max_rounds)$/,compaction:/^(?:enabled|reserveTokens|thresholdPercent|keepRecentTokens|summaryMaxTokens|thinking|model|instructions|prompt)$/,members:/^(?:slug|role)$/},pi={"":/^(?:name|version|model|model_reasoning_effort|approval_mode|created_by|created_at|avatar|lead|slug)$/,compaction:/^model$/,members:/^slug$/},su=/^(?:apps|enabled_skill_ids)$/,mi=t=>!!t&&typeof t=="object"&&!Array.isArray(t)&&!(t instanceof Date);function ou(t){try{let e=Hn(t),n=[],r=[],s=8192,o=(a,c)=>s<=0?!1:(s-=c.length+1,a.push(c),!0),i=(a,c,u)=>{let f=ru[a].test(c)?c:`[key:${c.length}]`,m=pi[a].test(c),h;return typeof u=="boolean"||typeof u=="number"?h=String(u):m&&typeof u=="string"&&!/[\r\n]/.test(u)&&JSON.stringify(u).length<=120?h=JSON.stringify(u):m&&u instanceof Date?h=u.toISOString():a===""&&su.test(c)&&Array.isArray(u)&&u.every(g=>typeof g=="string"&&!/[\r\n]/.test(g))&&JSON.stringify(u).length<=2e3&&(h=`[${u.map(g=>JSON.stringify(g)).join(", ")}]`),`${f} = ${h??`"[text:${typeof u=="string"?u.length:JSON.stringify(u).length}]"`}`},l=(a,c,u)=>{if(o(r,c)){for(let[f,m]of Object.entries(u))if(!o(r,i(a,f,m)))return}};for(let[a,c]of Object.entries(e)){let u=a!==""&&Object.hasOwn(pi,a);if(u&&mi(c))l(a,`[${a}]`,c);else if(u&&Array.isArray(c)&&c.length>0&&c.every(mi))for(let f of c)l(a,`[[${a}]]`,f);else o(n,i("",a,c));if(s<=0)break}return[...n,...r].join(`
237
+ `)}catch{return`[unparsed:${t.length}]`}}var Ai=async t=>{try{return(await Qe(t)).isFile()?await Mc(t,"utf8"):null}catch{return null}},nn=t=>Qe(t).then(e=>e.isDirectory(),()=>!1),Pt=async t=>{try{return JSON.parse(await Ai(t)??"null")}catch{return null}},Be=async(t,e=200)=>{try{return(await ki(t)).filter(n=>!n.startsWith(".")&&n.length<=120).sort().slice(0,e)}catch{return[]}};async function iu(t,e){if(!(await Qe(t)).isFile())return"";let n=await vi(t,"r");try{let{size:r}=await n.stat(),s=Math.max(0,r-e),o=Buffer.alloc(r-s);await n.read(o,0,o.length,s);let i=o.toString("utf8");return s>0?i.slice(i.indexOf(`
238
+ `)+1):i}finally{await n.close()}}function au(t){if(!t||typeof t!="object")return{};let e=n=>n&&typeof n=="object"?Object.entries(n).slice(0,100):[];return{defaultModel:ee(t.cloud?.defaultModel)??null,models:It(t.models),tts:It(t.tts),asr:It(t.asr),specialAgents:It(t.specialAgents),pluginSettings:It(t.plugins?.global),providers:(Array.isArray(t.providers)?t.providers:[]).slice(0,50).map(n=>({providerId:ee(n?.providerId)??null,models:(Array.isArray(n?.modelIds)?n.modelIds:[]).filter(r=>ee(r)!==void 0).slice(0,100)})),mcpServers:e(t.mcp?.mcpServers).map(([n,r])=>({name:ee(n,64)??"[name]",enabled:r?.enabled!==!1})),channels:e(t.channels).map(([n,r])=>({name:ee(n,64)??"[name]",enabled:r?.enabled===!0}))}}var lu=new Set(["config.toml","SOUL.md","MEMORY.md","HARNESS.md","HUMAN.md","Library","LOG","skills","plugins","Space","SCHEDULE.db","triggers.json"]);async function gi(t){let e=[];for(let n of await Be(t,100)){let r=ne(t,n);if(!await nn(r))continue;let s=await Ai(ne(r,"config.toml"));e.push({id:n,config:s===null?null:ou(s).slice(0,4096),files:(await Be(r,400)).filter(o=>lu.has(o))})}return e}async function yi(t){let e=[];for(let n of await Be(t,300)){let r=await Pt(ne(t,n,"manifest.json"));r&&e.push({id:ee(r.id)??n,version:ee(r.version,40)??null,name:ee(r.nameEn)??ee(r.name)??null})}return e}var pt=t=>String(t?.code||t?.message||t).slice(0,120);async function cu(t,e,n,r=Wc){let s=m=>String(m).padStart(2,"0"),o=m=>{let h=new Date(m);return`${h.getFullYear()}${s(h.getMonth()+1)}${s(h.getDate())}${s(h.getHours())}${s(h.getMinutes())}`},i=m=>`${m.slice(0,4)}-${m.slice(4,6)}-${m.slice(6,8)}.log`,l=o(n),a=o(e.getTime()),c=[],u=r,f=!1;try{let m=(await ki(t)).filter(h=>/^\d{4}-\d{2}-\d{2}\.log$/.test(h)&&h>=i(l)&&h<=i(a)).sort().reverse();for(let h of m){if(f)break;let p=(await iu(ne(t,h),Bc).catch(E=>{if(E?.code==="ENOENT")return"";throw E})).split(`
239
+ `).filter(E=>/^\d{12} /.test(E)&&E.slice(0,12)>=l&&E.slice(0,12)<a),y=p.length;for(;y>0&&Buffer.byteLength(p[y-1])+1<=u;)u-=Buffer.byteLength(p[--y])+1;y>0&&(f=!0),y<p.length&&c.push({date:h.slice(0,10),log:p.slice(y).join(`
240
+ `)})}}catch(m){return m?.code==="ENOENT"?{activity:[]}:{activity:[],activityError:pt(m)}}return{activity:c.reverse(),...f?{activityTruncated:!0}:{}}}var Ze=(t,e)=>{if(!(typeof t!="string"||!t))return t.length>e?`${t.slice(0,e)}\u2026[+${t.length-e}]`:t},wi=t=>{try{let e=typeof t=="string"?JSON.parse(t):t;return Array.isArray(e)?e:[]}catch{return[]}},Rt=t=>new Date(t).toISOString().slice(0,19).replace("T"," ");async function uu(t,e,n=xi,r=qe(e)){let s=ne(t,"tangu","state.db"),o=await Qe(s).then(l=>l.isFile(),l=>l?.code==="ENOENT"?!1:pt(l));if(o!==!0)return o===!1?{sessions:[]}:{sessions:[],sessionsError:o};let i;try{let{DatabaseSync:l}=await import("node:sqlite");i=new l(s,{readOnly:!0}),i.exec("PRAGMA busy_timeout = 1500");let c="m.updated_at >= ? AND m.updated_at < ? AND m.timestamp >= ?",u=[Rt(r),Rt(e.getTime()),qe(e)],f=i.prepare(`SELECT s.id, s.kind, s.parent_session_id, s.app_id, s.title, s.model_id, s.project_name, s.archived, s.created_at, s.updated_at, MAX(m.updated_at) AS changed_at
241
241
  FROM chat_messages m JOIN chat_sessions s ON s.id = m.session_id
242
- WHERE s.kind IN (${Ao.map(()=>"?").join(", ")}) AND ${d} GROUP BY s.id ORDER BY changed_at DESC, s.id LIMIT ?`).all(...Ao,...u,n.sessions+1),g=i.prepare(`SELECT m.role, m.content, m.reasoning, m.timestamp, m.model_id, m.is_error, m.tool_calls, length(m.tool_results) AS tool_result_chars, m.attachments, m.agent_slug
243
- FROM chat_messages m WHERE m.session_id = ? AND ${d} ORDER BY m.timestamp DESC, m.created_at DESC LIMIT ?`),p=[],y=0,f=m.length>n.sessions;for(let w of m.slice(0,n.sessions)){let P=g.all(w.id,...u,n.messages+1),H=P.length>n.messages,T=[],U=0;for(let v of P.slice(0,n.messages)){let b=Oo(v.tool_calls),A=w.kind==="teamwork"&&v.role==="user"&&Vl.test(String(v.content??"")),N={role:ee(v.role,16)??null,at:Number(v.timestamp)||null,agent:ee(v.agent_slug,64),model:ee(v.model_id,128),error:v.is_error?!0:void 0,text:A?void 0:Ge(v.content,n.textChars),relayChars:A?String(v.content??"").length:void 0,reasoning:Ge(v.reasoning,n.textChars),tools:b.length?b.map(G=>ee(G?.function?.name??G?.name,80)??"?"):void 0,toolArgChars:b.length?b.reduce((G,se)=>G+String(se?.function?.arguments??"").length,0):void 0,toolResultChars:Number(v.tool_result_chars)||void 0,attachments:Oo(v.attachments).length||void 0},B=Buffer.byteLength(JSON.stringify(N));if(U+B>n.sessionBytes){H=!0;break}U+=B,T.push(N)}let z={id:ee(w.id,64)??null,kind:ee(w.kind,16)??null,parent:ee(w.parent_session_id,64),app:ee(w.app_id,50)??null,title:Ge(w.title,200)??null,model:ee(w.model_id,128)??null,project:Ge(w.project_name,120),archived:w.archived?!0:void 0,createdAt:ee(w.created_at,40)??null,updatedAt:ee(w.updated_at,40)??null,messages:T.reverse(),...H?{olderMessagesDropped:!0}:{}},h=Buffer.byteLength(JSON.stringify(z));if(y+h>n.totalBytes){f=!0;break}y+=h,p.push(z)}return{sessions:p,...f?{sessionsTruncated:!0}:{}}}catch(l){return{sessions:[],sessionsError:ot(l)}}finally{try{i?.close()}catch{}}}async function dc(t,e,n=Gl){let r=ne(t,"tangu","state.db"),s=await Je(r).then(i=>i.isFile(),i=>i?.code==="ENOENT"?!1:ot(i));if(s!==!0)return s===!1?{runs:[]}:{runs:[],runsError:s};let o;try{let{DatabaseSync:i}=await import("node:sqlite");o=new i(r,{readOnly:!0}),o.exec("PRAGMA busy_timeout = 1500");let a=o.prepare(`SELECT r.id, r.session_id, r.app_id, r.status, r.current_step, r.model_id, substr(r.error, 1, ${Wt}) AS error, r.tokens_total, r.created_at, r.updated_at, s.kind
242
+ WHERE s.kind IN (${di.map(()=>"?").join(", ")}) AND ${c} GROUP BY s.id ORDER BY changed_at DESC, s.id LIMIT ?`).all(...di,...u,n.sessions+1),m=i.prepare(`SELECT m.role, m.content, m.reasoning, m.timestamp, m.model_id, m.is_error, m.tool_calls, length(m.tool_results) AS tool_result_chars, m.attachments, m.agent_slug
243
+ FROM chat_messages m WHERE m.session_id = ? AND ${c} ORDER BY m.timestamp DESC, m.created_at DESC LIMIT ?`),h=[],g=0,p=f.length>n.sessions;for(let y of f.slice(0,n.sessions)){let E=m.all(y.id,...u,n.messages+1),O=E.length>n.messages,C=[],M=0;for(let x of E.slice(0,n.messages)){let b=wi(x.tool_calls),I=y.kind==="teamwork"&&x.role==="user"&&Vc.test(String(x.content??"")),U={role:ee(x.role,16)??null,at:Number(x.timestamp)||null,agent:ee(x.agent_slug,64),model:ee(x.model_id,128),error:x.is_error?!0:void 0,text:I?void 0:Ze(x.content,n.textChars),relayChars:I?String(x.content??"").length:void 0,reasoning:Ze(x.reasoning,n.textChars),tools:b.length?b.map(J=>ee(J?.function?.name??J?.name,80)??"?"):void 0,toolArgChars:b.length?b.reduce((J,se)=>J+String(se?.function?.arguments??"").length,0):void 0,toolResultChars:Number(x.tool_result_chars)||void 0,attachments:wi(x.attachments).length||void 0},B=Buffer.byteLength(JSON.stringify(U));if(M+B>n.sessionBytes){O=!0;break}M+=B,C.push(U)}let H={id:ee(y.id,64)??null,kind:ee(y.kind,16)??null,parent:ee(y.parent_session_id,64),app:ee(y.app_id,50)??null,title:Ze(y.title,200)??null,model:ee(y.model_id,128)??null,project:Ze(y.project_name,120),archived:y.archived?!0:void 0,createdAt:ee(y.created_at,40)??null,updatedAt:ee(y.updated_at,40)??null,messages:C.reverse(),...O?{olderMessagesDropped:!0}:{}},w=Buffer.byteLength(JSON.stringify(H));if(g+w>n.totalBytes){p=!0;break}g+=w,h.push(H)}return{sessions:h,...p?{sessionsTruncated:!0}:{}}}catch(l){return{sessions:[],sessionsError:pt(l)}}finally{try{i?.close()}catch{}}}async function du(t,e,n=Jc){let r=ne(t,"tangu","state.db"),s=await Qe(r).then(i=>i.isFile(),i=>i?.code==="ENOENT"?!1:pt(i));if(s!==!0)return s===!1?{runs:[]}:{runs:[],runsError:s};let o;try{let{DatabaseSync:i}=await import("node:sqlite");o=new i(r,{readOnly:!0}),o.exec("PRAGMA busy_timeout = 1500");let a=o.prepare(`SELECT r.id, r.session_id, r.app_id, r.status, r.current_step, r.model_id, substr(r.error, 1, ${rn}) AS error, r.tokens_total, r.created_at, r.updated_at, s.kind
244
244
  FROM agent_runs r LEFT JOIN chat_sessions s ON s.id = r.session_id
245
- WHERE r.updated_at >= ? AND r.updated_at < ? ORDER BY r.updated_at DESC, r.id LIMIT ?`).all(St(ze(e)),St(e.getTime()),n.runs+1),d=o.prepare(`SELECT e.type, json_extract(e.payload, '$.name') AS name, json_extract(e.payload, '$.isError') AS failed, json_extract(e.payload, '$.elapsedMs') AS ms,
245
+ WHERE r.updated_at >= ? AND r.updated_at < ? ORDER BY r.updated_at DESC, r.id LIMIT ?`).all(Rt(qe(e)),Rt(e.getTime()),n.runs+1),c=o.prepare(`SELECT e.type, json_extract(e.payload, '$.name') AS name, json_extract(e.payload, '$.isError') AS failed, json_extract(e.payload, '$.elapsedMs') AS ms,
246
246
  json_extract(e.payload, '$.prompt') AS prompt, json_extract(e.payload, '$.completion') AS completion, json_extract(e.payload, '$.cached') AS cached,
247
247
  json_extract(e.payload, '$.reasoningTokens') AS reasoning, json_extract(e.payload, '$.llmMs') AS llm_ms, json_extract(e.payload, '$.ttftMs') AS ttft_ms,
248
- json_extract(e.payload, '$.requestBytes') AS request_bytes, json_extract(e.payload, '$.phase') AS phase, substr(json_extract(e.payload, '$.error'), 1, ${Wt}) AS error
249
- FROM agent_run_events e WHERE e.run_id = ? AND e.type IN ('usage', 'tool_result', 'error', 'status') AND json_valid(e.payload) ORDER BY e.seq LIMIT ?`),u=f=>typeof f=="number"&&Number.isFinite(f)&&f>0?f:0,m=f=>f||void 0,g=[],p=0,y=a.length>n.runs;for(let f of a.slice(0,n.runs)){let w={llmCalls:0,prompt:0,completion:0,cached:0,reasoning:0,llmMs:0,ttftMaxMs:0,requestMaxBytes:0},P=new Map,H=[],T=0,U=d.all(f.id,n.events+1),z=U.length>n.events;for(let b of U.slice(0,n.events))if(b.type==="usage")w.llmCalls++,w.prompt+=u(b.prompt),w.completion+=u(b.completion),w.cached+=u(b.cached),w.reasoning+=u(b.reasoning),w.llmMs+=u(b.llm_ms),w.ttftMaxMs=Math.max(w.ttftMaxMs,u(b.ttft_ms)),w.requestMaxBytes=Math.max(w.requestMaxBytes,u(b.request_bytes));else if(b.type==="tool_result"){let A=ee(b.name,80)??"?",N=P.get(A)??(P.size<n.tools?{name:A,n:0,ms:0,maxMs:0}:void 0);if(!N){z=!0;continue}P.set(A,N),N.n++,b.failed&&(N.errors=(N.errors??0)+1),N.ms+=u(b.ms),N.maxMs=Math.max(N.maxMs,u(b.ms))}else if(b.type==="error"){let A=Rn(b.error,n.errorChars);A&&!H.includes(A)&&H.length<3&&H.push(A)}else b.phase==="llm_retry"&&T++;let h={id:ee(f.id,64)??null,session:ee(f.session_id,64)??null,kind:ee(f.kind,16),app:ee(f.app_id,50),model:ee(f.model_id,128),status:ee(f.status,16)??null,error:Rn(f.error,n.errorChars),createdAt:ee(f.created_at,40)??null,updatedAt:ee(f.updated_at,40)??null,steps:m(u(f.current_step)),tokens:m(u(f.tokens_total)),retries:m(T),...Object.fromEntries(Object.entries(w).map(([b,A])=>[b,m(A)])),errors:H.length?H:void 0,tools:P.size?[...P.values()]:void 0,partial:z||void 0},v=Buffer.byteLength(JSON.stringify(h));if(p+v>n.totalBytes){y=!0;break}p+=v,g.push(h)}return{runs:g,...y?{runsTruncated:!0}:{}}}catch(i){return{runs:[],runsError:ot(i)}}finally{try{o?.close()}catch{}}}async function fc(t){let e=s=>Math.round(s/1048576),n=s=>Je(s).then(o=>o.isFile()?o.size:0,()=>0),r=ne(t,"tangu","state.db");return{cpus:Ul().length,memTotalMB:e(Ll()),memFreeMB:e(jl()),diskFreeMB:await Nl(t).then(s=>e(s.bavail*s.bsize),()=>null),stateDbMB:e(await n(r)+await n(`${r}-wal`)),uptimeMin:Math.round(process.uptime()/60)}}var No=t=>typeof t.diagnosticLogs=="function";function mc(t,e=Jl){let n=t?.engine;if(!n||typeof n!="object")return null;let r=(Array.isArray(n.lines)?n.lines:[]).filter(a=>typeof a=="string"&&!!a),s=r.map(a=>Rn(a,Rr)??""),o=s.some((a,d)=>a.length>Rr||r[d].length>Wt),i=s.length,l=e;for(;i>0&&Buffer.byteLength(s[i-1])+1<=l;)l-=Buffer.byteLength(s[--i])+1;return i>0&&(o=!0),{state:ee(n.state,32)??null,lastError:Rn(n.lastError,Rr)??null,log:s.slice(i).join(`
250
- `),...o?{logTruncated:!0}:{}}}function pc(t,e=Zl){let n;try{n=Tn(t)}catch{return{}}return Object.fromEntries(e.flatMap(r=>typeof n[r]=="string"&&n[r]?[[r,n[r]]]:[]))}async function Vo(t,e=Kl){try{if(!(await Je(t)).isFile())return null;let n=await jo(t,xo.O_RDONLY|(xo.O_NOFOLLOW??0));try{let r=await n.stat();if(!r.isFile())return null;let s=Buffer.alloc(Math.min(e,r.size)),{bytesRead:o}=await n.read(s,0,s.length,0);return s.subarray(0,o).toString("utf8")}finally{await n.close()}}catch{return null}}var qt=async(t,e)=>{let n=await Vo(t);return n?Ge(tt(n),e):void 0};async function gc(t,e){let n=await Vo(ne(t,"config.toml")),r=Object.entries(n?pc(n):{}).map(([s,o])=>[s,Ge(tt(o),e)??""]);return r.length?Object.fromEntries(r):void 0}async function Uo(t){let e=await bt(ne(t,".memory-state.json"));if(!e||typeof e!="object")return;let n=r=>Array.isArray(r)?r.length:0;return{entries:n(e.entries),tombstones:n(e.tombstones),revisions:n(e.revisions),processedCandidates:n(e.processedCandidateIds),updatedAt:typeof e.updatedAt=="number"?e.updatedAt:null,projectionPending:e.projectionPending===!0?!0:void 0}}async function hc(t,e,n=Xl){let r=ne(t,"tangu"),s=p=>Je(p).then(y=>y.isFile()?y.mtimeMs:0,()=>0),o=Ye(new Date(ze(e))),i={agents:[],teams:[],projects:[],activity:[]},l=n.totalBytes,a=(p,y)=>{let f=Buffer.byteLength(JSON.stringify(y))+1;return f>l?(i.truncated=!0,!1):(l-=f,p.push(y),!0)},d=await qt(ne(r,"USER.md"),n.fileChars);d&&a([],d)&&(i.user=d);let u=ne(r,"state.db"),m=await Je(u).then(p=>p.isFile(),p=>p?.code==="ENOENT"?!1:ot(p));if(typeof m=="string")i.activityError=m;else if(m){let p;try{let{DatabaseSync:y}=await import("node:sqlite");p=new y(u,{readOnly:!0}),p.exec("PRAGMA busy_timeout = 1500");let w=p.prepare(`SELECT agent, action, substr(detail, 1, ${Wt}) AS detail, session_ref, created_at FROM special_agent_log
251
- WHERE created_at >= ? AND created_at < ? AND (${Ql.map(P=>`action GLOB '${P}*'`).join(" OR ")})
252
- ORDER BY created_at DESC, rowid DESC LIMIT ?`).all(St(ze(e)),St(e.getTime()),n.activity+1);w.length>n.activity&&(i.truncated=!0);for(let P of w.slice(0,n.activity))if(!a(i.activity,{at:ee(P.created_at,40)??null,agent:ee(P.agent,64)??null,action:ee(P.action,64)??null,detail:typeof P.detail=="string"&&P.detail?Ge(tt(P.detail),n.detailChars):void 0,session:ee(P.session_ref,64)}))break}catch(y){i.activityError=ot(y)}finally{try{p?.close()}catch{}}}for(let p of await qe(ne(r,"project-memory"),100)){let y=ne(r,"project-memory",p);if(!await Bt(y))continue;let f=await qt(ne(y,"MEMORY.md"),n.fileChars),w=await Uo(y);if(!f&&!w)continue;let P=(await bt(ne(y,"PROJECT.json")))?.project;if(!a(i.projects,{id:ee(p,64)??null,name:typeof P=="string"?ee(Ho(P.replace(/[\\/]+$/,"").replace(/\\/g,"/"))):void 0,state:w,memory:f}))break}for(let p of await qe(ne(r,"teams"),100)){if(!await Bt(ne(r,"teams",p)))continue;let y=await qt(ne(r,"teams",p,"TEAM.md"),n.fileChars);if(y&&!a(i.teams,{id:p,files:{"TEAM.md":y}}))break}let g=[];for(let p of await qe(ne(r,"agents"),100)){let y=ne(r,"agents",p);await Bt(y)&&g.push({id:p,dir:y,at:Math.max(0,...await Promise.all([...Io,".memory-state.json"].map(f=>s(ne(y,f)))))})}for(let{id:p,dir:y,at:f}of g.sort((w,P)=>P.at-w.at||w.id.localeCompare(P.id))){let w={};for(let z of Io){let h=await qt(ne(y,z),n.fileChars);h&&(w[z]=h)}let P=[];if(await Bt(ne(y,"LOG")))for(let z of(await qe(ne(y,"LOG"),400)).filter(h=>/^\d{4}-\d{2}-\d{2}\.md$/.test(h)&&h.slice(0,10)>=o&&h.slice(0,10)<=Ye(e))){let h=await qt(ne(y,"LOG",z),n.logChars);h&&P.push({date:z.slice(0,10),text:h})}let H=(await bt(ne(y,".memory-dream.json")))?.last,T=await Uo(y),U=await gc(y,n.fileChars);!Object.keys(w).length&&!P.length&&!T&&!U||a(i.agents,{id:p,updatedAt:f?new Date(f).toISOString():null,config:U,state:T,dream:H&&typeof H=="object"?{state:ee(H.state,32),startedAt:ee(H.startedAt,40),finishedAt:ee(H.finishedAt,40),calls:typeof H.calls=="number"?H.calls:void 0,detail:typeof H.detail=="string"?Ge(tt(H.detail),n.detailChars):void 0}:void 0,files:Object.keys(w).length?w:void 0,log:P.length?P:void 0})}return i}async function Yo(t){let e=(await bt(ne(t,"tangu","device.json")))?.deviceId;return typeof e=="string"&&/^[A-Za-z0-9_-]{1,64}$/.test(e)?e:`h${Rl("sha256").update(Lo()).digest("hex").slice(0,8)}`}async function yc(t){let{home:e}=t,n=ne(e,"tangu"),r=t.now??new Date,s=i=>t.since?.[i]??ze(r),o=mc(t.engineLogs);return tt({schema:3,collectedAt:r.toISOString(),app:{version:t.appVersion,platform:process.platform,arch:process.arch,os:Fl(),electron:process.versions.electron??null,node:process.versions.node,locale:Intl.DateTimeFormat().resolvedOptions().locale,timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,home:Ho(e),cloudUrl:t.cloudUrl},device:{id:await Yo(e),name:Lo()},system:await fc(e),config:ac(await bt(ne(e,"config.json"))),agents:await $o(ne(n,"agents")),teams:await $o(ne(n,"teams")),plugins:{desktop:await Mo(ne(e,"plugins")),engine:await Mo(ne(n,"plugins"))},inventory:{skills:await qe(ne(n,"skills")),spaces:await qe(ne(e,"spaces")),themes:await qe(ne(e,"themes"))},...t.activity?{...await cc(ne(e,"activity"),r,s("activity")),activitySince:new Date(s("activity")).toISOString()}:{},...t.sessions?{...await uc(e,r,qo,s("sessions")),sessionsSince:new Date(s("sessions")).toISOString()}:{},...(typeof t.memory=="function"?t.memory():t.memory)===!0?{memory:await hc(e,r)}:{},...await dc(e,r),runsSince:new Date(ze(r)).toISOString(),...o?{engine:o}:{}})}function Go(t,e={}){let n=e.now??(()=>new Date),r=e.remoteFor??(T=>dn({baseUrl:T.cloudUrl,vault:fn,getToken:()=>T.token})),s=e.policyFor??Ir,o=()=>ne(t.homeDir(),"extend-diagnostics.json"),i=()=>{let T=U=>U&&typeof U=="object"?U:{};try{let U=JSON.parse(Pl(o(),"utf8"));return{accounts:T(U?.accounts),sent:T(U?.sent)}}catch{return{accounts:{},sent:{}}}},l=()=>i().accounts,a=(T,U,z)=>{let h=i();h.accounts[T]={...h.accounts[T],...U},Object.assign(h.sent,z),Dl(t.homeDir(),{recursive:!0});let v=`${o()}.${process.pid}.tmp`;Ml(v,JSON.stringify(h,null,2),{encoding:"utf8",mode:384}),$l(v,o())},d=()=>{let T=t.readCreds();return T.token&&T.cloudUrl?t.accountId():null},u=()=>{let T=d(),U=T?l()[T]??{}:{},z=zt(U.policy);return{signedIn:!!T,enabled:U.enabled===!0,activity:U.activity!==!1,sessions:U.sessions??U.enabled!==!0,memory:U.memory??U.enabled!==!0,lastUploadAt:U.lastUploadAt??null,lastError:U.lastError??null,retainDays:In,mode:z.mode,intervalHours:z.intervalHours}},m=()=>{try{return No(t)?t.diagnosticLogs():null}catch{return null}},g=null,p=new Map,y=async()=>{let T=d();if(!T)return!1;if(g)return g.id===T?g.done:(await g.done,y());let U={...t.readCreds()},z=n(),h=i(),v=h.accounts[T],b=U.cloudUrl.replace(/\/+$/,""),A=xr(v?.file,h.sent[b]??{},z),N=(async()=>{try{let B=await yc({home:t.homeDir(),appVersion:t.appVersion(),cloudUrl:U.cloudUrl,activity:v?.activity!==!1,sessions:v?.sessions===!0,now:z,since:A,engineLogs:m(),memory:()=>{let Z=d()===T?l()[T]:void 0;return Z?.enabled===!0&&Z.memory===!0}}),G=await Yo(t.homeDir()),se=l()[T];if(d()!==T||se?.enabled!==!0)return!1;if(se.activity===!1)for(let Z of["activity","activityTruncated","activityError","activitySince"])delete B[Z];if(se.sessions!==!0)for(let Z of["sessions","sessionsTruncated","sessionsError","sessionsSince"])delete B[Z];se.memory!==!0&&delete B.memory;let pe=[],X=Hl(B,pe);if(!X)throw new Error("snapshot too large");await Tr(r(U),G,X,z),p.delete(T);let de=Cr(i().sent[b]??{},v?.file,A,z,B,pe);return a(T,{lastUploadAt:n().getTime(),lastError:void 0,file:de.file},{[b]:de.sent}),t.log(`[forsion-extend] diagnostics uploaded (${X.length} bytes)`),!0}catch(B){p.set(T,n().getTime());let G=String(B?.message||B).slice(0,300);try{a(T,{lastError:G})}catch{}return t.log(`[forsion-extend] diagnostics upload failed: ${G}`),!1}finally{g=null}})();return g={id:T,done:N},N},f=async()=>{try{let T=d();if(!T||l()[T]?.enabled!==!0)return;let U=await s({...t.readCreds()}),z=d()===T?l()[T]:void 0;if(z?.enabled!==!0)return;U&&(U.mode!==z.policy?.mode||U.intervalHours!==z.policy?.intervalHours)&&a(T,{policy:{mode:U.mode,intervalHours:U.intervalHours}}),U&&z.requestSeen===void 0&&a(T,{requestSeen:U.requestedAt});let h=U??{...zt(z.policy),requestedAt:0},v=h.requestedAt>(z.requestSeen??h.requestedAt),b=z.lastUploadAt??0,A=!b||h.mode==="scheduled"&&n().getTime()-b>=h.intervalHours*zo;if(!v&&!A||n().getTime()-(p.get(T)??-To)<To)return;await y()&&v&&a(T,{requestSeen:h.requestedAt})}catch(T){t.log(`[forsion-extend] diagnostics tick failed: ${String(T?.message||T)}`)}},w={ok:!1,error:"untrusted"};t.handle("diagnostics:get",T=>t.isTrustedSender(T)?u():w),t.handle("diagnostics:set",(T,U)=>{if(!t.isTrustedSender(T))return w;let z=d();if(!z)return u();let h={};typeof U?.enabled=="boolean"&&(h.enabled=U.enabled),h.enabled&&(h.requestSeen=void 0),typeof U?.activity=="boolean"&&(h.activity=U.activity),typeof U?.sessions=="boolean"&&(h.sessions=U.sessions),typeof U?.memory=="boolean"&&(h.memory=U.memory);let v=l()[z];for(let b of["sessions","memory"])h[b]!==void 0||v?.[b]!==void 0||(v?.enabled===!0?h[b]=!1:h.enabled&&(h[b]=!0));return a(z,h),h.enabled&&(p.delete(z),f()),u()}),t.handle("diagnostics:uploadNow",async T=>t.isTrustedSender(T)?(u().enabled&&await y(),u()):w);let P=setTimeout(()=>void f(),zl),H=setInterval(()=>void f(),ql);return P.unref?.(),H.unref?.(),t.log(`[forsion-extend] diagnostics registered${No(t)?"":" (host has no diagnosticLogs: snapshots carry no engine log)"}`),Object.assign(()=>{clearTimeout(P),clearInterval(H)},{tick:f})}Lr(hs);function Mf(t){Gr(t),rr(t),t.log("[forsion-extend] cloud account handlers registered"),Gn(t)?Jn(t):t.log("[forsion-extend] host has no Connect seam (projectsRoot / transpileForServe / mimeOf / setPreviewHooks); Connect stays with the host"),Kn(t)?Zn(t):t.log("[forsion-extend] host has no remote-sync seam (registerRemoteSyncBackend / readCreds); penzor stays with the host"),ir(t)?ar(t):t.log("[forsion-extend] host has no account seam (accountCommit / accountClear / \u2026); account core stays with the host"),br(t)?Sr(t):t.log("[forsion-extend] host has no amadeus seam (setAmadeusSyncFactory); cloud sync stays with the host"),Er(t)?_r(t):t.log("[forsion-extend] host has no unit seam (setUnitHubFactory); the device channel stays with the host"),Bo(t)?Go(t):t.log("[forsion-extend] host has no diagnostics seam (homeDir / readCreds / accountId / appVersion); diagnostics upload is off")}export{zs as ACCOUNT_SEAM,mo as AMADEUS_SEAM,Vn as CONNECT_MAX_FILES,ws as CONNECT_MAX_FILE_BYTES,bs as CONNECT_MAX_TOTAL_BYTES,fn as DIAGNOSTICS_VAULT,xs as FORSION_CONNECT_LOCAL_SDK,Yr as PAY_PERIODS,Vr as PAY_TABS,As as PENZOR_MAX_FILE,ke as SYNC_IPC,ho as UNIT_SEAM,It as UPLOAD_MAX_FILE,Ft as UnitCapsReporter,jt as UnitHost,Ae as cloudJson,Ss as collectProjectFiles,wn as conflictCopyPath,Wa as conflictCopyVariant,Hs as createAccountCloud,po as createAmadeusCloud,dn as createPenzorRemote,yo as createUnitHub,un as deviceHeader,Xn as expectedPartsOf,$e as forsionAccountId,hn as forsionRefreshToken,At as forsionWhoami,ir as hasAccountHost,br as hasAmadeusHost,Gn as hasConnectHost,Kn as hasRemoteSyncHost,Er as hasUnitHost,vs as makePreviewProxy,Us as multipartFrame,Es as readConnectMeta,ar as registerAccount,Sr as registerAmadeus,Mf as registerCloud,Jn as registerConnect,Zn as registerPenzor,rr as registerPenzorTransfers,_r as registerUnit,mn as safeDownloadName,gn as shouldRefreshToken,Qn as speedOf,go as streamWorthy,ao as stripConflictSuffix,Va as textFingerprint,or as tokenAgeMs,js as tokenRemainingMs,er as uploadError,_s as writeConnectMeta};
248
+ json_extract(e.payload, '$.requestBytes') AS request_bytes, json_extract(e.payload, '$.phase') AS phase, substr(json_extract(e.payload, '$.error'), 1, ${rn}) AS error
249
+ FROM agent_run_events e WHERE e.run_id = ? AND e.type IN ('usage', 'tool_result', 'error', 'status') AND json_valid(e.payload) ORDER BY e.seq LIMIT ?`),u=p=>typeof p=="number"&&Number.isFinite(p)&&p>0?p:0,f=p=>p||void 0,m=[],h=0,g=a.length>n.runs;for(let p of a.slice(0,n.runs)){let y={llmCalls:0,prompt:0,completion:0,cached:0,reasoning:0,llmMs:0,ttftMaxMs:0,requestMaxBytes:0},E=new Map,O=[],C=0,M=c.all(p.id,n.events+1),H=M.length>n.events;for(let b of M.slice(0,n.events))if(b.type==="usage")y.llmCalls++,y.prompt+=u(b.prompt),y.completion+=u(b.completion),y.cached+=u(b.cached),y.reasoning+=u(b.reasoning),y.llmMs+=u(b.llm_ms),y.ttftMaxMs=Math.max(y.ttftMaxMs,u(b.ttft_ms)),y.requestMaxBytes=Math.max(y.requestMaxBytes,u(b.request_bytes));else if(b.type==="tool_result"){let I=ee(b.name,80)??"?",U=E.get(I)??(E.size<n.tools?{name:I,n:0,ms:0,maxMs:0}:void 0);if(!U){H=!0;continue}E.set(I,U),U.n++,b.failed&&(U.errors=(U.errors??0)+1),U.ms+=u(b.ms),U.maxMs=Math.max(U.maxMs,u(b.ms))}else if(b.type==="error"){let I=Wn(b.error,n.errorChars);I&&!O.includes(I)&&O.length<3&&O.push(I)}else b.phase==="llm_retry"&&C++;let w={id:ee(p.id,64)??null,session:ee(p.session_id,64)??null,kind:ee(p.kind,16),app:ee(p.app_id,50),model:ee(p.model_id,128),status:ee(p.status,16)??null,error:Wn(p.error,n.errorChars),createdAt:ee(p.created_at,40)??null,updatedAt:ee(p.updated_at,40)??null,steps:f(u(p.current_step)),tokens:f(u(p.tokens_total)),retries:f(C),...Object.fromEntries(Object.entries(y).map(([b,I])=>[b,f(I)])),errors:O.length?O:void 0,tools:E.size?[...E.values()]:void 0,partial:H||void 0},x=Buffer.byteLength(JSON.stringify(w));if(h+x>n.totalBytes){g=!0;break}h+=x,m.push(w)}return{runs:m,...g?{runsTruncated:!0}:{}}}catch(i){return{runs:[],runsError:pt(i)}}finally{try{o?.close()}catch{}}}async function fu(t){let e=s=>Math.round(s/1048576),n=s=>Qe(s).then(o=>o.isFile()?o.size:0,()=>0),r=ne(t,"tangu","state.db");return{cpus:jc().length,memTotalMB:e(Lc()),memFreeMB:e(Uc()),diskFreeMB:await Nc(t).then(s=>e(s.bavail*s.bsize),()=>null),stateDbMB:e(await n(r)+await n(`${r}-wal`)),uptimeMin:Math.round(process.uptime()/60)}}var bi=t=>typeof t.diagnosticLogs=="function";function hu(t,e=Gc){let n=t?.engine;if(!n||typeof n!="object")return null;let r=(Array.isArray(n.lines)?n.lines:[]).filter(a=>typeof a=="string"&&!!a),s=r.map(a=>Wn(a,Qr)??""),o=s.some((a,c)=>a.length>Qr||r[c].length>rn),i=s.length,l=e;for(;i>0&&Buffer.byteLength(s[i-1])+1<=l;)l-=Buffer.byteLength(s[--i])+1;return i>0&&(o=!0),{state:ee(n.state,32)??null,lastError:Wn(n.lastError,Qr)??null,log:s.slice(i).join(`
250
+ `),...o?{logTruncated:!0}:{}}}function pu(t,e=Zc){let n;try{n=Hn(t)}catch{return{}}return Object.fromEntries(e.flatMap(r=>typeof n[r]=="string"&&n[r]?[[r,n[r]]]:[]))}async function Ii(t,e=Kc){try{if(!(await Qe(t)).isFile())return null;let n=await vi(t,li.O_RDONLY|(li.O_NOFOLLOW??0));try{let r=await n.stat();if(!r.isFile())return null;let s=Buffer.alloc(Math.min(e,r.size)),{bytesRead:o}=await n.read(s,0,s.length,0);return s.subarray(0,o).toString("utf8")}finally{await n.close()}}catch{return null}}var tn=async(t,e)=>{let n=await Ii(t);return n?Ze(at(n),e):void 0};async function mu(t,e){let n=await Ii(ne(t,"config.toml")),r=Object.entries(n?pu(n):{}).map(([s,o])=>[s,Ze(at(o),e)??""]);return r.length?Object.fromEntries(r):void 0}async function Si(t){let e=await Pt(ne(t,".memory-state.json"));if(!e||typeof e!="object")return;let n=r=>Array.isArray(r)?r.length:0;return{entries:n(e.entries),tombstones:n(e.tombstones),revisions:n(e.revisions),processedCandidates:n(e.processedCandidateIds),updatedAt:typeof e.updatedAt=="number"?e.updatedAt:null,projectionPending:e.projectionPending===!0?!0:void 0}}async function gu(t,e,n=Xc){let r=ne(t,"tangu"),s=h=>Qe(h).then(g=>g.isFile()?g.mtimeMs:0,()=>0),o=Ke(new Date(qe(e))),i={agents:[],teams:[],projects:[],activity:[]},l=n.totalBytes,a=(h,g)=>{let p=Buffer.byteLength(JSON.stringify(g))+1;return p>l?(i.truncated=!0,!1):(l-=p,h.push(g),!0)},c=await tn(ne(r,"USER.md"),n.fileChars);c&&a([],c)&&(i.user=c);let u=ne(r,"state.db"),f=await Qe(u).then(h=>h.isFile(),h=>h?.code==="ENOENT"?!1:pt(h));if(typeof f=="string")i.activityError=f;else if(f){let h;try{let{DatabaseSync:g}=await import("node:sqlite");h=new g(u,{readOnly:!0}),h.exec("PRAGMA busy_timeout = 1500");let y=h.prepare(`SELECT agent, action, substr(detail, 1, ${rn}) AS detail, session_ref, created_at FROM special_agent_log
251
+ WHERE created_at >= ? AND created_at < ? AND (${Qc.map(E=>`action GLOB '${E}*'`).join(" OR ")})
252
+ ORDER BY created_at DESC, rowid DESC LIMIT ?`).all(Rt(qe(e)),Rt(e.getTime()),n.activity+1);y.length>n.activity&&(i.truncated=!0);for(let E of y.slice(0,n.activity))if(!a(i.activity,{at:ee(E.created_at,40)??null,agent:ee(E.agent,64)??null,action:ee(E.action,64)??null,detail:typeof E.detail=="string"&&E.detail?Ze(at(E.detail),n.detailChars):void 0,session:ee(E.session_ref,64)}))break}catch(g){i.activityError=pt(g)}finally{try{h?.close()}catch{}}}for(let h of await Be(ne(r,"project-memory"),100)){let g=ne(r,"project-memory",h);if(!await nn(g))continue;let p=await tn(ne(g,"MEMORY.md"),n.fileChars),y=await Si(g);if(!p&&!y)continue;let E=(await Pt(ne(g,"PROJECT.json")))?.project;if(!a(i.projects,{id:ee(h,64)??null,name:typeof E=="string"?ee(_i(E.replace(/[\\/]+$/,"").replace(/\\/g,"/"))):void 0,state:y,memory:p}))break}for(let h of await Be(ne(r,"teams"),100)){if(!await nn(ne(r,"teams",h)))continue;let g=await tn(ne(r,"teams",h,"TEAM.md"),n.fileChars);if(g&&!a(i.teams,{id:h,files:{"TEAM.md":g}}))break}let m=[];for(let h of await Be(ne(r,"agents"),100)){let g=ne(r,"agents",h);await nn(g)&&m.push({id:h,dir:g,at:Math.max(0,...await Promise.all([...fi,".memory-state.json"].map(p=>s(ne(g,p)))))})}for(let{id:h,dir:g,at:p}of m.sort((y,E)=>E.at-y.at||y.id.localeCompare(E.id))){let y={};for(let H of fi){let w=await tn(ne(g,H),n.fileChars);w&&(y[H]=w)}let E=[];if(await nn(ne(g,"LOG")))for(let H of(await Be(ne(g,"LOG"),400)).filter(w=>/^\d{4}-\d{2}-\d{2}\.md$/.test(w)&&w.slice(0,10)>=o&&w.slice(0,10)<=Ke(e))){let w=await tn(ne(g,"LOG",H),n.logChars);w&&E.push({date:H.slice(0,10),text:w})}let O=(await Pt(ne(g,".memory-dream.json")))?.last,C=await Si(g),M=await mu(g,n.fileChars);!Object.keys(y).length&&!E.length&&!C&&!M||a(i.agents,{id:h,updatedAt:p?new Date(p).toISOString():null,config:M,state:C,dream:O&&typeof O=="object"?{state:ee(O.state,32),startedAt:ee(O.startedAt,40),finishedAt:ee(O.finishedAt,40),calls:typeof O.calls=="number"?O.calls:void 0,detail:typeof O.detail=="string"?Ze(at(O.detail),n.detailChars):void 0}:void 0,files:Object.keys(y).length?y:void 0,log:E.length?E:void 0})}return i}async function Pi(t){let e=(await Pt(ne(t,"tangu","device.json")))?.deviceId;return typeof e=="string"&&/^[A-Za-z0-9_-]{1,64}$/.test(e)?e:`h${Pc("sha256").update(Ei()).digest("hex").slice(0,8)}`}async function yu(t){let{home:e}=t,n=ne(e,"tangu"),r=t.now??new Date,s=i=>t.since?.[i]??qe(r),o=hu(t.engineLogs);return at({schema:3,collectedAt:r.toISOString(),app:{version:t.appVersion,platform:process.platform,arch:process.arch,os:Fc(),electron:process.versions.electron??null,node:process.versions.node,locale:Intl.DateTimeFormat().resolvedOptions().locale,timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,home:_i(e),cloudUrl:t.cloudUrl},device:{id:await Pi(e),name:Ei()},system:await fu(e),config:au(await Pt(ne(e,"config.json"))),agents:await gi(ne(n,"agents")),teams:await gi(ne(n,"teams")),plugins:{desktop:await yi(ne(e,"plugins")),engine:await yi(ne(n,"plugins"))},inventory:{skills:await Be(ne(n,"skills")),spaces:await Be(ne(e,"spaces")),themes:await Be(ne(e,"themes"))},...t.activity?{...await cu(ne(e,"activity"),r,s("activity")),activitySince:new Date(s("activity")).toISOString()}:{},...t.sessions?{...await uu(e,r,xi,s("sessions")),sessionsSince:new Date(s("sessions")).toISOString()}:{},...(typeof t.memory=="function"?t.memory():t.memory)===!0?{memory:await gu(e,r)}:{},...await du(e,r),runsSince:new Date(qe(r)).toISOString(),...o?{engine:o}:{}})}function Ri(t,e={}){let n=e.now??(()=>new Date),r=e.remoteFor??(C=>xn({baseUrl:C.cloudUrl,vault:Tn,getToken:()=>C.token})),s=e.policyFor??Zr,o=()=>ne(t.homeDir(),"extend-diagnostics.json"),i=()=>{let C=M=>M&&typeof M=="object"?M:{};try{let M=JSON.parse(Dc(o(),"utf8"));return{accounts:C(M?.accounts),sent:C(M?.sent)}}catch{return{accounts:{},sent:{}}}},l=()=>i().accounts,a=(C,M,H)=>{let w=i();w.accounts[C]={...w.accounts[C],...M},Object.assign(w.sent,H),Rc(t.homeDir(),{recursive:!0});let x=`${o()}.${process.pid}.tmp`;Oc(x,JSON.stringify(w,null,2),{encoding:"utf8",mode:384}),$c(x,o())},c=()=>{let C=t.readCreds();return C.token&&C.cloudUrl?t.accountId():null},u=()=>{let C=c(),M=C?l()[C]??{}:{},H=en(M.policy);return{signedIn:!!C,enabled:M.enabled===!0,activity:M.activity!==!1,sessions:M.sessions??M.enabled!==!0,memory:M.memory??M.enabled!==!0,lastUploadAt:M.lastUploadAt??null,lastError:M.lastError??null,retainDays:Bn,mode:H.mode,intervalHours:H.intervalHours}},f=()=>{try{return bi(t)?t.diagnosticLogs():null}catch{return null}},m=null,h=new Map,g=async()=>{let C=c();if(!C)return!1;if(m)return m.id===C?m.done:(await m.done,g());let M={...t.readCreds()},H=n(),w=i(),x=w.accounts[C],b=M.cloudUrl.replace(/\/+$/,""),I=Jr(x?.file,w.sent[b]??{},H),U=(async()=>{try{let B=await yu({home:t.homeDir(),appVersion:t.appVersion(),cloudUrl:M.cloudUrl,activity:x?.activity!==!1,sessions:x?.sessions===!0,now:H,since:I,engineLogs:f(),memory:()=>{let Z=c()===C?l()[C]:void 0;return Z?.enabled===!0&&Z.memory===!0}}),J=await Pi(t.homeDir()),se=l()[C];if(c()!==C||se?.enabled!==!0)return!1;if(se.activity===!1)for(let Z of["activity","activityTruncated","activityError","activitySince"])delete B[Z];if(se.sessions!==!0)for(let Z of["sessions","sessionsTruncated","sessionsError","sessionsSince"])delete B[Z];se.memory!==!0&&delete B.memory;let pe=[],X=zc(B,pe);if(!X)throw new Error("snapshot too large");await Xr(r(M),J,X,H),h.delete(C);let de=Gr(i().sent[b]??{},x?.file,I,H,B,pe);return a(C,{lastUploadAt:n().getTime(),lastError:void 0,file:de.file},{[b]:de.sent}),t.log(`[forsion-extend] diagnostics uploaded (${X.length} bytes)`),!0}catch(B){h.set(C,n().getTime());let J=String(B?.message||B).slice(0,300);try{a(C,{lastError:J})}catch{}return t.log(`[forsion-extend] diagnostics upload failed: ${J}`),!1}finally{m=null}})();return m={id:C,done:U},U},p=async()=>{try{let C=c();if(!C||l()[C]?.enabled!==!0)return;let M=await s({...t.readCreds()}),H=c()===C?l()[C]:void 0;if(H?.enabled!==!0)return;M&&(M.mode!==H.policy?.mode||M.intervalHours!==H.policy?.intervalHours)&&a(C,{policy:{mode:M.mode,intervalHours:M.intervalHours}}),M&&H.requestSeen===void 0&&a(C,{requestSeen:M.requestedAt});let w=M??{...en(H.policy),requestedAt:0},x=w.requestedAt>(H.requestSeen??w.requestedAt),b=H.lastUploadAt??0,I=!b||w.mode==="scheduled"&&n().getTime()-b>=w.intervalHours*Ci;if(!x&&!I||n().getTime()-(h.get(C)??-ui)<ui)return;await g()&&x&&a(C,{requestSeen:w.requestedAt})}catch(C){t.log(`[forsion-extend] diagnostics tick failed: ${String(C?.message||C)}`)}},y={ok:!1,error:"untrusted"};t.handle("diagnostics:get",C=>t.isTrustedSender(C)?u():y),t.handle("diagnostics:set",(C,M)=>{if(!t.isTrustedSender(C))return y;let H=c();if(!H)return u();let w={};typeof M?.enabled=="boolean"&&(w.enabled=M.enabled),w.enabled&&(w.requestSeen=void 0),typeof M?.activity=="boolean"&&(w.activity=M.activity),typeof M?.sessions=="boolean"&&(w.sessions=M.sessions),typeof M?.memory=="boolean"&&(w.memory=M.memory);let x=l()[H];for(let b of["sessions","memory"])w[b]!==void 0||x?.[b]!==void 0||(x?.enabled===!0?w[b]=!1:w.enabled&&(w[b]=!0));return a(H,w),w.enabled&&(h.delete(H),p()),u()}),t.handle("diagnostics:uploadNow",async C=>t.isTrustedSender(C)?(u().enabled&&await g(),u()):y);let E=setTimeout(()=>void p(),Hc),O=setInterval(()=>void p(),qc);return E.unref?.(),O.unref?.(),t.log(`[forsion-extend] diagnostics registered${bi(t)?"":" (host has no diagnosticLogs: snapshots carry no engine log)"}`),Object.assign(()=>{clearTimeout(E),clearInterval(O)},{tick:p})}import{readFileSync as sn,lstatSync as Ji,renameSync as Ru,linkSync as Du,unlinkSync as Bi,readdirSync as $u,rmdirSync as Ou,writeFileSync as Mu,mkdirSync as Nu,copyFileSync as ju,constants as Uu}from"node:fs";import{readFile as as,writeFile as Wi,mkdir as Vi,rename as Fu,readdir as Lu,lstat as ls,stat as Kn,unlink as zu}from"node:fs/promises";import{join as et,dirname as Zn,relative as cs,sep as us}from"node:path";import{hostname as ds}from"node:os";import{randomUUID as ut}from"node:crypto";import{Readable as Yi}from"node:stream";var Di={version:1,revision:0,enabled:!1,rules:[{id:"default",source:"",target:"default"}]};function lt(t,e=!1){if(typeof t!="string"||!t&&!e||t.length>512||t.startsWith("/")||/[\\\u0000-\u001f\u007f]/.test(t)||t&&t.split("/").some(n=>!n||n==="."||n===".."||n.endsWith(".")||n.endsWith(" ")||n.startsWith(".forsion-sync")))throw Error("Invalid content path");return t}function wu(t){if(t==="default"||t==="off"||typeof t=="string"&&/^device-[A-Za-z0-9_-]{1,64}$/.test(t))return t;throw Error("Invalid content target")}function es(t,e){let n=t;if(!n||n.version!==1||typeof n.enabled!="boolean"||!Array.isArray(n.rules)||n.rules.length>512)throw Error("Invalid content sync configuration");let r=new Set,s=new Set,o=n.rules.map(i=>{let l=lt(i.source,!0),a=wu(i.target);if(typeof i.id!="string"||!/^[A-Za-z0-9_-]{1,80}$/.test(i.id)||s.has(i.id)||r.has(l))throw Error("Duplicate or invalid sync rule");return s.add(i.id),r.add(l),{id:i.id,source:l,target:a,...i.sourceId&&/^[a-f0-9-]{36}$/i.test(i.sourceId)?{sourceId:i.sourceId}:{}}});return{version:1,revision:e,enabled:n.enabled,rules:o}}function $i(t,e){let n=null;for(let r of e)(!r.source||t===r.source||t.startsWith(r.source+"/"))&&(!n||r.source.length>n.source.length)&&(n=r);return n}var mt={get:"penzor:sync:get",preview:"penzor:sync:preview",apply:"penzor:sync:apply",run:"penzor:sync:run",pause:"penzor:sync:pause",retry:"penzor:sync:retry"};import{constants as Oi,lstatSync as Vn,readFileSync as bu,renameSync as ts,unlinkSync as Su,linkSync as vu,mkdirSync as Yn,realpathSync as ku,rmdirSync as Eu}from"node:fs";import{open as Mi,lstat as ns,readdir as _u,realpath as Ni,readFile as rs,writeFile as Cu,mkdir as ji,unlink as xu}from"node:fs/promises";import{join as gt,dirname as Ui,relative as ss,sep as Jn}from"node:path";import{randomUUID as Fi,createHash as Tu}from"node:crypto";var Li=".forsion-sync-id.json",Au=new Set([".git","node_modules",".DS_Store",".Trash",".trash","__pycache__",".cache"]),Iu=t=>!Au.has(t)&&!t.startsWith(".forsion-sync")&&!/\.tmp-[0-9]|\.lock$|-(wal|shm)$/.test(t)&&(!t.startsWith(".")||t===".memory-tombstones.json"),Pe=t=>Tu("sha256").update(t).digest("hex");function zi(t){if(process.platform==="win32"&&t.split("/").some(e=>/[:*?"<>|]/.test(e)||/^(con|prn|aux|nul|com[1-9¹²³]|lpt[1-9¹²³])(?:\..*)?$/i.test(e)))throw Error("This name is not a safe Windows file destination")}async function We(t,e,n=!1){if(n){if(e.split("/").some(l=>l===".."||l==="."||!l)||e.startsWith("/")||e.includes("\\"))throw Error("Invalid internal content path")}else lt(e,!0);zi(e);let r=await Ni(t),s=gt(r,...e.split("/").filter(Boolean)),o=ss(r,s);if(o===".."||o.startsWith(".."+Jn))throw Error("Content path escapes root");let i=r;for(let l of o.split(Jn).filter(Boolean)){i=gt(i,l);try{if((await ns(i)).isSymbolicLink())throw Error("Content symlinks are not synchronized")}catch(a){if(a.code!=="ENOENT")throw a}}return s}function Ve(t,e,n=!1){if(n||lt(e,!0),zi(e),e.split("/").some(o=>o===".."||o===".")||e.startsWith("/")||e.includes("\\"))throw Error("Unsafe sync path");let s=ku(t);for(let o of e.split("/").filter(Boolean)){s=gt(s,o);try{if(Vn(s).isSymbolicLink())throw Error("Content symlinks are not synchronized")}catch(i){if(i.code!=="ENOENT")throw i}}return s}async function Gn(t){let e=new Map,n=t.filter(s=>s.prefix).map(s=>s.prefix),r=[];for(let s of t)try{r.push({...s,root:await Ni(s.root)})}catch(o){if(o.code!=="ENOENT")throw o}if(new Set(r.map(s=>s.root)).size!==r.length)throw Error("Managed roots refer to the same directory; choose a separate vault folder");for(let s of r){let o=s.root;if(!(await ns(o)).isDirectory())throw Error(`Sync root is not a directory: ${s.prefix||"Forsion"}`);let i=async(l,a)=>{let c=await ns(l);if(!c.isSymbolicLink()&&!(l!==o&&r.some(u=>u!==s&&u.root===l))&&!(a&&s.prefix===""&&n.some(u=>a===u||a.startsWith(u+"/")))){if(a){lt(a);let u;if(c.isDirectory())try{let f=JSON.parse(await rs(gt(l,Li),"utf8"));/^[a-f0-9-]{36}$/i.test(f.id)&&(u=f.id)}catch(f){if(f.code!=="ENOENT"&&!(f instanceof SyntaxError))throw f}e.set(a,{path:a,physical:l,root:o,kind:c.isDirectory()?"folder":"file",localId:u,size:c.isFile()?c.size:0,mtime:c.mtimeMs,inode:`${c.dev}:${c.ino}:${c.birthtimeMs}`})}if(c.isDirectory())for(let u of await _u(l,{withFileTypes:!0}))!Iu(u.name)||!u.isDirectory()&&!u.isFile()||await i(gt(l,u.name),a?`${a}/${u.name}`:u.name)}};await i(o,s.prefix)}return[...e.values()].sort((s,o)=>s.path.split("/").length-o.path.split("/").length||s.path.localeCompare(o.path))}async function os(t){if(t.kind!=="folder")throw Error("Folder identity required");if(t.localId)return t.localId;let e=await We(t.root,ss(t.root,gt(t.physical,Li)).split(Jn).join("/"),!0),n=Fi();try{let r=await Mi(e,"wx",384);try{await r.writeFile(JSON.stringify({version:1,id:n})+`
253
+ `)}finally{await r.close()}return t.localId=n,n}catch(r){if(r.code!=="EEXIST")throw r;let s=JSON.parse(await rs(e,"utf8"));if(!/^[a-f0-9-]{36}$/i.test(s.id))throw Error("Invalid folder sync identity");return t.localId=s.id,s.id}}async function Xn(t){let e=await We(t.root,ss(t.root,t.physical).split(Jn).join("/")),n=await Mi(e,Oi.O_RDONLY|(Oi.O_NOFOLLOW||0));try{if((await n.stat()).size>50*1024*1024)throw Error("File exceeds 50 MB content limit");return await n.readFile()}finally{await n.close()}}function ct(t,e){lt(e);let n=[...t].sort((r,s)=>s.prefix.length-r.prefix.length).find(r=>!r.prefix||e===r.prefix||e.startsWith(r.prefix+"/"));if(!n)throw Error("Content root unavailable");return{root:n.root,relative:n.prefix?e.slice(n.prefix.length).replace(/^\//,""):e}}async function Hi(t,e,n,r,s=async(o,i)=>i()){let o=ct(t,e);await ji(o.root,{recursive:!0});let i=await We(o.root,o.relative),l=await rs(i).catch(c=>{if(c.code==="ENOENT")return null;throw c});if((l?Pe(l):null)!==r)throw Error("Local file changed during download");let a=gt(o.root,`.forsion-sync-${Fi()}.tmp`);try{await Cu(a,n,{flag:"wx",mode:384}),await We(o.root,o.relative),await s(i,()=>{Ve(o.root,o.relative),Yn(Ui(i),{recursive:!0}),Ve(o.root,o.relative);let c=null;try{c=bu(i)}catch(u){if(u.code!=="ENOENT")throw u}if((c?Pe(c):null)!==r)throw Error("Local file changed during download");ts(a,i)})}finally{await xu(a).catch(()=>{})}}async function qi(t,e,n=async(r,s)=>s()){let r=ct(t,e);await ji(r.root,{recursive:!0});let s=await We(r.root,r.relative);await n([s],()=>{Ve(r.root,r.relative),Yn(s,{recursive:!0})})}async function is(t,e,n,r=async(s,o)=>o()){let s=ct(t,e),o=ct(t,n);if(s.root!==o.root)throw Error("Folder move crosses a managed source");let i=await We(s.root,s.relative),l=await We(o.root,o.relative);await r([i,l],()=>{if(Ve(s.root,s.relative),Ve(o.root,o.relative),Pu(l))throw Error("Local rename destination exists");Yn(Ui(l),{recursive:!0});let a=Vn(i);if(a.isDirectory()){if(process.platform==="win32"){ts(i,l);return}Yn(l,{mode:448});try{ts(i,l)}catch(c){try{Eu(l)}catch{}throw c}}else{vu(i,l);let c=Vn(i);if(c.ino!==a.ino||c.dev!==a.dev)throw Error("Source changed during rename");Su(i)}})}function Pu(t){try{return Vn(t),!0}catch(e){if(e.code==="ENOENT")return!1;throw e}}var Hu=()=>({config:structuredClone(Di),owned:!1,paused:!1,folders:{},files:{},jobs:[]}),on=50*1024*1024,tt=(t,e)=>`${t}:${e}`,fs=t=>t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",an=t=>t.slice(t.lastIndexOf("/")+1),Dt=t=>t.split("/").length,Ye=t=>t instanceof Error?t.message:String(t);function Gi(t){if(!t.contentSync)return;let e=new hs(t);for(let[n,r]of Object.entries({[mt.get]:()=>e.snapshot(),[mt.preview]:s=>e.preview(s),[mt.apply]:s=>e.apply(typeof s=="string"?s:""),[mt.run]:()=>e.run(),[mt.pause]:s=>e.pause(s===!0),[mt.retry]:()=>e.run()}))t.handle(n,async(s,...o)=>{if(!t.isTrustedSender(s))return{ok:!1,error:"untrusted"};try{return{ok:!0,value:await r(...o)}}catch(i){return{ok:!1,error:Ye(i)}}});t.addQuitGuard?.(n=>e.running?{message:n==="zh"?"\u8FD8\u6709\u5185\u5BB9\u6B63\u5728\u540C\u6B65":"Content is still syncing"}:null),e.start()}var hs=class{session=null;initializing=null;previewValue=null;watcher=null;sources=[];devices=[];deviceId="";serial=Promise.resolve();scheduled=null;tick=null;first=null;blocked=new Map;phase="idle";error;closed=!1;runFinished=Promise.resolve();running=!1;host;options;constructor(e,n={}){this.host=e,this.options=n}start(){(this.tick=setInterval(()=>{this.getSession().then(r=>{r.stored.config.enabled&&!r.stored.paused&&this.run()}).catch(r=>{this.error=Ye(r)})},3e4)).unref?.(),(this.first=setTimeout(()=>{this.getSession().then(r=>{r.stored.config.enabled&&this.run()}).catch(r=>{this.error=Ye(r)})},5e3)).unref?.()}async close(){this.closed=!0,this.tick&&clearInterval(this.tick),this.first&&clearTimeout(this.first),this.scheduled&&clearTimeout(this.scheduled),this.session?.abort.abort(),await this.watcher?.close(),await this.runFinished}guard(e,n=!0){if(this.closed)throw Error("content_sync_closed");if(this.host.accountId()!==e.account||this.session!==e)throw Error("account_changed");n&&e.abort.signal.throwIfAborted()}async persist(e){let n=e.writes.catch(()=>{}).then(async()=>{this.guard(e,!1),await Vi(Zn(e.file),{recursive:!0,mode:448});let r=e.file+".tmp-"+ut();try{await Wi(r,JSON.stringify(e.stored),{mode:384,flag:"wx"}),this.guard(e,!1),await Fu(r,e.file)}finally{await zu(r).catch(()=>{})}});return e.writes=n,n}async getSession(){let e=this.host.accountId();if(!e)throw this.session?.abort.abort(),this.session=null,Error("not_signed_in");return this.session?.account===e?this.session:this.initializing?this.initializing.then(n=>(this.guard(n),n)):(this.session?.abort.abort(new Error("account_changed")),await this.watcher?.close(),this.watcher=null,this.previewValue=null,this.sources=[],this.devices=[],this.initializing=(async()=>{let n=et(this.host.homeDir(),"content-sync"),r=et(n,Pe(e)+".json"),s=Hu();try{let c=JSON.parse(await as(r,"utf8"));s={...s,...c,config:es(c.config,c.config.revision)},s.jobs=Array.isArray(c.jobs)?c.jobs.slice(-200):[]}catch(c){if(c.code!=="ENOENT")throw Error("Invalid content sync state; original data was retained")}let o,i=et(this.host.homeDir(),"content-sync-device.json");try{if(o=JSON.parse(await as(i,"utf8")),!/^[A-Za-z0-9_-]{1,64}$/.test(o.id))throw Error("Invalid device sync ID")}catch(c){if(c.code!=="ENOENT")throw c;o={id:ut()},await Vi(Zn(i),{recursive:!0});try{await Wi(i,JSON.stringify(o),{flag:"wx",mode:384})}catch(u){if(u.code!=="EEXIST")throw u;o=JSON.parse(await as(i,"utf8"))}}if(this.host.accountId()!==e)throw Error("account_changed");this.deviceId=o.id;let l=await this.host.contentSync.roots();if(this.host.accountId()!==e)throw Error("account_changed");let a={account:e,file:r,stored:s,roots:l,abort:new AbortController,writes:Promise.resolve()};return this.session=a,await this.recoverTrash(a),s.owned&&await this.host.contentSync.claim(!0),this.sources=(await this.scan(a,l).catch(c=>(this.error=Ye(c),[]))).filter(c=>c.kind==="folder").slice(0,2e3).map(({path:c,kind:u,size:f})=>({path:c,kind:u,size:f})),await this.json(a,"devices",`/${encodeURIComponent(this.deviceId)}`,"PUT",{name:ds()}),this.devices=(await this.json(a,"devices")).devices,await this.watchRoots(a),a})().catch(n=>{throw this.session?.account===e&&(this.session.abort.abort(),this.session=null),n}).finally(()=>{this.initializing=null}),this.initializing)}async scan(e,n=e.roots){for(let r of e.stored.roots??[]){let s=n.find(i=>i.prefix===r.prefix);if(!s||s.root!==r.root)throw Error("content_roots_changed_preview_required");let o=await Kn(r.root).catch(()=>{throw Error(`Sync root unavailable: ${r.prefix||"Forsion"}`)});if(!o.isDirectory()||r.dev!==void 0&&(o.dev!==r.dev||o.ino!==r.ino))throw Error("Sync root changed; preview before rebinding")}return Gn(n)}async write(e,n,r,s){this.guard(e),await Hi(e.roots,n,r,s,(o,i)=>this.lock(e,o,i)),await this.recordRoots(e)}async recordRoots(e){this.guard(e);let n=!1;for(let r of e.roots){if(e.stored.roots?.some(o=>o.prefix===r.prefix&&o.root===r.root))continue;let s=await Kn(r.root).catch(o=>{if(o.code==="ENOENT")return null;throw o});if(s){if(!s.isDirectory())throw Error("Sync root is not a directory");(e.stored.roots??=[]).push({...r,dev:s.dev,ino:s.ino}),n=!0}}n&&await this.persist(e)}lock(e,n,r,s=!1){let o=()=>{if(this.guard(e),e.stored.paused&&!s)throw Error("paused");r()};return this.host.contentSync.withWriteLock?.(n,o)??Promise.resolve().then(o)}async previewScan(e,n){for(let r of e.stored.roots??[])n.some(s=>s.prefix===r.prefix&&s.root===r.root)&&await ls(r.root).catch(()=>{throw Error(`Sync root unavailable: ${r.prefix||"Forsion"}`)});return Gn(n)}async watchRoots(e){this.options.watch!==!1&&(this.guard(e),await this.watcher?.close(),this.watcher=hr(e.roots.map(n=>n.root),{ignoreInitial:!0,ignored:n=>{let r=n.split(/[\\/]/).at(-1)??"";return r.startsWith(".")&&r!==".memory-tombstones.json"||r==="node_modules"||r==="__pycache__"}}),this.watcher.on("all",()=>{this.scheduled&&clearTimeout(this.scheduled),this.scheduled=setTimeout(()=>{e.stored.config.enabled&&!e.stored.paused&&this.run()},1500),this.scheduled.unref?.()}))}async request(e,n,r="",s="GET",o,i){this.guard(e);let l=this.host.readCreds();if(!l.token)throw Error("not_signed_in");let a=l.cloudUrl.replace(/\/+$/,"")+`/api/remotesync/content/${encodeURIComponent(n)}${r}`,c={Authorization:`Bearer ${l.token}`},u;if(o instanceof Buffer){c["Content-Type"]="application/octet-stream",c["Content-Length"]=String(o.length);let h=async function*(){for(let g=0;g<o.length;g+=64*1024)e.abort.signal.throwIfAborted(),yield o.subarray(g,g+64*1024),i?.(Math.min(o.length,g+64*1024))};u=Yi.from(h())}else o!==void 0&&(c["Content-Type"]="application/json",u=JSON.stringify(o));let f={method:s,headers:c,body:u,signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(12e4)]),...o instanceof Buffer?{duplex:"half"}:{}},m=await fetch(a,f);if(this.guard(e),!m.ok){let h=await m.json().catch(()=>({}));throw Object.assign(new Error(typeof h.detail=="string"?h.detail:`content_http_${m.status}`),{status:m.status})}return m}async json(e,n,r="",s="GET",o){return await(await this.request(e,n,r,s,o)).json()}async manifests(e,n){let r=new Map;for(let s of new Set(n.rules.filter(o=>o.target!=="off").map(o=>o.target))){let o=await this.json(e,s);if(o.schemaVersion!==1||o.namespace!==s||!Array.isArray(o.nodes))throw Error("Incomplete cloud content manifest");let i=new Set;for(let l of o.nodes){if(lt(l.path),i.has(l.id))throw Error("Duplicate cloud content identity");i.add(l.id)}r.set(s,o)}return r}route(e,n){let r=$i(e,n.rules);return r&&r.target!=="off"?r.target:null}effective(e,n){let r=new Map(n.filter(s=>s.localId).map(s=>[s.localId,s.path]));return{...e,rules:e.rules.map(s=>s.sourceId&&r.has(s.sourceId)?{...s,source:r.get(s.sourceId)}:s)}}async snapshot(){let e=await this.getSession();return{available:!0,account:Pe(e.account),deviceId:this.deviceId,deviceName:ds(),config:structuredClone(e.stored.config),running:this.running,paused:e.stored.paused,phase:this.phase,jobs:structuredClone(e.stored.jobs),devices:this.devices,sources:this.sources,...this.error?{error:this.error}:{}}}async preview(e){let n=await this.getSession();if(e?.revision!==n.stored.config.revision)throw Error("config_changed");let s=es(e,n.stored.config.revision+1),o=await this.host.contentSync.roots();this.guard(n),n.roots=o;let i=await this.previewScan(n,o),l=this.effective(s,i),a=await this.manifests(n,l);this.guard(n),this.sources=i.map(({path:p,kind:y,size:E})=>({path:p,kind:y,size:E}));let c=0,u=0,f=0,m=0;for(let p of i.filter(y=>y.kind==="file")){let y=this.route(p.path,l);if(!y)continue;let E=a.get(y)?.nodes.find(C=>!C.deleted&&C.kind==="file"&&C.path===p.path);if(p.size>on){c++,m+=p.size;continue}let O=Pe(await Xn(p));this.guard(n),O!==E?.hash&&(c++,m+=p.size,E?.version&&f++)}for(let[p,y]of a)for(let E of y.nodes)!E.deleted&&E.kind==="file"&&E.version&&this.route(E.path,l)===p&&!i.some(O=>O.path===E.path)&&u++;let h=this.signature(i,a,o),g={token:ut(),config:l,upload:s.enabled?c:0,download:s.enabled?u:0,conflicts:s.enabled?f:0,bytes:s.enabled?m:0,oldTargetsRetained:!0,expiresAt:Date.now()+5*6e4};return this.previewValue={value:g,account:n.account,signature:h},g}signature(e,n,r){return Pe(JSON.stringify([r,e.map(s=>[s.path,s.size,s.mtime,s.inode]),[...n].map(([s,o])=>[s,o.nodes.map(i=>[i.id,i.revision,i.version,i.deleted])])]))}async apply(e){let n=this.serial,r;this.serial=new Promise(s=>{r=s}),await n;try{let s=await this.getSession(),o=this.previewValue;if(!o||o.value.token!==e||o.account!==s.account||o.value.expiresAt<Date.now()||o.value.config.revision!==s.stored.config.revision+1)throw Error("preview_expired");if(this.running)throw Error("sync_in_progress");let i=await this.host.contentSync.roots(),l=await this.previewScan(s,i),a=await this.manifests(s,o.value.config);if(this.signature(l,a,i)!==o.signature)throw Error("preview_changed");let c=[];for(let f of i){let m=await Kn(f.root).catch(h=>{if(h.code==="ENOENT")return null;throw h});m&&c.push({...f,dev:m.dev,ino:m.ino})}this.guard(s);let u=structuredClone(s.stored);s.stored.config=o.value.config,s.stored.owned=!0,s.stored.paused=!1;for(let f of s.stored.config.rules){let m=l.find(h=>h.kind==="folder"&&h.path===f.source);m&&(f.sourceId=await os(m))}for(let[f,m]of Object.entries(s.stored.files))(u.config.enabled!==s.stored.config.enabled||JSON.stringify(u.roots??c)!==JSON.stringify(c)||this.route(m.path,u.config)!==this.route(m.path,s.stored.config))&&delete s.stored.files[f];for(let[f,m]of Object.entries(s.stored.folders))(u.config.enabled!==s.stored.config.enabled||JSON.stringify(u.roots??c)!==JSON.stringify(c)||this.route(m.path,u.config)!==this.route(m.path,s.stored.config))&&delete s.stored.folders[f];s.stored.roots=c,await this.persist(s);try{await this.host.contentSync.claim(!0),this.guard(s)}catch(f){throw s.stored=u,await this.persist(s),await this.host.contentSync.claim(u.owned).catch(()=>{}),f}this.previewValue=null,s.roots=i,await this.watchRoots(s)}finally{r()}this.run()}async pause(e){let n=await this.getSession();n.stored.paused=e,e?(n.abort.abort(new Error("paused")),this.phase="paused"):this.running||(n.abort=new AbortController),await this.persist(n),e||this.run()}job(e,n,r,s,o){let i=e.stored.jobs.findLast(a=>a.path===n&&a.target===r&&a.direction===s&&["failed","paused","queued"].includes(a.state));if(i)return Object.assign(i,{state:"active",done:0,size:o,at:Date.now(),error:void 0,finishedAt:void 0}),i;let l={id:ut(),path:n,target:r,direction:s,state:"active",done:0,size:o,at:Date.now()};return e.stored.jobs.push(l),e.stored.jobs=e.stored.jobs.slice(-200),l}done(e){e.state="done",e.done=e.size??e.done,e.finishedAt=Date.now()}async operation(e,n,r,s,o,i){if(this.guard(e),e.stored.paused)throw Error("paused");let l=this.job(e,n,r,s,o);try{let a=await i(l);if(this.guard(e),e.stored.paused)throw Error("paused");return this.done(l),a}catch(a){throw l.state=e.stored.paused?"paused":"failed",l.error=Ye(a),l.finishedAt=Date.now(),a}}async run(){if(this.running||this.closed)return;this.running=!0;let e;this.runFinished=new Promise(r=>{e=r});let n;try{if(n=await this.getSession(),!n.stored.config.enabled||n.stored.paused)return;n.abort.signal.aborted&&(n.abort=new AbortController),this.blocked.clear(),this.phase="scanning",this.error=void 0;let r=await this.host.contentSync.roots();this.guard(n),n.roots=r;let s=await this.scan(n,r);await this.recordRoots(n);let o=this.effective(n.stored.config,s),i=await this.manifests(n,o);this.guard(n),await this.json(n,"devices",`/${encodeURIComponent(this.deviceId)}`,"PUT",{name:ds()}),this.devices=(await this.json(n,"devices")).devices,await this.folders(n,o,s,i),await this.recordRoots(n),await this.fileRenames(n,o,s,i),s=await this.scan(n,r),o=this.effective(o,s),n.stored.config=o,this.sources=s.map(({path:l,kind:a,size:c})=>({path:l,kind:a,size:c})),this.phase="syncing";for(let l of s.filter(a=>a.kind==="file")){if(this.guard(n),n.stored.paused)throw Error("paused");let a=this.route(l.path,o);if(!(!a||this.isBlocked(a,l.path)))try{await this.file(n,o,l,a,i.get(a))}catch(c){this.error=Ye(c)}}for(let[l,a]of i)for(let c of a.nodes.filter(u=>u.kind==="file"&&!u.busy)){if(this.guard(n),n.stored.paused)throw Error("paused");if(!(this.isBlocked(l,c.path)||this.route(c.path,o)!==l||s.some(u=>u.path===c.path)))try{await this.missing(n,c,l)}catch(u){this.error=Ye(u)}}await this.cleanupFolders(n,o,i),await this.host.contentSync.changed(),this.guard(n),await this.persist(n)}catch(r){this.error=Ye(r)}finally{this.running=!1,this.phase=n?.stored.paused?"paused":"idle",n&&this.host.accountId()===n.account&&(await this.persist(n).catch(()=>{}),!this.closed&&n.abort.signal.aborted&&!n.stored.paused&&n.stored.config.enabled&&(n.abort=new AbortController,queueMicrotask(()=>void this.run()))),e()}}isBlocked(e,n){return(this.blocked.get(e)??[]).some(r=>n===r||n.startsWith(r+"/"))}block(e,n,r){this.blocked.set(e,[...this.blocked.get(e)??[],n]),this.error=Ye(r)}async folders(e,n,r,s){let o=r.filter(l=>l.kind==="folder"),i=new Map;for(let l of o)if(l.localId){if(i.has(l.localId))throw Error(`Duplicate folder sync identity: ${l.path}`);i.set(l.localId,l.path)}for(let[l,a]of s){for(let c of a.nodes.filter(u=>u.kind==="folder"&&!u.deleted&&!u.busy).sort((u,f)=>Dt(u.path)-Dt(f.path)))if(!this.isBlocked(l,c.path))try{let u=Object.entries(e.stored.folders).find(([m,h])=>m.startsWith(l+":")&&h.id===c.id)?.[1],f=(u?o.find(m=>m.localId===u.localId):null)??o.find(m=>m.path===c.path);if(u&&f&&c.path!==u.path&&f.path!==u.path&&c.path!==f.path)throw Error(`Concurrent folder rename: ${f.path}`);if(u&&f&&c.path!==u.path&&f.path===u.path){if(this.route(f.path,n)!==l)continue;if(this.route(c.path,n)!==l)throw Error("Remote rename crosses a sync rule; review the destination");await this.operation(e,f.path,l,"rename",null,()=>is(e.roots,f.path,c.path,(h,g)=>this.lock(e,h,g)));let m=f.path;for(let h of r)if(h.path===m||h.path.startsWith(m+"/")){let g=h.path;h.path=c.path+g.slice(m.length);let p=ct(e.roots,h.path);h.physical=et(p.root,p.relative)}for(let[h,g]of Object.entries(e.stored.files))h.startsWith(l+":")&&g.path.startsWith(u.path+"/")&&(g.path=c.path+g.path.slice(u.path.length));for(let h of n.rules)(h.source===u.path||h.source.startsWith(u.path+"/"))&&(h.source=c.path+h.source.slice(u.path.length))}if(!f&&this.route(c.path,n)===l&&!u){await qi(e.roots,c.path,(h,g)=>this.lock(e,h,g));let m=(await this.scan(e)).find(h=>h.path===c.path);m&&(r.push(m),o.push(m))}}catch(u){this.block(l,c.path,u);let f=Object.entries(e.stored.folders).find(([m,h])=>m.startsWith(l+":")&&h.id===c.id)?.[1];f&&this.block(l,f.path,u)}for(let c of o.sort((u,f)=>Dt(u.path)-Dt(f.path)))if(!this.isBlocked(l,c.path))try{let u=this.route(c.path,n),f=n.rules.some(E=>E.target===l&&E.source.startsWith(c.path+"/"));if(u!==l&&!f)continue;let m=await os(c),h=e.stored.folders[tt(l,m)],g=h?a.nodes.find(E=>E.id===h.id):a.nodes.find(E=>E.path===c.path&&!E.deleted);if(g?.deleted){if(h){let E=!1;for(let O of r.filter(C=>C.kind==="file"&&C.path.startsWith(c.path+"/")&&this.route(C.path,n)===l)){let C=Object.entries(e.stored.files).find(([M,H])=>M.startsWith(l+":")&&H.path===O.path)?.[1];if(!C||Pe(await Xn(O))!==C.hash){E=!0;break}}if(!E)continue}g=void 0}let p=fs(c.path),y=p?a.nodes.find(E=>E.path===p&&E.kind==="folder"&&!E.deleted)?.id:"";if(p&&!y)throw Error("Cloud parent is unavailable");if(!g)g=await this.json(e,l,"/nodes","POST",{id:h?ut():m,parentId:y,name:an(c.path),kind:"folder"}),a.nodes.push(g);else if(h&&g.path!==c.path){if(g.revision!==h.revision)throw Error(`Concurrent folder rename: ${c.path}`);let E=g.path,O=await this.operation(e,c.path,l,"rename",null,()=>this.json(e,l,`/nodes/${g.id}`,"PATCH",{parentId:y,name:an(c.path),revision:g.revision}));for(let C of a.nodes)C.path.startsWith(E+"/")&&(C.path=c.path+C.path.slice(E.length));Object.assign(g,O);for(let[C,M]of Object.entries(e.stored.files))C.startsWith(l+":")&&M.path.startsWith(E+"/")&&(M.path=c.path+M.path.slice(E.length))}e.stored.folders[tt(l,m)]={id:g.id,localId:m,path:c.path,revision:g.revision,parentId:g.parentId,name:g.name}}catch(u){this.block(l,c.path,u);let f=this.job(e,c.path,l,"rename",null);f.state="conflict",f.error=Ye(u),f.finishedAt=Date.now()}}}async cleanupFolders(e,n,r){let s=await this.scan(e);for(let[o,i]of r)for(let l of i.nodes.filter(a=>a.kind==="folder"&&!a.busy).sort((a,c)=>Dt(c.path)-Dt(a.path))){if(this.isBlocked(o,l.path)||this.route(l.path,n)!==o)continue;let a=Object.entries(e.stored.folders).find(([u,f])=>u.startsWith(o+":")&&f.id===l.id);if(!a)continue;let c=s.find(u=>u.path===l.path&&u.kind==="folder");if(l.deleted&&c){if(s.some(f=>f.path.startsWith(l.path+"/"))||(await Lu(c.physical)).some(f=>f!==".forsion-sync-id.json"))continue;await this.operation(e,l.path,o,"delete",null,()=>this.lock(e,c.physical,()=>{Ve(c.root,cs(c.root,c.physical).split(us).join("/"));let f=$u(c.physical);if(f.some(g=>g!==".forsion-sync-id.json"))throw Error("Folder changed before deletion");let m=et(c.physical,".forsion-sync-id.json"),h=f.length?sn(m):null;h&&Bi(m);try{Ou(c.physical)}catch(g){if(h)try{Mu(m,h,{flag:"wx",mode:384})}catch{}throw g}})),delete e.stored.folders[a[0]]}else if(!l.deleted&&!c){if(i.nodes.some(u=>u.parentId===l.id&&!u.deleted))continue;await this.operation(e,l.path,o,"delete",null,()=>this.json(e,o,`/nodes/${l.id}`,"DELETE",{revision:l.revision,version:null})),l.deleted=!0,delete e.stored.folders[a[0]]}}}async download(e,n,r,s){if(n.size!==void 0&&n.size>on)throw Error("File exceeds 50 MB content limit");let o=await this.request(e,r,`/nodes/${n.id}/content`),i=[],l=0;if(o.body){let c=o.body.getReader();for(;;){let u=await c.read();if(u.done)break;if(this.guard(e),l+=u.value.length,l>on)throw await c.cancel(),Error("Content too large");i.push(u.value),s.done=l}}let a=Buffer.concat(i);if(n.hash&&Pe(a)!==n.hash)throw Error("Cloud file changed during download");return a}async fileRenames(e,n,r,s){for(let[o,i]of s)for(let l of i.nodes.filter(a=>a.kind==="file"&&!a.deleted&&!a.busy)){let a=e.stored.files[tt(o,l.id)];if(!a||a.path===l.path)continue;let c=r.find(u=>u.kind==="file"&&u.path===a.path);if(!(!c||this.route(c.path,n)!==o))try{if(this.route(l.path,n)!==o)throw Error("Remote rename crosses a sync rule; review the destination");await this.operation(e,c.path,o,"rename",null,()=>is(e.roots,c.path,l.path,(u,f)=>this.lock(e,u,f))),a.path=l.path}catch(u){this.block(o,c.path,u),this.block(o,l.path,u)}}}async upload(e,n,r,s,o){if(s.length>on)throw Error("File exceeds 50 MB content limit");this.guard(e);let i=this.host.readCreds(),l=Yi.from((async function*(){for(let c=0;c<s.length;c+=64*1024)e.abort.signal.throwIfAborted(),yield s.subarray(c,c+64*1024),o.done=Math.min(s.length,c+64*1024)})()),a=await fetch(i.cloudUrl.replace(/\/+$/,"")+`/api/remotesync/content/${encodeURIComponent(r)}/nodes/${n.id}/content`,{method:"PUT",headers:{Authorization:`Bearer ${i.token}`,"Content-Type":"application/octet-stream","Content-Length":String(s.length),"X-Content-Version":n.version??"create"},body:l,duplex:"half",signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(12e4)])});if(this.guard(e),!a.ok){let c=await a.json().catch(()=>({}));throw Error(c.detail??`content_http_${a.status}`)}return await a.json()}shadow(e,n,r,s,o){for(let i of e.stored.jobs)i.path===r.path&&i.target===n&&["failed","paused","active"].includes(i.state)&&["upload","download","merge"].includes(i.direction)&&this.done(i);e.stored.files[tt(n,r.id)]={id:r.id,path:r.path,version:r.version,hash:Pe(s),...s.length<1024*1024&&Buffer.from(s.toString("utf8")).equals(s)?{base:s.toString("utf8")}:{},...o?{inode:o.inode}:{}}}async file(e,n,r,s,o){if(r.size>on){await this.operation(e,r.path,s,"upload",r.size,async()=>{throw Error("File exceeds 50 MB content limit")});return}let i=await Xn(r),l=Pe(i);this.guard(e);let a=o.nodes.find(h=>h.kind==="file"&&!h.deleted&&h.path===r.path);if(!a){let h=Object.entries(e.stored.files).find(([g,p])=>g.startsWith(s+":")&&p.inode===r.inode&&p.path!==r.path)?.[1];if(h){let g=ct(e.roots,h.path),p=await ls(et(g.root,g.relative)).then(()=>!0,E=>E.code==="ENOENT"?!1:Promise.reject(E)),y=o.nodes.find(E=>E.id===h.id&&!E.deleted);if(!p&&y){if(y.path!==h.path)throw Error(`Concurrent file rename: ${r.path}`);let E=fs(r.path),O=E?o.nodes.find(M=>M.path===E&&M.kind==="folder"&&!M.deleted)?.id:"";if(E&&!O)throw Error("Rename parent unavailable");let C=await this.operation(e,r.path,s,"rename",null,()=>this.json(e,s,`/nodes/${y.id}`,"PATCH",{name:an(r.path),parentId:O,revision:y.revision}));Object.assign(y,C),h.path=r.path,a=y}}}let c=a?e.stored.files[tt(s,a.id)]:Object.entries(e.stored.files).find(([h,g])=>h.startsWith(s+":")&&g.path===r.path)?.[1];if(!a){if((c?o.nodes.find(y=>y.id===c.id&&y.deleted):null)&&c?.hash===l){await this.operation(e,r.path,s,"delete",r.size,()=>this.trashFile(e,r,l)),delete e.stored.files[tt(s,c.id)];return}let g=fs(r.path),p=g?o.nodes.find(y=>y.path===g&&!y.deleted&&y.kind==="folder")?.id:"";if(g&&!p)throw Error("Parent folder is unavailable");a=await this.json(e,s,"/nodes","POST",{id:ut(),parentId:p,name:an(r.path),kind:"file"}),o.nodes.push(a),c=void 0}if(a.busy)return;if(a.hash===l){this.shadow(e,s,a,i,r);return}if(!a.version||c&&a.version===c.version){let h=await this.operation(e,r.path,s,"upload",i.length,g=>this.upload(e,a,s,i,g));Object.assign(a,h),this.shadow(e,s,a,i,r);return}let u=await this.operation(e,r.path,s,"download",a.size??null,h=>this.download(e,a,s,h)),f=u,m=!1;if(!c||c.hash!==l){let h=i.toString("utf8"),g=u.toString("utf8"),p=Buffer.from(h).equals(i)&&Buffer.from(g).equals(u)?this.host.contentSync.merge(r.path,h,c?.base??null,g):null;if(p?(f=Buffer.from(p.content),m=p.conflict):m=!0,m){let y=r.path.lastIndexOf("."),E=` (conflict ${this.deviceId.slice(0,8)} ${Date.now()})`,O=y>r.path.lastIndexOf("/")?r.path.slice(0,y)+E+r.path.slice(y):r.path+E;await this.write(e,O,i,null);let C=this.job(e,r.path,s,"merge",i.length);C.state="conflict",C.error="Both versions preserved",C.finishedAt=Date.now()}if(!f.equals(u)){let y=await this.operation(e,r.path,s,"merge",f.length,E=>this.upload(e,a,s,f,E));Object.assign(a,y)}}await this.write(e,r.path,f,l),this.shadow(e,s,a,f,r)}async missing(e,n,r){let s=e.stored.files[tt(r,n.id)];if(n.deleted){s&&delete e.stored.files[tt(r,n.id)];return}if(!n.version)return;if(s&&s.version===n.version){await this.operation(e,n.path,r,"delete",n.size??null,()=>this.json(e,r,`/nodes/${n.id}`,"DELETE",{revision:n.revision,version:n.version})),delete e.stored.files[tt(r,n.id)],n.deleted=!0;return}let o=await this.operation(e,n.path,r,"download",n.size??null,i=>this.download(e,n,r,i));await this.write(e,n.path,o,null),this.shadow(e,r,n,o)}async recoverTrash(e){for(let n of[...e.stored.trash??[]]){if(n.parentId){let a=(await Gn(e.roots)).find(c=>c.kind==="folder"&&c.localId===n.parentId);a&&(n.path=a.path+"/"+an(n.path))}let r=ct(e.roots,n.path),s=await We(r.root,r.relative);if(!/^\.forsion-sync-trash-[a-f0-9-]+$/.test(n.stage))throw Error("Invalid sync recovery journal");let o=n.stageRoot??r.root,i=await Kn(o);if(n.stageDev!==void 0&&(i.dev!==n.stageDev||i.ino!==n.stageIno))throw Error("Sync recovery root changed; journal retained");let l=et(o,n.stage);await ls(l).then(()=>!0,a=>a.code==="ENOENT"?!1:Promise.reject(a))&&await this.lock(e,s,()=>{if(Ve(o,n.stage,!0),Pe(sn(l))!==n.hash)throw Error("Sync recovery content changed");Ve(r.root,r.relative),Nu(Zn(s),{recursive:!0});let a=qu(s)?s+` (sync recovery ${ut().slice(0,8)})`:s;try{Du(l,a)}catch(c){if(c.code!=="EXDEV")throw c;if(ju(l,a,Uu.COPYFILE_EXCL),Pe(sn(a))!==n.hash)throw Error("Sync recovery copy incomplete; original retained")}Bi(l)},!0),e.stored.trash=e.stored.trash.filter(a=>a!==n)}}async trashFile(e,n,r){this.guard(e);let s=await We(n.root,cs(n.root,n.physical).split(us).join("/")),o={path:n.path,stage:".forsion-sync-trash-"+ut(),hash:r},i=et(n.root,o.stage),l=Ji(n.root);o.stageRoot=n.root,o.stageDev=l.dev,o.stageIno=l.ino;try{let a=JSON.parse(sn(et(Zn(s),".forsion-sync-id.json"),"utf8")).id;/^[a-f0-9-]{36}$/i.test(a)&&(o.parentId=a)}catch{}(e.stored.trash??=[]).push(o),await this.persist(e);try{await this.lock(e,s,()=>{if(Ve(n.root,cs(n.root,s).split(us).join("/")),Pe(sn(s))!==r)throw Error("Local file changed before deletion");Ru(s,i)}),await this.host.contentSync.trash(i),e.stored.trash=e.stored.trash.filter(a=>a!==o)}catch(a){throw this.host.accountId()===e.account&&!e.abort.signal.aborted&&await this.recoverTrash(e),a}}};function qu(t){try{return Ji(t),!0}catch(e){if(e.code==="ENOENT")return!1;throw e}}Es(Qs);function Cp(t){Rs(t),xr(t),Gi(t),t.log("[forsion-extend] cloud account handlers registered"),yr(t)?wr(t):t.log("[forsion-extend] host has no Connect seam (projectsRoot / transpileForServe / mimeOf / setPreviewHooks); Connect stays with the host"),Sr(t)?vr(t):t.log("[forsion-extend] host has no remote-sync seam (registerRemoteSyncBackend / readCreds); penzor stays with the host"),Ir(t)?Pr(t):t.log("[forsion-extend] host has no account seam (accountCommit / accountClear / \u2026); account core stays with the host"),Hr(t)?qr(t):t.log("[forsion-extend] host has no amadeus seam (setAmadeusSyncFactory); cloud sync stays with the host"),Wr(t)?Vr(t):t.log("[forsion-extend] host has no unit seam (setUnitHubFactory); the device channel stays with the host"),Ti(t)?Ri(t):t.log("[forsion-extend] host has no diagnostics seam (homeDir / readCreds / accountId / appVersion); diagnostics upload is off")}export{xo as ACCOUNT_SEAM,Xo as AMADEUS_SEAM,mr as CONNECT_MAX_FILES,to as CONNECT_MAX_FILE_BYTES,no as CONNECT_MAX_TOTAL_BYTES,Tn as DIAGNOSTICS_VAULT,lo as FORSION_CONNECT_LOCAL_SDK,Ps as PAY_PERIODS,Is as PAY_TABS,fo as PENZOR_MAX_FILE,ve as SYNC_IPC,Qo as UNIT_SEAM,zt as UPLOAD_MAX_FILE,Kt as UnitCapsReporter,Xt as UnitHost,Ae as cloudJson,ro as collectProjectFiles,$n as conflictCopyPath,Wl as conflictCopyVariant,Co as createAccountCloud,Ko as createAmadeusCloud,xn as createPenzorRemote,ei as createUnitHub,Cn as deviceHeader,br as expectedPartsOf,Oe as forsionAccountId,Rn as forsionRefreshToken,Lt as forsionWhoami,Ir as hasAccountHost,Hr as hasAmadeusHost,yr as hasConnectHost,Sr as hasRemoteSyncHost,Wr as hasUnitHost,ao as makePreviewProxy,vo as multipartFrame,oo as readConnectMeta,Pr as registerAccount,qr as registerAmadeus,Cp as registerCloud,wr as registerConnect,vr as registerPenzor,xr as registerPenzorTransfers,Vr as registerUnit,An as safeDownloadName,Pn as shouldRefreshToken,kr as speedOf,Zo as streamWorthy,Wo as stripConflictSuffix,Vl as textFingerprint,Ar as tokenAgeMs,ko as tokenRemainingMs,Er as uploadError,io as writeConnectMeta};
253
254
  /*! Bundled license information:
254
255
 
255
256
  chokidar/index.js: