@forsion/extend 0.9.8 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/desktop.mjs CHANGED
@@ -1,7 +1,7 @@
1
- var vs=null;function Di(t){vs=t}function Ce(){if(!vs)throw new Error("core host not set (call setCoreHost first)");return vs}var Oi=new TextEncoder,Tu=new TextDecoder("utf-8",{ignoreBOM:!0}),_n=t=>Oi.encode(t),_t=t=>Tu.decode(t),ks=t=>typeof t=="string"?Oi.encode(t).length:t.length;function Pi(t){let e="";for(let n=0;n<t.length;n+=32768)e+=String.fromCharCode(...t.subarray(n,n+32768));return btoa(e)}function wr(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 $i(t){let e=new Blob([t]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response(e).arrayBuffer())}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),l=>l.charCodeAt(0)),i=JSON.parse(new TextDecoder().decode(o)),a=i.userId??i.sub;return typeof a!="string"&&typeof a!="number"||!String(a).trim()?null:`${n.origin}${n.pathname.replace(/\/+$/,"")}::${String(a)}`}catch{return null}}function Es(t){try{let e=t.split(".")[1];if(!e)return null;let n=JSON.parse(_t(wr(e)));return n&&typeof n=="object"?n:null}catch{return null}}function _s(t,e=Date.now()){let n=Es(t)?.iat;return typeof n=="number"?e-n*1e3:1/0}function Mi(t,e=Date.now()){let n=Es(t)?.exp;return typeof n=="number"?n*1e3-e:1/0}var Ru=36e5;function br(t,e=Date.now()){return!!t&&_s(t,e)>=Ru}async function Sr(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),a=typeof i?.token=="string"?i.token:"";return a&&a!==e?a:null}catch{return null}}var Cn=(t,e)=>`${t.replace(/\/+$/,"")}\0${e}`,Iu=(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 Ni(t,e){let n=f=>e.write(JSON.stringify(f,null,2)),r=()=>{let f;try{f=e.read()}catch(g){return g?.code==="ENOENT"?[]:null}if(f===null)return[];try{let g=JSON.parse(f);return Array.isArray(g.accounts)?g.accounts.filter(p=>p&&typeof p.token=="string"&&p.id===Oe(p.cloudUrl,p.token)):null}catch{return null}},s=(f,g)=>{let p=Oe(f.cloudUrl||"",f.token||"");if(!p||!f.token||!f.cloudUrl)return;let y=r();if(!y)return;let h=y.find(_=>_.id===p),m=Es(f.token),w={...h,id:p,cloudUrl:f.cloudUrl.replace(/\/+$/,""),token:f.token,username:g?.username||h?.username||m?.username,nickname:g?.nickname||h?.nickname};JSON.stringify(h)!==JSON.stringify(w)&&n({version:1,accounts:[...y.filter(_=>_.id!==p),w]})},o=()=>{let f=t.readCreds();s(f);let g=Oe(f.cloudUrl,f.token);return(r()??[]).map(({token:p,...y})=>({...y,active:y.id===g}))},i=f=>{let g=r()?.find(p=>p.id===f);if(!g)throw new Error("Account is no longer signed in. Sign in again.");return{cloudUrl:g.cloudUrl,token:g.token}},a=f=>{let g=Oe(f.cloudUrl||"",f.token||""),p=r();g&&p&&n({version:1,accounts:p.filter(y=>y.id!==g)})},l=null;return{rememberForsionAccount:s,forsionAccounts:o,savedForsionAccount:i,forgetForsionAccount:a,cancelForsionLogin:()=>{l?.abort(),l=null},forsionDeviceLogin:async(f,g,p)=>{if(l)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 y=new AbortController;l=y;let h=()=>{if(y.signal.aborted||l!==y)throw new Error("Sign-in cancelled.")};try{let m=f.replace(/\/+$/,""),w;try{w=await fetch(`${m}/api/auth/cli/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:"{}",signal:AbortSignal.any([y.signal,AbortSignal.timeout(15e3)])}).then(C=>C.json())}catch(C){throw new Error(`\u65E0\u6CD5\u8FDE\u63A5 ${m}:${C?.message||C}`)}if(h(),!w?.device_code)throw new Error("\u4E91\u7AEF\u4E0D\u652F\u6301 CLI \u767B\u5F55(/api/auth/cli/start \u8FD4\u56DE\u5F02\u5E38)");let _=w.verification_uri_complete||`${w.verification_uri}?code=${w.user_code}`,$=new URL(`${m}/auth`);$.searchParams.set("logout","1"),$.searchParams.set("app","forsion-desktop"),$.searchParams.set("redirect",_);let R=$.toString();g?.({url:R,userCode:String(w.user_code||"")}),t.openExternal(R);let O=Date.now()+(w.expires_in||600)*1e3,S=(w.interval||2)*1e3;for(;Date.now()<O;){await Iu(S,y.signal),h();let C=null;try{C=await fetch(`${m}/api/auth/cli/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_code:w.device_code}),signal:AbortSignal.any([y.signal,AbortSignal.timeout(15e3)])})}catch{h();continue}if(h(),C.status===410)throw new Error("\u767B\u5F55\u7801\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u53D1\u8D77\u767B\u5F55");let E=await C.json().catch(()=>({status:"pending"}));if(h(),E.status==="approved"&&E.token){let I={cloudUrl:m,token:E.token};return await p(I,h),h(),{token:E.token,cloudUrl:m}}}throw new Error("\u767B\u5F55\u8D85\u65F6,\u8BF7\u91CD\u8BD5")}finally{l===y&&(l=null)}},readAccounts:()=>r()??[]}}function ht(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 xn(t,e,n){return t.fetch?t.fetch(e,n):fetch(e,{...n,headers:{Authorization:`Bearer ${t.token}`,...n.headers}})}async function Ue(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 Du=50*1024*1024,Ou=new Set(["mode","type","source","name","summary","githubRepoUrl","npmPackage","version","readme","description","tags","minAppVersion","maxAppVersion","platforms"]);function Pu(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(!Ou.has(s)||typeof o!="string"||(r+=o.length,r>25e4)||e.id&&!["mode","name","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>Du)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"}${e.dryRun===!0?"?dryRun=1":""}`,body:n}}function ji(t){t.handle("cloud:marketSubmit",async(e,n)=>{if(!t.isTrustedSender(e))return{status:0,error:"untrusted"};let r=Pu(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=ht(s.base,r.path);if(!o)return{status:0,error:"no_cloud_url"};try{let i=await xn(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 Fi(t){if(!t.token)return"";try{let e=await Ue(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 Li=["membership","credits","storefront"],Ui=["monthly","quarterly","yearly"],$u=/^[A-Za-z0-9_-]{1,64}$/;function Hi(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(),a=i.base;if(!a)return{ok:!1};let l=o&&/^[a-z0-9-]+$/i.test(o)?`#${o}`:"",c=await Fi(i),u=`${a}/account${c?`?${c}`:""}${l}`;return i.signal?.throwIfAborted(),await t.openExternal(u),{ok:!0}}),t.handle("auth:openPayCenter",async(s,o,i,a)=>{if(!t.isTrustedSender(s))return n;if(o!==void 0&&!Li.includes(o))return{ok:!1,error:"invalid_tab"};if(i!==void 0&&(typeof i!="string"||!$u.test(i)))return{ok:!1,error:"invalid_plan"};if(a!==void 0&&!Ui.includes(a))return{ok:!1,error:"invalid_period"};let l=(o??"membership")==="membership"&&i?`&plan=${encodeURIComponent(i)}${a?`&period=${a}`:""}`:"",c=await t.getCloud(),u=c.base;if(!u)return{ok:!1};let f=await Fi(c),g=`${u}/pay?tab=${o??"membership"}${l}${f?`&${f}`:""}&redirect=${encodeURIComponent(`${u}/account`)}`;return c.signal?.throwIfAborted(),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 a=i.status>=300&&i.status<400?i.headers.get("location"):null;return a&&/^https?:\/\//i.test(a)?{ok:!0,origin:new URL(a).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 Ue(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 a=o??"both";try{return await Ue(i,"POST","/api/token-quota/reset-card/use",{type:a},15e3)}catch(l){return{status:0,json:{detail:String(l?.message||l)}}}}),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 Ue(i,"POST","/api/token-quota/background/convert",{percent:o},15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),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 Ue(i,"POST","/api/token-quota/background/auto-main",{enabled:o},15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),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"};if(o?.expectedAccountId!==void 0){let u=o.expectedAccountId;if(typeof u!="string"||!u||Oe(i.base,i.token)!==u)return{ok:!1,error:"account-changed"}}let a=(o?.description||"").trim();if(!a)return{ok:!1,error:"empty"};if(a.length>1e4)return{ok:!1,error:"description-too-long"};let l=[],c=!1;if(o?.sessionLogJson){let u=_n(o.sessionLogJson);if(u.length>5*1024*1024)return{ok:!1,error:"attachment-too-large"};l.push({filename:o.sessionLogName||"tangu-session.json",mime_type:"application/json",size:u.length,data_base64:Pi(u)})}try{let u=await xn(i,`${i.base}/api/feedback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({description:a,attachments:l}),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: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??{},a=typeof i.path=="string"?i.path:"",l=i.projectSource===void 0?null:i.projectSource;if(l!==null&&(typeof l!="string"||!/^[a-z0-9][a-z0-9-]{0,63}$/.test(l)))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(!a.startsWith("/"))return{status:0,error:"bad_path"};let f=await t.getCloud();if(!String(f.base||""))return{status:0,error:"no_cloud_url"};let g=ht(f.base,a);if(!g)return{status:0,error:"bad_path"};if(!f.token)return{status:401,error:"not_signed_in"};let p=i.body!==void 0&&u!=="GET"&&u!=="DELETE",y=new AbortController,h=setTimeout(()=>y.abort(),c);try{let m=await xn(f,g,{method:u,headers:{...p?{"Content-Type":"application/json"}:{},...l?{"X-Project-Source":l}:{}},body:p?JSON.stringify(i.body):void 0,signal:y.signal});return{status:m.status,json:await m.json().catch(()=>null)}}catch(m){return{status:0,error:String(m?.message||m)}}finally{clearTimeout(h)}}),ji(t)}import{createHash as ca}from"node:crypto";import{existsSync as xd,promises as Ad,readFileSync as Td,renameSync as Rd}from"node:fs";import Id from"node:path";import{EventEmitter as cd}from"node:events";import{stat as ud}from"node:fs";import{readdir as dd,stat as fd}from"node:fs/promises";import*as de from"node:path";import{lstat as zi,readdir as Mu,realpath as Nu,stat as ju}from"node:fs/promises";import{join as Fu,resolve as Lu,sep as Bi}from"node:path";import{Readable as Uu}from"node:stream";var Ve={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},Zt={root:".",fileFilter:t=>!0,directoryFilter:t=>!0,type:Ve.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:256};Object.freeze(Zt);var Yi="READDIRP_RECURSIVE_ERROR",Hu=new Set(["ENOENT","EPERM","EACCES","ELOOP",Yi]),qi=[Ve.DIR_TYPE,Ve.EVERYTHING_TYPE,Ve.FILE_DIR_TYPE,Ve.FILE_TYPE],zu=new Set([Ve.DIR_TYPE,Ve.EVERYTHING_TYPE,Ve.FILE_DIR_TYPE]),Bu=new Set([Ve.EVERYTHING_TYPE,Ve.FILE_DIR_TYPE,Ve.FILE_TYPE]),qu=t=>Hu.has(t.code),Wu=process.platform==="win32",Wi=t=>!0,Vi=t=>{if(t===void 0)return Wi;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 Wi},Cs=class extends Uu{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??Zt.highWaterMark});let n={...Zt,...e},r=n.root??Zt.root,s=n.type??Zt.type;this._fileFilter=Vi(n.fileFilter),this._directoryFilter=Vi(n.directoryFilter);let o=n.lstat?zi:ju;Wu?this._stat=a=>o(a,{bigint:!0}):this._stat=o,this._maxDepth=n.depth!=null&&Number.isSafeInteger(n.depth)?n.depth:Zt.depth,this._wantsDir=zu.has(s),this._wantsFile=Bu.has(s),this._wantsEverything=s===Ve.EVERYTHING_TYPE,this._root=Lu(r),this._relStart=this._root.endsWith(Bi)?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(l=>this._formatEntry(l,s)),a=this._isDirent?i:await Promise.all(i);for(let l of a){if(!l)continue;if(this.destroyed)return;let c=this._getEntryType(l);typeof c!="string"&&(c=await c),c==="directory"&&this._directoryFilter(l)?(o<=this._maxDepth&&this.parents.push({path:l.fullPath,depth:o+1}),this._wantsDir&&(this.push(l),e--)):(c==="file"||this._includeAsFile(l))&&this._fileFilter(l)&&this._wantsFile&&(this.push(l),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 Mu(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=Fu(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){qu(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 Nu(n),s=await zi(r);if(s.isFile())return"file";if(s.isDirectory()){let o=r.length;if(n.startsWith(r)&&n[o]===Bi){let i=new Error(`Circular symlink detected: "${n}" points to "${r}"`);return i.code=Yi,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 Gi(t,e={}){let n=e.entryType||e.type;if(n==="both"&&(n=Ve.FILE_DIR_TYPE),t){if(typeof t!="string")throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");if(n&&!qi.includes(n))throw new Error(`readdirp: Invalid type passed. Use one of ${qi.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 Cs(r)}import{watch as Vu,unwatchFile as Ji,watchFile as Yu}from"node:fs";import{realpath as xs,lstat as Gu,open as Ju,stat as Xi}from"node:fs/promises";import{type as Ku}from"node:os";import*as we from"node:path";var Xu="data",Rs="end",Zi="close",Cr=()=>{};var xr=process.platform,Is=xr==="win32",Zu=xr==="darwin",Qu=xr==="linux",ed=xr==="freebsd",Qi=Ku()==="OS400",Se={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},tt=Se,td="watch",nd={lstat:Gu,stat:Xi},Ft="listeners",vr="errHandlers",Qt="rawEmitters",rd=[Ft,vr,Qt],sd=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"]),od=t=>sd.has(we.extname(t).slice(1).toLowerCase()),Ts=(t,e)=>{t instanceof Set?t.forEach(e):e(t)},An=(t,e,n)=>{let r=t[e];r instanceof Set||(t[e]=r=new Set([r])),r.add(n)},id=t=>e=>{let n=t[e];n instanceof Set?n.clear():delete t[e]},Tn=(t,e,n)=>{let r=t[e];r instanceof Set?r.delete(n):r===n&&delete t[e]},ea=t=>t instanceof Set?t.size===0:!t,kr=new Map;function Ki(t,e,n,r,s){let o=(i,a)=>{n(t),s(i,a,{watchedPath:t}),a&&t!==a&&Er(we.resolve(t,a),Ft,we.join(t,a))};try{return Vu(t,{persistent:e.persistent},o)}catch(i){r(i);return}}var Er=(t,e,n,r,s)=>{let o=kr.get(t);o&&Ts(o[e],i=>{i(n,r,s)})},ad=(t,e,n,r)=>{let{listener:s,errHandler:o,rawEmitter:i}=r,a=kr.get(e),l;if(!n.persistent)return l=Ki(t,n,s,o,i),l?l.close.bind(l):void 0;if(a)An(a,Ft,s),An(a,vr,o),An(a,Qt,i);else{if(l=Ki(t,n,Er.bind(null,e,Ft),o,Er.bind(null,e,Qt)),!l)return;l.on(tt.ERROR,async c=>{let u=Er.bind(null,e,vr);if(a&&(a.watcherUnusable=!0),Is&&c.code==="EPERM")try{await(await Ju(t,"r")).close(),u(c)}catch{}else u(c)}),a={listeners:s,errHandlers:o,rawEmitters:i,watcher:l},kr.set(e,a)}return()=>{Tn(a,Ft,s),Tn(a,vr,o),Tn(a,Qt,i),ea(a.listeners)&&(a.watcher.close(),kr.delete(e),rd.forEach(id(a)),a.watcher=void 0,Object.freeze(a))}},As=new Map,ld=(t,e,n,r)=>{let{listener:s,rawEmitter:o}=r,i=As.get(e),a=i&&i.options;return a&&(a.persistent<n.persistent||a.interval>n.interval)&&(Ji(e),i=void 0),i?(An(i,Ft,s),An(i,Qt,o)):(i={listeners:s,rawEmitters:o,options:n,watcher:Yu(e,n,(l,c)=>{Ts(i.rawEmitters,f=>{f(tt.CHANGE,e,{curr:l,prev:c})});let u=l.mtimeMs;(l.size!==c.size||u>c.mtimeMs||u===0)&&Ts(i.listeners,f=>f(t,l))})},As.set(e,i)),()=>{Tn(i,Ft,s),Tn(i,Qt,o),ea(i.listeners)&&(As.delete(e),Ji(e),i.options=i.watcher=void 0,Object.freeze(i))}},_r=class{fsw;_boundHandleError;constructor(e){this.fsw=e,this._boundHandleError=n=>e._handleError(n)}_watchWithNodeFs(e,n){let r=this.fsw.options,s=we.dirname(e),o=we.basename(e);this.fsw._getWatchedDir(s).add(o);let a=we.resolve(e),l={persistent:r.persistent};n||(n=Cr);let c;if(r.usePolling){let u=r.interval!==r.binaryInterval;l.interval=u&&od(o)?r.binaryInterval:r.interval,c=ld(e,a,l,{listener:n,rawEmitter:this.fsw._emitRaw})}else c=ad(e,a,l,{listener:n,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return c}_handleFile(e,n,r){if(this.fsw.closed)return;let s=we.dirname(e),o=we.basename(e),i=this.fsw._getWatchedDir(s),a=n;if(i.has(o))return;let l=async(u,f)=>{if(this.fsw._throttle(td,e,5)){if(!f||f.mtimeMs===0)try{let g=await Xi(e);if(this.fsw.closed)return;let p=g.atimeMs,y=g.mtimeMs;if((!p||p<=y||y!==a.mtimeMs)&&this.fsw._emit(tt.CHANGE,e,g),(Zu||Qu||ed)&&a.ino!==g.ino){this.fsw._closeFile(u),a=g;let h=this._watchWithNodeFs(e,l);h&&this.fsw._addPathCloser(u,h)}else a=g}catch{this.fsw._remove(s,o)}else if(i.has(o)){let g=f.atimeMs,p=f.mtimeMs;(!g||g<=p||p!==a.mtimeMs)&&this.fsw._emit(tt.CHANGE,e,f),a=f}}},c=this._watchWithNodeFs(e,l);if(!(r&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(e)){if(!this.fsw._throttle(tt.ADD,e,0))return;this.fsw._emit(tt.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 a;try{a=await xs(r)}catch{return this.fsw._emitReady(),!0}return this.fsw.closed?void 0:(i.has(s)?this.fsw._symlinkPaths.get(o)!==a&&(this.fsw._symlinkPaths.set(o,a),this.fsw._emit(tt.CHANGE,r,e.stats)):(i.add(s),this.fsw._symlinkPaths.set(o,a),this.fsw._emit(tt.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,a){e=we.join(e,"");let l=s?`${e}:${s}`:e;if(a=this.fsw._throttle("readdir",l,1e3),!a)return;let c=this.fsw._getWatchedDir(r.path),u=new Set,f=this.fsw._readdirp(e,{fileFilter:g=>r.filterPath(g),directoryFilter:g=>r.filterDir(g)});if(f)return f.on(Xu,async g=>{if(this.fsw.closed){f=void 0;return}let p=g.path,y=we.join(e,p);if(u.add(p),!(g.stats.isSymbolicLink()&&await this._handleSymlink(g,e,y,p))){if(this.fsw.closed){f=void 0;return}(p===s||!s&&!c.has(p))&&(this.fsw._incrReadyCount(),y=we.join(o,we.relative(o,y)),this._addToNodeFs(y,n,r,i+1))}}).on(tt.ERROR,this._boundHandleError),new Promise((g,p)=>{if(!f)return p();f.once(Rs,()=>{if(this.fsw.closed){f=void 0;return}let y=a?a.clear():!1;g(void 0),c.getChildren().filter(h=>h!==e&&!u.has(h)).forEach(h=>{this.fsw._remove(e,h)}),f=void 0,y&&this._handleRead(e,!1,r,s,o,i,a)})})}async _handleDir(e,n,r,s,o,i,a){let l=this.fsw._getWatchedDir(we.dirname(e)),c=l.has(we.basename(e));!(r&&this.fsw.options.ignoreInitial)&&!o&&!c&&this.fsw._emit(tt.ADD_DIR,e,n),l.add(we.basename(e)),this.fsw._getWatchedDir(e);let u,f,g=this.fsw.options.depth;if((g==null||s<=g)&&!this.fsw._symlinkPaths.has(a)){if(!o&&(await this._handleRead(e,r,i,o,e,s,u),this.fsw.closed))return;f=this._watchWithNodeFs(e,(p,y)=>{y&&y.mtimeMs===0||this._handleRead(p,!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 a=this.fsw._getWatchHelpers(e);r&&(a.filterPath=l=>r.filterPath(l),a.filterDir=l=>r.filterDir(l));try{let l=await nd[a.statMethod](a.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(a.watchPath,l))return i(),!1;let c=this.fsw.options.followSymlinks,u;if(l.isDirectory()){let f=we.resolve(e),g=c?await xs(e):e;if(this.fsw.closed||(u=await this._handleDir(a.watchPath,l,n,s,o,a,g),this.fsw.closed))return;f!==g&&g!==void 0&&this.fsw._symlinkPaths.set(f,g)}else if(l.isSymbolicLink()){let f=c?await xs(e):e;if(this.fsw.closed)return;let g=we.dirname(a.watchPath);if(this.fsw._getWatchedDir(g).add(a.watchPath),this.fsw._emit(tt.ADD,a.watchPath,l),u=await this._handleDir(g,l,n,s,e,a,f),this.fsw.closed)return;f!==void 0&&this.fsw._symlinkPaths.set(we.resolve(e),f)}else u=this._handleFile(a.watchPath,l,n);return i(),u&&this.fsw._addPathCloser(e,u),!1}catch(l){if(this.fsw._handleError(l))return i(),e}}};var Ds="/",pd="//",oa=".",hd="..",gd="string",md=/\\/g,ia=/\/\//g,yd=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,wd=/^\.[/\\]/;function Ar(t){return Array.isArray(t)?t:[t]}var Os=t=>typeof t=="object"&&t!==null&&!(t instanceof RegExp);function bd(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=de.relative(t.path,e);return n?!n.startsWith("..")&&!de.isAbsolute(n):!1}return!1}:()=>!1}function Sd(t){if(typeof t!="string")throw new Error("string expected");t=de.normalize(t),t=t.replace(/\\/g,"/");let e=!1;return t.startsWith("//")&&(e=!0),t=t.replace(ia,"/"),e&&(t="/"+t),t}function ta(t,e,n){let r=Sd(e);for(let s=0;s<t.length;s++){let o=t[s];if(o(r,n))return!0}return!1}function vd(t,e){if(t==null)throw new TypeError("anymatch: specify first argument");let r=Ar(t).map(s=>bd(s));return e==null?(s,o)=>ta(r,s,o):ta(r,e)}var na=t=>{let e=Ar(t).flat();if(!e.every(n=>typeof n===gd))throw new TypeError(`Non-string provided as watch path: ${e}`);return e.map(aa)},ra=t=>{let e=t.replace(md,Ds),n=!1;return e.startsWith(pd)&&(n=!0),e=e.replace(ia,Ds),n&&(e=Ds+e),e},aa=t=>ra(de.normalize(ra(t))),sa=(t="")=>e=>typeof e=="string"?aa(de.isAbsolute(e)?e:de.join(t,e)):e,kd=(t,e)=>de.isAbsolute(t)?t:de.join(e,t),Ed=Object.freeze(new Set),Ps=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!==oa&&e!==hd&&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 dd(r)}catch{this._removeWatcher&&this._removeWatcher(de.dirname(r),de.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=Cr,this.items=Ed,Object.freeze(this)}},_d="stat",Cd="lstat",$s=class{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(e,n,r){this.fsw=r;let s=e;this.path=e=e.replace(wd,""),this.watchPath=s,this.fullWatchPath=de.resolve(s),this.dirParts=[],this.dirParts.forEach(o=>{o.length>1&&o.pop()}),this.followSymlinks=n,this.statMethod=n?_d:Cd}entryPath(e){return de.join(this.watchPath,de.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)}},Tr=class extends cd{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?Ar(e.ignored):Ar([]),awaitWriteFinish:n===!0?r:typeof n=="object"?{...r,...n}:!1};Qi&&(s.usePolling=!0),s.atomic===void 0&&(s.atomic=!s.usePolling);let o=process.env.CHOKIDAR_USEPOLLING;if(o!==void 0){let l=o.toLowerCase();l==="false"||l==="0"?s.usePolling=!1:l==="true"||l==="1"?s.usePolling=!0:s.usePolling=!!l}let i=process.env.CHOKIDAR_INTERVAL;i&&(s.interval=Number.parseInt(i,10));let a=0;this._emitReady=()=>{a++,a>=this._readyCount&&(this._emitReady=Cr,this._readyEmitted=!0,process.nextTick(()=>this.emit(Se.READY)))},this._emitRaw=(...l)=>this.emit(Se.RAW,...l),this._boundRemove=this._remove.bind(this),this.options=s,this._nodeFsHandler=new _r(this),Object.freeze(s)}_addIgnoredPath(e){if(Os(e)){for(let n of this._ignoredPaths)if(Os(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)Os(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=na(e);return s&&(o=o.map(i=>kd(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 a=await this._nodeFsHandler._addToNodeFs(i,!r,void 0,0,n);return a&&this._emitReady(),a})).then(i=>{this.closed||i.forEach(a=>{a&&this.add(de.dirname(a),de.basename(n||a))})}),this}unwatch(e){if(this.closed)return this;let n=na(e),{cwd:r}=this.options;return n.forEach(s=>{!de.isAbsolute(s)&&!this._closers.has(s)&&(r&&(s=de.join(r,s)),s=de.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?de.relative(this.options.cwd,r):r)||oa;e[o]=n.getChildren().sort()}),e}emitWithAll(e,n){this.emit(e,...n),e!==Se.ERROR&&this.emit(Se.ALL,e,...n)}async _emit(e,n,r){if(this.closed)return;let s=this.options;Is&&(n=de.normalize(n)),s.cwd&&(n=de.relative(s.cwd,n));let o=[n];r!=null&&o.push(r);let i=s.awaitWriteFinish,a;if(i&&(a=this._pendingWrites.get(n)))return a.lastChange=new Date,this;if(s.atomic){if(e===Se.UNLINK)return this._pendingUnlinks.set(n,[e,...o]),setTimeout(()=>{this._pendingUnlinks.forEach((l,c)=>{this.emit(...l),this.emit(Se.ALL,...l),this._pendingUnlinks.delete(c)})},typeof s.atomic=="number"?s.atomic:100),this;e===Se.ADD&&this._pendingUnlinks.has(n)&&(e=Se.CHANGE,this._pendingUnlinks.delete(n))}if(i&&(e===Se.ADD||e===Se.CHANGE)&&this._readyEmitted){let l=(c,u)=>{c?(e=Se.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,l),this}if(e===Se.CHANGE&&!this._throttle(Se.CHANGE,n,50))return this;if(s.alwaysStat&&r===void 0&&(e===Se.ADD||e===Se.ADD_DIR||e===Se.CHANGE)){let l=s.cwd?de.join(s.cwd,n):n,c;try{c=await fd(l)}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(Se.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,a=()=>{let c=s.get(n),u=c?c.count:0;return s.delete(n),clearTimeout(i),c&&clearTimeout(c.timeoutObject),u};i=setTimeout(a,r);let l={timeoutObject:i,clear:a,count:0};return s.set(n,l),l}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(e,n,r,s){let o=this.options.awaitWriteFinish;if(typeof o!="object")return;let i=o.pollInterval,a,l=e;this.options.cwd&&!de.isAbsolute(e)&&(l=de.join(this.options.cwd,e));let c=new Date,u=this._pendingWrites;function f(g){ud(l,(p,y)=>{if(p||!u.has(e)){p&&p.code!=="ENOENT"&&s(p);return}let h=Number(new Date);g&&y.size!==g.size&&(u.get(e).lastChange=h);let m=u.get(e);h-m.lastChange>=n?(u.delete(e),s(void 0,y)):a=setTimeout(f,i,y)})}u.has(e)||(u.set(e,{lastChange:c,cancelWait:()=>(u.delete(e),clearTimeout(a),r)}),a=setTimeout(f,i))}_isIgnored(e,n){if(this.options.atomic&&yd.test(e))return!0;if(!this._userIgnored){let{cwd:r}=this.options,o=(this.options.ignored||[]).map(sa(r)),a=[...[...this._ignoredPaths].map(sa(r)),...o];this._userIgnored=vd(a,void 0)}return this._userIgnored(e,n)}_isntIgnored(e,n){return!this._isIgnored(e,n)}_getWatchHelpers(e){return new $s(e,this.options.followSymlinks,this)}_getWatchedDir(e){let n=de.resolve(e);return this._watched.has(n)||this._watched.set(n,new Ps(n,this._boundRemove)),this._watched.get(n)}_hasReadPermissions(e){return this.options.ignorePermissionErrors?!0:!!(Number(e.mode)&256)}_remove(e,n,r){let s=de.join(e,n),o=de.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 l=this._getWatchedDir(e),c=l.has(n);l.remove(n),this._symlinkPaths.has(o)&&this._symlinkPaths.delete(o);let u=s;if(this.options.cwd&&(u=de.relative(this.options.cwd,s)),this.options.awaitWriteFinish&&this._pendingWrites.has(u)&&this._pendingWrites.get(u).cancelWait()===Se.ADD)return;this._watched.delete(s),this._watched.delete(o);let f=r?Se.UNLINK_DIR:Se.UNLINK;c&&!this._isIgnored(s)&&this._emit(f,s),this._closePath(s)}_closePath(e){this._closeFile(e);let n=de.dirname(e);this._getWatchedDir(n).remove(de.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:Se.ALL,alwaysStat:!0,lstat:!0,...n,depth:0},s=Gi(e,r);return this._streams.add(s),s.once(Zi,()=>{s=void 0}),s.once(Rs,()=>{s&&(this._streams.delete(s),s=void 0)}),s}};function Ms(t,e={}){let n=new Tr(e);return n.add(t),n}var la={watch:Ms,FSWatcher:Tr};var Ns;function ua(t){Ns=t}var da={fs:Ad,path:Id,sha256Hex:t=>ca("sha256").update(t).digest("hex"),tmpTag:()=>process.pid,existsSync:xd,async compareAndReplace(t,e,n,r){if(!Ns)throw new Error("This host needs the shared content write lock for safe cloud downloads");let s=!1;return await Ns(e,()=>{if(!r())return;let o=null;try{o=ca("sha256").update(Td(e)).digest("hex")}catch(i){if(i.code!=="ENOENT")throw i}o===n&&(Rd(t,e),s=!0)}),s},watch(t,e,n){let r=la.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 Dd,lstatSync as Od,readFileSync as js,writeFileSync as Pd,realpathSync as fa}from"node:fs";import{join as Ls,extname as $d,sep as Md}from"node:path";var Fs=300,pa=5*1024*1024,ha=20*1024*1024,Nd=50*1024*1024,jd=new Set(["node_modules"]),Fd=new Set([".ts",".tsx",".jsx",".mts",".cts"]);function ga(t,e){let n=[],r=0,s=(o,i)=>{for(let a of Dd(o)){if(a.startsWith("."))continue;let l=Ls(o,a),c;try{c=Od(l)}catch{continue}if(c.isSymbolicLink())continue;let u=i?`${i}/${a}`:a;if(c.isDirectory()){jd.has(a)||s(l,u);continue}if(!c.isFile()||a.endsWith(".d.ts"))continue;if(n.length>=Fs)throw new Error(`\u6587\u4EF6\u6570\u8D85\u8FC7 ${Fs}\uFF0C\u8BF7\u7CBE\u7B80\u9879\u76EE\uFF08node_modules \u4E0E\u9690\u85CF\u6587\u4EF6\u5DF2\u81EA\u52A8\u8DF3\u8FC7\uFF09`);let f=$d(a).toLowerCase(),g,p=e.mimeOf(f)??"application/octet-stream";if(Fd.has(f)){let y=e.transpile(js(l,"utf8"),f,u);g=Buffer.from(y??"","utf8"),p="text/javascript"}else g=js(l);if(g.length>pa)throw new Error(`\u5355\u6587\u4EF6\u8D85\u8FC7 5MB\uFF1A${u}`);if(r+=g.length,r>ha)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 ma=".forsion-connect.json";function ya(t){try{return JSON.parse(js(Ls(t,ma),"utf8"))}catch{return{}}}function wa(t,e){try{Pd(Ls(t,ma),JSON.stringify(e,null,2)+`
2
- `,"utf8")}catch{}}function ba(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("?"),a=(y,h)=>{s.headersSent||(s.statusCode=y,s.setHeader("Content-Type","application/json")),s.end(JSON.stringify({detail:h}))},l=n(o);if(!l)return a(404,"unknown connect endpoint");if((r.method||"GET")!==l.method)return a(405,"method not allowed");let c="",u="";try{({base:c,token:u}=await t())}catch{}if(!c)return a(502,"\u672A\u914D\u7F6E Forsion \u4E91\u7AEF\u5730\u5740");if(l.auth&&!u)return a(401,"\u8BF7\u5148\u5728 Forsion Desktop \u4E2D\u767B\u5F55 Forsion \u8D26\u53F7");let f;if(l.method==="POST"){let y=[],h=0;try{for await(let m of r){if(h+=m.length,h>Nd)return r.destroy(),a(413,"\u8BF7\u6C42\u4F53\u8FC7\u5927");y.push(m)}}catch(m){return a(400,`\u8BF7\u6C42\u4F53\u8BFB\u53D6\u5931\u8D25\uFF1A${m?.message||String(m)}`)}f=Buffer.concat(y)}if(l.agentRun){let y;try{y=JSON.parse((f||Buffer.alloc(0)).toString("utf8")||"{}")}catch{return a(400,"agent \u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON")}f=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")),l.timeoutMs??3e5);r.on("close",()=>g.abort());try{let y=await fetch(c+l.path+(i?`?${i}`:""),{method:l.method,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...u?{Authorization:`Bearer ${u}`}:{}},body:f&&f.length?new Uint8Array(f):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 h of y.body)s.write(h);s.end()}catch(y){let h=`\u4E91\u7AEF\u8BF7\u6C42\u4E2D\u65AD\uFF1A${y?.message||String(y)}`;if(s.headersSent){try{s.write(`data: ${JSON.stringify({error:h})}
1
+ var ks=null;function Mi(t){ks=t}function Ce(){if(!ks)throw new Error("core host not set (call setCoreHost first)");return ks}var $i=new TextEncoder,$u=new TextDecoder("utf-8",{ignoreBOM:!0}),_n=t=>$i.encode(t),_t=t=>$u.decode(t),Es=t=>typeof t=="string"?$i.encode(t).length:t.length;function Ni(t){let e="";for(let n=0;n<t.length;n+=32768)e+=String.fromCharCode(...t.subarray(n,n+32768));return btoa(e)}function wr(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 ji(t){let e=new Blob([t]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response(e).arrayBuffer())}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),c=>c.charCodeAt(0)),i=JSON.parse(new TextDecoder().decode(o)),a=i.userId??i.sub;return typeof a!="string"&&typeof a!="number"||!String(a).trim()?null:`${n.origin}${n.pathname.replace(/\/+$/,"")}::${String(a)}`}catch{return null}}function _s(t){try{let e=t.split(".")[1];if(!e)return null;let n=JSON.parse(_t(wr(e)));return n&&typeof n=="object"?n:null}catch{return null}}function Cs(t,e=Date.now()){let n=_s(t)?.iat;return typeof n=="number"?e-n*1e3:1/0}function Fi(t,e=Date.now()){let n=_s(t)?.exp;return typeof n=="number"?n*1e3-e:1/0}var Nu=36e5;function br(t,e=Date.now()){return!!t&&Cs(t,e)>=Nu}async function Sr(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),a=typeof i?.token=="string"?i.token:"";return a&&a!==e?a:null}catch{return null}}var Cn=(t,e)=>`${t.replace(/\/+$/,"")}\0${e}`,ju=(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 Li(t,e){let n=d=>e.write(JSON.stringify(d,null,2)),r=()=>{let d;try{d=e.read()}catch(g){return g?.code==="ENOENT"?[]:null}if(d===null)return[];try{let g=JSON.parse(d);return Array.isArray(g.accounts)?g.accounts.filter(p=>p&&typeof p.token=="string"&&p.id===Oe(p.cloudUrl,p.token)):null}catch{return null}},s=(d,g)=>{let p=Oe(d.cloudUrl||"",d.token||"");if(!p||!d.token||!d.cloudUrl)return;let y=r();if(!y)return;let h=y.find(_=>_.id===p),m=_s(d.token),w={...h,id:p,cloudUrl:d.cloudUrl.replace(/\/+$/,""),token:d.token,username:g?.username||h?.username||m?.username,nickname:g?.nickname||h?.nickname};JSON.stringify(h)!==JSON.stringify(w)&&n({version:1,accounts:[...y.filter(_=>_.id!==p),w]})},o=()=>{let d=t.readCreds();s(d);let g=Oe(d.cloudUrl,d.token);return(r()??[]).map(({token:p,...y})=>({...y,active:y.id===g}))},i=d=>{let g=r()?.find(p=>p.id===d);if(!g)throw new Error("Account is no longer signed in. Sign in again.");return{cloudUrl:g.cloudUrl,token:g.token}},a=d=>{let g=Oe(d.cloudUrl||"",d.token||""),p=r();g&&p&&n({version:1,accounts:p.filter(y=>y.id!==g)})},c=null;return{rememberForsionAccount:s,forsionAccounts:o,savedForsionAccount:i,forgetForsionAccount:a,cancelForsionLogin:()=>{c?.abort(),c=null},forsionDeviceLogin:async(d,g,p)=>{if(c)throw new Error("A sign-in is already in progress.");if(!d)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;c=y;let h=()=>{if(y.signal.aborted||c!==y)throw new Error("Sign-in cancelled.")};try{let m=d.replace(/\/+$/,""),w;try{w=await fetch(`${m}/api/auth/cli/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:"{}",signal:AbortSignal.any([y.signal,AbortSignal.timeout(15e3)])}).then(C=>C.json())}catch(C){throw new Error(`\u65E0\u6CD5\u8FDE\u63A5 ${m}:${C?.message||C}`)}if(h(),!w?.device_code)throw new Error("\u4E91\u7AEF\u4E0D\u652F\u6301 CLI \u767B\u5F55(/api/auth/cli/start \u8FD4\u56DE\u5F02\u5E38)");let _=w.verification_uri_complete||`${w.verification_uri}?code=${w.user_code}`,M=new URL(`${m}/auth`);M.searchParams.set("logout","1"),M.searchParams.set("app","forsion-desktop"),M.searchParams.set("redirect",_);let R=M.toString();g?.({url:R,userCode:String(w.user_code||"")}),t.openExternal(R);let O=Date.now()+(w.expires_in||600)*1e3,S=(w.interval||2)*1e3;for(;Date.now()<O;){await ju(S,y.signal),h();let C=null;try{C=await fetch(`${m}/api/auth/cli/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_code:w.device_code}),signal:AbortSignal.any([y.signal,AbortSignal.timeout(15e3)])})}catch{h();continue}if(h(),C.status===410)throw new Error("\u767B\u5F55\u7801\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u53D1\u8D77\u767B\u5F55");let E=await C.json().catch(()=>({status:"pending"}));if(h(),E.status==="approved"&&E.token){let I={cloudUrl:m,token:E.token};return await p(I,h),h(),{token:E.token,cloudUrl:m}}}throw new Error("\u767B\u5F55\u8D85\u65F6,\u8BF7\u91CD\u8BD5")}finally{c===y&&(c=null)}},readAccounts:()=>r()??[]}}function ht(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 xn(t,e,n){return t.fetch?t.fetch(e,n):fetch(e,{...n,headers:{Authorization:`Bearer ${t.token}`,...n.headers}})}async function Ue(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 Fu=50*1024*1024,Lu=new Set(["mode","type","source","name","summary","githubRepoUrl","npmPackage","version","readme","description","tags","minAppVersion","maxAppVersion","platforms"]);function Uu(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(!Lu.has(s)||typeof o!="string"||(r+=o.length,r>25e4)||e.id&&!["mode","name","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>Fu)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"}${e.dryRun===!0?"?dryRun=1":""}`,body:n}}function Ui(t){t.handle("cloud:marketSubmit",async(e,n)=>{if(!t.isTrustedSender(e))return{status:0,error:"untrusted"};let r=Uu(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=ht(s.base,r.path);if(!o)return{status:0,error:"no_cloud_url"};try{let i=await xn(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 Hi(t){if(!t.token)return"";try{let e=await Ue(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 zi=["membership","credits","storefront"],Bi=["monthly","quarterly","yearly"],Hu=/^[A-Za-z0-9_-]{1,64}$/;function qi(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(),a=i.base;if(!a)return{ok:!1};let c=o&&/^[a-z0-9-]+$/i.test(o)?`#${o}`:"",l=await Hi(i),u=`${a}/account${l?`?${l}`:""}${c}`;return i.signal?.throwIfAborted(),await t.openExternal(u),{ok:!0}}),t.handle("auth:openPayCenter",async(s,o,i,a)=>{if(!t.isTrustedSender(s))return n;if(o!==void 0&&!zi.includes(o))return{ok:!1,error:"invalid_tab"};if(i!==void 0&&(typeof i!="string"||!Hu.test(i)))return{ok:!1,error:"invalid_plan"};if(a!==void 0&&!Bi.includes(a))return{ok:!1,error:"invalid_period"};let c=(o??"membership")==="membership"&&i?`&plan=${encodeURIComponent(i)}${a?`&period=${a}`:""}`:"",l=await t.getCloud(),u=l.base;if(!u)return{ok:!1};let d=await Hi(l),g=`${u}/pay?tab=${o??"membership"}${c}${d?`&${d}`:""}&redirect=${encodeURIComponent(`${u}/account`)}`;return l.signal?.throwIfAborted(),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 a=i.status>=300&&i.status<400?i.headers.get("location"):null;return a&&/^https?:\/\//i.test(a)?{ok:!0,origin:new URL(a).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 Ue(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 a=o??"both";try{return await Ue(i,"POST","/api/token-quota/reset-card/use",{type:a},15e3)}catch(c){return{status:0,json:{detail:String(c?.message||c)}}}}),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 Ue(i,"POST","/api/token-quota/background/convert",{percent:o},15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),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 Ue(i,"POST","/api/token-quota/background/auto-main",{enabled:o},15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),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"};if(o?.expectedAccountId!==void 0){let u=o.expectedAccountId;if(typeof u!="string"||!u||Oe(i.base,i.token)!==u)return{ok:!1,error:"account-changed"}}let a=(o?.description||"").trim();if(!a)return{ok:!1,error:"empty"};if(a.length>1e4)return{ok:!1,error:"description-too-long"};let c=[],l=!1;if(o?.sessionLogJson){let u=_n(o.sessionLogJson);if(u.length>5*1024*1024)return{ok:!1,error:"attachment-too-large"};c.push({filename:o.sessionLogName||"tangu-session.json",mime_type:"application/json",size:u.length,data_base64:Ni(u)})}try{let u=await xn(i,`${i.base}/api/feedback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({description:a,attachments:c}),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:l}}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??{},a=typeof i.path=="string"?i.path:"",c=i.projectSource===void 0?null:i.projectSource;if(c!==null&&(typeof c!="string"||!/^[a-z0-9][a-z0-9-]{0,63}$/.test(c)))return{status:0,error:"bad_project_source"};let l=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(!a.startsWith("/"))return{status:0,error:"bad_path"};let d=await t.getCloud();if(!String(d.base||""))return{status:0,error:"no_cloud_url"};let g=ht(d.base,a);if(!g)return{status:0,error:"bad_path"};if(!d.token)return{status:401,error:"not_signed_in"};let p=i.body!==void 0&&u!=="GET"&&u!=="DELETE",y=new AbortController,h=setTimeout(()=>y.abort(),l);try{let m=await xn(d,g,{method:u,headers:{...p?{"Content-Type":"application/json"}:{},...c?{"X-Project-Source":c}:{}},body:p?JSON.stringify(i.body):void 0,signal:y.signal});return{status:m.status,json:await m.json().catch(()=>null)}}catch(m){return{status:0,error:String(m?.message||m)}}finally{clearTimeout(h)}}),Ui(t)}import{createHash as fa}from"node:crypto";import{existsSync as Pd,promises as Md,readFileSync as $d,renameSync as Nd}from"node:fs";import jd from"node:path";import{EventEmitter as md}from"node:events";import{stat as yd}from"node:fs";import{readdir as wd,stat as bd}from"node:fs/promises";import*as de from"node:path";import{lstat as Wi,readdir as zu,realpath as Bu,stat as qu}from"node:fs/promises";import{join as Wu,resolve as Vu,sep as Vi}from"node:path";import{Readable as Yu}from"node:stream";var Ve={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},Zt={root:".",fileFilter:t=>!0,directoryFilter:t=>!0,type:Ve.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:256};Object.freeze(Zt);var Ki="READDIRP_RECURSIVE_ERROR",Gu=new Set(["ENOENT","EPERM","EACCES","ELOOP",Ki]),Yi=[Ve.DIR_TYPE,Ve.EVERYTHING_TYPE,Ve.FILE_DIR_TYPE,Ve.FILE_TYPE],Ju=new Set([Ve.DIR_TYPE,Ve.EVERYTHING_TYPE,Ve.FILE_DIR_TYPE]),Ku=new Set([Ve.EVERYTHING_TYPE,Ve.FILE_DIR_TYPE,Ve.FILE_TYPE]),Xu=t=>Gu.has(t.code),Zu=process.platform==="win32",Gi=t=>!0,Ji=t=>{if(t===void 0)return Gi;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 Gi},xs=class extends Yu{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??Zt.highWaterMark});let n={...Zt,...e},r=n.root??Zt.root,s=n.type??Zt.type;this._fileFilter=Ji(n.fileFilter),this._directoryFilter=Ji(n.directoryFilter);let o=n.lstat?Wi:qu;Zu?this._stat=a=>o(a,{bigint:!0}):this._stat=o,this._maxDepth=n.depth!=null&&Number.isSafeInteger(n.depth)?n.depth:Zt.depth,this._wantsDir=Ju.has(s),this._wantsFile=Ku.has(s),this._wantsEverything=s===Ve.EVERYTHING_TYPE,this._root=Vu(r),this._relStart=this._root.endsWith(Vi)?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(c=>this._formatEntry(c,s)),a=this._isDirent?i:await Promise.all(i);for(let c of a){if(!c)continue;if(this.destroyed)return;let l=this._getEntryType(c);typeof l!="string"&&(l=await l),l==="directory"&&this._directoryFilter(c)?(o<=this._maxDepth&&this.parents.push({path:c.fullPath,depth:o+1}),this._wantsDir&&(this.push(c),e--)):(l==="file"||this._includeAsFile(c))&&this._fileFilter(c)&&this._wantsFile&&(this.push(c),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 zu(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=Wu(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){Xu(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 Bu(n),s=await Wi(r);if(s.isFile())return"file";if(s.isDirectory()){let o=r.length;if(n.startsWith(r)&&n[o]===Vi){let i=new Error(`Circular symlink detected: "${n}" points to "${r}"`);return i.code=Ki,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 Xi(t,e={}){let n=e.entryType||e.type;if(n==="both"&&(n=Ve.FILE_DIR_TYPE),t){if(typeof t!="string")throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");if(n&&!Yi.includes(n))throw new Error(`readdirp: Invalid type passed. Use one of ${Yi.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 xs(r)}import{watch as Qu,unwatchFile as Zi,watchFile as ed}from"node:fs";import{realpath as As,lstat as td,open as nd,stat as ea}from"node:fs/promises";import{type as rd}from"node:os";import*as we from"node:path";var sd="data",Is="end",ta="close",Cr=()=>{};var xr=process.platform,Ds=xr==="win32",od=xr==="darwin",id=xr==="linux",ad=xr==="freebsd",na=rd()==="OS400",Se={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},tt=Se,cd="watch",ld={lstat:td,stat:ea},Ft="listeners",vr="errHandlers",Qt="rawEmitters",ud=[Ft,vr,Qt],dd=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"]),fd=t=>dd.has(we.extname(t).slice(1).toLowerCase()),Rs=(t,e)=>{t instanceof Set?t.forEach(e):e(t)},An=(t,e,n)=>{let r=t[e];r instanceof Set||(t[e]=r=new Set([r])),r.add(n)},pd=t=>e=>{let n=t[e];n instanceof Set?n.clear():delete t[e]},Tn=(t,e,n)=>{let r=t[e];r instanceof Set?r.delete(n):r===n&&delete t[e]},ra=t=>t instanceof Set?t.size===0:!t,kr=new Map;function Qi(t,e,n,r,s){let o=(i,a)=>{n(t),s(i,a,{watchedPath:t}),a&&t!==a&&Er(we.resolve(t,a),Ft,we.join(t,a))};try{return Qu(t,{persistent:e.persistent},o)}catch(i){r(i);return}}var Er=(t,e,n,r,s)=>{let o=kr.get(t);o&&Rs(o[e],i=>{i(n,r,s)})},hd=(t,e,n,r)=>{let{listener:s,errHandler:o,rawEmitter:i}=r,a=kr.get(e),c;if(!n.persistent)return c=Qi(t,n,s,o,i),c?c.close.bind(c):void 0;if(a)An(a,Ft,s),An(a,vr,o),An(a,Qt,i);else{if(c=Qi(t,n,Er.bind(null,e,Ft),o,Er.bind(null,e,Qt)),!c)return;c.on(tt.ERROR,async l=>{let u=Er.bind(null,e,vr);if(a&&(a.watcherUnusable=!0),Ds&&l.code==="EPERM")try{await(await nd(t,"r")).close(),u(l)}catch{}else u(l)}),a={listeners:s,errHandlers:o,rawEmitters:i,watcher:c},kr.set(e,a)}return()=>{Tn(a,Ft,s),Tn(a,vr,o),Tn(a,Qt,i),ra(a.listeners)&&(a.watcher.close(),kr.delete(e),ud.forEach(pd(a)),a.watcher=void 0,Object.freeze(a))}},Ts=new Map,gd=(t,e,n,r)=>{let{listener:s,rawEmitter:o}=r,i=Ts.get(e),a=i&&i.options;return a&&(a.persistent<n.persistent||a.interval>n.interval)&&(Zi(e),i=void 0),i?(An(i,Ft,s),An(i,Qt,o)):(i={listeners:s,rawEmitters:o,options:n,watcher:ed(e,n,(c,l)=>{Rs(i.rawEmitters,d=>{d(tt.CHANGE,e,{curr:c,prev:l})});let u=c.mtimeMs;(c.size!==l.size||u>l.mtimeMs||u===0)&&Rs(i.listeners,d=>d(t,c))})},Ts.set(e,i)),()=>{Tn(i,Ft,s),Tn(i,Qt,o),ra(i.listeners)&&(Ts.delete(e),Zi(e),i.options=i.watcher=void 0,Object.freeze(i))}},_r=class{fsw;_boundHandleError;constructor(e){this.fsw=e,this._boundHandleError=n=>e._handleError(n)}_watchWithNodeFs(e,n){let r=this.fsw.options,s=we.dirname(e),o=we.basename(e);this.fsw._getWatchedDir(s).add(o);let a=we.resolve(e),c={persistent:r.persistent};n||(n=Cr);let l;if(r.usePolling){let u=r.interval!==r.binaryInterval;c.interval=u&&fd(o)?r.binaryInterval:r.interval,l=gd(e,a,c,{listener:n,rawEmitter:this.fsw._emitRaw})}else l=hd(e,a,c,{listener:n,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return l}_handleFile(e,n,r){if(this.fsw.closed)return;let s=we.dirname(e),o=we.basename(e),i=this.fsw._getWatchedDir(s),a=n;if(i.has(o))return;let c=async(u,d)=>{if(this.fsw._throttle(cd,e,5)){if(!d||d.mtimeMs===0)try{let g=await ea(e);if(this.fsw.closed)return;let p=g.atimeMs,y=g.mtimeMs;if((!p||p<=y||y!==a.mtimeMs)&&this.fsw._emit(tt.CHANGE,e,g),(od||id||ad)&&a.ino!==g.ino){this.fsw._closeFile(u),a=g;let h=this._watchWithNodeFs(e,c);h&&this.fsw._addPathCloser(u,h)}else a=g}catch{this.fsw._remove(s,o)}else if(i.has(o)){let g=d.atimeMs,p=d.mtimeMs;(!g||g<=p||p!==a.mtimeMs)&&this.fsw._emit(tt.CHANGE,e,d),a=d}}},l=this._watchWithNodeFs(e,c);if(!(r&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(e)){if(!this.fsw._throttle(tt.ADD,e,0))return;this.fsw._emit(tt.ADD,e,n)}return l}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 a;try{a=await As(r)}catch{return this.fsw._emitReady(),!0}return this.fsw.closed?void 0:(i.has(s)?this.fsw._symlinkPaths.get(o)!==a&&(this.fsw._symlinkPaths.set(o,a),this.fsw._emit(tt.CHANGE,r,e.stats)):(i.add(s),this.fsw._symlinkPaths.set(o,a),this.fsw._emit(tt.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,a){e=we.join(e,"");let c=s?`${e}:${s}`:e;if(a=this.fsw._throttle("readdir",c,1e3),!a)return;let l=this.fsw._getWatchedDir(r.path),u=new Set,d=this.fsw._readdirp(e,{fileFilter:g=>r.filterPath(g),directoryFilter:g=>r.filterDir(g)});if(d)return d.on(sd,async g=>{if(this.fsw.closed){d=void 0;return}let p=g.path,y=we.join(e,p);if(u.add(p),!(g.stats.isSymbolicLink()&&await this._handleSymlink(g,e,y,p))){if(this.fsw.closed){d=void 0;return}(p===s||!s&&!l.has(p))&&(this.fsw._incrReadyCount(),y=we.join(o,we.relative(o,y)),this._addToNodeFs(y,n,r,i+1))}}).on(tt.ERROR,this._boundHandleError),new Promise((g,p)=>{if(!d)return p();d.once(Is,()=>{if(this.fsw.closed){d=void 0;return}let y=a?a.clear():!1;g(void 0),l.getChildren().filter(h=>h!==e&&!u.has(h)).forEach(h=>{this.fsw._remove(e,h)}),d=void 0,y&&this._handleRead(e,!1,r,s,o,i,a)})})}async _handleDir(e,n,r,s,o,i,a){let c=this.fsw._getWatchedDir(we.dirname(e)),l=c.has(we.basename(e));!(r&&this.fsw.options.ignoreInitial)&&!o&&!l&&this.fsw._emit(tt.ADD_DIR,e,n),c.add(we.basename(e)),this.fsw._getWatchedDir(e);let u,d,g=this.fsw.options.depth;if((g==null||s<=g)&&!this.fsw._symlinkPaths.has(a)){if(!o&&(await this._handleRead(e,r,i,o,e,s,u),this.fsw.closed))return;d=this._watchWithNodeFs(e,(p,y)=>{y&&y.mtimeMs===0||this._handleRead(p,!1,i,o,e,s,u)})}return d}async _addToNodeFs(e,n,r,s,o){let i=this.fsw._emitReady;if(this.fsw._isIgnored(e)||this.fsw.closed)return i(),!1;let a=this.fsw._getWatchHelpers(e);r&&(a.filterPath=c=>r.filterPath(c),a.filterDir=c=>r.filterDir(c));try{let c=await ld[a.statMethod](a.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(a.watchPath,c))return i(),!1;let l=this.fsw.options.followSymlinks,u;if(c.isDirectory()){let d=we.resolve(e),g=l?await As(e):e;if(this.fsw.closed||(u=await this._handleDir(a.watchPath,c,n,s,o,a,g),this.fsw.closed))return;d!==g&&g!==void 0&&this.fsw._symlinkPaths.set(d,g)}else if(c.isSymbolicLink()){let d=l?await As(e):e;if(this.fsw.closed)return;let g=we.dirname(a.watchPath);if(this.fsw._getWatchedDir(g).add(a.watchPath),this.fsw._emit(tt.ADD,a.watchPath,c),u=await this._handleDir(g,c,n,s,e,a,d),this.fsw.closed)return;d!==void 0&&this.fsw._symlinkPaths.set(we.resolve(e),d)}else u=this._handleFile(a.watchPath,c,n);return i(),u&&this.fsw._addPathCloser(e,u),!1}catch(c){if(this.fsw._handleError(c))return i(),e}}};var Os="/",Sd="//",ca=".",vd="..",kd="string",Ed=/\\/g,la=/\/\//g,_d=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,Cd=/^\.[/\\]/;function Ar(t){return Array.isArray(t)?t:[t]}var Ps=t=>typeof t=="object"&&t!==null&&!(t instanceof RegExp);function xd(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=de.relative(t.path,e);return n?!n.startsWith("..")&&!de.isAbsolute(n):!1}return!1}:()=>!1}function Ad(t){if(typeof t!="string")throw new Error("string expected");t=de.normalize(t),t=t.replace(/\\/g,"/");let e=!1;return t.startsWith("//")&&(e=!0),t=t.replace(la,"/"),e&&(t="/"+t),t}function sa(t,e,n){let r=Ad(e);for(let s=0;s<t.length;s++){let o=t[s];if(o(r,n))return!0}return!1}function Td(t,e){if(t==null)throw new TypeError("anymatch: specify first argument");let r=Ar(t).map(s=>xd(s));return e==null?(s,o)=>sa(r,s,o):sa(r,e)}var oa=t=>{let e=Ar(t).flat();if(!e.every(n=>typeof n===kd))throw new TypeError(`Non-string provided as watch path: ${e}`);return e.map(ua)},ia=t=>{let e=t.replace(Ed,Os),n=!1;return e.startsWith(Sd)&&(n=!0),e=e.replace(la,Os),n&&(e=Os+e),e},ua=t=>ia(de.normalize(ia(t))),aa=(t="")=>e=>typeof e=="string"?ua(de.isAbsolute(e)?e:de.join(t,e)):e,Rd=(t,e)=>de.isAbsolute(t)?t:de.join(e,t),Id=Object.freeze(new Set),Ms=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!==ca&&e!==vd&&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 wd(r)}catch{this._removeWatcher&&this._removeWatcher(de.dirname(r),de.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=Cr,this.items=Id,Object.freeze(this)}},Dd="stat",Od="lstat",$s=class{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(e,n,r){this.fsw=r;let s=e;this.path=e=e.replace(Cd,""),this.watchPath=s,this.fullWatchPath=de.resolve(s),this.dirParts=[],this.dirParts.forEach(o=>{o.length>1&&o.pop()}),this.followSymlinks=n,this.statMethod=n?Dd:Od}entryPath(e){return de.join(this.watchPath,de.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)}},Tr=class extends md{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?Ar(e.ignored):Ar([]),awaitWriteFinish:n===!0?r:typeof n=="object"?{...r,...n}:!1};na&&(s.usePolling=!0),s.atomic===void 0&&(s.atomic=!s.usePolling);let o=process.env.CHOKIDAR_USEPOLLING;if(o!==void 0){let c=o.toLowerCase();c==="false"||c==="0"?s.usePolling=!1:c==="true"||c==="1"?s.usePolling=!0:s.usePolling=!!c}let i=process.env.CHOKIDAR_INTERVAL;i&&(s.interval=Number.parseInt(i,10));let a=0;this._emitReady=()=>{a++,a>=this._readyCount&&(this._emitReady=Cr,this._readyEmitted=!0,process.nextTick(()=>this.emit(Se.READY)))},this._emitRaw=(...c)=>this.emit(Se.RAW,...c),this._boundRemove=this._remove.bind(this),this.options=s,this._nodeFsHandler=new _r(this),Object.freeze(s)}_addIgnoredPath(e){if(Ps(e)){for(let n of this._ignoredPaths)if(Ps(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)Ps(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=oa(e);return s&&(o=o.map(i=>Rd(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 a=await this._nodeFsHandler._addToNodeFs(i,!r,void 0,0,n);return a&&this._emitReady(),a})).then(i=>{this.closed||i.forEach(a=>{a&&this.add(de.dirname(a),de.basename(n||a))})}),this}unwatch(e){if(this.closed)return this;let n=oa(e),{cwd:r}=this.options;return n.forEach(s=>{!de.isAbsolute(s)&&!this._closers.has(s)&&(r&&(s=de.join(r,s)),s=de.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?de.relative(this.options.cwd,r):r)||ca;e[o]=n.getChildren().sort()}),e}emitWithAll(e,n){this.emit(e,...n),e!==Se.ERROR&&this.emit(Se.ALL,e,...n)}async _emit(e,n,r){if(this.closed)return;let s=this.options;Ds&&(n=de.normalize(n)),s.cwd&&(n=de.relative(s.cwd,n));let o=[n];r!=null&&o.push(r);let i=s.awaitWriteFinish,a;if(i&&(a=this._pendingWrites.get(n)))return a.lastChange=new Date,this;if(s.atomic){if(e===Se.UNLINK)return this._pendingUnlinks.set(n,[e,...o]),setTimeout(()=>{this._pendingUnlinks.forEach((c,l)=>{this.emit(...c),this.emit(Se.ALL,...c),this._pendingUnlinks.delete(l)})},typeof s.atomic=="number"?s.atomic:100),this;e===Se.ADD&&this._pendingUnlinks.has(n)&&(e=Se.CHANGE,this._pendingUnlinks.delete(n))}if(i&&(e===Se.ADD||e===Se.CHANGE)&&this._readyEmitted){let c=(l,u)=>{l?(e=Se.ERROR,o[0]=l,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,c),this}if(e===Se.CHANGE&&!this._throttle(Se.CHANGE,n,50))return this;if(s.alwaysStat&&r===void 0&&(e===Se.ADD||e===Se.ADD_DIR||e===Se.CHANGE)){let c=s.cwd?de.join(s.cwd,n):n,l;try{l=await bd(c)}catch{}if(!l||this.closed)return;o.push(l)}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(Se.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,a=()=>{let l=s.get(n),u=l?l.count:0;return s.delete(n),clearTimeout(i),l&&clearTimeout(l.timeoutObject),u};i=setTimeout(a,r);let c={timeoutObject:i,clear:a,count:0};return s.set(n,c),c}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(e,n,r,s){let o=this.options.awaitWriteFinish;if(typeof o!="object")return;let i=o.pollInterval,a,c=e;this.options.cwd&&!de.isAbsolute(e)&&(c=de.join(this.options.cwd,e));let l=new Date,u=this._pendingWrites;function d(g){yd(c,(p,y)=>{if(p||!u.has(e)){p&&p.code!=="ENOENT"&&s(p);return}let h=Number(new Date);g&&y.size!==g.size&&(u.get(e).lastChange=h);let m=u.get(e);h-m.lastChange>=n?(u.delete(e),s(void 0,y)):a=setTimeout(d,i,y)})}u.has(e)||(u.set(e,{lastChange:l,cancelWait:()=>(u.delete(e),clearTimeout(a),r)}),a=setTimeout(d,i))}_isIgnored(e,n){if(this.options.atomic&&_d.test(e))return!0;if(!this._userIgnored){let{cwd:r}=this.options,o=(this.options.ignored||[]).map(aa(r)),a=[...[...this._ignoredPaths].map(aa(r)),...o];this._userIgnored=Td(a,void 0)}return this._userIgnored(e,n)}_isntIgnored(e,n){return!this._isIgnored(e,n)}_getWatchHelpers(e){return new $s(e,this.options.followSymlinks,this)}_getWatchedDir(e){let n=de.resolve(e);return this._watched.has(n)||this._watched.set(n,new Ms(n,this._boundRemove)),this._watched.get(n)}_hasReadPermissions(e){return this.options.ignorePermissionErrors?!0:!!(Number(e.mode)&256)}_remove(e,n,r){let s=de.join(e,n),o=de.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 c=this._getWatchedDir(e),l=c.has(n);c.remove(n),this._symlinkPaths.has(o)&&this._symlinkPaths.delete(o);let u=s;if(this.options.cwd&&(u=de.relative(this.options.cwd,s)),this.options.awaitWriteFinish&&this._pendingWrites.has(u)&&this._pendingWrites.get(u).cancelWait()===Se.ADD)return;this._watched.delete(s),this._watched.delete(o);let d=r?Se.UNLINK_DIR:Se.UNLINK;l&&!this._isIgnored(s)&&this._emit(d,s),this._closePath(s)}_closePath(e){this._closeFile(e);let n=de.dirname(e);this._getWatchedDir(n).remove(de.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:Se.ALL,alwaysStat:!0,lstat:!0,...n,depth:0},s=Xi(e,r);return this._streams.add(s),s.once(ta,()=>{s=void 0}),s.once(Is,()=>{s&&(this._streams.delete(s),s=void 0)}),s}};function Ns(t,e={}){let n=new Tr(e);return n.add(t),n}var da={watch:Ns,FSWatcher:Tr};var js;function pa(t){js=t}var ha={fs:Md,path:jd,sha256Hex:t=>fa("sha256").update(t).digest("hex"),tmpTag:()=>process.pid,existsSync:Pd,async compareAndReplace(t,e,n,r){if(!js)throw new Error("This host needs the shared content write lock for safe cloud downloads");let s=!1;return await js(e,()=>{if(!r())return;let o=null;try{o=fa("sha256").update($d(e)).digest("hex")}catch(i){if(i.code!=="ENOENT")throw i}o===n&&(Nd(t,e),s=!0)}),s},watch(t,e,n){let r=da.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 Fd,lstatSync as Us,readFileSync as Hs,writeFileSync as Ld,realpathSync as ga,opendirSync as Ud,openSync as Hd,fstatSync as zd,readSync as Bd,closeSync as qd,constants as Fs}from"node:fs";import{join as Rr,extname as ma,sep as Wd}from"node:path";var zs=300,ya=5*1024*1024,wa=20*1024*1024,Vd=50*1024*1024,ba=new Set(["node_modules"]),Yd=new Set([".ts",".tsx",".jsx",".mts",".cts"]);function Sa(t,e){let n=[],r=0,s=(o,i)=>{for(let a of Fd(o)){if(a.startsWith("."))continue;let c=Rr(o,a),l;try{l=Us(c)}catch{continue}if(l.isSymbolicLink())continue;let u=i?`${i}/${a}`:a;if(l.isDirectory()){ba.has(a)||s(c,u);continue}if(!l.isFile()||a.endsWith(".d.ts"))continue;if(n.length>=zs)throw new Error(`\u6587\u4EF6\u6570\u8D85\u8FC7 ${zs}\uFF0C\u8BF7\u7CBE\u7B80\u9879\u76EE\uFF08node_modules \u4E0E\u9690\u85CF\u6587\u4EF6\u5DF2\u81EA\u52A8\u8DF3\u8FC7\uFF09`);let d=ma(a).toLowerCase(),g,p=e.mimeOf(d)??"application/octet-stream";if(Yd.has(d)){let y=e.transpile(Hs(c,"utf8"),d,u);g=Buffer.from(y??"","utf8"),p="text/javascript"}else g=Hs(c);if(g.length>ya)throw new Error(`\u5355\u6587\u4EF6\u8D85\u8FC7 5MB\uFF1A${u}`);if(r+=g.length,r>wa)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 va=".forsion-connect.json";function ka(t){try{return JSON.parse(Hs(Rr(t,va),"utf8"))}catch{return{}}}function Ea(t,e){try{Ld(Rr(t,va),JSON.stringify(e,null,2)+`
2
+ `,"utf8")}catch{}}var Gd=new Set([".html",".htm",".js",".mjs",".cjs",".ts",".tsx",".jsx",".mts",".cts",".vue",".svelte"]),Jd=400,Kd=5e3,Ls=2*1024*1024,Xd=12,Zd=/\bforsion\.ai\.(chat|generateImage|agent|status)\b/g;function _a(t){try{if(!Us(t).isDirectory())return null}catch{return null}let e=!1,n=new Set,r=0,s=0,o=null,i=c=>{let l;try{l=Hd(c,Fs.O_RDONLY|(Fs.O_NOFOLLOW||0)|(Fs.O_NONBLOCK||0))}catch{return null}try{if(!zd(l).isFile())return null;o??=Buffer.allocUnsafe(Ls+1);let u=0;for(;u<o.length;){let d=Bd(l,o,u,o.length-u,null);if(d<=0)break;u+=d}return u>Ls?null:o.toString("utf8",0,u)}catch{return null}finally{try{qd(l)}catch{}}},a=(c,l)=>{let u;try{u=Ud(c)}catch{return}try{for(;;){if(r>=Jd||s>=Kd)return;let d;try{d=u.readSync()}catch{return}if(!d)return;s++;let g=d.name;if(g.startsWith(".")||ba.has(g))continue;let p=Rr(c,g),y;try{y=Us(p)}catch{continue}if(y.isSymbolicLink())continue;if(y.isDirectory()){l<Xd&&a(p,l+1);continue}if(!y.isFile()||y.size>Ls||!Gd.has(ma(g).toLowerCase()))continue;r++;let h=i(p);if(h!==null){!e&&h.includes("forsion-connect.js")&&(e=!0);for(let m of h.matchAll(Zd))n.add(`forsion.ai.${m[1]}`)}}}finally{try{u.closeSync()}catch{}}};return a(t,0),{usesSdk:e,sdkMethods:[...n].sort()}}function Ca(t){let e=ka(t),n=_a(t);return n?{...e,...n}:e}function xa(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("?"),a=(y,h)=>{s.headersSent||(s.statusCode=y,s.setHeader("Content-Type","application/json")),s.end(JSON.stringify({detail:h}))},c=n(o);if(!c)return a(404,"unknown connect endpoint");if((r.method||"GET")!==c.method)return a(405,"method not allowed");let l="",u="";try{({base:l,token:u}=await t())}catch{}if(!l)return a(502,"\u672A\u914D\u7F6E Forsion \u4E91\u7AEF\u5730\u5740");if(c.auth&&!u)return a(401,"\u8BF7\u5148\u5728 Forsion Desktop \u4E2D\u767B\u5F55 Forsion \u8D26\u53F7");let d;if(c.method==="POST"){let y=[],h=0;try{for await(let m of r){if(h+=m.length,h>Vd)return r.destroy(),a(413,"\u8BF7\u6C42\u4F53\u8FC7\u5927");y.push(m)}}catch(m){return a(400,`\u8BF7\u6C42\u4F53\u8BFB\u53D6\u5931\u8D25\uFF1A${m?.message||String(m)}`)}d=Buffer.concat(y)}if(c.agentRun){let y;try{y=JSON.parse((d||Buffer.alloc(0)).toString("utf8")||"{}")}catch{return a(400,"agent \u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON")}d=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")),c.timeoutMs??3e5);r.on("close",()=>g.abort());try{let y=await fetch(l+c.path+(i?`?${i}`:""),{method:c.method,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...u?{Authorization:`Bearer ${u}`}:{}},body:d&&d.length?new Uint8Array(d):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 h of y.body)s.write(h);s.end()}catch(y){let h=`\u4E91\u7AEF\u8BF7\u6C42\u4E2D\u65AD\uFF1A${y?.message||String(y)}`;if(s.headersSent){try{s.write(`data: ${JSON.stringify({error:h})}
3
3
 
4
- `)}catch{}s.end()}else a(502,h)}finally{clearTimeout(p)}}}var Sa=`
4
+ `)}catch{}s.end()}else a(502,h)}finally{clearTimeout(p)}}}var Aa=`
5
5
  (function () {
6
6
  'use strict';
7
7
  if (window.forsion) return;
@@ -177,6 +177,11 @@ var vs=null;function Di(t){vs=t}function Ce(){if(!vs)throw new Error("core host
177
177
  return { model: model, images: data.map(function (d) { return { url: d.url || null, b64: d.b64_json || null }; }) };
178
178
  }
179
179
 
180
+ // \u9884\u89C8\u6309\u4F5C\u8005\u81EA\u5DF1\u7684\u8D26\u53F7\u8D70(\u4E0D\u6263\u989D\u5EA6\u5305\u4F59\u989D),\u6240\u4EE5\u8C01\u6765\u4ED8\u6052\u4E3A\u8BBF\u5BA2\u3001\u8FD8\u5269\u51E0\u6B21\u4E0D\u77E5\u9053;\u53D1\u5E03\u6001\u7531\u58F3\u9875\u6309\u7F51\u9875\u7684\u8BBE\u7F6E\u56DE\u7B54\u3002
181
+ function aiStatus() {
182
+ return Promise.resolve({ payer: 'visitor', agentPayer: 'visitor', remainingToday: null, state: 'preview' });
183
+ }
184
+
180
185
  window.forsion = {
181
186
  mode: 'preview',
182
187
  user: function () { return getUser(); },
@@ -187,72 +192,72 @@ var vs=null;function Di(t){vs=t}function Ce(){if(!vs)throw new Error("core host
187
192
  });
188
193
  },
189
194
  models: function (type) { return listModels(type); },
190
- ai: { chat: chat, agent: agentRun, generateImage: generateImage }
195
+ ai: { chat: chat, agent: agentRun, generateImage: generateImage, status: aiStatus }
191
196
  };
192
197
  })();
193
- `,Ld=t=>({transpile:(e,n,r)=>t.transpileForServe(e,n,r),mimeOf:e=>t.mimeOf(e)});function Ud(t,e){let n=t.isAdoptedCreation;if(typeof n!="function")return!1;try{return n.call(t,e)===!0}catch{return!1}}function Us(t){let e=t;return typeof e.projectsRoot=="function"&&typeof e.transpileForServe=="function"&&typeof e.mimeOf=="function"&&typeof e.setPreviewHooks=="function"}function Hs(t){t.setPreviewHooks({sdkJs:Sa,proxy:ba(()=>t.getCloud())}),t.handle("connect:meta",(e,n)=>typeof n=="string"&&n?ya(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 Ue(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{r=fa(n.dir);let o=null;try{o=fa(t.projectsRoot())}catch{}if(!(!!o&&(r===o||r.startsWith(o+Md)))&&!Ud(t,r))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}=ga(r,Ld(t));if(!o.some(u=>u.path===n.entry))return{ok:!1,code:"error",detail:`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728:${n.entry}`};let{status:a,json:l}=await Ue(s,"POST","/api/connect/apps",{slug:n.slug,name:n.name,entry:n.entry,files:o},3e5);if(a===401)return{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"};if(a!==200)return{ok:!1,code:l?.code||"error",detail:l?.detail||`HTTP ${a}`,used:l?.used,limit:l?.limit};wa(r,{slug:String(l.slug)});let c=typeof l.publicUrl=="string"&&/^https?:\/\//i.test(l.publicUrl)?l.publicUrl:`${s.base}${l.url}`;return{ok:!0,slug:l.slug,handle:l.handle,url:c,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 Ue(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 Ue(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 Ue(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 Ue(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 Hd}from"node:crypto";import{hostname as zd}from"node:os";async function Rn(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 va=t=>`${t.seq}:${t.hash}`,Rr=(t=zd())=>{let e=t.replace(/\.local$/i,"").trim();return e?encodeURIComponent(e):null},Bd=t=>Hd("sha256").update(t).digest("hex");function zs(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 Ir(t){let e=t.baseUrl.replace(/\/+$/,""),n=o=>`${e}/api/remotesync/vaults/${encodeURIComponent(t.vault)}${o}`,r=Rr(),s=async(o,i)=>{let a=t.getToken();if(!a)throw new Error("penzor-not-logged-in");let l=await fetch(o,{...i,headers:{...i.headers,Authorization:`Bearer ${a}`}});if(l.status===409){let c=await l.json().catch(()=>({}));throw new Error(`cas-conflict ${String(c.code??"")}: seq=${String(c.seq??"?")}`)}if(!l.ok){let c=await l.text().catch(()=>"");throw new Error(`penzor ${i.method??"GET"} ${l.status}: ${c.slice(0,200)}`)}return l};return{kind:"penzor",async walk(o){let i=await s(n("/manifest"),{method:"GET",signal:o}),{files:a}=await i.json();return a.map(l=>({key:l.path,size:l.size,mtimeMs:l.mtimeMs,id:va(l),hash:l.hash}))},async readFile(o,i){let l=await(await s(n(`/file?path=${encodeURIComponent(o)}`),{method:"GET",signal:i})).json(),c=await fetch(l.url,{signal:i});if(!c.ok)throw new Error(`penzor blob GET ${c.status}: ${o}`);let u=Buffer.from(await c.arrayBuffer());if(Bd(u)!==l.hash)throw new Error(`penzor hash mismatch: ${o}`);return u},async writeFile(o,i,a,l,c){let u=zs(c),f=new URLSearchParams({path:o,mtimeMs:String(Math.floor(a)||0)});u&&(f.set("baseSeq",String(u.baseSeq)),u.baseHash&&f.set("baseHash",u.baseHash));let p=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:l})).json();return{key:o,size:p.size,mtimeMs:p.mtimeMs,id:va(p)}},async rm(o,i,a){let l=zs(a),c=new URLSearchParams({path:o});l&&l.baseSeq>0&&(c.set("baseSeq",String(l.baseSeq)),l.baseHash&&c.set("baseHash",l.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 Dr="forsion-diagnostics",Ea=50*1024*1024,ka=new Map;async function qd(t,e){let n=ka.get(e);if(n)return{id:n};let r=await Rn(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?(ka.set(e,s),{id:s}):{error:"penzor-auth-unverified"}}var Bs=t=>typeof t.registerRemoteSyncBackend=="function"&&typeof t.readCreds=="function";function qs(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===Dr)return{error:"penzor-bad-vault"};let o=await qd(n.cloudUrl,n.token);if("error"in o)return o;let i=n.token;return{remote:Ir({baseUrl:n.cloudUrl,vault:s,getToken:()=>i}),fingerprint:`penzor:${n.cloudUrl.replace(/\/+$/,"")}|u:${o.id}|${s}`,maxFileBytes:Ea}}),t.log('[forsion-extend] remote-sync backend "penzor" registered')}import{createReadStream as Vd}from"node:fs";import{access as Yd,link as Gd,lstat as Jd,mkdir as Kd,open as Xd,readdir as Zd,rename as Qd,stat as Ia,unlink as Ys}from"node:fs/promises";import{request as ef}from"node:http";import{request as tf}from"node:https";import{homedir as nf}from"node:os";import{basename as Da,extname as rf,isAbsolute as sf,join as Dn}from"node:path";import{randomUUID as Pr}from"node:crypto";var In=52428800;var _a=["bytes","signed","text"],Ca=/^[A-Za-z0-9_-]{1,64}$/,xa=/^[a-z0-9][a-z0-9-]{0,63}$/;function Or(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 Wd={".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 Aa(t){let e=t.lastIndexOf(".");return Wd[e>0?t.slice(e).toLowerCase():""]??"application/octet-stream"}function Ta(t,e,n,r){let s=n.replace(/[^\x20-\x7e]/g,"_").replace(/["\\]/g,"_")||"file",o=encodeURIComponent(n).replace(/['()*]/g,a=>`%${a.charCodeAt(0).toString(16).toUpperCase()}`),i="";for(let[a,l]of Object.entries(e))i+=`--${t}\r
198
+ `,Qd=t=>({transpile:(e,n,r)=>t.transpileForServe(e,n,r),mimeOf:e=>t.mimeOf(e)});function ef(t,e){let n=t.isAdoptedCreation;if(typeof n!="function")return!1;try{return n.call(t,e)===!0}catch{return!1}}function Bs(t){let e=t;return typeof e.projectsRoot=="function"&&typeof e.transpileForServe=="function"&&typeof e.mimeOf=="function"&&typeof e.setPreviewHooks=="function"}function qs(t){t.setPreviewHooks({sdkJs:Aa,proxy:xa(()=>t.getCloud())}),t.handle("connect:meta",(e,n)=>typeof n=="string"&&n?Ca(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 Ue(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{r=ga(n.dir);let o=null;try{o=ga(t.projectsRoot())}catch{}if(!(!!o&&(r===o||r.startsWith(o+Wd)))&&!ef(t,r))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}=Sa(r,Qd(t));if(!o.some(u=>u.path===n.entry))return{ok:!1,code:"error",detail:`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728:${n.entry}`};let{status:a,json:c}=await Ue(s,"POST","/api/connect/apps",{slug:n.slug,name:n.name,entry:n.entry,files:o},3e5);if(a===401)return{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"};if(a!==200)return{ok:!1,code:c?.code||"error",detail:c?.detail||`HTTP ${a}`,used:c?.used,limit:c?.limit};Ea(r,{slug:String(c.slug)});let l=typeof c.publicUrl=="string"&&/^https?:\/\//i.test(c.publicUrl)?c.publicUrl:`${s.base}${c.url}`;return{ok:!0,slug:c.slug,handle:c.handle,url:l,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 Ue(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 Ue(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 Ue(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 Ue(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 tf}from"node:crypto";import{hostname as nf}from"node:os";async function Rn(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 Ta=t=>`${t.seq}:${t.hash}`,Ir=(t=nf())=>{let e=t.replace(/\.local$/i,"").trim();return e?encodeURIComponent(e):null},rf=t=>tf("sha256").update(t).digest("hex");function Ws(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 Dr(t){let e=t.baseUrl.replace(/\/+$/,""),n=o=>`${e}/api/remotesync/vaults/${encodeURIComponent(t.vault)}${o}`,r=Ir(),s=async(o,i)=>{let a=t.getToken();if(!a)throw new Error("penzor-not-logged-in");let c=await fetch(o,{...i,headers:{...i.headers,Authorization:`Bearer ${a}`}});if(c.status===409){let l=await c.json().catch(()=>({}));throw new Error(`cas-conflict ${String(l.code??"")}: seq=${String(l.seq??"?")}`)}if(!c.ok){let l=await c.text().catch(()=>"");throw new Error(`penzor ${i.method??"GET"} ${c.status}: ${l.slice(0,200)}`)}return c};return{kind:"penzor",async walk(o){let i=await s(n("/manifest"),{method:"GET",signal:o}),{files:a}=await i.json();return a.map(c=>({key:c.path,size:c.size,mtimeMs:c.mtimeMs,id:Ta(c),hash:c.hash}))},async readFile(o,i){let c=await(await s(n(`/file?path=${encodeURIComponent(o)}`),{method:"GET",signal:i})).json(),l=await fetch(c.url,{signal:i});if(!l.ok)throw new Error(`penzor blob GET ${l.status}: ${o}`);let u=Buffer.from(await l.arrayBuffer());if(rf(u)!==c.hash)throw new Error(`penzor hash mismatch: ${o}`);return u},async writeFile(o,i,a,c,l){let u=Ws(l),d=new URLSearchParams({path:o,mtimeMs:String(Math.floor(a)||0)});u&&(d.set("baseSeq",String(u.baseSeq)),u.baseHash&&d.set("baseHash",u.baseHash));let p=await(await s(n(`/file?${d.toString()}`),{method:"PUT",body:new Uint8Array(i),headers:{"Content-Type":"application/octet-stream",...r?{"X-Forsion-Device":r}:{}},signal:c})).json();return{key:o,size:p.size,mtimeMs:p.mtimeMs,id:Ta(p)}},async rm(o,i,a){let c=Ws(a),l=new URLSearchParams({path:o});c&&c.baseSeq>0&&(l.set("baseSeq",String(c.baseSeq)),c.baseHash&&l.set("baseHash",c.baseHash)),await s(n(`/file?${l.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 Or="forsion-diagnostics",Ia=50*1024*1024,Ra=new Map;async function sf(t,e){let n=Ra.get(e);if(n)return{id:n};let r=await Rn(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?(Ra.set(e,s),{id:s}):{error:"penzor-auth-unverified"}}var Vs=t=>typeof t.registerRemoteSyncBackend=="function"&&typeof t.readCreds=="function";function Ys(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===Or)return{error:"penzor-bad-vault"};let o=await sf(n.cloudUrl,n.token);if("error"in o)return o;let i=n.token;return{remote:Dr({baseUrl:n.cloudUrl,vault:s,getToken:()=>i}),fingerprint:`penzor:${n.cloudUrl.replace(/\/+$/,"")}|u:${o.id}|${s}`,maxFileBytes:Ia}}),t.log('[forsion-extend] remote-sync backend "penzor" registered')}import{createReadStream as af}from"node:fs";import{access as cf,link as lf,lstat as uf,mkdir as df,open as ff,readdir as pf,rename as hf,stat as ja,unlink as Ks}from"node:fs/promises";import{request as gf}from"node:http";import{request as mf}from"node:https";import{homedir as yf}from"node:os";import{basename as Fa,extname as wf,isAbsolute as bf,join as Dn}from"node:path";import{randomUUID as Mr}from"node:crypto";var In=52428800;var Da=["bytes","signed","text"],Oa=/^[A-Za-z0-9_-]{1,64}$/,Pa=/^[a-z0-9][a-z0-9-]{0,63}$/;function Pr(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 of={".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 Ma(t){let e=t.lastIndexOf(".");return of[e>0?t.slice(e).toLowerCase():""]??"application/octet-stream"}function $a(t,e,n,r){let s=n.replace(/[^\x20-\x7e]/g,"_").replace(/["\\]/g,"_")||"file",o=encodeURIComponent(n).replace(/['()*]/g,a=>`%${a.charCodeAt(0).toString(16).toUpperCase()}`),i="";for(let[a,c]of Object.entries(e))i+=`--${t}\r
194
199
  Content-Disposition: form-data; name="${a}"\r
195
200
  \r
196
- ${l}\r
201
+ ${c}\r
197
202
  `;return i+=`--${t}\r
198
203
  Content-Disposition: form-data; name="file"; filename="${s}"; filename*=UTF-8''${o}\r
199
204
  Content-Type: ${r}\r
200
205
  \r
201
206
  `,{head:i,tail:`\r
202
207
  --${t}--\r
203
- `}}function Ws(t,e){let n=t.filter(([a])=>e-a<=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 Vs(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 of=3,Gs=6e4,af=200,lf=_a;function Oa(t,e,n,r){let{head:s,tail:o}=Ta(t,e,n,r);return{head:Buffer.from(s,"utf8"),tail:Buffer.from(o,"utf8")}}function cf(t,e,n,r,s,o,i,a){return new Promise((l,c)=>{let u=new URL(t),f=(u.protocol==="https:"?tf:ef)(u,{method:"POST",headers:{...e,"Content-Length":String(n.length+s+o.length)}},p=>{let y=[];p.on("data",h=>y.push(h)),p.on("end",()=>{let h=null;try{h=JSON.parse(Buffer.concat(y).toString("utf8"))}catch{}l({status:p.statusCode??0,body:h})}),p.on("error",c)}),g=()=>{f.destroy(new Error("aborted"))};if(a.aborted)return g();a.addEventListener("abort",g,{once:!0}),f.setTimeout(Gs,()=>f.destroy(new Error("timeout"))),f.on("error",p=>{a.removeEventListener("abort",g),c(p)}),(async()=>{try{f.write(n);let p=0;for await(let y of Vd(r)){let h=y;if(p+=h.length,p>s)throw new Error("changed");f.write(h)||await new Promise(m=>f.once("drain",m)),i(p)}if(p!==s)throw new Error("changed");f.end(o)}catch(p){f.destroy(p)}})()})}function Js(t,e={}){let n=e.downloadsDir??(()=>Dn(nf(),"Downloads")),r=e.post??cf,s=e.now??Date.now,o=[],i=new Map,a=Promise.resolve(),l=async()=>{let S=await t.getCloud(),C=typeof t.accountId=="function"?t.accountId():null;return{...S,account:C||`${S.base}|${S.token}`}},c=S=>{let{account:C,attempt:E,relDir:I,abort:U,samples:M,dl:V,...Z}=S;return{...Z,speed:S.state==="active"?Ws(M,s()):0}},u=(S,C,E=null)=>{S.state=C,S.error=E,S.abort=null,S.finishedAt=s(),S.samples=[];let I=o.filter(U=>U.state==="done"||U.state==="canceled");for(let U of I.slice(0,Math.max(0,I.length-af)))o.splice(o.indexOf(U),1);f()};function f(){for(let S of["up","down"]){let C=o.filter(E=>E.kind===S&&E.state==="active").length;for(let E of o){if(C>=of)break;if(E.kind!==S||E.state!=="queued")continue;C++,E.state="active",E.startedAt=s(),E.done=0,E.samples=[[s(),0]],E.abort=new AbortController;let I=++E.attempt,U=()=>E.attempt===I&&E.state==="active";(S==="up"?w(E,U):$(E,U)).catch(M=>{U()&&u(E,"failed",g(M))})}}}let g=S=>{let C=String(S?.message||S);return C==="changed"||C==="too_large"||C==="quota"||C==="account_changed"||C==="not_signed_in"||C.startsWith("http_")||C==="bad_response"||C==="gone"?C:"network"},p=(S,C)=>{S.done=C;let E=s(),I=S.samples[S.samples.length-1];for((!I||E-I[0]>=200)&&S.samples.push([E,C]);S.samples.length>2&&E-S.samples[0][0]>3500;)S.samples.shift()};async function y(S){let C=await l();if(C.account!==S.account)throw new Error("account_changed");if(!C.token)throw new Error("not_signed_in");return C}async function h(S,C,E,I){let U=ht(S,E);if(!U)throw new Error("bad_path");let M=await fetch(U,{method:I.method??"GET",headers:{Authorization:`Bearer ${C}`,...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:M.status,json:await M.json().catch(()=>null)}}function m(S,C,E){if(!S.relDir.length)return Promise.resolve(S.targetId);let I=i.get(S.batch);I||i.set(S.batch,I=new Map);let U=I,M=V=>{if(V===0)return Promise.resolve(S.targetId);let Z=S.relDir.slice(0,V).join("/"),re=U.get(Z);return re||(re=M(V-1).then(async se=>{let ee=S.relDir[V-1],Q=await h(C,E,"/files",{method:"POST",body:{type:"directory",parentId:se,name:ee},projectSource:S.projectSource});if(Q.status===201&&typeof Q.json?.id=="string")return Q.json.id;if(Q.status===409){let ge=await h(C,E,`/files${se==="ROOT"?"":`?parentId=${encodeURIComponent(se)}`}`,{projectSource:S.projectSource}),fe=Array.isArray(ge.json)?ge.json.find(ye=>ye?.fileType==="directory"&&ye?.name===ee):null;if(fe?.id)return String(fe.id)}throw new Error(Q.status===401?"not_signed_in":`http_${Q.status}`)}),re.catch(()=>U.delete(Z)),U.set(Z,re)),re};return M(S.relDir.length)}async function w(S,C){let{base:E,token:I}=await y(S),U=await Ia(S.localPath).catch(()=>null);if(!U?.isFile())throw new Error("gone");if(U.size>52428800)throw new Error("too_large");S.size=U.size;let M=await m(S,E,I);if(!C())return;S.parentId=M;let V=ht(E,"/files/upload");if(!V)throw new Error("bad_path");let Z=`----penzor${Pr().replace(/-/g,"")}`,{head:re,tail:se}=Oa(Z,{parentId:M,autoRename:"true"},S.name,Aa(S.name)),ee=await r(V,{Authorization:`Bearer ${I}`,"Content-Type":`multipart/form-data; boundary=${Z}`,...S.projectSource?{"X-Project-Source":S.projectSource}:{}},re,S.localPath,U.size,se,Q=>{C()&&p(S,Q)},S.abort.signal);C()&&(ee.status===201||ee.status===200?(S.fileId=typeof ee.body?.id=="string"?ee.body.id:null,p(S,S.size),u(S,"done")):u(S,"failed",Vs(ee.status,ee.body)))}function _(S,C,E,I){let U=async()=>{let V=rf(E),Z=V?E.slice(0,-V.length):E;for(let re=0;re<1e3;re++){if(!I())throw new Error("aborted");let se=Dn(C,re===0?E:`${Z} (${re})${V}`);try{await Gd(S,se)}catch(ee){let Q=ee.code;if(Q==="EEXIST")continue;if(Q!=="EPERM"&&Q!=="ENOTSUP"&&Q!=="EOPNOTSUPP"&&Q!=="ENOSYS"&&Q!=="EXDEV")throw ee;if(await Yd(se).then(()=>!0,()=>!1))continue;await Qd(S,se)}if(!I())throw await Ys(se).catch(()=>{}),new Error("aborted");return await Ys(S).catch(()=>{}),se}throw new Error("too many duplicates")},M=a.then(U,U);return a=M.catch(()=>{}),M}async function $(S,C){let E=S.dl,{base:I,token:U}=await y(S);if(!C())return;let M=ht(I,E.path);if(!M)throw new Error("bad_path");let V=S.abort.signal,Z=E.subdir?Dn(n(),E.subdir):n();await Kd(Z,{recursive:!0});let re=Dn(Z,`.${S.id}-${S.attempt}.penzor-part`),se=await Xd(re,"wx"),ee=!1;try{let Q=new AbortController,ge=setTimeout(()=>Q.abort(),Gs),fe=()=>{clearTimeout(ge),ge=setTimeout(()=>Q.abort(),Gs)},ye=AbortSignal.any([V,Q.signal]);try{let he=await fetch(M,{headers:{Authorization:`Bearer ${U}`},signal:ye});if(!he.ok)throw new Error(he.status===401?"not_signed_in":`http_${he.status}`);let ze=he.body,Fe=Number(he.headers.get("content-length"))||S.size;if(E.mode!=="bytes"){let be=await he.json().catch(()=>null);if(E.mode==="text"){if(typeof be?.content!="string")throw new Error("bad_response");let F=Buffer.from(be.content,"utf8");await se.writeFile(F),S.size=F.length,p(S,F.length),ze=null}else{if(typeof be?.url!="string"||!/^https?:\/\//i.test(be.url))throw new Error("bad_response");let F=await fetch(be.url,{signal:ye});if(!F.ok)throw new Error(`http_${F.status}`);ze=F.body,Fe=Number(F.headers.get("content-length"))||S.size}}if(ze){S.size=Fe;let be=0;for await(let F of ze){fe();for(let Y=0;Y<F.length;){let{bytesWritten:v}=await se.write(F,Y,F.length-Y);if(v<=0)throw new Error("short_write");Y+=v}if(be+=F.length,!C())throw new Error("aborted");p(S,be)}be>S.size&&(S.size=be)}}finally{clearTimeout(ge)}if(await se.close(),!C()||(S.localPath=await _(re,Z,E.name,C),ee=!0,!C()))return;u(S,"done")}finally{ee||(await se.close().catch(()=>{}),await Ys(re).catch(()=>{}))}}let R=(S,C)=>{let E={...S,id:Pr(),attempt:0,done:0,state:C?"failed":"queued",error:C??null,abort:null,samples:[],speed:0,startedAt:null,finishedAt:C?s():null};return o.push(E),E};async function O(S){let C=[],E=async(I,U)=>{if(U.length>32)return!0;let M=await(U.length?Jd(I):Ia(I)).catch(()=>null);if(!M)return!0;if(M.isFile())return C.push({path:I,size:M.size,relDir:U}),C.length<=2e3;if(!M.isDirectory())return!0;let V=(await Zd(I).catch(()=>[])).filter(Z=>!Z.startsWith(".")).sort();for(let Z of V)if(!await E(Dn(I,Z),[...U,Da(I)]))return!1;return!0};for(let I of S)if(!await E(I,[]))return"too_many";return C}return t.handle("penzor:device",S=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let C=Rr();return{ok:!0,name:C?decodeURIComponent(C):null}}),t.handle("penzor:upload",async(S,C)=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let E=C??{},I=Array.isArray(E.paths)?E.paths.filter(fe=>typeof fe=="string"&&sf(fe)):[],U=typeof E.parentId=="string"&&Ca.test(E.parentId)?E.parentId:null,M=typeof E.projectSource=="string"&&xa.test(E.projectSource)?E.projectSource:null;if(!I.length)return{ok:!1,error:"no_files"};if(!U||!M)return{ok:!1,error:"bad_target"};let{base:V,token:Z,account:re}=await l();if(!Z)return{ok:!1,error:"not_signed_in"};let se=await O(I);if(se==="too_many")return{ok:!1,error:"too_many",max:2e3};if(!se.length)return{ok:!1,error:"no_files"};let ee=se.filter(fe=>fe.size<=52428800).reduce((fe,ye)=>fe+ye.size,0);try{let fe=await h(V,Z,"/storage/quota",{}),ye=Number(fe.json?.used),he=Number(fe.json?.quota);if(fe.status===200&&he>0&&ye+ee>he)return{ok:!1,error:"quota",short:ye+ee-he}}catch{}if((await l()).account!==re)return{ok:!1,error:"account_changed"};let Q=Pr(),ge=se.map(fe=>R({kind:"up",name:Da(fe.path),size:fe.size,projectSource:M,parentId:fe.relDir.length?null:U,targetId:U,fileId:null,localPath:fe.path,batch:Q,account:re,relDir:fe.relDir},fe.size>52428800?"too_large":void 0).id);return f(),{ok:!0,ids:ge,batch:Q}}),t.handle("penzor:download",async(S,C)=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let E=C??{},I=lf.includes(E.mode)?E.mode:null,U=Or(E.name);if(!I)return{ok:!1,error:"bad_mode"};if(!U)return{ok:!1,error:"bad_name"};let{base:M,token:V,account:Z}=await l();if(typeof E.path!="string"||!ht(M,E.path))return{ok:!1,error:"bad_path"};if(!V)return{ok:!1,error:"not_signed_in"};let re=E.subdir==null?null:Or(E.subdir),se=R({kind:"down",name:U,size:Math.max(0,Number(E.size)||0),localPath:null,batch:typeof E.batch=="string"&&E.batch.length<=64?E.batch:Pr(),account:Z,relDir:[],dl:{path:E.path,mode:I,name:U,subdir:re}});return f(),{ok:!0,id:se.id}}),t.handle("penzor:transfers",S=>t.isTrustedSender(S)?{ok:!0,items:o.map(c)}:{ok:!1,error:"untrusted"}),t.handle("penzor:transfer",(S,C)=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let E=C??{},I=o.find(M=>M.id===E.id);if(!I)return{ok:!1,error:"not_found"};let U=()=>{I.abort?.abort(),I.abort=null,I.done=0,I.samples=[]};switch(E.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",(S,C)=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let E=C?.which==="all";for(let I of[...o])(I.state==="done"||I.state==="canceled"||E&&I.state==="failed")&&o.splice(o.indexOf(I),1);return{ok:!0}}),t.addQuitGuard?.(S=>{let C=o.filter(E=>E.state==="active"||E.state==="queued"||E.state==="paused").length;return C?S==="zh"?{message:`\u8FD8\u6709 ${C} \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:C===1?"1 file hasn't finished transferring":`${C} 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 yf,writeFileSync as wf,mkdirSync as bf,chmodSync as Sf,renameSync as vf}from"node:fs";import{join as kf}from"node:path";import{mkdirSync as uf,readFileSync as df,renameSync as ff,unlinkSync as pf,writeFileSync as hf}from"node:fs";import{dirname as gf,join as mf}from"node:path";import{randomUUID as Pa}from"node:crypto";var Qs=t=>mf(t,"content-sync","active-account.json"),Ks=()=>Error("Invalid content sync account binding; original data was retained");function On(t){try{let e=JSON.parse(df(t,"utf8"));if(e?.version!==1||!(e.account===null&&e.pending===!0||typeof e.account=="string"&&/^[a-f0-9]{64}$/.test(e.account))||e.epoch!==void 0&&(typeof e.epoch!="string"||!/^[a-f0-9-]{36}$/i.test(e.epoch))||e.pending!==void 0&&typeof e.pending!="boolean"||e.pending&&!e.epoch)throw Ks();return e}catch(e){if(e?.code==="ENOENT")return null;throw Ks()}}function eo(t,e){uf(gf(t),{recursive:!0,mode:448});let n=t+".tmp-"+Pa();try{hf(n,JSON.stringify(e),{flag:"wx",mode:384}),ff(n,t)}finally{try{pf(n)}catch{}}}var Xs=new WeakMap,Zs=new WeakSet;function $a(t,e){let n=Xs.get(t);return n||Xs.set(t,n=new Set),n.add(e),()=>{n.delete(e)}}function to(t){if(Zs.has(t))throw Ks()}function en(t,e,n){if(!t.contentSync||e===n)return;let r=Qs(t.homeDir());try{let s=On(r);eo(r,{version:1,account:s?.account??null,epoch:Pa(),pending:!0}),Zs.delete(t)}catch(s){throw Zs.add(t),s}finally{for(let s of Xs.get(t)??[])s()}}function Ef(t){let e=()=>kf(t(),"auth-accounts.json");return{read:()=>yf(e(),"utf8"),write:n=>{bf(t(),{recursive:!0});let r=`${e()}.tmp`;wf(r,n,{encoding:"utf8",mode:384}),Sf(r,384),vf(r,e())}}}var Na=t=>Ni(t,Ef(()=>t.homeDir())),ja=["homeDir","appVersion","broadcast","accountBackendState","accountTransition","accountCommit","accountClear","writeCreds","onExternalCredsChange","setTokenRefresher","readCreds"],no=t=>ja.every(e=>typeof t[e]=="function");function ro(t){let e={ok:!1,error:"untrusted"},n={loggedIn:!1,error:"untrusted"},r=Na(t),s=0,o=()=>{let l=t.readCreds();return Cn(l.cloudUrl,l.token)},i=l=>Oe(l.cloudUrl??"",l.token??""),a=null;t.handle("auth:status",async l=>{if(!t.isTrustedSender(l))return n;let c=s,u=o(),{base:f}=await t.getCloud(),g=t.readCreds().token,p=g?await Rn(f,g):null,y=await t.accountBackendState(),{base:h}=await t.getCloud(),m=t.readCreds(),w=Cn(h,m.token)!==Cn(f,g),_=Cn(f,g);!w&&p?.status==="ok"&&p.user&&(a={key:_,user:p.user},r.rememberForsionAccount({...m,cloudUrl:f},p.user));let $=w?void 0:p?.status==="ok"?p.user:p?.status==="offline"&&a?.key===_?a.user:void 0;if(w)return{loggedIn:!!m.token,tokenValid:null,cloudUrl:h,accountId:Oe(h,m.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:m.token?"tangu-login":null,backendState:y};if(p?.status==="expired"){await t.accountTransition(async()=>{if(c!==s||o()!==u)return;let O=()=>{if(c!==s||o()!==u)throw Ma};try{await t.accountClear(O,()=>{en(t,t.accountId?.()??null,null),t.log("[auth] token \u5DF2\u5931\u6548(\u670D\u52A1\u7AEF 401/403),\u81EA\u52A8\u767B\u51FA"),++s,r.cancelForsionLogin(),r.forgetForsionAccount(t.readCreds()),a=null})}catch(S){if(S!==Ma)throw S}});let R=t.readCreds();return{loggedIn:!!R.token,tokenValid:null,cloudUrl:R.cloudUrl||f,accountId:Oe(R.cloudUrl||f,R.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:R.token?"tangu-login":null,backendState:y}}return{loggedIn:!!g,tokenValid:p&&p.status==="ok"?!0:null,cloudUrl:f,accountId:Oe(f,g),username:$?.username||null,nickname:$?.nickname||null,avatar:$?.avatar||null,membershipTier:$?.membershipTier||null,tokenSource:g?"tangu-login":null,backendState:y}}),t.handle("auth:accounts",l=>t.isTrustedSender(l)?r.forsionAccounts():[]),t.handle("auth:switchAccount",async(l,c)=>{if(!t.isTrustedSender(l))return e;if(typeof c!="string")throw new Error("Invalid account.");let u=++s;return r.cancelForsionLogin(),t.accountTransition(async()=>{let f=r.savedForsionAccount(c);return await t.accountCommit(f,()=>{if(u!==s)throw new Error("Account switch cancelled.")},()=>{en(t,t.accountId?.()??null,i(f)),r.rememberForsionAccount(f),a=null}),{ok:!0,cloudUrl:f.cloudUrl||""}})}),t.handle("auth:forsionLogin",async(l,c)=>{if(!t.isTrustedSender(l))return e;let u=++s;r.cancelForsionLogin();let{base:f}=await t.getCloud();if(u!==s)throw new Error("Sign-in cancelled.");let g=(c||f||"").trim();return{ok:!0,cloudUrl:(await r.forsionDeviceLogin(g,y=>t.broadcast("auth:device",y),(y,h)=>t.accountTransition(()=>t.accountCommit(y,()=>{if(h(),u!==s)throw new Error("Sign-in cancelled.")},()=>{en(t,t.accountId?.()??null,i(y)),r.rememberForsionAccount(y),a=null})))).cloudUrl}}),t.handle("auth:logout",async l=>t.isTrustedSender(l)?(++s,r.cancelForsionLogin(),t.accountTransition(async()=>{let{base:c}=await t.getCloud(),u=t.readCreds();return await t.accountClear(void 0,()=>{en(t,t.accountId?.()??null,null),r.forgetForsionAccount(u),a=null,c&&u.token&&fetch(`${c}/api/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${u.token}`},signal:AbortSignal.timeout(5e3)}).catch(()=>{})}),{ok:!0}})):e),t.onExternalCredsChange(({previous:l,current:c})=>{try{en(t,i(l),i(c))}catch{t.log("[content-sync] account transition could not be recorded; sync is stopped")}++s,r.cancelForsionLogin(),l.token&&!c.token&&r.forgetForsionAccount(l),a=null,r.rememberForsionAccount(c)}),t.setTokenRefresher(async l=>{let c=s,u=o(),f=t.readCreds().token;if(!br(f))return;let{base:g}=await t.getCloud(),p=await Sr(g,f,l,`desktop/${t.appVersion()}`);if(!p){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}c!==s||o()!==u||(r.rememberForsionAccount({cloudUrl:g,token:p}),t.writeCreds({cloudUrl:g,token:p}),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 Ma=Symbol("stale-auth-intent");import{promises as on}from"node:fs";import Ut from"node:path";import{execFile as ep}from"node:child_process";import tp from"node:os";var so=null;function Fa(t){so=t}function He(){if(!so)throw new Error("amadeus sync env not set (registerAmadeus factory has not run)");return so}var Pe=()=>He().accountId();function Pn(t=Pe()){return t?Ce().sha256Hex(t):"signed-out"}var Ye=(t=Pe())=>He().readConfig(t),gt=(t,e=Pe())=>He().writeConfig(t,e),tn=(t,e=Pe())=>He().updateConfig(t,e),Ct=(t=Pe())=>He().cloudVaultDir(t),$r=t=>He().isManagedCloudVault(t);function _f(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],a=n[i]||[],l=0,c=s[0];for(let u of a){let f;for(f=l;f<s.length&&!(s[f].buffer2index<u&&(f===s.length-1||s[f+1].buffer2index>u));f++);if(f<s.length){let g={buffer1index:o,buffer2index:u,chain:s[f]};if(l===s.length?s.push(c):s[l]=c,l=f+1,c=g,l===s.length)break}}s[l]=c}return s[s.length-1]}function La(t,e){let n=_f(t,e),r=[],s=t.length,o=e.length;for(let i=n;i!==null;i=i.chain){let a=s-i.buffer1index-1,l=o-i.buffer2index-1;s=i.buffer1index,o=i.buffer2index,(a||l)&&r.push({buffer1:[s+1,a],buffer1Content:t.slice(s+1,s+1+a),buffer2:[o+1,l],buffer2Content:e.slice(o+1,o+1+l)})}return r.reverse(),r}function Cf(t,e,n){let r=[];function s(l,c){r.push({ab:c,oStart:l.buffer1[0],oLength:l.buffer1[1],abStart:l.buffer2[0],abLength:l.buffer2[1]})}La(e,t).forEach(l=>s(l,"a")),La(e,n).forEach(l=>s(l,"b")),r.sort((l,c)=>l.oStart-c.oStart);let o=[],i=0;function a(l){l>i&&(o.push({stable:!0,buffer:"o",bufferStart:i,bufferLength:l-i,bufferContent:e.slice(i,l)}),i=l)}for(;r.length;){let l=r.shift(),c=l.oStart,u=l.oStart+l.oLength,f=[l];for(a(c);r.length;){let g=r[0],p=g.oStart;if(p>u)break;u=Math.max(u,p+g.oLength),f.push(r.shift())}if(f.length===1){if(l.abLength>0){let g=l.ab==="a"?t:n;o.push({stable:!0,buffer:l.ab,bufferStart:l.abStart,bufferLength:l.abLength,bufferContent:g.slice(l.abStart,l.abStart+l.abLength)})}}else{let g={a:[t.length,-1,e.length,-1],b:[n.length,-1,e.length,-1]};for(;f.length;){l=f.shift();let _=l.oStart,$=_+l.oLength,R=l.abStart,O=R+l.abLength,S=g[l.ab];S[0]=Math.min(R,S[0]),S[1]=Math.max(O,S[1]),S[2]=Math.min(_,S[2]),S[3]=Math.max($,S[3])}let p=g.a[0]+(c-g.a[2]),y=g.a[1]+(u-g.a[3]),h=g.b[0]+(c-g.b[2]),m=g.b[1]+(u-g.b[3]),w={stable:!1,aStart:p,aLength:y-p,aContent:t.slice(p,y),oStart:c,oLength:u-c,oContent:e.slice(c,u),bStart:h,bLength:m-h,bContent:n.slice(h,m)};o.push(w)}i=u}return a(e.length),o}function Ua(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=Cf(t,e,n),a=[];function l(){a.length&&o.push({ok:a}),a=[]}function c(u,f){if(u.length!==f.length)return!1;for(let g=0;g<u.length;g++)if(u[g]!==f[g])return!1;return!0}return i.forEach(u=>{u.stable?a.push(...u.bufferContent):r.excludeFalseConflicts&&c(u.aContent,u.bContent)?a.push(...u.aContent):(l(),o.push({conflict:{a:u.aContent,aIndex:u.aStart,o:u.oContent,oIndex:u.oStart,b:u.bContent,bIndex:u.bStart}}))}),l(),o}function Mr(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,a=o>0?s.slice(o):"",l=u=>String(u).padStart(2,"0"),c=`${e.getFullYear()}-${l(e.getMonth()+1)}-${l(e.getDate())} ${l(e.getHours())}${l(e.getMinutes())}`;return`${r}${i} (conflict ${c})${a}`}function xf(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 Af(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 Nr(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 Ha(t,e,n){let r=Ua(t.split(`
208
+ `}}function Gs(t,e){let n=t.filter(([a])=>e-a<=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 Js(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 Sf=3,Xs=6e4,vf=200,kf=Da;function La(t,e,n,r){let{head:s,tail:o}=$a(t,e,n,r);return{head:Buffer.from(s,"utf8"),tail:Buffer.from(o,"utf8")}}function Ef(t,e,n,r,s,o,i,a){return new Promise((c,l)=>{let u=new URL(t),d=(u.protocol==="https:"?mf:gf)(u,{method:"POST",headers:{...e,"Content-Length":String(n.length+s+o.length)}},p=>{let y=[];p.on("data",h=>y.push(h)),p.on("end",()=>{let h=null;try{h=JSON.parse(Buffer.concat(y).toString("utf8"))}catch{}c({status:p.statusCode??0,body:h})}),p.on("error",l)}),g=()=>{d.destroy(new Error("aborted"))};if(a.aborted)return g();a.addEventListener("abort",g,{once:!0}),d.setTimeout(Xs,()=>d.destroy(new Error("timeout"))),d.on("error",p=>{a.removeEventListener("abort",g),l(p)}),(async()=>{try{d.write(n);let p=0;for await(let y of af(r)){let h=y;if(p+=h.length,p>s)throw new Error("changed");d.write(h)||await new Promise(m=>d.once("drain",m)),i(p)}if(p!==s)throw new Error("changed");d.end(o)}catch(p){d.destroy(p)}})()})}function Zs(t,e={}){let n=e.downloadsDir??(()=>Dn(yf(),"Downloads")),r=e.post??Ef,s=e.now??Date.now,o=[],i=new Map,a=Promise.resolve(),c=async()=>{let S=await t.getCloud(),C=typeof t.accountId=="function"?t.accountId():null;return{...S,account:C||`${S.base}|${S.token}`}},l=S=>{let{account:C,attempt:E,relDir:I,abort:U,samples:$,dl:V,...Z}=S;return{...Z,speed:S.state==="active"?Gs($,s()):0}},u=(S,C,E=null)=>{S.state=C,S.error=E,S.abort=null,S.finishedAt=s(),S.samples=[];let I=o.filter(U=>U.state==="done"||U.state==="canceled");for(let U of I.slice(0,Math.max(0,I.length-vf)))o.splice(o.indexOf(U),1);d()};function d(){for(let S of["up","down"]){let C=o.filter(E=>E.kind===S&&E.state==="active").length;for(let E of o){if(C>=Sf)break;if(E.kind!==S||E.state!=="queued")continue;C++,E.state="active",E.startedAt=s(),E.done=0,E.samples=[[s(),0]],E.abort=new AbortController;let I=++E.attempt,U=()=>E.attempt===I&&E.state==="active";(S==="up"?w(E,U):M(E,U)).catch($=>{U()&&u(E,"failed",g($))})}}}let g=S=>{let C=String(S?.message||S);return C==="changed"||C==="too_large"||C==="quota"||C==="account_changed"||C==="not_signed_in"||C.startsWith("http_")||C==="bad_response"||C==="gone"?C:"network"},p=(S,C)=>{S.done=C;let E=s(),I=S.samples[S.samples.length-1];for((!I||E-I[0]>=200)&&S.samples.push([E,C]);S.samples.length>2&&E-S.samples[0][0]>3500;)S.samples.shift()};async function y(S){let C=await c();if(C.account!==S.account)throw new Error("account_changed");if(!C.token)throw new Error("not_signed_in");return C}async function h(S,C,E,I){let U=ht(S,E);if(!U)throw new Error("bad_path");let $=await fetch(U,{method:I.method??"GET",headers:{Authorization:`Bearer ${C}`,...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:$.status,json:await $.json().catch(()=>null)}}function m(S,C,E){if(!S.relDir.length)return Promise.resolve(S.targetId);let I=i.get(S.batch);I||i.set(S.batch,I=new Map);let U=I,$=V=>{if(V===0)return Promise.resolve(S.targetId);let Z=S.relDir.slice(0,V).join("/"),re=U.get(Z);return re||(re=$(V-1).then(async se=>{let ee=S.relDir[V-1],Q=await h(C,E,"/files",{method:"POST",body:{type:"directory",parentId:se,name:ee},projectSource:S.projectSource});if(Q.status===201&&typeof Q.json?.id=="string")return Q.json.id;if(Q.status===409){let ge=await h(C,E,`/files${se==="ROOT"?"":`?parentId=${encodeURIComponent(se)}`}`,{projectSource:S.projectSource}),fe=Array.isArray(ge.json)?ge.json.find(ye=>ye?.fileType==="directory"&&ye?.name===ee):null;if(fe?.id)return String(fe.id)}throw new Error(Q.status===401?"not_signed_in":`http_${Q.status}`)}),re.catch(()=>U.delete(Z)),U.set(Z,re)),re};return $(S.relDir.length)}async function w(S,C){let{base:E,token:I}=await y(S),U=await ja(S.localPath).catch(()=>null);if(!U?.isFile())throw new Error("gone");if(U.size>52428800)throw new Error("too_large");S.size=U.size;let $=await m(S,E,I);if(!C())return;S.parentId=$;let V=ht(E,"/files/upload");if(!V)throw new Error("bad_path");let Z=`----penzor${Mr().replace(/-/g,"")}`,{head:re,tail:se}=La(Z,{parentId:$,autoRename:"true"},S.name,Ma(S.name)),ee=await r(V,{Authorization:`Bearer ${I}`,"Content-Type":`multipart/form-data; boundary=${Z}`,...S.projectSource?{"X-Project-Source":S.projectSource}:{}},re,S.localPath,U.size,se,Q=>{C()&&p(S,Q)},S.abort.signal);C()&&(ee.status===201||ee.status===200?(S.fileId=typeof ee.body?.id=="string"?ee.body.id:null,p(S,S.size),u(S,"done")):u(S,"failed",Js(ee.status,ee.body)))}function _(S,C,E,I){let U=async()=>{let V=wf(E),Z=V?E.slice(0,-V.length):E;for(let re=0;re<1e3;re++){if(!I())throw new Error("aborted");let se=Dn(C,re===0?E:`${Z} (${re})${V}`);try{await lf(S,se)}catch(ee){let Q=ee.code;if(Q==="EEXIST")continue;if(Q!=="EPERM"&&Q!=="ENOTSUP"&&Q!=="EOPNOTSUPP"&&Q!=="ENOSYS"&&Q!=="EXDEV")throw ee;if(await cf(se).then(()=>!0,()=>!1))continue;await hf(S,se)}if(!I())throw await Ks(se).catch(()=>{}),new Error("aborted");return await Ks(S).catch(()=>{}),se}throw new Error("too many duplicates")},$=a.then(U,U);return a=$.catch(()=>{}),$}async function M(S,C){let E=S.dl,{base:I,token:U}=await y(S);if(!C())return;let $=ht(I,E.path);if(!$)throw new Error("bad_path");let V=S.abort.signal,Z=E.subdir?Dn(n(),E.subdir):n();await df(Z,{recursive:!0});let re=Dn(Z,`.${S.id}-${S.attempt}.penzor-part`),se=await ff(re,"wx"),ee=!1;try{let Q=new AbortController,ge=setTimeout(()=>Q.abort(),Xs),fe=()=>{clearTimeout(ge),ge=setTimeout(()=>Q.abort(),Xs)},ye=AbortSignal.any([V,Q.signal]);try{let he=await fetch($,{headers:{Authorization:`Bearer ${U}`},signal:ye});if(!he.ok)throw new Error(he.status===401?"not_signed_in":`http_${he.status}`);let ze=he.body,Fe=Number(he.headers.get("content-length"))||S.size;if(E.mode!=="bytes"){let be=await he.json().catch(()=>null);if(E.mode==="text"){if(typeof be?.content!="string")throw new Error("bad_response");let F=Buffer.from(be.content,"utf8");await se.writeFile(F),S.size=F.length,p(S,F.length),ze=null}else{if(typeof be?.url!="string"||!/^https?:\/\//i.test(be.url))throw new Error("bad_response");let F=await fetch(be.url,{signal:ye});if(!F.ok)throw new Error(`http_${F.status}`);ze=F.body,Fe=Number(F.headers.get("content-length"))||S.size}}if(ze){S.size=Fe;let be=0;for await(let F of ze){fe();for(let Y=0;Y<F.length;){let{bytesWritten:v}=await se.write(F,Y,F.length-Y);if(v<=0)throw new Error("short_write");Y+=v}if(be+=F.length,!C())throw new Error("aborted");p(S,be)}be>S.size&&(S.size=be)}}finally{clearTimeout(ge)}if(await se.close(),!C()||(S.localPath=await _(re,Z,E.name,C),ee=!0,!C()))return;u(S,"done")}finally{ee||(await se.close().catch(()=>{}),await Ks(re).catch(()=>{}))}}let R=(S,C)=>{let E={...S,id:Mr(),attempt:0,done:0,state:C?"failed":"queued",error:C??null,abort:null,samples:[],speed:0,startedAt:null,finishedAt:C?s():null};return o.push(E),E};async function O(S){let C=[],E=async(I,U)=>{if(U.length>32)return!0;let $=await(U.length?uf(I):ja(I)).catch(()=>null);if(!$)return!0;if($.isFile())return C.push({path:I,size:$.size,relDir:U}),C.length<=2e3;if(!$.isDirectory())return!0;let V=(await pf(I).catch(()=>[])).filter(Z=>!Z.startsWith(".")).sort();for(let Z of V)if(!await E(Dn(I,Z),[...U,Fa(I)]))return!1;return!0};for(let I of S)if(!await E(I,[]))return"too_many";return C}return t.handle("penzor:device",S=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let C=Ir();return{ok:!0,name:C?decodeURIComponent(C):null}}),t.handle("penzor:upload",async(S,C)=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let E=C??{},I=Array.isArray(E.paths)?E.paths.filter(fe=>typeof fe=="string"&&bf(fe)):[],U=typeof E.parentId=="string"&&Oa.test(E.parentId)?E.parentId:null,$=typeof E.projectSource=="string"&&Pa.test(E.projectSource)?E.projectSource:null;if(!I.length)return{ok:!1,error:"no_files"};if(!U||!$)return{ok:!1,error:"bad_target"};let{base:V,token:Z,account:re}=await c();if(!Z)return{ok:!1,error:"not_signed_in"};let se=await O(I);if(se==="too_many")return{ok:!1,error:"too_many",max:2e3};if(!se.length)return{ok:!1,error:"no_files"};let ee=se.filter(fe=>fe.size<=52428800).reduce((fe,ye)=>fe+ye.size,0);try{let fe=await h(V,Z,"/storage/quota",{}),ye=Number(fe.json?.used),he=Number(fe.json?.quota);if(fe.status===200&&he>0&&ye+ee>he)return{ok:!1,error:"quota",short:ye+ee-he}}catch{}if((await c()).account!==re)return{ok:!1,error:"account_changed"};let Q=Mr(),ge=se.map(fe=>R({kind:"up",name:Fa(fe.path),size:fe.size,projectSource:$,parentId:fe.relDir.length?null:U,targetId:U,fileId:null,localPath:fe.path,batch:Q,account:re,relDir:fe.relDir},fe.size>52428800?"too_large":void 0).id);return d(),{ok:!0,ids:ge,batch:Q}}),t.handle("penzor:download",async(S,C)=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let E=C??{},I=kf.includes(E.mode)?E.mode:null,U=Pr(E.name);if(!I)return{ok:!1,error:"bad_mode"};if(!U)return{ok:!1,error:"bad_name"};let{base:$,token:V,account:Z}=await c();if(typeof E.path!="string"||!ht($,E.path))return{ok:!1,error:"bad_path"};if(!V)return{ok:!1,error:"not_signed_in"};let re=E.subdir==null?null:Pr(E.subdir),se=R({kind:"down",name:U,size:Math.max(0,Number(E.size)||0),localPath:null,batch:typeof E.batch=="string"&&E.batch.length<=64?E.batch:Mr(),account:Z,relDir:[],dl:{path:E.path,mode:I,name:U,subdir:re}});return d(),{ok:!0,id:se.id}}),t.handle("penzor:transfers",S=>t.isTrustedSender(S)?{ok:!0,items:o.map(l)}:{ok:!1,error:"untrusted"}),t.handle("penzor:transfer",(S,C)=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let E=C??{},I=o.find($=>$.id===E.id);if(!I)return{ok:!1,error:"not_found"};let U=()=>{I.abort?.abort(),I.abort=null,I.done=0,I.samples=[]};switch(E.op){case"pause":(I.state==="active"||I.state==="queued")&&(U(),I.state="paused",d());break;case"resume":I.state==="paused"&&(I.state="queued",d());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,d());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",(S,C)=>{if(!t.isTrustedSender(S))return{ok:!1,error:"untrusted"};let E=C?.which==="all";for(let I of[...o])(I.state==="done"||I.state==="canceled"||E&&I.state==="failed")&&o.splice(o.indexOf(I),1);return{ok:!0}}),t.addQuitGuard?.(S=>{let C=o.filter(E=>E.state==="active"||E.state==="queued"||E.state==="paused").length;return C?S==="zh"?{message:`\u8FD8\u6709 ${C} \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:C===1?"1 file hasn't finished transferring":`${C} files haven't finished transferring`,detail:"Quitting now stops them. You will need to start them again next time."}:null}),{list:()=>o.map(l)}}import{readFileSync as Df,writeFileSync as Of,mkdirSync as Pf,chmodSync as Mf,renameSync as $f}from"node:fs";import{join as Nf}from"node:path";import{mkdirSync as _f,readFileSync as Cf,renameSync as xf,unlinkSync as Af,writeFileSync as Tf}from"node:fs";import{dirname as Rf,join as If}from"node:path";import{randomUUID as Ua}from"node:crypto";var no=t=>If(t,"content-sync","active-account.json"),Qs=()=>Error("Invalid content sync account binding; original data was retained");function On(t){try{let e=JSON.parse(Cf(t,"utf8"));if(e?.version!==1||!(e.account===null&&e.pending===!0||typeof e.account=="string"&&/^[a-f0-9]{64}$/.test(e.account))||e.epoch!==void 0&&(typeof e.epoch!="string"||!/^[a-f0-9-]{36}$/i.test(e.epoch))||e.pending!==void 0&&typeof e.pending!="boolean"||e.pending&&!e.epoch)throw Qs();return e}catch(e){if(e?.code==="ENOENT")return null;throw Qs()}}function ro(t,e){_f(Rf(t),{recursive:!0,mode:448});let n=t+".tmp-"+Ua();try{Tf(n,JSON.stringify(e),{flag:"wx",mode:384}),xf(n,t)}finally{try{Af(n)}catch{}}}var eo=new WeakMap,to=new WeakSet;function Ha(t,e){let n=eo.get(t);return n||eo.set(t,n=new Set),n.add(e),()=>{n.delete(e)}}function so(t){if(to.has(t))throw Qs()}function en(t,e,n){if(!t.contentSync||e===n)return;let r=no(t.homeDir());try{let s=On(r);ro(r,{version:1,account:s?.account??null,epoch:Ua(),pending:!0}),to.delete(t)}catch(s){throw to.add(t),s}finally{for(let s of eo.get(t)??[])s()}}function jf(t){let e=()=>Nf(t(),"auth-accounts.json");return{read:()=>Df(e(),"utf8"),write:n=>{Pf(t(),{recursive:!0});let r=`${e()}.tmp`;Of(r,n,{encoding:"utf8",mode:384}),Mf(r,384),$f(r,e())}}}var Ba=t=>Li(t,jf(()=>t.homeDir())),qa=["homeDir","appVersion","broadcast","accountBackendState","accountTransition","accountCommit","accountClear","writeCreds","onExternalCredsChange","setTokenRefresher","readCreds"],oo=t=>qa.every(e=>typeof t[e]=="function");function io(t){let e={ok:!1,error:"untrusted"},n={loggedIn:!1,error:"untrusted"},r=Ba(t),s=0,o=()=>{let c=t.readCreds();return Cn(c.cloudUrl,c.token)},i=c=>Oe(c.cloudUrl??"",c.token??""),a=null;t.handle("auth:status",async c=>{if(!t.isTrustedSender(c))return n;let l=s,u=o(),{base:d}=await t.getCloud(),g=t.readCreds().token,p=g?await Rn(d,g):null,y=await t.accountBackendState(),{base:h}=await t.getCloud(),m=t.readCreds(),w=Cn(h,m.token)!==Cn(d,g),_=Cn(d,g);!w&&p?.status==="ok"&&p.user&&(a={key:_,user:p.user},r.rememberForsionAccount({...m,cloudUrl:d},p.user));let M=w?void 0:p?.status==="ok"?p.user:p?.status==="offline"&&a?.key===_?a.user:void 0;if(w)return{loggedIn:!!m.token,tokenValid:null,cloudUrl:h,accountId:Oe(h,m.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:m.token?"tangu-login":null,backendState:y};if(p?.status==="expired"){await t.accountTransition(async()=>{if(l!==s||o()!==u)return;let O=()=>{if(l!==s||o()!==u)throw za};try{await t.accountClear(O,()=>{en(t,t.accountId?.()??null,null),t.log("[auth] token \u5DF2\u5931\u6548(\u670D\u52A1\u7AEF 401/403),\u81EA\u52A8\u767B\u51FA"),++s,r.cancelForsionLogin(),r.forgetForsionAccount(t.readCreds()),a=null})}catch(S){if(S!==za)throw S}});let R=t.readCreds();return{loggedIn:!!R.token,tokenValid:null,cloudUrl:R.cloudUrl||d,accountId:Oe(R.cloudUrl||d,R.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:R.token?"tangu-login":null,backendState:y}}return{loggedIn:!!g,tokenValid:p&&p.status==="ok"?!0:null,cloudUrl:d,accountId:Oe(d,g),username:M?.username||null,nickname:M?.nickname||null,avatar:M?.avatar||null,membershipTier:M?.membershipTier||null,tokenSource:g?"tangu-login":null,backendState:y}}),t.handle("auth:accounts",c=>t.isTrustedSender(c)?r.forsionAccounts():[]),t.handle("auth:switchAccount",async(c,l)=>{if(!t.isTrustedSender(c))return e;if(typeof l!="string")throw new Error("Invalid account.");let u=++s;return r.cancelForsionLogin(),t.accountTransition(async()=>{let d=r.savedForsionAccount(l);return await t.accountCommit(d,()=>{if(u!==s)throw new Error("Account switch cancelled.")},()=>{en(t,t.accountId?.()??null,i(d)),r.rememberForsionAccount(d),a=null}),{ok:!0,cloudUrl:d.cloudUrl||""}})}),t.handle("auth:forsionLogin",async(c,l)=>{if(!t.isTrustedSender(c))return e;let u=++s;r.cancelForsionLogin();let{base:d}=await t.getCloud();if(u!==s)throw new Error("Sign-in cancelled.");let g=(l||d||"").trim();return{ok:!0,cloudUrl:(await r.forsionDeviceLogin(g,y=>t.broadcast("auth:device",y),(y,h)=>t.accountTransition(()=>t.accountCommit(y,()=>{if(h(),u!==s)throw new Error("Sign-in cancelled.")},()=>{en(t,t.accountId?.()??null,i(y)),r.rememberForsionAccount(y),a=null})))).cloudUrl}}),t.handle("auth:logout",async c=>t.isTrustedSender(c)?(++s,r.cancelForsionLogin(),t.accountTransition(async()=>{let{base:l}=await t.getCloud(),u=t.readCreds();return await t.accountClear(void 0,()=>{en(t,t.accountId?.()??null,null),r.forgetForsionAccount(u),a=null,l&&u.token&&fetch(`${l}/api/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${u.token}`},signal:AbortSignal.timeout(5e3)}).catch(()=>{})}),{ok:!0}})):e),t.onExternalCredsChange(({previous:c,current:l})=>{try{en(t,i(c),i(l))}catch{t.log("[content-sync] account transition could not be recorded; sync is stopped")}++s,r.cancelForsionLogin(),c.token&&!l.token&&r.forgetForsionAccount(c),a=null,r.rememberForsionAccount(l)}),t.setTokenRefresher(async c=>{let l=s,u=o(),d=t.readCreds().token;if(!br(d))return;let{base:g}=await t.getCloud(),p=await Sr(g,d,c,`desktop/${t.appVersion()}`);if(!p){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}l!==s||o()!==u||(r.rememberForsionAccount({cloudUrl:g,token:p}),t.writeCreds({cloudUrl:g,token:p}),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 za=Symbol("stale-auth-intent");import{promises as on}from"node:fs";import Ut from"node:path";import{execFile as hp}from"node:child_process";import gp from"node:os";var ao=null;function Wa(t){ao=t}function He(){if(!ao)throw new Error("amadeus sync env not set (registerAmadeus factory has not run)");return ao}var Pe=()=>He().accountId();function Pn(t=Pe()){return t?Ce().sha256Hex(t):"signed-out"}var Ye=(t=Pe())=>He().readConfig(t),gt=(t,e=Pe())=>He().writeConfig(t,e),tn=(t,e=Pe())=>He().updateConfig(t,e),Ct=(t=Pe())=>He().cloudVaultDir(t),$r=t=>He().isManagedCloudVault(t);function Ff(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],a=n[i]||[],c=0,l=s[0];for(let u of a){let d;for(d=c;d<s.length&&!(s[d].buffer2index<u&&(d===s.length-1||s[d+1].buffer2index>u));d++);if(d<s.length){let g={buffer1index:o,buffer2index:u,chain:s[d]};if(c===s.length?s.push(l):s[c]=l,c=d+1,l=g,c===s.length)break}}s[c]=l}return s[s.length-1]}function Va(t,e){let n=Ff(t,e),r=[],s=t.length,o=e.length;for(let i=n;i!==null;i=i.chain){let a=s-i.buffer1index-1,c=o-i.buffer2index-1;s=i.buffer1index,o=i.buffer2index,(a||c)&&r.push({buffer1:[s+1,a],buffer1Content:t.slice(s+1,s+1+a),buffer2:[o+1,c],buffer2Content:e.slice(o+1,o+1+c)})}return r.reverse(),r}function Lf(t,e,n){let r=[];function s(c,l){r.push({ab:l,oStart:c.buffer1[0],oLength:c.buffer1[1],abStart:c.buffer2[0],abLength:c.buffer2[1]})}Va(e,t).forEach(c=>s(c,"a")),Va(e,n).forEach(c=>s(c,"b")),r.sort((c,l)=>c.oStart-l.oStart);let o=[],i=0;function a(c){c>i&&(o.push({stable:!0,buffer:"o",bufferStart:i,bufferLength:c-i,bufferContent:e.slice(i,c)}),i=c)}for(;r.length;){let c=r.shift(),l=c.oStart,u=c.oStart+c.oLength,d=[c];for(a(l);r.length;){let g=r[0],p=g.oStart;if(p>u)break;u=Math.max(u,p+g.oLength),d.push(r.shift())}if(d.length===1){if(c.abLength>0){let g=c.ab==="a"?t:n;o.push({stable:!0,buffer:c.ab,bufferStart:c.abStart,bufferLength:c.abLength,bufferContent:g.slice(c.abStart,c.abStart+c.abLength)})}}else{let g={a:[t.length,-1,e.length,-1],b:[n.length,-1,e.length,-1]};for(;d.length;){c=d.shift();let _=c.oStart,M=_+c.oLength,R=c.abStart,O=R+c.abLength,S=g[c.ab];S[0]=Math.min(R,S[0]),S[1]=Math.max(O,S[1]),S[2]=Math.min(_,S[2]),S[3]=Math.max(M,S[3])}let p=g.a[0]+(l-g.a[2]),y=g.a[1]+(u-g.a[3]),h=g.b[0]+(l-g.b[2]),m=g.b[1]+(u-g.b[3]),w={stable:!1,aStart:p,aLength:y-p,aContent:t.slice(p,y),oStart:l,oLength:u-l,oContent:e.slice(l,u),bStart:h,bLength:m-h,bContent:n.slice(h,m)};o.push(w)}i=u}return a(e.length),o}function Ya(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=Lf(t,e,n),a=[];function c(){a.length&&o.push({ok:a}),a=[]}function l(u,d){if(u.length!==d.length)return!1;for(let g=0;g<u.length;g++)if(u[g]!==d[g])return!1;return!0}return i.forEach(u=>{u.stable?a.push(...u.bufferContent):r.excludeFalseConflicts&&l(u.aContent,u.bContent)?a.push(...u.aContent):(c(),o.push({conflict:{a:u.aContent,aIndex:u.aStart,o:u.oContent,oIndex:u.oStart,b:u.bContent,bIndex:u.bStart}}))}),c(),o}function Nr(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,a=o>0?s.slice(o):"",c=u=>String(u).padStart(2,"0"),l=`${e.getFullYear()}-${c(e.getMonth()+1)}-${c(e.getDate())} ${c(e.getHours())}${c(e.getMinutes())}`;return`${r}${i} (conflict ${l})${a}`}function Uf(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 Hf(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 jr(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 Ga(t,e,n){let r=Ya(t.split(`
204
209
  `),e.split(`
205
210
  `),n.split(`
206
211
  `),{excludeFalseConflicts:!0}),s=[];for(let o of r){if(o.conflict)return null;o.ok&&s.push(...o.ok)}return s.join(`
207
- `)}function oo(t,e,n=200){return t>=n||e>=5&&t>=Math.max(5,Math.ceil(e/2))}var za=["cycles","cycleMsTotal","errAuth","errOffline","errVaultMissing","errScan","errMirrorMissing","errHttp","errTimeout","errBlocked","errOther","conflicts","skippedTooLarge","skippedNotFound","skippedExists","skippedOther","massDeleteGuard","uploads","downloads"];function Ba(t){return t==="TOO_LARGE"?"skippedTooLarge":t==="ASSET_404"?"skippedNotFound":t==="EXISTS"?"skippedExists":/^http \d+$/.test(t)?"errHttp":t==="timeout"?"errTimeout":"skippedOther"}function qa(t,e){if(t==="offline")return"errOffline";if(t==="auth-required")return e==="not-logged-in"?null:"errAuth";if(t!=="error")return null;let n=e??"";return n.startsWith("vault-missing")?"errVaultMissing":n.startsWith("scan-failed")?"errScan":n.startsWith("mirror-missing")?"errMirrorMissing":"errOther"}function jr(t,e=0){if(/^(account_changed|content_sync_closed|paused)$/.test(t)||/^File exceeds \d+ MB/.test(t))return null;if(t==="not_signed_in"||e===401||e===403)return"errAuth";let n=/^content_http_(\d{3})$/.exec(t);return n?n[1]==="401"||n[1]==="403"?"errAuth":"errHttp":/timeout|timed out|aborted due to timeout/i.test(t)?"errTimeout":/fetch failed|econn|enotfound|eai_again|network|socket/i.test(t)?"errOffline":/^Sync root (unavailable|changed|is not a directory)|^content_roots_changed/.test(t)?"errVaultMissing":e?"errHttp":"errOther"}function Fr(t){let e=null;return{error(n){n!==e&&(e=n,t?.(n))},ok(){e=null}}}var Tf=/[\u0000-\u001f\u007f]/;function xt(t){let e=t.replace(/\\/g,"/").normalize("NFC").trim();if(e=e.replace(/\/+$/,""),!e||e.length>512||e.startsWith("/")||Tf.test(e))return null;let n=e.split("/");for(let r of n)if(!r||r==="."||r==="..")return null;return n.join("/")}function io(t,e){let n=t.replace(/\\/g,"/").normalize("NFC");return e===""?xt(n):n.startsWith(`${e}/`)?xt(n.slice(e.length+1)):null}function Wa(t,e){return e===""?t:`${e}/${t}`}function $n(t){return!!(t===".DS_Store"||t==="Icon\r"||t===".sync-trash"||/\.tmp-\d+-\d+-\d+$/.test(t)||/^\..+\.lock$/.test(t))}function Xe(t){return/\.md$/i.test(t)?"page":/\.db$/i.test(t)?"db":"binary"}var At=t=>t==="page"||t==="db";var Rf=1024,xe=class extends Error{status;body;constructor(e,n,r){super(`cloud http ${e} on ${r}`),this.status=e,this.body=n}},Va=t=>12e4+Math.ceil(t/256);function If(t,e){let n=AbortSignal.timeout(t);if(!e)return n;let r=new AbortController;for(let s of[n,e])s.addEventListener("abort",()=>r.abort(s.reason),{once:!0});return r.signal}function Ya(t){let e=`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus`,n=()=>t.getToken?.()??t.token,r=async(i,a)=>{let l=n();for(let c=0;;c++){let u={...a.headers,Authorization:`Bearer ${l}`},f=await fetch(i,{...a,headers:u});if(n(),f.status!==401||f.redirected)return f;let g=await f.text(),p=n();if(p===l||c>0)return new Response(g,{status:f.status,statusText:f.statusText,headers:f.headers});l=p}},s=async(i,a,l)=>{let c={Authorization:`Bearer ${t.token}`,...l?.headers};i!=="GET"&&(c["X-Amadeus-Client"]=t.clientId);let u;l?.json!==void 0?(c["Content-Type"]="application/json",u=JSON.stringify(l.json),u.length>=Rf&&(c["Content-Encoding"]="gzip",u=await $i(u))):l?.form&&(u=l.form);let f=await r(a,{method:i,headers:c,body:u,signal:If(l?.timeoutMs??3e4,l?.signal)});if(!f.ok){let p=null;try{p=await f.json()}catch{}throw n(),new xe(f.status,p,a)}let g=await f.json();return n(),g},o=i=>new URLSearchParams(i).toString();return{clientId:t.clientId,async listVaults(){return((await s("GET",`${e}/vaults`)).vaults??[]).map(a=>({id:String(a.id),name:String(a.name),lastChangeSeq:Number(a.lastChangeSeq??0)}))},async tree(i){let a=await s("GET",`${e}/vaults/${i}/tree`);if(!Array.isArray(a.entries))throw new Error("server too old: tree has no entries[] (deploy the amadeus microserver update)");return{folders:a.folders??[],seq:Number(a.seq??0),maxFileBytes:Number.isInteger(a.maxFileBytes)&&a.maxFileBytes>0?a.maxFileBytes:void 0,entries:a.entries.map(l=>({path:String(l.path),kind:l.kind,seq:Number(l.seq??0),hash:l.hash??null,size:Number(l.size??0)}))}},async getFile(i,a){let l=await s("GET",`${e}/vaults/${i}/file?${o({path:a})}`);return{content:String(l.content??""),seq:Number(l.seq??0),hash:l.hash??null}},putFile(i,a,l,c,u=!1){return s("PUT",`${e}/vaults/${i}/file`,{json:{path:a,content:l,baseSeq:c,...u?{force:!0}:{}}})},async deleteFile(i,a,l,c){let u={path:a};l!==void 0&&(u.baseSeq=String(l)),await s("DELETE",`${e}/vaults/${i}/file?${o(u)}`,c?.confirmed?{headers:{"X-Amadeus-Delete-Confirmed":"1"}}:void 0)},move(i,a,l){return s("POST",`${e}/vaults/${i}/move`,{json:{from:a,to:l}})},renameFolder(i,a,l){return s("POST",`${e}/vaults/${i}/folders/rename`,{json:{path:a,newName:l}})},moveFolder(i,a,l){return s("POST",`${e}/vaults/${i}/folders/move`,{json:{path:a,dest:l}})},async deleteFolder(i,a){await s("DELETE",`${e}/vaults/${i}/folders?${o({path:a})}`)},putBinary(i,a,l,c){let u=new FormData;return u.set("path",a),c?.ifAbsent&&u.set("ifAbsent","true"),c?.baseSeq!==void 0&&u.set("baseSeq",String(c.baseSeq)),u.set("file",new Blob([new Uint8Array(l)]),a.split("/").pop()||"file"),s("POST",`${e}/vaults/${i}/binary`,{form:u,timeoutMs:Va(l.length),signal:c?.signal})},async listVersions(i,a){return((await s("GET",`${e}/vaults/${i}/file/versions?${o({path:a})}`)).versions??[]).map(c=>({id:String(c.id),seq:Number(c.seq??0)}))},async getVersion(i,a){let l=await s("GET",`${e}/vaults/${i}/file/versions/${a}`);return String(l.content??"")},async getAsset(i,a,l){let c=new AbortController;l?.addEventListener("abort",()=>c.abort(l.reason),{once:!0});let u=()=>c.abort(new DOMException("Asset download timed out","TimeoutError")),f=setTimeout(u,12e4);try{let g=await r(`${e}/vaults/${i}/asset?${o({ref:a})}`,{headers:{Authorization:`Bearer ${t.token}`},signal:c.signal});if(!g.ok)throw new xe(g.redirected&&(g.status===401||g.status===403)?502:g.status,null,"asset:"+a);clearTimeout(f),f=setTimeout(u,Va(Number(g.headers.get("content-length"))||0));let p=new Uint8Array(await g.arrayBuffer());return n(),p}finally{clearTimeout(f)}},async changes(i,a){let l=await s("GET",`${e}/vaults/${i}/changes?${o({since:String(a)})}`);return{changes:l.changes??[],seq:Number(l.seq??0)}}}}function Ga(t,e){let n=!1,r=0,s=null,o=null,i=()=>`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus/vaults/${t.vaultId}/events?since=${e.getSince()}`,a=c=>{if(n)return;s?.abort(),e.onDown(c);let u=Math.min(3e4,1e3*2**r)*(.7+Math.random()*.6);r++,o=setTimeout(()=>void l(),u)},l=async()=>{if(n)return;s=new AbortController;let c;try{if(c=await fetch(i(),{headers:{Authorization:`Bearer ${t.getToken?.()??t.token}`,Accept:"text/event-stream"},signal:s.signal}),n){await c.body?.cancel();return}t.getToken?.()}catch(m){a(m);return}if(!c.ok||!c.body){a(new Error(`sse http ${c.status}`));return}r=0,e.onOpen();let u=c.body.getReader(),f=new TextDecoder,g="",p="",y=[],h=()=>{if(t.getToken?.(),!y.length&&!p)return;let m=y.join(`
208
- `),w=p||"message";p="",y=[];let _=null;try{_=m?JSON.parse(m):null}catch{return}w==="hello"?e.onHello(Number(_?.seq??0)):w==="change"?e.onChange(_):w==="reset"?e.onReset():w==="presence"?e.onPresence?.(_):w==="presence-roster"&&e.onPresenceRoster?.(_)};try{for(;;){let{done:m,value:w}=await u.read();if(m)break;for(g+=f.decode(w,{stream:!0});;){let _=g.indexOf(`
209
- `);if(_<0)break;let $=g.slice(0,_).replace(/\r$/,"");if(g=g.slice(_+1),$==="")h();else{if($.startsWith(":"))continue;$.startsWith("event:")?p=$.slice(6).trim():$.startsWith("data:")&&y.push($.slice(5).replace(/^ /,""))}}}}catch(m){n||a(m);return}a(new Error("sse stream ended"))};return l(),{stop:()=>{n=!0,o&&clearTimeout(o),s?.abort()}}}var Mn=t=>Ce().path.join(He().userDataDir(),He().isDevMode()?`${t}.dev.json`:`${t}.json`),ao=Mn,Lt=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),Lr=t=>typeof t=="number"&&Number.isSafeInteger(t)&&t>=0,Ja=t=>typeof t=="number"&&Number.isInteger(t)&&t>=0,Df=t=>Lt(t)&&Ja(t.dev)&&Ja(t.ino)&&t.ino>0,Ur=t=>typeof t=="string"&&xt(t)===t,Ka=t=>typeof t=="string"&&t.length>0,Of=t=>Lt(t)&&Lr(t.seq)&&Ka(t.hash)&&Lr(t.size)&&typeof t.mtimeMs=="number"&&Number.isFinite(t.mtimeMs),Pf=t=>Lt(t)&&Ur(t.from)&&Ur(t.to)&&(t.kind==="file"||t.kind==="folder")&&(t.hashes===void 0||Lt(t.hashes)&&Object.values(t.hashes).every(Ka));async function lo(t){let e;try{e=await Ce().fs.readFile(ao(t),"utf8")}catch(r){if(r?.code==="ENOENT")return null;throw r}let n;try{n=JSON.parse(e)}catch{throw Error("Invalid cloud vault sync state; original data was retained")}if(!Lt(n)||typeof n.vaultRoot!="string"||!n.vaultRoot||typeof n.vaultId!="string"||!n.vaultId||typeof n.folder!="string"||n.rootIdentity!==void 0&&!Df(n.rootIdentity)||!Lt(n.files)||!Object.entries(n.files).every(([r,s])=>Ur(r)&&Of(s))||n.cursor!==void 0&&!Lr(n.cursor)||n.lastSyncAt!=null&&!Lr(n.lastSyncAt)||n.pending!==void 0&&(!Lt(n.pending)||!Object.entries(n.pending).every(([r,s])=>Ur(r)&&(s==="local"||s==="remote")))||n.moves!==void 0&&(!Array.isArray(n.moves)||!n.moves.every(Pf)))throw Error("Invalid cloud vault sync state; original data was retained");return{...n,cursor:n.cursor??0,lastSyncAt:n.lastSyncAt??null}}function Xa(t){let e=null,n=null,r=Promise.resolve(),s=null,o=()=>{if(!e)return r;let i=e,a=JSON.stringify(e);return e=null,r=r.then(async()=>{try{let l=ao(t),c=`${l}.tmp-${Ce().tmpTag()}-${Date.now()}-0`;await Ce().fs.writeFile(c,a,"utf8"),await Ce().fs.rename(c,l),s=null}catch(l){e??=i,s=l}}),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 Za(t){try{await Ce().fs.unlink(ao(t))}catch{}}var $f=5*1024*1024,Mf=5*1024*1024,Nf=3e4,jf=5e3,Ff=5*6e4,Lf=2500,Uf=3e3,Hf=5,zf=256*1024,Bf=5,Qa=1024*1024,el=200,qf=6e4,Wf=50,Vf=".sync-trash",Tt=t=>Ce().sha256Hex(t);function Nn(t,e={localRoot:Ct(),shadowName:`amadeus-sync-${Pn()}`,vaultId:"first",serverDir:"",excludePrefixes:["\u4E0E\u6211\u5171\u4EAB/"]}){let n=d=>{let b=io(d,"");if(!b)return null;for(let x of e.excludePrefixes??[])if(b===x.replace(/\/$/,"")||b.startsWith(x))return null;if(e.ignoreNames?.length&&b.split("/").some(x=>e.ignoreNames.includes(x)))return null;let k=e.serverDir?`${e.serverDir}/${b}`:b;return e.inScope&&!e.inScope(k,Xe(k))?null:k},r=d=>{let b;if(e.serverDir){if(!d.startsWith(`${e.serverDir}/`))return null;b=d.slice(e.serverDir.length+1)}else{for(let k of e.excludePrefixes??[])if(d.startsWith(k))return null;b=d}return b.split("/").some(k=>$n(k)||!!e.ignoreNames?.includes(k))?null:b},s=(d,b)=>!e.inScope||e.inScope(d,b),o=e.accountId??Pe(),{fs:i,path:a}=Ce(),l=d=>i.access(d).then(()=>!0,()=>!1),c=!1,u=0,f=Promise.resolve(),g=new Set,p="disabled",y=null,h=null,m=null,w=null,_=null,$=()=>{let d=t.loadCreds();if(!_||o!==Pe()||!d.token||d.cloudUrl?.replace(/\/+$/,"")!==_.cloudUrl.replace(/\/+$/,""))throw new xe(401,{code:"ACCOUNT_CHANGED"},"sync-session");return d.token},R=null,O=0,S=new Map,C=null,E=Xa(e.shadowName),I=new Map,U=!1,M=!1,V=[],Z=(d,b,k)=>{try{t.onHealth?.(d,b,k)}catch{}},re=Fr(Z),se=0,ee=()=>{M||Z("massDeleteGuard"),M=!0},Q=()=>{h&&(h.pending=I.size?Object.fromEntries(I):void 0,E.save(h))},ge=()=>{M=!1,V.length=0},fe=()=>{if(M)return!0;let d=Date.now();for(;V.length&&d-V[0]>qf;)V.shift();return V.length>=Wf?(ee(),!0):!1},ye=[],he=new Set,ze=!1,Fe=null,be=null,F=null,Y=null,v=()=>{!c||Y||(Y=setTimeout(()=>{Y=null,t.onStatus(jt())},200))},A=(d,b)=>{let k=p;p=d,b!==void 0&&(y=b),T(k,d),v()},T=(d,b)=>{if(b==="syncing"&&d!=="syncing"&&(se=Date.now()),b==="idle"&&d==="syncing"&&(Z("cycles"),Z("cycleMsTotal",Math.max(0,Date.now()-se))),b==="idle"||b==="disabled"){re.ok();return}let k=qa(b,y);k&&re.error(k)},D=(d,b)=>{S.set(d,b),Z(Ba(b),1,d)},P=(d,b=!1)=>{if(c){if(d.key){if(he.has(d.key))return;he.add(d.key)}b?ye.unshift(d):ye.push(d),te()}},B=new Map,H=d=>{if(!c)return;let b=(h?.files[d]?.size??0)>zf,k=(e.pushQuietMs??Uf)*(b?Bf:1),x=Date.now(),N=B.get(d);N&&clearTimeout(N.timer);let L=N?.since??x,W=Math.max(0,Math.min(k,L+k*Hf-x)),j=setTimeout(()=>{B.delete(d),P({key:d,run:()=>_e(d,!0)})},W);B.set(d,{timer:j,since:L}),v()},z=()=>{for(let{timer:d}of B.values())clearTimeout(d);B.clear()},J=d=>!(d instanceof xe)||d.status>=500||d.status===0,G=d=>d instanceof xe&&(d.status===401||d.status===403),K=(d,b)=>{D(d,b?.body?.code||`http ${b?.status}`),v()},te=async()=>{if(!ze){ze=!0;try{for(;ye.length;){(p==="idle"||p==="starting")&&A("syncing");let d=ye.shift();d.key&&he.delete(d.key);try{await d.run()}catch(b){if(!c)return;if(G(b)){ye.length=0,he.clear(),gr(),A("auth-required","login-expired");return}if(J(b)){P(d,!0),gr(),A("offline",b?.message||"network error"),ue();return}K(d.key??"(op)",b)}}c&&p==="syncing"&&(h&&(h.lastSyncAt=Date.now(),E.save(h)),A("idle",null))}finally{ze=!1;for(let d of g)d();g.clear()}}},ue=()=>{!c||Fe||(Fe=setTimeout(()=>{Fe=null,En()},Nf))},ne=new Map,me=0,ie=null,Be=()=>!!be||!!ie||!c,Nt=d=>d instanceof xe&&d.status>=500||d?.name==="TimeoutError",Yt=e.pushRetryMs??jf,Me=(d,b)=>{(b||!ne.has(d))&&ne.set(d,b)},pi=(d,b,k)=>{D(d,b instanceof xe?`http ${b.status}`:"timeout"),Me(d,k),me=Math.min(me*2||Yt,Ff),be=setTimeout(lr,me),v()},hi=(d,b,k)=>{let x=new AbortController,N=b(x.signal).then(W=>()=>W,W=>()=>{throw W}),L={path:d,abort:x,after:[],settle:async()=>{let W=await N;if(ie===L){ie=null;try{await k(W)}catch(j){if(G(j)||J(j))throw j;K(d,j)}finally{for(let j of L.after)P(j);gi(d)}}}};ie=L,N.then(()=>P({run:L.settle}))},Gt=(d,b)=>{for(let[k,x]of[...ne])!x||!qe(k,d)||(ne.delete(k),S.delete(k),b!==null&&ne.set(b+k.slice(d.length),x));v()},lr=()=>{be=null;let[d]=ne;if(d===void 0)return;let[b]=d;he.delete(b),P({key:b,run:async()=>{if(ie?.path===b)return;let k=ne.get(b),x=!k&&ne.delete(b);(k||x)&&S.delete(b);try{k?await st(b,k.seq):x&&await _e(b,!0)}finally{x&&We(b)&&Me(b),gi(b)}}})},gi=d=>{if(!Be())if(ne.has(d)){let b=ne.get(d);ne.delete(d),ne.set(d,b),be=setTimeout(lr,me||Yt)}else lr()},Re=d=>{if(!R||!h)throw new Error("engine not bound");let b=r(d);if(b===null)throw new Error("path outside binding: "+d);let k=a.resolve(R,Wa(b,h.folder)),x=a.relative(R,k);if(x.startsWith("..")||a.isAbsolute(x))throw new Error("path escapes vault: "+d);return k},cr=d=>({size:d,mtimeMs:-1}),mi=async d=>{try{let b=await i.stat(d);return b.isFile()?{size:b.size,mtimeMs:Math.floor(b.mtimeMs)}:null}catch{return null}},yu=async d=>{if(!i.lstat||!R)return mi(d);let b=a.relative(R,d).split(a.sep),k=R;for(let[x,N]of b.entries()){k=a.join(k,N);let L=await i.lstat(k).catch(W=>{if(W?.code==="ENOENT")return null;throw W});if(!L)return null;if(L.isSymbolicLink())throw Error("Cloud vault sync does not follow symbolic links");if(x===b.length-1&&L.isFile())return{size:L.size,mtimeMs:Math.floor(L.mtimeMs)};if(x===b.length-1||!L.isDirectory())throw Error("Cloud vault sync path is not a regular file")}return null},wu=0,yi=async(d,b,k,x)=>{await i.mkdir(a.dirname(d),{recursive:!0});let N=`${d}.tmp-${Ce().tmpTag()}-${Date.now()}-${wu++}`;await i.writeFile(N,b);let L=await mi(N)??cr(ks(b));if(!x())return await i.rm(N,{force:!0}),null;try{let W=Ce().compareAndReplace;if(!W)throw new Error("Host does not support safe cloud download commits");return await W(N,d,k,x)?L:null}finally{await i.rm(N,{force:!0})}},wi=async d=>{let b;try{b=await i.readdir(d,{withFileTypes:!0})}catch{return}for(let k of b)k.isDirectory()&&await wi(a.join(d,k.name));try{await i.rmdir(d)}catch{}},vt=async d=>{let b=Re(d),k=await yu(b);if(!await Et())throw Error("Cloud vault sync root is unavailable or changed");if(i.lstat&&!k)return null;let x;try{x=await i.readFile(b)}catch(L){if(L?.code!=="ENOENT")throw L;if(!await Et())throw Error("Cloud vault sync root is unavailable or changed");return null}return{hash:At(Xe(d))?Tt(_t(x)):Tt(x),size:k?.size??x.length,mtimeMs:k?.mtimeMs??-1,buf:x}},kt=async(d,b,k,x)=>{h&&(h.files[d]={seq:b,hash:k,size:x.size,mtimeMs:x.mtimeMs},E.save(h))},Ke=d=>{h&&d in h.files&&(delete h.files[d],E.save(h))},st=async(d,b)=>{if(!m||!h||We(d))return;let k=ve,x=Xe(d);if(At(x)){let j;try{j=await m.getFile(h.vaultId,d),Z("downloads")}catch(X){if(X instanceof xe&&X.status===404){await ws(d);return}throw X}await bi(d,x,j.content,j.seq,j.hash??Tt(j.content),k);return}if(Be()){Me(d,{seq:b}),v();return}let{vaultId:N}=h,L=m,W={seq:b};ne.set(d,W),hi(d,j=>L.getAsset(N,d,j),async j=>{let X=ne.get(d)===W,q;try{q=j(),me=0,Z("downloads")}catch(oe){if(!X)return;if(ne.delete(d),oe instanceof xe&&oe.status===404){D(d,"ASSET_404"),v();return}if(Nt(oe)){pi(d,oe,{seq:b});return}throw oe}X&&await bi(d,x,q,b??0,Tt(q),k)}),v()},bi=async(d,b,k,x,N,L)=>{if(!h)return;let W=async pe=>{await kt(d,x,N,pe),ne.get(d)&&(ne.delete(d),S.delete(d))},j=await vt(d);if(L!==ve||We(d))return;if(j&&j.hash===N){await W(j);return}let X=h.files[d];if(j&&X&&N===X.hash&&j.hash!==X.hash){await W(cr(X.size)),P({key:d,run:()=>_e(d)});return}let q=j?Tt(j.buf):null;if(j&&(!X||j.hash!==X.hash)){if(X&&b==="page"&&typeof k=="string"&&await bu(d,X,j,k,x,N,()=>L===ve&&!We(d))||L!==ve||We(d)||!await Su(d,()=>L===ve&&!We(d)))return;q=null}let oe=await yi(Re(d),k,q,()=>c&&L===ve&&!We(d));if(!oe){P({key:d,run:()=>_e(d)});return}await W(oe)},bu=async(d,b,k,x,N,L,W)=>{try{if(!m||!h||k.buf.length>Qa||x.length>Qa)return!1;let X=(await m.listVersions(h.vaultId,d)).find(pe=>pe.seq===b.seq);if(!X)return!1;let q=await m.getVersion(h.vaultId,X.id);if(Tt(q)!==b.hash)return!1;let oe=Ha(_t(k.buf),q,x);return oe===null?!1:await yi(Re(d),oe,Tt(k.buf),()=>c&&W())?(await kt(d,N,L,cr(ks(oe))),P({key:d,run:()=>_e(d)}),!0):(P({key:d,run:()=>_e(d)}),!0)}catch{return!1}},Su=async(d,b)=>{let k=xt(Mr(d,new Date));if(!k)return!0;let x=k.lastIndexOf("."),N=x>k.lastIndexOf("/"),L=N?k.slice(0,x):k,W=N?k.slice(x):"",j=k,X=Ce().existsSync;if(X)for(let q=2;X(Re(j));q++)j=`${L}-${q}${W}`;else for(let q=2;await l(Re(j));q++)j=`${L}-${q}${W}`;if(!b())return!1;try{await i.rename(Re(d),Re(j))}catch(q){if(q?.code==="ENOENT")return!0;throw q}return O++,Z("conflicts"),P({key:j,run:()=>_e(j)}),v(),!0},Si=async d=>{if(!R)return;let b=Re(d),k=r(d)??d,x=a.join(R,Vf,new Date().toISOString().slice(0,10),...k.split("/")),N=await l(x)?`${x}.${Date.now()}`:x;try{await i.mkdir(a.dirname(N),{recursive:!0}),await i.rename(b,N)}catch(L){if(L?.code==="ENOENT")return;throw new Error(`\u8F6F\u5220\u5931\u8D25,\u4FDD\u7559\u672C\u5730\u6587\u4EF6 ${b}: ${L?.message??String(L)}`)}},ws=async d=>{if(!h)return;Gt(d,null);let b=await vt(d);if(We(d))return;let k=h.files[d]??null,x=Nr(b?.hash??null,k,null);if(x.kind==="deleteLocal"){if(!U&&fe()){I.set(d,"local"),Q(),v();return}V.push(Date.now()),await Si(d),Ke(d)}else x.kind==="pushCreate"?(Ke(d),P({key:d,run:()=>_e(d)})):Ke(d)},vi=(d,b)=>{if(h){Gt(d,b);for(let k of Object.keys(h.files))if(k===d||k.startsWith(`${d}/`)){let x=b+k.slice(d.length);h.files[x]=h.files[k],delete h.files[k]}E.save(h)}},ki=async d=>{if(!m||!h||d.seq<=h.cursor||!await Et())return;if(d.origin.client&&m.clientId===d.origin.client){h.cursor=d.seq,E.save(h);return}let b=d.type==="structure"?"folder":d.type,k=N=>r(N)!==null&&s(N,b);if(!k(d.path)&&!(d.newPath&&k(d.newPath))){h.cursor=d.seq,E.save(h);return}let x=d.path;if(d.op!=="write"&&d.op!=="mkdir"){for(;ie&&(qe(ie.path,x)||d.newPath&&qe(ie.path,d.newPath));)await ie.settle();if(!c)return}switch(d.op){case"write":await st(x,d.fileSeq);break;case"delete":await ws(x);break;case"move":{let N=d.newPath;if(!N)break;let L=h.files[x],W=await vt(x),j=!!ne.get(x);if(Gt(x,N),j&&Me(N,{seq:d.fileSeq}),W&&L)try{await i.mkdir(a.dirname(Re(N)),{recursive:!0}),await i.rename(Re(x),Re(N)),h.files[N]={...L,seq:j?L.seq:d.fileSeq??L.seq},delete h.files[x],E.save(h)}catch{await st(N,d.fileSeq)}else Ke(x),await st(N,d.fileSeq);break}case"mkdir":await i.mkdir(Re(x),{recursive:!0});break;case"rename-folder":case"move-folder":{let N=d.newPath;if(!N)break;try{await i.mkdir(a.dirname(Re(N)),{recursive:!0}),await i.rename(Re(x),Re(N))}catch{}vi(x,N);break}case"delete-folder":{let N=`${x}/`;for(let L of Object.keys(h.files))(L===x||L.startsWith(N))&&await ws(L);Gt(x,null),await wi(Re(x));break}}if(h.cursor=d.seq,E.save(h),d.op==="move"||d.op==="rename-folder"||d.op==="move-folder"||d.op==="delete"||d.op==="delete-folder")try{await t.onRemoteApplied?.(d)}catch{}},vu=async(d,b,k)=>{let x=Number(b?.seq??0),N=b?.content??null;if(N!==null&&Tt(N)===k.hash){await kt(d,x,k.hash,k);return}if(N===null&&x===0){if(!h?.files[d]){D(d,b?.code||"EXISTS"),v();return}Ke(d),P({key:d,run:()=>_e(d)});return}await st(d,x)},ur=async(d,b)=>{if(!m||!h)return;let k=await vt(d);if(!k){P({key:d,run:()=>_e(d)});return}if(k.size>$f){D(d,"TOO_LARGE"),v();return}let x=_t(k.buf);try{let N=await m.putFile(h.vaultId,d,x,b);Z("uploads"),S.delete(d),await kt(d,N.seq,N.hash??k.hash,k)}catch(N){if(N instanceof xe&&N.status===409){await vu(d,N.body,k);return}throw N}},dr=async(d,b)=>{if(!m||!h)return;let k=await vt(d);if(!k){P({key:d,run:()=>_e(d)});return}if(k.size>(C??Mf)){D(d,"TOO_LARGE"),v();return}if(Me(d),v(),Be())return;let{vaultId:x}=h,N=m;hi(d,L=>N.putBinary(x,d,k.buf,{baseSeq:b,signal:L}),async L=>{if(h){ne.get(d)||ne.delete(d);try{let W=L();me=0,Z("uploads"),S.delete(d),await kt(d,W.seq,k.hash,k)}catch(W){if(Nt(W)){pi(d,W);return}if(!(W instanceof xe)||W.status!==409)throw W;let j=Number(W.body?.seq??0),X=W.body?.hash??null;if(X!==null&&X===k.hash){await kt(d,j,k.hash,k);return}if(j===0){if(!h.files[d]){D(d,W.body?.code||"EXISTS"),v();return}Ke(d),P({key:d,run:()=>_e(d)});return}await st(d,j)}}})},Ei=async d=>{if(!m||!h||We(d))return;let b=ve,k=h.files[d];if(k){if(At(Xe(d)))try{let x=await m.getFile(h.vaultId,d);if(x.seq!==k.seq){await st(d,x.seq);return}}catch(x){if(x instanceof xe&&x.status===404){Ke(d);return}throw x}if(!(!await Et()||b!==ve||We(d))){try{await m.deleteFile(h.vaultId,d,k.seq,{confirmed:U})}catch(x){if(x instanceof xe&&x.status===409){await st(d,Number(x.body?.seq??0)||null);return}if(x instanceof xe&&x.status===429&&x.body?.code==="MASS_DELETE_BLOCKED"){I.set(d,"remote"),ee(),Q(),v();return}throw x}Ke(d)}}},bs=d=>i.stat(d).catch(b=>{if(b?.code==="ENOENT")return null;throw b}),_i=d=>{let b=h?.rootIdentity,k=d!==null&&d.isDirectory();return k&&(!b||d.dev===b.dev&&d.ino===b.ino)?!0:(A("error",`${k?"vault-changed":"vault-missing"}: ${R}`),ue(),!1)},Et=async()=>!!R&&_i(await bs(R)),ve=0,fr=new Set,pr=new Map,Le=d=>JSON.stringify([d.from,d.to]),qe=(d,b)=>d===b||d.startsWith(`${b}/`),We=d=>[...h?.moves??[],...fr].some(b=>qe(d,b.from)||qe(d,b.to)),pt=()=>!!(h?.moves?.length||fr.size),hr=async d=>{if(!m||!h)return;let{from:b,to:k,kind:x}=d;if(r(b)===null||r(k)===null)throw new Error("Invalid queued cloud move");if(ie&&(qe(ie.path,b)||qe(ie.path,k))){ie.after.push({key:`move:${Le(d)}`,run:()=>hr(d)});return}d.hashes??=Object.fromEntries(Object.entries(h.files).filter(([j])=>qe(j,b)).map(([j,X])=>[j.slice(b.length),X.hash])),E.save(h),await E.flush(!0);let N,L=!1;try{if(x==="folder"){let j=a.posix.dirname(b)==="."?"":a.posix.dirname(b),X=a.posix.dirname(k)==="."?"":a.posix.dirname(k);j===X?await m.renameFolder(h.vaultId,b,a.posix.basename(k)):await m.moveFolder(h.vaultId,b,X)}else{let j=await m.move(h.vaultId,b,k);N=Number(j.seq)}}catch(j){if(!(j instanceof xe)||j.status!==404)throw j;let X=await m.tree(h.vaultId);if(X.entries.some(pe=>qe(pe.path,b))||X.folders.some(pe=>qe(pe,b)))throw j;let oe=X.entries.find(pe=>pe.path===k);if(N=oe?.seq,L=!oe&&!X.entries.some(pe=>qe(pe.path,k))&&!X.folders.some(pe=>qe(pe,k)),!L){let pe=Object.entries(d.hashes);if(!(pe.length>0&&pe.every(([ot,Kt])=>X.entries.some(Xt=>Xt.path===k+ot&&Xt.hash===Kt))))throw new xe(409,{code:"MOVE_DESTINATION_CHANGED"},"local-move")}}if(L){for(let j of Object.keys(h.files))qe(j,b)&&delete h.files[j];Gt(b,null)}else vi(b,k),N!==void 0&&h.files[k]&&!ne.get(k)&&(h.files[k].seq=N);h.moves=(h.moves??[]).filter(j=>Le(j)!==Le(d)),E.save(h);try{await E.flush(!0)}catch(j){throw h.moves.unshift(d),E.save(h),j}let W=pr.get(Le(d));pr.delete(Le(d)),W?.(),We(k)||(x==="folder"?await Ss():await _e(k))},_e=async(d,b=!1)=>{if(!h||We(d))return;if(ie?.path===d){ie.after.push({key:d,run:()=>_e(d,b)});return}if(!s(d,Xe(d))){Ke(d);return}if(!await Et())return;let k=await vt(d);if(We(d))return;let x=h.files[d]??null,N=Nr(k?.hash??null,x,x?{seq:x.seq,hash:x.hash}:null);switch(N.kind){case"push":At(Xe(d))?await ur(d,N.baseSeq):await dr(d,N.baseSeq);break;case"pushCreate":At(Xe(d))?await ur(d,0):await dr(d,0);break;case"pushDelete":if(b){yr();break}if(!U&&(I.has(d)||fe())){I.set(d,"remote"),Q(),v();break}V.push(Date.now()),await Ei(d);break;case"dropShadow":Ke(d);break;default:k&&x&&k.hash===x.hash&&k.mtimeMs>=0&&(x.size!==k.size||x.mtimeMs!==k.mtimeMs)&&await kt(d,x.seq,x.hash,k);break}},Ci=async()=>{let d=new Map;if(!R||!h)return d;let b=R,k=null,x=async N=>{if(k)return;let L;try{L=await i.readdir(N,{withFileTypes:!0})}catch(W){k=`${N}: ${W?.message??String(W)}`;return}for(let W of L){if($n(W.name)||W.isDirectory()&&e.ignoreNames?.includes(W.name))continue;let j=a.join(N,W.name);if(W.isDirectory())await x(j);else if(W.isFile()){let X=a.relative(b,j).split(a.sep).join("/"),q=n(X);if(!q)continue;try{let oe=await i.stat(j);if(!oe.isFile())continue;d.set(q,{size:oe.size,mtimeMs:Math.floor(oe.mtimeMs)})}catch(oe){if(oe?.code==="ENOENT")continue;k=`${j}: ${oe?.message??String(oe)}`;return}}}};return await x(b),k?(A("error",`scan-failed: ${k}`),ue(),null):d},Ss=async()=>{let d=ve;if(pt()||d!==ve||!h||!await Et())return;let b=await Ci();if(!b||pt()||d!==ve)return;let k=!1;for(let[L,W]of[...I])(W==="remote"&&b.has(L)||W==="local"&&!b.has(L))&&(I.delete(L),k=!0);I.size||ge();for(let[L,W]of b){let j=h.files[L];j&&j.size===W.size&&j.mtimeMs===W.mtimeMs||P({key:L,run:()=>_e(L)})}let x=Object.keys(h.files),N=x.filter(L=>!b.has(L));if(N.length&&!U&&(M||oo(N.length,x.length,el))){ee();for(let L of N)I.set(L,"remote");Q(),v();return}k&&(Q(),v());for(let L of N)I.has(L)||P({key:L,run:()=>_e(L)})},Jt=async()=>{if(ie){ie.after.push({run:Jt});return}let d=ve;if(pt()||d!==ve||!m||!h||!R||!await Et())return;let b=await m.tree(h.vaultId);if(b.maxFileBytes!==void 0&&b.maxFileBytes!==C&&(C=b.maxFileBytes,v()),pt()||d!==ve)return;let k=new Map;for(let q of b.entries)r(q.path)===null||!s(q.path,q.kind)||k.set(q.path,q);for(let[q,oe]of[...ne])oe&&!k.has(q)&&Gt(q,null);let x=await Ci();if(!x||pt()||d!==ve)return;let N=new Set([...k.keys(),...x.keys(),...Object.keys(h.files)]),L=Object.keys(h.files).length,W=[];for(let q of N){if(pt()||d!==ve)return;let oe=h.files[q]??null,pe=k.get(q)??null,Ne=x.get(q)??null,ot=null,Kt=cr(Ne?.size??0);if(Ne)if(oe&&oe.size===Ne.size&&oe.mtimeMs===Ne.mtimeMs)ot=oe.hash,Kt=Ne;else{let Xt=await vt(q);Xt&&(ot=Xt.hash,Kt=Xt)}W.push({sp:q,d:Nr(ot,oe,pe?{seq:pe.seq,hash:pe.hash}:null),rSeq:pe?.seq??null,localHash:ot,localStat:Kt})}if(pt()||d!==ve)return;let j=W.filter(q=>q.d.kind==="deleteLocal"||q.d.kind==="pushDelete").length,X=!U&&(M||oo(j,L,el));X&&j&&ee(),I.clear();for(let{sp:q,d:oe,rSeq:pe,localHash:Ne,localStat:ot}of W){if(pt()||d!==ve)return;if(X&&(oe.kind==="deleteLocal"||oe.kind==="pushDelete")){I.set(q,oe.kind==="deleteLocal"?"local":"remote");continue}if((oe.kind==="deleteLocal"||oe.kind==="pushDelete")&&((await vt(q))?.hash??null)!==Ne){P({key:q,run:()=>_e(q)});continue}if(pt()||d!==ve)return;switch(oe.kind){case"adopt":await kt(q,pe,Ne,ot);break;case"pull":await st(q,pe);break;case"push":At(Xe(q))?await ur(q,oe.baseSeq):await dr(q,oe.baseSeq);break;case"pushCreate":At(Xe(q))?await ur(q,0):await dr(q,0);break;case"pushDelete":await Ei(q);break;case"deleteLocal":await Si(q),Ke(q);break;case"conflict":await st(q,pe);break;case"dropShadow":Ke(q);break;case"none":break}}U&&(U=!1,V.length=0),I.size||ge(),Q(),X&&v();for(let q of b.folders)if(!(r(q)===null||!s(q,"folder")))try{await i.mkdir(Re(q),{recursive:!0})}catch{}h.cursor=b.seq,h.lastSyncAt=Date.now(),E.save(h)},ku=async()=>{if(!m||!h)return;let d=h.cursor,b=await m.changes(h.vaultId,d);if(b.changes.length===0&&b.seq>d||b.changes.length>0&&b.changes[0].seq!==d+1){await Jt();return}for(let x of b.changes)await ki(x)},kn=null,xi=[],Ai=()=>{kn&&xi.push(kn.close()),kn=null},Eu=()=>{if(!c||kn||!R)return;let d=Ce();if(!d.watch)return;let b=k=>{if(!R)return;let x=a.relative(R,k);if(!x||x.startsWith(".."))return;let N=n(x);N&&H(N)};kn=d.watch(R,{depth:12,ignored:k=>{let x=a.basename(k);return $n(x)||!!e.ignoreNames?.includes(x)}},{change:b,add:b,unlink:()=>yr(),unlinkDir:()=>yr()})},gr=()=>{w?.stop(),w=null},_u=()=>{if(!c||!m||!h||w)return;let d=_;d&&(w=Ga({baseUrl:d.cloudUrl,vaultId:h.vaultId,token:d.token,getToken:$},{getSince:()=>h?.cursor??0,onHello:b=>{h&&b>h.cursor&&P({run:ku})},onChange:b=>{P({run:()=>ki(b)})},onReset:()=>{P({run:Jt})},onOpen:()=>{(p==="offline"||p==="starting")&&A("idle",null),P({run:Ss})},onDown:()=>{(p==="idle"||p==="syncing")&&A("offline")},onPresence:b=>t.onPresence?.(h?.vaultId??"",b),onPresenceRoster:b=>t.onPresenceRoster?.(h?.vaultId??"",b)}))},Cu=async()=>{let d=await Ye(o);if(d.cloudSync?.deviceId)return d.cloudSync.deviceId;let b=`desk-${Math.random().toString(36).slice(2,10)}${Date.now().toString(36)}`;return await gt({cloudSync:{...d.cloudSync??{},deviceId:b}},o),b},xu=async d=>{gr(),Ai(),ye.length=0,he.clear(),I.clear(),U=!1,M=!1,V.length=0;let b=await Ye(o);if(d!==u)return;let k=b.cloudSync;if(k?.enabled===!1){R=null,m=null,A("disabled",null);return}if(!o||o!==Pe()){A("auth-required","not-logged-in");return}if(R=e.localRoot,e.requireRootExists){let W=await i.stat(R).then(j=>j.isDirectory()).catch(()=>!1);if(d!==u)return;if(!W){A("error",`vault-missing: ${R}`),ue();return}}if(d!==u)return;let x=t.loadCreds();if(!x.cloudUrl||!x.token){m=null,A("auth-required","not-logged-in");return}A("starting",null);let N=k?.deviceId??await Cu();if(d!==u)return;let L=e.clientIdSuffix?`${N}#${e.clientIdSuffix}`:N;_={cloudUrl:x.cloudUrl,token:x.token},m=Ya({baseUrl:x.cloudUrl,token:x.token,clientId:L,getToken:()=>{if(d!==u)throw new xe(401,{code:"ACCOUNT_CHANGED"},"sync-session");return $()}});try{let W=e.vaultId==="first"?k?.vaultId:e.vaultId;if(!W){let q=await m.listVaults();if(d!==u)return;if(!q.length)throw new Error("\u4E91\u7AEF\u65E0\u53EF\u7528 vault");W=q[0].id,await gt({cloudSync:{...k??{},vaultId:W}},o)}if(d!==u)return;let j=await lo(e.shadowName);if(d!==u||(h=j&&j.vaultRoot===R&&j.vaultId===W&&j.folder===""?j:{vaultRoot:R,folder:"",vaultId:W,cursor:0,lastSyncAt:null,files:{}},d!==u))return;for(let[q,oe]of Object.entries(h.pending??{}))I.set(q,oe);I.size&&(M=!0);let X=await bs(R);if(d!==u||!X&&!e.requireRootExists&&!h.rootIdentity&&!Object.keys(h.files).length&&(await i.mkdir(R,{recursive:!0}),X=await bs(R),d!==u)||!_i(X)||!h.rootIdentity&&typeof X?.dev=="number"&&Number.isInteger(X.dev)&&X.dev>=0&&typeof X.ino=="number"&&Number.isInteger(X.ino)&&X.ino>0&&(h.rootIdentity={dev:X.dev,ino:X.ino},E.save(h),await E.flush(!0),d!==u||!await Et()))return;Eu();for(let q of h.moves??[])P({key:`move:${Le(q)}`,run:()=>hr(q)});P({run:Jt}),P({run:async()=>{_u()}})}catch(W){if(d!==u)return;G(W)?A("auth-required","login-expired"):(A("offline",W?.message||String(W)),ue())}},Ti=()=>{c=!1,gr(),Ai(),ye.length=0,he.clear(),z();for(let d of[Fe,be,F,Y])d&&clearTimeout(d);Fe=be=F=Y=null,ie?.abort.abort(),ie=null},Ri=async()=>{ze&&await new Promise(d=>g.add(d)),await Promise.all(xi.splice(0)),await E.flush(),h=null,m=null,_=null,R=null,O=0,S.clear(),ne.clear(),me=0,C=null,I.clear(),U=!1,M=!1,V.length=0,p="disabled",y=null},Au=()=>{Ii()},mr=null,En=()=>{mr?.(),mr=He().onBeforeQuit(Au);let d=++u;Ti();let b=f.catch(()=>{}).then(async()=>{await Ri(),d===u&&(c=!0,await xu(d))});return f=b,b},Ii=()=>{mr?.(),mr=null,++u,Ti();let d=f.catch(()=>{}).then(Ri);return f=d,d},jt=()=>({enabled:p!=="disabled",state:p==="idle"&&(B.size||ne.size)?"syncing":p,lastSyncAt:h?.lastSyncAt??null,pending:ye.length+B.size+ne.size,conflicts:O,skipped:[...S].map(([d,b])=>({path:d,reason:b})),error:y,pendingDeletions:I.size,maxFileBytes:C});return{getStatus:jt,start(){En()},notifyLocal(d,b,k){if(!h||p==="disabled"||p==="auth-required")return;let x=n(d),N=k?n(k):null;if(b==="write"&&x){$n(x.split("/").pop()||"")||H(x);return}if(b==="remove"){if(!x)return;let L=`${x}/`,W=!1;for(let j of Object.keys(h.files))(j===x||j.startsWith(L))&&(W=!0,P({key:j,run:()=>_e(j)}));!W&&x&&P({key:x,run:()=>_e(x)})}},holdLocalMove(d,b){let k=N=>e.serverDir?`${e.serverDir}/${N.replace(/\\/g,"/").normalize("NFC")}`:N.replace(/\\/g,"/").normalize("NFC"),x={from:k(d),to:k(b)};return++ve,fr.add(x),()=>{fr.delete(x)}},async notifyLocalMove(d,b,k,x){let N=n(d),L=n(b),W=h??await lo(e.shadowName),j=io(d,""),X=j&&(e.serverDir?`${e.serverDir}/${j}`:j);if(!N&&L&&X&&W&&Object.keys(W.files).some(q=>q===X||q.startsWith(`${X}/`))&&(N=X),!N&&!L){k?.();return}if(N&&L){let q=h??W;if(!q){k?.();return}let oe=x??(Object.keys(q.files).some(Ne=>Ne.startsWith(`${N}/`))?"folder":"file"),pe={from:N,to:L,kind:oe};q.moves??=[],q.moves.some(Ne=>Le(Ne)===Le(pe))||(q.moves.push(pe),++ve),k&&pr.set(Le(pe),k),E.save(q);try{await E.flush(!0)}catch(Ne){throw q.moves=q.moves.filter(ot=>Le(ot)!==Le(pe)),pr.delete(Le(pe)),E.save(q),Ne}h===q&&c&&p!=="disabled"&&p!=="auth-required"&&P({key:`move:${Le(pe)}`,run:()=>hr(pe)});return}N&&this.notifyLocal(d,"remove"),L&&(P({key:L,run:()=>_e(L)}),yr()),k?.()},async setEnabled(d){let b=await Ye(o);return await gt({cloudSync:{...b.cloudSync??{},enabled:d}},o),await En(),jt()},async restart(){return await En(),jt()},async syncNow(){if(S.clear(),p==="disabled"||p==="auth-required"||!m)await En();else{be&&(clearTimeout(be),lr());for(let d of h?.moves??[])P({key:`move:${Le(d)}`,run:()=>hr(d)});P({run:Jt})}return jt()},confirmMassDeletions(){return I.size&&(U=!0,M=!1,I.clear(),V.length=0,Q(),P({run:Jt})),jt()},stop:Ii};function yr(){c&&(F&&clearTimeout(F),F=setTimeout(()=>{F=null,P({run:Ss})},Lf))}}function co(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 uo(t){return/\.md$/i.test(t)?co(t):{root:t,fdPrefix:"\0",assetPrefix:"\0"}}function tl(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 Yf=t=>Ce().sha256Hex(t).slice(0,8),Gf=t=>t.replace(/[\\/:*?"<>|]/g," ").trim().slice(0,40)||"shared",Hr="\u4E0E\u6211\u5171\u4EAB";function nl(t,e){let n=Yf(`${t.vaultId}:${t.path}`),r=t.path.includes("/")?t.path.slice(0,t.path.lastIndexOf("/")):"";return{key:n,vaultId:t.vaultId,rootPath:t.path,title:t.title,localRelDir:`${Hr}/${Gf(t.title)}-${n}`,serverDir:r,inScope:(s,o)=>e.some(i=>tl(i,s,o)),scopeKey:e.map(s=>s.root).join("\0")}}function rl(t){return nl(t,[co(t.path),...(t.items??[]).map(uo)])}function sl(t){let e=t.map(rl),n=t.flatMap((s,o)=>{let i=e[o].serverDir?`${e[o].serverDir}/`:"";return(s.items??[]).filter(a=>!a.startsWith(i)).map(a=>nl({vaultId:s.vaultId,path:a,title:(a.split("/").pop()??a).replace(/\.md$/i,"")},[uo(a)]))}),r=new Map;for(let s of[...e,...n])r.has(s.key)||r.set(s.key,s);return[...r.values()]}var Jf=t=>{let e=[];for(let n of t.split("/"))!n||n==="."||(n===".."&&e.length&&e[e.length-1]!==".."?e.pop():e.push(n));return e.join("/")};function ol(t,e){let n=l=>l.normalize("NFC"),r=n(e.replace(/\\/g,"/")),s=t.find(l=>r.startsWith(`${n(l.localRelDir)}/`));if(!s)return null;let o=r.slice(n(s.localRelDir).length+1),i=Jf(s.serverDir?`${s.serverDir}/${o}`:o);if(!i||i===".."||i.startsWith("../"))return null;let a=[s,...t].find(l=>l.vaultId===s.vaultId&&(!l.serverDir||i.startsWith(`${l.serverDir}/`))&&l.inScope(i,Xe(i)));return a?`${a.localRelDir}/${a.serverDir?i.slice(a.serverDir.length+1):i}`:null}function fo(){let t=He().readCreds(),e=Oe(t.cloudUrl??"",t.token??""),n=new AbortController,r=()=>{let f=He().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,g,p)=>{let y=r();if(!y.cloudUrl||!y.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});let h=await fetch(`${y.cloudUrl.replace(/\/+$/,"")}/api/amadeus${g}`,{method:f,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(!h.ok){let w=null;try{w=await h.json()}catch{}throw Object.assign(new Error(w?.detail||`http ${h.status}`),{status:h.status,code:w?.code})}let m=await h.json();return r(),m},i=null,a=async()=>(r(),i||(i=(await o("GET","/vaults")).vaults[0]?.id??"default",i)),l=()=>{try{let f=(r().token??"").split(".")[1],g=JSON.parse(_t(wr(f)));return typeof g.userId=="string"?g.userId:null}catch{return null}},c=async()=>(await o("GET","/shared-with-me")).items.map(g=>{let p=rl(g),y=g.path.split("/").pop()??g.path;return{...g,localPath:`${p.localRelDir}/${y}`}}),u=null;return{stop:()=>n.abort(),call:o,ensureOwnVault:a,myUserId:l,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,g){let p=(f??"").replace(/\\/g,"/"),y,h=null,m=g.find(w=>p.startsWith(`${w.localRelDir}/`));m?(y=m.vaultId,h=m.serverDir?`${m.serverDir}/${p.slice(m.localRelDir.length+1)}`:p.slice(m.localRelDir.length+1)):(y=await a(),h=p||null),await o("POST",`/vaults/${encodeURIComponent(y)}/presence`,{page:h})}}}import{promises as ll}from"node:fs";import Kf from"node:path";var po=".forsion-vault.md",il=t=>`${t}/${po}`;function zr(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 al=t=>`---
212
+ `)}function co(t,e,n=200){return t>=n||e>=5&&t>=Math.max(5,Math.ceil(e/2))}var Ja=["cycles","cycleMsTotal","errAuth","errOffline","errVaultMissing","errScan","errMirrorMissing","errHttp","errTimeout","errBlocked","errOther","conflicts","skippedTooLarge","skippedNotFound","skippedExists","skippedOther","massDeleteGuard","uploads","downloads"];function Ka(t){return t==="TOO_LARGE"?"skippedTooLarge":t==="ASSET_404"?"skippedNotFound":t==="EXISTS"?"skippedExists":/^http \d+$/.test(t)?"errHttp":t==="timeout"?"errTimeout":"skippedOther"}function Xa(t,e){if(t==="offline")return"errOffline";if(t==="auth-required")return e==="not-logged-in"?null:"errAuth";if(t!=="error")return null;let n=e??"";return n.startsWith("vault-missing")?"errVaultMissing":n.startsWith("scan-failed")?"errScan":n.startsWith("mirror-missing")?"errMirrorMissing":"errOther"}function Fr(t,e=0){if(/^(account_changed|content_sync_closed|paused)$/.test(t)||/^File exceeds \d+ MB/.test(t))return null;if(t==="not_signed_in"||e===401||e===403)return"errAuth";let n=/^content_http_(\d{3})$/.exec(t);return n?n[1]==="401"||n[1]==="403"?"errAuth":"errHttp":/timeout|timed out|aborted due to timeout/i.test(t)?"errTimeout":/fetch failed|econn|enotfound|eai_again|network|socket/i.test(t)?"errOffline":/^Sync root (unavailable|changed|is not a directory)|^content_roots_changed/.test(t)?"errVaultMissing":e?"errHttp":"errOther"}function Lr(t){let e=null;return{error(n){n!==e&&(e=n,t?.(n))},ok(){e=null}}}var zf=/[\u0000-\u001f\u007f]/;function xt(t){let e=t.replace(/\\/g,"/").normalize("NFC").trim();if(e=e.replace(/\/+$/,""),!e||e.length>512||e.startsWith("/")||zf.test(e))return null;let n=e.split("/");for(let r of n)if(!r||r==="."||r==="..")return null;return n.join("/")}function lo(t,e){let n=t.replace(/\\/g,"/").normalize("NFC");return e===""?xt(n):n.startsWith(`${e}/`)?xt(n.slice(e.length+1)):null}function Za(t,e){return e===""?t:`${e}/${t}`}function Mn(t){return!!(t===".DS_Store"||t==="Icon\r"||t===".sync-trash"||/\.tmp-\d+-\d+-\d+$/.test(t)||/^\..+\.lock$/.test(t))}function Xe(t){return/\.md$/i.test(t)?"page":/\.db$/i.test(t)?"db":"binary"}var At=t=>t==="page"||t==="db";var Bf=1024,xe=class extends Error{status;body;constructor(e,n,r){super(`cloud http ${e} on ${r}`),this.status=e,this.body=n}},Qa=t=>12e4+Math.ceil(t/256);function qf(t,e){let n=AbortSignal.timeout(t);if(!e)return n;let r=new AbortController;for(let s of[n,e])s.addEventListener("abort",()=>r.abort(s.reason),{once:!0});return r.signal}function ec(t){let e=`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus`,n=()=>t.getToken?.()??t.token,r=async(i,a)=>{let c=n();for(let l=0;;l++){let u={...a.headers,Authorization:`Bearer ${c}`},d=await fetch(i,{...a,headers:u});if(n(),d.status!==401||d.redirected)return d;let g=await d.text(),p=n();if(p===c||l>0)return new Response(g,{status:d.status,statusText:d.statusText,headers:d.headers});c=p}},s=async(i,a,c)=>{let l={Authorization:`Bearer ${t.token}`,...c?.headers};i!=="GET"&&(l["X-Amadeus-Client"]=t.clientId);let u;c?.json!==void 0?(l["Content-Type"]="application/json",u=JSON.stringify(c.json),u.length>=Bf&&(l["Content-Encoding"]="gzip",u=await ji(u))):c?.form&&(u=c.form);let d=await r(a,{method:i,headers:l,body:u,signal:qf(c?.timeoutMs??3e4,c?.signal)});if(!d.ok){let p=null;try{p=await d.json()}catch{}throw n(),new xe(d.status,p,a)}let g=await d.json();return n(),g},o=i=>new URLSearchParams(i).toString();return{clientId:t.clientId,async listVaults(){return((await s("GET",`${e}/vaults`)).vaults??[]).map(a=>({id:String(a.id),name:String(a.name),lastChangeSeq:Number(a.lastChangeSeq??0)}))},async tree(i){let a=await s("GET",`${e}/vaults/${i}/tree`);if(!Array.isArray(a.entries))throw new Error("server too old: tree has no entries[] (deploy the amadeus microserver update)");return{folders:a.folders??[],seq:Number(a.seq??0),maxFileBytes:Number.isInteger(a.maxFileBytes)&&a.maxFileBytes>0?a.maxFileBytes:void 0,entries:a.entries.map(c=>({path:String(c.path),kind:c.kind,seq:Number(c.seq??0),hash:c.hash??null,size:Number(c.size??0)}))}},async getFile(i,a){let c=await s("GET",`${e}/vaults/${i}/file?${o({path:a})}`);return{content:String(c.content??""),seq:Number(c.seq??0),hash:c.hash??null}},putFile(i,a,c,l,u=!1){return s("PUT",`${e}/vaults/${i}/file`,{json:{path:a,content:c,baseSeq:l,...u?{force:!0}:{}}})},async deleteFile(i,a,c,l){let u={path:a};c!==void 0&&(u.baseSeq=String(c)),await s("DELETE",`${e}/vaults/${i}/file?${o(u)}`,l?.confirmed?{headers:{"X-Amadeus-Delete-Confirmed":"1"}}:void 0)},move(i,a,c){return s("POST",`${e}/vaults/${i}/move`,{json:{from:a,to:c}})},renameFolder(i,a,c){return s("POST",`${e}/vaults/${i}/folders/rename`,{json:{path:a,newName:c}})},moveFolder(i,a,c){return s("POST",`${e}/vaults/${i}/folders/move`,{json:{path:a,dest:c}})},async deleteFolder(i,a){await s("DELETE",`${e}/vaults/${i}/folders?${o({path:a})}`)},putBinary(i,a,c,l){let u=new FormData;return u.set("path",a),l?.ifAbsent&&u.set("ifAbsent","true"),l?.baseSeq!==void 0&&u.set("baseSeq",String(l.baseSeq)),u.set("file",new Blob([new Uint8Array(c)]),a.split("/").pop()||"file"),s("POST",`${e}/vaults/${i}/binary`,{form:u,timeoutMs:Qa(c.length),signal:l?.signal})},async listVersions(i,a){return((await s("GET",`${e}/vaults/${i}/file/versions?${o({path:a})}`)).versions??[]).map(l=>({id:String(l.id),seq:Number(l.seq??0)}))},async getVersion(i,a){let c=await s("GET",`${e}/vaults/${i}/file/versions/${a}`);return String(c.content??"")},async getAsset(i,a,c){let l=new AbortController;c?.addEventListener("abort",()=>l.abort(c.reason),{once:!0});let u=()=>l.abort(new DOMException("Asset download timed out","TimeoutError")),d=setTimeout(u,12e4);try{let g=await r(`${e}/vaults/${i}/asset?${o({ref:a})}`,{headers:{Authorization:`Bearer ${t.token}`},signal:l.signal});if(!g.ok)throw new xe(g.redirected&&(g.status===401||g.status===403)?502:g.status,null,"asset:"+a);clearTimeout(d),d=setTimeout(u,Qa(Number(g.headers.get("content-length"))||0));let p=new Uint8Array(await g.arrayBuffer());return n(),p}finally{clearTimeout(d)}},async changes(i,a){let c=await s("GET",`${e}/vaults/${i}/changes?${o({since:String(a)})}`);return{changes:c.changes??[],seq:Number(c.seq??0)}}}}function tc(t,e){let n=!1,r=0,s=null,o=null,i=()=>`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus/vaults/${t.vaultId}/events?since=${e.getSince()}`,a=l=>{if(n)return;s?.abort(),e.onDown(l);let u=Math.min(3e4,1e3*2**r)*(.7+Math.random()*.6);r++,o=setTimeout(()=>void c(),u)},c=async()=>{if(n)return;s=new AbortController;let l;try{if(l=await fetch(i(),{headers:{Authorization:`Bearer ${t.getToken?.()??t.token}`,Accept:"text/event-stream"},signal:s.signal}),n){await l.body?.cancel();return}t.getToken?.()}catch(m){a(m);return}if(!l.ok||!l.body){a(new Error(`sse http ${l.status}`));return}r=0,e.onOpen();let u=l.body.getReader(),d=new TextDecoder,g="",p="",y=[],h=()=>{if(t.getToken?.(),!y.length&&!p)return;let m=y.join(`
213
+ `),w=p||"message";p="",y=[];let _=null;try{_=m?JSON.parse(m):null}catch{return}w==="hello"?e.onHello(Number(_?.seq??0)):w==="change"?e.onChange(_):w==="reset"?e.onReset():w==="presence"?e.onPresence?.(_):w==="presence-roster"&&e.onPresenceRoster?.(_)};try{for(;;){let{done:m,value:w}=await u.read();if(m)break;for(g+=d.decode(w,{stream:!0});;){let _=g.indexOf(`
214
+ `);if(_<0)break;let M=g.slice(0,_).replace(/\r$/,"");if(g=g.slice(_+1),M==="")h();else{if(M.startsWith(":"))continue;M.startsWith("event:")?p=M.slice(6).trim():M.startsWith("data:")&&y.push(M.slice(5).replace(/^ /,""))}}}}catch(m){n||a(m);return}a(new Error("sse stream ended"))};return c(),{stop:()=>{n=!0,o&&clearTimeout(o),s?.abort()}}}var $n=t=>Ce().path.join(He().userDataDir(),He().isDevMode()?`${t}.dev.json`:`${t}.json`),uo=$n,Lt=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),Ur=t=>typeof t=="number"&&Number.isSafeInteger(t)&&t>=0,nc=t=>typeof t=="number"&&Number.isInteger(t)&&t>=0,Wf=t=>Lt(t)&&nc(t.dev)&&nc(t.ino)&&t.ino>0,Hr=t=>typeof t=="string"&&xt(t)===t,rc=t=>typeof t=="string"&&t.length>0,Vf=t=>Lt(t)&&Ur(t.seq)&&rc(t.hash)&&Ur(t.size)&&typeof t.mtimeMs=="number"&&Number.isFinite(t.mtimeMs),Yf=t=>Lt(t)&&Hr(t.from)&&Hr(t.to)&&(t.kind==="file"||t.kind==="folder")&&(t.hashes===void 0||Lt(t.hashes)&&Object.values(t.hashes).every(rc));async function fo(t){let e;try{e=await Ce().fs.readFile(uo(t),"utf8")}catch(r){if(r?.code==="ENOENT")return null;throw r}let n;try{n=JSON.parse(e)}catch{throw Error("Invalid cloud vault sync state; original data was retained")}if(!Lt(n)||typeof n.vaultRoot!="string"||!n.vaultRoot||typeof n.vaultId!="string"||!n.vaultId||typeof n.folder!="string"||n.rootIdentity!==void 0&&!Wf(n.rootIdentity)||!Lt(n.files)||!Object.entries(n.files).every(([r,s])=>Hr(r)&&Vf(s))||n.cursor!==void 0&&!Ur(n.cursor)||n.lastSyncAt!=null&&!Ur(n.lastSyncAt)||n.pending!==void 0&&(!Lt(n.pending)||!Object.entries(n.pending).every(([r,s])=>Hr(r)&&(s==="local"||s==="remote")))||n.moves!==void 0&&(!Array.isArray(n.moves)||!n.moves.every(Yf)))throw Error("Invalid cloud vault sync state; original data was retained");return{...n,cursor:n.cursor??0,lastSyncAt:n.lastSyncAt??null}}function sc(t){let e=null,n=null,r=Promise.resolve(),s=null,o=()=>{if(!e)return r;let i=e,a=JSON.stringify(e);return e=null,r=r.then(async()=>{try{let c=uo(t),l=`${c}.tmp-${Ce().tmpTag()}-${Date.now()}-0`;await Ce().fs.writeFile(l,a,"utf8"),await Ce().fs.rename(l,c),s=null}catch(c){e??=i,s=c}}),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 oc(t){try{await Ce().fs.unlink(uo(t))}catch{}}var Gf=5*1024*1024,Jf=5*1024*1024,Kf=3e4,Xf=5e3,Zf=5*6e4,Qf=2500,ep=3e3,tp=5,np=256*1024,rp=5,ic=1024*1024,ac=200,sp=6e4,op=50,ip=".sync-trash",Tt=t=>Ce().sha256Hex(t);function Nn(t,e={localRoot:Ct(),shadowName:`amadeus-sync-${Pn()}`,vaultId:"first",serverDir:"",excludePrefixes:["\u4E0E\u6211\u5171\u4EAB/"]}){let n=f=>{let b=lo(f,"");if(!b)return null;for(let x of e.excludePrefixes??[])if(b===x.replace(/\/$/,"")||b.startsWith(x))return null;if(e.ignoreNames?.length&&b.split("/").some(x=>e.ignoreNames.includes(x)))return null;let k=e.serverDir?`${e.serverDir}/${b}`:b;return e.inScope&&!e.inScope(k,Xe(k))?null:k},r=f=>{let b;if(e.serverDir){if(!f.startsWith(`${e.serverDir}/`))return null;b=f.slice(e.serverDir.length+1)}else{for(let k of e.excludePrefixes??[])if(f.startsWith(k))return null;b=f}return b.split("/").some(k=>Mn(k)||!!e.ignoreNames?.includes(k))?null:b},s=(f,b)=>!e.inScope||e.inScope(f,b),o=e.accountId??Pe(),{fs:i,path:a}=Ce(),c=f=>i.access(f).then(()=>!0,()=>!1),l=!1,u=0,d=Promise.resolve(),g=new Set,p="disabled",y=null,h=null,m=null,w=null,_=null,M=()=>{let f=t.loadCreds();if(!_||o!==Pe()||!f.token||f.cloudUrl?.replace(/\/+$/,"")!==_.cloudUrl.replace(/\/+$/,""))throw new xe(401,{code:"ACCOUNT_CHANGED"},"sync-session");return f.token},R=null,O=0,S=new Map,C=null,E=sc(e.shadowName),I=new Map,U=!1,$=!1,V=[],Z=(f,b,k)=>{try{t.onHealth?.(f,b,k)}catch{}},re=Lr(Z),se=0,ee=()=>{$||Z("massDeleteGuard"),$=!0},Q=()=>{h&&(h.pending=I.size?Object.fromEntries(I):void 0,E.save(h))},ge=()=>{$=!1,V.length=0},fe=()=>{if($)return!0;let f=Date.now();for(;V.length&&f-V[0]>sp;)V.shift();return V.length>=op?(ee(),!0):!1},ye=[],he=new Set,ze=!1,Fe=null,be=null,F=null,Y=null,v=()=>{!l||Y||(Y=setTimeout(()=>{Y=null,t.onStatus(jt())},200))},A=(f,b)=>{let k=p;p=f,b!==void 0&&(y=b),T(k,f),v()},T=(f,b)=>{if(b==="syncing"&&f!=="syncing"&&(se=Date.now()),b==="idle"&&f==="syncing"&&(Z("cycles"),Z("cycleMsTotal",Math.max(0,Date.now()-se))),b==="idle"||b==="disabled"){re.ok();return}let k=Xa(b,y);k&&re.error(k)},D=(f,b)=>{S.set(f,b),Z(Ka(b),1,f)},P=(f,b=!1)=>{if(l){if(f.key){if(he.has(f.key))return;he.add(f.key)}b?ye.unshift(f):ye.push(f),te()}},B=new Map,H=f=>{if(!l)return;let b=(h?.files[f]?.size??0)>np,k=(e.pushQuietMs??ep)*(b?rp:1),x=Date.now(),N=B.get(f);N&&clearTimeout(N.timer);let L=N?.since??x,W=Math.max(0,Math.min(k,L+k*tp-x)),j=setTimeout(()=>{B.delete(f),P({key:f,run:()=>_e(f,!0)})},W);B.set(f,{timer:j,since:L}),v()},z=()=>{for(let{timer:f}of B.values())clearTimeout(f);B.clear()},J=f=>!(f instanceof xe)||f.status>=500||f.status===0,G=f=>f instanceof xe&&(f.status===401||f.status===403),K=(f,b)=>{D(f,b?.body?.code||`http ${b?.status}`),v()},te=async()=>{if(!ze){ze=!0;try{for(;ye.length;){(p==="idle"||p==="starting")&&A("syncing");let f=ye.shift();f.key&&he.delete(f.key);try{await f.run()}catch(b){if(!l)return;if(G(b)){ye.length=0,he.clear(),gr(),A("auth-required","login-expired");return}if(J(b)){P(f,!0),gr(),A("offline",b?.message||"network error"),ue();return}K(f.key??"(op)",b)}}l&&p==="syncing"&&(h&&(h.lastSyncAt=Date.now(),E.save(h)),A("idle",null))}finally{ze=!1;for(let f of g)f();g.clear()}}},ue=()=>{!l||Fe||(Fe=setTimeout(()=>{Fe=null,En()},Kf))},ne=new Map,me=0,ie=null,Be=()=>!!be||!!ie||!l,Nt=f=>f instanceof xe&&f.status>=500||f?.name==="TimeoutError",Yt=e.pushRetryMs??Xf,$e=(f,b)=>{(b||!ne.has(f))&&ne.set(f,b)},mi=(f,b,k)=>{D(f,b instanceof xe?`http ${b.status}`:"timeout"),$e(f,k),me=Math.min(me*2||Yt,Zf),be=setTimeout(cr,me),v()},yi=(f,b,k)=>{let x=new AbortController,N=b(x.signal).then(W=>()=>W,W=>()=>{throw W}),L={path:f,abort:x,after:[],settle:async()=>{let W=await N;if(ie===L){ie=null;try{await k(W)}catch(j){if(G(j)||J(j))throw j;K(f,j)}finally{for(let j of L.after)P(j);wi(f)}}}};ie=L,N.then(()=>P({run:L.settle}))},Gt=(f,b)=>{for(let[k,x]of[...ne])!x||!qe(k,f)||(ne.delete(k),S.delete(k),b!==null&&ne.set(b+k.slice(f.length),x));v()},cr=()=>{be=null;let[f]=ne;if(f===void 0)return;let[b]=f;he.delete(b),P({key:b,run:async()=>{if(ie?.path===b)return;let k=ne.get(b),x=!k&&ne.delete(b);(k||x)&&S.delete(b);try{k?await st(b,k.seq):x&&await _e(b,!0)}finally{x&&We(b)&&$e(b),wi(b)}}})},wi=f=>{if(!Be())if(ne.has(f)){let b=ne.get(f);ne.delete(f),ne.set(f,b),be=setTimeout(cr,me||Yt)}else cr()},Re=f=>{if(!R||!h)throw new Error("engine not bound");let b=r(f);if(b===null)throw new Error("path outside binding: "+f);let k=a.resolve(R,Za(b,h.folder)),x=a.relative(R,k);if(x.startsWith("..")||a.isAbsolute(x))throw new Error("path escapes vault: "+f);return k},lr=f=>({size:f,mtimeMs:-1}),bi=async f=>{try{let b=await i.stat(f);return b.isFile()?{size:b.size,mtimeMs:Math.floor(b.mtimeMs)}:null}catch{return null}},_u=async f=>{if(!i.lstat||!R)return bi(f);let b=a.relative(R,f).split(a.sep),k=R;for(let[x,N]of b.entries()){k=a.join(k,N);let L=await i.lstat(k).catch(W=>{if(W?.code==="ENOENT")return null;throw W});if(!L)return null;if(L.isSymbolicLink())throw Error("Cloud vault sync does not follow symbolic links");if(x===b.length-1&&L.isFile())return{size:L.size,mtimeMs:Math.floor(L.mtimeMs)};if(x===b.length-1||!L.isDirectory())throw Error("Cloud vault sync path is not a regular file")}return null},Cu=0,Si=async(f,b,k,x)=>{await i.mkdir(a.dirname(f),{recursive:!0});let N=`${f}.tmp-${Ce().tmpTag()}-${Date.now()}-${Cu++}`;await i.writeFile(N,b);let L=await bi(N)??lr(Es(b));if(!x())return await i.rm(N,{force:!0}),null;try{let W=Ce().compareAndReplace;if(!W)throw new Error("Host does not support safe cloud download commits");return await W(N,f,k,x)?L:null}finally{await i.rm(N,{force:!0})}},vi=async f=>{let b;try{b=await i.readdir(f,{withFileTypes:!0})}catch{return}for(let k of b)k.isDirectory()&&await vi(a.join(f,k.name));try{await i.rmdir(f)}catch{}},vt=async f=>{let b=Re(f),k=await _u(b);if(!await Et())throw Error("Cloud vault sync root is unavailable or changed");if(i.lstat&&!k)return null;let x;try{x=await i.readFile(b)}catch(L){if(L?.code!=="ENOENT")throw L;if(!await Et())throw Error("Cloud vault sync root is unavailable or changed");return null}return{hash:At(Xe(f))?Tt(_t(x)):Tt(x),size:k?.size??x.length,mtimeMs:k?.mtimeMs??-1,buf:x}},kt=async(f,b,k,x)=>{h&&(h.files[f]={seq:b,hash:k,size:x.size,mtimeMs:x.mtimeMs},E.save(h))},Ke=f=>{h&&f in h.files&&(delete h.files[f],E.save(h))},st=async(f,b)=>{if(!m||!h||We(f))return;let k=ve,x=Xe(f);if(At(x)){let j;try{j=await m.getFile(h.vaultId,f),Z("downloads")}catch(X){if(X instanceof xe&&X.status===404){await bs(f);return}throw X}await ki(f,x,j.content,j.seq,j.hash??Tt(j.content),k);return}if(Be()){$e(f,{seq:b}),v();return}let{vaultId:N}=h,L=m,W={seq:b};ne.set(f,W),yi(f,j=>L.getAsset(N,f,j),async j=>{let X=ne.get(f)===W,q;try{q=j(),me=0,Z("downloads")}catch(oe){if(!X)return;if(ne.delete(f),oe instanceof xe&&oe.status===404){D(f,"ASSET_404"),v();return}if(Nt(oe)){mi(f,oe,{seq:b});return}throw oe}X&&await ki(f,x,q,b??0,Tt(q),k)}),v()},ki=async(f,b,k,x,N,L)=>{if(!h)return;let W=async pe=>{await kt(f,x,N,pe),ne.get(f)&&(ne.delete(f),S.delete(f))},j=await vt(f);if(L!==ve||We(f))return;if(j&&j.hash===N){await W(j);return}let X=h.files[f];if(j&&X&&N===X.hash&&j.hash!==X.hash){await W(lr(X.size)),P({key:f,run:()=>_e(f)});return}let q=j?Tt(j.buf):null;if(j&&(!X||j.hash!==X.hash)){if(X&&b==="page"&&typeof k=="string"&&await xu(f,X,j,k,x,N,()=>L===ve&&!We(f))||L!==ve||We(f)||!await Au(f,()=>L===ve&&!We(f)))return;q=null}let oe=await Si(Re(f),k,q,()=>l&&L===ve&&!We(f));if(!oe){P({key:f,run:()=>_e(f)});return}await W(oe)},xu=async(f,b,k,x,N,L,W)=>{try{if(!m||!h||k.buf.length>ic||x.length>ic)return!1;let X=(await m.listVersions(h.vaultId,f)).find(pe=>pe.seq===b.seq);if(!X)return!1;let q=await m.getVersion(h.vaultId,X.id);if(Tt(q)!==b.hash)return!1;let oe=Ga(_t(k.buf),q,x);return oe===null?!1:await Si(Re(f),oe,Tt(k.buf),()=>l&&W())?(await kt(f,N,L,lr(Es(oe))),P({key:f,run:()=>_e(f)}),!0):(P({key:f,run:()=>_e(f)}),!0)}catch{return!1}},Au=async(f,b)=>{let k=xt(Nr(f,new Date));if(!k)return!0;let x=k.lastIndexOf("."),N=x>k.lastIndexOf("/"),L=N?k.slice(0,x):k,W=N?k.slice(x):"",j=k,X=Ce().existsSync;if(X)for(let q=2;X(Re(j));q++)j=`${L}-${q}${W}`;else for(let q=2;await c(Re(j));q++)j=`${L}-${q}${W}`;if(!b())return!1;try{await i.rename(Re(f),Re(j))}catch(q){if(q?.code==="ENOENT")return!0;throw q}return O++,Z("conflicts"),P({key:j,run:()=>_e(j)}),v(),!0},Ei=async f=>{if(!R)return;let b=Re(f),k=r(f)??f,x=a.join(R,ip,new Date().toISOString().slice(0,10),...k.split("/")),N=await c(x)?`${x}.${Date.now()}`:x;try{await i.mkdir(a.dirname(N),{recursive:!0}),await i.rename(b,N)}catch(L){if(L?.code==="ENOENT")return;throw new Error(`\u8F6F\u5220\u5931\u8D25,\u4FDD\u7559\u672C\u5730\u6587\u4EF6 ${b}: ${L?.message??String(L)}`)}},bs=async f=>{if(!h)return;Gt(f,null);let b=await vt(f);if(We(f))return;let k=h.files[f]??null,x=jr(b?.hash??null,k,null);if(x.kind==="deleteLocal"){if(!U&&fe()){I.set(f,"local"),Q(),v();return}V.push(Date.now()),await Ei(f),Ke(f)}else x.kind==="pushCreate"?(Ke(f),P({key:f,run:()=>_e(f)})):Ke(f)},_i=(f,b)=>{if(h){Gt(f,b);for(let k of Object.keys(h.files))if(k===f||k.startsWith(`${f}/`)){let x=b+k.slice(f.length);h.files[x]=h.files[k],delete h.files[k]}E.save(h)}},Ci=async f=>{if(!m||!h||f.seq<=h.cursor||!await Et())return;if(f.origin.client&&m.clientId===f.origin.client){h.cursor=f.seq,E.save(h);return}let b=f.type==="structure"?"folder":f.type,k=N=>r(N)!==null&&s(N,b);if(!k(f.path)&&!(f.newPath&&k(f.newPath))){h.cursor=f.seq,E.save(h);return}let x=f.path;if(f.op!=="write"&&f.op!=="mkdir"){for(;ie&&(qe(ie.path,x)||f.newPath&&qe(ie.path,f.newPath));)await ie.settle();if(!l)return}switch(f.op){case"write":await st(x,f.fileSeq);break;case"delete":await bs(x);break;case"move":{let N=f.newPath;if(!N)break;let L=h.files[x],W=await vt(x),j=!!ne.get(x);if(Gt(x,N),j&&$e(N,{seq:f.fileSeq}),W&&L)try{await i.mkdir(a.dirname(Re(N)),{recursive:!0}),await i.rename(Re(x),Re(N)),h.files[N]={...L,seq:j?L.seq:f.fileSeq??L.seq},delete h.files[x],E.save(h)}catch{await st(N,f.fileSeq)}else Ke(x),await st(N,f.fileSeq);break}case"mkdir":await i.mkdir(Re(x),{recursive:!0});break;case"rename-folder":case"move-folder":{let N=f.newPath;if(!N)break;try{await i.mkdir(a.dirname(Re(N)),{recursive:!0}),await i.rename(Re(x),Re(N))}catch{}_i(x,N);break}case"delete-folder":{let N=`${x}/`;for(let L of Object.keys(h.files))(L===x||L.startsWith(N))&&await bs(L);Gt(x,null),await vi(Re(x));break}}if(h.cursor=f.seq,E.save(h),f.op==="move"||f.op==="rename-folder"||f.op==="move-folder"||f.op==="delete"||f.op==="delete-folder")try{await t.onRemoteApplied?.(f)}catch{}},Tu=async(f,b,k)=>{let x=Number(b?.seq??0),N=b?.content??null;if(N!==null&&Tt(N)===k.hash){await kt(f,x,k.hash,k);return}if(N===null&&x===0){if(!h?.files[f]){D(f,b?.code||"EXISTS"),v();return}Ke(f),P({key:f,run:()=>_e(f)});return}await st(f,x)},ur=async(f,b)=>{if(!m||!h)return;let k=await vt(f);if(!k){P({key:f,run:()=>_e(f)});return}if(k.size>Gf){D(f,"TOO_LARGE"),v();return}let x=_t(k.buf);try{let N=await m.putFile(h.vaultId,f,x,b);Z("uploads"),S.delete(f),await kt(f,N.seq,N.hash??k.hash,k)}catch(N){if(N instanceof xe&&N.status===409){await Tu(f,N.body,k);return}throw N}},dr=async(f,b)=>{if(!m||!h)return;let k=await vt(f);if(!k){P({key:f,run:()=>_e(f)});return}if(k.size>(C??Jf)){D(f,"TOO_LARGE"),v();return}if($e(f),v(),Be())return;let{vaultId:x}=h,N=m;yi(f,L=>N.putBinary(x,f,k.buf,{baseSeq:b,signal:L}),async L=>{if(h){ne.get(f)||ne.delete(f);try{let W=L();me=0,Z("uploads"),S.delete(f),await kt(f,W.seq,k.hash,k)}catch(W){if(Nt(W)){mi(f,W);return}if(!(W instanceof xe)||W.status!==409)throw W;let j=Number(W.body?.seq??0),X=W.body?.hash??null;if(X!==null&&X===k.hash){await kt(f,j,k.hash,k);return}if(j===0){if(!h.files[f]){D(f,W.body?.code||"EXISTS"),v();return}Ke(f),P({key:f,run:()=>_e(f)});return}await st(f,j)}}})},xi=async f=>{if(!m||!h||We(f))return;let b=ve,k=h.files[f];if(k){if(At(Xe(f)))try{let x=await m.getFile(h.vaultId,f);if(x.seq!==k.seq){await st(f,x.seq);return}}catch(x){if(x instanceof xe&&x.status===404){Ke(f);return}throw x}if(!(!await Et()||b!==ve||We(f))){try{await m.deleteFile(h.vaultId,f,k.seq,{confirmed:U})}catch(x){if(x instanceof xe&&x.status===409){await st(f,Number(x.body?.seq??0)||null);return}if(x instanceof xe&&x.status===429&&x.body?.code==="MASS_DELETE_BLOCKED"){I.set(f,"remote"),ee(),Q(),v();return}throw x}Ke(f)}}},Ss=f=>i.stat(f).catch(b=>{if(b?.code==="ENOENT")return null;throw b}),Ai=f=>{let b=h?.rootIdentity,k=f!==null&&f.isDirectory();return k&&(!b||f.dev===b.dev&&f.ino===b.ino)?!0:(A("error",`${k?"vault-changed":"vault-missing"}: ${R}`),ue(),!1)},Et=async()=>!!R&&Ai(await Ss(R)),ve=0,fr=new Set,pr=new Map,Le=f=>JSON.stringify([f.from,f.to]),qe=(f,b)=>f===b||f.startsWith(`${b}/`),We=f=>[...h?.moves??[],...fr].some(b=>qe(f,b.from)||qe(f,b.to)),pt=()=>!!(h?.moves?.length||fr.size),hr=async f=>{if(!m||!h)return;let{from:b,to:k,kind:x}=f;if(r(b)===null||r(k)===null)throw new Error("Invalid queued cloud move");if(ie&&(qe(ie.path,b)||qe(ie.path,k))){ie.after.push({key:`move:${Le(f)}`,run:()=>hr(f)});return}f.hashes??=Object.fromEntries(Object.entries(h.files).filter(([j])=>qe(j,b)).map(([j,X])=>[j.slice(b.length),X.hash])),E.save(h),await E.flush(!0);let N,L=!1;try{if(x==="folder"){let j=a.posix.dirname(b)==="."?"":a.posix.dirname(b),X=a.posix.dirname(k)==="."?"":a.posix.dirname(k);j===X?await m.renameFolder(h.vaultId,b,a.posix.basename(k)):await m.moveFolder(h.vaultId,b,X)}else{let j=await m.move(h.vaultId,b,k);N=Number(j.seq)}}catch(j){if(!(j instanceof xe)||j.status!==404)throw j;let X=await m.tree(h.vaultId);if(X.entries.some(pe=>qe(pe.path,b))||X.folders.some(pe=>qe(pe,b)))throw j;let oe=X.entries.find(pe=>pe.path===k);if(N=oe?.seq,L=!oe&&!X.entries.some(pe=>qe(pe.path,k))&&!X.folders.some(pe=>qe(pe,k)),!L){let pe=Object.entries(f.hashes);if(!(pe.length>0&&pe.every(([ot,Kt])=>X.entries.some(Xt=>Xt.path===k+ot&&Xt.hash===Kt))))throw new xe(409,{code:"MOVE_DESTINATION_CHANGED"},"local-move")}}if(L){for(let j of Object.keys(h.files))qe(j,b)&&delete h.files[j];Gt(b,null)}else _i(b,k),N!==void 0&&h.files[k]&&!ne.get(k)&&(h.files[k].seq=N);h.moves=(h.moves??[]).filter(j=>Le(j)!==Le(f)),E.save(h);try{await E.flush(!0)}catch(j){throw h.moves.unshift(f),E.save(h),j}let W=pr.get(Le(f));pr.delete(Le(f)),W?.(),We(k)||(x==="folder"?await vs():await _e(k))},_e=async(f,b=!1)=>{if(!h||We(f))return;if(ie?.path===f){ie.after.push({key:f,run:()=>_e(f,b)});return}if(!s(f,Xe(f))){Ke(f);return}if(!await Et())return;let k=await vt(f);if(We(f))return;let x=h.files[f]??null,N=jr(k?.hash??null,x,x?{seq:x.seq,hash:x.hash}:null);switch(N.kind){case"push":At(Xe(f))?await ur(f,N.baseSeq):await dr(f,N.baseSeq);break;case"pushCreate":At(Xe(f))?await ur(f,0):await dr(f,0);break;case"pushDelete":if(b){yr();break}if(!U&&(I.has(f)||fe())){I.set(f,"remote"),Q(),v();break}V.push(Date.now()),await xi(f);break;case"dropShadow":Ke(f);break;default:k&&x&&k.hash===x.hash&&k.mtimeMs>=0&&(x.size!==k.size||x.mtimeMs!==k.mtimeMs)&&await kt(f,x.seq,x.hash,k);break}},Ti=async()=>{let f=new Map;if(!R||!h)return f;let b=R,k=null,x=async N=>{if(k)return;let L;try{L=await i.readdir(N,{withFileTypes:!0})}catch(W){k=`${N}: ${W?.message??String(W)}`;return}for(let W of L){if(Mn(W.name)||W.isDirectory()&&e.ignoreNames?.includes(W.name))continue;let j=a.join(N,W.name);if(W.isDirectory())await x(j);else if(W.isFile()){let X=a.relative(b,j).split(a.sep).join("/"),q=n(X);if(!q)continue;try{let oe=await i.stat(j);if(!oe.isFile())continue;f.set(q,{size:oe.size,mtimeMs:Math.floor(oe.mtimeMs)})}catch(oe){if(oe?.code==="ENOENT")continue;k=`${j}: ${oe?.message??String(oe)}`;return}}}};return await x(b),k?(A("error",`scan-failed: ${k}`),ue(),null):f},vs=async()=>{let f=ve;if(pt()||f!==ve||!h||!await Et())return;let b=await Ti();if(!b||pt()||f!==ve)return;let k=!1;for(let[L,W]of[...I])(W==="remote"&&b.has(L)||W==="local"&&!b.has(L))&&(I.delete(L),k=!0);I.size||ge();for(let[L,W]of b){let j=h.files[L];j&&j.size===W.size&&j.mtimeMs===W.mtimeMs||P({key:L,run:()=>_e(L)})}let x=Object.keys(h.files),N=x.filter(L=>!b.has(L));if(N.length&&!U&&($||co(N.length,x.length,ac))){ee();for(let L of N)I.set(L,"remote");Q(),v();return}k&&(Q(),v());for(let L of N)I.has(L)||P({key:L,run:()=>_e(L)})},Jt=async()=>{if(ie){ie.after.push({run:Jt});return}let f=ve;if(pt()||f!==ve||!m||!h||!R||!await Et())return;let b=await m.tree(h.vaultId);if(b.maxFileBytes!==void 0&&b.maxFileBytes!==C&&(C=b.maxFileBytes,v()),pt()||f!==ve)return;let k=new Map;for(let q of b.entries)r(q.path)===null||!s(q.path,q.kind)||k.set(q.path,q);for(let[q,oe]of[...ne])oe&&!k.has(q)&&Gt(q,null);let x=await Ti();if(!x||pt()||f!==ve)return;let N=new Set([...k.keys(),...x.keys(),...Object.keys(h.files)]),L=Object.keys(h.files).length,W=[];for(let q of N){if(pt()||f!==ve)return;let oe=h.files[q]??null,pe=k.get(q)??null,Ne=x.get(q)??null,ot=null,Kt=lr(Ne?.size??0);if(Ne)if(oe&&oe.size===Ne.size&&oe.mtimeMs===Ne.mtimeMs)ot=oe.hash,Kt=Ne;else{let Xt=await vt(q);Xt&&(ot=Xt.hash,Kt=Xt)}W.push({sp:q,d:jr(ot,oe,pe?{seq:pe.seq,hash:pe.hash}:null),rSeq:pe?.seq??null,localHash:ot,localStat:Kt})}if(pt()||f!==ve)return;let j=W.filter(q=>q.d.kind==="deleteLocal"||q.d.kind==="pushDelete").length,X=!U&&($||co(j,L,ac));X&&j&&ee(),I.clear();for(let{sp:q,d:oe,rSeq:pe,localHash:Ne,localStat:ot}of W){if(pt()||f!==ve)return;if(X&&(oe.kind==="deleteLocal"||oe.kind==="pushDelete")){I.set(q,oe.kind==="deleteLocal"?"local":"remote");continue}if((oe.kind==="deleteLocal"||oe.kind==="pushDelete")&&((await vt(q))?.hash??null)!==Ne){P({key:q,run:()=>_e(q)});continue}if(pt()||f!==ve)return;switch(oe.kind){case"adopt":await kt(q,pe,Ne,ot);break;case"pull":await st(q,pe);break;case"push":At(Xe(q))?await ur(q,oe.baseSeq):await dr(q,oe.baseSeq);break;case"pushCreate":At(Xe(q))?await ur(q,0):await dr(q,0);break;case"pushDelete":await xi(q);break;case"deleteLocal":await Ei(q),Ke(q);break;case"conflict":await st(q,pe);break;case"dropShadow":Ke(q);break;case"none":break}}U&&(U=!1,V.length=0),I.size||ge(),Q(),X&&v();for(let q of b.folders)if(!(r(q)===null||!s(q,"folder")))try{await i.mkdir(Re(q),{recursive:!0})}catch{}h.cursor=b.seq,h.lastSyncAt=Date.now(),E.save(h)},Ru=async()=>{if(!m||!h)return;let f=h.cursor,b=await m.changes(h.vaultId,f);if(b.changes.length===0&&b.seq>f||b.changes.length>0&&b.changes[0].seq!==f+1){await Jt();return}for(let x of b.changes)await Ci(x)},kn=null,Ri=[],Ii=()=>{kn&&Ri.push(kn.close()),kn=null},Iu=()=>{if(!l||kn||!R)return;let f=Ce();if(!f.watch)return;let b=k=>{if(!R)return;let x=a.relative(R,k);if(!x||x.startsWith(".."))return;let N=n(x);N&&H(N)};kn=f.watch(R,{depth:12,ignored:k=>{let x=a.basename(k);return Mn(x)||!!e.ignoreNames?.includes(x)}},{change:b,add:b,unlink:()=>yr(),unlinkDir:()=>yr()})},gr=()=>{w?.stop(),w=null},Du=()=>{if(!l||!m||!h||w)return;let f=_;f&&(w=tc({baseUrl:f.cloudUrl,vaultId:h.vaultId,token:f.token,getToken:M},{getSince:()=>h?.cursor??0,onHello:b=>{h&&b>h.cursor&&P({run:Ru})},onChange:b=>{P({run:()=>Ci(b)})},onReset:()=>{P({run:Jt})},onOpen:()=>{(p==="offline"||p==="starting")&&A("idle",null),P({run:vs})},onDown:()=>{(p==="idle"||p==="syncing")&&A("offline")},onPresence:b=>t.onPresence?.(h?.vaultId??"",b),onPresenceRoster:b=>t.onPresenceRoster?.(h?.vaultId??"",b)}))},Ou=async()=>{let f=await Ye(o);if(f.cloudSync?.deviceId)return f.cloudSync.deviceId;let b=`desk-${Math.random().toString(36).slice(2,10)}${Date.now().toString(36)}`;return await gt({cloudSync:{...f.cloudSync??{},deviceId:b}},o),b},Pu=async f=>{gr(),Ii(),ye.length=0,he.clear(),I.clear(),U=!1,$=!1,V.length=0;let b=await Ye(o);if(f!==u)return;let k=b.cloudSync;if(k?.enabled===!1){R=null,m=null,A("disabled",null);return}if(!o||o!==Pe()){A("auth-required","not-logged-in");return}if(R=e.localRoot,e.requireRootExists){let W=await i.stat(R).then(j=>j.isDirectory()).catch(()=>!1);if(f!==u)return;if(!W){A("error",`vault-missing: ${R}`),ue();return}}if(f!==u)return;let x=t.loadCreds();if(!x.cloudUrl||!x.token){m=null,A("auth-required","not-logged-in");return}A("starting",null);let N=k?.deviceId??await Ou();if(f!==u)return;let L=e.clientIdSuffix?`${N}#${e.clientIdSuffix}`:N;_={cloudUrl:x.cloudUrl,token:x.token},m=ec({baseUrl:x.cloudUrl,token:x.token,clientId:L,getToken:()=>{if(f!==u)throw new xe(401,{code:"ACCOUNT_CHANGED"},"sync-session");return M()}});try{let W=e.vaultId==="first"?k?.vaultId:e.vaultId;if(!W){let q=await m.listVaults();if(f!==u)return;if(!q.length)throw new Error("\u4E91\u7AEF\u65E0\u53EF\u7528 vault");W=q[0].id,await gt({cloudSync:{...k??{},vaultId:W}},o)}if(f!==u)return;let j=await fo(e.shadowName);if(f!==u||(h=j&&j.vaultRoot===R&&j.vaultId===W&&j.folder===""?j:{vaultRoot:R,folder:"",vaultId:W,cursor:0,lastSyncAt:null,files:{}},f!==u))return;for(let[q,oe]of Object.entries(h.pending??{}))I.set(q,oe);I.size&&($=!0);let X=await Ss(R);if(f!==u||!X&&!e.requireRootExists&&!h.rootIdentity&&!Object.keys(h.files).length&&(await i.mkdir(R,{recursive:!0}),X=await Ss(R),f!==u)||!Ai(X)||!h.rootIdentity&&typeof X?.dev=="number"&&Number.isInteger(X.dev)&&X.dev>=0&&typeof X.ino=="number"&&Number.isInteger(X.ino)&&X.ino>0&&(h.rootIdentity={dev:X.dev,ino:X.ino},E.save(h),await E.flush(!0),f!==u||!await Et()))return;Iu();for(let q of h.moves??[])P({key:`move:${Le(q)}`,run:()=>hr(q)});P({run:Jt}),P({run:async()=>{Du()}})}catch(W){if(f!==u)return;G(W)?A("auth-required","login-expired"):(A("offline",W?.message||String(W)),ue())}},Di=()=>{l=!1,gr(),Ii(),ye.length=0,he.clear(),z();for(let f of[Fe,be,F,Y])f&&clearTimeout(f);Fe=be=F=Y=null,ie?.abort.abort(),ie=null},Oi=async()=>{ze&&await new Promise(f=>g.add(f)),await Promise.all(Ri.splice(0)),await E.flush(),h=null,m=null,_=null,R=null,O=0,S.clear(),ne.clear(),me=0,C=null,I.clear(),U=!1,$=!1,V.length=0,p="disabled",y=null},Mu=()=>{Pi()},mr=null,En=()=>{mr?.(),mr=He().onBeforeQuit(Mu);let f=++u;Di();let b=d.catch(()=>{}).then(async()=>{await Oi(),f===u&&(l=!0,await Pu(f))});return d=b,b},Pi=()=>{mr?.(),mr=null,++u,Di();let f=d.catch(()=>{}).then(Oi);return d=f,f},jt=()=>({enabled:p!=="disabled",state:p==="idle"&&(B.size||ne.size)?"syncing":p,lastSyncAt:h?.lastSyncAt??null,pending:ye.length+B.size+ne.size,conflicts:O,skipped:[...S].map(([f,b])=>({path:f,reason:b})),error:y,pendingDeletions:I.size,maxFileBytes:C});return{getStatus:jt,start(){En()},notifyLocal(f,b,k){if(!h||p==="disabled"||p==="auth-required")return;let x=n(f),N=k?n(k):null;if(b==="write"&&x){Mn(x.split("/").pop()||"")||H(x);return}if(b==="remove"){if(!x)return;let L=`${x}/`,W=!1;for(let j of Object.keys(h.files))(j===x||j.startsWith(L))&&(W=!0,P({key:j,run:()=>_e(j)}));!W&&x&&P({key:x,run:()=>_e(x)})}},holdLocalMove(f,b){let k=N=>e.serverDir?`${e.serverDir}/${N.replace(/\\/g,"/").normalize("NFC")}`:N.replace(/\\/g,"/").normalize("NFC"),x={from:k(f),to:k(b)};return++ve,fr.add(x),()=>{fr.delete(x)}},async notifyLocalMove(f,b,k,x){let N=n(f),L=n(b),W=h??await fo(e.shadowName),j=lo(f,""),X=j&&(e.serverDir?`${e.serverDir}/${j}`:j);if(!N&&L&&X&&W&&Object.keys(W.files).some(q=>q===X||q.startsWith(`${X}/`))&&(N=X),!N&&!L){k?.();return}if(N&&L){let q=h??W;if(!q){k?.();return}let oe=x??(Object.keys(q.files).some(Ne=>Ne.startsWith(`${N}/`))?"folder":"file"),pe={from:N,to:L,kind:oe};q.moves??=[],q.moves.some(Ne=>Le(Ne)===Le(pe))||(q.moves.push(pe),++ve),k&&pr.set(Le(pe),k),E.save(q);try{await E.flush(!0)}catch(Ne){throw q.moves=q.moves.filter(ot=>Le(ot)!==Le(pe)),pr.delete(Le(pe)),E.save(q),Ne}h===q&&l&&p!=="disabled"&&p!=="auth-required"&&P({key:`move:${Le(pe)}`,run:()=>hr(pe)});return}N&&this.notifyLocal(f,"remove"),L&&(P({key:L,run:()=>_e(L)}),yr()),k?.()},async setEnabled(f){let b=await Ye(o);return await gt({cloudSync:{...b.cloudSync??{},enabled:f}},o),await En(),jt()},async restart(){return await En(),jt()},async syncNow(){if(S.clear(),p==="disabled"||p==="auth-required"||!m)await En();else{be&&(clearTimeout(be),cr());for(let f of h?.moves??[])P({key:`move:${Le(f)}`,run:()=>hr(f)});P({run:Jt})}return jt()},confirmMassDeletions(){return I.size&&(U=!0,$=!1,I.clear(),V.length=0,Q(),P({run:Jt})),jt()},stop:Pi};function yr(){l&&(F&&clearTimeout(F),F=setTimeout(()=>{F=null,P({run:vs})},Qf))}}function po(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 ho(t){return/\.md$/i.test(t)?po(t):{root:t,fdPrefix:"\0",assetPrefix:"\0"}}function cc(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 ap=t=>Ce().sha256Hex(t).slice(0,8),cp=t=>t.replace(/[\\/:*?"<>|]/g," ").trim().slice(0,40)||"shared",zr="\u4E0E\u6211\u5171\u4EAB";function lc(t,e){let n=ap(`${t.vaultId}:${t.path}`),r=t.path.includes("/")?t.path.slice(0,t.path.lastIndexOf("/")):"";return{key:n,vaultId:t.vaultId,rootPath:t.path,title:t.title,localRelDir:`${zr}/${cp(t.title)}-${n}`,serverDir:r,inScope:(s,o)=>e.some(i=>cc(i,s,o)),scopeKey:e.map(s=>s.root).join("\0")}}function uc(t){return lc(t,[po(t.path),...(t.items??[]).map(ho)])}function dc(t){let e=t.map(uc),n=t.flatMap((s,o)=>{let i=e[o].serverDir?`${e[o].serverDir}/`:"";return(s.items??[]).filter(a=>!a.startsWith(i)).map(a=>lc({vaultId:s.vaultId,path:a,title:(a.split("/").pop()??a).replace(/\.md$/i,"")},[ho(a)]))}),r=new Map;for(let s of[...e,...n])r.has(s.key)||r.set(s.key,s);return[...r.values()]}var lp=t=>{let e=[];for(let n of t.split("/"))!n||n==="."||(n===".."&&e.length&&e[e.length-1]!==".."?e.pop():e.push(n));return e.join("/")};function fc(t,e){let n=c=>c.normalize("NFC"),r=n(e.replace(/\\/g,"/")),s=t.find(c=>r.startsWith(`${n(c.localRelDir)}/`));if(!s)return null;let o=r.slice(n(s.localRelDir).length+1),i=lp(s.serverDir?`${s.serverDir}/${o}`:o);if(!i||i===".."||i.startsWith("../"))return null;let a=[s,...t].find(c=>c.vaultId===s.vaultId&&(!c.serverDir||i.startsWith(`${c.serverDir}/`))&&c.inScope(i,Xe(i)));return a?`${a.localRelDir}/${a.serverDir?i.slice(a.serverDir.length+1):i}`:null}function go(){let t=He().readCreds(),e=Oe(t.cloudUrl??"",t.token??""),n=new AbortController,r=()=>{let d=He().readCreds();if(n.signal.aborted||!e||Oe(d.cloudUrl??"",d.token??"")!==e)throw Object.assign(new Error("Cloud account changed; retry from the current account"),{status:401});return d},s=()=>{let d=r();if(!d.cloudUrl||!d.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});return d.cloudUrl.replace(/\/+$/,"")},o=async(d,g,p)=>{let y=r();if(!y.cloudUrl||!y.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});let h=await fetch(`${y.cloudUrl.replace(/\/+$/,"")}/api/amadeus${g}`,{method:d,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(!h.ok){let w=null;try{w=await h.json()}catch{}throw Object.assign(new Error(w?.detail||`http ${h.status}`),{status:h.status,code:w?.code})}let m=await h.json();return r(),m},i=null,a=async()=>(r(),i||(i=(await o("GET","/vaults")).vaults[0]?.id??"default",i)),c=()=>{try{let d=(r().token??"").split(".")[1],g=JSON.parse(_t(wr(d)));return typeof g.userId=="string"?g.userId:null}catch{return null}},l=async()=>(await o("GET","/shared-with-me")).items.map(g=>{let p=uc(g),y=g.path.split("/").pop()??g.path;return{...g,localPath:`${p.localRelDir}/${y}`}}),u=null;return{stop:()=>n.abort(),call:o,ensureOwnVault:a,myUserId:c,sharedWithMe:l,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(d,g){let p=(d??"").replace(/\\/g,"/"),y,h=null,m=g.find(w=>p.startsWith(`${w.localRelDir}/`));m?(y=m.vaultId,h=m.serverDir?`${m.serverDir}/${p.slice(m.localRelDir.length+1)}`:p.slice(m.localRelDir.length+1)):(y=await a(),h=p||null),await o("POST",`/vaults/${encodeURIComponent(y)}/presence`,{page:h})}}}import{promises as gc}from"node:fs";import up from"node:path";var mo=".forsion-vault.md",pc=t=>`${t}/${mo}`;function Br(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 hc=t=>`---
210
215
  devices: ${JSON.stringify(t.map(e=>({id:e.id,name:e.name,...e.since?{since:e.since}:{}})))}
211
216
  ---
212
- `;var Ge=t=>t.replace(/\\/g,"/").normalize("NFC");function ho(t){let e=Ge(t.path);return e?t.kind==="folder"?`${e}/`:t.kind==="page"?`${e.replace(/\.md$/i,"")}.fd/`:null:null}function nn(t,e,n){let r=Ge(n);if(!r)return!1;if(t.some(s=>Ge(s.path)===r))return!0;for(let s of e??[]){let o=Ge(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=ho(s);return!!o&&r.startsWith(o)})}function go(t,e,n){let r=Ge(t),s=Ge(e);return r===s?Ge(n):r.startsWith(`${s}/`)?Ge(n)+r.slice(s.length):null}function jn(t,e,n){let r=!1,s=t.map(o=>{let i=go(o,e,n);return i===null?o:(r=!0,i)});return{changed:r,next:s}}async function cl(t){let e=await ll.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 ll.readFile(Kf.join(t,s.name,po),"utf8").catch(()=>null);if(o===null)continue;n.push(s.name);let i=zr(o);i?.length&&(r[s.name]=i)}return{names:n.sort(),devices:r}}var Ae={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 Br=t=>Ce().sha256Hex(t).slice(0,8);function ul(t){return t.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}\)(?=(?:\.[^./]+)?$)/,"")}function Rt(t,e=[]){let n=[],r=[];for(let s of t){let o=Ge(s.path);if(!o)continue;r.push(o);let i=ho(s);i&&n.push(i)}return{entries:t,exclude:e,prefixes:n,paths:r}}function dl(t,e){let n=ul(Ge(e));if(!n)return!1;if(nn(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 Fn(t,e,n){let r=!1,s=t.map(o=>{let i=go(o.path,e,n);return i===null?o:(r=!0,{...o,path:i})});return{changed:r,next:s}}function fl(t,e,n,r){if(e==="delete"||e==="delete-folder"){let s=Ge(n),o=t.filter(i=>{let a=Ge(i.path);return!(a===s||e==="delete-folder"&&a.startsWith(`${s}/`))});return{changed:o.length!==t.length,next:o}}return r?Fn(t,n,r):{changed:!1,next:t}}function mo(t,e){let n=xt(t);return!n||n!==t.normalize("NFC").trim()?"\u540D\u79F0\u4E0D\u5408\u6CD5":n.includes("/")?"\u540D\u79F0\u4E0D\u80FD\u5305\u542B /":n===Hr?`\u300C${Hr}\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 Xf,promises as pl}from"node:fs";async function hl(t,e){try{await pl.copyFile(Mn(t),Mn(e),Xf.COPYFILE_EXCL)}catch(n){let r=n?.code;if(r==="EEXIST"||r==="ENOENT")return!1;throw n}return await pl.unlink(Mn(t)).catch(()=>{}),!0}var Zf=/^\d{4}-\d{2}-\d{2}$/,gl=["vault","content"],ml=new Set(za),Qf=40,rn=t=>new Date(t).toISOString().slice(0,10),Un=t=>typeof t=="string"&&Zf.test(t),yl=!1,Ze=Object.create(null),sn=!1,yo=()=>Date.now(),Ln=new Set,qr="";function nt(t,e,n=1,r){try{if(!yl||!ml.has(e)||!(typeof n=="number"&&Number.isFinite(n)&&n>0))return;let s=rn(yo());if(r!==void 0){s!==qr&&(Ln.clear(),qr=s);let a=`${t}\0${e}\0${r}`;if(Ln.has(a))return;Ln.add(a)}let o=Ze[s]??={},i=o[t]??={};i[e]=(i[e]??0)+Math.round(n),sn=!0}catch{}}function wo(t){yl=t}function wl(t){if(Ze=Object.create(null),Ln.clear(),qr="",sn=!1,!(!t||typeof t!="object"||Array.isArray(t))){for(let[e,n]of Object.entries(t))if(!(!Un(e)||!n||typeof n!="object"))for(let r of gl){let s=n[r];if(!s||typeof s!="object")continue;let o={};for(let[i,a]of Object.entries(s))ml.has(i)&&typeof a=="number"&&Number.isFinite(a)&&a>0&&(o[i]=Math.round(a));Object.keys(o).length&&((Ze[e]??={})[r]=o)}}}function bl(){let t=rn(yo()-Qf*864e5),e={};for(let n of Object.keys(Ze).sort()){if(n<t){delete Ze[n];continue}e[n]=JSON.parse(JSON.stringify(Ze[n]))}return e}var Sl=()=>sn,vl=()=>{sn=!1};function kl(t,e){let n=[];for(let r of Object.keys(Ze).sort())if(!(r<=t||r>e))for(let s of gl){let o=Ze[r][s];o&&Object.keys(o).length&&n.push({day:r,system:s,counts:{...o}})}return n}function bo(t){for(let e of Object.keys(Ze))e<=t&&(delete Ze[e],sn=!0)}function El(){Object.keys(Ze).length&&(sn=!0),Ze=Object.create(null),Ln.clear(),qr=""}function _l(t){yo=t}var Cl=["setAmadeusSyncFactory","readCreds","accountId","homeDir"],So=t=>Cl.every(e=>typeof t[e]=="function"),np=()=>({enabled:!1,state:"disabled",lastSyncAt:null,pending:0,conflicts:0,skipped:[],error:null,pendingDeletions:0,maxFileBytes:null,side:"local"});function vo(t){let e=null,n=()=>{if(!e)throw new Error("Cloud sync is not ready");return e};t.handle(Ae.get,()=>e?e.get():np()),t.handle(Ae.setEnabled,(r,s)=>n().setEnabled(s)),t.handle(Ae.syncNow,()=>n().syncNow()),t.handle(Ae.confirmDeletions,()=>n().confirmDeletions()),t.handle(Ae.entryGet,()=>n().entryGet()),t.handle(Ae.otherSideDbs,()=>n().otherSideDbs()),t.handle(Ae.entryEnable,(r,s)=>n().entryEnable(s)),t.handle(Ae.entryDisable,(r,s)=>n().entryDisable(s)),t.handle(Ae.entryMark,(r,s,o)=>n().entryMark(s,o)),t.handle(Ae.entryClosure,(r,s,o)=>n().entryClosure(s,o)),t.handle(Ae.collabCall,(r,s,o)=>n().collabCall(s,o)),t.handle(Ae.switchSide,(r,s)=>n().switchSide(r.sender.id,s)),t.setAmadeusSyncFactory(r=>{Fa(r);let s=xl(r);return e=s.handlers,s.instance}),t.log("[forsion-extend] amadeus cloud sync registered")}function xl(t){let e=t.notifyAll,n=()=>t.vaultRoot(),r=0,s=!1,o=fo(),i=new Map,a=()=>{let v=Date.now();for(let[A,T]of i)v-T.at>7e4&&i.delete(A);e(Ae.presence,[...i.values()])},c={loadCreds:()=>t.readCreds(),onHealth:(v,A,T)=>nt("vault",v,A,T),onStatus:v=>e(Ae.status,{...v,pendingDeletions:ye(),side:m()?"cloud":"local"}),onPresence:(v,A)=>{let T=A;T?.userId&&(i.set(T.userId,{userId:T.userId,username:String(T.username??"user"),page:T.page??null,at:Number(T.at)||Date.now()}),a())},onPresenceRoster:(v,A)=>{if(Array.isArray(A)){for(let T of A){let D=T;D?.userId&&i.set(D.userId,{userId:D.userId,username:String(D.username??"user"),page:D.page??null,at:Number(D.at)||Date.now()})}a()}}},u=()=>{let v=r;return{...c,onStatus:A=>{v===r&&c.onStatus(A)},onPresence:(A,T)=>{v===r&&c.onPresence(A,T)},onPresenceRoster:(A,T)=>{v===r&&c.onPresenceRoster(A,T)}}},f=Nn(u()),g=new Map,p=[],y=0,h=async()=>{if(!s||!Pe())return;let v=r,A=++y,T=o,D;try{D=await T.sharedWithMe()}catch{return}if(v!==r||!s||A!==y)return;let P=sl(D);p=P;let B=new Map(P.map(H=>[H.key,H.scopeKey]));for(let[H,z]of g)if(B.get(H)!==z.plan.scopeKey){if(await z.engine.stop(),v!==r)return;g.delete(H)}for(let H of P){if(g.has(H.key))continue;let z=Nn(u(),{localRoot:Ut.join(Ct(),...H.localRelDir.split("/")),shadowName:`amadeus-sync-${Pn()}-share-${H.key}`,vaultId:H.vaultId,serverDir:H.serverDir,inScope:H.inScope});g.set(H.key,{engine:z,plan:H}),z.start()}},m=()=>n()===Ct(),w=(v,A=v.base)=>{v.base=A;let T=[A,...v.pendingMoves];v.scope.current=Rt(T.flatMap(D=>D.entries),T.flatMap(D=>D.exclude))},_=new Map,$=new Set,R=new Set,O=null,S=()=>O??=new Promise(v=>{let A=()=>tp.hostname().replace(/\.(local|lan|home)$/i,"")||"Desktop";if(process.platform!=="darwin")return v(A());ep("scutil",["--get","ComputerName"],{timeout:1500},(T,D)=>v(!T&&String(D).trim()||A()))}),C=async()=>{let v=(await Ye()).cloudSync?.deviceId;return v?{id:v,name:await S()}:null},E=new Map,I=(v,A,T)=>{let D=r,P=(E.get(v)??Promise.resolve()).catch(()=>{}).then(async()=>{D!==r||T&&!await T()||D!==r||await U(v,A,D)});return E.set(v,P),P.finally(()=>{E.get(v)===P&&E.delete(v)}).catch(()=>{}),P},U=async(v,A,T)=>{let D=o,P=encodeURIComponent(await D.ensureOwnVault()),B=il(v);for(let H=0;H<3;H++){let z=null;try{z=await D.call("GET",`/vaults/${P}/file?path=${encodeURIComponent(B)}`)}catch(G){if(G?.status!==404)throw G}let J=A(!!z,z?zr(z.content):null);if(J===void 0||T!==r)return;try{if(J===null){z&&await D.call("DELETE",`/vaults/${P}/file?path=${encodeURIComponent(B)}&baseSeq=${z.seq}`);return}await D.call("PUT",`/vaults/${P}/file`,{path:B,content:al(J),baseSeq:z?.seq??0});return}catch(G){if(G?.status!==409)throw G}}throw Object.assign(new Error("marker write kept conflicting"),{status:409})},M=async v=>!!(await Ye()).entrySync?.some(A=>A.cloudName===v&&A.entries.length>0),V=(v,A)=>I(v,(T,D)=>{let P=D?.find(H=>H.id===A.id);if(P&&P.name===A.name)return;let B=P?.since??new Date().toISOString().slice(0,10);return[...(D??[]).filter(H=>H.id!==A.id),{...A,since:B}]},()=>M(v)),Z=(v,A)=>I(v,(T,D)=>{if(!T||!D?.some(B=>B.id===A))return;let P=D.filter(B=>B.id!==A);return P.length?P:null},async()=>!await M(v)),re=()=>{e(Ae.entryChange)},se=async(v,A)=>{let T=_.get(v);if(!T)return;let D=H=>H&&H.startsWith(`${T.cloudName}/`)?H.slice(T.cloudName.length+1):null,P=D(A.path);if(!P)return;let B=!1;await tn(H=>{if(_.get(v)!==T)return!1;let z=(H.entrySync??[]).find(ue=>ue.vaultRoot===v);if(!z)return!1;let J=A.op,G=D(A.newPath),K=fl(z.entries,J,P,G),te=G?jn(z.exclude??[],P,G):{changed:!1,next:z.exclude??[]};if(!K.changed&&!te.changed)return!1;B=!0,z.entries=K.next,te.changed&&(z.exclude=te.next),w(T,Rt(z.entries,z.exclude??[]))}),B&&_.get(v)===T&&re()},ee=v=>{let A=r;return{...u(),onStatus:T=>{A===r&&e(Ae.status,{...T,pendingDeletions:ye(),side:"local",binding:v})},onRemoteApplied:async T=>{A===r&&await se(v,T)}}},Q=async()=>{let v=Pe();if(!s||!v)return;let A=r,T=o,D=Pn(v);await t.adoptLegacyCloudState(v,hl);let P=await Ye(v),B=P.entrySync??[];if(A!==r||!s||v!==Pe())return;let H=new Map(B.map(z=>[z.vaultRoot,z]));for(let[z,J]of _){let G=H.get(z);if(!(G&&G.cloudName===J.cloudName)&&(await J.engine.stop(),A!==r||(_.delete(z),G&&await Za(`amadeus-sync-${D}-entry-${Br(z)}`),A!==r)))return}for(let z of B){let J=_.get(z.vaultRoot);if(J){w(J,Rt(z.entries,z.exclude??[]));continue}let G={current:Rt(z.entries,z.exclude??[])},K=z.cloudName,te=Nn(ee(z.vaultRoot),{accountId:v,localRoot:z.vaultRoot,shadowName:`amadeus-sync-${D}-entry-${Br(z.vaultRoot)}`,vaultId:"first",serverDir:K,clientIdSuffix:`entry-${Br(z.vaultRoot)}`,requireRootExists:!0,ignoreNames:[".git","node_modules",".trash"],inScope:ue=>ue===K?!0:ue.startsWith(`${K}/`)?dl(G.current,ue.slice(K.length+1)):!1});_.set(z.vaultRoot,{engine:te,scope:G,cloudName:K,base:G.current,pendingMoves:new Set}),te.start()}if(P.cloudSync?.enabled!==!1)for(let z of B){let J=z.entries.length>0,G=J?$:R;G.has(z.cloudName)||((J?R:$).delete(z.cloudName),(async()=>{try{let K=await C();if(!K||A!==r||(await(J?V(z.cloudName,K):Z(z.cloudName,K.id)),A!==r))return;G.add(z.cloudName),(J?R:$).delete(z.cloudName)}catch{}})())}},ge=async(v,A,T,D,P)=>{let B=A.replace(/\\/g,"/").normalize("NFC"),H=T.replace(/\\/g,"/").normalize("NFC"),z=!1,J,G,K,te=P??"file";try{await tn(async ue=>{if(_.get(v)!==D)return!1;let ne=(ue.entrySync??[]).find(Me=>Me.vaultRoot===v);if(!ne)return!1;let me=Fn(ne.entries,B,H),ie=jn(ne.exclude??[],B,H),Be=nn(ne.entries,ne.exclude,B);!P&&await on.stat(Ut.join(v,...H.split("/"))).then(Me=>Me.isDirectory(),()=>!1)&&(te="folder");let Nt=te==="folder"?"folder":/\.md$/i.test(H)?"page":"asset";Be&&!nn(me.next,ie.next,H)&&(me.next.push({path:H,kind:Nt}),me.changed=!0),z=me.changed||ie.changed;let Yt=ne.entries.filter(Me=>Fn([Me],B,H).changed);return Be&&!Yt.some(Me=>Me.path===B)&&Yt.push({path:B,kind:Nt}),J=Rt(Yt,(ne.exclude??[]).filter(Me=>jn([Me],B,H).changed)),G=D.base,D.pendingMoves.add(J),ne.entries=me.next,ne.exclude=ie.next,K=Rt(ne.entries,ne.exclude),w(D,K),z})}catch(ue){throw J&&D.pendingMoves.delete(J),w(D,D.base===K&&G?G:D.base),ue}try{J&&await D.engine.notifyLocalMove(B,H,()=>{D.pendingMoves.delete(J),w(D)},te)}catch(ue){throw J&&D.pendingMoves.delete(J),await tn(ne=>{let me=ne.entrySync?.find(ie=>ie.vaultRoot===v);if(!me)return!1;me.entries=Fn(me.entries,H,B).next,me.exclude=jn(me.exclude??[],H,B).next,w(D,Rt(me.entries,me.exclude))}),ue}z&&_.get(v)===D&&re()},fe=v=>{let A=v.replace(/\\/g,"/");for(let{engine:T,plan:D}of g.values())if(A.startsWith(`${D.localRelDir}/`))return{engine:T,rel:A.slice(D.localRelDir.length+1)};return{engine:f,rel:A}};t.setMutationHooks((v,A)=>{if(m()){let T=fe(v);T.engine.notifyLocal(T.rel,A);return}_.get(n()??"")?.engine.notifyLocal(v,A)},(v,A,T)=>{if(m()){let B=fe(v),H=fe(A);if(B.engine===H.engine)return B.engine.notifyLocalMove(B.rel,H.rel,void 0,T);B.engine.notifyLocal(B.rel,"remove"),H.engine.notifyLocal(H.rel,"write");return}let D=n()??"",P=_.get(D);if(P)return ge(D,v,A,P,T)},(v,A)=>{if(m()){let T=fe(v),D=fe(A),P=[T.engine.holdLocalMove(T.rel,D.rel)];return T.engine!==D.engine&&P.push(D.engine.holdLocalMove(T.rel,D.rel)),()=>{for(let B of P)B()}}return _.get(n()??"")?.engine.holdLocalMove(v,A)});let ye=()=>{let v=f.getStatus().pendingDeletions;for(let{engine:A}of g.values())v+=A.getStatus().pendingDeletions;for(let{engine:A}of _.values())v+=A.getStatus().pendingDeletions;return v},he=v=>({...v,pendingDeletions:ye(),side:m()?"cloud":"local"}),ze=()=>{if(!s)return Promise.resolve(f.getStatus());h();for(let{engine:v}of g.values())v.syncNow();for(let{engine:v}of _.values())v.syncNow();return f.syncNow()},Fe=async()=>{++r,s=!1,o.stop();let v=[f.stop(),...[...g.values()].map(({engine:T})=>T.stop()),...[..._.values()].map(({engine:T})=>T.stop())];g.clear(),_.clear(),p=[],$.clear(),R.clear(),i.clear(),a(),await Promise.all(v),await t.awaitPendingVaultWrites();let A=n();if(A&&$r(A)){let T=await Ye(),D=T.localVault&&!$r(T.localVault)?T.localVault:Ut.join(t.workspaceDir(),"Amadeus");await on.mkdir(D,{recursive:!0}),await gt({lastVault:D,localVault:D,lastPage:void 0}),await t.activateRoot(D,!1)}re()};return{handlers:{get:()=>he(f.getStatus()),setEnabled:async v=>{if(!s)throw new Error("Cloud account is changing");let A=r;return await f.setEnabled(v),A!==r?f.getStatus():(await Promise.all([...g.values(),..._.values()].map(({engine:T})=>T.restart())),he(f.getStatus()))},syncNow:()=>ze(),confirmDeletions:()=>{for(let{engine:v}of g.values())v.confirmMassDeletions();for(let{engine:v}of _.values())v.confirmMassDeletions();return he(f.confirmMassDeletions())},entryGet:async()=>{let v=await Ye(),A=Ct(),T=await cl(A);return{vaults:v.entrySync??[],activeRoot:n(),cloudRoot:A,mirrorVaults:T.names,mirrorVaultDevices:T.devices,deviceId:v.cloudSync?.deviceId??null}},otherSideDbs:async()=>{let v=n();if(!v)return null;let A=Ct(),T=await Ye(),D=v===A?T.localVault&&T.localVault!==A?T.localVault:null:A;if(!D)return null;let P=[],B=500,H=async(z,J)=>{if(P.length>=B)return;let G;try{G=await on.readdir(z,{withFileTypes:!0})}catch{return}for(let K of G){if(P.length>=B)break;if(K.name.startsWith(".")||K.isSymbolicLink())continue;let te=J?`${J}/${K.name}`:K.name;if(K.isDirectory())await H(Ut.join(z,K.name),te);else if(K.isFile()&&/\.db$/i.test(K.name))try{P.push({rel:te,source:await on.readFile(Ut.join(z,K.name),"utf8")})}catch{}}};return await H(D,""),{root:D,vaultName:D===A?"\u4E91\u7AEF":Ut.basename(D),dbs:P}},entryEnable:async v=>{let A=r,T=o;if(!s||!Pe())return{error:"Sign in to enable cloud sync"};let D=n();if(!D||m())return{error:"\u4EC5\u672C\u5730 vault \u53EF\u5F00\u542F\u4E91\u540C\u6B65"};let P=await Ye(),B=P.entrySync??[],H=B.find(z=>z.vaultRoot===D);if(!H){let z=(v.cloudName??Ut.basename(D)).normalize("NFC").trim(),J=mo(z,B.map(G=>G.cloudName));if(J)return{error:J};if(!v.merge)try{let G=await T.ensureOwnVault(),K=await T.call("GET",`/vaults/${encodeURIComponent(G)}/tree`);if((K.folders??[]).some(ue=>ue===z||ue.startsWith(`${z}/`))||(K.entries??[]).some(ue=>ue.path===z||ue.path.startsWith(`${z}/`)))return{conflict:z}}catch(G){return{error:G?.message||"\u65E0\u6CD5\u8FDE\u63A5\u4E91\u7AEF(\u9996\u6B21\u5F00\u542F\u9700\u8981\u5728\u7EBF)"}}H={vaultRoot:D,cloudName:z,entries:[]},B.push(H)}return A!==r||!s?{error:"Cloud account changed; retry from the current account"}:(await tn(z=>{if(A!==r||!s)return!1;let J=z.entrySync??[],G=J.find(ie=>ie.vaultRoot===D);if(!G){let ie=mo(H.cloudName,J.map(Be=>Be.cloudName));if(ie)throw new Error(ie);G={vaultRoot:D,cloudName:H.cloudName,entries:[]},J.push(G)}let K=ie=>String(ie??"").replace(/\\/g,"/").normalize("NFC"),te=new Set;for(let ie of v.entries??[]){let Be=K(ie.path);Be&&(te.add(Be),!G.entries.some(Nt=>Nt.path===Be)&&G.entries.push({path:Be,kind:ie.kind==="folder"||ie.kind==="asset"?ie.kind:"page"}))}let ue=(v.exclude??[]).map(K).filter(Boolean),ne=new Set([...te,...(v.include??[]).map(K).filter(Boolean)]);G.exclude=[...new Set([...(G.exclude??[]).filter(ie=>!ne.has(ie)),...ue])];let me=new Set(ue);G.entries=G.entries.filter(ie=>!me.has(ie.path)),z.entrySync=J,H=G},P.cloudAccountId),A!==r?{error:"Cloud account changed; retry from the current account"}:(await Q(),_.get(D)?.engine.syncNow(),re(),{ok:!0,cloudName:H.cloudName}))},entryDisable:async v=>{let A=n(),T=!1,D=r;return await tn(P=>{if(D!==r||!s)return!1;let B=(P.entrySync??[]).find(J=>J.vaultRoot===A);if(!A||!B)return!1;let H=String(v??"").replace(/\\/g,"/").normalize("NFC"),z=B.entries.length;if(B.entries=B.entries.filter(J=>J.path!==H),nn(B.entries,B.exclude,H))B.exclude=[...new Set([...B.exclude??[],H])];else if(B.entries.length===z)return!1;T=!0}),!T||D!==r?{ok:!1}:(await Q(),re(),{ok:!0})},entryMark:async(v,A)=>{let T=String(v??"").normalize("NFC");if(!T||T.includes("/")||T.startsWith("."))return{error:"invalid name"};if(!s||!Pe())return{error:"Sign in first"};try{await I(T,D=>A?D?void 0:[]:D?null:void 0)}catch(D){return{error:D?.message||String(D)}}return f.syncNow(),{ok:!0}},entryClosure:(v,A)=>t.relatedClosure(String(v??""),A==="folder"?"folder":"page"),collabCall:async(v,A)=>{let T=o,D=async()=>T.ensureOwnVault(),P=H=>String((A??[])[H]??""),B=H=>(A??[])[H]??{};switch(v){case"listVaults":return(await T.call("GET","/vaults")).vaults;case"activeVaultId":return D();case"pageShare":return T.call("GET",`/vaults/${encodeURIComponent(await D())}/page-shares?path=${encodeURIComponent(P(0))}`);case"relatedItems":return T.call("GET",`/vaults/${encodeURIComponent(await D())}/page-shares/${encodeURIComponent(P(0))}/related`);case"setShareItem":return T.call("POST",`/vaults/${encodeURIComponent(await D())}/page-shares/${encodeURIComponent(P(0))}/items`,{path:P(1),included:(A??[])[2]===!0});case"createPageShare":return T.call("POST",`/vaults/${encodeURIComponent(await D())}/page-shares`,{path:P(0),...B(1)});case"updatePageShare":return T.call("PATCH",`/vaults/${encodeURIComponent(P(2)||await D())}/page-shares/${encodeURIComponent(P(0))}`,B(1));case"revokePageShare":return T.call("DELETE",`/vaults/${encodeURIComponent(await D())}/page-shares/${encodeURIComponent(P(0))}`);case"setParticipantRole":return T.call("PATCH",`/vaults/${encodeURIComponent(P(3)||await D())}/page-shares/${encodeURIComponent(P(0))}/members/${encodeURIComponent(P(1))}`,{role:P(2)});case"removeParticipant":return T.call("DELETE",`/vaults/${encodeURIComponent(P(2)||await D())}/page-shares/${encodeURIComponent(P(0))}/members/${encodeURIComponent(P(1))}`);case"sharedWithMe":{let H=await T.sharedWithMe();return h(),H}case"leaveShare":{let H=T.myUserId();if(!H)throw new Error("\u672A\u767B\u5F55");let z=await T.call("DELETE",`/vaults/${encodeURIComponent(P(1)||await D())}/page-shares/${encodeURIComponent(P(0))}/members/${encodeURIComponent(H)}`);return h(),z}case"publishes":return T.call("GET",`/vaults/${encodeURIComponent(await D())}/shares`);case"listAllShares":{let H=(await T.call("GET","/vaults")).vaults||[],z=T.myUserId(),J=[],G=[];for(let K of H){try{let te=await T.call("GET",`/vaults/${encodeURIComponent(K.id)}/shares`);for(let ue of te.shares||[])J.push({...ue,vaultId:K.id,vaultName:K.name||""})}catch(te){t.log(`[connect] listAllShares publishes vault ${K.id} failed: ${te?.message}`)}try{let te=await T.call("GET",`/vaults/${encodeURIComponent(K.id)}/page-shares?expired=1`),ue=te?.shares||te?.pageShares||(Array.isArray(te)?te:[]);for(let ne of ue){let me=ne.created_by??ne.createdBy;(!z||!me||me===z)&&G.push({...ne,vaultId:K.id,vaultName:K.name||""})}}catch(te){t.log(`[connect] listAllShares pageShares vault ${K.id} failed: ${te?.message}`)}}return{publishes:J,pageShares:G,linkBase:await T.linkBase()}}case"createPublish":{let H=await T.call("POST",`/vaults/${encodeURIComponent(await D())}/shares`,{mode:P(0),path:P(1)});return{...H,url:`${await T.linkBase()}/share/${H.token}`}}case"revokePublish":return T.call("DELETE",`/vaults/${encodeURIComponent(await D())}/shares/${encodeURIComponent(P(0))}`);case"revokePublishIn":return T.call("DELETE",`/vaults/${encodeURIComponent(P(0))}/shares/${encodeURIComponent(P(1))}`);case"revokePageShareIn":return T.call("DELETE",`/vaults/${encodeURIComponent(P(0))}/page-shares/${encodeURIComponent(P(1))}`);case"myUserId":return T.myUserId();case"linkBase":return T.linkBase();case"heartbeat":return T.heartbeat((A??[])[0]??null,p);default:throw new Error(`unknown collab fn: ${v}`)}},switchSide:async(v,A)=>{let T=await Ye();if(A==="cloud"){if(!s||!Pe())throw new Error("Sign in to open cloud notes");let B=Ct();await on.mkdir(B,{recursive:!0}),T.lastVault&&!$r(T.lastVault)&&await gt({localVault:T.lastVault}),await gt({lastVault:B});let H=await t.activateRoot(B,!1);return t.bindRenderer(v,B),{...H,side:"cloud"}}let D=T.localVault&&await on.stat(T.localVault).then(B=>B.isDirectory()).catch(()=>!1)?T.localVault:null;if(!D){let B=await t.ensureDefaultVault();return t.bindRenderer(v,B.root),{...B,side:"local"}}await gt({lastVault:D});let P=await t.activateRoot(D,!1);return t.bindRenderer(v,D),{...P,side:"local"}}},instance:{start:()=>{s=!0,f.start(),h(),Q()},stopAllSync:Fe,restartAllSync:async()=>{await Fe(),o=fo(),f=Nn(u()),s=!0,await Promise.all([f.restart(),h(),Q()]),re(),e(Ae.status,he(f.getStatus()))},resolveSharedAsset:v=>ol(p,v)}}}import{hostname as rp}from"node:os";var sp=256*1024;function Al(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>sp}var ko=45e3,op=3e3,ip=16*1024,ap=6e4,Wr=t=>`${t.replace(/\/+$/,"")}/api`,Hn=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??ap}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 a=this.deps.getPairing();if(!a){if(a=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(a),this.deps.log(`[unit-host] \u5DF2\u5165\u518C\u4E3A\u8BBE\u5907 ${a.unitId}`)}let l=this.deps.getLanUrl();this.hubCaps=new Set;let c=this.deps.readIdleMs??ko,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(`${Wr(o)}/units/${a.unitId}/channel`,{headers:{Authorization:`Bearer ${i}`,"X-Unit-Secret":a.secret,...l?{"X-Unit-Lan-Url":l}:{}},signal:r.signal})}finally{u&&clearTimeout(u)}if(f.status===403||f.status===404){let g=Number(f.headers.get("content-length"))>ip,p=setTimeout(()=>r.abort(),g?0:op),y=await f.json().then(h=>h?.code,()=>null);throw clearTimeout(p),y==="UNIT_NOT_FOUND"||y==="UNIT_SECRET_MISMATCH"?(await this.deps.clearPairing(),new Error(`\u901A\u9053\u88AB\u62D2(${f.status} ${y}),\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??ko,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(`${Wr(e)}/units/register`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({name:rp(),platform:process.platform}),signal:r.signal});if(!i.ok)throw new Error(`\u8BBE\u5907\u5165\u518C\u5931\u8D25 HTTP ${i.status}`);let a=await i.json();if(!a.unitId||!a.secret)throw new Error("\u8BBE\u5907\u5165\u518C\u54CD\u5E94\u7F3A\u5B57\u6BB5");return{unitId:a.unitId,secret:a.secret}}finally{o&&clearTimeout(o)}}async consume(e,n){let r=e.getReader(),s=new TextDecoder,o="",i=this.deps.readIdleMs??ko,a=null,l=()=>{i&&(a&&clearTimeout(a),a=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))};l();try{for(;;){let{done:c,value:u}=await r.read();if(c||n.signal.aborted)return;l(),o=this.parseFrames(o+s.decode(u,{stream:!0}),n)}}finally{a&&clearTimeout(a)}}parseFrames(e,n){let r=e,s;for(;(s=r.indexOf(`
217
+ `;var Ge=t=>t.replace(/\\/g,"/").normalize("NFC");function yo(t){let e=Ge(t.path);return e?t.kind==="folder"?`${e}/`:t.kind==="page"?`${e.replace(/\.md$/i,"")}.fd/`:null:null}function nn(t,e,n){let r=Ge(n);if(!r)return!1;if(t.some(s=>Ge(s.path)===r))return!0;for(let s of e??[]){let o=Ge(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=yo(s);return!!o&&r.startsWith(o)})}function wo(t,e,n){let r=Ge(t),s=Ge(e);return r===s?Ge(n):r.startsWith(`${s}/`)?Ge(n)+r.slice(s.length):null}function jn(t,e,n){let r=!1,s=t.map(o=>{let i=wo(o,e,n);return i===null?o:(r=!0,i)});return{changed:r,next:s}}async function mc(t){let e=await gc.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 gc.readFile(up.join(t,s.name,mo),"utf8").catch(()=>null);if(o===null)continue;n.push(s.name);let i=Br(o);i?.length&&(r[s.name]=i)}return{names:n.sort(),devices:r}}var Ae={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 qr=t=>Ce().sha256Hex(t).slice(0,8);function yc(t){return t.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}\)(?=(?:\.[^./]+)?$)/,"")}function Rt(t,e=[]){let n=[],r=[];for(let s of t){let o=Ge(s.path);if(!o)continue;r.push(o);let i=yo(s);i&&n.push(i)}return{entries:t,exclude:e,prefixes:n,paths:r}}function wc(t,e){let n=yc(Ge(e));if(!n)return!1;if(nn(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 Fn(t,e,n){let r=!1,s=t.map(o=>{let i=wo(o.path,e,n);return i===null?o:(r=!0,{...o,path:i})});return{changed:r,next:s}}function bc(t,e,n,r){if(e==="delete"||e==="delete-folder"){let s=Ge(n),o=t.filter(i=>{let a=Ge(i.path);return!(a===s||e==="delete-folder"&&a.startsWith(`${s}/`))});return{changed:o.length!==t.length,next:o}}return r?Fn(t,n,r):{changed:!1,next:t}}function bo(t,e){let n=xt(t);return!n||n!==t.normalize("NFC").trim()?"\u540D\u79F0\u4E0D\u5408\u6CD5":n.includes("/")?"\u540D\u79F0\u4E0D\u80FD\u5305\u542B /":n===zr?`\u300C${zr}\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 dp,promises as Sc}from"node:fs";async function vc(t,e){try{await Sc.copyFile($n(t),$n(e),dp.COPYFILE_EXCL)}catch(n){let r=n?.code;if(r==="EEXIST"||r==="ENOENT")return!1;throw n}return await Sc.unlink($n(t)).catch(()=>{}),!0}var fp=/^\d{4}-\d{2}-\d{2}$/,kc=["vault","content"],Ec=new Set(Ja),pp=40,rn=t=>new Date(t).toISOString().slice(0,10),Un=t=>typeof t=="string"&&fp.test(t),_c=!1,Ze=Object.create(null),sn=!1,So=()=>Date.now(),Ln=new Set,Wr="";function nt(t,e,n=1,r){try{if(!_c||!Ec.has(e)||!(typeof n=="number"&&Number.isFinite(n)&&n>0))return;let s=rn(So());if(r!==void 0){s!==Wr&&(Ln.clear(),Wr=s);let a=`${t}\0${e}\0${r}`;if(Ln.has(a))return;Ln.add(a)}let o=Ze[s]??={},i=o[t]??={};i[e]=(i[e]??0)+Math.round(n),sn=!0}catch{}}function vo(t){_c=t}function Cc(t){if(Ze=Object.create(null),Ln.clear(),Wr="",sn=!1,!(!t||typeof t!="object"||Array.isArray(t))){for(let[e,n]of Object.entries(t))if(!(!Un(e)||!n||typeof n!="object"))for(let r of kc){let s=n[r];if(!s||typeof s!="object")continue;let o={};for(let[i,a]of Object.entries(s))Ec.has(i)&&typeof a=="number"&&Number.isFinite(a)&&a>0&&(o[i]=Math.round(a));Object.keys(o).length&&((Ze[e]??={})[r]=o)}}}function xc(){let t=rn(So()-pp*864e5),e={};for(let n of Object.keys(Ze).sort()){if(n<t){delete Ze[n];continue}e[n]=JSON.parse(JSON.stringify(Ze[n]))}return e}var Ac=()=>sn,Tc=()=>{sn=!1};function Rc(t,e){let n=[];for(let r of Object.keys(Ze).sort())if(!(r<=t||r>e))for(let s of kc){let o=Ze[r][s];o&&Object.keys(o).length&&n.push({day:r,system:s,counts:{...o}})}return n}function ko(t){for(let e of Object.keys(Ze))e<=t&&(delete Ze[e],sn=!0)}function Ic(){Object.keys(Ze).length&&(sn=!0),Ze=Object.create(null),Ln.clear(),Wr=""}function Dc(t){So=t}var Oc=["setAmadeusSyncFactory","readCreds","accountId","homeDir"],Eo=t=>Oc.every(e=>typeof t[e]=="function"),mp=()=>({enabled:!1,state:"disabled",lastSyncAt:null,pending:0,conflicts:0,skipped:[],error:null,pendingDeletions:0,maxFileBytes:null,side:"local"});function _o(t){let e=null,n=()=>{if(!e)throw new Error("Cloud sync is not ready");return e};t.handle(Ae.get,()=>e?e.get():mp()),t.handle(Ae.setEnabled,(r,s)=>n().setEnabled(s)),t.handle(Ae.syncNow,()=>n().syncNow()),t.handle(Ae.confirmDeletions,()=>n().confirmDeletions()),t.handle(Ae.entryGet,()=>n().entryGet()),t.handle(Ae.otherSideDbs,()=>n().otherSideDbs()),t.handle(Ae.entryEnable,(r,s)=>n().entryEnable(s)),t.handle(Ae.entryDisable,(r,s)=>n().entryDisable(s)),t.handle(Ae.entryMark,(r,s,o)=>n().entryMark(s,o)),t.handle(Ae.entryClosure,(r,s,o)=>n().entryClosure(s,o)),t.handle(Ae.collabCall,(r,s,o)=>n().collabCall(s,o)),t.handle(Ae.switchSide,(r,s)=>n().switchSide(r.sender.id,s)),t.setAmadeusSyncFactory(r=>{Wa(r);let s=Pc(r);return e=s.handlers,s.instance}),t.log("[forsion-extend] amadeus cloud sync registered")}function Pc(t){let e=t.notifyAll,n=()=>t.vaultRoot(),r=0,s=!1,o=go(),i=new Map,a=()=>{let v=Date.now();for(let[A,T]of i)v-T.at>7e4&&i.delete(A);e(Ae.presence,[...i.values()])},l={loadCreds:()=>t.readCreds(),onHealth:(v,A,T)=>nt("vault",v,A,T),onStatus:v=>e(Ae.status,{...v,pendingDeletions:ye(),side:m()?"cloud":"local"}),onPresence:(v,A)=>{let T=A;T?.userId&&(i.set(T.userId,{userId:T.userId,username:String(T.username??"user"),page:T.page??null,at:Number(T.at)||Date.now()}),a())},onPresenceRoster:(v,A)=>{if(Array.isArray(A)){for(let T of A){let D=T;D?.userId&&i.set(D.userId,{userId:D.userId,username:String(D.username??"user"),page:D.page??null,at:Number(D.at)||Date.now()})}a()}}},u=()=>{let v=r;return{...l,onStatus:A=>{v===r&&l.onStatus(A)},onPresence:(A,T)=>{v===r&&l.onPresence(A,T)},onPresenceRoster:(A,T)=>{v===r&&l.onPresenceRoster(A,T)}}},d=Nn(u()),g=new Map,p=[],y=0,h=async()=>{if(!s||!Pe())return;let v=r,A=++y,T=o,D;try{D=await T.sharedWithMe()}catch{return}if(v!==r||!s||A!==y)return;let P=dc(D);p=P;let B=new Map(P.map(H=>[H.key,H.scopeKey]));for(let[H,z]of g)if(B.get(H)!==z.plan.scopeKey){if(await z.engine.stop(),v!==r)return;g.delete(H)}for(let H of P){if(g.has(H.key))continue;let z=Nn(u(),{localRoot:Ut.join(Ct(),...H.localRelDir.split("/")),shadowName:`amadeus-sync-${Pn()}-share-${H.key}`,vaultId:H.vaultId,serverDir:H.serverDir,inScope:H.inScope});g.set(H.key,{engine:z,plan:H}),z.start()}},m=()=>n()===Ct(),w=(v,A=v.base)=>{v.base=A;let T=[A,...v.pendingMoves];v.scope.current=Rt(T.flatMap(D=>D.entries),T.flatMap(D=>D.exclude))},_=new Map,M=new Set,R=new Set,O=null,S=()=>O??=new Promise(v=>{let A=()=>gp.hostname().replace(/\.(local|lan|home)$/i,"")||"Desktop";if(process.platform!=="darwin")return v(A());hp("scutil",["--get","ComputerName"],{timeout:1500},(T,D)=>v(!T&&String(D).trim()||A()))}),C=async()=>{let v=(await Ye()).cloudSync?.deviceId;return v?{id:v,name:await S()}:null},E=new Map,I=(v,A,T)=>{let D=r,P=(E.get(v)??Promise.resolve()).catch(()=>{}).then(async()=>{D!==r||T&&!await T()||D!==r||await U(v,A,D)});return E.set(v,P),P.finally(()=>{E.get(v)===P&&E.delete(v)}).catch(()=>{}),P},U=async(v,A,T)=>{let D=o,P=encodeURIComponent(await D.ensureOwnVault()),B=pc(v);for(let H=0;H<3;H++){let z=null;try{z=await D.call("GET",`/vaults/${P}/file?path=${encodeURIComponent(B)}`)}catch(G){if(G?.status!==404)throw G}let J=A(!!z,z?Br(z.content):null);if(J===void 0||T!==r)return;try{if(J===null){z&&await D.call("DELETE",`/vaults/${P}/file?path=${encodeURIComponent(B)}&baseSeq=${z.seq}`);return}await D.call("PUT",`/vaults/${P}/file`,{path:B,content:hc(J),baseSeq:z?.seq??0});return}catch(G){if(G?.status!==409)throw G}}throw Object.assign(new Error("marker write kept conflicting"),{status:409})},$=async v=>!!(await Ye()).entrySync?.some(A=>A.cloudName===v&&A.entries.length>0),V=(v,A)=>I(v,(T,D)=>{let P=D?.find(H=>H.id===A.id);if(P&&P.name===A.name)return;let B=P?.since??new Date().toISOString().slice(0,10);return[...(D??[]).filter(H=>H.id!==A.id),{...A,since:B}]},()=>$(v)),Z=(v,A)=>I(v,(T,D)=>{if(!T||!D?.some(B=>B.id===A))return;let P=D.filter(B=>B.id!==A);return P.length?P:null},async()=>!await $(v)),re=()=>{e(Ae.entryChange)},se=async(v,A)=>{let T=_.get(v);if(!T)return;let D=H=>H&&H.startsWith(`${T.cloudName}/`)?H.slice(T.cloudName.length+1):null,P=D(A.path);if(!P)return;let B=!1;await tn(H=>{if(_.get(v)!==T)return!1;let z=(H.entrySync??[]).find(ue=>ue.vaultRoot===v);if(!z)return!1;let J=A.op,G=D(A.newPath),K=bc(z.entries,J,P,G),te=G?jn(z.exclude??[],P,G):{changed:!1,next:z.exclude??[]};if(!K.changed&&!te.changed)return!1;B=!0,z.entries=K.next,te.changed&&(z.exclude=te.next),w(T,Rt(z.entries,z.exclude??[]))}),B&&_.get(v)===T&&re()},ee=v=>{let A=r;return{...u(),onStatus:T=>{A===r&&e(Ae.status,{...T,pendingDeletions:ye(),side:"local",binding:v})},onRemoteApplied:async T=>{A===r&&await se(v,T)}}},Q=async()=>{let v=Pe();if(!s||!v)return;let A=r,T=o,D=Pn(v);await t.adoptLegacyCloudState(v,vc);let P=await Ye(v),B=P.entrySync??[];if(A!==r||!s||v!==Pe())return;let H=new Map(B.map(z=>[z.vaultRoot,z]));for(let[z,J]of _){let G=H.get(z);if(!(G&&G.cloudName===J.cloudName)&&(await J.engine.stop(),A!==r||(_.delete(z),G&&await oc(`amadeus-sync-${D}-entry-${qr(z)}`),A!==r)))return}for(let z of B){let J=_.get(z.vaultRoot);if(J){w(J,Rt(z.entries,z.exclude??[]));continue}let G={current:Rt(z.entries,z.exclude??[])},K=z.cloudName,te=Nn(ee(z.vaultRoot),{accountId:v,localRoot:z.vaultRoot,shadowName:`amadeus-sync-${D}-entry-${qr(z.vaultRoot)}`,vaultId:"first",serverDir:K,clientIdSuffix:`entry-${qr(z.vaultRoot)}`,requireRootExists:!0,ignoreNames:[".git","node_modules",".trash"],inScope:ue=>ue===K?!0:ue.startsWith(`${K}/`)?wc(G.current,ue.slice(K.length+1)):!1});_.set(z.vaultRoot,{engine:te,scope:G,cloudName:K,base:G.current,pendingMoves:new Set}),te.start()}if(P.cloudSync?.enabled!==!1)for(let z of B){let J=z.entries.length>0,G=J?M:R;G.has(z.cloudName)||((J?R:M).delete(z.cloudName),(async()=>{try{let K=await C();if(!K||A!==r||(await(J?V(z.cloudName,K):Z(z.cloudName,K.id)),A!==r))return;G.add(z.cloudName),(J?R:M).delete(z.cloudName)}catch{}})())}},ge=async(v,A,T,D,P)=>{let B=A.replace(/\\/g,"/").normalize("NFC"),H=T.replace(/\\/g,"/").normalize("NFC"),z=!1,J,G,K,te=P??"file";try{await tn(async ue=>{if(_.get(v)!==D)return!1;let ne=(ue.entrySync??[]).find($e=>$e.vaultRoot===v);if(!ne)return!1;let me=Fn(ne.entries,B,H),ie=jn(ne.exclude??[],B,H),Be=nn(ne.entries,ne.exclude,B);!P&&await on.stat(Ut.join(v,...H.split("/"))).then($e=>$e.isDirectory(),()=>!1)&&(te="folder");let Nt=te==="folder"?"folder":/\.md$/i.test(H)?"page":"asset";Be&&!nn(me.next,ie.next,H)&&(me.next.push({path:H,kind:Nt}),me.changed=!0),z=me.changed||ie.changed;let Yt=ne.entries.filter($e=>Fn([$e],B,H).changed);return Be&&!Yt.some($e=>$e.path===B)&&Yt.push({path:B,kind:Nt}),J=Rt(Yt,(ne.exclude??[]).filter($e=>jn([$e],B,H).changed)),G=D.base,D.pendingMoves.add(J),ne.entries=me.next,ne.exclude=ie.next,K=Rt(ne.entries,ne.exclude),w(D,K),z})}catch(ue){throw J&&D.pendingMoves.delete(J),w(D,D.base===K&&G?G:D.base),ue}try{J&&await D.engine.notifyLocalMove(B,H,()=>{D.pendingMoves.delete(J),w(D)},te)}catch(ue){throw J&&D.pendingMoves.delete(J),await tn(ne=>{let me=ne.entrySync?.find(ie=>ie.vaultRoot===v);if(!me)return!1;me.entries=Fn(me.entries,H,B).next,me.exclude=jn(me.exclude??[],H,B).next,w(D,Rt(me.entries,me.exclude))}),ue}z&&_.get(v)===D&&re()},fe=v=>{let A=v.replace(/\\/g,"/");for(let{engine:T,plan:D}of g.values())if(A.startsWith(`${D.localRelDir}/`))return{engine:T,rel:A.slice(D.localRelDir.length+1)};return{engine:d,rel:A}};t.setMutationHooks((v,A)=>{if(m()){let T=fe(v);T.engine.notifyLocal(T.rel,A);return}_.get(n()??"")?.engine.notifyLocal(v,A)},(v,A,T)=>{if(m()){let B=fe(v),H=fe(A);if(B.engine===H.engine)return B.engine.notifyLocalMove(B.rel,H.rel,void 0,T);B.engine.notifyLocal(B.rel,"remove"),H.engine.notifyLocal(H.rel,"write");return}let D=n()??"",P=_.get(D);if(P)return ge(D,v,A,P,T)},(v,A)=>{if(m()){let T=fe(v),D=fe(A),P=[T.engine.holdLocalMove(T.rel,D.rel)];return T.engine!==D.engine&&P.push(D.engine.holdLocalMove(T.rel,D.rel)),()=>{for(let B of P)B()}}return _.get(n()??"")?.engine.holdLocalMove(v,A)});let ye=()=>{let v=d.getStatus().pendingDeletions;for(let{engine:A}of g.values())v+=A.getStatus().pendingDeletions;for(let{engine:A}of _.values())v+=A.getStatus().pendingDeletions;return v},he=v=>({...v,pendingDeletions:ye(),side:m()?"cloud":"local"}),ze=()=>{if(!s)return Promise.resolve(d.getStatus());h();for(let{engine:v}of g.values())v.syncNow();for(let{engine:v}of _.values())v.syncNow();return d.syncNow()},Fe=async()=>{++r,s=!1,o.stop();let v=[d.stop(),...[...g.values()].map(({engine:T})=>T.stop()),...[..._.values()].map(({engine:T})=>T.stop())];g.clear(),_.clear(),p=[],M.clear(),R.clear(),i.clear(),a(),await Promise.all(v),await t.awaitPendingVaultWrites();let A=n();if(A&&$r(A)){let T=await Ye(),D=T.localVault&&!$r(T.localVault)?T.localVault:Ut.join(t.workspaceDir(),"Amadeus");await on.mkdir(D,{recursive:!0}),await gt({lastVault:D,localVault:D,lastPage:void 0}),await t.activateRoot(D,!1)}re()};return{handlers:{get:()=>he(d.getStatus()),setEnabled:async v=>{if(!s)throw new Error("Cloud account is changing");let A=r;return await d.setEnabled(v),A!==r?d.getStatus():(await Promise.all([...g.values(),..._.values()].map(({engine:T})=>T.restart())),he(d.getStatus()))},syncNow:()=>ze(),confirmDeletions:()=>{for(let{engine:v}of g.values())v.confirmMassDeletions();for(let{engine:v}of _.values())v.confirmMassDeletions();return he(d.confirmMassDeletions())},entryGet:async()=>{let v=await Ye(),A=Ct(),T=await mc(A);return{vaults:v.entrySync??[],activeRoot:n(),cloudRoot:A,mirrorVaults:T.names,mirrorVaultDevices:T.devices,deviceId:v.cloudSync?.deviceId??null}},otherSideDbs:async()=>{let v=n();if(!v)return null;let A=Ct(),T=await Ye(),D=v===A?T.localVault&&T.localVault!==A?T.localVault:null:A;if(!D)return null;let P=[],B=500,H=async(z,J)=>{if(P.length>=B)return;let G;try{G=await on.readdir(z,{withFileTypes:!0})}catch{return}for(let K of G){if(P.length>=B)break;if(K.name.startsWith(".")||K.isSymbolicLink())continue;let te=J?`${J}/${K.name}`:K.name;if(K.isDirectory())await H(Ut.join(z,K.name),te);else if(K.isFile()&&/\.db$/i.test(K.name))try{P.push({rel:te,source:await on.readFile(Ut.join(z,K.name),"utf8")})}catch{}}};return await H(D,""),{root:D,vaultName:D===A?"\u4E91\u7AEF":Ut.basename(D),dbs:P}},entryEnable:async v=>{let A=r,T=o;if(!s||!Pe())return{error:"Sign in to enable cloud sync"};let D=n();if(!D||m())return{error:"\u4EC5\u672C\u5730 vault \u53EF\u5F00\u542F\u4E91\u540C\u6B65"};let P=await Ye(),B=P.entrySync??[],H=B.find(z=>z.vaultRoot===D);if(!H){let z=(v.cloudName??Ut.basename(D)).normalize("NFC").trim(),J=bo(z,B.map(G=>G.cloudName));if(J)return{error:J};if(!v.merge)try{let G=await T.ensureOwnVault(),K=await T.call("GET",`/vaults/${encodeURIComponent(G)}/tree`);if((K.folders??[]).some(ue=>ue===z||ue.startsWith(`${z}/`))||(K.entries??[]).some(ue=>ue.path===z||ue.path.startsWith(`${z}/`)))return{conflict:z}}catch(G){return{error:G?.message||"\u65E0\u6CD5\u8FDE\u63A5\u4E91\u7AEF(\u9996\u6B21\u5F00\u542F\u9700\u8981\u5728\u7EBF)"}}H={vaultRoot:D,cloudName:z,entries:[]},B.push(H)}return A!==r||!s?{error:"Cloud account changed; retry from the current account"}:(await tn(z=>{if(A!==r||!s)return!1;let J=z.entrySync??[],G=J.find(ie=>ie.vaultRoot===D);if(!G){let ie=bo(H.cloudName,J.map(Be=>Be.cloudName));if(ie)throw new Error(ie);G={vaultRoot:D,cloudName:H.cloudName,entries:[]},J.push(G)}let K=ie=>String(ie??"").replace(/\\/g,"/").normalize("NFC"),te=new Set;for(let ie of v.entries??[]){let Be=K(ie.path);Be&&(te.add(Be),!G.entries.some(Nt=>Nt.path===Be)&&G.entries.push({path:Be,kind:ie.kind==="folder"||ie.kind==="asset"?ie.kind:"page"}))}let ue=(v.exclude??[]).map(K).filter(Boolean),ne=new Set([...te,...(v.include??[]).map(K).filter(Boolean)]);G.exclude=[...new Set([...(G.exclude??[]).filter(ie=>!ne.has(ie)),...ue])];let me=new Set(ue);G.entries=G.entries.filter(ie=>!me.has(ie.path)),z.entrySync=J,H=G},P.cloudAccountId),A!==r?{error:"Cloud account changed; retry from the current account"}:(await Q(),_.get(D)?.engine.syncNow(),re(),{ok:!0,cloudName:H.cloudName}))},entryDisable:async v=>{let A=n(),T=!1,D=r;return await tn(P=>{if(D!==r||!s)return!1;let B=(P.entrySync??[]).find(J=>J.vaultRoot===A);if(!A||!B)return!1;let H=String(v??"").replace(/\\/g,"/").normalize("NFC"),z=B.entries.length;if(B.entries=B.entries.filter(J=>J.path!==H),nn(B.entries,B.exclude,H))B.exclude=[...new Set([...B.exclude??[],H])];else if(B.entries.length===z)return!1;T=!0}),!T||D!==r?{ok:!1}:(await Q(),re(),{ok:!0})},entryMark:async(v,A)=>{let T=String(v??"").normalize("NFC");if(!T||T.includes("/")||T.startsWith("."))return{error:"invalid name"};if(!s||!Pe())return{error:"Sign in first"};try{await I(T,D=>A?D?void 0:[]:D?null:void 0)}catch(D){return{error:D?.message||String(D)}}return d.syncNow(),{ok:!0}},entryClosure:(v,A)=>t.relatedClosure(String(v??""),A==="folder"?"folder":"page"),collabCall:async(v,A)=>{let T=o,D=async()=>T.ensureOwnVault(),P=H=>String((A??[])[H]??""),B=H=>(A??[])[H]??{};switch(v){case"listVaults":return(await T.call("GET","/vaults")).vaults;case"activeVaultId":return D();case"pageShare":return T.call("GET",`/vaults/${encodeURIComponent(await D())}/page-shares?path=${encodeURIComponent(P(0))}`);case"relatedItems":return T.call("GET",`/vaults/${encodeURIComponent(await D())}/page-shares/${encodeURIComponent(P(0))}/related`);case"setShareItem":return T.call("POST",`/vaults/${encodeURIComponent(await D())}/page-shares/${encodeURIComponent(P(0))}/items`,{path:P(1),included:(A??[])[2]===!0});case"createPageShare":return T.call("POST",`/vaults/${encodeURIComponent(await D())}/page-shares`,{path:P(0),...B(1)});case"updatePageShare":return T.call("PATCH",`/vaults/${encodeURIComponent(P(2)||await D())}/page-shares/${encodeURIComponent(P(0))}`,B(1));case"revokePageShare":return T.call("DELETE",`/vaults/${encodeURIComponent(await D())}/page-shares/${encodeURIComponent(P(0))}`);case"setParticipantRole":return T.call("PATCH",`/vaults/${encodeURIComponent(P(3)||await D())}/page-shares/${encodeURIComponent(P(0))}/members/${encodeURIComponent(P(1))}`,{role:P(2)});case"removeParticipant":return T.call("DELETE",`/vaults/${encodeURIComponent(P(2)||await D())}/page-shares/${encodeURIComponent(P(0))}/members/${encodeURIComponent(P(1))}`);case"sharedWithMe":{let H=await T.sharedWithMe();return h(),H}case"leaveShare":{let H=T.myUserId();if(!H)throw new Error("\u672A\u767B\u5F55");let z=await T.call("DELETE",`/vaults/${encodeURIComponent(P(1)||await D())}/page-shares/${encodeURIComponent(P(0))}/members/${encodeURIComponent(H)}`);return h(),z}case"publishes":return T.call("GET",`/vaults/${encodeURIComponent(await D())}/shares`);case"listAllShares":{let H=(await T.call("GET","/vaults")).vaults||[],z=T.myUserId(),J=[],G=[];for(let K of H){try{let te=await T.call("GET",`/vaults/${encodeURIComponent(K.id)}/shares`);for(let ue of te.shares||[])J.push({...ue,vaultId:K.id,vaultName:K.name||""})}catch(te){t.log(`[connect] listAllShares publishes vault ${K.id} failed: ${te?.message}`)}try{let te=await T.call("GET",`/vaults/${encodeURIComponent(K.id)}/page-shares?expired=1`),ue=te?.shares||te?.pageShares||(Array.isArray(te)?te:[]);for(let ne of ue){let me=ne.created_by??ne.createdBy;(!z||!me||me===z)&&G.push({...ne,vaultId:K.id,vaultName:K.name||""})}}catch(te){t.log(`[connect] listAllShares pageShares vault ${K.id} failed: ${te?.message}`)}}return{publishes:J,pageShares:G,linkBase:await T.linkBase()}}case"createPublish":{let H=await T.call("POST",`/vaults/${encodeURIComponent(await D())}/shares`,{mode:P(0),path:P(1)});return{...H,url:`${await T.linkBase()}/share/${H.token}`}}case"revokePublish":return T.call("DELETE",`/vaults/${encodeURIComponent(await D())}/shares/${encodeURIComponent(P(0))}`);case"revokePublishIn":return T.call("DELETE",`/vaults/${encodeURIComponent(P(0))}/shares/${encodeURIComponent(P(1))}`);case"revokePageShareIn":return T.call("DELETE",`/vaults/${encodeURIComponent(P(0))}/page-shares/${encodeURIComponent(P(1))}`);case"myUserId":return T.myUserId();case"linkBase":return T.linkBase();case"heartbeat":return T.heartbeat((A??[])[0]??null,p);default:throw new Error(`unknown collab fn: ${v}`)}},switchSide:async(v,A)=>{let T=await Ye();if(A==="cloud"){if(!s||!Pe())throw new Error("Sign in to open cloud notes");let B=Ct();await on.mkdir(B,{recursive:!0}),T.lastVault&&!$r(T.lastVault)&&await gt({localVault:T.lastVault}),await gt({lastVault:B});let H=await t.activateRoot(B,!1);return t.bindRenderer(v,B),{...H,side:"cloud"}}let D=T.localVault&&await on.stat(T.localVault).then(B=>B.isDirectory()).catch(()=>!1)?T.localVault:null;if(!D){let B=await t.ensureDefaultVault();return t.bindRenderer(v,B.root),{...B,side:"local"}}await gt({lastVault:D});let P=await t.activateRoot(D,!1);return t.bindRenderer(v,D),{...P,side:"local"}}},instance:{start:()=>{s=!0,d.start(),h(),Q()},stopAllSync:Fe,restartAllSync:async()=>{await Fe(),o=go(),d=Nn(u()),s=!0,await Promise.all([d.restart(),h(),Q()]),re(),e(Ae.status,he(d.getStatus()))},resolveSharedAsset:v=>fc(p,v)}}}import{hostname as yp}from"node:os";var wp=256*1024;function Mc(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>wp}var Co=45e3,bp=3e3,Sp=16*1024,vp=6e4,Vr=t=>`${t.replace(/\/+$/,"")}/api`,Hn=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??vp}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 a=this.deps.getPairing();if(!a){if(a=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(a),this.deps.log(`[unit-host] \u5DF2\u5165\u518C\u4E3A\u8BBE\u5907 ${a.unitId}`)}let c=this.deps.getLanUrl();this.hubCaps=new Set;let l=this.deps.readIdleMs??Co,u=l?setTimeout(()=>{this.deps.log(`[unit-host] \u901A\u9053 ${Math.round(l/1e3)}s \u672A\u6536\u5230\u54CD\u5E94\u5934,\u5224\u5B9A\u5DF2\u65AD,\u91CD\u8FDE`),r.abort()},l):null,d;try{d=await this.hubFetch(`${Vr(o)}/units/${a.unitId}/channel`,{headers:{Authorization:`Bearer ${i}`,"X-Unit-Secret":a.secret,...c?{"X-Unit-Lan-Url":c}:{}},signal:r.signal})}finally{u&&clearTimeout(u)}if(d.status===403||d.status===404){let g=Number(d.headers.get("content-length"))>Sp,p=setTimeout(()=>r.abort(),g?0:bp),y=await d.json().then(h=>h?.code,()=>null);throw clearTimeout(p),y==="UNIT_NOT_FOUND"||y==="UNIT_SECRET_MISMATCH"?(await this.deps.clearPairing(),new Error(`\u901A\u9053\u88AB\u62D2(${d.status} ${y}),\u5DF2\u6E05\u9664\u914D\u5BF9\u5F85\u91CD\u65B0\u5165\u518C`)):new Error(`channel HTTP ${d.status} (not a hub verdict; keeping pairing and retrying)`)}if(!d.ok||!d.body)throw new Error(`channel HTTP ${d.status}`);this.connected=!0,this.lastError=null,n=1e3,this.deps.log("[unit-host] \u901A\u9053\u5DF2\u8FDE\u63A5"),await this.consume(d.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??Co,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(`${Vr(e)}/units/register`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({name:yp(),platform:process.platform}),signal:r.signal});if(!i.ok)throw new Error(`\u8BBE\u5907\u5165\u518C\u5931\u8D25 HTTP ${i.status}`);let a=await i.json();if(!a.unitId||!a.secret)throw new Error("\u8BBE\u5907\u5165\u518C\u54CD\u5E94\u7F3A\u5B57\u6BB5");return{unitId:a.unitId,secret:a.secret}}finally{o&&clearTimeout(o)}}async consume(e,n){let r=e.getReader(),s=new TextDecoder,o="",i=this.deps.readIdleMs??Co,a=null,c=()=>{i&&(a&&clearTimeout(a),a=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))};c();try{for(;;){let{done:l,value:u}=await r.read();if(l||n.signal.aborted)return;c(),o=this.parseFrames(o+s.decode(u,{stream:!0}),n)}}finally{a&&clearTimeout(a)}}parseFrames(e,n){let r=e,s;for(;(s=r.indexOf(`
213
218
 
214
219
  `))>=0;){let o=r.slice(0,s);if(r=r.slice(s+2),o.includes("event: ready")){let a=o.split(`
215
- `).find(l=>l.startsWith("data: "))?.slice(6);try{let l=JSON.parse(a||"{}").caps;this.hubCaps=new Set(Array.isArray(l)?l.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(a=>a.startsWith("data: "))?.slice(6);if(i)try{let a=JSON.parse(i);this.dispatch(a,n).catch(l=>this.deps.log(`[unit-host] \u6D3E\u53D1\u5904\u7406\u5931\u8D25: ${l?.message||l}`))}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")||"",a={};for(let u of["content-security-policy","x-content-type-options"]){let f=o.headers.get(u);f&&(a[u]=f)}let l=i||"application/octet-stream";o.body&&Al(i,o.headers.get("content-length"),{hasSecHeaders:Object.keys(a).length>0,gatewayStreamsSecHeaders:this.hubCaps.has("stream-sec-headers")})?await this.streamBack(e.id,o,n,l,a):await this.respond(e.id,o.status,l,Buffer.from(await o.arrayBuffer()),a,n.signal)}async respond(e,n,r,s,o,i){if(i?.aborted)return;let{cloudUrl:a,token:l}=this.deps.getCreds(),c=this.deps.getPairing();if(!c)return;let u=this.requestTimeoutMs*2,f=[...u?[AbortSignal.timeout(u)]:[],...i?[i]:[]],g=f.length>1?AbortSignal.any(f):f[0];await this.hubFetch(`${Wr(a)}/units/${c.unitId}/resp/${e}`,{method:"POST",headers:{Authorization:`Bearer ${l}`,"X-Unit-Secret":c.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:a}=this.deps.getCreds(),l=this.deps.getPairing();if(!l)return;let c=o?.["content-security-policy"],u=o?.["x-content-type-options"],f=`${Wr(i)}/units/${l.unitId}/stream/${e}?status=${n.status}&ct=${encodeURIComponent(s)}`+(c?`&csp=${encodeURIComponent(c)}`:"")+(u?`&xcto=${encodeURIComponent(u)}`:""),g=n.body;if(!g)return;let p=g.getReader(),y=0,h=this.requestTimeoutMs,m=h?setTimeout(()=>{y>=2||(this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20 ${Math.round(h/1e3)}s \u672A\u628A\u9996\u5757\u5199\u7ED9\u7F51\u5173,\u4E2D\u6B62\u672C\u6B21\u6D3E\u53D1`),r.abort())},h):null,w=new ReadableStream({async pull(_){++y===2&&m&&clearTimeout(m);let{done:$,value:R}=await p.read();$?_.close():_.enqueue(R)},cancel(_){return p.cancel(_)}},{highWaterMark:0});try{await this.hubFetch(f,{method:"POST",headers:{Authorization:`Bearer ${a}`,"X-Unit-Secret":l.secret,"Content-Type":"application/octet-stream"},body:w,signal:r.signal,duplex:"half"})}catch(_){this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20\u4E2D\u65AD: ${_?.message||_}`);try{await p.cancel()}catch{}}finally{m&&clearTimeout(m)}}};var zn=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(a){this.d.log(`[unit-caps] \u8BFB\u5F15\u64CE\u6001\u5931\u8D25:${a?.message||a}`);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 a=`${r.cloudUrl.replace(/\/+$/,"")}/api/units/${encodeURIComponent(n.unitId)}/caps`,l=await(this.d.hubFetch??fetch)(a,{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 l.text()}catch{}if(s!==this.gen)return;l.ok?(this.lastSent=e,this.d.log(`[unit-caps] \u5DF2\u4E0A\u62A5\u5F15\u64CE\u6001 ${e}`)):l.status===404||l.status===405?(this.disabled=!0,this.d.log(`[unit-caps] \u7F51\u5173\u4E0D\u6536 caps(HTTP ${l.status},\u8001\u7248\u672C),\u672C\u8FDE\u63A5\u5185\u4E0D\u518D\u4E0A\u62A5`)):l.status===400||l.status===401||l.status===403?this.warned.has(l.status)||(this.warned.add(l.status),this.d.log(`[unit-caps] \u4E0A\u62A5\u88AB\u62D2 HTTP ${l.status}`)):this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25 HTTP ${l.status},\u7B49\u4E0B\u6B21\u53D8\u5316 / \u91CD\u8FDE\u518D\u62A5`)}catch(a){s===this.gen&&this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25:${o.signal.aborted?"\u8D85\u65F6":a?.message||a}`)}finally{clearTimeout(i),this.inflight=!1,this.again&&this.up&&!this.disabled&&(this.again=!1,this.flush())}}};var Tl=["setUnitHubFactory"],Eo=t=>Tl.every(e=>typeof t[e]=="function");function Rl(t){let e=new zn({getCreds:()=>t.getCreds(),getPairing:()=>t.getPairing(),current:()=>t.engineCaps(),log:r=>t.log(r)}),n=new Hn({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 _o(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 a=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:a.status,json:await a.json().catch(()=>null)}}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}};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(Rl),t.log("[forsion-extend] unit hub registered")}import{createHash as Ap}from"node:crypto";import{constants as Ql,mkdirSync as Tp,readFileSync as Rp,renameSync as Ip,writeFileSync as Dp}from"node:fs";import{lstat as wt,open as pc,readFile as Op,readdir as hc,statfs as Pp}from"node:fs/promises";import{cpus as $p,freemem as Mp,homedir as ec,hostname as gc,release as Np,totalmem as jp}from"node:os";import{basename as mc,join as ce}from"node:path";var lp=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i,Bn=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(lp);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 cp(t,e){let n=t.slice(0,e).split(/\r\n|\n|\r/g);return[n.length,n.pop().length+1]}function up(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 a=r[i-1];a&&(s+=i.toString().padEnd(o," "),s+=": ",s+=a,s+=`
220
+ `).find(c=>c.startsWith("data: "))?.slice(6);try{let c=JSON.parse(a||"{}").caps;this.hubCaps=new Set(Array.isArray(c)?c.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(`
221
+ `).find(a=>a.startsWith("data: "))?.slice(6);if(i)try{let a=JSON.parse(i);this.dispatch(a,n).catch(c=>this.deps.log(`[unit-host] \u6D3E\u53D1\u5904\u7406\u5931\u8D25: ${c?.message||c}`))}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")||"",a={};for(let u of["content-security-policy","x-content-type-options"]){let d=o.headers.get(u);d&&(a[u]=d)}let c=i||"application/octet-stream";o.body&&Mc(i,o.headers.get("content-length"),{hasSecHeaders:Object.keys(a).length>0,gatewayStreamsSecHeaders:this.hubCaps.has("stream-sec-headers")})?await this.streamBack(e.id,o,n,c,a):await this.respond(e.id,o.status,c,Buffer.from(await o.arrayBuffer()),a,n.signal)}async respond(e,n,r,s,o,i){if(i?.aborted)return;let{cloudUrl:a,token:c}=this.deps.getCreds(),l=this.deps.getPairing();if(!l)return;let u=this.requestTimeoutMs*2,d=[...u?[AbortSignal.timeout(u)]:[],...i?[i]:[]],g=d.length>1?AbortSignal.any(d):d[0];await this.hubFetch(`${Vr(a)}/units/${l.unitId}/resp/${e}`,{method:"POST",headers:{Authorization:`Bearer ${c}`,"X-Unit-Secret":l.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:a}=this.deps.getCreds(),c=this.deps.getPairing();if(!c)return;let l=o?.["content-security-policy"],u=o?.["x-content-type-options"],d=`${Vr(i)}/units/${c.unitId}/stream/${e}?status=${n.status}&ct=${encodeURIComponent(s)}`+(l?`&csp=${encodeURIComponent(l)}`:"")+(u?`&xcto=${encodeURIComponent(u)}`:""),g=n.body;if(!g)return;let p=g.getReader(),y=0,h=this.requestTimeoutMs,m=h?setTimeout(()=>{y>=2||(this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20 ${Math.round(h/1e3)}s \u672A\u628A\u9996\u5757\u5199\u7ED9\u7F51\u5173,\u4E2D\u6B62\u672C\u6B21\u6D3E\u53D1`),r.abort())},h):null,w=new ReadableStream({async pull(_){++y===2&&m&&clearTimeout(m);let{done:M,value:R}=await p.read();M?_.close():_.enqueue(R)},cancel(_){return p.cancel(_)}},{highWaterMark:0});try{await this.hubFetch(d,{method:"POST",headers:{Authorization:`Bearer ${a}`,"X-Unit-Secret":c.secret,"Content-Type":"application/octet-stream"},body:w,signal:r.signal,duplex:"half"})}catch(_){this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20\u4E2D\u65AD: ${_?.message||_}`);try{await p.cancel()}catch{}}finally{m&&clearTimeout(m)}}};var zn=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(a){this.d.log(`[unit-caps] \u8BFB\u5F15\u64CE\u6001\u5931\u8D25:${a?.message||a}`);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 a=`${r.cloudUrl.replace(/\/+$/,"")}/api/units/${encodeURIComponent(n.unitId)}/caps`,c=await(this.d.hubFetch??fetch)(a,{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 c.text()}catch{}if(s!==this.gen)return;c.ok?(this.lastSent=e,this.d.log(`[unit-caps] \u5DF2\u4E0A\u62A5\u5F15\u64CE\u6001 ${e}`)):c.status===404||c.status===405?(this.disabled=!0,this.d.log(`[unit-caps] \u7F51\u5173\u4E0D\u6536 caps(HTTP ${c.status},\u8001\u7248\u672C),\u672C\u8FDE\u63A5\u5185\u4E0D\u518D\u4E0A\u62A5`)):c.status===400||c.status===401||c.status===403?this.warned.has(c.status)||(this.warned.add(c.status),this.d.log(`[unit-caps] \u4E0A\u62A5\u88AB\u62D2 HTTP ${c.status}`)):this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25 HTTP ${c.status},\u7B49\u4E0B\u6B21\u53D8\u5316 / \u91CD\u8FDE\u518D\u62A5`)}catch(a){s===this.gen&&this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25:${o.signal.aborted?"\u8D85\u65F6":a?.message||a}`)}finally{clearTimeout(i),this.inflight=!1,this.again&&this.up&&!this.disabled&&(this.again=!1,this.flush())}}};var $c=["setUnitHubFactory"],xo=t=>$c.every(e=>typeof t[e]=="function");function Nc(t){let e=new zn({getCreds:()=>t.getCreds(),getPairing:()=>t.getPairing(),current:()=>t.engineCaps(),log:r=>t.log(r)}),n=new Hn({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 Ao(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 a=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:a.status,json:await a.json().catch(()=>null)}}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}};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(Nc),t.log("[forsion-extend] unit hub registered")}import{createHash as Hp}from"node:crypto";import{constants as il,mkdirSync as zp,readFileSync as Bp,renameSync as qp,writeFileSync as Wp}from"node:fs";import{lstat as wt,open as Sl,readFile as Vp,readdir as vl,statfs as Yp}from"node:fs/promises";import{cpus as Gp,freemem as Jp,homedir as al,hostname as kl,release as Kp,totalmem as Xp}from"node:os";import{basename as El,join as le}from"node:path";var kp=/^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i,Bn=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(kp);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 Ep(t,e){let n=t.slice(0,e).split(/\r\n|\n|\r/g);return[n.length,n.pop().length+1]}function _p(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 a=r[i-1];a&&(s+=i.toString().padEnd(o," "),s+=": ",s+=a,s+=`
217
222
  `,i===e&&(s+=" ".repeat(o+n+2),s+=`^
218
- `))}return s}var ae=class extends Error{line;column;codeblock;constructor(e,n){let[r,s]=cp(n.toml,n.ptr),o=up(n.toml,r,s);super(`Invalid TOML document: ${e}
223
+ `))}return s}var ae=class extends Error{line;column;codeblock;constructor(e,n){let[r,s]=Ep(n.toml,n.ptr),o=_p(n.toml,r,s);super(`Invalid TOML document: ${e}
219
224
 
220
- ${o}`,n),this.line=r,this.column=s,this.codeblock=o}};var dp=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,fp=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,pp=/^[+-]?0[0-9_]/;function Vr(t,e){let n=t[e++],r=n,s=n==="'",o=n===t[e]&&n===t[e+1];o&&(t[e+=2]===`
225
+ ${o}`,n),this.line=r,this.column=s,this.codeblock=o}};var Cp=/^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/,xp=/^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/,Ap=/^[+-]?0[0-9_]/;function Yr(t,e){let n=t[e++],r=n,s=n==="'",o=n===t[e]&&n===t[e+1];o&&(t[e+=2]===`
221
226
  `?e++:t[e]==="\r"&&t[e+1]===`
222
- `&&(e+=2));let i="",a=e,l=0;for(let c=e;c<t.length;c++)if(n=t[c],o&&(n===`
223
- `||n==="\r"&&t[c+1]===`
224
- `))l=l&&3;else{if(n<" "&&n!==" "||n==="\x7F")throw new ae("control characters are not allowed in strings",{toml:t,ptr:c});if((!l||l===3)&&n===r&&(!o||t[c+1]===r&&t[c+2]===r))return o&&(t[c+3]===r&&c++,t[c+3]===r&&c++),[l?i:i+t.slice(a,c),c+(o?3:1)];if(!l)!s&&n==="\\"&&(i+=t.slice(a,a=c),l=1);else if(l===1)if(n==="x"||n==="u"||n==="U"){let u=0,f=n==="x"?2:n==="u"?4:8;for(let g=0;g<f;g++,c++){let p=t.charCodeAt(c+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 ae("invalid non-hex character in unicode escape",{toml:t,ptr:c+1});u=u<<4|y}if(u<0||u>1114111||u>=55296&&u<=57343)throw new ae("invalid unicode escape",{toml:t,ptr:c});i+=String.fromCodePoint(u),a=c+1,l=0}else if(n===" "||n===" ")l=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 ae("unrecognized escape sequence",{toml:t,ptr:c});a=c+1,l=0}else if(n!==" "&&n!==" "){if(l===2)throw new ae("invalid escape: only line-ending whitespace may be escaped",{toml:t,ptr:a});l=!s&&n==="\\"?1:0,a=c}}throw new ae("unfinished string",{toml:t,ptr:e})}function Il(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=dp.test(t);if(s||fp.test(t)){if(pp.test(t))throw new ae("leading zeroes are not allowed",{toml:e,ptr:n});t=t.replace(/_/g,"");let i=+t;if(isNaN(i))throw new ae("invalid number",{toml:e,ptr:n});if(s){if((s=!Number.isSafeInteger(i))&&!r)throw new ae("integer value cannot be represented losslessly",{toml:e,ptr:n});(s||r===!0)&&(i=BigInt(t))}return i}let o=new Bn(t);if(!o.isValid())throw new ae("invalid value",{toml:e,ptr:n});return o}function Yr(t,e=0,n=t.length){let r=t.indexOf(`
227
+ `&&(e+=2));let i="",a=e,c=0;for(let l=e;l<t.length;l++)if(n=t[l],o&&(n===`
228
+ `||n==="\r"&&t[l+1]===`
229
+ `))c=c&&3;else{if(n<" "&&n!==" "||n==="\x7F")throw new ae("control characters are not allowed in strings",{toml:t,ptr:l});if((!c||c===3)&&n===r&&(!o||t[l+1]===r&&t[l+2]===r))return o&&(t[l+3]===r&&l++,t[l+3]===r&&l++),[c?i:i+t.slice(a,l),l+(o?3:1)];if(!c)!s&&n==="\\"&&(i+=t.slice(a,a=l),c=1);else if(c===1)if(n==="x"||n==="u"||n==="U"){let u=0,d=n==="x"?2:n==="u"?4:8;for(let g=0;g<d;g++,l++){let p=t.charCodeAt(l+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 ae("invalid non-hex character in unicode escape",{toml:t,ptr:l+1});u=u<<4|y}if(u<0||u>1114111||u>=55296&&u<=57343)throw new ae("invalid unicode escape",{toml:t,ptr:l});i+=String.fromCodePoint(u),a=l+1,c=0}else if(n===" "||n===" ")c=2;else{if(n==="b")i+="\b";else if(n==="t")i+=" ";else if(n==="n")i+=`
230
+ `;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 ae("unrecognized escape sequence",{toml:t,ptr:l});a=l+1,c=0}else if(n!==" "&&n!==" "){if(c===2)throw new ae("invalid escape: only line-ending whitespace may be escaped",{toml:t,ptr:a});c=!s&&n==="\\"?1:0,a=l}}throw new ae("unfinished string",{toml:t,ptr:e})}function jc(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=Cp.test(t);if(s||xp.test(t)){if(Ap.test(t))throw new ae("leading zeroes are not allowed",{toml:e,ptr:n});t=t.replace(/_/g,"");let i=+t;if(isNaN(i))throw new ae("invalid number",{toml:e,ptr:n});if(s){if((s=!Number.isSafeInteger(i))&&!r)throw new ae("integer value cannot be represented losslessly",{toml:e,ptr:n});(s||r===!0)&&(i=BigInt(t))}return i}let o=new Bn(t);if(!o.isValid())throw new ae("invalid value",{toml:e,ptr:n});return o}function Gr(t,e=0,n=t.length){let r=t.indexOf(`
226
231
  `,e);return t[r-1]==="\r"&&r--,r<=n?r:-1}function an(t,e){for(let n=e;n<t.length;n++){let r=t[n];if(r===`
227
232
  `)return n;if(r==="\r"&&t[n+1]===`
228
233
  `)return n+1;if(r<" "&&r!==" "||r==="\x7F")throw new ae("control characters are not allowed in comments",{toml:t,ptr:e})}return t.length}function it(t,e,n,r){let s;for(;;){for(;(s=t[e])===" "||s===" "||!n&&(s===`
229
234
  `||s==="\r"&&t[e+1]===`
230
- `);)e++;if(r||s!=="#")break;e=an(t,e)}return e}function Dl(t,e,n,r,s=!1){if(!r)return e=Yr(t,e),e<0?t.length:e;for(let o=e;o<t.length;o++){let i=t[o];if(i==="#")o=Yr(t,o);else{if(i===n)return o+1;if(i===r||s&&(i===`
235
+ `);)e++;if(r||s!=="#")break;e=an(t,e)}return e}function Fc(t,e,n,r,s=!1){if(!r)return e=Gr(t,e),e<0?t.length:e;for(let o=e;o<t.length;o++){let i=t[o];if(i==="#")o=Gr(t,o);else{if(i===n)return o+1;if(i===r||s&&(i===`
231
236
  `||i==="\r"&&t[o+1]===`
232
- `))return o}}throw new ae("cannot find end of structure",{toml:t,ptr:e})}function hp(t,e,n){let r=t.slice(e,n),s=r.indexOf("#");return s>-1&&(an(t,s),r=r.slice(0,s)),[r.trimEnd(),s]}function qn(t,e,n,r,s){if(r===0)throw new ae("document contains excessively nested structures. aborting.",{toml:t,ptr:e});let o=t[e];if(o==="["||o==="{"){let[l,c]=o==="["?Pl(t,e,r,s):Ol(t,e,r,s);if(n){if(c=it(t,c),t[c]===",")c++;else if(t[c]!==n)throw new ae("expected comma or end of structure",{toml:t,ptr:c})}return[l,c]}if(o==='"'||o==="'"){let[l,c]=Vr(t,e);if(n){if(c=it(t,c),t[c]&&t[c]!==","&&t[c]!==n&&t[c]!==`
233
- `&&t[c]!=="\r")throw new ae("unexpected character encountered",{toml:t,ptr:c});t[c]===","&&c++}return[l,c]}let i=Dl(t,e,",",n),a=hp(t,e,i-(t[i-1]===","?1:0));if(!a[0])throw new ae("incomplete key-value declaration: no value specified",{toml:t,ptr:e});return n&&a[1]>-1&&(i=it(t,e+a[1]),t[i]===","&&i++),[Il(a[0],t,e,s),i]}var gp=/^[a-zA-Z0-9-_]+[ \t]*$/;function Gr(t,e,n="="){let r=e-1,s=[],o=t.indexOf(n,e);if(o<0)throw new ae("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 ae("multiline strings are not allowed in keys",{toml:t,ptr:e});let[a,l]=Vr(t,e);r=t.indexOf(".",l);let c=t.slice(l,r<0||r>o?o:r),u=Yr(c);if(u>-1)throw new ae("newlines are not allowed in keys",{toml:t,ptr:e+r+u});if(c.trimStart())throw new ae("found extra tokens after the string part",{toml:t,ptr:l});if(o<l&&(o=t.indexOf(n,l),o<0))throw new ae("incomplete key-value: cannot find end of key",{toml:t,ptr:e});s.push(a)}else{r=t.indexOf(".",e);let a=t.slice(e,r<0||r>o?o:r);if(!gp.test(a))throw new ae("only letter, numbers, dashes and underscores are allowed in keys",{toml:t,ptr:e});s.push(a.trimEnd())}}while(r+1&&r<o);return[s,it(t,o+1,!0,!0)]}function Ol(t,e,n,r){let s={},o=new Set,i;for(e++;(i=t[e++])!=="}"&&i;){if(i===",")throw new ae("expected value, found comma",{toml:t,ptr:e-1});if(i==="#")e=an(t,e);else if(i!==" "&&i!==" "&&i!==`
234
- `&&i!=="\r"){let a,l=s,c=!1,[u,f]=Gr(t,e-1);for(let y=0;y<u.length;y++){if(y&&(l=c?l[a]:l[a]={}),a=u[y],(c=Object.hasOwn(l,a))&&(typeof l[a]!="object"||o.has(l[a])))throw new ae("trying to redefine an already defined value",{toml:t,ptr:e});!c&&a==="__proto__"&&Object.defineProperty(l,a,{enumerable:!0,configurable:!0,writable:!0})}if(c)throw new ae("trying to redefine an already defined value",{toml:t,ptr:e});let[g,p]=qn(t,f,"}",n-1,r);o.add(g),l[a]=g,e=p}}if(!i)throw new ae("unfinished table encountered",{toml:t,ptr:e});return[s,e]}function Pl(t,e,n,r){let s=[],o;for(e++;(o=t[e++])!=="]"&&o;){if(o===",")throw new ae("expected value, found comma",{toml:t,ptr:e-1});if(o==="#")e=an(t,e);else if(o!==" "&&o!==" "&&o!==`
235
- `&&o!=="\r"){let i=qn(t,e-1,"]",n-1,r);s.push(i[0]),e=i[1]}}if(!o)throw new ae("unfinished array encountered",{toml:t,ptr:e});return[s,e]}function $l(t,e,n,r){let s=e,o=n,i,a=!1,l;for(let c=0;c<t.length;c++){if(c){if(s=a?s[i]:s[i]={},o=(l=o[i]).c,r===0&&(l.t===1||l.t===2))return null;if(l.t===2){let u=s.length-1;s=s[u],o=o[u].c}}if(i=t[c],(a=Object.hasOwn(s,i))&&o[i]?.t===0&&o[i]?.d)return null;a||(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(l=o[i],l.t!==r&&!(r===1&&l.t===3)||(r===2&&(l.d||(l.d=!0,s[i]=[]),s[i].push(s={}),l.c[l.i++]=l={t:1,d:!1,i:0,c:{}}),l.d))return null;if(l.d=!0,r===1)s=a?s[i]:s[i]={};else if(r===0&&a)return null;return[i,s,l.c]}function Jr(t,{maxDepth:e=1e3,integersAsBigInt:n}={}){let r={},s={},o=r,i=s;for(let a=it(t,0);a<t.length;){if(t[a]==="["){let l=t[++a]==="[",c=Gr(t,a+=+l,"]");if(l){if(t[c[1]-1]!=="]")throw new ae("expected end of table declaration",{toml:t,ptr:c[1]-1});c[1]++}let u=$l(c[0],r,s,l?2:1);if(!u)throw new ae("trying to redefine an already defined table or value",{toml:t,ptr:a});i=u[2],o=u[1],a=c[1]}else{let l=Gr(t,a),c=$l(l[0],o,i,0);if(!c)throw new ae("trying to redefine an already defined table or value",{toml:t,ptr:a});let u=qn(t,l[1],void 0,e,n);c[1][c[0]]=u[0],a=u[1]}if(a=it(t,a,!0),t[a]&&t[a]!==`
236
- `&&t[a]!=="\r")throw new ae("each key-value declaration must be followed by an end-of-line",{toml:t,ptr:a});a=it(t,a)}return r}var Xr=14,mp=1440*6e4,yp=12e4,wp=15e3,Co=1792*1024,bp=7,mt=t=>t.toISOString().slice(0,10),at=t=>Date.parse(mt(t))-(bp-1)*mp,Ml=["sessions","activity"],Kr=t=>typeof t=="number"&&Number.isFinite(t)?t:void 0;function xo(t,e,n){let r=t?.day===mt(n)?t:void 0;return Object.fromEntries(Ml.map(s=>[s,Kr(r?.[s])??Math.min(Math.max(Kr(e[s])??0,at(n)),n.getTime())]))}function Ao(t,e,n,r,s,o){let i=e?.day===mt(r)?e:void 0,a={sent:{...t},file:{day:mt(r)}};for(let l of Ml){let c=l in s&&!o.includes(l)&&!(`${l}Error`in s),u=Kr(i?.[l]);c?(a.file[l]=n[l],a.sent[l]=r.getTime()):u!==void 0&&(a.sent[l]=Math.min(Kr(t[l])??u,u))}return a}function Nl(t,e=[]){let n={...t},r=_n(JSON.stringify(n));for(let s of["activity","sessions","memory","runs","engine"]){if(r.length<=Co)break;s in n&&(delete n[s],e.push(s),r=_n(JSON.stringify({...n,truncated:e})))}return r.length>Co?null:r}async function To(t,e,n,r=new Date){let s=AbortSignal.timeout(yp);await t.writeFile(`${e}/${mt(r)}.json`,n,r.getTime(),s);try{let o=mt(new Date(r.getTime()-Xr*24*60*6e4));for(let i of await t.walk(s)){let a=/^([^/]+)\/(\d{4}-\d{2}-\d{2})\.json$/.exec(i.key);a&&a[1]===e&&a[2]<o&&await t.rm(i.key,s)}}catch{}}var Ro={mode:"scheduled",intervalHours:24,requestedAt:0};function Wn(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:Ro.intervalHours,requestedAt:Number.isFinite(r)&&r>0?r:0}}async function Io(t){try{let e=await fetch(`${t.cloudUrl.replace(/\/+$/,"")}/api/remotesync/diagnostics/policy`,{headers:{Authorization:`Bearer ${t.token}`},signal:AbortSignal.timeout(wp)});return e.status===404?{...Ro}:e.ok?Wn(await e.json()):null}catch{return null}}var Fl=["merge","cloud","local"],Ll={version:1,revision:0,enabled:!1,rules:[{id:"default",source:"",target:"default"}]};function It(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 Sp(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 Dt(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 a=It(i.source,!0),l=Sp(i.target);if(typeof i.id!="string"||!/^[A-Za-z0-9_-]{1,80}$/.test(i.id)||s.has(i.id)||r.has(a))throw Error("Duplicate or invalid sync rule");return s.add(i.id),r.add(a),{id:i.id,source:a,target:l,...i.sourceId&&/^[a-f0-9-]{36}$/i.test(i.sourceId)?{sourceId:i.sourceId}:{}}});return{version:1,revision:e,enabled:n.enabled,rules:o}}function ln(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 lt={get:"penzor:sync:get",preview:"penzor:sync:preview",apply:"penzor:sync:apply",run:"penzor:sync:run",pause:"penzor:sync:pause",retry:"penzor:sync:retry",rename:"penzor:sync:rename",setup:"penzor:sync:setup",archiveSeen:"penzor:sync:archiveSeen"},Zr=t=>t.replace(/\.local$/i,"").replace(/[-_]+/g," ").trim()||t,jl=t=>String(t??"").normalize("NFC").trim().replace(/\s+/g," ").toLowerCase(),Do=(t,e,n)=>{let r=jl(t);return r?/[\[\]]/.test(t)||t.trim().length>64?"invalid":r==="macos"||r==="windows"||r==="linux"?"reserved":e.some(s=>s.id!==n&&jl(s.name)===r)?"taken":null:null},Ul=["Amadeus","agents","human","Plugins"];var yt=[{id:"notes",path:"Amadeus"},{id:"agents",path:"agents"},{id:"profile",path:"human"},{id:"plugins",path:"Plugins"}];var Vn=/^[a-z0-9][a-z0-9-]{0,63}$/,Qr=new Set(["muse"]),Yn=t=>{let e=/^agents\/([^/]+)$/.exec(t);return e&&Vn.test(e[1])?e[1]:null},vp=t=>[...Qr].some(e=>Oo(t,`agents/${e}`));function Hl(t){let e=t.split(/^\s*\[/m)[0]??"",n=o=>{let i=new RegExp(`^[ \\t]*${o}[ \\t]*=[ \\t]*(?:"((?:[^"\\\\\\n]|\\\\.)*)"|'([^'\\n]*)')`,"m").exec(e);return(i?.[1]!=null?i[1].replace(/\\(["\\])/g,"$1").replace(/\\n/g," "):i?.[2])?.replace(/[\u0000-\u001f\u007f]/g,"").trim().slice(0,80)||void 0},r=n("name"),s=n("name_en");return{...r?{name:r}:{},...s?{nameEn:s}:{}}}var cn=(t,e)=>ln(e,t)?.target??"off",Oo=(t,e)=>t===e||t.startsWith(e+"/"),kp=t=>yt.some(e=>Oo(t,e.path)),Po=t=>t.some(e=>e.id==="default")?es():"default",zl=(t,e)=>t.enabled?cn(t.rules,e):"off";function Bl(t,e,n){n==="off"&&(t=t.filter(o=>e?!o.source.startsWith(e+"/"):!o.source||kp(o.source)));let r=t.find(o=>o.source===e),s=t.filter(o=>o!==r);return e&&cn(s,e)===n?s:r?t.map(o=>o===r?{...o,target:n}:o):[...t,{id:e?es():Po(t),source:e,target:n}]}function un(t,e,n,r=!1){if(vp(e))return t;let s=t.rules;if(!t.enabled){let o=s.find(a=>!a.source),i=e?s.filter(a=>a.source&&Oo(a.source,e)):[];s=[{id:o?.id??Po(i),source:"",target:"off"},...i],e!=="agents"&&(s=$o(s,"agents","off"))}if(!e)for(let o of yt)s.some(i=>i.source===o.path)||(s=[...s,{id:es(),source:o.path,target:cn(s,o.path)}]);return ql({...t,rules:Bl(s,e,n)},r)}function ql(t,e=!1){let n=r=>cn(t.rules,r)!=="off";return{...t,enabled:yt.some(r=>n(r.path))||t.rules.some(r=>r.source&&r.target!=="off")||e&&n("")}}function Wl(t){let e=t.rules.some(n=>n.source==="")?t.rules:[{id:Po(t.rules),source:"",target:"default"},...t.rules];for(let n of yt)n.id!=="agents"&&cn(e,n.path)==="off"&&(e=Bl(e,n.path,"default"));return e=$o(e,"agents","off"),{...t,enabled:!0,rules:e}}function $o(t,e,n){let r=t.find(s=>s.source===e);return r?t.map(s=>s===r?{...s,target:n}:s):[...t,{id:es(),source:e,target:n}]}function Vl(t,e){let n=t;for(let r of new Set(e))Vn.test(r)&&!Qr.has(r)&&(n=un(n,`agents/${r}`,"default"));return n}function Yl(t){let e=cn(t.rules,"agents")!=="off"||t.rules.some(s=>s.source.startsWith("agents/")&&s.target!=="off"),n=t.rules.some(s=>s.source.startsWith("agents/"));if(!e&&!n)return null;let r=$o(t.rules.filter(s=>!s.source.startsWith("agents/")),"agents","off");return t.enabled?ql({...t,rules:r},!0):{...t,rules:r}}var Ep=0,es=()=>`rule-${Date.now().toString(36)}-${(Ep++).toString(36)}`;var Gl=["uploads","downloads","merges","renames","deletesSent","deletesLocal","conflictCopies","folderConflicts","tooLarge","errors"];var _p=/^(?:account_changed|content_sync_closed|paused|not_signed_in)$/;function Jl(t,e=[]){let n=t;for(let r of[...e].filter(s=>s&&s.length>=2).sort((s,o)=>o.length-s.length))n=n.split(r).join("[path]");return n.replace(/^(Duplicate folder sync identity|Concurrent (?:folder|file) rename): [\s\S]*$/,"$1: [path]")}var Gn=class{since;cur=null;last=null;runs=[];totals={runs:0,completedRuns:0,idleRuns:0};errors=[];clock;constructor(e=Date.now){this.clock=e,this.since=e()}reset(){this.since=this.clock(),this.cur=null,this.last=null,this.runs=[],this.errors=[],this.totals={runs:0,completedRuns:0,idleRuns:0}}begin(e=this.clock()){this.cur={at:e,counts:{}}}count(e,n=1){n>0&&(this.cur&&(this.cur.counts[e]=(this.cur.counts[e]??0)+n),this.totals[e]=(this.totals[e]??0)+n)}fault(e,n=[],r=this.clock()){if(!e||_p.test(e))return;this.count("errors"),/^File exceeds \d+ MB/.test(e)&&this.count("tooLarge");let s=this.errors[this.errors.length-1];if(s&&s.text===e){s.n++,s.at=r,this.addPaths(n);return}this.errors.push({first:r,at:r,n:1,text:e}),this.addPaths(n),this.errors.length>20&&this.errors.shift()}addPaths(e){let n=this.errors[this.errors.length-1],r=e.filter(s=>typeof s=="string"&&s);!n||!r.length||(n.paths=[...new Set([...n.paths??[],...r])].slice(0,8))}end(e,n=this.clock()){let r=this.cur;if(!r)return;this.cur=null;let s={at:r.at,ms:Math.max(0,n-r.at),completed:e,counts:r.counts};this.last=s,this.totals.runs++,e&&this.totals.completedRuns++,!e||Object.keys(r.counts).length?(this.runs.push(s),this.runs.length>20&&this.runs.shift()):this.totals.idleRuns++}snapshot(){let e=n=>({...n,counts:{...n.counts}});return{since:this.since,lastRun:this.last&&e(this.last),runs:this.runs.map(e),totals:{...this.totals},errors:this.errors.map(n=>({...n,...n.paths?{paths:[...n.paths]}:{}}))}}},Kl=null;function Xl(t){Kl=t}function Zl(){try{return Kl?.()??null}catch{return null}}var Fp=(t,e=[])=>{let n=Nl(t,e);return n&&Buffer.from(n.buffer,n.byteOffset,n.byteLength)},yc=60*6e4,Lp=2*6e4,Up=10*6e4,tc=yc,Hp=4*1024*1024,zp=256*1024,nc=["user","teamwork","discussion","delegate"],Bp=/^(?:New remarks in the team chat:|You are activated now \()/,wc={totalBytes:1024*1024,sessionBytes:256*1024,textChars:8e3,sessions:300,messages:400},No=/^(?:[a-z][a-z0-9+.-]*:\/\/|\/(?:v\d+|api)\/)/i,bc=(t,e)=>t.replace(/(["'`])([^"'`\n]*[\\/][^"'`\n]*)\1/g,(n,r,s)=>No.test(s)||e&&!/\s/.test(s)?n:`${r}[path]${r}`),Sc=t=>bc(t,!0).replace(/\b[a-z][a-z0-9+.-]*:\/\/[^\s"'`<>]+|(?:~|\b[A-Za-z]:|\\)?(?:[\\/][^\s"'`<>:*?|\\/()[\]{},;]+){2,}[\\/]?/gi,e=>No.test(e)?e:"[path]"),Xn=4e3,ns=(t,e)=>typeof t=="string"&&t?ut(Sc(dt(t.slice(0,Xn))),e):void 0,qp={runs:200,totalBytes:128*1024,errorChars:300,events:2e3,tools:40},Wp=64*1024,Mo=500,Vp={totalBytes:256*1024,fileChars:24e3,logChars:12e3,activity:300,detailChars:300},Yp=256*1024,rc=["SOUL.md","MEMORY.md",".memory-raw.md","HARNESS.md",".harness-raw.md",".harness-refinements.jsonl","HUMAN.md"],Gp=["description","developer_instructions"],Jp=["memory","harness","project_memory","human","dream","log_appended"],Kp=["homeDir","readCreds","accountId","appVersion"],jo=t=>Kp.every(e=>typeof t[e]=="function"),sc=ec().length>3?ec():null;function dt(t){return typeof t=="string"?(sc?t.split(sc).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(dt):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]":dt(n)])):t}var Xp=/^(?:model|modelId|voice|mode|backend|notify|escalateTo|realtimeModel|realtimeVoice|vision|background)$/,le=(t,e=120)=>typeof t=="string"&&t.length<=e?t:void 0,Zp=(t,e)=>/^[A-Za-z_][\w.-]{0,63}$/.test(t)?t:`[key:${e}]`;function dn(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[Zp(s,r)]=Xp.test(s)&&le(o,80)!==void 0?o:dn(o,e+1);return n}var Qp={"":/^(?: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)$/},oc={"":/^(?:name|version|model|model_reasoning_effort|approval_mode|created_by|created_at|avatar|lead|slug)$/,compaction:/^model$/,members:/^slug$/},eh=/^(?:apps|enabled_skill_ids)$/,ic=t=>!!t&&typeof t=="object"&&!Array.isArray(t)&&!(t instanceof Date);function th(t){try{let e=Jr(t),n=[],r=[],s=8192,o=(l,c)=>s<=0?!1:(s-=c.length+1,l.push(c),!0),i=(l,c,u)=>{let f=Qp[l].test(c)?c:`[key:${c.length}]`,g=oc[l].test(c),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():l===""&&eh.test(c)&&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(", ")}]`),`${f} = ${p??`"[text:${typeof u=="string"?u.length:JSON.stringify(u).length}]"`}`},a=(l,c,u)=>{if(o(r,c)){for(let[f,g]of Object.entries(u))if(!o(r,i(l,f,g)))return}};for(let[l,c]of Object.entries(e)){let u=l!==""&&Object.hasOwn(oc,l);if(u&&ic(c))a(l,`[${l}]`,c);else if(u&&Array.isArray(c)&&c.length>0&&c.every(ic))for(let f of c)a(l,`[[${l}]]`,f);else o(n,i("",l,c));if(s<=0)break}return[...n,...r].join(`
237
- `)}catch{return`[unparsed:${t.length}]`}}var vc=async t=>{try{return(await wt(t)).isFile()?await Op(t,"utf8"):null}catch{return null}},Kn=t=>wt(t).then(e=>e.isDirectory(),()=>!1),fn=async t=>{try{return JSON.parse(await vc(t)??"null")}catch{return null}},ct=async(t,e=200)=>{try{return(await hc(t)).filter(n=>!n.startsWith(".")&&n.length<=120).sort().slice(0,e)}catch{return[]}};async function nh(t,e){if(!(await wt(t)).isFile())return"";let n=await pc(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 rh(t){if(!t||typeof t!="object")return{};let e=n=>n&&typeof n=="object"?Object.entries(n).slice(0,100):[];return{defaultModel:le(t.cloud?.defaultModel)??null,models:dn(t.models),tts:dn(t.tts),asr:dn(t.asr),specialAgents:dn(t.specialAgents),pluginSettings:dn(t.plugins?.global),providers:(Array.isArray(t.providers)?t.providers:[]).slice(0,50).map(n=>({providerId:le(n?.providerId)??null,models:(Array.isArray(n?.modelIds)?n.modelIds:[]).filter(r=>le(r)!==void 0).slice(0,100)})),mcpServers:e(t.mcp?.mcpServers).map(([n,r])=>({name:le(n,64)??"[name]",enabled:r?.enabled!==!1})),channels:e(t.channels).map(([n,r])=>({name:le(n,64)??"[name]",enabled:r?.enabled===!0}))}}var sh=new Set(["config.toml","SOUL.md","MEMORY.md","HARNESS.md","HUMAN.md","Library","LOG","skills","plugins","Space","SCHEDULE.db","triggers.json"]);async function ac(t){let e=[];for(let n of await ct(t,100)){let r=ce(t,n);if(!await Kn(r))continue;let s=await vc(ce(r,"config.toml"));e.push({id:n,config:s===null?null:th(s).slice(0,4096),files:(await ct(r,400)).filter(o=>sh.has(o))})}return e}async function lc(t){let e=[];for(let n of await ct(t,300)){let r=await fn(ce(t,n,"manifest.json"));r&&e.push({id:le(r.id)??n,version:le(r.version,40)??null,name:le(r.nameEn)??le(r.name)??null})}return e}var Ht=t=>String(t?.code||t?.message||t).slice(0,120);async function oh(t,e,n,r=zp){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`,a=o(n),l=o(e.getTime()),c=[],u=r,f=!1;try{let g=(await hc(t)).filter(p=>/^\d{4}-\d{2}-\d{2}\.log$/.test(p)&&p>=i(a)&&p<=i(l)).sort().reverse();for(let p of g){if(f)break;let h=(await nh(ce(t,p),Hp).catch(w=>{if(w?.code==="ENOENT")return"";throw w})).split(`
239
- `).filter(w=>/^\d{12} /.test(w)&&w.slice(0,12)>=a&&w.slice(0,12)<l),m=h.length;for(;m>0&&Buffer.byteLength(h[m-1])+1<=u;)u-=Buffer.byteLength(h[--m])+1;m>0&&(f=!0),m<h.length&&c.push({date:p.slice(0,10),log:h.slice(m).join(`
240
- `)})}}catch(g){return g?.code==="ENOENT"?{activity:[]}:{activity:[],activityError:Ht(g)}}return{activity:c.reverse(),...f?{activityTruncated:!0}:{}}}var ut=(t,e)=>{if(!(typeof t!="string"||!t))return t.length>e?`${t.slice(0,e)}\u2026[+${t.length-e}]`:t},cc=t=>{try{let e=typeof t=="string"?JSON.parse(t):t;return Array.isArray(e)?e:[]}catch{return[]}},pn=t=>new Date(t).toISOString().slice(0,19).replace("T"," ");async function ih(t,e,n=wc,r=at(e)){let s=ce(t,"tangu","state.db"),o=await wt(s).then(a=>a.isFile(),a=>a?.code==="ENOENT"?!1:Ht(a));if(o!==!0)return o===!1?{sessions:[]}:{sessions:[],sessionsError:o};let i;try{let{DatabaseSync:a}=await import("node:sqlite");i=new a(s,{readOnly:!0}),i.exec("PRAGMA busy_timeout = 1500");let c="m.updated_at >= ? AND m.updated_at < ? AND m.timestamp >= ?",u=[pn(r),pn(e.getTime()),at(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
237
+ `))return o}}throw new ae("cannot find end of structure",{toml:t,ptr:e})}function Tp(t,e,n){let r=t.slice(e,n),s=r.indexOf("#");return s>-1&&(an(t,s),r=r.slice(0,s)),[r.trimEnd(),s]}function qn(t,e,n,r,s){if(r===0)throw new ae("document contains excessively nested structures. aborting.",{toml:t,ptr:e});let o=t[e];if(o==="["||o==="{"){let[c,l]=o==="["?Uc(t,e,r,s):Lc(t,e,r,s);if(n){if(l=it(t,l),t[l]===",")l++;else if(t[l]!==n)throw new ae("expected comma or end of structure",{toml:t,ptr:l})}return[c,l]}if(o==='"'||o==="'"){let[c,l]=Yr(t,e);if(n){if(l=it(t,l),t[l]&&t[l]!==","&&t[l]!==n&&t[l]!==`
238
+ `&&t[l]!=="\r")throw new ae("unexpected character encountered",{toml:t,ptr:l});t[l]===","&&l++}return[c,l]}let i=Fc(t,e,",",n),a=Tp(t,e,i-(t[i-1]===","?1:0));if(!a[0])throw new ae("incomplete key-value declaration: no value specified",{toml:t,ptr:e});return n&&a[1]>-1&&(i=it(t,e+a[1]),t[i]===","&&i++),[jc(a[0],t,e,s),i]}var Rp=/^[a-zA-Z0-9-_]+[ \t]*$/;function Jr(t,e,n="="){let r=e-1,s=[],o=t.indexOf(n,e);if(o<0)throw new ae("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 ae("multiline strings are not allowed in keys",{toml:t,ptr:e});let[a,c]=Yr(t,e);r=t.indexOf(".",c);let l=t.slice(c,r<0||r>o?o:r),u=Gr(l);if(u>-1)throw new ae("newlines are not allowed in keys",{toml:t,ptr:e+r+u});if(l.trimStart())throw new ae("found extra tokens after the string part",{toml:t,ptr:c});if(o<c&&(o=t.indexOf(n,c),o<0))throw new ae("incomplete key-value: cannot find end of key",{toml:t,ptr:e});s.push(a)}else{r=t.indexOf(".",e);let a=t.slice(e,r<0||r>o?o:r);if(!Rp.test(a))throw new ae("only letter, numbers, dashes and underscores are allowed in keys",{toml:t,ptr:e});s.push(a.trimEnd())}}while(r+1&&r<o);return[s,it(t,o+1,!0,!0)]}function Lc(t,e,n,r){let s={},o=new Set,i;for(e++;(i=t[e++])!=="}"&&i;){if(i===",")throw new ae("expected value, found comma",{toml:t,ptr:e-1});if(i==="#")e=an(t,e);else if(i!==" "&&i!==" "&&i!==`
239
+ `&&i!=="\r"){let a,c=s,l=!1,[u,d]=Jr(t,e-1);for(let y=0;y<u.length;y++){if(y&&(c=l?c[a]:c[a]={}),a=u[y],(l=Object.hasOwn(c,a))&&(typeof c[a]!="object"||o.has(c[a])))throw new ae("trying to redefine an already defined value",{toml:t,ptr:e});!l&&a==="__proto__"&&Object.defineProperty(c,a,{enumerable:!0,configurable:!0,writable:!0})}if(l)throw new ae("trying to redefine an already defined value",{toml:t,ptr:e});let[g,p]=qn(t,d,"}",n-1,r);o.add(g),c[a]=g,e=p}}if(!i)throw new ae("unfinished table encountered",{toml:t,ptr:e});return[s,e]}function Uc(t,e,n,r){let s=[],o;for(e++;(o=t[e++])!=="]"&&o;){if(o===",")throw new ae("expected value, found comma",{toml:t,ptr:e-1});if(o==="#")e=an(t,e);else if(o!==" "&&o!==" "&&o!==`
240
+ `&&o!=="\r"){let i=qn(t,e-1,"]",n-1,r);s.push(i[0]),e=i[1]}}if(!o)throw new ae("unfinished array encountered",{toml:t,ptr:e});return[s,e]}function Hc(t,e,n,r){let s=e,o=n,i,a=!1,c;for(let l=0;l<t.length;l++){if(l){if(s=a?s[i]:s[i]={},o=(c=o[i]).c,r===0&&(c.t===1||c.t===2))return null;if(c.t===2){let u=s.length-1;s=s[u],o=o[u].c}}if(i=t[l],(a=Object.hasOwn(s,i))&&o[i]?.t===0&&o[i]?.d)return null;a||(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:l<t.length-1&&r===2?3:r,d:!1,i:0,c:{}})}if(c=o[i],c.t!==r&&!(r===1&&c.t===3)||(r===2&&(c.d||(c.d=!0,s[i]=[]),s[i].push(s={}),c.c[c.i++]=c={t:1,d:!1,i:0,c:{}}),c.d))return null;if(c.d=!0,r===1)s=a?s[i]:s[i]={};else if(r===0&&a)return null;return[i,s,c.c]}function Kr(t,{maxDepth:e=1e3,integersAsBigInt:n}={}){let r={},s={},o=r,i=s;for(let a=it(t,0);a<t.length;){if(t[a]==="["){let c=t[++a]==="[",l=Jr(t,a+=+c,"]");if(c){if(t[l[1]-1]!=="]")throw new ae("expected end of table declaration",{toml:t,ptr:l[1]-1});l[1]++}let u=Hc(l[0],r,s,c?2:1);if(!u)throw new ae("trying to redefine an already defined table or value",{toml:t,ptr:a});i=u[2],o=u[1],a=l[1]}else{let c=Jr(t,a),l=Hc(c[0],o,i,0);if(!l)throw new ae("trying to redefine an already defined table or value",{toml:t,ptr:a});let u=qn(t,c[1],void 0,e,n);l[1][l[0]]=u[0],a=u[1]}if(a=it(t,a,!0),t[a]&&t[a]!==`
241
+ `&&t[a]!=="\r")throw new ae("each key-value declaration must be followed by an end-of-line",{toml:t,ptr:a});a=it(t,a)}return r}var Zr=14,Ip=1440*6e4,Dp=12e4,Op=15e3,To=1792*1024,Pp=7,mt=t=>t.toISOString().slice(0,10),at=t=>Date.parse(mt(t))-(Pp-1)*Ip,zc=["sessions","activity"],Xr=t=>typeof t=="number"&&Number.isFinite(t)?t:void 0;function Ro(t,e,n){let r=t?.day===mt(n)?t:void 0;return Object.fromEntries(zc.map(s=>[s,Xr(r?.[s])??Math.min(Math.max(Xr(e[s])??0,at(n)),n.getTime())]))}function Io(t,e,n,r,s,o){let i=e?.day===mt(r)?e:void 0,a={sent:{...t},file:{day:mt(r)}};for(let c of zc){let l=c in s&&!o.includes(c)&&!(`${c}Error`in s),u=Xr(i?.[c]);l?(a.file[c]=n[c],a.sent[c]=r.getTime()):u!==void 0&&(a.sent[c]=Math.min(Xr(t[c])??u,u))}return a}function Bc(t,e=[]){let n={...t},r=_n(JSON.stringify(n));for(let s of["activity","sessions","memory","runs","engine"]){if(r.length<=To)break;s in n&&(delete n[s],e.push(s),r=_n(JSON.stringify({...n,truncated:e})))}return r.length>To?null:r}async function Do(t,e,n,r=new Date){let s=AbortSignal.timeout(Dp);await t.writeFile(`${e}/${mt(r)}.json`,n,r.getTime(),s);try{let o=mt(new Date(r.getTime()-Zr*24*60*6e4));for(let i of await t.walk(s)){let a=/^([^/]+)\/(\d{4}-\d{2}-\d{2})\.json$/.exec(i.key);a&&a[1]===e&&a[2]<o&&await t.rm(i.key,s)}}catch{}}var Oo={mode:"scheduled",intervalHours:24,requestedAt:0};function Wn(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:Oo.intervalHours,requestedAt:Number.isFinite(r)&&r>0?r:0}}async function Po(t){try{let e=await fetch(`${t.cloudUrl.replace(/\/+$/,"")}/api/remotesync/diagnostics/policy`,{headers:{Authorization:`Bearer ${t.token}`},signal:AbortSignal.timeout(Op)});return e.status===404?{...Oo}:e.ok?Wn(await e.json()):null}catch{return null}}var Wc=["merge","cloud","local"],Vc={version:1,revision:0,enabled:!1,rules:[{id:"default",source:"",target:"default"}]};function It(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 Mp(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 Dt(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 a=It(i.source,!0),c=Mp(i.target);if(typeof i.id!="string"||!/^[A-Za-z0-9_-]{1,80}$/.test(i.id)||s.has(i.id)||r.has(a))throw Error("Duplicate or invalid sync rule");return s.add(i.id),r.add(a),{id:i.id,source:a,target:c,...i.sourceId&&/^[a-f0-9-]{36}$/i.test(i.sourceId)?{sourceId:i.sourceId}:{}}});return{version:1,revision:e,enabled:n.enabled,rules:o}}function cn(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 ct={get:"penzor:sync:get",preview:"penzor:sync:preview",apply:"penzor:sync:apply",run:"penzor:sync:run",pause:"penzor:sync:pause",retry:"penzor:sync:retry",rename:"penzor:sync:rename",setup:"penzor:sync:setup",archiveSeen:"penzor:sync:archiveSeen"},Qr=t=>t.replace(/\.local$/i,"").replace(/[-_]+/g," ").trim()||t,qc=t=>String(t??"").normalize("NFC").trim().replace(/\s+/g," ").toLowerCase(),Mo=(t,e,n)=>{let r=qc(t);return r?/[\[\]]/.test(t)||t.trim().length>64?"invalid":r==="macos"||r==="windows"||r==="linux"?"reserved":e.some(s=>s.id!==n&&qc(s.name)===r)?"taken":null:null},Yc=["Amadeus","agents","human","Plugins"];var yt=[{id:"notes",path:"Amadeus"},{id:"agents",path:"agents"},{id:"profile",path:"human"},{id:"plugins",path:"Plugins"}];var Vn=/^[a-z0-9][a-z0-9-]{0,63}$/,es=new Set(["muse"]),Yn=t=>{let e=/^agents\/([^/]+)$/.exec(t);return e&&Vn.test(e[1])?e[1]:null},$p=t=>[...es].some(e=>$o(t,`agents/${e}`));function Gc(t){let e=t.split(/^\s*\[/m)[0]??"",n=o=>{let i=new RegExp(`^[ \\t]*${o}[ \\t]*=[ \\t]*(?:"((?:[^"\\\\\\n]|\\\\.)*)"|'([^'\\n]*)')`,"m").exec(e);return(i?.[1]!=null?i[1].replace(/\\(["\\])/g,"$1").replace(/\\n/g," "):i?.[2])?.replace(/[\u0000-\u001f\u007f]/g,"").trim().slice(0,80)||void 0},r=n("name"),s=n("name_en");return{...r?{name:r}:{},...s?{nameEn:s}:{}}}var ln=(t,e)=>cn(e,t)?.target??"off",$o=(t,e)=>t===e||t.startsWith(e+"/"),Np=t=>yt.some(e=>$o(t,e.path)),No=t=>t.some(e=>e.id==="default")?ts():"default",Jc=(t,e)=>t.enabled?ln(t.rules,e):"off";function Kc(t,e,n){n==="off"&&(t=t.filter(o=>e?!o.source.startsWith(e+"/"):!o.source||Np(o.source)));let r=t.find(o=>o.source===e),s=t.filter(o=>o!==r);return e&&ln(s,e)===n?s:r?t.map(o=>o===r?{...o,target:n}:o):[...t,{id:e?ts():No(t),source:e,target:n}]}function un(t,e,n,r=!1){if($p(e))return t;let s=t.rules;if(!t.enabled){let o=s.find(a=>!a.source),i=e?s.filter(a=>a.source&&$o(a.source,e)):[];s=[{id:o?.id??No(i),source:"",target:"off"},...i],e!=="agents"&&(s=jo(s,"agents","off"))}if(!e)for(let o of yt)s.some(i=>i.source===o.path)||(s=[...s,{id:ts(),source:o.path,target:ln(s,o.path)}]);return Xc({...t,rules:Kc(s,e,n)},r)}function Xc(t,e=!1){let n=r=>ln(t.rules,r)!=="off";return{...t,enabled:yt.some(r=>n(r.path))||t.rules.some(r=>r.source&&r.target!=="off")||e&&n("")}}function Zc(t){let e=t.rules.some(n=>n.source==="")?t.rules:[{id:No(t.rules),source:"",target:"default"},...t.rules];for(let n of yt)n.id!=="agents"&&ln(e,n.path)==="off"&&(e=Kc(e,n.path,"default"));return e=jo(e,"agents","off"),{...t,enabled:!0,rules:e}}function jo(t,e,n){let r=t.find(s=>s.source===e);return r?t.map(s=>s===r?{...s,target:n}:s):[...t,{id:ts(),source:e,target:n}]}function Qc(t,e){let n=t;for(let r of new Set(e))Vn.test(r)&&!es.has(r)&&(n=un(n,`agents/${r}`,"default"));return n}function el(t){let e=ln(t.rules,"agents")!=="off"||t.rules.some(s=>s.source.startsWith("agents/")&&s.target!=="off"),n=t.rules.some(s=>s.source.startsWith("agents/"));if(!e&&!n)return null;let r=jo(t.rules.filter(s=>!s.source.startsWith("agents/")),"agents","off");return t.enabled?Xc({...t,rules:r},!0):{...t,rules:r}}var jp=0,ts=()=>`rule-${Date.now().toString(36)}-${(jp++).toString(36)}`;var tl=["uploads","downloads","merges","renames","deletesSent","deletesLocal","conflictCopies","folderConflicts","tooLarge","errors"];var Fp=/^(?:account_changed|content_sync_closed|paused|not_signed_in)$/;function nl(t,e=[]){let n=t;for(let r of[...e].filter(s=>s&&s.length>=2).sort((s,o)=>o.length-s.length))n=n.split(r).join("[path]");return n.replace(/^(Duplicate folder sync identity|Concurrent (?:folder|file) rename): [\s\S]*$/,"$1: [path]")}var Gn=class{since;cur=null;last=null;runs=[];totals={runs:0,completedRuns:0,idleRuns:0};errors=[];clock;constructor(e=Date.now){this.clock=e,this.since=e()}reset(){this.since=this.clock(),this.cur=null,this.last=null,this.runs=[],this.errors=[],this.totals={runs:0,completedRuns:0,idleRuns:0}}begin(e=this.clock()){this.cur={at:e,counts:{}}}count(e,n=1){n>0&&(this.cur&&(this.cur.counts[e]=(this.cur.counts[e]??0)+n),this.totals[e]=(this.totals[e]??0)+n)}fault(e,n=[],r=this.clock()){if(!e||Fp.test(e))return;this.count("errors"),/^File exceeds \d+ MB/.test(e)&&this.count("tooLarge");let s=this.errors[this.errors.length-1];if(s&&s.text===e){s.n++,s.at=r,this.addPaths(n);return}this.errors.push({first:r,at:r,n:1,text:e}),this.addPaths(n),this.errors.length>20&&this.errors.shift()}addPaths(e){let n=this.errors[this.errors.length-1],r=e.filter(s=>typeof s=="string"&&s);!n||!r.length||(n.paths=[...new Set([...n.paths??[],...r])].slice(0,8))}end(e,n=this.clock()){let r=this.cur;if(!r)return;this.cur=null;let s={at:r.at,ms:Math.max(0,n-r.at),completed:e,counts:r.counts};this.last=s,this.totals.runs++,e&&this.totals.completedRuns++,!e||Object.keys(r.counts).length?(this.runs.push(s),this.runs.length>20&&this.runs.shift()):this.totals.idleRuns++}snapshot(){let e=n=>({...n,counts:{...n.counts}});return{since:this.since,lastRun:this.last&&e(this.last),runs:this.runs.map(e),totals:{...this.totals},errors:this.errors.map(n=>({...n,...n.paths?{paths:[...n.paths]}:{}}))}}},rl=null;function sl(t){rl=t}function ol(){try{return rl?.()??null}catch{return null}}var Zp=(t,e=[])=>{let n=Bc(t,e);return n&&Buffer.from(n.buffer,n.byteOffset,n.byteLength)},_l=60*6e4,Qp=2*6e4,eh=10*6e4,cl=_l,th=4*1024*1024,nh=256*1024,ll=["user","teamwork","discussion","delegate"],rh=/^(?:New remarks in the team chat:|You are activated now \()/,Cl={totalBytes:1024*1024,sessionBytes:256*1024,textChars:8e3,sessions:300,messages:400},Lo=/^(?:[a-z][a-z0-9+.-]*:\/\/|\/(?:v\d+|api)\/)/i,xl=(t,e)=>t.replace(/(["'`])([^"'`\n]*[\\/][^"'`\n]*)\1/g,(n,r,s)=>Lo.test(s)||e&&!/\s/.test(s)?n:`${r}[path]${r}`),Al=t=>xl(t,!0).replace(/\b[a-z][a-z0-9+.-]*:\/\/[^\s"'`<>]+|(?:~|\b[A-Za-z]:|\\)?(?:[\\/][^\s"'`<>:*?|\\/()[\]{},;]+){2,}[\\/]?/gi,e=>Lo.test(e)?e:"[path]"),Xn=4e3,rs=(t,e)=>typeof t=="string"&&t?ut(Al(dt(t.slice(0,Xn))),e):void 0,sh={runs:200,totalBytes:128*1024,errorChars:300,events:2e3,tools:40},oh=64*1024,Fo=500,ih={totalBytes:256*1024,fileChars:24e3,logChars:12e3,activity:300,detailChars:300},ah=256*1024,ul=["SOUL.md","MEMORY.md",".memory-raw.md","HARNESS.md",".harness-raw.md",".harness-refinements.jsonl","HUMAN.md"],ch=["description","developer_instructions"],lh=["memory","harness","project_memory","human","dream","log_appended"],uh=["homeDir","readCreds","accountId","appVersion"],Uo=t=>uh.every(e=>typeof t[e]=="function"),dl=al().length>3?al():null;function dt(t){return typeof t=="string"?(dl?t.split(dl).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(dt):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]":dt(n)])):t}var dh=/^(?:model|modelId|voice|mode|backend|notify|escalateTo|realtimeModel|realtimeVoice|vision|background)$/,ce=(t,e=120)=>typeof t=="string"&&t.length<=e?t:void 0,fh=(t,e)=>/^[A-Za-z_][\w.-]{0,63}$/.test(t)?t:`[key:${e}]`;function dn(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[fh(s,r)]=dh.test(s)&&ce(o,80)!==void 0?o:dn(o,e+1);return n}var ph={"":/^(?: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)$/},fl={"":/^(?:name|version|model|model_reasoning_effort|approval_mode|created_by|created_at|avatar|lead|slug)$/,compaction:/^model$/,members:/^slug$/},hh=/^(?:apps|enabled_skill_ids)$/,pl=t=>!!t&&typeof t=="object"&&!Array.isArray(t)&&!(t instanceof Date);function gh(t){try{let e=Kr(t),n=[],r=[],s=8192,o=(c,l)=>s<=0?!1:(s-=l.length+1,c.push(l),!0),i=(c,l,u)=>{let d=ph[c].test(l)?l:`[key:${l.length}]`,g=fl[c].test(l),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():c===""&&hh.test(l)&&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(", ")}]`),`${d} = ${p??`"[text:${typeof u=="string"?u.length:JSON.stringify(u).length}]"`}`},a=(c,l,u)=>{if(o(r,l)){for(let[d,g]of Object.entries(u))if(!o(r,i(c,d,g)))return}};for(let[c,l]of Object.entries(e)){let u=c!==""&&Object.hasOwn(fl,c);if(u&&pl(l))a(c,`[${c}]`,l);else if(u&&Array.isArray(l)&&l.length>0&&l.every(pl))for(let d of l)a(c,`[[${c}]]`,d);else o(n,i("",c,l));if(s<=0)break}return[...n,...r].join(`
242
+ `)}catch{return`[unparsed:${t.length}]`}}var Tl=async t=>{try{return(await wt(t)).isFile()?await Vp(t,"utf8"):null}catch{return null}},Kn=t=>wt(t).then(e=>e.isDirectory(),()=>!1),fn=async t=>{try{return JSON.parse(await Tl(t)??"null")}catch{return null}},lt=async(t,e=200)=>{try{return(await vl(t)).filter(n=>!n.startsWith(".")&&n.length<=120).sort().slice(0,e)}catch{return[]}};async function mh(t,e){if(!(await wt(t)).isFile())return"";let n=await Sl(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(`
243
+ `)+1):i}finally{await n.close()}}function yh(t){if(!t||typeof t!="object")return{};let e=n=>n&&typeof n=="object"?Object.entries(n).slice(0,100):[];return{defaultModel:ce(t.cloud?.defaultModel)??null,models:dn(t.models),tts:dn(t.tts),asr:dn(t.asr),specialAgents:dn(t.specialAgents),pluginSettings:dn(t.plugins?.global),providers:(Array.isArray(t.providers)?t.providers:[]).slice(0,50).map(n=>({providerId:ce(n?.providerId)??null,models:(Array.isArray(n?.modelIds)?n.modelIds:[]).filter(r=>ce(r)!==void 0).slice(0,100)})),mcpServers:e(t.mcp?.mcpServers).map(([n,r])=>({name:ce(n,64)??"[name]",enabled:r?.enabled!==!1})),channels:e(t.channels).map(([n,r])=>({name:ce(n,64)??"[name]",enabled:r?.enabled===!0}))}}var wh=new Set(["config.toml","SOUL.md","MEMORY.md","HARNESS.md","HUMAN.md","Library","LOG","skills","plugins","Space","SCHEDULE.db","triggers.json"]);async function hl(t){let e=[];for(let n of await lt(t,100)){let r=le(t,n);if(!await Kn(r))continue;let s=await Tl(le(r,"config.toml"));e.push({id:n,config:s===null?null:gh(s).slice(0,4096),files:(await lt(r,400)).filter(o=>wh.has(o))})}return e}async function gl(t){let e=[];for(let n of await lt(t,300)){let r=await fn(le(t,n,"manifest.json"));r&&e.push({id:ce(r.id)??n,version:ce(r.version,40)??null,name:ce(r.nameEn)??ce(r.name)??null})}return e}var Ht=t=>String(t?.code||t?.message||t).slice(0,120);async function bh(t,e,n,r=nh){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`,a=o(n),c=o(e.getTime()),l=[],u=r,d=!1;try{let g=(await vl(t)).filter(p=>/^\d{4}-\d{2}-\d{2}\.log$/.test(p)&&p>=i(a)&&p<=i(c)).sort().reverse();for(let p of g){if(d)break;let h=(await mh(le(t,p),th).catch(w=>{if(w?.code==="ENOENT")return"";throw w})).split(`
244
+ `).filter(w=>/^\d{12} /.test(w)&&w.slice(0,12)>=a&&w.slice(0,12)<c),m=h.length;for(;m>0&&Buffer.byteLength(h[m-1])+1<=u;)u-=Buffer.byteLength(h[--m])+1;m>0&&(d=!0),m<h.length&&l.push({date:p.slice(0,10),log:h.slice(m).join(`
245
+ `)})}}catch(g){return g?.code==="ENOENT"?{activity:[]}:{activity:[],activityError:Ht(g)}}return{activity:l.reverse(),...d?{activityTruncated:!0}:{}}}var ut=(t,e)=>{if(!(typeof t!="string"||!t))return t.length>e?`${t.slice(0,e)}\u2026[+${t.length-e}]`:t},ml=t=>{try{let e=typeof t=="string"?JSON.parse(t):t;return Array.isArray(e)?e:[]}catch{return[]}},pn=t=>new Date(t).toISOString().slice(0,19).replace("T"," ");async function Sh(t,e,n=Cl,r=at(e)){let s=le(t,"tangu","state.db"),o=await wt(s).then(a=>a.isFile(),a=>a?.code==="ENOENT"?!1:Ht(a));if(o!==!0)return o===!1?{sessions:[]}:{sessions:[],sessionsError:o};let i;try{let{DatabaseSync:a}=await import("node:sqlite");i=new a(s,{readOnly:!0}),i.exec("PRAGMA busy_timeout = 1500");let l="m.updated_at >= ? AND m.updated_at < ? AND m.timestamp >= ?",u=[pn(r),pn(e.getTime()),at(e)],d=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
246
  FROM chat_messages m JOIN chat_sessions s ON s.id = m.session_id
242
- WHERE s.kind IN (${nc.map(()=>"?").join(", ")}) AND ${c} GROUP BY s.id ORDER BY changed_at DESC, s.id LIMIT ?`).all(...nc,...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 ${c} ORDER BY m.timestamp DESC, m.created_at DESC LIMIT ?`),p=[],y=0,h=f.length>n.sessions;for(let m of f.slice(0,n.sessions)){let w=g.all(m.id,...u,n.messages+1),_=w.length>n.messages,$=[],R=0;for(let C of w.slice(0,n.messages)){let E=cc(C.tool_calls),I=m.kind==="teamwork"&&C.role==="user"&&Bp.test(String(C.content??"")),U={role:le(C.role,16)??null,at:Number(C.timestamp)||null,agent:le(C.agent_slug,64),model:le(C.model_id,128),error:C.is_error?!0:void 0,text:I?void 0:ut(C.content,n.textChars),relayChars:I?String(C.content??"").length:void 0,reasoning:ut(C.reasoning,n.textChars),tools:E.length?E.map(V=>le(V?.function?.name??V?.name,80)??"?"):void 0,toolArgChars:E.length?E.reduce((V,Z)=>V+String(Z?.function?.arguments??"").length,0):void 0,toolResultChars:Number(C.tool_result_chars)||void 0,attachments:cc(C.attachments).length||void 0},M=Buffer.byteLength(JSON.stringify(U));if(R+M>n.sessionBytes){_=!0;break}R+=M,$.push(U)}let O={id:le(m.id,64)??null,kind:le(m.kind,16)??null,parent:le(m.parent_session_id,64),app:le(m.app_id,50)??null,title:ut(m.title,200)??null,model:le(m.model_id,128)??null,project:ut(m.project_name,120),archived:m.archived?!0:void 0,createdAt:le(m.created_at,40)??null,updatedAt:le(m.updated_at,40)??null,messages:$.reverse(),..._?{olderMessagesDropped:!0}:{}},S=Buffer.byteLength(JSON.stringify(O));if(y+S>n.totalBytes){h=!0;break}y+=S,p.push(O)}return{sessions:p,...h?{sessionsTruncated:!0}:{}}}catch(a){return{sessions:[],sessionsError:Ht(a)}}finally{try{i?.close()}catch{}}}async function ah(t,e,n=qp){let r=ce(t,"tangu","state.db"),s=await wt(r).then(i=>i.isFile(),i=>i?.code==="ENOENT"?!1:Ht(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 l=o.prepare(`SELECT r.id, r.session_id, r.app_id, r.status, r.current_step, r.model_id, substr(r.error, 1, ${Xn}) AS error, r.tokens_total, r.created_at, r.updated_at, s.kind
247
+ WHERE s.kind IN (${ll.map(()=>"?").join(", ")}) AND ${l} GROUP BY s.id ORDER BY changed_at DESC, s.id LIMIT ?`).all(...ll,...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
248
+ FROM chat_messages m WHERE m.session_id = ? AND ${l} ORDER BY m.timestamp DESC, m.created_at DESC LIMIT ?`),p=[],y=0,h=d.length>n.sessions;for(let m of d.slice(0,n.sessions)){let w=g.all(m.id,...u,n.messages+1),_=w.length>n.messages,M=[],R=0;for(let C of w.slice(0,n.messages)){let E=ml(C.tool_calls),I=m.kind==="teamwork"&&C.role==="user"&&rh.test(String(C.content??"")),U={role:ce(C.role,16)??null,at:Number(C.timestamp)||null,agent:ce(C.agent_slug,64),model:ce(C.model_id,128),error:C.is_error?!0:void 0,text:I?void 0:ut(C.content,n.textChars),relayChars:I?String(C.content??"").length:void 0,reasoning:ut(C.reasoning,n.textChars),tools:E.length?E.map(V=>ce(V?.function?.name??V?.name,80)??"?"):void 0,toolArgChars:E.length?E.reduce((V,Z)=>V+String(Z?.function?.arguments??"").length,0):void 0,toolResultChars:Number(C.tool_result_chars)||void 0,attachments:ml(C.attachments).length||void 0},$=Buffer.byteLength(JSON.stringify(U));if(R+$>n.sessionBytes){_=!0;break}R+=$,M.push(U)}let O={id:ce(m.id,64)??null,kind:ce(m.kind,16)??null,parent:ce(m.parent_session_id,64),app:ce(m.app_id,50)??null,title:ut(m.title,200)??null,model:ce(m.model_id,128)??null,project:ut(m.project_name,120),archived:m.archived?!0:void 0,createdAt:ce(m.created_at,40)??null,updatedAt:ce(m.updated_at,40)??null,messages:M.reverse(),..._?{olderMessagesDropped:!0}:{}},S=Buffer.byteLength(JSON.stringify(O));if(y+S>n.totalBytes){h=!0;break}y+=S,p.push(O)}return{sessions:p,...h?{sessionsTruncated:!0}:{}}}catch(a){return{sessions:[],sessionsError:Ht(a)}}finally{try{i?.close()}catch{}}}async function vh(t,e,n=sh){let r=le(t,"tangu","state.db"),s=await wt(r).then(i=>i.isFile(),i=>i?.code==="ENOENT"?!1:Ht(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 c=o.prepare(`SELECT r.id, r.session_id, r.app_id, r.status, r.current_step, r.model_id, substr(r.error, 1, ${Xn}) AS error, r.tokens_total, r.created_at, r.updated_at, s.kind
244
249
  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(pn(at(e)),pn(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,
250
+ WHERE r.updated_at >= ? AND r.updated_at < ? ORDER BY r.updated_at DESC, r.id LIMIT ?`).all(pn(at(e)),pn(e.getTime()),n.runs+1),l=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
251
  json_extract(e.payload, '$.prompt') AS prompt, json_extract(e.payload, '$.completion') AS completion, json_extract(e.payload, '$.cached') AS cached,
247
252
  json_extract(e.payload, '$.reasoningTokens') AS reasoning, json_extract(e.payload, '$.llmMs') AS llm_ms, json_extract(e.payload, '$.ttftMs') AS ttft_ms,
248
253
  json_extract(e.payload, '$.requestBytes') AS request_bytes, json_extract(e.payload, '$.phase') AS phase, substr(json_extract(e.payload, '$.error'), 1, ${Xn}) 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=h=>typeof h=="number"&&Number.isFinite(h)&&h>0?h:0,f=h=>h||void 0,g=[],p=0,y=l.length>n.runs;for(let h of l.slice(0,n.runs)){let m={llmCalls:0,prompt:0,completion:0,cached:0,reasoning:0,llmMs:0,ttftMaxMs:0,requestMaxBytes:0},w=new Map,_=[],$=0,R=c.all(h.id,n.events+1),O=R.length>n.events;for(let E of R.slice(0,n.events))if(E.type==="usage")m.llmCalls++,m.prompt+=u(E.prompt),m.completion+=u(E.completion),m.cached+=u(E.cached),m.reasoning+=u(E.reasoning),m.llmMs+=u(E.llm_ms),m.ttftMaxMs=Math.max(m.ttftMaxMs,u(E.ttft_ms)),m.requestMaxBytes=Math.max(m.requestMaxBytes,u(E.request_bytes));else if(E.type==="tool_result"){let I=le(E.name,80)??"?",U=w.get(I)??(w.size<n.tools?{name:I,n:0,ms:0,maxMs:0}:void 0);if(!U){O=!0;continue}w.set(I,U),U.n++,E.failed&&(U.errors=(U.errors??0)+1),U.ms+=u(E.ms),U.maxMs=Math.max(U.maxMs,u(E.ms))}else if(E.type==="error"){let I=ns(E.error,n.errorChars);I&&!_.includes(I)&&_.length<3&&_.push(I)}else E.phase==="llm_retry"&&$++;let S={id:le(h.id,64)??null,session:le(h.session_id,64)??null,kind:le(h.kind,16),app:le(h.app_id,50),model:le(h.model_id,128),status:le(h.status,16)??null,error:ns(h.error,n.errorChars),createdAt:le(h.created_at,40)??null,updatedAt:le(h.updated_at,40)??null,steps:f(u(h.current_step)),tokens:f(u(h.tokens_total)),retries:f($),...Object.fromEntries(Object.entries(m).map(([E,I])=>[E,f(I)])),errors:_.length?_:void 0,tools:w.size?[...w.values()]:void 0,partial:O||void 0},C=Buffer.byteLength(JSON.stringify(S));if(p+C>n.totalBytes){y=!0;break}p+=C,g.push(S)}return{runs:g,...y?{runsTruncated:!0}:{}}}catch(i){return{runs:[],runsError:Ht(i)}}finally{try{o?.close()}catch{}}}async function lh(t){let e=s=>Math.round(s/1048576),n=s=>wt(s).then(o=>o.isFile()?o.size:0,()=>0),r=ce(t,"tangu","state.db");return{cpus:$p().length,memTotalMB:e(jp()),memFreeMB:e(Mp()),diskFreeMB:await Pp(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 uc=t=>typeof t.diagnosticLogs=="function";function ch(t,e=Wp){let n=t?.engine;if(!n||typeof n!="object")return null;let r=(Array.isArray(n.lines)?n.lines:[]).filter(l=>typeof l=="string"&&!!l),s=r.map(l=>ns(l,Mo)??""),o=s.some((l,c)=>l.length>Mo||r[c].length>Xn),i=s.length,a=e;for(;i>0&&Buffer.byteLength(s[i-1])+1<=a;)a-=Buffer.byteLength(s[--i])+1;return i>0&&(o=!0),{state:le(n.state,32)??null,lastError:ns(n.lastError,Mo)??null,log:s.slice(i).join(`
250
- `),...o?{logTruncated:!0}:{}}}var Fo={errors:20,errorChars:300,agents:100},uh=t=>Sc(bc(t,!1).replace(/[^\s"'`<>()[\]{},;]*\/[^\s"'`<>()[\]{},;]*/g,e=>No.test(e)?e:"[path]")),dh=(t,e=[],n=Fo.errorChars)=>ut(uh(Jl(dt(t),e.map(r=>dt(r)))),n)??"",$e=t=>typeof t=="number"&&Number.isFinite(t)&&t>0?Math.round(t):0,ts=t=>typeof t=="number"&&Number.isFinite(t)&&t>0?new Date(t).toISOString():null,kc=t=>{let e=t&&typeof t=="object"?t:{};return Object.fromEntries(Gl.flatMap(n=>$e(e[n])?[[n,$e(e[n])]]:[]))},dc=t=>{let e=t;return e&&typeof e=="object"?{at:ts(e.at),ms:$e(e.ms),completed:e.completed===!0,...kc(e.counts)}:null},fh=Object.fromEntries(yt.map(t=>[t.path,t.id])),ph=new Set(["idle","scanning","syncing","paused"]),hh=new Set(["queued","active","done","failed","paused","conflict"]);function gh(t,e){let n=(Array.isArray(t)?t:[]).filter(a=>!!a&&typeof a.source=="string"&&typeof a.target=="string"),r=a=>a===void 0?null:a==="default"?"shared":a==="off"?"off":e&&a===`device-${e}`?"device":/^device-/.test(a)?"other-device":"unknown",s={other:r(n.find(a=>a.source==="")?.target)};for(let a of yt)s[a.id]=r(ln(a.path,n)?.target);let o={},i={};for(let a of n){if(a.source===""||fh[a.source])continue;let l=Yn(a.source);if(l&&Object.keys(o).length<Fo.agents)o[l]=r(a.target);else if(!l){let c=r(a.target)??"unknown";i[c]=(i[c]??0)+1}}return{...s,agentRules:o,folderRules:i,count:n.length}}function mh(t){let e=t;if(!e||typeof e!="object")return null;let n=typeof e.deviceId=="string"&&/^[A-Za-z0-9_-]{1,64}$/.test(e.deviceId)?e.deviceId:null,r=e.backlog&&typeof e.backlog=="object"?e.backlog:null,s=r?.jobs&&typeof r.jobs=="object"?Object.fromEntries(Object.entries(r.jobs).filter(([i,a])=>hh.has(i)&&$e(a)).map(([i,a])=>[i,$e(a)])):{},o=e.totals??{};return{deviceId:n,session:e.session===!0,enabled:e.enabled===!0,paused:e.paused===!0,running:e.running===!0,phase:typeof e.phase=="string"&&ph.has(e.phase)?e.phase:null,revision:$e(e.revision),rules:gh(e.rules,n),backlog:r?{jobs:s,blocked:$e(r.blocked),pendingUploads:$e(r.pendingUploads),unconfirmed:$e(r.unconfirmed),trash:$e(r.trash),awaitingBytes:$e(r.awaitingBytes),dirty:$e(r.dirty)}:null,archive:e.archive==="running"||e.archive==="done"?e.archive:null,since:ts(e.since),lastRun:dc(e.lastRun),runs:(Array.isArray(e.runs)?e.runs:[]).slice(-20).map(dc).filter(Boolean),totals:{runs:$e(o.runs),completedRuns:$e(o.completedRuns),idleRuns:$e(o.idleRuns),...kc(o)},errors:(Array.isArray(e.errors)?e.errors:[]).slice(-Fo.errors).flatMap(i=>{if(!i||typeof i!="object"||typeof i.text!="string"||!i.text)return[];let a=Array.isArray(i.paths)?i.paths.filter(l=>typeof l=="string"):[];return[{first:ts(i.first),at:ts(i.at),n:$e(i.n)||1,kind:jr(i.text)??"other",text:dh(i.text,a)}]})}}function yh(t){let e=t?.engine?.lines;if(!Array.isArray(e))return null;let n={lines:0,errorRounds:0,tooLarge:0,overwrites:0,pulledNew:0,conflictCopies:0};for(let r of e){if(typeof r!="string"||!r.includes("[agent sync]"))continue;n.lines++;let s=/已从云端拉取(覆盖|新文件)/.exec(r);if(s){s[1]==="\u8986\u76D6"?n.overwrites++:n.pulledNew++,r.includes("\u672C\u5730\u7248\u672C\u5DF2\u5B58\u4E3A")&&n.conflictCopies++;continue}n.errorRounds++,n.tooLarge+=r.match(/exceeds sync limit/g)?.length??0}return n}function wh(t,e=Gp){let n;try{n=Jr(t)}catch{return{}}return Object.fromEntries(e.flatMap(r=>typeof n[r]=="string"&&n[r]?[[r,n[r]]]:[]))}async function Ec(t,e=Yp){try{if(!(await wt(t)).isFile())return null;let n=await pc(t,Ql.O_RDONLY|(Ql.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 Jn=async(t,e)=>{let n=await Ec(t);return n?ut(dt(n),e):void 0};async function bh(t,e){let n=await Ec(ce(t,"config.toml")),r=Object.entries(n?wh(n):{}).map(([s,o])=>[s,ut(dt(o),e)??""]);return r.length?Object.fromEntries(r):void 0}async function fc(t){let e=await fn(ce(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 Sh(t,e,n=Vp){let r=ce(t,"tangu"),s=p=>wt(p).then(y=>y.isFile()?y.mtimeMs:0,()=>0),o=mt(new Date(at(e))),i={agents:[],teams:[],projects:[],activity:[]},a=n.totalBytes,l=(p,y)=>{let h=Buffer.byteLength(JSON.stringify(y))+1;return h>a?(i.truncated=!0,!1):(a-=h,p.push(y),!0)},c=await Jn(ce(r,"USER.md"),n.fileChars);c&&l([],c)&&(i.user=c);let u=ce(r,"state.db"),f=await wt(u).then(p=>p.isFile(),p=>p?.code==="ENOENT"?!1:Ht(p));if(typeof f=="string")i.activityError=f;else if(f){let p;try{let{DatabaseSync:y}=await import("node:sqlite");p=new y(u,{readOnly:!0}),p.exec("PRAGMA busy_timeout = 1500");let m=p.prepare(`SELECT agent, action, substr(detail, 1, ${Xn}) AS detail, session_ref, created_at FROM special_agent_log
251
- WHERE created_at >= ? AND created_at < ? AND (${Jp.map(w=>`action GLOB '${w}*'`).join(" OR ")})
252
- ORDER BY created_at DESC, rowid DESC LIMIT ?`).all(pn(at(e)),pn(e.getTime()),n.activity+1);m.length>n.activity&&(i.truncated=!0);for(let w of m.slice(0,n.activity))if(!l(i.activity,{at:le(w.created_at,40)??null,agent:le(w.agent,64)??null,action:le(w.action,64)??null,detail:typeof w.detail=="string"&&w.detail?ut(dt(w.detail),n.detailChars):void 0,session:le(w.session_ref,64)}))break}catch(y){i.activityError=Ht(y)}finally{try{p?.close()}catch{}}}for(let p of await ct(ce(r,"project-memory"),100)){let y=ce(r,"project-memory",p);if(!await Kn(y))continue;let h=await Jn(ce(y,"MEMORY.md"),n.fileChars),m=await fc(y);if(!h&&!m)continue;let w=(await fn(ce(y,"PROJECT.json")))?.project;if(!l(i.projects,{id:le(p,64)??null,name:typeof w=="string"?le(mc(w.replace(/[\\/]+$/,"").replace(/\\/g,"/"))):void 0,state:m,memory:h}))break}for(let p of await ct(ce(r,"teams"),100)){if(!await Kn(ce(r,"teams",p)))continue;let y=await Jn(ce(r,"teams",p,"TEAM.md"),n.fileChars);if(y&&!l(i.teams,{id:p,files:{"TEAM.md":y}}))break}let g=[];for(let p of await ct(ce(r,"agents"),100)){let y=ce(r,"agents",p);await Kn(y)&&g.push({id:p,dir:y,at:Math.max(0,...await Promise.all([...rc,".memory-state.json"].map(h=>s(ce(y,h)))))})}for(let{id:p,dir:y,at:h}of g.sort((m,w)=>w.at-m.at||m.id.localeCompare(w.id))){let m={};for(let O of rc){let S=await Jn(ce(y,O),n.fileChars);S&&(m[O]=S)}let w=[];if(await Kn(ce(y,"LOG")))for(let O of(await ct(ce(y,"LOG"),400)).filter(S=>/^\d{4}-\d{2}-\d{2}\.md$/.test(S)&&S.slice(0,10)>=o&&S.slice(0,10)<=mt(e))){let S=await Jn(ce(y,"LOG",O),n.logChars);S&&w.push({date:O.slice(0,10),text:S})}let _=(await fn(ce(y,".memory-dream.json")))?.last,$=await fc(y),R=await bh(y,n.fileChars);!Object.keys(m).length&&!w.length&&!$&&!R||l(i.agents,{id:p,updatedAt:h?new Date(h).toISOString():null,config:R,state:$,dream:_&&typeof _=="object"?{state:le(_.state,32),startedAt:le(_.startedAt,40),finishedAt:le(_.finishedAt,40),calls:typeof _.calls=="number"?_.calls:void 0,detail:typeof _.detail=="string"?ut(dt(_.detail),n.detailChars):void 0}:void 0,files:Object.keys(m).length?m:void 0,log:w.length?w:void 0})}return i}async function _c(t){let e=(await fn(ce(t,"tangu","device.json")))?.deviceId;return typeof e=="string"&&/^[A-Za-z0-9_-]{1,64}$/.test(e)?e:`h${Ap("sha256").update(gc()).digest("hex").slice(0,8)}`}async function vh(t){let{home:e}=t,n=ce(e,"tangu"),r=t.now??new Date,s=i=>t.since?.[i]??at(r),o=ch(t.engineLogs);return dt({schema:4,collectedAt:r.toISOString(),app:{version:t.appVersion,platform:process.platform,arch:process.arch,os:Np(),electron:process.versions.electron??null,node:process.versions.node,locale:Intl.DateTimeFormat().resolvedOptions().locale,timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,home:mc(e),cloudUrl:t.cloudUrl},device:{id:await _c(e),name:gc()},system:await lh(e),config:rh(await fn(ce(e,"config.json"))),agents:await ac(ce(n,"agents")),teams:await ac(ce(n,"teams")),plugins:{desktop:await lc(ce(e,"plugins")),engine:await lc(ce(n,"plugins"))},inventory:{skills:await ct(ce(n,"skills")),spaces:await ct(ce(e,"spaces")),themes:await ct(ce(e,"themes"))},...t.activity?{...await oh(ce(e,"activity"),r,s("activity")),activitySince:new Date(s("activity")).toISOString()}:{},...t.sessions?{...await ih(e,r,wc,s("sessions")),sessionsSince:new Date(s("sessions")).toISOString()}:{},...(typeof t.memory=="function"?t.memory():t.memory)===!0?{memory:await Sh(e,r)}:{},...await ah(e,r),runsSince:new Date(at(r)).toISOString(),...o?{engine:o}:{},sync:{content:mh(t.contentSync),legacy:yh(t.engineLogs)}})}function Cc(t,e={}){let n=e.now??(()=>new Date),r=e.remoteFor??(R=>Ir({baseUrl:R.cloudUrl,vault:Dr,getToken:()=>R.token})),s=e.policyFor??Io,o=()=>ce(t.homeDir(),"extend-diagnostics.json"),i=()=>{let R=O=>O&&typeof O=="object"?O:{};try{let O=JSON.parse(Rp(o(),"utf8"));return{accounts:R(O?.accounts),sent:R(O?.sent)}}catch{return{accounts:{},sent:{}}}},a=()=>i().accounts,l=(R,O,S)=>{let C=i();C.accounts[R]={...C.accounts[R],...O},Object.assign(C.sent,S),Tp(t.homeDir(),{recursive:!0});let E=`${o()}.${process.pid}.tmp`;Dp(E,JSON.stringify(C,null,2),{encoding:"utf8",mode:384}),Ip(E,o())},c=()=>{let R=t.readCreds();return R.token&&R.cloudUrl?t.accountId():null},u=()=>{let R=c(),O=R?a()[R]??{}:{},S=Wn(O.policy);return{signedIn:!!R,enabled:O.enabled===!0,activity:O.activity!==!1,sessions:O.sessions??O.enabled!==!0,memory:O.memory??O.enabled!==!0,lastUploadAt:O.lastUploadAt??null,lastError:O.lastError??null,retainDays:Xr,mode:S.mode,intervalHours:S.intervalHours}},f=()=>{try{return uc(t)?t.diagnosticLogs():null}catch{return null}},g=null,p=new Map,y=async()=>{let R=c();if(!R)return!1;if(g)return g.id===R?g.done:(await g.done,y());let O={...t.readCreds()},S=n(),C=i(),E=C.accounts[R],I=O.cloudUrl.replace(/\/+$/,""),U=xo(E?.file,C.sent[I]??{},S),M=(async()=>{try{let V=await vh({home:t.homeDir(),appVersion:t.appVersion(),cloudUrl:O.cloudUrl,activity:E?.activity!==!1,sessions:E?.sessions===!0,now:S,since:U,engineLogs:f(),contentSync:Zl(),memory:()=>{let ge=c()===R?a()[R]:void 0;return ge?.enabled===!0&&ge.memory===!0}}),Z=await _c(t.homeDir()),re=a()[R];if(c()!==R||re?.enabled!==!0)return!1;if(re.activity===!1)for(let ge of["activity","activityTruncated","activityError","activitySince"])delete V[ge];if(re.sessions!==!0)for(let ge of["sessions","sessionsTruncated","sessionsError","sessionsSince"])delete V[ge];re.memory!==!0&&delete V.memory;let se=[],ee=Fp(V,se);if(!ee)throw new Error("snapshot too large");await To(r(O),Z,ee,S),p.delete(R);let Q=Ao(i().sent[I]??{},E?.file,U,S,V,se);return l(R,{lastUploadAt:n().getTime(),lastError:void 0,file:Q.file},{[I]:Q.sent}),t.log(`[forsion-extend] diagnostics uploaded (${ee.length} bytes)`),!0}catch(V){p.set(R,n().getTime());let Z=String(V?.message||V).slice(0,300);try{l(R,{lastError:Z})}catch{}return t.log(`[forsion-extend] diagnostics upload failed: ${Z}`),!1}finally{g=null}})();return g={id:R,done:M},M},h=async()=>{try{let R=c();if(!R||a()[R]?.enabled!==!0)return;let O=await s({...t.readCreds()}),S=c()===R?a()[R]:void 0;if(S?.enabled!==!0)return;O&&(O.mode!==S.policy?.mode||O.intervalHours!==S.policy?.intervalHours)&&l(R,{policy:{mode:O.mode,intervalHours:O.intervalHours}}),O&&S.requestSeen===void 0&&l(R,{requestSeen:O.requestedAt});let C=O??{...Wn(S.policy),requestedAt:0},E=C.requestedAt>(S.requestSeen??C.requestedAt),I=S.lastUploadAt??0,U=!I||C.mode==="scheduled"&&n().getTime()-I>=C.intervalHours*yc;if(!E&&!U||n().getTime()-(p.get(R)??-tc)<tc)return;await y()&&E&&l(R,{requestSeen:C.requestedAt})}catch(R){t.log(`[forsion-extend] diagnostics tick failed: ${String(R?.message||R)}`)}},m=Promise.resolve(),w={ok:!1,error:"untrusted"};t.handle("diagnostics:get",R=>t.isTrustedSender(R)?u():w),t.handle("diagnostics:set",(R,O)=>{if(!t.isTrustedSender(R))return w;let S=c();if(!S)return u();let C={};typeof O?.enabled=="boolean"&&(C.enabled=O.enabled),C.enabled&&(C.requestSeen=void 0),typeof O?.activity=="boolean"&&(C.activity=O.activity),typeof O?.sessions=="boolean"&&(C.sessions=O.sessions),typeof O?.memory=="boolean"&&(C.memory=O.memory);let E=a()[S];for(let I of["sessions","memory"])C[I]!==void 0||E?.[I]!==void 0||(E?.enabled===!0?C[I]=!1:C.enabled&&(C[I]=!0));return l(S,C),C.enabled&&(p.delete(S),m=Promise.all([m,h()]).then(()=>{})),u()}),t.handle("diagnostics:uploadNow",async R=>t.isTrustedSender(R)?(u().enabled&&await y(),u()):w);let _=setTimeout(()=>void h(),Lp),$=setInterval(()=>void h(),Up);return _.unref?.(),$.unref?.(),t.log(`[forsion-extend] diagnostics registered${uc(t)?"":" (host has no diagnosticLogs: snapshots carry no engine log)"}`),Object.assign(()=>{clearTimeout(_),clearInterval($)},{tick:h,settled:()=>m})}import{randomUUID as Nc}from"node:crypto";import{appendFileSync as Ph,existsSync as $h,mkdirSync as qo,readFileSync as jc,renameSync as Fc,rmSync as Wo,statSync as Mh,writeFileSync as Lc}from"node:fs";import{lstat as Bc}from"node:fs/promises";import{homedir as Nh,release as jh}from"node:os";import{join as gn}from"node:path";var Zn={$comment:"\u5E2E\u52A9\u6539\u8FDB Forsion(\u533F\u540D\u9065\u6D4B)\u4E8B\u4EF6\u767D\u540D\u5355 v2(v1 \u539F\u6837\u4FDD\u7559,v2 \u53EA\u52A0\u4E8B\u4EF6\u4E0E\u5B57\u6BB5;\u5951\u7EA6\u89C1\u540C\u76EE\u5F55 contract.md \xA76\u2013\xA714)\u3002\u6B63\u5178\u5728\u4ED3\u6839 docs/ToBeImproved/\u9ED8\u8BA4\u6570\u636E\u91C7\u96C6\u65B9\u6848_2026-10-28/telemetry-schema.json;server(src/config/telemetry-schema.json)\u4E0E Forsion-Extend(src/core/telemetry-schema.json)\u5404\u5B58\u4E00\u4EFD\u539F\u6837\u526F\u672C,\u6539\u4E00\u5904\u4E09\u5904\u540C\u6539,\u5E76\u540C\u6B65\u9690\u79C1\u653F\u7B56\u300C\u6539\u8FDB\u6570\u636E\u300D\u4E00\u8282\u3002\u7C7B\u578B:int = 0..2147483647 \u7684\u6574\u6570;bool;enum = \u53EA\u80FD\u53D6\u5217\u51FA\u7684\u503C;id = \u5339\u914D ^[A-Za-z0-9._:/@+-]{1,max}$ \u7684\u77ED\u4E32;text = \u81EA\u7531\u6587\u672C,\u5FC5\u987B\u5148\u8FC7 sanitize \u518D\u622A\u5230 max\u3002\u4E0D\u5728\u8868\u91CC\u7684\u4E8B\u4EF6\u4E0E\u5B57\u6BB5\u4E00\u5F8B\u4E22\u3002",version:2,limits:{maxBatchBytes:65536,maxEvents:200},envelope:{installId:{type:"uuid"},app:{type:"enum",values:["desktop","web","mobile"]},appVersion:{type:"id",max:40},coreVersion:{type:"id",max:40},channel:{type:"enum",values:["stable","beta"]},os:{type:"enum",values:["darwin","win32","linux","android","ios","other"]},osVersion:{type:"id",max:40},arch:{type:"enum",values:["arm64","x64","ia32","other"]},locale:{type:"enum",values:["zh","en"]},region:{type:"enum",values:["CN","other"]}},eventFields:{event:{type:"enum",values:["crash","agent_run","tool_call","perf","feature","approval","plugin_install","plugin_deps","plugin_lifecycle","plugin_load","update","onboarding","guide_tip","command_use","app_counts","sync_health","daily_muse","daily_muse_card","daily_memory","daily_judge","daily_human"]},ts:{type:"iso-time"},sessionId:{type:"uuid"}},events:{crash:{process:{type:"enum",values:["main","renderer","engine","plugin-host","extend","other"]},errorName:{type:"id",max:60},stack:{type:"stack",max:4e3},uptimeS:{type:"int"},exitCode:{type:"int"},reason:{type:"enum",values:["exception","rejection","crashed","oom","killed","abnormal-exit","launch-failed","integrity-failure","other"]},pluginId:{type:"id",max:64}},agent_run:{modelId:{type:"id",max:80},providerKind:{type:"enum",values:["forsion","codex","byok","local","other"]},mode:{type:"enum",values:["chat","agent","muse","historian","team","task","other"]},steps:{type:"int"},llmCalls:{type:"int"},tokensIn:{type:"int"},tokensOut:{type:"int"},tokensCached:{type:"int"},retries:{type:"int"},durationMs:{type:"int"},outcome:{type:"enum",values:["done","error","aborted","other"]},errorClass:{type:"enum",values:["timeout","rate_limit","auth","network","context_length","upstream","tool","aborted","other"]},agentRole:{type:"enum",values:["xyra","aria","recita","coding","muse","historian","custom"]},recallEntries:{type:"int"},recallHistory:{type:"int"},recallTruncated:{type:"bool"},memoryTokens:{type:"int"},humanTokens:{type:"int"},profileTokens:{type:"int"},projectTokens:{type:"int"}},tool_call:{tool:{type:"id",max:80},calls:{type:"int"},failures:{type:"int"},totalMs:{type:"int"},maxMs:{type:"int"},runOutcome:{type:"enum",values:["done","error","aborted","other"]},toolSource:{type:"enum",values:["builtin","mcp","plugin","other"]}},perf:{kind:{type:"enum",values:["startup","hourly"]},startupMs:{type:"int"},engineReadyMs:{type:"int"},rssMb:{type:"int"},heapMb:{type:"int"},longTasks:{type:"int"}},feature:{name:{type:"enum",values:["space_open","view_open","plugin_open","setting_change"]},kind:{type:"id",max:60},id:{type:"id",max:80},key:{type:"id",max:80},value:{type:"id",max:40}},approval:{tool:{type:"id",max:80},toolSource:{type:"enum",values:["builtin","mcp","plugin","other"]},reasonKind:{type:"enum",values:["custom-ask","escalate","mode","protected","control","always","other"]},mode:{type:"enum",values:["readonly","auto-edit","full-auto","custom","other"]},asked:{type:"int"},approved:{type:"int"},rejected:{type:"int"},expired:{type:"int"},decideSecTotal:{type:"int"},remoteAnswers:{type:"int"}},plugin_install:{id:{type:"id",max:80},entry:{type:"enum",values:["store","chat-card","muse-card","plugin-onboarding","deps","other"]},kind:{type:"enum",values:["plugin","skill","agent","space","theme","amadeus-plugin","other"]},source:{type:"enum",values:["github","npm","zip","other"]},stage:{type:"enum",values:["resolve","download","install","activate","done"]},outcome:{type:"enum",values:["done","error","canceled"]},errorClass:{type:"enum",values:["timeout","network","http","too-large","not-zip","integrity","identity","version","min-app","platform","deps","builtin","activate","disk","other"]},durationMs:{type:"int"},sizeKb:{type:"int"},restart:{type:"bool"}},plugin_deps:{total:{type:"int"},installed:{type:"int"},failedAt:{type:"int"},outcome:{type:"enum",values:["ready","not-ready","not-running","failed"]}},plugin_lifecycle:{id:{type:"id",max:80},action:{type:"enum",values:["uninstall","enable","disable","blocked"]},blockedReason:{type:"enum",values:["min-app","api","invalid","dev-fileext","deps","other"]},daysSinceInstall:{type:"int"}},plugin_load:{id:{type:"id",max:80},outcome:{type:"enum",values:["ok","error"]},activateMs:{type:"int"}},update:{target:{type:"enum",values:["app","engine","ui","builtin-plugin","store-plugin","first-boot-prefetch"]},id:{type:"id",max:80},outcome:{type:"enum",values:["available","not-available","staged","applied","current","error","incompatible","rolled-back","timeout","skipped"]},errorClass:{type:"enum",values:["network","http","integrity","signature","version","identity","incompatible","disk","other"]}},onboarding:{mode:{type:"enum",values:["full","returning","brief","update"]},outcome:{type:"enum",values:["finish","skip","error-skip"]},screens:{type:"int"},backJumps:{type:"int"},msStart:{type:"int"},msTheme:{type:"int"},msYou:{type:"int"},msTeam:{type:"int"},msWelcome:{type:"int"},signedIn:{type:"bool"},syncNotes:{type:"bool"},syncAgents:{type:"bool"},syncPlugins:{type:"bool"},addedAgent:{type:"bool"},museOn:{type:"bool"},computerHistoryOn:{type:"bool"},youWritten:{type:"bool"}},guide_tip:{pluginId:{type:"id",max:80},tipId:{type:"id",max:60},result:{type:"enum",values:["ok","learned","mute","gone","missing","replaced","closed"]}},command_use:{id:{type:"id",max:80},source:{type:"enum",values:["palette","hotkey","ribbon","agent","other"]},n:{type:"int"}},app_counts:{achChatSend:{type:"int"},achChatGroup:{type:"int"},achNoteCreate:{type:"int"},achNoteWikilink:{type:"int"},achNoteCanvas:{type:"int"},achBaseCreate:{type:"int"},achSpaceSave:{type:"int"},achSpaceSwitch:{type:"int"},achAgentCreate:{type:"int"},achAutomationCreate:{type:"int"},achMuseOpen:{type:"int"},achComputerUse:{type:"int"},achMarketInstall:{type:"int"},achThemeChange:{type:"int"},achTodoDone:{type:"int"},achCalendarEvent:{type:"int"},achAccountLogin:{type:"int"},achImageGenerate:{type:"int"},achDrawingCreate:{type:"int"},achMiniOpen:{type:"int"},achSpecialEnable:{type:"int"},chatStop:{type:"int"},chatRegenerate:{type:"int"},chatEditResend:{type:"int"},chatTruncateResend:{type:"int"},chatRetry:{type:"int"},chatRewind:{type:"int"},chatBranch:{type:"int"},chatSteer:{type:"int"},chatSteerWithdraw:{type:"int"},chatCompact:{type:"int"},chatRetryFailed:{type:"int"},searchOpen:{type:"int"},searchPick:{type:"int"},searchCloseEmpty:{type:"int"},providerLoginOk:{type:"int"},providerLoginFail:{type:"int"},byokSave:{type:"int"},byokImport:{type:"int"},byokImportStale:{type:"int"},byokDelete:{type:"int"},connTestOk:{type:"int"},connTestFail:{type:"int"},connTestAuthRejected:{type:"int"},modelSwitchUser:{type:"int"},modelSwitchRemember:{type:"int"},engineDefaultModelSet:{type:"int"},homeWidgetAdd:{type:"int"},homeWidgetRemove:{type:"int"},homeWidgetMove:{type:"int"},openNote:{type:"int"},openDatabase:{type:"int"},openDashboard:{type:"int"},openPdf:{type:"int"},openBoard:{type:"int"},openPluginFile:{type:"int"},openOther:{type:"int"}},sync_health:{system:{type:"enum",values:["vault","content","remote"]},day:{type:"id",max:10},cycles:{type:"int"},cycleMsTotal:{type:"int"},errAuth:{type:"int"},errOffline:{type:"int"},errVaultMissing:{type:"int"},errScan:{type:"int"},errMirrorMissing:{type:"int"},errHttp:{type:"int"},errTimeout:{type:"int"},errBlocked:{type:"int"},errOther:{type:"int"},conflicts:{type:"int"},skippedTooLarge:{type:"int"},skippedNotFound:{type:"int"},skippedExists:{type:"int"},skippedOther:{type:"int"},massDeleteGuard:{type:"int"},uploads:{type:"int"},downloads:{type:"int"}},daily_muse:{day:{type:"id",max:10},cyclesRule:{type:"int"},cyclesSchedule:{type:"int"},cyclesHeartbeat:{type:"int"},cyclesRunEnd:{type:"int"},cyclesModeAsk:{type:"int"},cyclesModeAgent:{type:"int"},cyclesModeAuto:{type:"int"},cyclesDone:{type:"int"},cyclesError:{type:"int"},cyclesAborted:{type:"int"},cyclesSilent:{type:"int"},cycleTokens:{type:"int"},cycleMs:{type:"int"},producedCards:{type:"int"},producedDms:{type:"int"},producedTodos:{type:"int"},producedStarters:{type:"int"},inboxMarked:{type:"int"},inboxUnmarked:{type:"int"},skipNoModel:{type:"int"},skipOutsideHours:{type:"int"},skipUserActive:{type:"int"},skipNothingDue:{type:"int"},skipAlreadyRunning:{type:"int"},skipBudgetBillable:{type:"int"},skipBudgetGross:{type:"int"},skipRestartCap:{type:"int"},skipRemoteLock:{type:"int"},skipSleepCleared:{type:"int"},dmProactive:{type:"int"},dmTodo:{type:"int"},dmApproval:{type:"int"},dmCard:{type:"int"},dmNotice:{type:"int"},dmRemind:{type:"int"},dmSuppressed:{type:"int"},dmAwaitingUser:{type:"int"},dmReadIn24h:{type:"int"},dmRepliedIn24h:{type:"int"},feedbackUp:{type:"int"},feedbackDown:{type:"int"},feedbackText:{type:"int"},todoCreated:{type:"int"},todoApproved:{type:"int"},todoInjected:{type:"int"},todoDone:{type:"int"},todoDismissed:{type:"int"},starterCreated:{type:"int"},starterUsed:{type:"int"},starterDismissed:{type:"int"},starterMuted:{type:"int"},ruleCreatedMuse:{type:"int"},ruleCreatedUser:{type:"int"},ruleObserveForced:{type:"int"},rulePromoted:{type:"int"},ruleExtended:{type:"int"},rulePaused:{type:"int"},ruleObservedHits:{type:"int"},approvalByAgent:{type:"int"},approvalUserApproved:{type:"int"},approvalUserRejected:{type:"int"},introAnswered:{type:"int"},introSkipped:{type:"int"},introWhenAnytime:{type:"int"},introWhenDaytime:{type:"int"},introWhenOpen:{type:"int"},introPaceAsNeeded:{type:"int"},introPaceDaily:{type:"int"},introPaceFree:{type:"int"},introFocusSchedule:{type:"int"},introFocusStudy:{type:"int"},introFocusProjects:{type:"int"},introFocusInbox:{type:"int"},introFocusCustom:{type:"int"},summarySent:{type:"int"},summaryProposed:{type:"int"},summaryAdopted:{type:"int"},summaryAskUpgrade:{type:"int"},sleepSet:{type:"int"},digestSent:{type:"int"},gEnabled:{type:"int"},gDaysEnabled:{type:"int"},gModeAsk:{type:"int"},gModeAgent:{type:"int"},gModeAuto:{type:"int"},gNotifyDigest:{type:"int"},gHeartbeatMin:{type:"int"},gMaxDmPerDay:{type:"int"},gOnboardingDay:{type:"int"},gRulesObserving:{type:"int"},gRulesEnabled:{type:"int"}},daily_muse_card:{day:{type:"id",max:10},cardKind:{type:"enum",values:["plugin","feature","inbox-ask","inbox-list","channel","settings","intro","summary","rule","rule-observed"]},created:{type:"int"},accept:{type:"int"},observe:{type:"int"},edit:{type:"int"},dismiss:{type:"int"},open:{type:"int"},apply:{type:"int"},yes:{type:"int"},later:{type:"int"},ignore:{type:"int"},ack:{type:"int"},item:{type:"int"},enable:{type:"int"},extend:{type:"int"},pause:{type:"int"},answer:{type:"int"},skip:{type:"int"},ok:{type:"int"},remove:{type:"int"},installed:{type:"int"},gone:{type:"int"},dismissIrrelevant:{type:"int"},dismissTiming:{type:"int"},dismissFrequent:{type:"int"},dismissKnown:{type:"int"},decideSecTotal:{type:"int"},decidedRemote:{type:"int"},gPendingOver3d:{type:"int"}},daily_memory:{day:{type:"id",max:10},agentRole:{type:"enum",values:["xyra","aria","recita","coding","muse","historian","custom"]},addAgent:{type:"int"},addProject:{type:"int"},addPerson:{type:"int"},updateAgent:{type:"int"},updateProject:{type:"int"},updatePerson:{type:"int"},forgetAgent:{type:"int"},forgetProject:{type:"int"},forgetPerson:{type:"int"},moveScope:{type:"int"},srcExplicit:{type:"int"},srcHistorian:{type:"int"},srcDream:{type:"int"},srcManual:{type:"int"},srcRestore:{type:"int"},srcExternalEdit:{type:"int"},srcSync:{type:"int"},srcMigration:{type:"int"},errFull:{type:"int"},errVersionConflict:{type:"int"},errPortraitFull:{type:"int"},userEditAgentWritten7d:{type:"int"},userForgetAgentWritten7d:{type:"int"},userRestoreDreamRetired:{type:"int"},userEdit:{type:"int"},userForget:{type:"int"},userAdd:{type:"int"},userForgetWrong:{type:"int"},userForgetStale:{type:"int"},userForgetUnwanted:{type:"int"},userForgetDuplicate:{type:"int"},retellExisting:{type:"int"},retellForgotten:{type:"int"},candidatesAdded:{type:"int"},dreamAuto:{type:"int"},dreamManual:{type:"int"},dreamArchive:{type:"int"},dreamCompleted:{type:"int"},dreamSkipped:{type:"int"},dreamFailed:{type:"int"},dreamCancelled:{type:"int"},dreamCalls:{type:"int"},dreamSources:{type:"int"},dreamGroups:{type:"int"},dreamMerges:{type:"int"},dreamDiscarded:{type:"int"},dreamToPortrait:{type:"int"},dreamPending:{type:"int"},dreamDeferred:{type:"int"},dreamVerifyFail:{type:"int"},dreamRetried:{type:"int"},dreamMs:{type:"int"},harnessUpsertAgent:{type:"int"},harnessUpsertHistorian:{type:"int"},harnessUpsertMuse:{type:"int"},harnessUpsertUser:{type:"int"},harnessDelete:{type:"int"},harnessRollback:{type:"int"},gEntries:{type:"int"},gCharsPct:{type:"int"},gTombstones:{type:"int"},gCandidatesPending:{type:"int"},gCandidatesOldestDays:{type:"int"},gHarnessEntries:{type:"int"}},daily_judge:{day:{type:"id",max:10},rounds:{type:"int"},roundsIndependent:{type:"int"},roundsAssist:{type:"int"},roundsFork:{type:"int"},isolationSkips:{type:"int"},memCandidates:{type:"int"},projCandidatesAuto:{type:"int"},projCandidatesQueued:{type:"int"},projAdopted:{type:"int"},projDismissed:{type:"int"},projForgotten:{type:"int"},projRestored:{type:"int"},projCompacted:{type:"int"},harnessCandidatesAuto:{type:"int"},harnessCandidatesQueued:{type:"int"},signalStop:{type:"int"},signalToolLoop:{type:"int"},signalNudge:{type:"int"},signalCorrectionDecision:{type:"int"},signalCorrectionLexical:{type:"int"},titleUpdated:{type:"int"},summaryUpdated:{type:"int"},iconUpdated:{type:"int"}},daily_human:{day:{type:"id",max:10},wAgentShared:{type:"int"},wAgentAgent:{type:"int"},wAgentProject:{type:"int"},wAgentPortrait:{type:"int"},wAgentAgentMd:{type:"int"},wAgentMemory:{type:"int"},wUserShared:{type:"int"},wUserAgent:{type:"int"},wUserProject:{type:"int"},wUserPortrait:{type:"int"},wUserAgentMd:{type:"int"},wUserMemory:{type:"int"},srcRemember:{type:"int"},srcDream:{type:"int"},srcMove:{type:"int"},srcPromote:{type:"int"},srcUser:{type:"int"},userUndoAgentWrite7d:{type:"int"},moveScan:{type:"int"},moveMoved:{type:"int"},moveKept:{type:"int"},moveUndo:{type:"int"},promoteToAgentMd:{type:"int"},coldstartAgents:{type:"int"},coldstartPersonWrites:{type:"int"},coldstartRelearned:{type:"int"},mirrorConflicts:{type:"int"},syncConflictCopies:{type:"int"},gHumanMdEntries:{type:"int"},gAgentMdEntries:{type:"int"},gPortraitEntries:{type:"int"},gMemoryEntries:{type:"int"},gCalendarRows:{type:"int"},gAgentsWithHumanMd:{type:"int"},gAgentsTotal:{type:"int"}}}};var Eh=Zn.events,_h=Zn.envelope,Uo=Zn.limits,Tc=Zn.version,Ch=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,xh=/^[A-Za-z0-9._:/@+-]+$/,Rc=t=>typeof t=="string"&&Ch.test(t),xc=/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,Ah=[[/\/Users\/[^/\s]+\//gi,"~/"],[/\/home\/[^/\s]+\//gi,"~/"],[/[a-z]:\\Users\\[^\\\s]+\\/gi,"~\\"],[/~([/\\])[^\s"'`」:()]+/g,"~$1\u2026"],[/\/Volumes\/[^\s"'`」:()]+/g,"/Volumes/\u2026"],[/\b([d-z]):\\[^\s"'`」:()]+/gi,"$1:\\\u2026"],[/forsion-agent-space\/[^/\s]+\//g,"forsion-agent-space/\u2026/"],[/"[^"]{1,200}"/g,'"\u2026"'],[/'[^']{1,200}'/g,"'\u2026'"],[/`[^`]{1,200}`/g,"`\u2026`"],[/「[^「」]{1,200}」/g,"\u300C\u2026\u300D"],[/(https?:\/\/[^\s?#"'`」]+)[?#][^\s"'`」]*/gi,"$1"],[/sk-[A-Za-z0-9_-]{10,}/g,"[redacted]"],[/Bearer\s+\S+/gi,"[redacted]"],[/[0-9a-f]{32,}/gi,"[redacted]"],[/[A-Za-z0-9+/]{40,}={0,2}/g,"[redacted]"],[/[A-Za-z0-9_-]{40,}/g,"[redacted]"],[/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,"[email]"]],Ic=t=>Ah.reduce((e,[n,r])=>e.replace(n,r),t);function Ac(t,e,n){let r=t.slice(0,2e4).replace(/\u0000/g,"").replace(xc,"\uFFFD");return n&&n.length>3&&(r=r.split(n).join("~")),r=Ic(r),(r.length>e?r.slice(0,e):r).replace(xc,"\uFFFD")}var Th=/^pr-[a-f0-9]{48}$/,Rh=/^market-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,Ih=t=>Th.test(t)||Rh.test(t)||Ic(t)===t;function Dh(t){if(typeof t!="string")return"";let e=t.search(/^\s+at /m);return e<0?"":t.slice(e)}function Lo(t,e,n){switch(t.type){case"enum":return typeof e=="string"&&t.values.includes(e)?e:void 0;case"int":return typeof e=="number"&&Number.isFinite(e)&&e>=0?Math.min(Math.round(e),2147483647):void 0;case"bool":return typeof e=="boolean"?e:void 0;case"uuid":return Rc(e)?e.toLowerCase():void 0;case"iso-time":return typeof e=="string"&&!Number.isNaN(Date.parse(e))?new Date(e).toISOString():void 0;case"id":return typeof e=="string"&&e.length<=t.max&&xh.test(e)&&Ih(e)?e:void 0;case"text":return typeof e=="string"&&e?Ac(e,t.max,n):void 0;case"stack":{let r=Dh(e);return r?Ac(r,t.max,n):void 0}}}function zt(t,e){let n=typeof t?.event=="string"?Eh[t.event]:void 0;if(!n)return null;let r={},s=t.props&&typeof t.props=="object"?t.props:{};for(let[i,a]of Object.entries(n)){let l=Lo(a,s[i],e);l!==void 0&&(r[i]=l)}let o=Lo({type:"iso-time"},t.ts);return{event:t.event,ts:o??new Date().toISOString(),...Rc(t.sessionId)?{sessionId:t.sessionId.toLowerCase()}:{},props:r}}function Dc(t){let e={};for(let[n,r]of Object.entries(_h)){if(n==="installId")continue;let s=Lo(r,t[n]);e[n]=typeof s=="string"?s:null}return e}function Oc(t,e){if(e==="aborted")return"aborted";if(!t)return;let n=t.toLowerCase();return/abort|cancel/.test(n)?"aborted":/timeout|timed out|etimedout/.test(n)?"timeout":/\b429\b|rate.?limit|too many requests|quota/.test(n)?"rate_limit":/\b40[13]\b|unauthori[sz]ed|forbidden|invalid api key|authentication/.test(n)?"auth":/context.{0,20}(length|window|too long)|maximum context|too many tokens|prompt is too long/.test(n)?"context_length":/econn|enotfound|eai_again|socket|network|fetch failed|getaddrinfo/.test(n)?"network":/\b5\d\d\b|upstream|bad gateway|overloaded|service unavailable/.test(n)?"upstream":/tool/.test(n)?"tool":"other"}function Pc(t){return t==="done"?"done":t==="failed"?"error":t==="aborted"?"aborted":"other"}function Ho(t){return t?/^pr-/.test(t)?"forsion":/^codex\//.test(t)?"codex":/^(?:ollama|lmstudio|local)[/:]/i.test(t)?"local":"byok":"other"}var Oh=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;function $c(t){if(typeof t!="string"||!t)return;let e=Ho(t);if(e==="forsion"||e==="codex")return t;let n=t.slice(t.lastIndexOf("/")+1);return Oh.test(n)?n:void 0}function zo(t){return t==="builtin"||t==="mcp"||t==="plugin"?t:"other"}function Bo(t,e){return e==="plugin"?"plugin":e==="mcp"||t.startsWith("mcp__")?"mcp":t}function Mc(t){return{user:"chat",agent:"agent",muse:"muse",historian:"historian",teamwork:"team",discussion:"team",subagent:"task"}[t||"user"]??"other"}var Fh=10*6e4,Lh=6e4,Uh=50,Uc=1024*1024,Hh=168*36e5,Hc=15e3,zh=200,Bh=2e3,Vo=7,qh=5e3,zc=864e5,Wh=new Set(["crash","perf","feature","plugin_install","plugin_deps","plugin_lifecycle","plugin_load","update","onboarding","guide_tip","command_use","app_counts"]),Yo={daily_muse:null,daily_muse_card:"cardKind",daily_memory:"agentRole",daily_judge:null,daily_human:null},Vh=new Set(["custom-ask","escalate","mode","protected","control","always"]),Yh=new Set(["readonly","auto-edit","full-auto","custom"]),qc=t=>new Date(t).toISOString().slice(0,19).replace("T"," "),Go=t=>({at:qc(t),id:"~"}),hn=t=>typeof t=="string"?Date.parse(`${t.replace(" ","T")}Z`):NaN;async function Gh(t,e,n,r){let s=gn(t,"tangu","state.db");if(!await Bc(s).then(i=>i.isFile(),()=>!1))return{events:[],cursor:e};let o;try{let{DatabaseSync:i}=await import("node:sqlite");o=new i(s,{readOnly:!0}),o.exec("PRAGMA busy_timeout = 1500");let a=o.prepare(`SELECT r.id, r.status, r.current_step, r.model_id, substr(r.error, 1, 2000) AS error, r.created_at, r.updated_at, s.kind
254
+ 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=h=>typeof h=="number"&&Number.isFinite(h)&&h>0?h:0,d=h=>h||void 0,g=[],p=0,y=c.length>n.runs;for(let h of c.slice(0,n.runs)){let m={llmCalls:0,prompt:0,completion:0,cached:0,reasoning:0,llmMs:0,ttftMaxMs:0,requestMaxBytes:0},w=new Map,_=[],M=0,R=l.all(h.id,n.events+1),O=R.length>n.events;for(let E of R.slice(0,n.events))if(E.type==="usage")m.llmCalls++,m.prompt+=u(E.prompt),m.completion+=u(E.completion),m.cached+=u(E.cached),m.reasoning+=u(E.reasoning),m.llmMs+=u(E.llm_ms),m.ttftMaxMs=Math.max(m.ttftMaxMs,u(E.ttft_ms)),m.requestMaxBytes=Math.max(m.requestMaxBytes,u(E.request_bytes));else if(E.type==="tool_result"){let I=ce(E.name,80)??"?",U=w.get(I)??(w.size<n.tools?{name:I,n:0,ms:0,maxMs:0}:void 0);if(!U){O=!0;continue}w.set(I,U),U.n++,E.failed&&(U.errors=(U.errors??0)+1),U.ms+=u(E.ms),U.maxMs=Math.max(U.maxMs,u(E.ms))}else if(E.type==="error"){let I=rs(E.error,n.errorChars);I&&!_.includes(I)&&_.length<3&&_.push(I)}else E.phase==="llm_retry"&&M++;let S={id:ce(h.id,64)??null,session:ce(h.session_id,64)??null,kind:ce(h.kind,16),app:ce(h.app_id,50),model:ce(h.model_id,128),status:ce(h.status,16)??null,error:rs(h.error,n.errorChars),createdAt:ce(h.created_at,40)??null,updatedAt:ce(h.updated_at,40)??null,steps:d(u(h.current_step)),tokens:d(u(h.tokens_total)),retries:d(M),...Object.fromEntries(Object.entries(m).map(([E,I])=>[E,d(I)])),errors:_.length?_:void 0,tools:w.size?[...w.values()]:void 0,partial:O||void 0},C=Buffer.byteLength(JSON.stringify(S));if(p+C>n.totalBytes){y=!0;break}p+=C,g.push(S)}return{runs:g,...y?{runsTruncated:!0}:{}}}catch(i){return{runs:[],runsError:Ht(i)}}finally{try{o?.close()}catch{}}}async function kh(t){let e=s=>Math.round(s/1048576),n=s=>wt(s).then(o=>o.isFile()?o.size:0,()=>0),r=le(t,"tangu","state.db");return{cpus:Gp().length,memTotalMB:e(Xp()),memFreeMB:e(Jp()),diskFreeMB:await Yp(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 yl=t=>typeof t.diagnosticLogs=="function";function Eh(t,e=oh){let n=t?.engine;if(!n||typeof n!="object")return null;let r=(Array.isArray(n.lines)?n.lines:[]).filter(c=>typeof c=="string"&&!!c),s=r.map(c=>rs(c,Fo)??""),o=s.some((c,l)=>c.length>Fo||r[l].length>Xn),i=s.length,a=e;for(;i>0&&Buffer.byteLength(s[i-1])+1<=a;)a-=Buffer.byteLength(s[--i])+1;return i>0&&(o=!0),{state:ce(n.state,32)??null,lastError:rs(n.lastError,Fo)??null,log:s.slice(i).join(`
255
+ `),...o?{logTruncated:!0}:{}}}var Ho={errors:20,errorChars:300,agents:100},_h=t=>Al(xl(t,!1).replace(/[^\s"'`<>()[\]{},;]*\/[^\s"'`<>()[\]{},;]*/g,e=>Lo.test(e)?e:"[path]")),Ch=(t,e=[],n=Ho.errorChars)=>ut(_h(nl(dt(t),e.map(r=>dt(r)))),n)??"",Me=t=>typeof t=="number"&&Number.isFinite(t)&&t>0?Math.round(t):0,ns=t=>typeof t=="number"&&Number.isFinite(t)&&t>0?new Date(t).toISOString():null,Rl=t=>{let e=t&&typeof t=="object"?t:{};return Object.fromEntries(tl.flatMap(n=>Me(e[n])?[[n,Me(e[n])]]:[]))},wl=t=>{let e=t;return e&&typeof e=="object"?{at:ns(e.at),ms:Me(e.ms),completed:e.completed===!0,...Rl(e.counts)}:null},xh=Object.fromEntries(yt.map(t=>[t.path,t.id])),Ah=new Set(["idle","scanning","syncing","paused"]),Th=new Set(["queued","active","done","failed","paused","conflict"]);function Rh(t,e){let n=(Array.isArray(t)?t:[]).filter(a=>!!a&&typeof a.source=="string"&&typeof a.target=="string"),r=a=>a===void 0?null:a==="default"?"shared":a==="off"?"off":e&&a===`device-${e}`?"device":/^device-/.test(a)?"other-device":"unknown",s={other:r(n.find(a=>a.source==="")?.target)};for(let a of yt)s[a.id]=r(cn(a.path,n)?.target);let o={},i={};for(let a of n){if(a.source===""||xh[a.source])continue;let c=Yn(a.source);if(c&&Object.keys(o).length<Ho.agents)o[c]=r(a.target);else if(!c){let l=r(a.target)??"unknown";i[l]=(i[l]??0)+1}}return{...s,agentRules:o,folderRules:i,count:n.length}}function Ih(t){let e=t;if(!e||typeof e!="object")return null;let n=typeof e.deviceId=="string"&&/^[A-Za-z0-9_-]{1,64}$/.test(e.deviceId)?e.deviceId:null,r=e.backlog&&typeof e.backlog=="object"?e.backlog:null,s=r?.jobs&&typeof r.jobs=="object"?Object.fromEntries(Object.entries(r.jobs).filter(([i,a])=>Th.has(i)&&Me(a)).map(([i,a])=>[i,Me(a)])):{},o=e.totals??{};return{deviceId:n,session:e.session===!0,enabled:e.enabled===!0,paused:e.paused===!0,running:e.running===!0,phase:typeof e.phase=="string"&&Ah.has(e.phase)?e.phase:null,revision:Me(e.revision),rules:Rh(e.rules,n),backlog:r?{jobs:s,blocked:Me(r.blocked),pendingUploads:Me(r.pendingUploads),unconfirmed:Me(r.unconfirmed),trash:Me(r.trash),awaitingBytes:Me(r.awaitingBytes),dirty:Me(r.dirty)}:null,archive:e.archive==="running"||e.archive==="done"?e.archive:null,since:ns(e.since),lastRun:wl(e.lastRun),runs:(Array.isArray(e.runs)?e.runs:[]).slice(-20).map(wl).filter(Boolean),totals:{runs:Me(o.runs),completedRuns:Me(o.completedRuns),idleRuns:Me(o.idleRuns),...Rl(o)},errors:(Array.isArray(e.errors)?e.errors:[]).slice(-Ho.errors).flatMap(i=>{if(!i||typeof i!="object"||typeof i.text!="string"||!i.text)return[];let a=Array.isArray(i.paths)?i.paths.filter(c=>typeof c=="string"):[];return[{first:ns(i.first),at:ns(i.at),n:Me(i.n)||1,kind:Fr(i.text)??"other",text:Ch(i.text,a)}]})}}function Dh(t){let e=t?.engine?.lines;if(!Array.isArray(e))return null;let n={lines:0,errorRounds:0,tooLarge:0,overwrites:0,pulledNew:0,conflictCopies:0};for(let r of e){if(typeof r!="string"||!r.includes("[agent sync]"))continue;n.lines++;let s=/已从云端拉取(覆盖|新文件)/.exec(r);if(s){s[1]==="\u8986\u76D6"?n.overwrites++:n.pulledNew++,r.includes("\u672C\u5730\u7248\u672C\u5DF2\u5B58\u4E3A")&&n.conflictCopies++;continue}n.errorRounds++,n.tooLarge+=r.match(/exceeds sync limit/g)?.length??0}return n}function Oh(t,e=ch){let n;try{n=Kr(t)}catch{return{}}return Object.fromEntries(e.flatMap(r=>typeof n[r]=="string"&&n[r]?[[r,n[r]]]:[]))}async function Il(t,e=ah){try{if(!(await wt(t)).isFile())return null;let n=await Sl(t,il.O_RDONLY|(il.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 Jn=async(t,e)=>{let n=await Il(t);return n?ut(dt(n),e):void 0};async function Ph(t,e){let n=await Il(le(t,"config.toml")),r=Object.entries(n?Oh(n):{}).map(([s,o])=>[s,ut(dt(o),e)??""]);return r.length?Object.fromEntries(r):void 0}async function bl(t){let e=await fn(le(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 Mh(t,e,n=ih){let r=le(t,"tangu"),s=p=>wt(p).then(y=>y.isFile()?y.mtimeMs:0,()=>0),o=mt(new Date(at(e))),i={agents:[],teams:[],projects:[],activity:[]},a=n.totalBytes,c=(p,y)=>{let h=Buffer.byteLength(JSON.stringify(y))+1;return h>a?(i.truncated=!0,!1):(a-=h,p.push(y),!0)},l=await Jn(le(r,"USER.md"),n.fileChars);l&&c([],l)&&(i.user=l);let u=le(r,"state.db"),d=await wt(u).then(p=>p.isFile(),p=>p?.code==="ENOENT"?!1:Ht(p));if(typeof d=="string")i.activityError=d;else if(d){let p;try{let{DatabaseSync:y}=await import("node:sqlite");p=new y(u,{readOnly:!0}),p.exec("PRAGMA busy_timeout = 1500");let m=p.prepare(`SELECT agent, action, substr(detail, 1, ${Xn}) AS detail, session_ref, created_at FROM special_agent_log
256
+ WHERE created_at >= ? AND created_at < ? AND (${lh.map(w=>`action GLOB '${w}*'`).join(" OR ")})
257
+ ORDER BY created_at DESC, rowid DESC LIMIT ?`).all(pn(at(e)),pn(e.getTime()),n.activity+1);m.length>n.activity&&(i.truncated=!0);for(let w of m.slice(0,n.activity))if(!c(i.activity,{at:ce(w.created_at,40)??null,agent:ce(w.agent,64)??null,action:ce(w.action,64)??null,detail:typeof w.detail=="string"&&w.detail?ut(dt(w.detail),n.detailChars):void 0,session:ce(w.session_ref,64)}))break}catch(y){i.activityError=Ht(y)}finally{try{p?.close()}catch{}}}for(let p of await lt(le(r,"project-memory"),100)){let y=le(r,"project-memory",p);if(!await Kn(y))continue;let h=await Jn(le(y,"MEMORY.md"),n.fileChars),m=await bl(y);if(!h&&!m)continue;let w=(await fn(le(y,"PROJECT.json")))?.project;if(!c(i.projects,{id:ce(p,64)??null,name:typeof w=="string"?ce(El(w.replace(/[\\/]+$/,"").replace(/\\/g,"/"))):void 0,state:m,memory:h}))break}for(let p of await lt(le(r,"teams"),100)){if(!await Kn(le(r,"teams",p)))continue;let y=await Jn(le(r,"teams",p,"TEAM.md"),n.fileChars);if(y&&!c(i.teams,{id:p,files:{"TEAM.md":y}}))break}let g=[];for(let p of await lt(le(r,"agents"),100)){let y=le(r,"agents",p);await Kn(y)&&g.push({id:p,dir:y,at:Math.max(0,...await Promise.all([...ul,".memory-state.json"].map(h=>s(le(y,h)))))})}for(let{id:p,dir:y,at:h}of g.sort((m,w)=>w.at-m.at||m.id.localeCompare(w.id))){let m={};for(let O of ul){let S=await Jn(le(y,O),n.fileChars);S&&(m[O]=S)}let w=[];if(await Kn(le(y,"LOG")))for(let O of(await lt(le(y,"LOG"),400)).filter(S=>/^\d{4}-\d{2}-\d{2}\.md$/.test(S)&&S.slice(0,10)>=o&&S.slice(0,10)<=mt(e))){let S=await Jn(le(y,"LOG",O),n.logChars);S&&w.push({date:O.slice(0,10),text:S})}let _=(await fn(le(y,".memory-dream.json")))?.last,M=await bl(y),R=await Ph(y,n.fileChars);!Object.keys(m).length&&!w.length&&!M&&!R||c(i.agents,{id:p,updatedAt:h?new Date(h).toISOString():null,config:R,state:M,dream:_&&typeof _=="object"?{state:ce(_.state,32),startedAt:ce(_.startedAt,40),finishedAt:ce(_.finishedAt,40),calls:typeof _.calls=="number"?_.calls:void 0,detail:typeof _.detail=="string"?ut(dt(_.detail),n.detailChars):void 0}:void 0,files:Object.keys(m).length?m:void 0,log:w.length?w:void 0})}return i}async function Dl(t){let e=(await fn(le(t,"tangu","device.json")))?.deviceId;return typeof e=="string"&&/^[A-Za-z0-9_-]{1,64}$/.test(e)?e:`h${Hp("sha256").update(kl()).digest("hex").slice(0,8)}`}async function $h(t){let{home:e}=t,n=le(e,"tangu"),r=t.now??new Date,s=i=>t.since?.[i]??at(r),o=Eh(t.engineLogs);return dt({schema:4,collectedAt:r.toISOString(),app:{version:t.appVersion,platform:process.platform,arch:process.arch,os:Kp(),electron:process.versions.electron??null,node:process.versions.node,locale:Intl.DateTimeFormat().resolvedOptions().locale,timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,home:El(e),cloudUrl:t.cloudUrl},device:{id:await Dl(e),name:kl()},system:await kh(e),config:yh(await fn(le(e,"config.json"))),agents:await hl(le(n,"agents")),teams:await hl(le(n,"teams")),plugins:{desktop:await gl(le(e,"plugins")),engine:await gl(le(n,"plugins"))},inventory:{skills:await lt(le(n,"skills")),spaces:await lt(le(e,"spaces")),themes:await lt(le(e,"themes"))},...t.activity?{...await bh(le(e,"activity"),r,s("activity")),activitySince:new Date(s("activity")).toISOString()}:{},...t.sessions?{...await Sh(e,r,Cl,s("sessions")),sessionsSince:new Date(s("sessions")).toISOString()}:{},...(typeof t.memory=="function"?t.memory():t.memory)===!0?{memory:await Mh(e,r)}:{},...await vh(e,r),runsSince:new Date(at(r)).toISOString(),...o?{engine:o}:{},sync:{content:Ih(t.contentSync),legacy:Dh(t.engineLogs)}})}function Ol(t,e={}){let n=e.now??(()=>new Date),r=e.remoteFor??(R=>Dr({baseUrl:R.cloudUrl,vault:Or,getToken:()=>R.token})),s=e.policyFor??Po,o=()=>le(t.homeDir(),"extend-diagnostics.json"),i=()=>{let R=O=>O&&typeof O=="object"?O:{};try{let O=JSON.parse(Bp(o(),"utf8"));return{accounts:R(O?.accounts),sent:R(O?.sent)}}catch{return{accounts:{},sent:{}}}},a=()=>i().accounts,c=(R,O,S)=>{let C=i();C.accounts[R]={...C.accounts[R],...O},Object.assign(C.sent,S),zp(t.homeDir(),{recursive:!0});let E=`${o()}.${process.pid}.tmp`;Wp(E,JSON.stringify(C,null,2),{encoding:"utf8",mode:384}),qp(E,o())},l=()=>{let R=t.readCreds();return R.token&&R.cloudUrl?t.accountId():null},u=()=>{let R=l(),O=R?a()[R]??{}:{},S=Wn(O.policy);return{signedIn:!!R,enabled:O.enabled===!0,activity:O.activity!==!1,sessions:O.sessions??O.enabled!==!0,memory:O.memory??O.enabled!==!0,lastUploadAt:O.lastUploadAt??null,lastError:O.lastError??null,retainDays:Zr,mode:S.mode,intervalHours:S.intervalHours}},d=()=>{try{return yl(t)?t.diagnosticLogs():null}catch{return null}},g=null,p=new Map,y=async()=>{let R=l();if(!R)return!1;if(g)return g.id===R?g.done:(await g.done,y());let O={...t.readCreds()},S=n(),C=i(),E=C.accounts[R],I=O.cloudUrl.replace(/\/+$/,""),U=Ro(E?.file,C.sent[I]??{},S),$=(async()=>{try{let V=await $h({home:t.homeDir(),appVersion:t.appVersion(),cloudUrl:O.cloudUrl,activity:E?.activity!==!1,sessions:E?.sessions===!0,now:S,since:U,engineLogs:d(),contentSync:ol(),memory:()=>{let ge=l()===R?a()[R]:void 0;return ge?.enabled===!0&&ge.memory===!0}}),Z=await Dl(t.homeDir()),re=a()[R];if(l()!==R||re?.enabled!==!0)return!1;if(re.activity===!1)for(let ge of["activity","activityTruncated","activityError","activitySince"])delete V[ge];if(re.sessions!==!0)for(let ge of["sessions","sessionsTruncated","sessionsError","sessionsSince"])delete V[ge];re.memory!==!0&&delete V.memory;let se=[],ee=Zp(V,se);if(!ee)throw new Error("snapshot too large");await Do(r(O),Z,ee,S),p.delete(R);let Q=Io(i().sent[I]??{},E?.file,U,S,V,se);return c(R,{lastUploadAt:n().getTime(),lastError:void 0,file:Q.file},{[I]:Q.sent}),t.log(`[forsion-extend] diagnostics uploaded (${ee.length} bytes)`),!0}catch(V){p.set(R,n().getTime());let Z=String(V?.message||V).slice(0,300);try{c(R,{lastError:Z})}catch{}return t.log(`[forsion-extend] diagnostics upload failed: ${Z}`),!1}finally{g=null}})();return g={id:R,done:$},$},h=async()=>{try{let R=l();if(!R||a()[R]?.enabled!==!0)return;let O=await s({...t.readCreds()}),S=l()===R?a()[R]:void 0;if(S?.enabled!==!0)return;O&&(O.mode!==S.policy?.mode||O.intervalHours!==S.policy?.intervalHours)&&c(R,{policy:{mode:O.mode,intervalHours:O.intervalHours}}),O&&S.requestSeen===void 0&&c(R,{requestSeen:O.requestedAt});let C=O??{...Wn(S.policy),requestedAt:0},E=C.requestedAt>(S.requestSeen??C.requestedAt),I=S.lastUploadAt??0,U=!I||C.mode==="scheduled"&&n().getTime()-I>=C.intervalHours*_l;if(!E&&!U||n().getTime()-(p.get(R)??-cl)<cl)return;await y()&&E&&c(R,{requestSeen:C.requestedAt})}catch(R){t.log(`[forsion-extend] diagnostics tick failed: ${String(R?.message||R)}`)}},m=Promise.resolve(),w={ok:!1,error:"untrusted"};t.handle("diagnostics:get",R=>t.isTrustedSender(R)?u():w),t.handle("diagnostics:set",(R,O)=>{if(!t.isTrustedSender(R))return w;let S=l();if(!S)return u();let C={};typeof O?.enabled=="boolean"&&(C.enabled=O.enabled),C.enabled&&(C.requestSeen=void 0),typeof O?.activity=="boolean"&&(C.activity=O.activity),typeof O?.sessions=="boolean"&&(C.sessions=O.sessions),typeof O?.memory=="boolean"&&(C.memory=O.memory);let E=a()[S];for(let I of["sessions","memory"])C[I]!==void 0||E?.[I]!==void 0||(E?.enabled===!0?C[I]=!1:C.enabled&&(C[I]=!0));return c(S,C),C.enabled&&(p.delete(S),m=Promise.all([m,h()]).then(()=>{})),u()}),t.handle("diagnostics:uploadNow",async R=>t.isTrustedSender(R)?(u().enabled&&await y(),u()):w);let _=setTimeout(()=>void h(),Qp),M=setInterval(()=>void h(),eh);return _.unref?.(),M.unref?.(),t.log(`[forsion-extend] diagnostics registered${yl(t)?"":" (host has no diagnosticLogs: snapshots carry no engine log)"}`),Object.assign(()=>{clearTimeout(_),clearInterval(M)},{tick:h,settled:()=>m})}import{randomUUID as Bl}from"node:crypto";import{appendFileSync as Yh,existsSync as Gh,mkdirSync as Yo,readFileSync as ql,renameSync as Wl,rmSync as Go,statSync as Jh,writeFileSync as Vl}from"node:fs";import{lstat as Kl}from"node:fs/promises";import{homedir as Kh,release as Xh}from"node:os";import{join as gn}from"node:path";var Zn={$comment:"\u5E2E\u52A9\u6539\u8FDB Forsion(\u533F\u540D\u9065\u6D4B)\u4E8B\u4EF6\u767D\u540D\u5355 v2(v1 \u539F\u6837\u4FDD\u7559,v2 \u53EA\u52A0\u4E8B\u4EF6\u4E0E\u5B57\u6BB5;\u5951\u7EA6\u89C1\u540C\u76EE\u5F55 contract.md \xA76\u2013\xA714)\u3002\u6B63\u5178\u5728\u4ED3\u6839 docs/ToBeImproved/\u9ED8\u8BA4\u6570\u636E\u91C7\u96C6\u65B9\u6848_2026-10-28/telemetry-schema.json;server(src/config/telemetry-schema.json)\u4E0E Forsion-Extend(src/core/telemetry-schema.json)\u5404\u5B58\u4E00\u4EFD\u539F\u6837\u526F\u672C,\u6539\u4E00\u5904\u4E09\u5904\u540C\u6539,\u5E76\u540C\u6B65\u9690\u79C1\u653F\u7B56\u300C\u6539\u8FDB\u6570\u636E\u300D\u4E00\u8282\u3002\u7C7B\u578B:int = 0..2147483647 \u7684\u6574\u6570;bool;enum = \u53EA\u80FD\u53D6\u5217\u51FA\u7684\u503C;id = \u5339\u914D ^[A-Za-z0-9._:/@+-]{1,max}$ \u7684\u77ED\u4E32;text = \u81EA\u7531\u6587\u672C,\u5FC5\u987B\u5148\u8FC7 sanitize \u518D\u622A\u5230 max\u3002\u4E0D\u5728\u8868\u91CC\u7684\u4E8B\u4EF6\u4E0E\u5B57\u6BB5\u4E00\u5F8B\u4E22\u3002",version:2,limits:{maxBatchBytes:65536,maxEvents:200},envelope:{installId:{type:"uuid"},app:{type:"enum",values:["desktop","web","mobile"]},appVersion:{type:"id",max:40},coreVersion:{type:"id",max:40},channel:{type:"enum",values:["stable","beta"]},os:{type:"enum",values:["darwin","win32","linux","android","ios","other"]},osVersion:{type:"id",max:40},arch:{type:"enum",values:["arm64","x64","ia32","other"]},locale:{type:"enum",values:["zh","en"]},region:{type:"enum",values:["CN","other"]}},eventFields:{event:{type:"enum",values:["crash","agent_run","tool_call","perf","feature","approval","plugin_install","plugin_deps","plugin_lifecycle","plugin_load","update","onboarding","guide_tip","command_use","app_counts","sync_health","daily_muse","daily_muse_card","daily_memory","daily_judge","daily_human"]},ts:{type:"iso-time"},sessionId:{type:"uuid"}},events:{crash:{process:{type:"enum",values:["main","renderer","engine","plugin-host","extend","other"]},errorName:{type:"id",max:60},stack:{type:"stack",max:4e3},uptimeS:{type:"int"},exitCode:{type:"int"},reason:{type:"enum",values:["exception","rejection","crashed","oom","killed","abnormal-exit","launch-failed","integrity-failure","other"]},pluginId:{type:"id",max:64}},agent_run:{modelId:{type:"id",max:80},providerKind:{type:"enum",values:["forsion","codex","byok","local","other"]},mode:{type:"enum",values:["chat","agent","muse","historian","team","task","other"]},steps:{type:"int"},llmCalls:{type:"int"},tokensIn:{type:"int"},tokensOut:{type:"int"},tokensCached:{type:"int"},retries:{type:"int"},durationMs:{type:"int"},outcome:{type:"enum",values:["done","error","aborted","other"]},errorClass:{type:"enum",values:["timeout","rate_limit","auth","network","context_length","upstream","tool","aborted","other"]},agentRole:{type:"enum",values:["xyra","aria","recita","coding","muse","historian","custom"]},recallEntries:{type:"int"},recallHistory:{type:"int"},recallTruncated:{type:"bool"},memoryTokens:{type:"int"},humanTokens:{type:"int"},profileTokens:{type:"int"},projectTokens:{type:"int"}},tool_call:{tool:{type:"id",max:80},calls:{type:"int"},failures:{type:"int"},totalMs:{type:"int"},maxMs:{type:"int"},runOutcome:{type:"enum",values:["done","error","aborted","other"]},toolSource:{type:"enum",values:["builtin","mcp","plugin","other"]}},perf:{kind:{type:"enum",values:["startup","hourly"]},startupMs:{type:"int"},engineReadyMs:{type:"int"},rssMb:{type:"int"},heapMb:{type:"int"},longTasks:{type:"int"}},feature:{name:{type:"enum",values:["space_open","view_open","plugin_open","setting_change"]},kind:{type:"id",max:60},id:{type:"id",max:80},key:{type:"id",max:80},value:{type:"id",max:40}},approval:{tool:{type:"id",max:80},toolSource:{type:"enum",values:["builtin","mcp","plugin","other"]},reasonKind:{type:"enum",values:["custom-ask","escalate","mode","protected","control","always","other"]},mode:{type:"enum",values:["readonly","auto-edit","full-auto","custom","other"]},asked:{type:"int"},approved:{type:"int"},rejected:{type:"int"},expired:{type:"int"},decideSecTotal:{type:"int"},remoteAnswers:{type:"int"}},plugin_install:{id:{type:"id",max:80},entry:{type:"enum",values:["store","chat-card","muse-card","plugin-onboarding","deps","other"]},kind:{type:"enum",values:["plugin","skill","agent","space","theme","amadeus-plugin","other"]},source:{type:"enum",values:["github","npm","zip","other"]},stage:{type:"enum",values:["resolve","download","install","activate","done"]},outcome:{type:"enum",values:["done","error","canceled"]},errorClass:{type:"enum",values:["timeout","network","http","too-large","not-zip","integrity","identity","version","min-app","platform","deps","builtin","activate","disk","other"]},durationMs:{type:"int"},sizeKb:{type:"int"},restart:{type:"bool"}},plugin_deps:{total:{type:"int"},installed:{type:"int"},failedAt:{type:"int"},outcome:{type:"enum",values:["ready","not-ready","not-running","failed"]}},plugin_lifecycle:{id:{type:"id",max:80},action:{type:"enum",values:["uninstall","enable","disable","blocked"]},blockedReason:{type:"enum",values:["min-app","api","invalid","dev-fileext","deps","other"]},daysSinceInstall:{type:"int"}},plugin_load:{id:{type:"id",max:80},outcome:{type:"enum",values:["ok","error"]},activateMs:{type:"int"}},update:{target:{type:"enum",values:["app","engine","ui","builtin-plugin","store-plugin","first-boot-prefetch"]},id:{type:"id",max:80},outcome:{type:"enum",values:["available","not-available","staged","applied","current","error","incompatible","rolled-back","timeout","skipped"]},errorClass:{type:"enum",values:["network","http","integrity","signature","version","identity","incompatible","disk","other"]}},onboarding:{mode:{type:"enum",values:["full","returning","brief","update"]},outcome:{type:"enum",values:["finish","skip","error-skip"]},screens:{type:"int"},backJumps:{type:"int"},msStart:{type:"int"},msTheme:{type:"int"},msYou:{type:"int"},msTeam:{type:"int"},msWelcome:{type:"int"},signedIn:{type:"bool"},syncNotes:{type:"bool"},syncAgents:{type:"bool"},syncPlugins:{type:"bool"},addedAgent:{type:"bool"},museOn:{type:"bool"},computerHistoryOn:{type:"bool"},youWritten:{type:"bool"}},guide_tip:{pluginId:{type:"id",max:80},tipId:{type:"id",max:60},result:{type:"enum",values:["ok","learned","mute","gone","missing","replaced","closed"]}},command_use:{id:{type:"id",max:80},source:{type:"enum",values:["palette","hotkey","ribbon","agent","other"]},n:{type:"int"}},app_counts:{achChatSend:{type:"int"},achChatGroup:{type:"int"},achNoteCreate:{type:"int"},achNoteWikilink:{type:"int"},achNoteCanvas:{type:"int"},achBaseCreate:{type:"int"},achSpaceSave:{type:"int"},achSpaceSwitch:{type:"int"},achAgentCreate:{type:"int"},achAutomationCreate:{type:"int"},achMuseOpen:{type:"int"},achComputerUse:{type:"int"},achMarketInstall:{type:"int"},achThemeChange:{type:"int"},achTodoDone:{type:"int"},achCalendarEvent:{type:"int"},achAccountLogin:{type:"int"},achImageGenerate:{type:"int"},achDrawingCreate:{type:"int"},achMiniOpen:{type:"int"},achSpecialEnable:{type:"int"},chatStop:{type:"int"},chatRegenerate:{type:"int"},chatEditResend:{type:"int"},chatTruncateResend:{type:"int"},chatRetry:{type:"int"},chatRewind:{type:"int"},chatBranch:{type:"int"},chatSteer:{type:"int"},chatSteerWithdraw:{type:"int"},chatCompact:{type:"int"},chatRetryFailed:{type:"int"},searchOpen:{type:"int"},searchPick:{type:"int"},searchCloseEmpty:{type:"int"},providerLoginOk:{type:"int"},providerLoginFail:{type:"int"},byokSave:{type:"int"},byokImport:{type:"int"},byokImportStale:{type:"int"},byokDelete:{type:"int"},connTestOk:{type:"int"},connTestFail:{type:"int"},connTestAuthRejected:{type:"int"},modelSwitchUser:{type:"int"},modelSwitchRemember:{type:"int"},engineDefaultModelSet:{type:"int"},homeWidgetAdd:{type:"int"},homeWidgetRemove:{type:"int"},homeWidgetMove:{type:"int"},openNote:{type:"int"},openDatabase:{type:"int"},openDashboard:{type:"int"},openPdf:{type:"int"},openBoard:{type:"int"},openPluginFile:{type:"int"},openOther:{type:"int"}},sync_health:{system:{type:"enum",values:["vault","content","remote"]},day:{type:"id",max:10},cycles:{type:"int"},cycleMsTotal:{type:"int"},errAuth:{type:"int"},errOffline:{type:"int"},errVaultMissing:{type:"int"},errScan:{type:"int"},errMirrorMissing:{type:"int"},errHttp:{type:"int"},errTimeout:{type:"int"},errBlocked:{type:"int"},errOther:{type:"int"},conflicts:{type:"int"},skippedTooLarge:{type:"int"},skippedNotFound:{type:"int"},skippedExists:{type:"int"},skippedOther:{type:"int"},massDeleteGuard:{type:"int"},uploads:{type:"int"},downloads:{type:"int"}},daily_muse:{day:{type:"id",max:10},cyclesRule:{type:"int"},cyclesSchedule:{type:"int"},cyclesHeartbeat:{type:"int"},cyclesRunEnd:{type:"int"},cyclesModeAsk:{type:"int"},cyclesModeAgent:{type:"int"},cyclesModeAuto:{type:"int"},cyclesDone:{type:"int"},cyclesError:{type:"int"},cyclesAborted:{type:"int"},cyclesSilent:{type:"int"},cycleTokens:{type:"int"},cycleMs:{type:"int"},producedCards:{type:"int"},producedDms:{type:"int"},producedTodos:{type:"int"},producedStarters:{type:"int"},inboxMarked:{type:"int"},inboxUnmarked:{type:"int"},skipNoModel:{type:"int"},skipOutsideHours:{type:"int"},skipUserActive:{type:"int"},skipNothingDue:{type:"int"},skipAlreadyRunning:{type:"int"},skipBudgetBillable:{type:"int"},skipBudgetGross:{type:"int"},skipRestartCap:{type:"int"},skipRemoteLock:{type:"int"},skipSleepCleared:{type:"int"},dmProactive:{type:"int"},dmTodo:{type:"int"},dmApproval:{type:"int"},dmCard:{type:"int"},dmNotice:{type:"int"},dmRemind:{type:"int"},dmSuppressed:{type:"int"},dmAwaitingUser:{type:"int"},dmReadIn24h:{type:"int"},dmRepliedIn24h:{type:"int"},feedbackUp:{type:"int"},feedbackDown:{type:"int"},feedbackText:{type:"int"},todoCreated:{type:"int"},todoApproved:{type:"int"},todoInjected:{type:"int"},todoDone:{type:"int"},todoDismissed:{type:"int"},starterCreated:{type:"int"},starterUsed:{type:"int"},starterDismissed:{type:"int"},starterMuted:{type:"int"},ruleCreatedMuse:{type:"int"},ruleCreatedUser:{type:"int"},ruleObserveForced:{type:"int"},rulePromoted:{type:"int"},ruleExtended:{type:"int"},rulePaused:{type:"int"},ruleObservedHits:{type:"int"},approvalByAgent:{type:"int"},approvalUserApproved:{type:"int"},approvalUserRejected:{type:"int"},introAnswered:{type:"int"},introSkipped:{type:"int"},introWhenAnytime:{type:"int"},introWhenDaytime:{type:"int"},introWhenOpen:{type:"int"},introPaceAsNeeded:{type:"int"},introPaceDaily:{type:"int"},introPaceFree:{type:"int"},introFocusSchedule:{type:"int"},introFocusStudy:{type:"int"},introFocusProjects:{type:"int"},introFocusInbox:{type:"int"},introFocusCustom:{type:"int"},summarySent:{type:"int"},summaryProposed:{type:"int"},summaryAdopted:{type:"int"},summaryAskUpgrade:{type:"int"},sleepSet:{type:"int"},digestSent:{type:"int"},gEnabled:{type:"int"},gDaysEnabled:{type:"int"},gModeAsk:{type:"int"},gModeAgent:{type:"int"},gModeAuto:{type:"int"},gNotifyDigest:{type:"int"},gHeartbeatMin:{type:"int"},gMaxDmPerDay:{type:"int"},gOnboardingDay:{type:"int"},gRulesObserving:{type:"int"},gRulesEnabled:{type:"int"}},daily_muse_card:{day:{type:"id",max:10},cardKind:{type:"enum",values:["plugin","feature","inbox-ask","inbox-list","channel","settings","intro","summary","rule","rule-observed"]},created:{type:"int"},accept:{type:"int"},observe:{type:"int"},edit:{type:"int"},dismiss:{type:"int"},open:{type:"int"},apply:{type:"int"},yes:{type:"int"},later:{type:"int"},ignore:{type:"int"},ack:{type:"int"},item:{type:"int"},enable:{type:"int"},extend:{type:"int"},pause:{type:"int"},answer:{type:"int"},skip:{type:"int"},ok:{type:"int"},remove:{type:"int"},installed:{type:"int"},gone:{type:"int"},dismissIrrelevant:{type:"int"},dismissTiming:{type:"int"},dismissFrequent:{type:"int"},dismissKnown:{type:"int"},decideSecTotal:{type:"int"},decidedRemote:{type:"int"},gPendingOver3d:{type:"int"}},daily_memory:{day:{type:"id",max:10},agentRole:{type:"enum",values:["xyra","aria","recita","coding","muse","historian","custom"]},addAgent:{type:"int"},addProject:{type:"int"},addPerson:{type:"int"},updateAgent:{type:"int"},updateProject:{type:"int"},updatePerson:{type:"int"},forgetAgent:{type:"int"},forgetProject:{type:"int"},forgetPerson:{type:"int"},moveScope:{type:"int"},srcExplicit:{type:"int"},srcHistorian:{type:"int"},srcDream:{type:"int"},srcManual:{type:"int"},srcRestore:{type:"int"},srcExternalEdit:{type:"int"},srcSync:{type:"int"},srcMigration:{type:"int"},errFull:{type:"int"},errVersionConflict:{type:"int"},errPortraitFull:{type:"int"},userEditAgentWritten7d:{type:"int"},userForgetAgentWritten7d:{type:"int"},userRestoreDreamRetired:{type:"int"},userEdit:{type:"int"},userForget:{type:"int"},userAdd:{type:"int"},userForgetWrong:{type:"int"},userForgetStale:{type:"int"},userForgetUnwanted:{type:"int"},userForgetDuplicate:{type:"int"},retellExisting:{type:"int"},retellForgotten:{type:"int"},candidatesAdded:{type:"int"},dreamAuto:{type:"int"},dreamManual:{type:"int"},dreamArchive:{type:"int"},dreamCompleted:{type:"int"},dreamSkipped:{type:"int"},dreamFailed:{type:"int"},dreamCancelled:{type:"int"},dreamCalls:{type:"int"},dreamSources:{type:"int"},dreamGroups:{type:"int"},dreamMerges:{type:"int"},dreamDiscarded:{type:"int"},dreamToPortrait:{type:"int"},dreamPending:{type:"int"},dreamDeferred:{type:"int"},dreamVerifyFail:{type:"int"},dreamRetried:{type:"int"},dreamMs:{type:"int"},harnessUpsertAgent:{type:"int"},harnessUpsertHistorian:{type:"int"},harnessUpsertMuse:{type:"int"},harnessUpsertUser:{type:"int"},harnessDelete:{type:"int"},harnessRollback:{type:"int"},gEntries:{type:"int"},gCharsPct:{type:"int"},gTombstones:{type:"int"},gCandidatesPending:{type:"int"},gCandidatesOldestDays:{type:"int"},gHarnessEntries:{type:"int"}},daily_judge:{day:{type:"id",max:10},rounds:{type:"int"},roundsIndependent:{type:"int"},roundsAssist:{type:"int"},roundsFork:{type:"int"},isolationSkips:{type:"int"},memCandidates:{type:"int"},projCandidatesAuto:{type:"int"},projCandidatesQueued:{type:"int"},projAdopted:{type:"int"},projDismissed:{type:"int"},projForgotten:{type:"int"},projRestored:{type:"int"},projCompacted:{type:"int"},harnessCandidatesAuto:{type:"int"},harnessCandidatesQueued:{type:"int"},signalStop:{type:"int"},signalToolLoop:{type:"int"},signalNudge:{type:"int"},signalCorrectionDecision:{type:"int"},signalCorrectionLexical:{type:"int"},titleUpdated:{type:"int"},summaryUpdated:{type:"int"},iconUpdated:{type:"int"}},daily_human:{day:{type:"id",max:10},wAgentShared:{type:"int"},wAgentAgent:{type:"int"},wAgentProject:{type:"int"},wAgentPortrait:{type:"int"},wAgentAgentMd:{type:"int"},wAgentMemory:{type:"int"},wUserShared:{type:"int"},wUserAgent:{type:"int"},wUserProject:{type:"int"},wUserPortrait:{type:"int"},wUserAgentMd:{type:"int"},wUserMemory:{type:"int"},srcRemember:{type:"int"},srcDream:{type:"int"},srcMove:{type:"int"},srcPromote:{type:"int"},srcUser:{type:"int"},userUndoAgentWrite7d:{type:"int"},moveScan:{type:"int"},moveMoved:{type:"int"},moveKept:{type:"int"},moveUndo:{type:"int"},promoteToAgentMd:{type:"int"},coldstartAgents:{type:"int"},coldstartPersonWrites:{type:"int"},coldstartRelearned:{type:"int"},mirrorConflicts:{type:"int"},syncConflictCopies:{type:"int"},gHumanMdEntries:{type:"int"},gAgentMdEntries:{type:"int"},gPortraitEntries:{type:"int"},gMemoryEntries:{type:"int"},gCalendarRows:{type:"int"},gAgentsWithHumanMd:{type:"int"},gAgentsTotal:{type:"int"}}}};var jh=Zn.events,Fh=Zn.envelope,Bo=Zn.limits,$l=Zn.version,Lh=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Uh=/^[A-Za-z0-9._:/@+-]+$/,Nl=t=>typeof t=="string"&&Lh.test(t),Pl=/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,Hh=[[/\/Users\/[^/\s]+\//gi,"~/"],[/\/home\/[^/\s]+\//gi,"~/"],[/[a-z]:\\Users\\[^\\\s]+\\/gi,"~\\"],[/~([/\\])[^\s"'`」:()]+/g,"~$1\u2026"],[/\/Volumes\/[^\s"'`」:()]+/g,"/Volumes/\u2026"],[/\b([d-z]):\\[^\s"'`」:()]+/gi,"$1:\\\u2026"],[/forsion-agent-space\/[^/\s]+\//g,"forsion-agent-space/\u2026/"],[/"[^"]{1,200}"/g,'"\u2026"'],[/'[^']{1,200}'/g,"'\u2026'"],[/`[^`]{1,200}`/g,"`\u2026`"],[/「[^「」]{1,200}」/g,"\u300C\u2026\u300D"],[/(https?:\/\/[^\s?#"'`」]+)[?#][^\s"'`」]*/gi,"$1"],[/sk-[A-Za-z0-9_-]{10,}/g,"[redacted]"],[/Bearer\s+\S+/gi,"[redacted]"],[/[0-9a-f]{32,}/gi,"[redacted]"],[/[A-Za-z0-9+/]{40,}={0,2}/g,"[redacted]"],[/[A-Za-z0-9_-]{40,}/g,"[redacted]"],[/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,"[email]"]],jl=t=>Hh.reduce((e,[n,r])=>e.replace(n,r),t);function Ml(t,e,n){let r=t.slice(0,2e4).replace(/\u0000/g,"").replace(Pl,"\uFFFD");return n&&n.length>3&&(r=r.split(n).join("~")),r=jl(r),(r.length>e?r.slice(0,e):r).replace(Pl,"\uFFFD")}var zh=/^pr-[a-f0-9]{48}$/,Bh=/^market-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,qh=t=>zh.test(t)||Bh.test(t)||jl(t)===t;function Wh(t){if(typeof t!="string")return"";let e=t.search(/^\s+at /m);return e<0?"":t.slice(e)}function zo(t,e,n){switch(t.type){case"enum":return typeof e=="string"&&t.values.includes(e)?e:void 0;case"int":return typeof e=="number"&&Number.isFinite(e)&&e>=0?Math.min(Math.round(e),2147483647):void 0;case"bool":return typeof e=="boolean"?e:void 0;case"uuid":return Nl(e)?e.toLowerCase():void 0;case"iso-time":return typeof e=="string"&&!Number.isNaN(Date.parse(e))?new Date(e).toISOString():void 0;case"id":return typeof e=="string"&&e.length<=t.max&&Uh.test(e)&&qh(e)?e:void 0;case"text":return typeof e=="string"&&e?Ml(e,t.max,n):void 0;case"stack":{let r=Wh(e);return r?Ml(r,t.max,n):void 0}}}function zt(t,e){let n=typeof t?.event=="string"?jh[t.event]:void 0;if(!n)return null;let r={},s=t.props&&typeof t.props=="object"?t.props:{};for(let[i,a]of Object.entries(n)){let c=zo(a,s[i],e);c!==void 0&&(r[i]=c)}let o=zo({type:"iso-time"},t.ts);return{event:t.event,ts:o??new Date().toISOString(),...Nl(t.sessionId)?{sessionId:t.sessionId.toLowerCase()}:{},props:r}}function Fl(t){let e={};for(let[n,r]of Object.entries(Fh)){if(n==="installId")continue;let s=zo(r,t[n]);e[n]=typeof s=="string"?s:null}return e}function Ll(t,e){if(e==="aborted")return"aborted";if(!t)return;let n=t.toLowerCase();return/abort|cancel/.test(n)?"aborted":/timeout|timed out|etimedout/.test(n)?"timeout":/\b429\b|rate.?limit|too many requests|quota/.test(n)?"rate_limit":/\b40[13]\b|unauthori[sz]ed|forbidden|invalid api key|authentication/.test(n)?"auth":/context.{0,20}(length|window|too long)|maximum context|too many tokens|prompt is too long/.test(n)?"context_length":/econn|enotfound|eai_again|socket|network|fetch failed|getaddrinfo/.test(n)?"network":/\b5\d\d\b|upstream|bad gateway|overloaded|service unavailable/.test(n)?"upstream":/tool/.test(n)?"tool":"other"}function Ul(t){return t==="done"?"done":t==="failed"?"error":t==="aborted"?"aborted":"other"}function qo(t){return t?/^pr-/.test(t)?"forsion":/^codex\//.test(t)?"codex":/^(?:ollama|lmstudio|local)[/:]/i.test(t)?"local":"byok":"other"}var Vh=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;function Hl(t){if(typeof t!="string"||!t)return;let e=qo(t);if(e==="forsion"||e==="codex")return t;let n=t.slice(t.lastIndexOf("/")+1);return Vh.test(n)?n:void 0}function Wo(t){return t==="builtin"||t==="mcp"||t==="plugin"?t:"other"}function Vo(t,e){return e==="plugin"?"plugin":e==="mcp"||t.startsWith("mcp__")?"mcp":t}function zl(t){return{user:"chat",agent:"agent",muse:"muse",historian:"historian",teamwork:"team",discussion:"team",subagent:"task"}[t||"user"]??"other"}var Zh=10*6e4,Qh=6e4,eg=50,Yl=1024*1024,tg=168*36e5,Gl=15e3,ng=200,rg=2e3,Jo=7,sg=5e3,Jl=864e5,og=new Set(["crash","perf","feature","plugin_install","plugin_deps","plugin_lifecycle","plugin_load","update","onboarding","guide_tip","command_use","app_counts"]),Ko={daily_muse:null,daily_muse_card:"cardKind",daily_memory:"agentRole",daily_judge:null,daily_human:null},ig=new Set(["custom-ask","escalate","mode","protected","control","always"]),ag=new Set(["readonly","auto-edit","full-auto","custom"]),Xl=t=>new Date(t).toISOString().slice(0,19).replace("T"," "),Xo=t=>({at:Xl(t),id:"~"}),hn=t=>typeof t=="string"?Date.parse(`${t.replace(" ","T")}Z`):NaN;async function cg(t,e,n,r){let s=gn(t,"tangu","state.db");if(!await Kl(s).then(i=>i.isFile(),()=>!1))return{events:[],cursor:e};let o;try{let{DatabaseSync:i}=await import("node:sqlite");o=new i(s,{readOnly:!0}),o.exec("PRAGMA busy_timeout = 1500");let a=o.prepare(`SELECT r.id, r.status, r.current_step, r.model_id, substr(r.error, 1, 2000) AS error, r.created_at, r.updated_at, s.kind
253
258
  FROM agent_runs r LEFT JOIN chat_sessions s ON s.id = r.session_id
254
259
  WHERE r.status IN ('done', 'failed', 'aborted') AND (r.updated_at > ? OR (r.updated_at = ? AND r.id > ?)) AND r.updated_at < ?
255
- ORDER BY r.updated_at, r.id LIMIT ?`).all(e.at,e.at,e.id,r??"9999-12-31 23:59:59",zh),l=o.prepare(`SELECT e.type, json_extract(e.payload, '$.id') AS id, json_extract(e.payload, '$.name') AS name, json_extract(e.payload, '$.source') AS source,
260
+ ORDER BY r.updated_at, r.id LIMIT ?`).all(e.at,e.at,e.id,r??"9999-12-31 23:59:59",ng),c=o.prepare(`SELECT e.type, json_extract(e.payload, '$.id') AS id, json_extract(e.payload, '$.name') AS name, json_extract(e.payload, '$.source') AS source,
256
261
  json_extract(e.payload, '$.isError') AS failed, json_extract(e.payload, '$.elapsedMs') AS ms,
257
262
  json_extract(e.payload, '$.prompt') AS prompt, json_extract(e.payload, '$.completion') AS completion, json_extract(e.payload, '$.cached') AS cached,
258
263
  json_extract(e.payload, '$.phase') AS phase,
@@ -261,22 +266,22 @@ ${o}`,n),this.line=r,this.column=s,this.codeblock=o}};var dp=/^((0x[0-9a-fA-F](_
261
266
  json_extract(e.payload, '$.action') AS action, json_extract(e.payload, '$.by.via') AS via, e.created_at AS at
262
267
  FROM agent_run_events e
263
268
  WHERE e.run_id = ? AND e.type IN ('usage', 'tool_call', 'tool_result', 'status', 'approval_request', 'approval_result') AND json_valid(e.payload)
264
- ORDER BY e.seq LIMIT ?`),c=h=>`(SELECT total(json_extract(s.value, '$.tokens')) FROM json_each(e.payload, '$.sections') s WHERE json_extract(s.value, '$.k') = '${h}')`,u=o.prepare(`SELECT json_extract(e.payload, '$.telemetry.agentRole') AS agentRole, json_extract(e.payload, '$.telemetry.recallEntries') AS recallEntries,
269
+ ORDER BY e.seq LIMIT ?`),l=h=>`(SELECT total(json_extract(s.value, '$.tokens')) FROM json_each(e.payload, '$.sections') s WHERE json_extract(s.value, '$.k') = '${h}')`,u=o.prepare(`SELECT json_extract(e.payload, '$.telemetry.agentRole') AS agentRole, json_extract(e.payload, '$.telemetry.recallEntries') AS recallEntries,
265
270
  json_extract(e.payload, '$.telemetry.recallHistory') AS recallHistory, json_extract(e.payload, '$.telemetry.recallTruncated') AS recallTruncated,
266
271
  json_type(e.payload, '$.sections') AS sectionsType,
267
- ${c("memory")} AS memoryTokens, ${c("human")} AS humanTokens,
268
- ${c("profile")} AS profileTokens, ${c("project")} AS projectTokens
272
+ ${l("memory")} AS memoryTokens, ${l("human")} AS humanTokens,
273
+ ${l("profile")} AS profileTokens, ${l("project")} AS projectTokens
269
274
  FROM agent_run_events e
270
275
  WHERE e.run_id = ? AND e.type = 'status' AND json_valid(e.payload) AND json_extract(e.payload, '$.phase') = 'context_info'
271
- ORDER BY e.seq LIMIT 1`),f=h=>typeof h=="number"&&Number.isFinite(h)&&h>0?h:0,g=h=>typeof h=="string"&&h?h:void 0,p=[],y=e;for(let h of a){y={at:String(h.updated_at),id:String(h.id)};let m={llmCalls:0,tokensIn:0,tokensOut:0,tokensCached:0,retries:0},w=new Map,_=new Map,$=[],R=new Map;for(let M of l.all(h.id,Bh))if(M.type==="usage")m.llmCalls++,m.tokensIn+=f(M.prompt),m.tokensOut+=f(M.completion),m.tokensCached+=f(M.cached);else if(M.type==="tool_call"||M.type==="tool_result"){if(typeof M.id=="string"&&M.source!=null&&_.set(M.id,M.source),M.type!=="tool_result"||typeof M.name!="string")continue;let V=M.source??(typeof M.id=="string"?_.get(M.id):void 0),Z=Bo(M.name,V),re=zo(V),se=`${Z}\0${re}`,ee=w.get(se)??{tool:Z,toolSource:re,calls:0,failures:0,totalMs:0,maxMs:0};w.set(se,ee),ee.calls++,M.failed&&ee.failures++,ee.totalMs+=f(M.ms),ee.maxMs=Math.max(ee.maxMs,f(M.ms))}else if(M.type==="approval_request")$.push({approvalId:g(M.approvalId),name:g(M.name),toolCallId:g(M.toolCallId),reasonKind:Vh.has(M.reasonKind)?M.reasonKind:"other",mode:Yh.has(M.reasonMode)?M.reasonMode:"other",at:hn(M.at)});else if(M.type==="approval_result"){let V=g(M.approvalId);V&&!R.has(V)&&R.set(V,{action:g(M.action),via:g(M.via),at:hn(M.at)})}else M.phase==="llm_retry"&&m.retries++;let O=u.all(h.id)[0],S=Pc(h.status),C=hn(h.updated_at)-hn(h.created_at),E=new Date(Number.isNaN(hn(h.updated_at))?Date.now():hn(h.updated_at)).toISOString(),I=zt({event:"agent_run",ts:E,sessionId:n,props:{modelId:$c(h.model_id),providerKind:Ho(h.model_id),mode:Mc(h.kind),steps:f(h.current_step),...m,durationMs:Number.isFinite(C)&&C>=0?C:void 0,outcome:S,errorClass:S==="done"?void 0:Oc(h.error,h.status),...O?{agentRole:O.agentRole,recallEntries:O.recallEntries,recallHistory:O.recallHistory,recallTruncated:O.recallTruncated===1?!0:O.recallTruncated===0?!1:void 0,...O.sectionsType==="array"?{memoryTokens:O.memoryTokens,humanTokens:O.humanTokens,profileTokens:O.profileTokens,projectTokens:O.projectTokens}:{}}:{}}});I&&p.push(I);for(let M of w.values()){let V=zt({event:"tool_call",ts:E,sessionId:n,props:{...M,runOutcome:S}});V&&V.props.tool&&p.push(V)}let U=new Map;for(let M of $){if(!M.name)continue;let V=M.toolCallId?_.get(M.toolCallId):void 0,Z=V==null?M.name.startsWith("mcp__")?"mcp":void 0:Bo(M.name,V),re=zo(V),se=`${Z??""}\0${re}\0${M.reasonKind}\0${M.mode}`,ee=U.get(se)??{tool:Z,toolSource:re,reasonKind:M.reasonKind,mode:M.mode,asked:0,approved:0,rejected:0,expired:0,decideSecTotal:0,remoteAnswers:0};U.set(se,ee),ee.asked++;let Q=M.approvalId?R.get(M.approvalId):void 0;if(!Q){ee.expired++;continue}Q.action==="approve"||Q.action==="approve_always"?ee.approved++:Q.action==="reject"&&ee.rejected++;let ge=Math.round((Q.at-M.at)/1e3);Number.isFinite(ge)&&ge>0&&(ee.decideSecTotal+=ge),Q.via&&Q.via!=="local"&&ee.remoteAnswers++}for(let M of U.values()){let V=zt({event:"approval",ts:E,sessionId:n,props:M});V&&(V.props.tool||M.tool===void 0)&&p.push(V)}}return{events:p,cursor:y}}catch{return{events:[],cursor:e}}finally{try{o?.close()}catch{}}}async function Jh(t,e,n){let r=gn(t,"tangu","state.db"),s=await Bc(r).then(i=>i.isFile(),i=>i?.code==="ENOENT"||i?.code==="ENOTDIR"?!1:null);if(s===null)return null;if(!s)return{days:[],complete:!0};let o;try{let{DatabaseSync:i}=await import("node:sqlite");if(o=new i(r,{readOnly:!0}),o.exec("PRAGMA busy_timeout = 1500"),!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'telemetry_ledger'").all().length)return{days:[],complete:!0};let a=Object.keys(Yo),l=o.prepare(`SELECT DISTINCT day FROM telemetry_ledger
276
+ ORDER BY e.seq LIMIT 1`),d=h=>typeof h=="number"&&Number.isFinite(h)&&h>0?h:0,g=h=>typeof h=="string"&&h?h:void 0,p=[],y=e;for(let h of a){y={at:String(h.updated_at),id:String(h.id)};let m={llmCalls:0,tokensIn:0,tokensOut:0,tokensCached:0,retries:0},w=new Map,_=new Map,M=[],R=new Map;for(let $ of c.all(h.id,rg))if($.type==="usage")m.llmCalls++,m.tokensIn+=d($.prompt),m.tokensOut+=d($.completion),m.tokensCached+=d($.cached);else if($.type==="tool_call"||$.type==="tool_result"){if(typeof $.id=="string"&&$.source!=null&&_.set($.id,$.source),$.type!=="tool_result"||typeof $.name!="string")continue;let V=$.source??(typeof $.id=="string"?_.get($.id):void 0),Z=Vo($.name,V),re=Wo(V),se=`${Z}\0${re}`,ee=w.get(se)??{tool:Z,toolSource:re,calls:0,failures:0,totalMs:0,maxMs:0};w.set(se,ee),ee.calls++,$.failed&&ee.failures++,ee.totalMs+=d($.ms),ee.maxMs=Math.max(ee.maxMs,d($.ms))}else if($.type==="approval_request")M.push({approvalId:g($.approvalId),name:g($.name),toolCallId:g($.toolCallId),reasonKind:ig.has($.reasonKind)?$.reasonKind:"other",mode:ag.has($.reasonMode)?$.reasonMode:"other",at:hn($.at)});else if($.type==="approval_result"){let V=g($.approvalId);V&&!R.has(V)&&R.set(V,{action:g($.action),via:g($.via),at:hn($.at)})}else $.phase==="llm_retry"&&m.retries++;let O=u.all(h.id)[0],S=Ul(h.status),C=hn(h.updated_at)-hn(h.created_at),E=new Date(Number.isNaN(hn(h.updated_at))?Date.now():hn(h.updated_at)).toISOString(),I=zt({event:"agent_run",ts:E,sessionId:n,props:{modelId:Hl(h.model_id),providerKind:qo(h.model_id),mode:zl(h.kind),steps:d(h.current_step),...m,durationMs:Number.isFinite(C)&&C>=0?C:void 0,outcome:S,errorClass:S==="done"?void 0:Ll(h.error,h.status),...O?{agentRole:O.agentRole,recallEntries:O.recallEntries,recallHistory:O.recallHistory,recallTruncated:O.recallTruncated===1?!0:O.recallTruncated===0?!1:void 0,...O.sectionsType==="array"?{memoryTokens:O.memoryTokens,humanTokens:O.humanTokens,profileTokens:O.profileTokens,projectTokens:O.projectTokens}:{}}:{}}});I&&p.push(I);for(let $ of w.values()){let V=zt({event:"tool_call",ts:E,sessionId:n,props:{...$,runOutcome:S}});V&&V.props.tool&&p.push(V)}let U=new Map;for(let $ of M){if(!$.name)continue;let V=$.toolCallId?_.get($.toolCallId):void 0,Z=V==null?$.name.startsWith("mcp__")?"mcp":void 0:Vo($.name,V),re=Wo(V),se=`${Z??""}\0${re}\0${$.reasonKind}\0${$.mode}`,ee=U.get(se)??{tool:Z,toolSource:re,reasonKind:$.reasonKind,mode:$.mode,asked:0,approved:0,rejected:0,expired:0,decideSecTotal:0,remoteAnswers:0};U.set(se,ee),ee.asked++;let Q=$.approvalId?R.get($.approvalId):void 0;if(!Q){ee.expired++;continue}Q.action==="approve"||Q.action==="approve_always"?ee.approved++:Q.action==="reject"&&ee.rejected++;let ge=Math.round((Q.at-$.at)/1e3);Number.isFinite(ge)&&ge>0&&(ee.decideSecTotal+=ge),Q.via&&Q.via!=="local"&&ee.remoteAnswers++}for(let $ of U.values()){let V=zt({event:"approval",ts:E,sessionId:n,props:$});V&&(V.props.tool||$.tool===void 0)&&p.push(V)}}return{events:p,cursor:y}}catch{return{events:[],cursor:e}}finally{try{o?.close()}catch{}}}async function lg(t,e,n){let r=gn(t,"tangu","state.db"),s=await Kl(r).then(i=>i.isFile(),i=>i?.code==="ENOENT"||i?.code==="ENOTDIR"?!1:null);if(s===null)return null;if(!s)return{days:[],complete:!0};let o;try{let{DatabaseSync:i}=await import("node:sqlite");if(o=new i(r,{readOnly:!0}),o.exec("PRAGMA busy_timeout = 1500"),!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'telemetry_ledger'").all().length)return{days:[],complete:!0};let a=Object.keys(Ko),c=o.prepare(`SELECT DISTINCT day FROM telemetry_ledger
272
277
  WHERE day > ? AND day < ? AND day GLOB '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]' AND event IN (${a.map(()=>"?").join(", ")})
273
- ORDER BY day LIMIT ?`).all(e,n,...a,Vo+1),c=o.prepare("SELECT event, dim, field, n FROM telemetry_ledger WHERE day = ? ORDER BY event, dim, field LIMIT ?"),u=[];for(let{day:f}of l.slice(0,Vo)){if(!Un(f))continue;let g=new Map;for(let y of c.all(f,qh)){if(typeof y.event!="string"||!Object.hasOwn(Yo,y.event))continue;let h=Yo[y.event],m=typeof y.dim=="string"?y.dim:"";if((h?!m:m!=="")||typeof y.field!="string"||typeof y.n!="number")continue;let w=`${y.event}\0${m}`,_=g.get(w)??{event:y.event,dimKey:h,dim:m,fields:new Map};g.set(w,_),_.fields.set(y.field,(_.fields.get(y.field)??0)+y.n)}let p=[];for(let y of g.values()){let h=zt({event:y.event,ts:`${f}T23:59:59.000Z`,props:{...Object.fromEntries(y.fields),day:f,...y.dimKey?{[y.dimKey]:y.dim}:{}}});!h||h.props.day!==f||y.dimKey&&h.props[y.dimKey]===void 0||Object.keys(h.props).some(m=>m!=="day"&&m!==y.dimKey)&&p.push(h)}u.push({day:f,events:p})}return{days:u,complete:l.length<=Vo}}catch{return null}finally{try{o?.close()}catch{}}}var Kh=(t,e,n)=>zt({event:"sync_health",ts:`${t}T23:59:59.000Z`,props:{...n,system:e,day:t}}),Xh=t=>["darwin","win32","linux"].includes(t)?t:"other",Zh=t=>["arm64","x64","ia32"].includes(t)?t:"other",Qh=()=>/^zh\b/i.test(Intl.DateTimeFormat().resolvedOptions().locale)?"zh":"en";function Wc(t,e={}){let n=e.now??(()=>new Date),r=e.fetch??fetch,s=()=>t.homeDir(),o=()=>gn(s(),"extend-telemetry.json"),i=()=>gn(s(),"telemetry"),a=()=>gn(i(),"queue.jsonl"),l=()=>gn(i(),"sent.jsonl"),c=t.telemetry,u=()=>rn(n().getTime()-zc);_l(()=>n().getTime());let f=()=>g()??{},g=()=>{let F;try{F=jc(o(),"utf8")}catch(Y){return Y?.code==="ENOENT"?{}:null}try{let Y=JSON.parse(F);return Y&&typeof Y=="object"&&!Array.isArray(Y)?Y:null}catch{return null}},p=(F,Y=f())=>{let v={...Y,...F};qo(s(),{recursive:!0});let A=`${o()}.${process.pid}.tmp`;return Lc(A,JSON.stringify(v,null,2),{encoding:"utf8",mode:384}),Fc(A,o()),v},y=()=>f().installId??p({installId:Nc()}).installId,h=()=>{try{return!!t.readCreds().token}catch{return!1}},m=(F=f())=>F.enabled!==!1&&F.noticeSeen===!0&&c?.packaged===!0&&h(),w=F=>{try{return jc(F,"utf8").split(`
274
- `).filter(Boolean)}catch{return[]}},_=()=>w(a()).flatMap(F=>{try{return[JSON.parse(F)]}catch{return[]}}),$=(F,Y)=>{if(qo(i(),{recursive:!0}),!Y.length){Wo(F,{force:!0});return}let v=`${F}.${process.pid}.tmp`;Lc(v,Y.map(A=>JSON.stringify(A)).join(`
278
+ ORDER BY day LIMIT ?`).all(e,n,...a,Jo+1),l=o.prepare("SELECT event, dim, field, n FROM telemetry_ledger WHERE day = ? ORDER BY event, dim, field LIMIT ?"),u=[];for(let{day:d}of c.slice(0,Jo)){if(!Un(d))continue;let g=new Map;for(let y of l.all(d,sg)){if(typeof y.event!="string"||!Object.hasOwn(Ko,y.event))continue;let h=Ko[y.event],m=typeof y.dim=="string"?y.dim:"";if((h?!m:m!=="")||typeof y.field!="string"||typeof y.n!="number")continue;let w=`${y.event}\0${m}`,_=g.get(w)??{event:y.event,dimKey:h,dim:m,fields:new Map};g.set(w,_),_.fields.set(y.field,(_.fields.get(y.field)??0)+y.n)}let p=[];for(let y of g.values()){let h=zt({event:y.event,ts:`${d}T23:59:59.000Z`,props:{...Object.fromEntries(y.fields),day:d,...y.dimKey?{[y.dimKey]:y.dim}:{}}});!h||h.props.day!==d||y.dimKey&&h.props[y.dimKey]===void 0||Object.keys(h.props).some(m=>m!=="day"&&m!==y.dimKey)&&p.push(h)}u.push({day:d,events:p})}return{days:u,complete:c.length<=Jo}}catch{return null}finally{try{o?.close()}catch{}}}var ug=(t,e,n)=>zt({event:"sync_health",ts:`${t}T23:59:59.000Z`,props:{...n,system:e,day:t}}),dg=t=>["darwin","win32","linux"].includes(t)?t:"other",fg=t=>["arm64","x64","ia32"].includes(t)?t:"other",pg=()=>/^zh\b/i.test(Intl.DateTimeFormat().resolvedOptions().locale)?"zh":"en";function Zl(t,e={}){let n=e.now??(()=>new Date),r=e.fetch??fetch,s=()=>t.homeDir(),o=()=>gn(s(),"extend-telemetry.json"),i=()=>gn(s(),"telemetry"),a=()=>gn(i(),"queue.jsonl"),c=()=>gn(i(),"sent.jsonl"),l=t.telemetry,u=()=>rn(n().getTime()-Jl);Dc(()=>n().getTime());let d=()=>g()??{},g=()=>{let F;try{F=ql(o(),"utf8")}catch(Y){return Y?.code==="ENOENT"?{}:null}try{let Y=JSON.parse(F);return Y&&typeof Y=="object"&&!Array.isArray(Y)?Y:null}catch{return null}},p=(F,Y=d())=>{let v={...Y,...F};Yo(s(),{recursive:!0});let A=`${o()}.${process.pid}.tmp`;return Vl(A,JSON.stringify(v,null,2),{encoding:"utf8",mode:384}),Wl(A,o()),v},y=()=>d().installId??p({installId:Bl()}).installId,h=()=>{try{return!!t.readCreds().token}catch{return!1}},m=(F=d())=>F.enabled!==!1&&F.noticeSeen===!0&&l?.packaged===!0&&h(),w=F=>{try{return ql(F,"utf8").split(`
279
+ `).filter(Boolean)}catch{return[]}},_=()=>w(a()).flatMap(F=>{try{return[JSON.parse(F)]}catch{return[]}}),M=(F,Y)=>{if(Yo(i(),{recursive:!0}),!Y.length){Go(F,{force:!0});return}let v=`${F}.${process.pid}.tmp`;Vl(v,Y.map(A=>JSON.stringify(A)).join(`
275
280
  `)+`
276
- `,{encoding:"utf8",mode:384}),Fc(v,F)},R=0,O=()=>{R++,Wo(a(),{force:!0}),Wo(l(),{force:!0}),El()},S=()=>{let F=n().getTime(),Y=w(l()).flatMap(A=>{try{return[JSON.parse(A)]}catch{return[]}}),v=Y.filter(A=>F-A.at<Hh);return v.length!==Y.length&&$(l(),v),v},C=0,E=!1,I=0,U=()=>{let F=g();if(!F)return wo(!1),!1;let Y=m(F);return Y&&F.closed?p({closed:void 0,cursor:Go(n().getTime()),ledgerCursor:u()},F):Y&&!Un(F.ledgerCursor)?p({ledgerCursor:u()},F):!Y&&!F.closed&&(C++,p({closed:!0},F)),wo(Y),Y},M=()=>{let F=g();if(!F){t.log("[forsion-extend] telemetry state unreadable; skipping the signed-in migration");return}if(F.signedInGate)return;let Y={signedInGate:1};!h()&&F.enabled===void 0&&F.noticeSeen===!0&&(Y.enabled=!1,Y.syncHealth=void 0,C++,O(),t.log("[forsion-extend] telemetry turned off: not signed in (sending now needs a Forsion account)")),p(Y,F)},V=F=>{if(!(!F.length||!m())){qo(i(),{recursive:!0}),Ph(a(),F.map(Y=>JSON.stringify(Y)).join(`
281
+ `,{encoding:"utf8",mode:384}),Wl(v,F)},R=0,O=()=>{R++,Go(a(),{force:!0}),Go(c(),{force:!0}),Ic()},S=()=>{let F=n().getTime(),Y=w(c()).flatMap(A=>{try{return[JSON.parse(A)]}catch{return[]}}),v=Y.filter(A=>F-A.at<tg);return v.length!==Y.length&&M(c(),v),v},C=0,E=!1,I=0,U=()=>{let F=g();if(!F)return vo(!1),!1;let Y=m(F);return Y&&F.closed?p({closed:void 0,cursor:Xo(n().getTime()),ledgerCursor:u()},F):Y&&!Un(F.ledgerCursor)?p({ledgerCursor:u()},F):!Y&&!F.closed&&(C++,p({closed:!0},F)),vo(Y),Y},$=()=>{let F=g();if(!F){t.log("[forsion-extend] telemetry state unreadable; skipping the signed-in migration");return}if(F.signedInGate)return;let Y={signedInGate:1};!h()&&F.enabled===void 0&&F.noticeSeen===!0&&(Y.enabled=!1,Y.syncHealth=void 0,C++,O(),t.log("[forsion-extend] telemetry turned off: not signed in (sending now needs a Forsion account)")),p(Y,F)},V=F=>{if(!(!F.length||!m())){Yo(i(),{recursive:!0}),Yh(a(),F.map(Y=>JSON.stringify(Y)).join(`
277
282
  `)+`
278
- `,{encoding:"utf8",mode:384});try{if(Mh(a()).size>Uc){let Y=_(),v=Y.length,A=0;for(;v>0&&A+Buffer.byteLength(JSON.stringify(Y[v-1]))+1<=Uc/2;)A+=Buffer.byteLength(JSON.stringify(Y[--v]))+1;$(a(),Y.slice(v))}}catch{}_().length>=Uh&&ee()}},Z=()=>{let F=f();return{available:!!c,enabled:F.enabled!==!1,noticeSeen:F.noticeSeen===!0,signedIn:h(),active:m(F),packaged:c?.packaged===!0,installId:y(),queued:$h(a())?_().length:0,lastSentAt:F.lastSentAt??null,lastError:F.lastError??null}},re=()=>Dc({app:"desktop",appVersion:t.appVersion(),coreVersion:c?.coreVersion()??void 0,channel:c?.channel(),os:Xh(process.platform),osVersion:jh(),arch:Zh(process.arch),locale:Qh()}),se=null,ee=()=>{if(se)return se;if(E||n().getTime()<I)return Promise.resolve();let F=C,Y=R,v=(async()=>{try{for(let A=0;A<5;A++){let T=_();if(!T.length)return;let D=y(),P={v:Tc,installId:D,...re()},B=[],H=Buffer.byteLength(JSON.stringify({...P,events:[]}));for(let te of T){let ue=Buffer.byteLength(JSON.stringify(te))+1;if(B.length>=Uo.maxEvents||H+ue>Uo.maxBatchBytes)break;B.push(te),H+=ue}if(!B.length){$(a(),T.slice(1));continue}let{base:z}=await t.getCloud(),J={...P,events:B};if(!U()||F!==C)return;let G=await r(`${z.replace(/\/+$/,"")}/api/telemetry/batch`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(J),signal:AbortSignal.timeout(Hc)}).catch(te=>({ok:!1,status:0,error:String(te?.message||te)})),K=G.status;if(K>=200&&K<300||K===400||K===413){let te=new Set(B.map(ue=>JSON.stringify(ue)));$(a(),_().filter(ue=>!te.has(JSON.stringify(ue))))}if(K>=200&&K<300){let te=n().getTime();Y===R&&$(l(),[...S(),{at:te,body:J}]),p({lastSentAt:te,lastError:void 0});continue}if(K!==400&&K!==413){let te=Number(G.headers?.get?.("retry-after"));I=n().getTime()+(Number.isFinite(te)&&te>0?Math.min(te,3600)*1e3:5*6e4)}p({lastError:K?`HTTP ${K}`:String(G.error??"network error").slice(0,200)});return}}catch(A){try{p({lastError:String(A?.message||A).slice(0,200)})}catch{}}})();return se=v,v.finally(()=>{se===v&&(se=null)}),v},Q=async()=>{try{if(S(),!U())return;let F=f(),Y=C,v=F.cursor??Go(n().getTime()),A=await Gh(s(),v,c?.sessionId,qc(n().getTime()));if(!U()||Y!==C)return;V(A.events),A.cursor!==v&&p({cursor:A.cursor}),await ge(Y),await ee()}catch(F){t.log(`[forsion-extend] telemetry tick failed: ${String(F?.message||F)}`)}},ge=async F=>{let Y=n().getTime(),v=rn(Y),A=rn(Y-zc),T=f().ledgerCursor;if(Un(T)||(T=A,p({ledgerCursor:T})),bo(T),T>=A){fe();return}let D=await Jh(s(),T,v);if(!(!U()||F!==C)){if(D){let P=D.complete?A:D.days[D.days.length-1]?.day??T;if(P>T){let B=kl(T,P),H=[...new Set([...D.days.map(J=>J.day),...B.map(J=>J.day)])].filter(J=>J>T&&J<=P).sort(),z=[];for(let J of H){z.push(...D.days.find(G=>G.day===J)?.events??[]);for(let G of B)if(G.day===J){let K=Kh(J,G.system,G.counts);K&&z.push(K)}}V(z),p({ledgerCursor:P}),bo(P)}}fe()}},fe=()=>{if(!Sl())return;let F=g();if(!F)return;let Y=bl();p({syncHealth:Object.keys(Y).length?Y:void 0},F),vl()},ye=c?.subscribe(F=>{try{if(!Wh.has(F?.event)||!U())return;let Y=zt({...F,sessionId:c.sessionId},Nh());Y&&V([Y])}catch(Y){t.log(`[forsion-extend] telemetry event dropped: ${String(Y?.message||Y)}`)}}),he={ok:!1,error:"untrusted"};t.handle("telemetry:get",F=>t.isTrustedSender(F)?(U(),Z()):he),t.handle("telemetry:set",(F,Y)=>{if(!t.isTrustedSender(F))return he;let v=f(),A={};typeof Y?.enabled=="boolean"&&(A.enabled=Y.enabled),Y?.noticeSeen===!0&&(A.noticeSeen=!0);let T={...v,...A};return!m(v)&&m(T)&&(A.cursor=Go(n().getTime()),A.ledgerCursor=u()),m(v)&&!m(T)&&C++,A.enabled===!1&&(A.syncHealth=void 0),p(A),A.enabled===!1&&O(),U(),Z()}),t.handle("telemetry:sent",F=>t.isTrustedSender(F)?{batches:S()}:he),t.handle("telemetry:delete",async F=>{if(!t.isTrustedSender(F))return he;E=!0,C++;try{await se?.catch(()=>{});let Y=y(),{base:v}=await t.getCloud(),T=(await r(`${v.replace(/\/+$/,"")}/api/telemetry/install/${Y}`,{method:"DELETE",signal:AbortSignal.timeout(Hc)}).catch(D=>({ok:!1,status:0,error:String(D?.message||D)}))).status;return T>=200&&T<300?(O(),p({installId:Nc(),lastSentAt:void 0,lastError:void 0,ledgerCursor:u(),syncHealth:void 0}),Z()):{ok:!1,error:T?`HTTP ${T}`:"network error"}}finally{E=!1}});try{wl(f().syncHealth),M(),U()}catch(F){t.log(`[forsion-extend] telemetry startup check failed: ${String(F?.message||F)}`)}let ze=t.addFlushHook?.(F=>{if(F!=="blur")try{fe()}catch{}}),Fe=setTimeout(()=>void Q(),Lh),be=setInterval(()=>void Q(),Fh);return Fe.unref?.(),be.unref?.(),t.log(`[forsion-extend] telemetry registered (${c?c.packaged?"packaged":"dev build: never sends":"host has no telemetry seam: never sends"})`),Object.assign(()=>{clearTimeout(Fe),clearInterval(be),ye?.(),ze?.()},{tick:Q,flush:ee})}import{readFileSync as bn,lstatSync as hu,renameSync as Tg,linkSync as Rg,unlinkSync as oi,readdirSync as Ig,rmdirSync as Dg,writeFileSync as Og,mkdirSync as Pg,copyFileSync as $g,constants as Mg}from"node:fs";import{readFile as tr,writeFile as nr,mkdir as ii,rename as ms,readdir as rr,lstat as bt,stat as ys,unlink as sr}from"node:fs/promises";import{join as Te,dirname as Wt,relative as or,sep as Sn}from"node:path";import{hostname as ai}from"node:os";import{randomUUID as et}from"node:crypto";import{isUtf8 as li}from"node:buffer";import{Readable as uu}from"node:stream";var eg=["config.toml","SOUL.md","HARNESS.md","HUMAN.md","MEMORY.md","CALENDAR.db"],tg=["HUMAN.md","AGENT.md","SOUL.md","MEMORY.md","CALENDAR.db"],Qn=".memory-tombstones.json",Yc=t=>/^WidgetData\/[a-z0-9][a-z0-9_-]{0,63}\/data\.db$/.test(t),Vc=t=>t==="WidgetData"||/^WidgetData\/[a-z0-9][a-z0-9_-]{0,63}$/.test(t),ng=t=>/^\d{4}-\d{2}-\d{2}$/.test(t)&&Number.isFinite(Date.parse(`${t}T00:00:00Z`))&&new Date(`${t}T00:00:00Z`).toISOString().slice(0,10)===t,rg=t=>/^[a-z0-9][a-z0-9-]{0,63}$/.test(t)&&!t.startsWith("__");function sg(t){if(!t||t.length>1024||/[\\\x00-\x1f:]/.test(t))return!1;if(t===Qn)return!0;let e=t.split("/");return e.some(n=>!n||n.startsWith(".")||n.endsWith(".")||n.endsWith(" "))?!1:eg.includes(t)||Yc(t)?!0:t.startsWith("LOG/")?e.length===2&&t.endsWith(".md")&&ng(e[1].slice(0,-3)):e.length>1&&e[0]==="Library"}var og=t=>t==="muse"||/^historian-[a-z0-9]{1,12}$/.test(t),ig=/\(conflict \d{4}-\d{2}-\d{2} \d{4}(?: \d+)?\)/,ag=/\(conflict [A-Za-z0-9_-]{1,64} \d{10,}\)/;function rs(t){let e=t.slice(t.lastIndexOf("/")+1);return ig.test(e)||ag.test(e)}function Gc(t,e,n=1){let r=t.lastIndexOf("/"),s=r<0?"":t.slice(0,r+1),o=r<0?t:t.slice(r+1),i=o.lastIndexOf("."),a=i>0?o.slice(0,i):o,l=i>0?o.slice(i):"",c=f=>String(f).padStart(2,"0"),u=`${e.getFullYear()}-${c(e.getMonth()+1)}-${c(e.getDate())} ${c(e.getHours())}${c(e.getMinutes())}${n>1?` ${n}`:""}`;return`${s}${a} (conflict ${u})${l}`}function Jo(t,e="file"){if(t==="agents"||t==="human")return e==="folder";let n=t.startsWith("human/"),r=t.startsWith("agents/");if(!n&&!r)return null;if(rs(t))return!1;if(n){let c=t.slice(6);return e==="folder"?Vc(c):tg.includes(c)||Yc(c)}let s=t.slice(7),o=s.indexOf("/"),i=o<0?s:s.slice(0,o),a=o<0?"":s.slice(o+1);if(!rg(i)||og(i))return!1;if(e==="file")return sg(a);if(a===""||a==="LOG"||Vc(a))return!0;let l=a.split("/");return l[0]==="Library"&&l.every(c=>c&&!c.startsWith(".")&&!c.endsWith(".")&&!c.endsWith(" "))}import{isAbsolute as lg}from"node:path";var Qe=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),ft=t=>typeof t=="string",Xo=t=>ft(t)&&t.length>0,Ot=t=>typeof t=="boolean",Bt=t=>typeof t=="number"&&Number.isFinite(t),mn=t=>Bt(t)&&Number.isSafeInteger(t)&&t>=0,os=t=>Bt(t)&&Number.isInteger(t)&&t>=0,Jc=t=>mn(t)&&t>0,yn=t=>ft(t)&&/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i.test(t),ls=t=>ft(t)&&/^[a-f0-9]{64}$/.test(t),Kc=t=>ft(t)&&/^(default|device-[A-Za-z0-9_-]{1,64})$/.test(t),is=(t,e)=>ft(t)&&e.includes(t),ke=(t,e)=>t===void 0||e(t),Xc=(t,e,n)=>e.every(r=>ke(t[r],n)),Zc=t=>ft(t)&&!t.includes("\0")&&lg(t);function Pt(t,e=!1){try{return It(t,e),!0}catch{return!1}}var Qc=t=>Pt(t)&&!t.includes("/")&&Buffer.byteLength(t)<=255,eu=t=>t===""||yn(t);function as(t,e){let n=t.indexOf(":");return n>0&&yn(e)&&t.slice(n+1)===e&&Kc(t.slice(0,n))}function cg(t,e){return Qe(e)&&as(t,e.id)&&Pt(e.path)&&Xo(e.version)&&ls(e.hash)&&Xc(e,["base","inode","stat"],ft)&&ke(e.statAt,Bt)&&ke(e.memoryDeleted,Ot)}function ug(t,e){return Qe(e)&&as(t,e.localId)&&yn(e.id)&&Pt(e.path)&&Jc(e.revision)&&eu(e.parentId)&&Qc(e.name)}function dg(t){return Qe(t)&&yn(t.id)&&Pt(t.path)&&Kc(t.target)&&is(t.direction,["upload","download","merge","rename","delete"])&&is(t.state,["queued","active","done","failed","paused","conflict"])&&mn(t.done)&&(t.size===null||mn(t.size))&&Bt(t.at)&&ke(t.error,ft)&&ke(t.finishedAt,Bt)}function fg(t){return Qe(t)&&Pt(t.path)&&ls(t.hash)&&ft(t.stage)&&/^\.forsion-sync-trash-[a-f0-9-]+$/.test(t.stage)&&ke(t.parentId,yn)&&ke(t.stageRoot,Zc)&&(t.stageDev===void 0&&t.stageIno===void 0||t.stageRoot!==void 0&&os(t.stageDev)&&os(t.stageIno))}function pg(t){return Qe(t)&&Pt(t.prefix,!0)&&Zc(t.root)&&(t.dev===void 0&&t.ino===void 0||os(t.dev)&&os(t.ino))}function hg(t){return Qe(t)&&is(t.state,["running","done"])&&Ot(t.seen)&&Xc(t,["name","folderId","shelfId","shelfName"],ft)&&ke(t.files,mn)&&ke(t.at,Bt)&&ke(t.rewritten,Ot)}var ss=(t,e)=>Qe(t)&&Object.entries(t).every(([n,r])=>e(n,r)),Ko=(t,e)=>Array.isArray(t)&&t.every(e);function tu(t){if(!Qe(t)||!Qe(t.config)||!mn(t.config.revision)||!Ot(t.owned)||!Ot(t.paused)||!ss(t.files,cg)||!ss(t.folders,ug)||!Ko(t.jobs,dg)||!ke(t.accountReview,Ot)||!ke(t.agentArchive,hg)||!ke(t.roots,e=>Ko(e,pg))||!ke(t.trash,e=>Ko(e,fg))||!ke(t.unconfirmed,e=>ss(e,(n,r)=>as(n,n.slice(-36))&&ls(r)))||!ke(t.pendingUploads,e=>ss(e,(n,r)=>Qe(r)&&as(n,r.id)&&Pt(r.path))))throw Error("Invalid content sync state; original data was retained");Dt(t.config,t.config.revision)}function gg(t){return Qe(t)&&yn(t.id)&&eu(t.parentId)&&Qc(t.name)&&Pt(t.path)&&is(t.kind,["file","folder"])&&Jc(t.revision)&&Ot(t.deleted)&&ke(t.busy,Ot)&&ke(t.version,Xo)&&ke(t.hash,ls)&&ke(t.size,mn)&&ke(t.mtime,Bt)&&t.version===void 0==(t.hash===void 0)}function cs(t,e){let n=()=>Error("Incomplete or invalid cloud content manifest");if(!Qe(t)||t.schemaVersion!==1||t.namespace!==e||!Xo(t.folder)||!Array.isArray(t.nodes))throw n();let r=new Map,s=new Set;for(let o of t.nodes){if(!gg(o)||r.has(o.id)||!o.deleted&&s.has(o.path))throw n();r.set(o.id,o),o.deleted||s.add(o.path)}for(let o of r.values()){let i=o.parentId?r.get(o.parentId):void 0;if(o.parentId&&(!i||i.kind!=="folder"||i.deleted&&!o.deleted)||o.path!==(i?i.path+"/"+o.name:o.name))throw n()}}import{constants as nu,lstatSync as qt,readdirSync as mg,readFileSync as yg,renameSync as us,unlinkSync as wg,linkSync as bg,mkdirSync as fs,realpathSync as Zo,rmdirSync as Sg}from"node:fs";import{open as ru,lstat as Qo,readdir as vg,realpath as su,readFile as ei,writeFile as kg,mkdir as ou,unlink as Eg}from"node:fs/promises";import{join as $t,dirname as ds,relative as ti,sep as ps}from"node:path";import{randomUUID as iu,createHash as _g}from"node:crypto";var er=t=>`${t.size}:${t.mtime}:${t.ctime}:${t.inode}`,hs=t=>({size:t.size,mtime:t.mtimeMs,ctime:t.ctimeMs,inode:`${t.dev}:${t.ino}:${t.birthtimeMs}`}),au=".forsion-sync-id.json",Cg=new Set([".git","node_modules",".DS_Store",".Trash",".trash","__pycache__",".cache"]),xg=t=>!Cg.has(t)&&!t.startsWith(".forsion-sync")&&!/\.tmp-[0-9]|\.lock$|-(wal|shm)$/.test(t)&&(!t.startsWith(".")||t===".memory-tombstones.json"),Ee=t=>_g("sha256").update(t).digest("hex");function lu(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 Je(t,e,n=!1){if(n){if(e.split("/").some(a=>a===".."||a==="."||!a)||e.startsWith("/")||e.includes("\\"))throw Error("Invalid internal content path")}else It(e,!0);lu(e);let r=await su(t),s=$t(r,...e.split("/").filter(Boolean)),o=ti(r,s);if(o===".."||o.startsWith(".."+ps))throw Error("Content path escapes root");let i=r;for(let a of o.split(ps).filter(Boolean)){i=$t(i,a);try{if((await Qo(i)).isSymbolicLink())throw Error("Content symlinks are not synchronized")}catch(l){if(l.code!=="ENOENT")throw l}}return s}function rt(t,e,n=!1){if(n||It(e,!0),lu(e),e.split("/").some(o=>o===".."||o===".")||e.startsWith("/")||e.includes("\\"))throw Error("Unsafe sync path");let s=Zo(t);for(let o of e.split("/").filter(Boolean)){s=$t(s,o);try{if(qt(s).isSymbolicLink())throw Error("Content symlinks are not synchronized")}catch(i){if(i.code!=="ENOENT")throw i}}return s}async function gs(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 su(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 Qo(o)).isDirectory())throw Error(`Sync root is not a directory: ${s.prefix||"Forsion"}`);let i=async(a,l)=>{let c=await Qo(a);if(!c.isSymbolicLink()&&!(a!==o&&r.some(u=>u!==s&&u.root===a))&&!(l&&s.prefix===""&&n.some(u=>l===u||l.startsWith(u+"/")))){if(l){It(l);let u;if(c.isDirectory())try{let f=JSON.parse(await ei($t(a,au),"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(l,{path:l,physical:a,root:o,kind:c.isDirectory()?"folder":"file",localId:u,...hs(c),size:c.isFile()?c.size:0})}if(c.isDirectory())for(let u of await vg(a,{withFileTypes:!0}))!xg(u.name)||!u.isDirectory()&&!u.isFile()||await i($t(a,u.name),l?`${l}/${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 ni(t){if(t.kind!=="folder")throw Error("Folder identity required");if(t.localId)return t.localId;let e=await Je(t.root,ti(t.root,$t(t.physical,au)).split(ps).join("/"),!0),n=iu();try{let r=await ru(e,"wx",384);try{await r.writeFile(JSON.stringify({version:1,id:n})+`
279
- `)}finally{await r.close()}return t.localId=n,n}catch(r){if(r.code!=="EEXIST")throw r;let s=JSON.parse(await ei(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 wn(t){let e=await Je(t.root,ti(t.root,t.physical).split(ps).join("/")),n=await ru(e,nu.O_RDONLY|(nu.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 je(t,e){It(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 ri(t,e,n,r,s=async(o,i)=>i()){let o=je(t,e);await ou(o.root,{recursive:!0});let i=await Je(o.root,o.relative),a=await ei(i).catch(c=>{if(c.code==="ENOENT")return null;throw c});if((a?Ee(a):null)!==r)throw Error("Local file changed during download");let l=$t(o.root,`.forsion-sync-${iu()}.tmp`);try{await kg(l,n,{flag:"wx",mode:384}),await Je(o.root,o.relative),await s(i,()=>{rt(o.root,o.relative),fs(ds(i),{recursive:!0}),rt(o.root,o.relative);let c=null;try{c=yg(i)}catch(u){if(u.code!=="ENOENT")throw u}if((c?Ee(c):null)!==r)throw Error("Local file changed during download");us(l,i)})}finally{await Eg(l).catch(()=>{})}}async function cu(t,e,n=async(r,s)=>s()){let r=je(t,e);await ou(r.root,{recursive:!0});let s=await Je(r.root,r.relative);await n([s],()=>{rt(r.root,r.relative),fs(s,{recursive:!0})})}async function si(t,e,n,r=async(s,o)=>o()){let s=je(t,e),o=je(t,n);if(s.root!==o.root)throw Error("Folder move crosses a managed source");let i=await Je(s.root,s.relative),a=await Je(o.root,o.relative);await r([i,a],()=>{if(rt(s.root,s.relative),rt(o.root,o.relative),Ag(a)){let c=qt(i),u=qt(a),f=Zo(ds(i));if((c.dev===u.dev&&c.ino===u.ino&&f===Zo(ds(a))?mg(f).filter(y=>{let h=qt($t(f,y));return h.dev===c.dev&&h.ino===c.ino}):[]).length!==1)throw Error("Local rename destination exists");us(i,a);return}fs(ds(a),{recursive:!0});let l=qt(i);if(l.isDirectory()){if(process.platform==="win32"){us(i,a);return}fs(a,{mode:448});try{us(i,a)}catch(c){try{Sg(a)}catch{}throw c}}else{bg(i,a);let c=qt(i);if(c.ino!==l.ino||c.dev!==l.dev)throw Error("Source changed during rename");wg(i)}})}function Ag(t){try{return qt(t),!0}catch(e){if(e.code==="ENOENT")return!1;throw e}}var Ng=()=>({config:structuredClone(Ll),owned:!1,paused:!1,folders:{},files:{},jobs:[]}),vn=50*1024*1024,jg=10*6e4,du=1024*1024,Ie=(t,e)=>`${t}:${e}`,St=t=>t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",Vt=t=>t.slice(t.lastIndexOf("/")+1),ir=Ee(""),ci=t=>t==="human/MEMORY.md"||/^agents\/[a-z0-9][a-z0-9-]{0,63}\/MEMORY\.md$/.test(t),Mt=t=>t.split("/").length,De=t=>t instanceof Error?t.message:String(t),Fg={upload:"uploads",download:"downloads",merge:"merges",rename:"renames",delete:void 0},ui=t=>t.file.replace(/\.json$/,".bases"),gu=5e3,Lg=3e4,fu=3e4,Ug=3e3,ar=10*6e4,di=t=>/^(agents|human)\//.test(t)?Lg:gu,Hg=t=>Math.max(t.mtime,t.ctime);function mu(t){if(!t.contentSync)return;let e=new fi(t);for(let[n,r]of Object.entries({[lt.get]:s=>e.snapshot(s),[lt.preview]:s=>e.preview(s),[lt.apply]:(s,o)=>e.apply(typeof s=="string"?s:"",o),[lt.run]:()=>e.kick(),[lt.pause]:s=>e.pause(s===!0),[lt.retry]:()=>e.kick(),[lt.rename]:s=>e.rename(s),[lt.setup]:s=>e.setup(s),[lt.archiveSeen]:()=>e.archiveSeen()}))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:De(i)}}});t.addQuitGuard?.(n=>e.running&&!e.quitting?{message:n==="zh"?"\u8FD8\u6709\u5185\u5BB9\u6B63\u5728\u540C\u6B65":"Content is still syncing"}:null),t.addFlushHook?.(n=>e.flush(n)),Xl(()=>e.stats()),e.start()}var fi=class{session=null;initializing=null;previewValue=null;watcher=null;sources=[];agentNames=new Map;cloudAgents;sourcesAt=0;devices=[];others;deviceId="";customName="";serial=Promise.resolve();scheduled=null;tick=null;first=null;blocked=new Map;phase="idle";lastError;get error(){return this.lastError}set error(e){this.lastError=e,e&&this.fault(e)}runLog=new Gn;logAccount=null;runAccount=null;blockedError=void 0;live(){let e=this.host.accountId();return!!e&&e===this.logAccount&&(!this.running||!this.runAccount||this.runAccount===e)}tally(e){this.live()&&this.runLog.count(e)}fault(e,n=[]){this.live()&&this.runLog.fault(e,n)}health=Fr((e,n,r)=>nt("content",e,n,r));httpStatus=0;closed=!1;runFinished=Promise.resolve();archiving=null;archiveRetry={account:"",at:0};resolving=!1;awaitingBytes=new Map;uiLocale=null;running=!1;quitting=!1;again=!1;flushing=null;flushRequest=0;flushThrough=0;dirty=new Map;flushAt=0;due=null;registered=null;devicesAt=0;changedAt=0;wroteLocal=!1;openJobs=new Set;host;options;accountGeneration=0;stopAccountWatch;constructor(e,n={}){this.host=e,this.options=n,this.stopAccountWatch=$a(e,()=>{this.accountGeneration++,this.previewValue=null,this.session?.abort.abort(new Error("account_changed"))})}start(){(this.tick=setInterval(()=>{this.run()},3e4)).unref?.(),(this.first=setTimeout(()=>{this.run()},5e3)).unref?.()}locale(){if(this.uiLocale)return this.uiLocale;try{return/^zh/i.test(Intl.DateTimeFormat().resolvedOptions().locale)?"zh":"en"}catch{return"zh"}}archiveStep(e){if(e.stored.accountReview||e.stored.agentArchive?.state==="done"||this.archiveRetry.account===e.account&&Date.now()<this.archiveRetry.at)return Promise.resolve();let n=()=>{this.archiveRetry={account:e.account,at:Date.now()+ar}};return this.archiving??=(async()=>{try{let r=this.host.readCreds();if(!r.token)return;let s=await fetch(r.cloudUrl.replace(/\/+$/,"")+"/api/remotesync/agent-archive",{method:"POST",headers:{Authorization:`Bearer ${r.token}`,"Content-Type":"application/json","X-Content-Device":this.deviceId},body:JSON.stringify({locale:this.locale()}),signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(6e4)])});if(this.guard(e),!s.ok){n();return}let o=await s.json();if(this.guard(e),o.state!=="done"&&o.state!=="running"){n();return}let i=e.stored.agentArchive,a=o.archive;i?.rewritten||this.turnAgentsOff(e);let l={rewritten:!0,seen:i?.seen??!1,state:o.state};o.state==="done"&&(a?.folderId?Object.assign(l,{folderId:a.folderId,name:a.name??void 0,shelfId:a.shelfId??void 0,shelfName:a.shelfName??void 0,files:a.files??0,at:a.at??Date.now()}):l.seen=!0),e.stored.agentArchive=l,await this.persist(e)}catch(r){if(De(r)==="account_changed"||e.abort.signal.aborted)return;n(),this.host.log?.(`[content-sync] agent archive: ${De(r)}`)}finally{this.archiving=null}})()}turnAgentsOff(e){let n=e.stored.config;if(!n.enabled&&n.revision===0)return;let r=Yl(n);if(!r)return;e.stored.config=Dt(r,n.revision+1);let s=o=>o==="agents"||o.startsWith("agents/");for(let[o,i]of Object.entries(e.stored.files))s(i.path)&&(delete e.stored.files[o],delete e.stored.unconfirmed?.[o]);for(let[o,i]of Object.entries(e.stored.folders))s(i.path)&&delete e.stored.folders[o];for(let[o,i]of Object.entries(e.stored.pendingUploads??{}))s(i.path)&&delete e.stored.pendingUploads[o];this.previewValue=null}async archiveSeen(){let e=await this.getSession();e.stored.agentArchive&&(e.stored.agentArchive.seen=!0,await this.persist(e))}async close(){this.closed=!0,this.stopAccountWatch(),this.tick&&clearInterval(this.tick),this.first&&clearTimeout(this.first),this.scheduled&&clearTimeout(this.scheduled),this.due&&clearTimeout(this.due),this.session?.abort.abort(),await this.watcher?.close(),await this.runFinished}currentBinding(e){if(!e.binding)return!0;let n=On(e.binding.file);return n!==null&&!n.pending&&n.account===e.binding.account&&n.epoch===e.binding.epoch}guard(e,n=!0){if(this.closed)throw Error("content_sync_closed");if(to(this.host),this.host.accountId()!==e.account||this.session!==e||e.generation!==this.accountGeneration)throw Error("account_changed");if(!this.currentBinding(e))throw Error("content_account_changed_preview_required");n&&e.abort.signal.throwIfAborted()}async accountWrite(e,n){let r=async()=>{this.guard(e),await n(e.account),this.guard(e)};this.host.accountTransition?await this.host.accountTransition(r):await r()}async persist(e){let n=e.writes.catch(()=>{}).then(async()=>{this.guard(e,!1);let r=JSON.stringify(e.stored);if(r===e.persisted)return;await ii(Wt(e.file),{recursive:!0,mode:448});let s=e.file+".tmp-"+et();try{await nr(s,r,{mode:384,flag:"wx"}),this.guard(e,!1),await ms(s,e.file),e.persisted=r}finally{await sr(s).catch(()=>{})}});return e.writes=n,n}async getSession(){let e=this.host.accountId();if(!e)throw this.logAccount&&(this.runLog.reset(),this.logAccount=null),this.session?.abort.abort(),this.session=null,Error("not_signed_in");let n=this.accountGeneration;return to(this.host),this.initializing?this.initializing.then(r=>(this.guard(r),r)):this.session?.account===e&&this.session.generation===n&&this.currentBinding(this.session)?(this.guard(this.session,!1),this.session):(this.session?.abort.abort(new Error("account_changed")),this.logAccount!==e&&(this.runLog.reset(),this.logAccount=e),this.initializing=(async()=>{await this.watcher?.close(),this.watcher=null,this.previewValue=null,this.sources=[],this.agentNames.clear(),this.cloudAgents=void 0,this.devices=[],this.dirty.clear(),this.registered=null,this.devicesAt=0,this.changedAt=0;let r=Te(this.host.homeDir(),"content-sync"),s=Te(r,Ee(e)+".json"),o=Ng();try{let f=JSON.parse(await tr(s,"utf8"));tu(f),o={...o,...f,config:Dt(f.config,f.config.revision)},o.jobs=Array.isArray(f.jobs)?f.jobs.slice(-200):[]}catch(f){if(f.code!=="ENOENT")throw Error("Invalid content sync state; original data was retained")}let i,a=Te(this.host.homeDir(),"content-sync-device.json"),l=async()=>{let f=JSON.parse(await tr(a,"utf8"));if(typeof f?.id!="string"||!/^[A-Za-z0-9_-]{1,64}$/.test(f.id))throw Error("Invalid device sync ID");return f};try{i=await l()}catch(f){if(f.code!=="ENOENT")throw f;i={id:et()},await ii(Wt(a),{recursive:!0});try{await nr(a,JSON.stringify(i),{flag:"wx",mode:384})}catch(g){if(g.code!=="EEXIST")throw g;i=await l()}}if(this.host.accountId()!==e)throw Error("account_changed");this.deviceId=i.id,this.customName=typeof i.name=="string"?i.name:"";let c=await this.host.contentSync.roots();if(this.host.accountId()!==e)throw Error("account_changed");let u={account:e,generation:n,file:s,stored:o,roots:c,abort:new AbortController,writes:Promise.resolve(),manifests:new Map};return this.session=u,await this.bindAccount(u),await this.recoverTrash(u),this.guard(u),o.owned&&await this.accountWrite(u,f=>this.host.contentSync.claim(!0,f)),this.setSources(await this.scan(u,c).catch(f=>(this.error=De(f),[]))),await this.register(u,!0),await this.watchRoots(u),u})().catch(r=>{throw this.session?.account===e&&(this.session.abort.abort(),this.session=null),r}).finally(()=>{this.initializing=null}),this.initializing)}async bindAccount(e){let n=Wt(e.file),r=Qs(this.host.homeDir()),s=Ee(e.account),o=On(r),i=!o?.account&&(await rr(n).catch(l=>{if(l.code==="ENOENT")return[];throw l})).some(l=>/^[a-f0-9]{64}\.json$/.test(l)&&l!==s+".json"),a=o?.pending&&(e.stored.owned||e.stored.config.revision>0);if((o?.account&&o.account!==s||i||a)&&(e.stored.accountReview=!0,e.stored.owned=!0,e.stored.config.enabled&&(e.stored.config={...e.stored.config,enabled:!1,revision:e.stored.config.revision+1}),await this.persist(e)),o?.account!==s||o.pending){this.guard(e,!1);let l=On(r);if(l?.account!==o?.account||l?.epoch!==o?.epoch||l?.pending!==o?.pending)throw Error("account_changed");eo(r,{version:1,account:s,...o?.epoch?{epoch:o.epoch}:{}})}e.binding={file:r,account:s,epoch:o?.epoch},this.guard(e,!1)}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 ys(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 gs(n)}async write(e,n,r,s){this.guard(e),await ri(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 ys(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(),this.wroteLocal=!0};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 bt(r.root).catch(()=>{throw Error(`Sync root unavailable: ${r.prefix||"Forsion"}`)});return gs(n)}async watchRoots(e){this.options.watch!==!1&&(this.guard(e),await this.watcher?.close(),this.watcher=Ms(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",(n,r)=>{let s=this.logical(e,r),o=Date.now();if(s){let i=this.dirty.get(s);i?i.last=o:this.dirty.set(s,{first:o,last:o})}this.schedule(s?void 0:o+gu)}))}logical(e,n){let r=null;for(let i of e.roots)(n===i.root||n.startsWith(i.root+Sn))&&(!r||i.root.length>r.root.length)&&(r=i);if(!r)return null;let s=or(r.root,n).split(Sn).join("/");return(r.prefix?s?`${r.prefix}/${s}`:r.prefix:s)||null}dueAt(e,n){return n.last<=this.flushAt?0:Math.min(n.last+di(e),n.first+fu)}schedule(e){let n=e??1/0;for(let[r,s]of this.dirty)n=Math.min(n,this.dueAt(r,s));this.due&&clearTimeout(this.due),this.due=null,!(n===1/0||this.closed)&&(this.due=setTimeout(()=>{this.due=null;let r=this.session;r?.stored.config.enabled&&!r.stored.paused&&this.kick()},Math.max(0,n-Date.now())+50),this.due.unref?.())}kick(){if(this.running){this.again=!0;return}this.run()}flush(e){let n=this.session;if(!(this.closed||!this.host.accountId()||n&&(!n.stored.config.enabled||n.stored.paused)))return this.flushRequest++,this.flushThrough=Math.max(this.flushThrough,Date.now()),e==="quit"&&(this.quitting=!0),this.flushAt=this.quitting?1/0:this.flushThrough,this.flushing?this.flushing:this.flushing=(async()=>{try{for(;!this.closed;){let r=this.serial;if(await r,r!==this.serial)continue;if(this.running){await this.runFinished;continue}let s=this.flushRequest;if(await this.run(),s===this.flushRequest)return}}finally{this.flushing=null,this.quitting=!1,this.flushAt=this.flushThrough}})()}async request(e,n,r="",s="GET",o,i,a){this.guard(e);let l=this.host.readCreds();if(!l.token)throw Error("not_signed_in");let c=l.cloudUrl.replace(/\/+$/,"")+`/api/remotesync/content/${encodeURIComponent(n)}${r}`,u={Authorization:`Bearer ${l.token}`,"X-Content-Device":this.deviceId,...a},f;if(o instanceof Buffer){u["Content-Type"]="application/octet-stream",u["Content-Length"]=String(o.length);let y=async function*(){for(let h=0;h<o.length;h+=64*1024)e.abort.signal.throwIfAborted(),yield o.subarray(h,h+64*1024),i?.(Math.min(o.length,h+64*1024))};f=uu.from(y())}else o!==void 0&&(u["Content-Type"]="application/json",f=JSON.stringify(o));let g={method:s,headers:u,body:f,signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(12e4)]),...o instanceof Buffer?{duplex:"half"}:{}},p=await fetch(c,g);if(this.guard(e),!p.ok&&!(p.status===304&&a?.["If-None-Match"])){this.httpStatus=p.status;let y=await p.json().catch(()=>({}));throw Object.assign(new Error(typeof y.detail=="string"?y.detail:`content_http_${p.status}`),{status:p.status})}return s==="DELETE"&&this.tally("deletesSent"),p}async json(e,n,r="",s="GET",o){let i=await(await this.request(e,n,r,s,o)).json();return this.guard(e),i}async manifests(e,n){let r=new Map;for(let o of new Set(n.rules.filter(i=>i.target!=="off").map(i=>i.target))){let i=JSON.parse(await this.manifestText(e,o));cs(i,o),r.set(o,i)}let s=[r.get("default"),r.get(`device-${this.deviceId}`)].filter(Boolean);return s.length&&(this.cloudAgents=[...new Set(s.flatMap(o=>o.nodes.filter(i=>!i.deleted&&i.kind==="file").map(i=>/^agents\/([^/]+)\/config\.toml$/.exec(i.path)?.[1]).filter(i=>!!i&&Vn.test(i))))].sort()),r}async manifestText(e,n){let r=e.manifests.get(n),s=r&&Date.now()-r.at<ar?r:void 0,o=await this.request(e,n,"","GET",void 0,void 0,s?{"If-None-Match":s.etag}:void 0);if(o.status===304)return await o.body?.cancel(),s?s.text:(e.manifests.delete(n),this.manifestText(e,n));let i=await o.text();this.guard(e),cs(JSON.parse(i),n);let a=o.headers.get("etag");return a?e.manifests.set(n,{etag:a,text:i,at:Date.now()}):e.manifests.delete(n),i}route(e,n,r="file"){if(rs(e)||Jo(e,r)===!1)return null;let s=ln(e,n.rules);return s&&s.target!=="off"?s.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)}}deviceName(){return this.customName||Zr(ai())}setSources(e){let n=new Map,r={files:0,size:0};for(let o of e)o.kind==="folder"&&n.set(o.path,{size:0,files:0});for(let o of e)if(o.kind==="file"){Ul.some(i=>o.path.startsWith(i+"/"))||(r.files++,r.size+=o.size);for(let i=St(o.path);i;i=St(i)){let a=n.get(i);a&&(a.size+=o.size,a.files++)}}let s=new Map(e.filter(o=>o.kind==="file"&&/^agents\/[^/]+\/config\.toml$/.test(o.path)).map(o=>[o.path.slice(0,-12),o]));this.others=r,this.sources=[...n].sort(([o],[i])=>Mt(o)-Mt(i)||(o<i?-1:1)).slice(0,2e3).map(([o,i])=>({path:o,kind:"folder",size:i.size,files:i.files,...Yn(o)&&s.has(o)?{agent:!0}:{}})),this.sourcesAt=Date.now(),this.readAgentNames(s)}async readAgentNames(e){for(let n of this.agentNames.keys())e.has(n)||this.agentNames.delete(n);for(let[n,r]of e){let s=`${r.mtime}:${r.size}`;if(!(this.agentNames.get(n)?.key===s||r.size>256*1024))try{this.agentNames.set(n,{key:s,...Hl((await wn(r)).toString("utf8"))})}catch{this.agentNames.set(n,{key:s})}}}async rename(e){let n=typeof e=="string"?e.trim():"";if(n.length>64||/[\u0000-\u001f\u007f]/.test(n))throw Error("Invalid device name");let r=await this.getSession(),s=n||Zr(ai()),o=Do(s,this.devices,this.deviceId);if(o)throw Error(o==="taken"?"device_name_taken":o==="reserved"?"device_name_reserved":"device_name_invalid");return await this.json(r,"devices",`/${encodeURIComponent(this.deviceId)}`,"PUT",{name:s,unique:!0}),await this.saveName(n),await this.register(r,!0),this.deviceName()}async saveName(e){let n=Te(this.host.homeDir(),"content-sync-device.json"),r=n+".tmp-"+et();try{await nr(r,JSON.stringify({id:this.deviceId,...e?{name:e}:{}}),{mode:384,flag:"wx"}),await ms(r,n)}finally{await sr(r).catch(()=>{})}this.customName=e}async register(e,n=!1){let r=Date.now();if(!n&&this.registered?.name===this.deviceName()&&r-this.registered.at<ar){r-this.devicesAt>=ar&&await this.refreshDevices(e);return}let s=(a,l)=>this.json(e,"devices",`/${encodeURIComponent(this.deviceId)}`,"PUT",{name:a,...l?{unique:!0}:{}}),o=async()=>(await this.json(e,"devices")).devices,i=a=>/device_name_(taken|reserved|invalid)/.test(De(a));try{await s(this.deviceName(),!0)}catch(a){if(!i(a))throw a;let l=!1;if(!this.customName){let c=Zr(ai());for(let u=0;u<5&&!l;u++){let f=await o(),g=null;for(let p=2;p<100&&!g;p++){let y=`${c} ${p}`;Do(y,f,this.deviceId)||(g=y)}if(!g)break;try{await s(g,!0),await this.saveName(g),l=!0}catch(p){if(!i(p))throw p}}}l||await s(this.deviceName(),!1)}this.registered={name:this.deviceName(),at:r},await this.refreshDevices(e)}async refreshDevices(e){this.devicesAt=Date.now(),this.devices=(await this.json(e,"devices")).devices,await this.cacheDevices()}cachedDevices="";async cacheDevices(){let e=Te(this.host.homeDir(),"content-sync-devices.json"),n=[];try{let a=JSON.parse(await tr(e,"utf8"));Array.isArray(a?.devices)&&(n=a.devices)}catch{}let r=new Map(n.filter(a=>a&&typeof a.id=="string").map(a=>[a.id,a])),s=this.devices.map(a=>{let l=r.get(a.id),c=[...Array.isArray(l?.aliases)?l.aliases:[],...l&&typeof l.name=="string"&&l.name!==a.name?[l.name]:[]],u=c.filter((f,g)=>typeof f=="string"&&f!==a.name&&c.lastIndexOf(f)===g).slice(-5);return{id:a.id,name:a.name,...u.length?{aliases:u}:{}}}),o=JSON.stringify({devices:s});if(o===this.cachedDevices)return;let i=e+".tmp-"+et();try{await nr(i,o,{mode:384,flag:"wx"}),await ms(i,e),this.cachedDevices=o}catch(a){this.error=De(a)}finally{await sr(i).catch(()=>{})}}async setup(e){let n=await this.getSession(),r=e&&typeof e=="object"?e:{};if(n.stored.config.enabled||n.stored.config.revision>0)return null;let s=un(Wl(n.stored.config),"","off");for(let a of yt)a.id!=="agents"&&r[a.id]===!1&&(s=un(s,a.path,"off"));let o=new Set(this.sources.filter(a=>a.agent).map(a=>a.path.slice(7))),i=Array.isArray(r.agentSlugs)?r.agentSlugs.slice(0,512).filter(a=>typeof a=="string"&&o.has(a)):[];return this.preview(Vl(s,i))}async snapshot(e){(e==="zh"||e==="en")&&(this.uiLocale=e);let n=await this.getSession();return!n.stored.config.enabled&&!this.running&&Date.now()-this.sourcesAt>1e4&&(this.sourcesAt=Date.now(),this.scan(n).then(r=>{this.session===n&&this.setSources(r)},()=>{})),Date.now()-this.devicesAt>6e4&&(this.devicesAt=Date.now(),this.refreshDevices(n).catch(()=>{})),{available:!0,account:Ee(n.account),deviceId:this.deviceId,deviceName:this.deviceName(),config:structuredClone(n.stored.config),running:this.running,paused:n.stored.paused,phase:this.phase,jobs:structuredClone(n.stored.jobs),devices:this.devices,sources:this.sources.map(r=>{let s=r.agent&&this.agentNames.get(r.path);return s?{...r,...s.name?{name:s.name}:{},...s.nameEn?{nameEn:s.nameEn}:{}}:r}),...this.cloudAgents?{cloudAgents:this.cloudAgents}:{},...this.others?{others:this.others}:{},...n.stored.accountReview?{error:"content_account_changed_preview_required"}:this.error?{error:this.error}:{},...n.stored.agentArchive?{agentArchive:(({rewritten:r,...s})=>s)(n.stored.agentArchive)}:{}}}stats(){let e=this.host.accountId(),n=e&&this.session?.account===e?this.session:null,r=n?.stored,s={},o=e&&e===this.logAccount?this.runLog.snapshot():new Gn().snapshot();for(let i of r?.jobs??[])s[i.state]=(s[i.state]??0)+1;return{deviceId:this.deviceId||null,session:!!n,enabled:!!r?.config.enabled,paused:!!r?.paused,running:!!n&&this.running,phase:n?this.phase:"idle",revision:r?.config.revision??0,rules:(r?.config.rules??[]).map(i=>({source:i.source,target:i.target})),backlog:r?{jobs:s,blocked:[...this.blocked.values()].reduce((i,a)=>i+a.length,0),pendingUploads:Object.keys(r.pendingUploads??{}).length,unconfirmed:Object.keys(r.unconfirmed??{}).length,trash:r.trash?.length??0,awaitingBytes:this.awaitingBytes.size,dirty:this.dirty.size}:null,archive:r?.agentArchive?.state??null,...o}}async preview(e){let n=await this.getSession();if(e?.revision!==n.stored.config.revision)throw Error("config_changed");let s=Dt(e,n.stored.config.revision+1),o=await this.host.contentSync.roots();this.guard(n);let i=await this.previewScan(n,o),a=this.effective(s,i);if(n.stored.agentArchive?.state==="running"&&i.some(w=>w.kind==="file"&&w.path.startsWith("agents/")&&this.route(w.path,a)))throw Error("agent_archive_running");let l=await this.manifests(n,a);this.guard(n),this.setSources(i);let c=0,u=0,f=0,g=0,p=new Map;for(let w of i.filter(_=>_.kind==="file")){let _=this.route(w.path,a);if(!_)continue;let $=l.get(_)?.nodes.find(O=>!O.deleted&&O.kind==="file"&&O.path===w.path);if(w.size>vn){c++,g+=w.size;continue}let R=Ee(await wn(w));this.guard(n),p.set(w.path,R),R!==$?.hash&&(c++,g+=w.size,$?.version&&f++)}let y=s.enabled?this.agentAsks(n,i,a,l,p):[];for(let[w,_]of l)for(let $ of _.nodes)!$.deleted&&$.kind==="file"&&$.version&&this.route($.path,a)===w&&!i.some(R=>R.path===$.path)&&u++;let h=this.signature(i,l,o),m={token:et(),config:a,upload:s.enabled?c:0,download:s.enabled?u:0,conflicts:s.enabled?f:0,bytes:s.enabled?g:0,oldTargetsRetained:!0,expiresAt:Date.now()+5*6e4,...y.length?{agentAsks:y}:{}};return this.previewValue={value:m,account:n.account,signature:h},m}signature(e,n,r){return Ee(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,n){let r=this.serial,s;this.serial=new Promise(o=>{s=o}),await r;try{let o=await this.getSession(),i=this.previewValue;if(!i||i.value.token!==e||i.account!==o.account||i.value.expiresAt<Date.now()||i.value.config.revision!==o.stored.config.revision+1)throw Error("preview_expired");if(this.running)throw Error("sync_in_progress");let a=i.value.agentAsks??[],l=zg(n);this.resolving=!0;try{let c=await this.host.contentSync.roots(),u=await this.previewScan(o,c),f=await this.manifests(o,i.value.config);if(this.signature(u,f,c)!==i.signature)throw Error("preview_changed");let g=[];for(let m of c){let w=await ys(m.root).catch(_=>{if(_.code==="ENOENT")return null;throw _});w&&g.push({...m,dev:w.dev,ino:w.ino})}let p=structuredClone(i.value.config);for(let m of p.rules){let w=u.find(_=>_.kind==="folder"&&_.path===m.source);w&&(m.sourceId=await ni(w))}let y=a.length?Dt(a.reduce((m,w)=>un(m,`agents/${w.slug}`,"off"),p),p.revision):p;if(this.guard(o),this.previewValue!==i||i.value.config.revision!==o.stored.config.revision+1)throw Error("preview_expired");let h=structuredClone(o.stored);o.stored.config=y,o.stored.owned=!0,o.stored.paused=!1,delete o.stored.unconfirmed;for(let[m,w]of Object.entries(o.stored.files))(h.config.enabled!==o.stored.config.enabled||JSON.stringify(h.roots??g)!==JSON.stringify(g)||this.route(w.path,h.config)!==this.route(w.path,o.stored.config))&&delete o.stored.files[m];for(let[m,w]of Object.entries(o.stored.folders))(h.config.enabled!==o.stored.config.enabled||JSON.stringify(h.roots??g)!==JSON.stringify(g)||this.route(w.path,h.config,"folder")!==this.route(w.path,o.stored.config,"folder"))&&delete o.stored.folders[m];o.stored.roots=g,await this.persist(o);try{await this.accountWrite(o,m=>this.host.contentSync.claim(!0,m))}catch(m){throw o.stored=h,await this.persist(o),await this.accountWrite(o,w=>this.host.contentSync.claim(h.owned,w)).catch(()=>{}),m}if(this.previewValue=null,o.roots=c,await this.watchRoots(o),a.length)try{await this.resolveAsks(o,a,l,p)}catch(m){throw this.fault(De(m)),m}o.stored.accountReview&&(delete o.stored.accountReview,await this.persist(o))}finally{this.resolving=!1}}finally{s()}this.run()}async pause(e){let n=await this.getSession();if(!e&&n.stored.accountReview)throw Error("content_account_changed_preview_required");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(l=>l.path===n&&l.target===r&&l.direction===s&&["failed","paused","queued"].includes(l.state));if(i)return Object.assign(i,{state:"active",done:0,size:o,at:Date.now(),error:void 0,finishedAt:void 0}),i;let a={id:et(),path:n,target:r,direction:s,state:"active",done:0,size:o,at:Date.now()};return e.stored.jobs.push(a),e.stored.jobs=e.stored.jobs.slice(-200),a}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 a=this.job(e,n,r,s,o);try{let l=await i(a);if(this.guard(e),e.stored.paused)throw Error("paused");this.done(a),s==="upload"?nt("content","uploads"):s==="download"&&nt("content","downloads");let c=Fg[s];return c&&this.tally(c),l}catch(l){throw a.state=e.stored.paused?"paused":"failed",a.error=De(l),a.finishedAt=Date.now(),l}}async run(){if(this.running||this.closed||this.resolving)return;this.running=!0;let e;this.runFinished=new Promise(a=>{e=a});let n=Date.now();this.wroteLocal=!1;let r=new Set,s,o=!1,i=!1;try{if(s=await this.getSession(),this.runAccount=s.account,s.stored.accountReview){this.error="content_account_changed_preview_required";return}if(await this.archiveStep(s),!s.stored.config.enabled||s.stored.paused)return;s.abort.signal.aborted&&(s.abort=new AbortController),this.blocked.clear(),this.phase="scanning",this.error=void 0,o=!0,this.httpStatus=0,this.live()&&this.runLog.begin(n);let a=await this.host.contentSync.roots();this.guard(s),s.roots=a,await this.host.contentSync.agentFiles?.prepare().catch(m=>{this.error=De(m)}),this.guard(s);let l=await this.scan(s,a);await this.recordRoots(s);let c=this.effective(s.stored.config,l),u=await this.manifests(s,c);this.guard(s),await this.register(s),this.openJobs=new Set(s.stored.jobs.filter(m=>["failed","paused","active"].includes(m.state)&&["upload","download","merge"].includes(m.direction)).map(m=>m.target+"\0"+m.path)),await this.folders(s,c,l,u),await this.recordRoots(s),await this.fileRenames(s,c,l,u),l=await this.scan(s,a),c=this.effective(c,l),s.stored.config=c,this.setSources(l),this.phase="syncing";let f=m=>m.endsWith("/"+Qn),g=new Set,p=new Set,y=m=>m.startsWith("agents/")?m.slice(0,m.lastIndexOf("/")+1):null,h=m=>m.endsWith("/MEMORY.md")&&p.has(y(m)??"");for(let[m,w]of u)for(let _ of w.nodes.filter($=>$.kind==="file"&&!$.busy&&f($.path))){if(this.guard(s),s.stored.paused)throw Error("paused");if(!(this.route(_.path,c)!==m||l.some($=>$.path===_.path))){if(this.isBlocked(m,_.path)){p.add(y(_.path)??"");continue}g.add(_.id);try{await this.missing(s,_,m,l,c)}catch($){this.error=De($),p.add(y(_.path)??"")}}}for(let m of l.filter(w=>w.kind==="file").sort((w,_)=>+!f(w.path)-+!f(_.path))){if(this.guard(s),s.stored.paused)throw Error("paused");let w=this.route(m.path,c);if(!(!w||h(m.path))){if(this.isBlocked(w,m.path)){f(m.path)&&p.add(y(m.path)??"");continue}try{await this.file(s,c,m,w,u.get(w))==="held"&&r.add(m.path)}catch(_){this.error=De(_),f(m.path)&&p.add(y(m.path)??"")}}}for(let[m,w]of u)for(let _ of w.nodes.filter($=>$.kind==="file"&&!$.busy&&!g.has($.id))){if(this.guard(s),s.stored.paused)throw Error("paused");if(!(this.isBlocked(m,_.path)||this.route(_.path,c)!==m||l.some($=>$.path===_.path)||h(_.path))){if(this.holdGone(_.path)){r.add(_.path);continue}try{await this.missing(s,_,m,l,c)}catch($){this.error=De($)}}}await this.cleanupFolders(s,c,u),this.wroteLocal&&Date.now()-this.devicesAt>=6e4&&await this.refreshDevices(s).catch(()=>{}),(this.wroteLocal||Date.now()-this.changedAt>=ar)&&(await this.accountWrite(s,m=>this.host.contentSync.changed(m)),this.changedAt=Date.now()),this.guard(s),await this.persist(s),await this.pruneBases(s),i=!0}catch(a){this.error=De(a)}finally{this.phase=s?.stored.paused?"paused":"idle",o&&(this.noteHealth(n,i),this.live()&&this.runLog.end(i));for(let[a,l]of this.dirty)!r.has(a)&&l.last<n&&this.dirty.delete(a);s&&this.host.accountId()===s.account&&(await this.persist(s).catch(()=>{}),!this.closed&&s.abort.signal.aborted&&!s.stored.paused&&s.stored.config.enabled&&(s.abort=new AbortController,this.again=!0)),this.running=!1,this.runAccount=null,this.again&&!this.closed?(this.again=!1,queueMicrotask(()=>void this.run())):this.schedule(),e()}}noteHealth(e,n){n&&(nt("content","cycles"),nt("content","cycleMsTotal",Math.max(0,Date.now()-e)));let r=this.blocked.size?"errBlocked":this.error?jr(this.error,this.httpStatus):null;r?this.health.error(r):this.error||this.health.ok()}holdGone(e){let n=this.dirty.get(e);if(!n)return!1;let r=Date.now();return n.last>this.flushAt&&r-n.last<di(e)&&r-n.first<fu}isBlocked(e,n){return(this.blocked.get(e)??[]).some(r=>n===r||n.startsWith(r+"/"))}block(e,n,r){if(this.blocked.set(e,[...this.blocked.get(e)??[],n]),this.lastError=De(r),r!==void 0&&r===this.blockedError){this.live()&&this.runLog.addPaths([n]);return}this.blockedError=r,this.fault(De(r),[n])}async folders(e,n,r,s){let o=r.filter(a=>a.kind==="folder"),i=new Map;for(let a of o)if(a.localId){if(i.has(a.localId))throw Error(`Duplicate folder sync identity: ${a.path}`);i.set(a.localId,a.path)}for(let[a,l]of s){for(let c of l.nodes.filter(u=>u.kind==="folder"&&!u.deleted&&!u.busy).sort((u,f)=>Mt(u.path)-Mt(f.path)))if(!this.isBlocked(a,c.path))try{let u=Object.entries(e.stored.folders).find(([g,p])=>g.startsWith(a+":")&&p.id===c.id)?.[1],f=(u?o.find(g=>g.localId===u.localId):null)??o.find(g=>g.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,"folder")!==a)continue;if(this.route(c.path,n,"folder")!==a)throw Error("Remote rename crosses a sync rule; review the destination");await this.operation(e,f.path,a,"rename",null,()=>si(e.roots,f.path,c.path,(p,y)=>this.lock(e,p,y)));let g=f.path;for(let p of r)if(p.path===g||p.path.startsWith(g+"/")){let y=p.path;p.path=c.path+y.slice(g.length);let h=je(e.roots,p.path);p.physical=Te(h.root,h.relative)}for(let[p,y]of Object.entries(e.stored.files))p.startsWith(a+":")&&y.path.startsWith(u.path+"/")&&(y.path=c.path+y.path.slice(u.path.length));for(let p of n.rules)(p.source===u.path||p.source.startsWith(u.path+"/"))&&(p.source=c.path+p.source.slice(u.path.length))}if(!f&&this.route(c.path,n,"folder")===a&&!u){await cu(e.roots,c.path,(p,y)=>this.lock(e,p,y));let g=(await this.scan(e)).find(p=>p.path===c.path);g&&(r.push(g),o.push(g))}}catch(u){this.block(a,c.path,u),this.tally("folderConflicts");let f=Object.entries(e.stored.folders).find(([g,p])=>g.startsWith(a+":")&&p.id===c.id)?.[1];f&&this.block(a,f.path,u)}for(let c of o.sort((u,f)=>Mt(u.path)-Mt(f.path)))if(!this.isBlocked(a,c.path))try{let u=this.route(c.path,n,"folder"),f=n.rules.some(w=>w.target===a&&w.source.startsWith(c.path+"/"));if(u!==a&&!f||Jo(c.path,"folder")===!1)continue;let g=await ni(c),p=e.stored.folders[Ie(a,g)],y=p?l.nodes.find(w=>w.id===p.id):l.nodes.find(w=>w.path===c.path&&!w.deleted);if(y?.deleted){if(p){let w=!1;for(let _ of r.filter($=>$.kind==="file"&&$.path.startsWith(c.path+"/")&&this.route($.path,n)===a)){let $=Object.entries(e.stored.files).find(([R,O])=>R.startsWith(a+":")&&O.path===_.path)?.[1];if(!$){w=!0;break}if(!this.sameAsShadow($,_)){let R=Ee(await wn(_));if(R!==$.hash&&!($.memoryDeleted&&ci(_.path)&&R===ir)){w=!0;break}}}if(!w)continue}y=void 0}let h=St(c.path),m=h?l.nodes.find(w=>w.path===h&&w.kind==="folder"&&!w.deleted)?.id:"";if(h&&!m)throw Error("Cloud parent is unavailable");if(!y)y=await this.json(e,a,"/nodes","POST",{id:p?et():g,parentId:m,name:Vt(c.path),kind:"folder"}),l.nodes.push(y);else if(p&&y.path!==c.path){if(y.revision!==p.revision)throw Error(`Concurrent folder rename: ${c.path}`);let w=y.path,_=await this.operation(e,c.path,a,"rename",null,()=>this.json(e,a,`/nodes/${y.id}`,"PATCH",{parentId:m,name:Vt(c.path),revision:y.revision}));for(let $ of l.nodes)$.path.startsWith(w+"/")&&($.path=c.path+$.path.slice(w.length));Object.assign(y,_);for(let[$,R]of Object.entries(e.stored.files))$.startsWith(a+":")&&R.path.startsWith(w+"/")&&(R.path=c.path+R.path.slice(w.length))}e.stored.folders[Ie(a,g)]={id:y.id,localId:g,path:c.path,revision:y.revision,parentId:y.parentId,name:y.name}}catch(u){this.block(a,c.path,u);let f=c.localId?e.stored.folders[Ie(a,c.localId)]:void 0;f&&this.block(a,f.path,u),nt("content","conflicts"),this.tally("folderConflicts");let g=this.job(e,c.path,a,"rename",null);g.state="conflict",g.error=De(u),g.finishedAt=Date.now()}}}async cleanupFolders(e,n,r){let s=await this.scan(e);for(let[o,i]of r)for(let a of i.nodes.filter(l=>l.kind==="folder"&&!l.busy).sort((l,c)=>Mt(c.path)-Mt(l.path))){if(this.isBlocked(o,a.path)||this.route(a.path,n,"folder")!==o)continue;let l=Object.entries(e.stored.folders).find(([u,f])=>u.startsWith(o+":")&&f.id===a.id);if(!l)continue;let c=s.find(u=>u.path===a.path&&u.kind==="folder");if(a.deleted&&c){if(s.some(f=>f.path.startsWith(a.path+"/"))||(await rr(c.physical)).some(f=>f!==".forsion-sync-id.json"))continue;await this.operation(e,a.path,o,"delete",null,()=>this.lock(e,c.physical,()=>{rt(c.root,or(c.root,c.physical).split(Sn).join("/"));let f=Ig(c.physical);if(f.some(y=>y!==".forsion-sync-id.json"))throw Error("Folder changed before deletion");let g=Te(c.physical,".forsion-sync-id.json"),p=f.length?bn(g):null;p&&oi(g);try{Dg(c.physical)}catch(y){if(p)try{Og(g,p,{flag:"wx",mode:384})}catch{}throw y}})),this.tally("deletesLocal"),delete e.stored.folders[l[0]]}else if(!a.deleted&&!c){if(!await this.absent(e,a.path)||i.nodes.some(u=>u.parentId===a.id&&!u.deleted))continue;await this.operation(e,a.path,o,"delete",null,()=>this.json(e,o,`/nodes/${a.id}`,"DELETE",{revision:a.revision,version:null})),a.deleted=!0,delete e.stored.folders[l[0]]}}}async download(e,n,r,s){if(n.size!==void 0&&n.size>vn)throw Error("File exceeds 50 MB content limit");let o=await this.request(e,r,`/nodes/${n.id}/content`),i=[],a=0;if(o.body){let c=o.body.getReader();for(;;){let u=await c.read();if(u.done)break;if(this.guard(e),a+=u.value.length,a>vn)throw await c.cancel(),Error("Content too large");i.push(u.value),s.done=a}}let l=Buffer.concat(i);if(n.hash&&Ee(l)!==n.hash)throw Error("Cloud file changed during download");return l}async fileRenames(e,n,r,s){for(let[o,i]of s)for(let a of i.nodes.filter(l=>l.kind==="file"&&!l.deleted&&!l.busy)){let l=e.stored.files[Ie(o,a.id)];if(!l||l.path===a.path)continue;let c=r.find(u=>u.kind==="file"&&u.path===l.path);if(!(!c||this.route(c.path,n)!==o))try{if(this.route(a.path,n)!==o)throw Error("Remote rename crosses a sync rule; review the destination");await this.operation(e,c.path,o,"rename",null,()=>si(e.roots,c.path,a.path,(u,f)=>this.lock(e,u,f))),l.path=a.path}catch(u){this.block(o,c.path,u),this.block(o,a.path,u)}}}async upload(e,n,r,s,o){if(s.length>vn)throw Error("File exceeds 50 MB content limit");this.guard(e);let i=this.host.readCreds(),a=uu.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)})()),l=await fetch(i.cloudUrl.replace(/\/+$/,"")+`/api/remotesync/content/${encodeURIComponent(r)}/nodes/${n.id}/content`,{method:"PUT",headers:{Authorization:`Bearer ${i.token}`,"X-Content-Device":this.deviceId,"Content-Type":"application/octet-stream","Content-Length":String(s.length),"X-Content-Version":n.version??"create"},body:a,duplex:"half",signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(12e4)])});if(this.guard(e),!l.ok){let c=await l.json().catch(()=>({}));throw Error(c.detail??`content_http_${l.status}`)}return await l.json()}async shadow(e,n,r,s,o,i){let a=Ie(n,r.id),l=Ee(s),c=li(s);c&&s.length>=du&&await this.keepBase(e,l,s);for(let u of e.stored.jobs)u.path===r.path&&u.target===n&&["failed","paused","active"].includes(u.state)&&["upload","download","merge"].includes(u.direction)&&this.done(u);e.stored.pendingUploads&&delete e.stored.pendingUploads[a],delete e.stored.unconfirmed?.[a],e.stored.files[a]={id:r.id,path:r.path,version:r.version,hash:l,...c&&s.length<du?{base:s.toString("utf8")}:{},...i?{inode:i.inode,stat:i.key,statAt:i.at}:o?{inode:o.inode}:{}}}async seen(e,n,r){let s=je(e.roots,n),o=await bt(Te(s.root,...s.relative.split("/"))).catch(()=>null);if(!o?.isFile())return;let i=hs(o);return{key:er(i),at:r,inode:i.inode}}sameAsShadow(e,n){return!this.dirty.has(n.path)&&e.stat!==void 0&&e.statAt!==void 0&&e.stat===er(n)&&Hg(n)<=e.statAt-Ug}unchanged(e,n,r,s,o){let i=Ie(n,r.id);return this.sameAsShadow(s,o)&&s.id===r.id&&s.path===o.path&&!r.busy&&!r.deleted&&r.version===s.version&&r.hash===s.hash&&!e.stored.unconfirmed?.[i]&&!e.stored.pendingUploads?.[i]&&!this.openJobs.has(n+"\0"+o.path)}hold(e,n){if(e.path.endsWith("/"+Qn)||n?.stat===er(e))return!1;let r=e.mtime,s=Date.now(),o=this.dirty.get(e.path);if(Math.floor(r)<=this.flushAt)return!1;if(o)o.last=Math.max(o.last,r);else{if(s-r>=di(e.path))return!1;o={first:Math.min(s,r),last:r},this.dirty.set(e.path,o)}return this.dueAt(e.path,o)>s}settled(e,n){let r=this.dirty.get(e);r&&(r.last<n?this.dirty.delete(e):r.first=n)}async keepBase(e,n,r){let s=ui(e),o=Te(s,n);if(await bt(o).then(()=>!0,()=>!1))return;await ii(s,{recursive:!0,mode:448});let i=o+".tmp-"+et();try{await nr(i,r,{mode:384,flag:"wx"}),await ms(i,o)}finally{await sr(i).catch(()=>{})}}async readBase(e,n){if(n.base!==void 0)return n.base;let r=await tr(Te(ui(e),n.hash)).catch(s=>{if(s.code==="ENOENT")return null;throw s});return r&&Ee(r)===n.hash?r.toString("utf8"):null}async pruneBases(e){let n=new Set(Object.values(e.stored.files).map(s=>s.hash)),r=ui(e);for(let s of await rr(r).catch(()=>[]))n.has(s)||await sr(Te(r,s)).catch(()=>{})}async file(e,n,r,s,o){if(r.size>vn){nt("content","skippedTooLarge",1,r.path),await this.operation(e,r.path,s,"upload",r.size,async()=>{throw Error("File exceeds 50 MB content limit")});return}let i=o.nodes.find(w=>w.kind==="file"&&!w.deleted&&w.path===r.path);if(!i){let w=Object.entries(e.stored.files).find(([_,$])=>_.startsWith(s+":")&&$.inode===r.inode&&$.path!==r.path)?.[1];if(w){let _=je(e.roots,w.path),$=await bt(Te(_.root,_.relative)).then(async O=>hs(O).inode!==r.inode||St(w.path)!==St(r.path)?!0:(await rr(Wt(r.physical))).includes(Vt(w.path)),O=>O.code==="ENOENT"?!1:Promise.reject(O)),R=o.nodes.find(O=>O.id===w.id&&!O.deleted);if(!$&&R)try{if(R.path!==w.path)throw Error(`Concurrent file rename: ${r.path}`);let O=St(r.path),S=O?o.nodes.find(E=>E.path===O&&E.kind==="folder"&&!E.deleted)?.id:"";if(O&&!S)throw Error("Rename parent unavailable");let C=await this.operation(e,r.path,s,"rename",null,()=>this.json(e,s,`/nodes/${R.id}`,"PATCH",{name:Vt(r.path),parentId:S,revision:R.revision}));Object.assign(R,C),w.path=r.path,i=R}catch(O){for(let S of new Set([w.path,R.path,r.path]))this.block(s,S,O);throw O}}}let a=i?e.stored.files[Ie(s,i.id)]:Object.entries(e.stored.files).find(([w,_])=>w.startsWith(s+":")&&_.path===r.path)?.[1];if(!a&&i?.version&&s==="default"&&(a=await this.legacyBaseline(r.path,i)),i&&a&&this.unchanged(e,s,i,a,r))return;if(this.hold(r,a))return"held";let l=Date.now(),c=await wn(r),u=Ee(c),f={key:er(r),at:l,inode:r.inode};if(this.guard(e),this.settled(r.path,l),!i){if((a?o.nodes.find(C=>C.id===a.id&&C.deleted):null)&&a&&(a.hash===u||a.memoryDeleted&&ci(r.path)&&u===ir)){ci(r.path)?await this.clearDeletedMemory(e,s,r,a,c,u):(await this.operation(e,r.path,s,"delete",r.size,()=>this.trashFile(e,r,u)),this.tally("deletesLocal"),delete e.stored.files[Ie(s,a.id)]);return}let _=St(r.path),$=_?o.nodes.find(C=>C.path===_&&!C.deleted&&C.kind==="folder")?.id:"";if(_&&!$)throw Error("Parent folder is unavailable");let R=Object.entries(e.stored.pendingUploads??{}).find(([C,E])=>C.startsWith(s+":")&&E.path===r.path&&!o.nodes.some(I=>I.id===E.id))?.[1];for(let[C,E]of Object.entries(e.stored.pendingUploads??{}))C.startsWith(s+":")&&E.path===r.path&&o.nodes.some(I=>I.id===E.id&&I.deleted)&&delete e.stored.pendingUploads[C];let O=R?.id??et(),S=Ie(s,O);(e.stored.pendingUploads??={})[S]={id:O,path:r.path},await this.persist(e),i=await this.json(e,s,"/nodes","POST",{id:O,parentId:$,name:Vt(r.path),kind:"file"}),i.id!==O&&delete e.stored.pendingUploads[S],o.nodes.push(i),a=void 0}if(i.busy)return;let g=Ie(s,i.id);if(i.version&&this.awaitingBytes.delete(g),i.hash===u){await this.shadow(e,s,i,c,r,f);return}if(i.hash&&e.stored.unconfirmed?.[g]===i.hash&&(await this.shadow(e,s,i,await this.operation(e,r.path,s,"download",i.size??null,w=>this.download(e,i,s,w)),r),a=e.stored.files[g]),!i.version&&a&&a.hash===u&&!e.stored.pendingUploads?.[g]){let w=this.awaitingBytes.get(g)??Date.now();if(this.awaitingBytes.set(g,w),Date.now()-w<jg)return}if(this.awaitingBytes.delete(g),!i.version||a&&i.version===a.version){(e.stored.unconfirmed??={})[g]=u,await this.persist(e);let w=await this.operation(e,r.path,s,"upload",c.length,_=>this.upload(e,i,s,c,_));Object.assign(i,w),await this.shadow(e,s,i,c,r,f);return}let p=await this.operation(e,r.path,s,"download",i.size??null,w=>this.download(e,i,s,w)),y=p,h=!1;if(!a||a.hash!==u){let w=c.toString("utf8"),_=p.toString("utf8"),$=a?await this.readBase(e,a):null,R=Buffer.from(w).equals(c)&&Buffer.from(_).equals(p)?this.host.contentSync.merge(r.path,w,$,_):null;if(R?(y=Buffer.from(R.content),h=R.conflict):h=!0,h){await this.preserveConflict(e,r.path,c)&&(nt("content","conflicts"),this.tally("conflictCopies"));let O=this.job(e,r.path,s,"merge",c.length);O.state="conflict",O.error="Both versions preserved",O.finishedAt=Date.now()}if(!y.equals(p)){let O=await this.operation(e,r.path,s,"merge",y.length,S=>this.upload(e,i,s,y,S));Object.assign(i,O)}}let m=Date.now();await this.write(e,r.path,y,u),await this.shadow(e,s,i,y,r,await this.seen(e,r.path,m))}async preserveConflict(e,n,r){let s=je(e.roots,n),o=await Je(s.root,s.relative),i=Vt(n),a=Ee(r);for(let l of await rr(Wt(o))){if(l.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}(?: \d+)?\)/,"")!==i||!rs(l))continue;let c=St(n)?St(n)+"/"+l:l,u=je(e.roots,c),f=await Je(u.root,u.relative),g=await bt(f);if(g.isFile()&&g.size===r.length&&Ee(await tr(f))===a)return!1}return await this.write(e,await this.copyName(e,n),r,null),!0}async copyName(e,n){let r=new Date;for(let s=1;;s++){let o=Gc(n,r,s),i=je(e.roots,o);if(!await bt(Te(i.root,...i.relative.split("/"))).then(()=>!0,a=>a.code==="ENOENT"?!1:Promise.reject(a)))return o}}async legacyBaseline(e,n){let r=await this.host.contentSync.agentFiles?.baseline(e).catch(()=>null);if(!(!r||!n.version)&&!(r.pending&&Number(n.version.split(":")[0])!==r.seq))return{id:n.id,path:e,version:`${r.seq}:${r.hash}`,hash:r.hash,...r.base!==void 0?{base:r.base}:{}}}agentAsks(e,n,r,s,o){let i=[],a=l=>l.length?Math.max(...l):null;for(let l of n){let c=l.kind==="folder"?Yn(l.path):null;if(!c||Qr.has(c))continue;let u=`agents/${c}/`,f=this.route(u+"config.toml",r);if(!f||Object.entries(e.stored.files).some(([m,w])=>m.startsWith(f+":")&&w.path.startsWith(u)))continue;let g=(s.get(f)?.nodes??[]).filter(m=>!m.deleted&&m.kind==="file"&&m.version&&m.path.startsWith(u)&&this.route(m.path,r)===f),p=n.filter(m=>m.kind==="file"&&m.path.startsWith(u)&&this.route(m.path,r)===f);if(!g.length||!p.length)continue;let y=new Map(g.map(m=>[m.path,m])),h=p.filter(m=>{let w=y.get(m.path);return!!w&&o.get(m.path)!==w.hash}).length;!h&&p.length===g.length&&p.every(m=>y.has(m.path))||i.push({slug:c,namespace:f,cloudFiles:g.length,localFiles:p.length,differ:h,cloudMtime:a(g.map(m=>m.mtime??0)),localMtime:a(p.map(m=>m.mtime))})}return i}async resolveAsks(e,n,r,s){for(let o of n){try{await this.resolveAsk(e,o,r[o.slug]??"merge",s)}catch(c){throw this.dropShadows(e,o.namespace,`agents/${o.slug}/`),await this.persist(e),Error(`agent_open_failed: ${De(c)}`)}let i=`agents/${o.slug}`,a=s.rules.find(c=>c.source===i),l=un(e.stored.config,i,zl(s,i));a&&(l={...l,rules:l.rules.map(c=>c.source===i?{...a,target:c.target}:c)}),e.stored.config=Dt(l,e.stored.config.revision+1),await this.persist(e)}}async resolveAsk(e,n,r,s){let o=n.namespace,i=`agents/${n.slug}/`;if(this.dropShadows(e,o,i),r==="local"){await this.archiveAgent(e,o,n.slug),await this.persist(e);return}let a=await this.json(e,o);this.guard(e),cs(a,o);let l=new Map(a.nodes.filter(p=>!p.deleted&&!p.busy&&p.kind==="file"&&p.version&&p.path.startsWith(i)&&this.route(p.path,s)===o).map(p=>[p.path,p])),c=p=>p.endsWith("/"+Qn),u=async(p,y,h)=>{let m=Date.now();return await this.write(e,p,y,h),this.seen(e,p,m)};for(let[p,y]of l){if(!c(p))continue;let h=je(e.roots,p);if(pu(Te(h.root,h.relative)))continue;let m=await this.operation(e,p,o,"download",y.size??null,w=>this.download(e,y,o,w));await this.shadow(e,o,y,m,void 0,await u(p,m,null))}let f=(await this.scan(e)).filter(p=>p.kind==="file"&&p.path.startsWith(i)&&this.route(p.path,s)===o&&p.size<=vn).sort((p,y)=>+!c(p.path)-+!c(y.path)),g=await this.removedDir(e,n.slug);for(let p of f){this.guard(e);let y=await wn(p),h=Ee(y),m=l.get(p.path),w=p.path.slice(i.length);if(m&&m.hash===h){await this.shadow(e,o,m,y,p);continue}if(r==="cloud"){if(await this.keep(e,`${g}/${w}`,y),m){let S=await this.operation(e,p.path,o,"download",m.size??null,C=>this.download(e,m,o,C));await this.shadow(e,o,m,S,p,await u(p.path,S,h))}else w==="MEMORY.md"?await this.write(e,p.path,Buffer.alloc(0),h):await this.removeLocal(e,p,h);continue}if(!m)continue;let _=await this.operation(e,p.path,o,"download",m.size??null,S=>this.download(e,m,o,S)),$=o==="default"?await this.legacyBaseline(p.path,m):void 0;if($?.hash===h){await this.shadow(e,o,m,_,p,await u(p.path,_,h));continue}let R=$?await this.readBase(e,$):null,O=li(y)&&li(_)?this.host.contentSync.merge(p.path,y.toString("utf8"),R,_.toString("utf8")):null;if(O&&!O.conflict){let S=Buffer.from(O.content);S.equals(y)||await this.write(e,p.path,S,h),await this.shadow(e,o,m,_)}else(m.mtime??0)>p.mtime?(await this.keep(e,`${g}/${w}`,y),await this.shadow(e,o,m,_,p,await u(p.path,_,h))):(await this.keep(e,`${g}/${w}`,_),await this.shadow(e,o,m,_))}await this.persist(e)}dropShadows(e,n,r){for(let[s,o]of Object.entries(e.stored.files))s.startsWith(n+":")&&o.path.startsWith(r)&&(delete e.stored.files[s],delete e.stored.unconfirmed?.[s])}async removedDir(e,n,r="agents"){let s=new Date,o=a=>String(a).padStart(2,"0"),i=`${s.getFullYear()}-${o(s.getMonth()+1)}-${o(s.getDate())} ${o(s.getHours())}${o(s.getMinutes())}`;for(let a=1;;a++){let l=`${r}/.removed/${n} ${i}${a>1?` ${a}`:""}`,c=je(e.roots,l);if(!await bt(Te(c.root,...c.relative.split("/"))).then(()=>!0,u=>u.code==="ENOENT"?!1:Promise.reject(u)))return l}}async keep(e,n,r){this.guard(e),await ri(e.roots,n,r,null)}async removeLocal(e,n,r){await this.lock(e,n.physical,()=>{if(rt(n.root,or(n.root,n.physical).split(Sn).join("/")),Ee(bn(n.physical))!==r)throw Error("Local file changed before replacing");oi(n.physical)})}async archiveAgent(e,n,r){let s=this.host.readCreds();if(!s.token)throw Error("not_signed_in");let o=await fetch(s.cloudUrl.replace(/\/+$/,"")+"/api/remotesync/agent-archive/agent",{method:"POST",headers:{Authorization:`Bearer ${s.token}`,"Content-Type":"application/json","X-Content-Device":this.deviceId},body:JSON.stringify({namespace:n,slug:r,opId:et(),locale:this.locale()}),signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(12e4)])});this.guard(e);let i=await o.json().catch(()=>({}));if(this.guard(e),!o.ok||i?.state!=="done")throw Error(typeof i?.detail=="string"?i.detail:`agent_archive_http_${o.status}`)}async absent(e,n){this.guard(e);let r=je(e.roots,n),s=await Je(r.root,r.relative);try{return await bt(s),!1}catch(o){if(o.code==="ENOENT")return!0;throw o}}async missing(e,n,r,s,o){let i=e.stored.files[Ie(r,n.id)],a=e.stored.pendingUploads?.[Ie(r,n.id)];if(n.deleted){i&&delete e.stored.files[Ie(r,n.id)],a&&delete e.stored.pendingUploads[Ie(r,n.id)];return}if(n.busy||i?.inode&&this.blocked.has(r)&&s.some(u=>u.kind==="file"&&u.inode===i.inode&&this.isBlocked(r,u.path)&&this.route(u.path,o)===r))return;if(!n.version){a&&await this.absent(e,n.path)&&(await this.operation(e,n.path,r,"delete",null,()=>this.json(e,r,`/nodes/${n.id}`,"DELETE",{revision:n.revision,version:null})),delete e.stored.pendingUploads[Ie(r,n.id)],n.deleted=!0);return}if(i&&i.version===n.version){if(!await this.absent(e,n.path))return;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[Ie(r,n.id)],n.deleted=!0;return}let l=await this.operation(e,n.path,r,"download",n.size??null,u=>this.download(e,n,r,u)),c=Date.now();await this.write(e,n.path,l,null),await this.shadow(e,r,n,l,void 0,await this.seen(e,n.path,c))}async recoverTrash(e){for(let n of[...e.stored.trash??[]]){if(n.parentId){let l=(await gs(e.roots)).find(c=>c.kind==="folder"&&c.localId===n.parentId);l&&(n.path=l.path+"/"+Vt(n.path))}let r=je(e.roots,n.path),s=await Je(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 ys(o);if(n.stageDev!==void 0&&(i.dev!==n.stageDev||i.ino!==n.stageIno))throw Error("Sync recovery root changed; journal retained");let a=Te(o,n.stage);await bt(a).then(()=>!0,l=>l.code==="ENOENT"?!1:Promise.reject(l))&&await this.lock(e,s,()=>{if(rt(o,n.stage,!0),Ee(bn(a))!==n.hash)throw Error("Sync recovery content changed");rt(r.root,r.relative),Pg(Wt(s),{recursive:!0});let l=pu(s)?s+` (sync recovery ${et().slice(0,8)})`:s;try{Rg(a,l)}catch(c){if(c.code!=="EXDEV")throw c;if($g(a,l,Mg.COPYFILE_EXCL),Ee(bn(l))!==n.hash)throw Error("Sync recovery copy incomplete; original retained")}oi(a)},!0),e.stored.trash=e.stored.trash.filter(l=>l!==n)}}async clearDeletedMemory(e,n,r,s,o,i){s.memoryDeleted&&s.hash===ir&&i===ir||(await this.operation(e,r.path,n,"delete",r.size,async()=>{if(!s.memoryDeleted&&o.length){let c=r.path==="human/MEMORY.md",u=await this.removedDir(e,c?"memory":r.path.split("/")[1],c?"human":"agents");await this.keep(e,`${u}/MEMORY.md`,o)}s.memoryDeleted=!0,await this.persist(e);let a=Date.now();o.length&&await this.write(e,r.path,Buffer.alloc(0),i);let l=await this.seen(e,r.path,a);e.stored.files[Ie(n,s.id)]={...s,hash:ir,base:"",stat:void 0,statAt:void 0,...l?{inode:l.inode,stat:l.key,statAt:l.at}:{}}}),this.tally("deletesLocal"))}async trashFile(e,n,r){this.guard(e);let s=await Je(n.root,or(n.root,n.physical).split(Sn).join("/")),o={path:n.path,stage:".forsion-sync-trash-"+et(),hash:r},i=Te(n.root,o.stage),a=hu(n.root);o.stageRoot=n.root,o.stageDev=a.dev,o.stageIno=a.ino;try{let l=JSON.parse(bn(Te(Wt(s),".forsion-sync-id.json"),"utf8")).id;/^[a-f0-9-]{36}$/i.test(l)&&(o.parentId=l)}catch{}(e.stored.trash??=[]).push(o),await this.persist(e);try{await this.lock(e,s,()=>{if(rt(n.root,or(n.root,s).split(Sn).join("/")),Ee(bn(s))!==r)throw Error("Local file changed before deletion");Tg(s,i)}),await this.host.contentSync.trash(i),e.stored.trash=e.stored.trash.filter(l=>l!==o)}catch(l){throw this.host.accountId()===e.account&&!e.abort.signal.aborted&&await this.recoverTrash(e),l}}};function zg(t){let e={};if(t&&typeof t=="object")for(let[n,r]of Object.entries(t))Vn.test(n)&&Fl.includes(r)&&(e[n]=r);return e}function pu(t){try{return hu(t),!0}catch(e){if(e.code==="ENOENT")return!1;throw e}}Di(da);function hS(t){ua(t.contentSync?.withWriteLock?.bind(t.contentSync)),Hi(t),Js(t),mu(t),t.log("[forsion-extend] cloud account handlers registered"),Us(t)?Hs(t):t.log("[forsion-extend] host has no Connect seam (projectsRoot / transpileForServe / mimeOf / setPreviewHooks); Connect stays with the host"),Bs(t)?qs(t):t.log("[forsion-extend] host has no remote-sync seam (registerRemoteSyncBackend / readCreds); penzor stays with the host"),no(t)?ro(t):t.log("[forsion-extend] host has no account seam (accountCommit / accountClear / \u2026); account core stays with the host"),So(t)?vo(t):t.log("[forsion-extend] host has no amadeus seam (setAmadeusSyncFactory); cloud sync stays with the host"),Eo(t)?_o(t):t.log("[forsion-extend] host has no unit seam (setUnitHubFactory); the device channel stays with the host"),jo(t)?Cc(t):t.log("[forsion-extend] host has no diagnostics seam (homeDir / readCreds / accountId / appVersion); diagnostics upload is off"),jo(t)&&Wc(t)}export{ja as ACCOUNT_SEAM,Cl as AMADEUS_SEAM,Fs as CONNECT_MAX_FILES,pa as CONNECT_MAX_FILE_BYTES,ha as CONNECT_MAX_TOTAL_BYTES,Dr as DIAGNOSTICS_VAULT,Sa as FORSION_CONNECT_LOCAL_SDK,Ui as PAY_PERIODS,Li as PAY_TABS,Ea as PENZOR_MAX_FILE,Ae as SYNC_IPC,Tl as UNIT_SEAM,In as UPLOAD_MAX_FILE,zn as UnitCapsReporter,Hn as UnitHost,Ue as cloudJson,ga as collectProjectFiles,Mr as conflictCopyPath,xf as conflictCopyVariant,Na as createAccountCloud,xl as createAmadeusCloud,Ir as createPenzorRemote,Rl as createUnitHub,Rr as deviceHeader,zs as expectedPartsOf,Oe as forsionAccountId,Sr as forsionRefreshToken,Rn as forsionWhoami,no as hasAccountHost,So as hasAmadeusHost,Us as hasConnectHost,Bs as hasRemoteSyncHost,Eo as hasUnitHost,ba as makePreviewProxy,Oa as multipartFrame,ya as readConnectMeta,ro as registerAccount,vo as registerAmadeus,hS as registerCloud,Hs as registerConnect,qs as registerPenzor,Js as registerPenzorTransfers,_o as registerUnit,Or as safeDownloadName,br as shouldRefreshToken,Ws as speedOf,Al as streamWorthy,ul as stripConflictSuffix,Af as textFingerprint,_s as tokenAgeMs,Mi as tokenRemainingMs,Vs as uploadError,wa as writeConnectMeta};
283
+ `,{encoding:"utf8",mode:384});try{if(Jh(a()).size>Yl){let Y=_(),v=Y.length,A=0;for(;v>0&&A+Buffer.byteLength(JSON.stringify(Y[v-1]))+1<=Yl/2;)A+=Buffer.byteLength(JSON.stringify(Y[--v]))+1;M(a(),Y.slice(v))}}catch{}_().length>=eg&&ee()}},Z=()=>{let F=d();return{available:!!l,enabled:F.enabled!==!1,noticeSeen:F.noticeSeen===!0,signedIn:h(),active:m(F),packaged:l?.packaged===!0,installId:y(),queued:Gh(a())?_().length:0,lastSentAt:F.lastSentAt??null,lastError:F.lastError??null}},re=()=>Fl({app:"desktop",appVersion:t.appVersion(),coreVersion:l?.coreVersion()??void 0,channel:l?.channel(),os:dg(process.platform),osVersion:Xh(),arch:fg(process.arch),locale:pg()}),se=null,ee=()=>{if(se)return se;if(E||n().getTime()<I)return Promise.resolve();let F=C,Y=R,v=(async()=>{try{for(let A=0;A<5;A++){let T=_();if(!T.length)return;let D=y(),P={v:$l,installId:D,...re()},B=[],H=Buffer.byteLength(JSON.stringify({...P,events:[]}));for(let te of T){let ue=Buffer.byteLength(JSON.stringify(te))+1;if(B.length>=Bo.maxEvents||H+ue>Bo.maxBatchBytes)break;B.push(te),H+=ue}if(!B.length){M(a(),T.slice(1));continue}let{base:z}=await t.getCloud(),J={...P,events:B};if(!U()||F!==C)return;let G=await r(`${z.replace(/\/+$/,"")}/api/telemetry/batch`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(J),signal:AbortSignal.timeout(Gl)}).catch(te=>({ok:!1,status:0,error:String(te?.message||te)})),K=G.status;if(K>=200&&K<300||K===400||K===413){let te=new Set(B.map(ue=>JSON.stringify(ue)));M(a(),_().filter(ue=>!te.has(JSON.stringify(ue))))}if(K>=200&&K<300){let te=n().getTime();Y===R&&M(c(),[...S(),{at:te,body:J}]),p({lastSentAt:te,lastError:void 0});continue}if(K!==400&&K!==413){let te=Number(G.headers?.get?.("retry-after"));I=n().getTime()+(Number.isFinite(te)&&te>0?Math.min(te,3600)*1e3:5*6e4)}p({lastError:K?`HTTP ${K}`:String(G.error??"network error").slice(0,200)});return}}catch(A){try{p({lastError:String(A?.message||A).slice(0,200)})}catch{}}})();return se=v,v.finally(()=>{se===v&&(se=null)}),v},Q=async()=>{try{if(S(),!U())return;let F=d(),Y=C,v=F.cursor??Xo(n().getTime()),A=await cg(s(),v,l?.sessionId,Xl(n().getTime()));if(!U()||Y!==C)return;V(A.events),A.cursor!==v&&p({cursor:A.cursor}),await ge(Y),await ee()}catch(F){t.log(`[forsion-extend] telemetry tick failed: ${String(F?.message||F)}`)}},ge=async F=>{let Y=n().getTime(),v=rn(Y),A=rn(Y-Jl),T=d().ledgerCursor;if(Un(T)||(T=A,p({ledgerCursor:T})),ko(T),T>=A){fe();return}let D=await lg(s(),T,v);if(!(!U()||F!==C)){if(D){let P=D.complete?A:D.days[D.days.length-1]?.day??T;if(P>T){let B=Rc(T,P),H=[...new Set([...D.days.map(J=>J.day),...B.map(J=>J.day)])].filter(J=>J>T&&J<=P).sort(),z=[];for(let J of H){z.push(...D.days.find(G=>G.day===J)?.events??[]);for(let G of B)if(G.day===J){let K=ug(J,G.system,G.counts);K&&z.push(K)}}V(z),p({ledgerCursor:P}),ko(P)}}fe()}},fe=()=>{if(!Ac())return;let F=g();if(!F)return;let Y=xc();p({syncHealth:Object.keys(Y).length?Y:void 0},F),Tc()},ye=l?.subscribe(F=>{try{if(!og.has(F?.event)||!U())return;let Y=zt({...F,sessionId:l.sessionId},Kh());Y&&V([Y])}catch(Y){t.log(`[forsion-extend] telemetry event dropped: ${String(Y?.message||Y)}`)}}),he={ok:!1,error:"untrusted"};t.handle("telemetry:get",F=>t.isTrustedSender(F)?(U(),Z()):he),t.handle("telemetry:set",(F,Y)=>{if(!t.isTrustedSender(F))return he;let v=d(),A={};typeof Y?.enabled=="boolean"&&(A.enabled=Y.enabled),Y?.noticeSeen===!0&&(A.noticeSeen=!0);let T={...v,...A};return!m(v)&&m(T)&&(A.cursor=Xo(n().getTime()),A.ledgerCursor=u()),m(v)&&!m(T)&&C++,A.enabled===!1&&(A.syncHealth=void 0),p(A),A.enabled===!1&&O(),U(),Z()}),t.handle("telemetry:sent",F=>t.isTrustedSender(F)?{batches:S()}:he),t.handle("telemetry:delete",async F=>{if(!t.isTrustedSender(F))return he;E=!0,C++;try{await se?.catch(()=>{});let Y=y(),{base:v}=await t.getCloud(),T=(await r(`${v.replace(/\/+$/,"")}/api/telemetry/install/${Y}`,{method:"DELETE",signal:AbortSignal.timeout(Gl)}).catch(D=>({ok:!1,status:0,error:String(D?.message||D)}))).status;return T>=200&&T<300?(O(),p({installId:Bl(),lastSentAt:void 0,lastError:void 0,ledgerCursor:u(),syncHealth:void 0}),Z()):{ok:!1,error:T?`HTTP ${T}`:"network error"}}finally{E=!1}});try{Cc(d().syncHealth),$(),U()}catch(F){t.log(`[forsion-extend] telemetry startup check failed: ${String(F?.message||F)}`)}let ze=t.addFlushHook?.(F=>{if(F!=="blur")try{fe()}catch{}}),Fe=setTimeout(()=>void Q(),Qh),be=setInterval(()=>void Q(),Zh);return Fe.unref?.(),be.unref?.(),t.log(`[forsion-extend] telemetry registered (${l?l.packaged?"packaged":"dev build: never sends":"host has no telemetry seam: never sends"})`),Object.assign(()=>{clearTimeout(Fe),clearInterval(be),ye?.(),ze?.()},{tick:Q,flush:ee})}import{readFileSync as bn,lstatSync as vu,renameSync as zg,linkSync as Bg,unlinkSync as ci,readdirSync as qg,rmdirSync as Wg,writeFileSync as Vg,mkdirSync as Yg,copyFileSync as Gg,constants as Jg}from"node:fs";import{readFile as tr,writeFile as nr,mkdir as li,rename as ys,readdir as rr,lstat as bt,stat as ws,unlink as sr}from"node:fs/promises";import{join as Te,dirname as Wt,relative as or,sep as Sn}from"node:path";import{hostname as ui}from"node:os";import{randomUUID as et}from"node:crypto";import{isUtf8 as di}from"node:buffer";import{Readable as yu}from"node:stream";var hg=["config.toml","SOUL.md","HARNESS.md","HUMAN.md","MEMORY.md","CALENDAR.db"],gg=["HUMAN.md","AGENT.md","SOUL.md","MEMORY.md","CALENDAR.db"],Qn=".memory-tombstones.json",eu=t=>/^WidgetData\/[a-z0-9][a-z0-9_-]{0,63}\/data\.db$/.test(t),Ql=t=>t==="WidgetData"||/^WidgetData\/[a-z0-9][a-z0-9_-]{0,63}$/.test(t),mg=t=>/^\d{4}-\d{2}-\d{2}$/.test(t)&&Number.isFinite(Date.parse(`${t}T00:00:00Z`))&&new Date(`${t}T00:00:00Z`).toISOString().slice(0,10)===t,yg=t=>/^[a-z0-9][a-z0-9-]{0,63}$/.test(t)&&!t.startsWith("__");function wg(t){if(!t||t.length>1024||/[\\\x00-\x1f:]/.test(t))return!1;if(t===Qn)return!0;let e=t.split("/");return e.some(n=>!n||n.startsWith(".")||n.endsWith(".")||n.endsWith(" "))?!1:hg.includes(t)||eu(t)?!0:t.startsWith("LOG/")?e.length===2&&t.endsWith(".md")&&mg(e[1].slice(0,-3)):e.length>1&&e[0]==="Library"}var bg=t=>t==="muse"||/^historian-[a-z0-9]{1,12}$/.test(t),Sg=/\(conflict \d{4}-\d{2}-\d{2} \d{4}(?: \d+)?\)/,vg=/\(conflict [A-Za-z0-9_-]{1,64} \d{10,}\)/;function ss(t){let e=t.slice(t.lastIndexOf("/")+1);return Sg.test(e)||vg.test(e)}function tu(t,e,n=1){let r=t.lastIndexOf("/"),s=r<0?"":t.slice(0,r+1),o=r<0?t:t.slice(r+1),i=o.lastIndexOf("."),a=i>0?o.slice(0,i):o,c=i>0?o.slice(i):"",l=d=>String(d).padStart(2,"0"),u=`${e.getFullYear()}-${l(e.getMonth()+1)}-${l(e.getDate())} ${l(e.getHours())}${l(e.getMinutes())}${n>1?` ${n}`:""}`;return`${s}${a} (conflict ${u})${c}`}function Zo(t,e="file"){if(t==="agents"||t==="human")return e==="folder";let n=t.startsWith("human/"),r=t.startsWith("agents/");if(!n&&!r)return null;if(ss(t))return!1;if(n){let l=t.slice(6);return e==="folder"?Ql(l):gg.includes(l)||eu(l)}let s=t.slice(7),o=s.indexOf("/"),i=o<0?s:s.slice(0,o),a=o<0?"":s.slice(o+1);if(!yg(i)||bg(i))return!1;if(e==="file")return wg(a);if(a===""||a==="LOG"||Ql(a))return!0;let c=a.split("/");return c[0]==="Library"&&c.every(l=>l&&!l.startsWith(".")&&!l.endsWith(".")&&!l.endsWith(" "))}import{isAbsolute as kg}from"node:path";var Qe=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),ft=t=>typeof t=="string",ei=t=>ft(t)&&t.length>0,Ot=t=>typeof t=="boolean",Bt=t=>typeof t=="number"&&Number.isFinite(t),mn=t=>Bt(t)&&Number.isSafeInteger(t)&&t>=0,is=t=>Bt(t)&&Number.isInteger(t)&&t>=0,nu=t=>mn(t)&&t>0,yn=t=>ft(t)&&/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i.test(t),ls=t=>ft(t)&&/^[a-f0-9]{64}$/.test(t),ru=t=>ft(t)&&/^(default|device-[A-Za-z0-9_-]{1,64})$/.test(t),as=(t,e)=>ft(t)&&e.includes(t),ke=(t,e)=>t===void 0||e(t),su=(t,e,n)=>e.every(r=>ke(t[r],n)),ou=t=>ft(t)&&!t.includes("\0")&&kg(t);function Pt(t,e=!1){try{return It(t,e),!0}catch{return!1}}var iu=t=>Pt(t)&&!t.includes("/")&&Buffer.byteLength(t)<=255,au=t=>t===""||yn(t);function cs(t,e){let n=t.indexOf(":");return n>0&&yn(e)&&t.slice(n+1)===e&&ru(t.slice(0,n))}function Eg(t,e){return Qe(e)&&cs(t,e.id)&&Pt(e.path)&&ei(e.version)&&ls(e.hash)&&su(e,["base","inode","stat"],ft)&&ke(e.statAt,Bt)&&ke(e.memoryDeleted,Ot)}function _g(t,e){return Qe(e)&&cs(t,e.localId)&&yn(e.id)&&Pt(e.path)&&nu(e.revision)&&au(e.parentId)&&iu(e.name)}function Cg(t){return Qe(t)&&yn(t.id)&&Pt(t.path)&&ru(t.target)&&as(t.direction,["upload","download","merge","rename","delete"])&&as(t.state,["queued","active","done","failed","paused","conflict"])&&mn(t.done)&&(t.size===null||mn(t.size))&&Bt(t.at)&&ke(t.error,ft)&&ke(t.finishedAt,Bt)}function xg(t){return Qe(t)&&Pt(t.path)&&ls(t.hash)&&ft(t.stage)&&/^\.forsion-sync-trash-[a-f0-9-]+$/.test(t.stage)&&ke(t.parentId,yn)&&ke(t.stageRoot,ou)&&(t.stageDev===void 0&&t.stageIno===void 0||t.stageRoot!==void 0&&is(t.stageDev)&&is(t.stageIno))}function Ag(t){return Qe(t)&&Pt(t.prefix,!0)&&ou(t.root)&&(t.dev===void 0&&t.ino===void 0||is(t.dev)&&is(t.ino))}function Tg(t){return Qe(t)&&as(t.state,["running","done"])&&Ot(t.seen)&&su(t,["name","folderId","shelfId","shelfName"],ft)&&ke(t.files,mn)&&ke(t.at,Bt)&&ke(t.rewritten,Ot)}var os=(t,e)=>Qe(t)&&Object.entries(t).every(([n,r])=>e(n,r)),Qo=(t,e)=>Array.isArray(t)&&t.every(e);function cu(t){if(!Qe(t)||!Qe(t.config)||!mn(t.config.revision)||!Ot(t.owned)||!Ot(t.paused)||!os(t.files,Eg)||!os(t.folders,_g)||!Qo(t.jobs,Cg)||!ke(t.accountReview,Ot)||!ke(t.agentArchive,Tg)||!ke(t.roots,e=>Qo(e,Ag))||!ke(t.trash,e=>Qo(e,xg))||!ke(t.unconfirmed,e=>os(e,(n,r)=>cs(n,n.slice(-36))&&ls(r)))||!ke(t.pendingUploads,e=>os(e,(n,r)=>Qe(r)&&cs(n,r.id)&&Pt(r.path))))throw Error("Invalid content sync state; original data was retained");Dt(t.config,t.config.revision)}function Rg(t){return Qe(t)&&yn(t.id)&&au(t.parentId)&&iu(t.name)&&Pt(t.path)&&as(t.kind,["file","folder"])&&nu(t.revision)&&Ot(t.deleted)&&ke(t.busy,Ot)&&ke(t.version,ei)&&ke(t.hash,ls)&&ke(t.size,mn)&&ke(t.mtime,Bt)&&t.version===void 0==(t.hash===void 0)}function us(t,e){let n=()=>Error("Incomplete or invalid cloud content manifest");if(!Qe(t)||t.schemaVersion!==1||t.namespace!==e||!ei(t.folder)||!Array.isArray(t.nodes))throw n();let r=new Map,s=new Set;for(let o of t.nodes){if(!Rg(o)||r.has(o.id)||!o.deleted&&s.has(o.path))throw n();r.set(o.id,o),o.deleted||s.add(o.path)}for(let o of r.values()){let i=o.parentId?r.get(o.parentId):void 0;if(o.parentId&&(!i||i.kind!=="folder"||i.deleted&&!o.deleted)||o.path!==(i?i.path+"/"+o.name:o.name))throw n()}}import{constants as lu,lstatSync as qt,readdirSync as Ig,readFileSync as Dg,renameSync as ds,unlinkSync as Og,linkSync as Pg,mkdirSync as ps,realpathSync as ti,rmdirSync as Mg}from"node:fs";import{open as uu,lstat as ni,readdir as $g,realpath as du,readFile as ri,writeFile as Ng,mkdir as fu,unlink as jg}from"node:fs/promises";import{join as Mt,dirname as fs,relative as si,sep as hs}from"node:path";import{randomUUID as pu,createHash as Fg}from"node:crypto";var er=t=>`${t.size}:${t.mtime}:${t.ctime}:${t.inode}`,gs=t=>({size:t.size,mtime:t.mtimeMs,ctime:t.ctimeMs,inode:`${t.dev}:${t.ino}:${t.birthtimeMs}`}),hu=".forsion-sync-id.json",Lg=new Set([".git","node_modules",".DS_Store",".Trash",".trash","__pycache__",".cache"]),Ug=t=>!Lg.has(t)&&!t.startsWith(".forsion-sync")&&!/\.tmp-[0-9]|\.lock$|-(wal|shm)$/.test(t)&&(!t.startsWith(".")||t===".memory-tombstones.json"),Ee=t=>Fg("sha256").update(t).digest("hex");function gu(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 Je(t,e,n=!1){if(n){if(e.split("/").some(a=>a===".."||a==="."||!a)||e.startsWith("/")||e.includes("\\"))throw Error("Invalid internal content path")}else It(e,!0);gu(e);let r=await du(t),s=Mt(r,...e.split("/").filter(Boolean)),o=si(r,s);if(o===".."||o.startsWith(".."+hs))throw Error("Content path escapes root");let i=r;for(let a of o.split(hs).filter(Boolean)){i=Mt(i,a);try{if((await ni(i)).isSymbolicLink())throw Error("Content symlinks are not synchronized")}catch(c){if(c.code!=="ENOENT")throw c}}return s}function rt(t,e,n=!1){if(n||It(e,!0),gu(e),e.split("/").some(o=>o===".."||o===".")||e.startsWith("/")||e.includes("\\"))throw Error("Unsafe sync path");let s=ti(t);for(let o of e.split("/").filter(Boolean)){s=Mt(s,o);try{if(qt(s).isSymbolicLink())throw Error("Content symlinks are not synchronized")}catch(i){if(i.code!=="ENOENT")throw i}}return s}async function ms(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 du(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 ni(o)).isDirectory())throw Error(`Sync root is not a directory: ${s.prefix||"Forsion"}`);let i=async(a,c)=>{let l=await ni(a);if(!l.isSymbolicLink()&&!(a!==o&&r.some(u=>u!==s&&u.root===a))&&!(c&&s.prefix===""&&n.some(u=>c===u||c.startsWith(u+"/")))){if(c){It(c);let u;if(l.isDirectory())try{let d=JSON.parse(await ri(Mt(a,hu),"utf8"));/^[a-f0-9-]{36}$/i.test(d.id)&&(u=d.id)}catch(d){if(d.code!=="ENOENT"&&!(d instanceof SyntaxError))throw d}e.set(c,{path:c,physical:a,root:o,kind:l.isDirectory()?"folder":"file",localId:u,...gs(l),size:l.isFile()?l.size:0})}if(l.isDirectory())for(let u of await $g(a,{withFileTypes:!0}))!Ug(u.name)||!u.isDirectory()&&!u.isFile()||await i(Mt(a,u.name),c?`${c}/${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 oi(t){if(t.kind!=="folder")throw Error("Folder identity required");if(t.localId)return t.localId;let e=await Je(t.root,si(t.root,Mt(t.physical,hu)).split(hs).join("/"),!0),n=pu();try{let r=await uu(e,"wx",384);try{await r.writeFile(JSON.stringify({version:1,id:n})+`
284
+ `)}finally{await r.close()}return t.localId=n,n}catch(r){if(r.code!=="EEXIST")throw r;let s=JSON.parse(await ri(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 wn(t){let e=await Je(t.root,si(t.root,t.physical).split(hs).join("/")),n=await uu(e,lu.O_RDONLY|(lu.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 je(t,e){It(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 ii(t,e,n,r,s=async(o,i)=>i()){let o=je(t,e);await fu(o.root,{recursive:!0});let i=await Je(o.root,o.relative),a=await ri(i).catch(l=>{if(l.code==="ENOENT")return null;throw l});if((a?Ee(a):null)!==r)throw Error("Local file changed during download");let c=Mt(o.root,`.forsion-sync-${pu()}.tmp`);try{await Ng(c,n,{flag:"wx",mode:384}),await Je(o.root,o.relative),await s(i,()=>{rt(o.root,o.relative),ps(fs(i),{recursive:!0}),rt(o.root,o.relative);let l=null;try{l=Dg(i)}catch(u){if(u.code!=="ENOENT")throw u}if((l?Ee(l):null)!==r)throw Error("Local file changed during download");ds(c,i)})}finally{await jg(c).catch(()=>{})}}async function mu(t,e,n=async(r,s)=>s()){let r=je(t,e);await fu(r.root,{recursive:!0});let s=await Je(r.root,r.relative);await n([s],()=>{rt(r.root,r.relative),ps(s,{recursive:!0})})}async function ai(t,e,n,r=async(s,o)=>o()){let s=je(t,e),o=je(t,n);if(s.root!==o.root)throw Error("Folder move crosses a managed source");let i=await Je(s.root,s.relative),a=await Je(o.root,o.relative);await r([i,a],()=>{if(rt(s.root,s.relative),rt(o.root,o.relative),Hg(a)){let l=qt(i),u=qt(a),d=ti(fs(i));if((l.dev===u.dev&&l.ino===u.ino&&d===ti(fs(a))?Ig(d).filter(y=>{let h=qt(Mt(d,y));return h.dev===l.dev&&h.ino===l.ino}):[]).length!==1)throw Error("Local rename destination exists");ds(i,a);return}ps(fs(a),{recursive:!0});let c=qt(i);if(c.isDirectory()){if(process.platform==="win32"){ds(i,a);return}ps(a,{mode:448});try{ds(i,a)}catch(l){try{Mg(a)}catch{}throw l}}else{Pg(i,a);let l=qt(i);if(l.ino!==c.ino||l.dev!==c.dev)throw Error("Source changed during rename");Og(i)}})}function Hg(t){try{return qt(t),!0}catch(e){if(e.code==="ENOENT")return!1;throw e}}var Kg=()=>({config:structuredClone(Vc),owned:!1,paused:!1,folders:{},files:{},jobs:[]}),vn=50*1024*1024,Xg=10*6e4,wu=1024*1024,Ie=(t,e)=>`${t}:${e}`,St=t=>t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",Vt=t=>t.slice(t.lastIndexOf("/")+1),ir=Ee(""),fi=t=>t==="human/MEMORY.md"||/^agents\/[a-z0-9][a-z0-9-]{0,63}\/MEMORY\.md$/.test(t),$t=t=>t.split("/").length,De=t=>t instanceof Error?t.message:String(t),Zg={upload:"uploads",download:"downloads",merge:"merges",rename:"renames",delete:void 0},pi=t=>t.file.replace(/\.json$/,".bases"),ku=5e3,Qg=3e4,bu=3e4,em=3e3,ar=10*6e4,hi=t=>/^(agents|human)\//.test(t)?Qg:ku,tm=t=>Math.max(t.mtime,t.ctime);function Eu(t){if(!t.contentSync)return;let e=new gi(t);for(let[n,r]of Object.entries({[ct.get]:s=>e.snapshot(s),[ct.preview]:s=>e.preview(s),[ct.apply]:(s,o)=>e.apply(typeof s=="string"?s:"",o),[ct.run]:()=>e.kick(),[ct.pause]:s=>e.pause(s===!0),[ct.retry]:()=>e.kick(),[ct.rename]:s=>e.rename(s),[ct.setup]:s=>e.setup(s),[ct.archiveSeen]:()=>e.archiveSeen()}))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:De(i)}}});t.addQuitGuard?.(n=>e.running&&!e.quitting?{message:n==="zh"?"\u8FD8\u6709\u5185\u5BB9\u6B63\u5728\u540C\u6B65":"Content is still syncing"}:null),t.addFlushHook?.(n=>e.flush(n)),sl(()=>e.stats()),e.start()}var gi=class{session=null;initializing=null;previewValue=null;watcher=null;sources=[];agentNames=new Map;cloudAgents;sourcesAt=0;devices=[];others;deviceId="";customName="";serial=Promise.resolve();scheduled=null;tick=null;first=null;blocked=new Map;phase="idle";lastError;get error(){return this.lastError}set error(e){this.lastError=e,e&&this.fault(e)}runLog=new Gn;logAccount=null;runAccount=null;blockedError=void 0;live(){let e=this.host.accountId();return!!e&&e===this.logAccount&&(!this.running||!this.runAccount||this.runAccount===e)}tally(e){this.live()&&this.runLog.count(e)}fault(e,n=[]){this.live()&&this.runLog.fault(e,n)}health=Lr((e,n,r)=>nt("content",e,n,r));httpStatus=0;closed=!1;runFinished=Promise.resolve();archiving=null;archiveRetry={account:"",at:0};resolving=!1;awaitingBytes=new Map;uiLocale=null;running=!1;quitting=!1;again=!1;flushing=null;flushRequest=0;flushThrough=0;dirty=new Map;flushAt=0;due=null;registered=null;devicesAt=0;changedAt=0;wroteLocal=!1;openJobs=new Set;host;options;accountGeneration=0;stopAccountWatch;constructor(e,n={}){this.host=e,this.options=n,this.stopAccountWatch=Ha(e,()=>{this.accountGeneration++,this.previewValue=null,this.session?.abort.abort(new Error("account_changed"))})}start(){(this.tick=setInterval(()=>{this.run()},3e4)).unref?.(),(this.first=setTimeout(()=>{this.run()},5e3)).unref?.()}locale(){if(this.uiLocale)return this.uiLocale;try{return/^zh/i.test(Intl.DateTimeFormat().resolvedOptions().locale)?"zh":"en"}catch{return"zh"}}archiveStep(e){if(e.stored.accountReview||e.stored.agentArchive?.state==="done"||this.archiveRetry.account===e.account&&Date.now()<this.archiveRetry.at)return Promise.resolve();let n=()=>{this.archiveRetry={account:e.account,at:Date.now()+ar}};return this.archiving??=(async()=>{try{let r=this.host.readCreds();if(!r.token)return;let s=await fetch(r.cloudUrl.replace(/\/+$/,"")+"/api/remotesync/agent-archive",{method:"POST",headers:{Authorization:`Bearer ${r.token}`,"Content-Type":"application/json","X-Content-Device":this.deviceId},body:JSON.stringify({locale:this.locale()}),signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(6e4)])});if(this.guard(e),!s.ok){n();return}let o=await s.json();if(this.guard(e),o.state!=="done"&&o.state!=="running"){n();return}let i=e.stored.agentArchive,a=o.archive;i?.rewritten||this.turnAgentsOff(e);let c={rewritten:!0,seen:i?.seen??!1,state:o.state};o.state==="done"&&(a?.folderId?Object.assign(c,{folderId:a.folderId,name:a.name??void 0,shelfId:a.shelfId??void 0,shelfName:a.shelfName??void 0,files:a.files??0,at:a.at??Date.now()}):c.seen=!0),e.stored.agentArchive=c,await this.persist(e)}catch(r){if(De(r)==="account_changed"||e.abort.signal.aborted)return;n(),this.host.log?.(`[content-sync] agent archive: ${De(r)}`)}finally{this.archiving=null}})()}turnAgentsOff(e){let n=e.stored.config;if(!n.enabled&&n.revision===0)return;let r=el(n);if(!r)return;e.stored.config=Dt(r,n.revision+1);let s=o=>o==="agents"||o.startsWith("agents/");for(let[o,i]of Object.entries(e.stored.files))s(i.path)&&(delete e.stored.files[o],delete e.stored.unconfirmed?.[o]);for(let[o,i]of Object.entries(e.stored.folders))s(i.path)&&delete e.stored.folders[o];for(let[o,i]of Object.entries(e.stored.pendingUploads??{}))s(i.path)&&delete e.stored.pendingUploads[o];this.previewValue=null}async archiveSeen(){let e=await this.getSession();e.stored.agentArchive&&(e.stored.agentArchive.seen=!0,await this.persist(e))}async close(){this.closed=!0,this.stopAccountWatch(),this.tick&&clearInterval(this.tick),this.first&&clearTimeout(this.first),this.scheduled&&clearTimeout(this.scheduled),this.due&&clearTimeout(this.due),this.session?.abort.abort(),await this.watcher?.close(),await this.runFinished}currentBinding(e){if(!e.binding)return!0;let n=On(e.binding.file);return n!==null&&!n.pending&&n.account===e.binding.account&&n.epoch===e.binding.epoch}guard(e,n=!0){if(this.closed)throw Error("content_sync_closed");if(so(this.host),this.host.accountId()!==e.account||this.session!==e||e.generation!==this.accountGeneration)throw Error("account_changed");if(!this.currentBinding(e))throw Error("content_account_changed_preview_required");n&&e.abort.signal.throwIfAborted()}async accountWrite(e,n){let r=async()=>{this.guard(e),await n(e.account),this.guard(e)};this.host.accountTransition?await this.host.accountTransition(r):await r()}async persist(e){let n=e.writes.catch(()=>{}).then(async()=>{this.guard(e,!1);let r=JSON.stringify(e.stored);if(r===e.persisted)return;await li(Wt(e.file),{recursive:!0,mode:448});let s=e.file+".tmp-"+et();try{await nr(s,r,{mode:384,flag:"wx"}),this.guard(e,!1),await ys(s,e.file),e.persisted=r}finally{await sr(s).catch(()=>{})}});return e.writes=n,n}async getSession(){let e=this.host.accountId();if(!e)throw this.logAccount&&(this.runLog.reset(),this.logAccount=null),this.session?.abort.abort(),this.session=null,Error("not_signed_in");let n=this.accountGeneration;return so(this.host),this.initializing?this.initializing.then(r=>(this.guard(r),r)):this.session?.account===e&&this.session.generation===n&&this.currentBinding(this.session)?(this.guard(this.session,!1),this.session):(this.session?.abort.abort(new Error("account_changed")),this.logAccount!==e&&(this.runLog.reset(),this.logAccount=e),this.initializing=(async()=>{await this.watcher?.close(),this.watcher=null,this.previewValue=null,this.sources=[],this.agentNames.clear(),this.cloudAgents=void 0,this.devices=[],this.dirty.clear(),this.registered=null,this.devicesAt=0,this.changedAt=0;let r=Te(this.host.homeDir(),"content-sync"),s=Te(r,Ee(e)+".json"),o=Kg();try{let d=JSON.parse(await tr(s,"utf8"));cu(d),o={...o,...d,config:Dt(d.config,d.config.revision)},o.jobs=Array.isArray(d.jobs)?d.jobs.slice(-200):[]}catch(d){if(d.code!=="ENOENT")throw Error("Invalid content sync state; original data was retained")}let i,a=Te(this.host.homeDir(),"content-sync-device.json"),c=async()=>{let d=JSON.parse(await tr(a,"utf8"));if(typeof d?.id!="string"||!/^[A-Za-z0-9_-]{1,64}$/.test(d.id))throw Error("Invalid device sync ID");return d};try{i=await c()}catch(d){if(d.code!=="ENOENT")throw d;i={id:et()},await li(Wt(a),{recursive:!0});try{await nr(a,JSON.stringify(i),{flag:"wx",mode:384})}catch(g){if(g.code!=="EEXIST")throw g;i=await c()}}if(this.host.accountId()!==e)throw Error("account_changed");this.deviceId=i.id,this.customName=typeof i.name=="string"?i.name:"";let l=await this.host.contentSync.roots();if(this.host.accountId()!==e)throw Error("account_changed");let u={account:e,generation:n,file:s,stored:o,roots:l,abort:new AbortController,writes:Promise.resolve(),manifests:new Map};return this.session=u,await this.bindAccount(u),await this.recoverTrash(u),this.guard(u),o.owned&&await this.accountWrite(u,d=>this.host.contentSync.claim(!0,d)),this.setSources(await this.scan(u,l).catch(d=>(this.error=De(d),[]))),await this.register(u,!0),await this.watchRoots(u),u})().catch(r=>{throw this.session?.account===e&&(this.session.abort.abort(),this.session=null),r}).finally(()=>{this.initializing=null}),this.initializing)}async bindAccount(e){let n=Wt(e.file),r=no(this.host.homeDir()),s=Ee(e.account),o=On(r),i=!o?.account&&(await rr(n).catch(c=>{if(c.code==="ENOENT")return[];throw c})).some(c=>/^[a-f0-9]{64}\.json$/.test(c)&&c!==s+".json"),a=o?.pending&&(e.stored.owned||e.stored.config.revision>0);if((o?.account&&o.account!==s||i||a)&&(e.stored.accountReview=!0,e.stored.owned=!0,e.stored.config.enabled&&(e.stored.config={...e.stored.config,enabled:!1,revision:e.stored.config.revision+1}),await this.persist(e)),o?.account!==s||o.pending){this.guard(e,!1);let c=On(r);if(c?.account!==o?.account||c?.epoch!==o?.epoch||c?.pending!==o?.pending)throw Error("account_changed");ro(r,{version:1,account:s,...o?.epoch?{epoch:o.epoch}:{}})}e.binding={file:r,account:s,epoch:o?.epoch},this.guard(e,!1)}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 ws(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 ms(n)}async write(e,n,r,s){this.guard(e),await ii(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 ws(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(),this.wroteLocal=!0};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 bt(r.root).catch(()=>{throw Error(`Sync root unavailable: ${r.prefix||"Forsion"}`)});return ms(n)}async watchRoots(e){this.options.watch!==!1&&(this.guard(e),await this.watcher?.close(),this.watcher=Ns(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",(n,r)=>{let s=this.logical(e,r),o=Date.now();if(s){let i=this.dirty.get(s);i?i.last=o:this.dirty.set(s,{first:o,last:o})}this.schedule(s?void 0:o+ku)}))}logical(e,n){let r=null;for(let i of e.roots)(n===i.root||n.startsWith(i.root+Sn))&&(!r||i.root.length>r.root.length)&&(r=i);if(!r)return null;let s=or(r.root,n).split(Sn).join("/");return(r.prefix?s?`${r.prefix}/${s}`:r.prefix:s)||null}dueAt(e,n){return n.last<=this.flushAt?0:Math.min(n.last+hi(e),n.first+bu)}schedule(e){let n=e??1/0;for(let[r,s]of this.dirty)n=Math.min(n,this.dueAt(r,s));this.due&&clearTimeout(this.due),this.due=null,!(n===1/0||this.closed)&&(this.due=setTimeout(()=>{this.due=null;let r=this.session;r?.stored.config.enabled&&!r.stored.paused&&this.kick()},Math.max(0,n-Date.now())+50),this.due.unref?.())}kick(){if(this.running){this.again=!0;return}this.run()}flush(e){let n=this.session;if(!(this.closed||!this.host.accountId()||n&&(!n.stored.config.enabled||n.stored.paused)))return this.flushRequest++,this.flushThrough=Math.max(this.flushThrough,Date.now()),e==="quit"&&(this.quitting=!0),this.flushAt=this.quitting?1/0:this.flushThrough,this.flushing?this.flushing:this.flushing=(async()=>{try{for(;!this.closed;){let r=this.serial;if(await r,r!==this.serial)continue;if(this.running){await this.runFinished;continue}let s=this.flushRequest;if(await this.run(),s===this.flushRequest)return}}finally{this.flushing=null,this.quitting=!1,this.flushAt=this.flushThrough}})()}async request(e,n,r="",s="GET",o,i,a){this.guard(e);let c=this.host.readCreds();if(!c.token)throw Error("not_signed_in");let l=c.cloudUrl.replace(/\/+$/,"")+`/api/remotesync/content/${encodeURIComponent(n)}${r}`,u={Authorization:`Bearer ${c.token}`,"X-Content-Device":this.deviceId,...a},d;if(o instanceof Buffer){u["Content-Type"]="application/octet-stream",u["Content-Length"]=String(o.length);let y=async function*(){for(let h=0;h<o.length;h+=64*1024)e.abort.signal.throwIfAborted(),yield o.subarray(h,h+64*1024),i?.(Math.min(o.length,h+64*1024))};d=yu.from(y())}else o!==void 0&&(u["Content-Type"]="application/json",d=JSON.stringify(o));let g={method:s,headers:u,body:d,signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(12e4)]),...o instanceof Buffer?{duplex:"half"}:{}},p=await fetch(l,g);if(this.guard(e),!p.ok&&!(p.status===304&&a?.["If-None-Match"])){this.httpStatus=p.status;let y=await p.json().catch(()=>({}));throw Object.assign(new Error(typeof y.detail=="string"?y.detail:`content_http_${p.status}`),{status:p.status})}return s==="DELETE"&&this.tally("deletesSent"),p}async json(e,n,r="",s="GET",o){let i=await(await this.request(e,n,r,s,o)).json();return this.guard(e),i}async manifests(e,n){let r=new Map;for(let o of new Set(n.rules.filter(i=>i.target!=="off").map(i=>i.target))){let i=JSON.parse(await this.manifestText(e,o));us(i,o),r.set(o,i)}let s=[r.get("default"),r.get(`device-${this.deviceId}`)].filter(Boolean);return s.length&&(this.cloudAgents=[...new Set(s.flatMap(o=>o.nodes.filter(i=>!i.deleted&&i.kind==="file").map(i=>/^agents\/([^/]+)\/config\.toml$/.exec(i.path)?.[1]).filter(i=>!!i&&Vn.test(i))))].sort()),r}async manifestText(e,n){let r=e.manifests.get(n),s=r&&Date.now()-r.at<ar?r:void 0,o=await this.request(e,n,"","GET",void 0,void 0,s?{"If-None-Match":s.etag}:void 0);if(o.status===304)return await o.body?.cancel(),s?s.text:(e.manifests.delete(n),this.manifestText(e,n));let i=await o.text();this.guard(e),us(JSON.parse(i),n);let a=o.headers.get("etag");return a?e.manifests.set(n,{etag:a,text:i,at:Date.now()}):e.manifests.delete(n),i}route(e,n,r="file"){if(ss(e)||Zo(e,r)===!1)return null;let s=cn(e,n.rules);return s&&s.target!=="off"?s.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)}}deviceName(){return this.customName||Qr(ui())}setSources(e){let n=new Map,r={files:0,size:0};for(let o of e)o.kind==="folder"&&n.set(o.path,{size:0,files:0});for(let o of e)if(o.kind==="file"){Yc.some(i=>o.path.startsWith(i+"/"))||(r.files++,r.size+=o.size);for(let i=St(o.path);i;i=St(i)){let a=n.get(i);a&&(a.size+=o.size,a.files++)}}let s=new Map(e.filter(o=>o.kind==="file"&&/^agents\/[^/]+\/config\.toml$/.test(o.path)).map(o=>[o.path.slice(0,-12),o]));this.others=r,this.sources=[...n].sort(([o],[i])=>$t(o)-$t(i)||(o<i?-1:1)).slice(0,2e3).map(([o,i])=>({path:o,kind:"folder",size:i.size,files:i.files,...Yn(o)&&s.has(o)?{agent:!0}:{}})),this.sourcesAt=Date.now(),this.readAgentNames(s)}async readAgentNames(e){for(let n of this.agentNames.keys())e.has(n)||this.agentNames.delete(n);for(let[n,r]of e){let s=`${r.mtime}:${r.size}`;if(!(this.agentNames.get(n)?.key===s||r.size>256*1024))try{this.agentNames.set(n,{key:s,...Gc((await wn(r)).toString("utf8"))})}catch{this.agentNames.set(n,{key:s})}}}async rename(e){let n=typeof e=="string"?e.trim():"";if(n.length>64||/[\u0000-\u001f\u007f]/.test(n))throw Error("Invalid device name");let r=await this.getSession(),s=n||Qr(ui()),o=Mo(s,this.devices,this.deviceId);if(o)throw Error(o==="taken"?"device_name_taken":o==="reserved"?"device_name_reserved":"device_name_invalid");return await this.json(r,"devices",`/${encodeURIComponent(this.deviceId)}`,"PUT",{name:s,unique:!0}),await this.saveName(n),await this.register(r,!0),this.deviceName()}async saveName(e){let n=Te(this.host.homeDir(),"content-sync-device.json"),r=n+".tmp-"+et();try{await nr(r,JSON.stringify({id:this.deviceId,...e?{name:e}:{}}),{mode:384,flag:"wx"}),await ys(r,n)}finally{await sr(r).catch(()=>{})}this.customName=e}async register(e,n=!1){let r=Date.now();if(!n&&this.registered?.name===this.deviceName()&&r-this.registered.at<ar){r-this.devicesAt>=ar&&await this.refreshDevices(e);return}let s=(a,c)=>this.json(e,"devices",`/${encodeURIComponent(this.deviceId)}`,"PUT",{name:a,...c?{unique:!0}:{}}),o=async()=>(await this.json(e,"devices")).devices,i=a=>/device_name_(taken|reserved|invalid)/.test(De(a));try{await s(this.deviceName(),!0)}catch(a){if(!i(a))throw a;let c=!1;if(!this.customName){let l=Qr(ui());for(let u=0;u<5&&!c;u++){let d=await o(),g=null;for(let p=2;p<100&&!g;p++){let y=`${l} ${p}`;Mo(y,d,this.deviceId)||(g=y)}if(!g)break;try{await s(g,!0),await this.saveName(g),c=!0}catch(p){if(!i(p))throw p}}}c||await s(this.deviceName(),!1)}this.registered={name:this.deviceName(),at:r},await this.refreshDevices(e)}async refreshDevices(e){this.devicesAt=Date.now(),this.devices=(await this.json(e,"devices")).devices,await this.cacheDevices()}cachedDevices="";async cacheDevices(){let e=Te(this.host.homeDir(),"content-sync-devices.json"),n=[];try{let a=JSON.parse(await tr(e,"utf8"));Array.isArray(a?.devices)&&(n=a.devices)}catch{}let r=new Map(n.filter(a=>a&&typeof a.id=="string").map(a=>[a.id,a])),s=this.devices.map(a=>{let c=r.get(a.id),l=[...Array.isArray(c?.aliases)?c.aliases:[],...c&&typeof c.name=="string"&&c.name!==a.name?[c.name]:[]],u=l.filter((d,g)=>typeof d=="string"&&d!==a.name&&l.lastIndexOf(d)===g).slice(-5);return{id:a.id,name:a.name,...u.length?{aliases:u}:{}}}),o=JSON.stringify({devices:s});if(o===this.cachedDevices)return;let i=e+".tmp-"+et();try{await nr(i,o,{mode:384,flag:"wx"}),await ys(i,e),this.cachedDevices=o}catch(a){this.error=De(a)}finally{await sr(i).catch(()=>{})}}async setup(e){let n=await this.getSession(),r=e&&typeof e=="object"?e:{};if(n.stored.config.enabled||n.stored.config.revision>0)return null;let s=un(Zc(n.stored.config),"","off");for(let a of yt)a.id!=="agents"&&r[a.id]===!1&&(s=un(s,a.path,"off"));let o=new Set(this.sources.filter(a=>a.agent).map(a=>a.path.slice(7))),i=Array.isArray(r.agentSlugs)?r.agentSlugs.slice(0,512).filter(a=>typeof a=="string"&&o.has(a)):[];return this.preview(Qc(s,i))}async snapshot(e){(e==="zh"||e==="en")&&(this.uiLocale=e);let n=await this.getSession();return!n.stored.config.enabled&&!this.running&&Date.now()-this.sourcesAt>1e4&&(this.sourcesAt=Date.now(),this.scan(n).then(r=>{this.session===n&&this.setSources(r)},()=>{})),Date.now()-this.devicesAt>6e4&&(this.devicesAt=Date.now(),this.refreshDevices(n).catch(()=>{})),{available:!0,account:Ee(n.account),deviceId:this.deviceId,deviceName:this.deviceName(),config:structuredClone(n.stored.config),running:this.running,paused:n.stored.paused,phase:this.phase,jobs:structuredClone(n.stored.jobs),devices:this.devices,sources:this.sources.map(r=>{let s=r.agent&&this.agentNames.get(r.path);return s?{...r,...s.name?{name:s.name}:{},...s.nameEn?{nameEn:s.nameEn}:{}}:r}),...this.cloudAgents?{cloudAgents:this.cloudAgents}:{},...this.others?{others:this.others}:{},...n.stored.accountReview?{error:"content_account_changed_preview_required"}:this.error?{error:this.error}:{},...n.stored.agentArchive?{agentArchive:(({rewritten:r,...s})=>s)(n.stored.agentArchive)}:{}}}stats(){let e=this.host.accountId(),n=e&&this.session?.account===e?this.session:null,r=n?.stored,s={},o=e&&e===this.logAccount?this.runLog.snapshot():new Gn().snapshot();for(let i of r?.jobs??[])s[i.state]=(s[i.state]??0)+1;return{deviceId:this.deviceId||null,session:!!n,enabled:!!r?.config.enabled,paused:!!r?.paused,running:!!n&&this.running,phase:n?this.phase:"idle",revision:r?.config.revision??0,rules:(r?.config.rules??[]).map(i=>({source:i.source,target:i.target})),backlog:r?{jobs:s,blocked:[...this.blocked.values()].reduce((i,a)=>i+a.length,0),pendingUploads:Object.keys(r.pendingUploads??{}).length,unconfirmed:Object.keys(r.unconfirmed??{}).length,trash:r.trash?.length??0,awaitingBytes:this.awaitingBytes.size,dirty:this.dirty.size}:null,archive:r?.agentArchive?.state??null,...o}}async preview(e){let n=await this.getSession();if(e?.revision!==n.stored.config.revision)throw Error("config_changed");let s=Dt(e,n.stored.config.revision+1),o=await this.host.contentSync.roots();this.guard(n);let i=await this.previewScan(n,o),a=this.effective(s,i);if(n.stored.agentArchive?.state==="running"&&i.some(w=>w.kind==="file"&&w.path.startsWith("agents/")&&this.route(w.path,a)))throw Error("agent_archive_running");let c=await this.manifests(n,a);this.guard(n),this.setSources(i);let l=0,u=0,d=0,g=0,p=new Map;for(let w of i.filter(_=>_.kind==="file")){let _=this.route(w.path,a);if(!_)continue;let M=c.get(_)?.nodes.find(O=>!O.deleted&&O.kind==="file"&&O.path===w.path);if(w.size>vn){l++,g+=w.size;continue}let R=Ee(await wn(w));this.guard(n),p.set(w.path,R),R!==M?.hash&&(l++,g+=w.size,M?.version&&d++)}let y=s.enabled?this.agentAsks(n,i,a,c,p):[];for(let[w,_]of c)for(let M of _.nodes)!M.deleted&&M.kind==="file"&&M.version&&this.route(M.path,a)===w&&!i.some(R=>R.path===M.path)&&u++;let h=this.signature(i,c,o),m={token:et(),config:a,upload:s.enabled?l:0,download:s.enabled?u:0,conflicts:s.enabled?d:0,bytes:s.enabled?g:0,oldTargetsRetained:!0,expiresAt:Date.now()+5*6e4,...y.length?{agentAsks:y}:{}};return this.previewValue={value:m,account:n.account,signature:h},m}signature(e,n,r){return Ee(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,n){let r=this.serial,s;this.serial=new Promise(o=>{s=o}),await r;try{let o=await this.getSession(),i=this.previewValue;if(!i||i.value.token!==e||i.account!==o.account||i.value.expiresAt<Date.now()||i.value.config.revision!==o.stored.config.revision+1)throw Error("preview_expired");if(this.running)throw Error("sync_in_progress");let a=i.value.agentAsks??[],c=nm(n);this.resolving=!0;try{let l=await this.host.contentSync.roots(),u=await this.previewScan(o,l),d=await this.manifests(o,i.value.config);if(this.signature(u,d,l)!==i.signature)throw Error("preview_changed");let g=[];for(let m of l){let w=await ws(m.root).catch(_=>{if(_.code==="ENOENT")return null;throw _});w&&g.push({...m,dev:w.dev,ino:w.ino})}let p=structuredClone(i.value.config);for(let m of p.rules){let w=u.find(_=>_.kind==="folder"&&_.path===m.source);w&&(m.sourceId=await oi(w))}let y=a.length?Dt(a.reduce((m,w)=>un(m,`agents/${w.slug}`,"off"),p),p.revision):p;if(this.guard(o),this.previewValue!==i||i.value.config.revision!==o.stored.config.revision+1)throw Error("preview_expired");let h=structuredClone(o.stored);o.stored.config=y,o.stored.owned=!0,o.stored.paused=!1,delete o.stored.unconfirmed;for(let[m,w]of Object.entries(o.stored.files))(h.config.enabled!==o.stored.config.enabled||JSON.stringify(h.roots??g)!==JSON.stringify(g)||this.route(w.path,h.config)!==this.route(w.path,o.stored.config))&&delete o.stored.files[m];for(let[m,w]of Object.entries(o.stored.folders))(h.config.enabled!==o.stored.config.enabled||JSON.stringify(h.roots??g)!==JSON.stringify(g)||this.route(w.path,h.config,"folder")!==this.route(w.path,o.stored.config,"folder"))&&delete o.stored.folders[m];o.stored.roots=g,await this.persist(o);try{await this.accountWrite(o,m=>this.host.contentSync.claim(!0,m))}catch(m){throw o.stored=h,await this.persist(o),await this.accountWrite(o,w=>this.host.contentSync.claim(h.owned,w)).catch(()=>{}),m}if(this.previewValue=null,o.roots=l,await this.watchRoots(o),a.length)try{await this.resolveAsks(o,a,c,p)}catch(m){throw this.fault(De(m)),m}o.stored.accountReview&&(delete o.stored.accountReview,await this.persist(o))}finally{this.resolving=!1}}finally{s()}this.run()}async pause(e){let n=await this.getSession();if(!e&&n.stored.accountReview)throw Error("content_account_changed_preview_required");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(c=>c.path===n&&c.target===r&&c.direction===s&&["failed","paused","queued"].includes(c.state));if(i)return Object.assign(i,{state:"active",done:0,size:o,at:Date.now(),error:void 0,finishedAt:void 0}),i;let a={id:et(),path:n,target:r,direction:s,state:"active",done:0,size:o,at:Date.now()};return e.stored.jobs.push(a),e.stored.jobs=e.stored.jobs.slice(-200),a}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 a=this.job(e,n,r,s,o);try{let c=await i(a);if(this.guard(e),e.stored.paused)throw Error("paused");this.done(a),s==="upload"?nt("content","uploads"):s==="download"&&nt("content","downloads");let l=Zg[s];return l&&this.tally(l),c}catch(c){throw a.state=e.stored.paused?"paused":"failed",a.error=De(c),a.finishedAt=Date.now(),c}}async run(){if(this.running||this.closed||this.resolving)return;this.running=!0;let e;this.runFinished=new Promise(a=>{e=a});let n=Date.now();this.wroteLocal=!1;let r=new Set,s,o=!1,i=!1;try{if(s=await this.getSession(),this.runAccount=s.account,s.stored.accountReview){this.error="content_account_changed_preview_required";return}if(await this.archiveStep(s),!s.stored.config.enabled||s.stored.paused)return;s.abort.signal.aborted&&(s.abort=new AbortController),this.blocked.clear(),this.phase="scanning",this.error=void 0,o=!0,this.httpStatus=0,this.live()&&this.runLog.begin(n);let a=await this.host.contentSync.roots();this.guard(s),s.roots=a,await this.host.contentSync.agentFiles?.prepare().catch(m=>{this.error=De(m)}),this.guard(s);let c=await this.scan(s,a);await this.recordRoots(s);let l=this.effective(s.stored.config,c),u=await this.manifests(s,l);this.guard(s),await this.register(s),this.openJobs=new Set(s.stored.jobs.filter(m=>["failed","paused","active"].includes(m.state)&&["upload","download","merge"].includes(m.direction)).map(m=>m.target+"\0"+m.path)),await this.folders(s,l,c,u),await this.recordRoots(s),await this.fileRenames(s,l,c,u),c=await this.scan(s,a),l=this.effective(l,c),s.stored.config=l,this.setSources(c),this.phase="syncing";let d=m=>m.endsWith("/"+Qn),g=new Set,p=new Set,y=m=>m.startsWith("agents/")?m.slice(0,m.lastIndexOf("/")+1):null,h=m=>m.endsWith("/MEMORY.md")&&p.has(y(m)??"");for(let[m,w]of u)for(let _ of w.nodes.filter(M=>M.kind==="file"&&!M.busy&&d(M.path))){if(this.guard(s),s.stored.paused)throw Error("paused");if(!(this.route(_.path,l)!==m||c.some(M=>M.path===_.path))){if(this.isBlocked(m,_.path)){p.add(y(_.path)??"");continue}g.add(_.id);try{await this.missing(s,_,m,c,l)}catch(M){this.error=De(M),p.add(y(_.path)??"")}}}for(let m of c.filter(w=>w.kind==="file").sort((w,_)=>+!d(w.path)-+!d(_.path))){if(this.guard(s),s.stored.paused)throw Error("paused");let w=this.route(m.path,l);if(!(!w||h(m.path))){if(this.isBlocked(w,m.path)){d(m.path)&&p.add(y(m.path)??"");continue}try{await this.file(s,l,m,w,u.get(w))==="held"&&r.add(m.path)}catch(_){this.error=De(_),d(m.path)&&p.add(y(m.path)??"")}}}for(let[m,w]of u)for(let _ of w.nodes.filter(M=>M.kind==="file"&&!M.busy&&!g.has(M.id))){if(this.guard(s),s.stored.paused)throw Error("paused");if(!(this.isBlocked(m,_.path)||this.route(_.path,l)!==m||c.some(M=>M.path===_.path)||h(_.path))){if(this.holdGone(_.path)){r.add(_.path);continue}try{await this.missing(s,_,m,c,l)}catch(M){this.error=De(M)}}}await this.cleanupFolders(s,l,u),this.wroteLocal&&Date.now()-this.devicesAt>=6e4&&await this.refreshDevices(s).catch(()=>{}),(this.wroteLocal||Date.now()-this.changedAt>=ar)&&(await this.accountWrite(s,m=>this.host.contentSync.changed(m)),this.changedAt=Date.now()),this.guard(s),await this.persist(s),await this.pruneBases(s),i=!0}catch(a){this.error=De(a)}finally{this.phase=s?.stored.paused?"paused":"idle",o&&(this.noteHealth(n,i),this.live()&&this.runLog.end(i));for(let[a,c]of this.dirty)!r.has(a)&&c.last<n&&this.dirty.delete(a);s&&this.host.accountId()===s.account&&(await this.persist(s).catch(()=>{}),!this.closed&&s.abort.signal.aborted&&!s.stored.paused&&s.stored.config.enabled&&(s.abort=new AbortController,this.again=!0)),this.running=!1,this.runAccount=null,this.again&&!this.closed?(this.again=!1,queueMicrotask(()=>void this.run())):this.schedule(),e()}}noteHealth(e,n){n&&(nt("content","cycles"),nt("content","cycleMsTotal",Math.max(0,Date.now()-e)));let r=this.blocked.size?"errBlocked":this.error?Fr(this.error,this.httpStatus):null;r?this.health.error(r):this.error||this.health.ok()}holdGone(e){let n=this.dirty.get(e);if(!n)return!1;let r=Date.now();return n.last>this.flushAt&&r-n.last<hi(e)&&r-n.first<bu}isBlocked(e,n){return(this.blocked.get(e)??[]).some(r=>n===r||n.startsWith(r+"/"))}block(e,n,r){if(this.blocked.set(e,[...this.blocked.get(e)??[],n]),this.lastError=De(r),r!==void 0&&r===this.blockedError){this.live()&&this.runLog.addPaths([n]);return}this.blockedError=r,this.fault(De(r),[n])}async folders(e,n,r,s){let o=r.filter(a=>a.kind==="folder"),i=new Map;for(let a of o)if(a.localId){if(i.has(a.localId))throw Error(`Duplicate folder sync identity: ${a.path}`);i.set(a.localId,a.path)}for(let[a,c]of s){for(let l of c.nodes.filter(u=>u.kind==="folder"&&!u.deleted&&!u.busy).sort((u,d)=>$t(u.path)-$t(d.path)))if(!this.isBlocked(a,l.path))try{let u=Object.entries(e.stored.folders).find(([g,p])=>g.startsWith(a+":")&&p.id===l.id)?.[1],d=(u?o.find(g=>g.localId===u.localId):null)??o.find(g=>g.path===l.path);if(u&&d&&l.path!==u.path&&d.path!==u.path&&l.path!==d.path)throw Error(`Concurrent folder rename: ${d.path}`);if(u&&d&&l.path!==u.path&&d.path===u.path){if(this.route(d.path,n,"folder")!==a)continue;if(this.route(l.path,n,"folder")!==a)throw Error("Remote rename crosses a sync rule; review the destination");await this.operation(e,d.path,a,"rename",null,()=>ai(e.roots,d.path,l.path,(p,y)=>this.lock(e,p,y)));let g=d.path;for(let p of r)if(p.path===g||p.path.startsWith(g+"/")){let y=p.path;p.path=l.path+y.slice(g.length);let h=je(e.roots,p.path);p.physical=Te(h.root,h.relative)}for(let[p,y]of Object.entries(e.stored.files))p.startsWith(a+":")&&y.path.startsWith(u.path+"/")&&(y.path=l.path+y.path.slice(u.path.length));for(let p of n.rules)(p.source===u.path||p.source.startsWith(u.path+"/"))&&(p.source=l.path+p.source.slice(u.path.length))}if(!d&&this.route(l.path,n,"folder")===a&&!u){await mu(e.roots,l.path,(p,y)=>this.lock(e,p,y));let g=(await this.scan(e)).find(p=>p.path===l.path);g&&(r.push(g),o.push(g))}}catch(u){this.block(a,l.path,u),this.tally("folderConflicts");let d=Object.entries(e.stored.folders).find(([g,p])=>g.startsWith(a+":")&&p.id===l.id)?.[1];d&&this.block(a,d.path,u)}for(let l of o.sort((u,d)=>$t(u.path)-$t(d.path)))if(!this.isBlocked(a,l.path))try{let u=this.route(l.path,n,"folder"),d=n.rules.some(w=>w.target===a&&w.source.startsWith(l.path+"/"));if(u!==a&&!d||Zo(l.path,"folder")===!1)continue;let g=await oi(l),p=e.stored.folders[Ie(a,g)],y=p?c.nodes.find(w=>w.id===p.id):c.nodes.find(w=>w.path===l.path&&!w.deleted);if(y?.deleted){if(p){let w=!1;for(let _ of r.filter(M=>M.kind==="file"&&M.path.startsWith(l.path+"/")&&this.route(M.path,n)===a)){let M=Object.entries(e.stored.files).find(([R,O])=>R.startsWith(a+":")&&O.path===_.path)?.[1];if(!M){w=!0;break}if(!this.sameAsShadow(M,_)){let R=Ee(await wn(_));if(R!==M.hash&&!(M.memoryDeleted&&fi(_.path)&&R===ir)){w=!0;break}}}if(!w)continue}y=void 0}let h=St(l.path),m=h?c.nodes.find(w=>w.path===h&&w.kind==="folder"&&!w.deleted)?.id:"";if(h&&!m)throw Error("Cloud parent is unavailable");if(!y)y=await this.json(e,a,"/nodes","POST",{id:p?et():g,parentId:m,name:Vt(l.path),kind:"folder"}),c.nodes.push(y);else if(p&&y.path!==l.path){if(y.revision!==p.revision)throw Error(`Concurrent folder rename: ${l.path}`);let w=y.path,_=await this.operation(e,l.path,a,"rename",null,()=>this.json(e,a,`/nodes/${y.id}`,"PATCH",{parentId:m,name:Vt(l.path),revision:y.revision}));for(let M of c.nodes)M.path.startsWith(w+"/")&&(M.path=l.path+M.path.slice(w.length));Object.assign(y,_);for(let[M,R]of Object.entries(e.stored.files))M.startsWith(a+":")&&R.path.startsWith(w+"/")&&(R.path=l.path+R.path.slice(w.length))}e.stored.folders[Ie(a,g)]={id:y.id,localId:g,path:l.path,revision:y.revision,parentId:y.parentId,name:y.name}}catch(u){this.block(a,l.path,u);let d=l.localId?e.stored.folders[Ie(a,l.localId)]:void 0;d&&this.block(a,d.path,u),nt("content","conflicts"),this.tally("folderConflicts");let g=this.job(e,l.path,a,"rename",null);g.state="conflict",g.error=De(u),g.finishedAt=Date.now()}}}async cleanupFolders(e,n,r){let s=await this.scan(e);for(let[o,i]of r)for(let a of i.nodes.filter(c=>c.kind==="folder"&&!c.busy).sort((c,l)=>$t(l.path)-$t(c.path))){if(this.isBlocked(o,a.path)||this.route(a.path,n,"folder")!==o)continue;let c=Object.entries(e.stored.folders).find(([u,d])=>u.startsWith(o+":")&&d.id===a.id);if(!c)continue;let l=s.find(u=>u.path===a.path&&u.kind==="folder");if(a.deleted&&l){if(s.some(d=>d.path.startsWith(a.path+"/"))||(await rr(l.physical)).some(d=>d!==".forsion-sync-id.json"))continue;await this.operation(e,a.path,o,"delete",null,()=>this.lock(e,l.physical,()=>{rt(l.root,or(l.root,l.physical).split(Sn).join("/"));let d=qg(l.physical);if(d.some(y=>y!==".forsion-sync-id.json"))throw Error("Folder changed before deletion");let g=Te(l.physical,".forsion-sync-id.json"),p=d.length?bn(g):null;p&&ci(g);try{Wg(l.physical)}catch(y){if(p)try{Vg(g,p,{flag:"wx",mode:384})}catch{}throw y}})),this.tally("deletesLocal"),delete e.stored.folders[c[0]]}else if(!a.deleted&&!l){if(!await this.absent(e,a.path)||i.nodes.some(u=>u.parentId===a.id&&!u.deleted))continue;await this.operation(e,a.path,o,"delete",null,()=>this.json(e,o,`/nodes/${a.id}`,"DELETE",{revision:a.revision,version:null})),a.deleted=!0,delete e.stored.folders[c[0]]}}}async download(e,n,r,s){if(n.size!==void 0&&n.size>vn)throw Error("File exceeds 50 MB content limit");let o=await this.request(e,r,`/nodes/${n.id}/content`),i=[],a=0;if(o.body){let l=o.body.getReader();for(;;){let u=await l.read();if(u.done)break;if(this.guard(e),a+=u.value.length,a>vn)throw await l.cancel(),Error("Content too large");i.push(u.value),s.done=a}}let c=Buffer.concat(i);if(n.hash&&Ee(c)!==n.hash)throw Error("Cloud file changed during download");return c}async fileRenames(e,n,r,s){for(let[o,i]of s)for(let a of i.nodes.filter(c=>c.kind==="file"&&!c.deleted&&!c.busy)){let c=e.stored.files[Ie(o,a.id)];if(!c||c.path===a.path)continue;let l=r.find(u=>u.kind==="file"&&u.path===c.path);if(!(!l||this.route(l.path,n)!==o))try{if(this.route(a.path,n)!==o)throw Error("Remote rename crosses a sync rule; review the destination");await this.operation(e,l.path,o,"rename",null,()=>ai(e.roots,l.path,a.path,(u,d)=>this.lock(e,u,d))),c.path=a.path}catch(u){this.block(o,l.path,u),this.block(o,a.path,u)}}}async upload(e,n,r,s,o){if(s.length>vn)throw Error("File exceeds 50 MB content limit");this.guard(e);let i=this.host.readCreds(),a=yu.from((async function*(){for(let l=0;l<s.length;l+=64*1024)e.abort.signal.throwIfAborted(),yield s.subarray(l,l+64*1024),o.done=Math.min(s.length,l+64*1024)})()),c=await fetch(i.cloudUrl.replace(/\/+$/,"")+`/api/remotesync/content/${encodeURIComponent(r)}/nodes/${n.id}/content`,{method:"PUT",headers:{Authorization:`Bearer ${i.token}`,"X-Content-Device":this.deviceId,"Content-Type":"application/octet-stream","Content-Length":String(s.length),"X-Content-Version":n.version??"create"},body:a,duplex:"half",signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(12e4)])});if(this.guard(e),!c.ok){let l=await c.json().catch(()=>({}));throw Error(l.detail??`content_http_${c.status}`)}return await c.json()}async shadow(e,n,r,s,o,i){let a=Ie(n,r.id),c=Ee(s),l=di(s);l&&s.length>=wu&&await this.keepBase(e,c,s);for(let u of e.stored.jobs)u.path===r.path&&u.target===n&&["failed","paused","active"].includes(u.state)&&["upload","download","merge"].includes(u.direction)&&this.done(u);e.stored.pendingUploads&&delete e.stored.pendingUploads[a],delete e.stored.unconfirmed?.[a],e.stored.files[a]={id:r.id,path:r.path,version:r.version,hash:c,...l&&s.length<wu?{base:s.toString("utf8")}:{},...i?{inode:i.inode,stat:i.key,statAt:i.at}:o?{inode:o.inode}:{}}}async seen(e,n,r){let s=je(e.roots,n),o=await bt(Te(s.root,...s.relative.split("/"))).catch(()=>null);if(!o?.isFile())return;let i=gs(o);return{key:er(i),at:r,inode:i.inode}}sameAsShadow(e,n){return!this.dirty.has(n.path)&&e.stat!==void 0&&e.statAt!==void 0&&e.stat===er(n)&&tm(n)<=e.statAt-em}unchanged(e,n,r,s,o){let i=Ie(n,r.id);return this.sameAsShadow(s,o)&&s.id===r.id&&s.path===o.path&&!r.busy&&!r.deleted&&r.version===s.version&&r.hash===s.hash&&!e.stored.unconfirmed?.[i]&&!e.stored.pendingUploads?.[i]&&!this.openJobs.has(n+"\0"+o.path)}hold(e,n){if(e.path.endsWith("/"+Qn)||n?.stat===er(e))return!1;let r=e.mtime,s=Date.now(),o=this.dirty.get(e.path);if(Math.floor(r)<=this.flushAt)return!1;if(o)o.last=Math.max(o.last,r);else{if(s-r>=hi(e.path))return!1;o={first:Math.min(s,r),last:r},this.dirty.set(e.path,o)}return this.dueAt(e.path,o)>s}settled(e,n){let r=this.dirty.get(e);r&&(r.last<n?this.dirty.delete(e):r.first=n)}async keepBase(e,n,r){let s=pi(e),o=Te(s,n);if(await bt(o).then(()=>!0,()=>!1))return;await li(s,{recursive:!0,mode:448});let i=o+".tmp-"+et();try{await nr(i,r,{mode:384,flag:"wx"}),await ys(i,o)}finally{await sr(i).catch(()=>{})}}async readBase(e,n){if(n.base!==void 0)return n.base;let r=await tr(Te(pi(e),n.hash)).catch(s=>{if(s.code==="ENOENT")return null;throw s});return r&&Ee(r)===n.hash?r.toString("utf8"):null}async pruneBases(e){let n=new Set(Object.values(e.stored.files).map(s=>s.hash)),r=pi(e);for(let s of await rr(r).catch(()=>[]))n.has(s)||await sr(Te(r,s)).catch(()=>{})}async file(e,n,r,s,o){if(r.size>vn){nt("content","skippedTooLarge",1,r.path),await this.operation(e,r.path,s,"upload",r.size,async()=>{throw Error("File exceeds 50 MB content limit")});return}let i=o.nodes.find(w=>w.kind==="file"&&!w.deleted&&w.path===r.path);if(!i){let w=Object.entries(e.stored.files).find(([_,M])=>_.startsWith(s+":")&&M.inode===r.inode&&M.path!==r.path)?.[1];if(w){let _=je(e.roots,w.path),M=await bt(Te(_.root,_.relative)).then(async O=>gs(O).inode!==r.inode||St(w.path)!==St(r.path)?!0:(await rr(Wt(r.physical))).includes(Vt(w.path)),O=>O.code==="ENOENT"?!1:Promise.reject(O)),R=o.nodes.find(O=>O.id===w.id&&!O.deleted);if(!M&&R)try{if(R.path!==w.path)throw Error(`Concurrent file rename: ${r.path}`);let O=St(r.path),S=O?o.nodes.find(E=>E.path===O&&E.kind==="folder"&&!E.deleted)?.id:"";if(O&&!S)throw Error("Rename parent unavailable");let C=await this.operation(e,r.path,s,"rename",null,()=>this.json(e,s,`/nodes/${R.id}`,"PATCH",{name:Vt(r.path),parentId:S,revision:R.revision}));Object.assign(R,C),w.path=r.path,i=R}catch(O){for(let S of new Set([w.path,R.path,r.path]))this.block(s,S,O);throw O}}}let a=i?e.stored.files[Ie(s,i.id)]:Object.entries(e.stored.files).find(([w,_])=>w.startsWith(s+":")&&_.path===r.path)?.[1];if(!a&&i?.version&&s==="default"&&(a=await this.legacyBaseline(r.path,i)),i&&a&&this.unchanged(e,s,i,a,r))return;if(this.hold(r,a))return"held";let c=Date.now(),l=await wn(r),u=Ee(l),d={key:er(r),at:c,inode:r.inode};if(this.guard(e),this.settled(r.path,c),!i){if((a?o.nodes.find(C=>C.id===a.id&&C.deleted):null)&&a&&(a.hash===u||a.memoryDeleted&&fi(r.path)&&u===ir)){fi(r.path)?await this.clearDeletedMemory(e,s,r,a,l,u):(await this.operation(e,r.path,s,"delete",r.size,()=>this.trashFile(e,r,u)),this.tally("deletesLocal"),delete e.stored.files[Ie(s,a.id)]);return}let _=St(r.path),M=_?o.nodes.find(C=>C.path===_&&!C.deleted&&C.kind==="folder")?.id:"";if(_&&!M)throw Error("Parent folder is unavailable");let R=Object.entries(e.stored.pendingUploads??{}).find(([C,E])=>C.startsWith(s+":")&&E.path===r.path&&!o.nodes.some(I=>I.id===E.id))?.[1];for(let[C,E]of Object.entries(e.stored.pendingUploads??{}))C.startsWith(s+":")&&E.path===r.path&&o.nodes.some(I=>I.id===E.id&&I.deleted)&&delete e.stored.pendingUploads[C];let O=R?.id??et(),S=Ie(s,O);(e.stored.pendingUploads??={})[S]={id:O,path:r.path},await this.persist(e),i=await this.json(e,s,"/nodes","POST",{id:O,parentId:M,name:Vt(r.path),kind:"file"}),i.id!==O&&delete e.stored.pendingUploads[S],o.nodes.push(i),a=void 0}if(i.busy)return;let g=Ie(s,i.id);if(i.version&&this.awaitingBytes.delete(g),i.hash===u){await this.shadow(e,s,i,l,r,d);return}if(i.hash&&e.stored.unconfirmed?.[g]===i.hash&&(await this.shadow(e,s,i,await this.operation(e,r.path,s,"download",i.size??null,w=>this.download(e,i,s,w)),r),a=e.stored.files[g]),!i.version&&a&&a.hash===u&&!e.stored.pendingUploads?.[g]){let w=this.awaitingBytes.get(g)??Date.now();if(this.awaitingBytes.set(g,w),Date.now()-w<Xg)return}if(this.awaitingBytes.delete(g),!i.version||a&&i.version===a.version){(e.stored.unconfirmed??={})[g]=u,await this.persist(e);let w=await this.operation(e,r.path,s,"upload",l.length,_=>this.upload(e,i,s,l,_));Object.assign(i,w),await this.shadow(e,s,i,l,r,d);return}let p=await this.operation(e,r.path,s,"download",i.size??null,w=>this.download(e,i,s,w)),y=p,h=!1;if(!a||a.hash!==u){let w=l.toString("utf8"),_=p.toString("utf8"),M=a?await this.readBase(e,a):null,R=Buffer.from(w).equals(l)&&Buffer.from(_).equals(p)?this.host.contentSync.merge(r.path,w,M,_):null;if(R?(y=Buffer.from(R.content),h=R.conflict):h=!0,h){await this.preserveConflict(e,r.path,l)&&(nt("content","conflicts"),this.tally("conflictCopies"));let O=this.job(e,r.path,s,"merge",l.length);O.state="conflict",O.error="Both versions preserved",O.finishedAt=Date.now()}if(!y.equals(p)){let O=await this.operation(e,r.path,s,"merge",y.length,S=>this.upload(e,i,s,y,S));Object.assign(i,O)}}let m=Date.now();await this.write(e,r.path,y,u),await this.shadow(e,s,i,y,r,await this.seen(e,r.path,m))}async preserveConflict(e,n,r){let s=je(e.roots,n),o=await Je(s.root,s.relative),i=Vt(n),a=Ee(r);for(let c of await rr(Wt(o))){if(c.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}(?: \d+)?\)/,"")!==i||!ss(c))continue;let l=St(n)?St(n)+"/"+c:c,u=je(e.roots,l),d=await Je(u.root,u.relative),g=await bt(d);if(g.isFile()&&g.size===r.length&&Ee(await tr(d))===a)return!1}return await this.write(e,await this.copyName(e,n),r,null),!0}async copyName(e,n){let r=new Date;for(let s=1;;s++){let o=tu(n,r,s),i=je(e.roots,o);if(!await bt(Te(i.root,...i.relative.split("/"))).then(()=>!0,a=>a.code==="ENOENT"?!1:Promise.reject(a)))return o}}async legacyBaseline(e,n){let r=await this.host.contentSync.agentFiles?.baseline(e).catch(()=>null);if(!(!r||!n.version)&&!(r.pending&&Number(n.version.split(":")[0])!==r.seq))return{id:n.id,path:e,version:`${r.seq}:${r.hash}`,hash:r.hash,...r.base!==void 0?{base:r.base}:{}}}agentAsks(e,n,r,s,o){let i=[],a=c=>c.length?Math.max(...c):null;for(let c of n){let l=c.kind==="folder"?Yn(c.path):null;if(!l||es.has(l))continue;let u=`agents/${l}/`,d=this.route(u+"config.toml",r);if(!d||Object.entries(e.stored.files).some(([m,w])=>m.startsWith(d+":")&&w.path.startsWith(u)))continue;let g=(s.get(d)?.nodes??[]).filter(m=>!m.deleted&&m.kind==="file"&&m.version&&m.path.startsWith(u)&&this.route(m.path,r)===d),p=n.filter(m=>m.kind==="file"&&m.path.startsWith(u)&&this.route(m.path,r)===d);if(!g.length||!p.length)continue;let y=new Map(g.map(m=>[m.path,m])),h=p.filter(m=>{let w=y.get(m.path);return!!w&&o.get(m.path)!==w.hash}).length;!h&&p.length===g.length&&p.every(m=>y.has(m.path))||i.push({slug:l,namespace:d,cloudFiles:g.length,localFiles:p.length,differ:h,cloudMtime:a(g.map(m=>m.mtime??0)),localMtime:a(p.map(m=>m.mtime))})}return i}async resolveAsks(e,n,r,s){for(let o of n){try{await this.resolveAsk(e,o,r[o.slug]??"merge",s)}catch(l){throw this.dropShadows(e,o.namespace,`agents/${o.slug}/`),await this.persist(e),Error(`agent_open_failed: ${De(l)}`)}let i=`agents/${o.slug}`,a=s.rules.find(l=>l.source===i),c=un(e.stored.config,i,Jc(s,i));a&&(c={...c,rules:c.rules.map(l=>l.source===i?{...a,target:l.target}:l)}),e.stored.config=Dt(c,e.stored.config.revision+1),await this.persist(e)}}async resolveAsk(e,n,r,s){let o=n.namespace,i=`agents/${n.slug}/`;if(this.dropShadows(e,o,i),r==="local"){await this.archiveAgent(e,o,n.slug),await this.persist(e);return}let a=await this.json(e,o);this.guard(e),us(a,o);let c=new Map(a.nodes.filter(p=>!p.deleted&&!p.busy&&p.kind==="file"&&p.version&&p.path.startsWith(i)&&this.route(p.path,s)===o).map(p=>[p.path,p])),l=p=>p.endsWith("/"+Qn),u=async(p,y,h)=>{let m=Date.now();return await this.write(e,p,y,h),this.seen(e,p,m)};for(let[p,y]of c){if(!l(p))continue;let h=je(e.roots,p);if(Su(Te(h.root,h.relative)))continue;let m=await this.operation(e,p,o,"download",y.size??null,w=>this.download(e,y,o,w));await this.shadow(e,o,y,m,void 0,await u(p,m,null))}let d=(await this.scan(e)).filter(p=>p.kind==="file"&&p.path.startsWith(i)&&this.route(p.path,s)===o&&p.size<=vn).sort((p,y)=>+!l(p.path)-+!l(y.path)),g=await this.removedDir(e,n.slug);for(let p of d){this.guard(e);let y=await wn(p),h=Ee(y),m=c.get(p.path),w=p.path.slice(i.length);if(m&&m.hash===h){await this.shadow(e,o,m,y,p);continue}if(r==="cloud"){if(await this.keep(e,`${g}/${w}`,y),m){let S=await this.operation(e,p.path,o,"download",m.size??null,C=>this.download(e,m,o,C));await this.shadow(e,o,m,S,p,await u(p.path,S,h))}else w==="MEMORY.md"?await this.write(e,p.path,Buffer.alloc(0),h):await this.removeLocal(e,p,h);continue}if(!m)continue;let _=await this.operation(e,p.path,o,"download",m.size??null,S=>this.download(e,m,o,S)),M=o==="default"?await this.legacyBaseline(p.path,m):void 0;if(M?.hash===h){await this.shadow(e,o,m,_,p,await u(p.path,_,h));continue}let R=M?await this.readBase(e,M):null,O=di(y)&&di(_)?this.host.contentSync.merge(p.path,y.toString("utf8"),R,_.toString("utf8")):null;if(O&&!O.conflict){let S=Buffer.from(O.content);S.equals(y)||await this.write(e,p.path,S,h),await this.shadow(e,o,m,_)}else(m.mtime??0)>p.mtime?(await this.keep(e,`${g}/${w}`,y),await this.shadow(e,o,m,_,p,await u(p.path,_,h))):(await this.keep(e,`${g}/${w}`,_),await this.shadow(e,o,m,_))}await this.persist(e)}dropShadows(e,n,r){for(let[s,o]of Object.entries(e.stored.files))s.startsWith(n+":")&&o.path.startsWith(r)&&(delete e.stored.files[s],delete e.stored.unconfirmed?.[s])}async removedDir(e,n,r="agents"){let s=new Date,o=a=>String(a).padStart(2,"0"),i=`${s.getFullYear()}-${o(s.getMonth()+1)}-${o(s.getDate())} ${o(s.getHours())}${o(s.getMinutes())}`;for(let a=1;;a++){let c=`${r}/.removed/${n} ${i}${a>1?` ${a}`:""}`,l=je(e.roots,c);if(!await bt(Te(l.root,...l.relative.split("/"))).then(()=>!0,u=>u.code==="ENOENT"?!1:Promise.reject(u)))return c}}async keep(e,n,r){this.guard(e),await ii(e.roots,n,r,null)}async removeLocal(e,n,r){await this.lock(e,n.physical,()=>{if(rt(n.root,or(n.root,n.physical).split(Sn).join("/")),Ee(bn(n.physical))!==r)throw Error("Local file changed before replacing");ci(n.physical)})}async archiveAgent(e,n,r){let s=this.host.readCreds();if(!s.token)throw Error("not_signed_in");let o=await fetch(s.cloudUrl.replace(/\/+$/,"")+"/api/remotesync/agent-archive/agent",{method:"POST",headers:{Authorization:`Bearer ${s.token}`,"Content-Type":"application/json","X-Content-Device":this.deviceId},body:JSON.stringify({namespace:n,slug:r,opId:et(),locale:this.locale()}),signal:AbortSignal.any([e.abort.signal,AbortSignal.timeout(12e4)])});this.guard(e);let i=await o.json().catch(()=>({}));if(this.guard(e),!o.ok||i?.state!=="done")throw Error(typeof i?.detail=="string"?i.detail:`agent_archive_http_${o.status}`)}async absent(e,n){this.guard(e);let r=je(e.roots,n),s=await Je(r.root,r.relative);try{return await bt(s),!1}catch(o){if(o.code==="ENOENT")return!0;throw o}}async missing(e,n,r,s,o){let i=e.stored.files[Ie(r,n.id)],a=e.stored.pendingUploads?.[Ie(r,n.id)];if(n.deleted){i&&delete e.stored.files[Ie(r,n.id)],a&&delete e.stored.pendingUploads[Ie(r,n.id)];return}if(n.busy||i?.inode&&this.blocked.has(r)&&s.some(u=>u.kind==="file"&&u.inode===i.inode&&this.isBlocked(r,u.path)&&this.route(u.path,o)===r))return;if(!n.version){a&&await this.absent(e,n.path)&&(await this.operation(e,n.path,r,"delete",null,()=>this.json(e,r,`/nodes/${n.id}`,"DELETE",{revision:n.revision,version:null})),delete e.stored.pendingUploads[Ie(r,n.id)],n.deleted=!0);return}if(i&&i.version===n.version){if(!await this.absent(e,n.path))return;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[Ie(r,n.id)],n.deleted=!0;return}let c=await this.operation(e,n.path,r,"download",n.size??null,u=>this.download(e,n,r,u)),l=Date.now();await this.write(e,n.path,c,null),await this.shadow(e,r,n,c,void 0,await this.seen(e,n.path,l))}async recoverTrash(e){for(let n of[...e.stored.trash??[]]){if(n.parentId){let c=(await ms(e.roots)).find(l=>l.kind==="folder"&&l.localId===n.parentId);c&&(n.path=c.path+"/"+Vt(n.path))}let r=je(e.roots,n.path),s=await Je(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 ws(o);if(n.stageDev!==void 0&&(i.dev!==n.stageDev||i.ino!==n.stageIno))throw Error("Sync recovery root changed; journal retained");let a=Te(o,n.stage);await bt(a).then(()=>!0,c=>c.code==="ENOENT"?!1:Promise.reject(c))&&await this.lock(e,s,()=>{if(rt(o,n.stage,!0),Ee(bn(a))!==n.hash)throw Error("Sync recovery content changed");rt(r.root,r.relative),Yg(Wt(s),{recursive:!0});let c=Su(s)?s+` (sync recovery ${et().slice(0,8)})`:s;try{Bg(a,c)}catch(l){if(l.code!=="EXDEV")throw l;if(Gg(a,c,Jg.COPYFILE_EXCL),Ee(bn(c))!==n.hash)throw Error("Sync recovery copy incomplete; original retained")}ci(a)},!0),e.stored.trash=e.stored.trash.filter(c=>c!==n)}}async clearDeletedMemory(e,n,r,s,o,i){s.memoryDeleted&&s.hash===ir&&i===ir||(await this.operation(e,r.path,n,"delete",r.size,async()=>{if(!s.memoryDeleted&&o.length){let l=r.path==="human/MEMORY.md",u=await this.removedDir(e,l?"memory":r.path.split("/")[1],l?"human":"agents");await this.keep(e,`${u}/MEMORY.md`,o)}s.memoryDeleted=!0,await this.persist(e);let a=Date.now();o.length&&await this.write(e,r.path,Buffer.alloc(0),i);let c=await this.seen(e,r.path,a);e.stored.files[Ie(n,s.id)]={...s,hash:ir,base:"",stat:void 0,statAt:void 0,...c?{inode:c.inode,stat:c.key,statAt:c.at}:{}}}),this.tally("deletesLocal"))}async trashFile(e,n,r){this.guard(e);let s=await Je(n.root,or(n.root,n.physical).split(Sn).join("/")),o={path:n.path,stage:".forsion-sync-trash-"+et(),hash:r},i=Te(n.root,o.stage),a=vu(n.root);o.stageRoot=n.root,o.stageDev=a.dev,o.stageIno=a.ino;try{let c=JSON.parse(bn(Te(Wt(s),".forsion-sync-id.json"),"utf8")).id;/^[a-f0-9-]{36}$/i.test(c)&&(o.parentId=c)}catch{}(e.stored.trash??=[]).push(o),await this.persist(e);try{await this.lock(e,s,()=>{if(rt(n.root,or(n.root,s).split(Sn).join("/")),Ee(bn(s))!==r)throw Error("Local file changed before deletion");zg(s,i)}),await this.host.contentSync.trash(i),e.stored.trash=e.stored.trash.filter(c=>c!==o)}catch(c){throw this.host.accountId()===e.account&&!e.abort.signal.aborted&&await this.recoverTrash(e),c}}};function nm(t){let e={};if(t&&typeof t=="object")for(let[n,r]of Object.entries(t))Vn.test(n)&&Wc.includes(r)&&(e[n]=r);return e}function Su(t){try{return vu(t),!0}catch(e){if(e.code==="ENOENT")return!1;throw e}}Mi(ha);function TS(t){pa(t.contentSync?.withWriteLock?.bind(t.contentSync)),qi(t),Zs(t),Eu(t),t.log("[forsion-extend] cloud account handlers registered"),Bs(t)?qs(t):t.log("[forsion-extend] host has no Connect seam (projectsRoot / transpileForServe / mimeOf / setPreviewHooks); Connect stays with the host"),Vs(t)?Ys(t):t.log("[forsion-extend] host has no remote-sync seam (registerRemoteSyncBackend / readCreds); penzor stays with the host"),oo(t)?io(t):t.log("[forsion-extend] host has no account seam (accountCommit / accountClear / \u2026); account core stays with the host"),Eo(t)?_o(t):t.log("[forsion-extend] host has no amadeus seam (setAmadeusSyncFactory); cloud sync stays with the host"),xo(t)?Ao(t):t.log("[forsion-extend] host has no unit seam (setUnitHubFactory); the device channel stays with the host"),Uo(t)?Ol(t):t.log("[forsion-extend] host has no diagnostics seam (homeDir / readCreds / accountId / appVersion); diagnostics upload is off"),Uo(t)&&Zl(t)}export{qa as ACCOUNT_SEAM,Oc as AMADEUS_SEAM,zs as CONNECT_MAX_FILES,ya as CONNECT_MAX_FILE_BYTES,wa as CONNECT_MAX_TOTAL_BYTES,Or as DIAGNOSTICS_VAULT,Aa as FORSION_CONNECT_LOCAL_SDK,Bi as PAY_PERIODS,zi as PAY_TABS,Ia as PENZOR_MAX_FILE,Ae as SYNC_IPC,$c as UNIT_SEAM,In as UPLOAD_MAX_FILE,zn as UnitCapsReporter,Hn as UnitHost,Ue as cloudJson,Sa as collectProjectFiles,Nr as conflictCopyPath,Uf as conflictCopyVariant,Ca as connectMetaOf,Ba as createAccountCloud,Pc as createAmadeusCloud,Dr as createPenzorRemote,Nc as createUnitHub,Ir as deviceHeader,Ws as expectedPartsOf,Oe as forsionAccountId,Sr as forsionRefreshToken,Rn as forsionWhoami,oo as hasAccountHost,Eo as hasAmadeusHost,Bs as hasConnectHost,Vs as hasRemoteSyncHost,xo as hasUnitHost,xa as makePreviewProxy,La as multipartFrame,ka as readConnectMeta,io as registerAccount,_o as registerAmadeus,TS as registerCloud,qs as registerConnect,Ys as registerPenzor,Zs as registerPenzorTransfers,Ao as registerUnit,Pr as safeDownloadName,_a as scanSdkUsage,br as shouldRefreshToken,Gs as speedOf,Mc as streamWorthy,yc as stripConflictSuffix,Hf as textFingerprint,Cs as tokenAgeMs,Fi as tokenRemainingMs,Js as uploadError,Ea as writeConnectMeta};
280
285
  /*! Bundled license information:
281
286
 
282
287
  chokidar/index.js: