@kitelev/exocortex-cli 16.149.3 → 16.149.5

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.
Files changed (2) hide show
  1. package/dist/index.js +3 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // @kitelev/exocortex-cli v16.149.3
2
+ // @kitelev/exocortex-cli v16.149.5
3
3
  // CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more
4
4
  // License: MIT
5
5
 
@@ -305,7 +305,7 @@ To resolve:
305
305
  path = ${e}
306
306
  url = ${t}
307
307
  `;return{content:n+i+s,added:!0}}a(fH,"appendGitmodulesEntry");function dH(n,e){let t=n.split(/\r?\n/),r=[],i=!1,s=new RegExp(`^\\[submodule\\s+"${JE(e)}"\\]\\s*$`);for(let l of t){if(i){if(/^\[.+\]\s*$/.test(l)){i=!1,r.push(l);continue}continue}if(s.test(l)){i=!0;continue}r.push(l)}let o=[],c=!1;for(let l of r){let u=l.trim().length===0;u&&c||(o.push(l),c=u)}return o.join(`
308
- `)}a(dH,"stripGitmodulesEntry")});var su=v(ZE=>{"use strict";Object.defineProperty(ZE,"__esModule",{value:!0});ZE.gitBlobSha=hH;async function hH(n,e){let t=new TextEncoder,r=typeof n=="string"?t.encode(n):n,i=t.encode(`blob ${r.byteLength}\0`),s=new Uint8Array(i.byteLength+r.byteLength);return s.set(i,0),s.set(r,i.byteLength),e(s)}a(hH,"gitBlobSha")});var py=v(hy=>{"use strict";Object.defineProperty(hy,"__esModule",{value:!0});hy.extractAssetUid=oP;hy.detectChanges=mH;var pH=su();function oP(n){let e=/^---\r?\n([\s\S]*?)\r?\n---(?=\r?\n|$)/.exec(n);if(!e)return;let t=/^exo__Asset_uid:[ \t]*["']?([^\s"']+)["']?[ \t]*$/m.exec(e[1]);return t?t[1]:void 0}a(oP,"extractAssetUid");async function mH(n){let{localFiles:e,cachedEntries:t,watermark:r,actualBaseTreeSha:i,sha1:s}=n;if(r===null)return{kind:"full-conflict",reason:"first-sync"};if(i===null)return{kind:"full-conflict",reason:"base-mismatch",detail:`watermark commit ${r.lastSyncedSha} not resolvable on remote`};if(i!==r.rootTreeSha)return{kind:"full-conflict",reason:"base-mismatch",detail:`stored root tree ${r.rootTreeSha} != actual ${i} at ${r.lastSyncedSha}`};let o=[],c=new Map;for(let[A,T]of e){let R=await(0,pH.gitBlobSha)(T,s);c.set(A,R),o.push({path:A,blobSha:R,uid:typeof T=="string"?oP(T):void 0})}if(t!==void 0)for(let[A,T]of t)c.set(A,T.blobSha),o.push({path:A,blobSha:T.blobSha,uid:T.uid});let l=[],u=[],f=[],d=[],h=new Map;for(let A of o){if(A.uid===void 0)continue;let T=h.get(A.uid)??[];T.push(A.path),h.set(A.uid,T)}let p=new Map;for(let A of r.files){if(A.uid===void 0)continue;let T=p.get(A.uid)??[];T.push(A.path),p.set(A.uid,T)}let y=new Set;for(let[A,T]of h)T.length>1&&y.add(A);for(let[A,T]of p)T.length>1&&y.add(A);for(let A of[...y].sort()){let T=h.get(A)??[],R=T.length>1?`on disk (${T.join(", ")})`:`in the sync base (${(p.get(A)??[]).join(", ")})`;d.push(`duplicate uid ${A} ${R} \u2014 uid identity suppressed for the group; every path matched by path identity (#3477)`)}let g=new Map,b=[];for(let A of r.files)A.uid!==void 0&&!y.has(A.uid)?g.set(A.uid,A):b.push(A);let w=[],S=new Set;for(let A of o){let T=A.uid!==void 0&&!y.has(A.uid)?g.get(A.uid):void 0;A.uid!==void 0&&T!==void 0?(S.add(A.uid),(T.blobSha!==A.blobSha||T.path!==A.path)&&u.push({path:A.path,uid:A.uid,blobSha:A.blobSha,...T.path!==A.path?{basePath:T.path}:{}})):w.push(A)}let x=new Map;for(let A of b)x.set(A.path,A);for(let[A,T]of g)S.has(A)||x.set(T.path,T);for(let A of w){let T=x.get(A.path);T!==void 0?(x.delete(A.path),T.blobSha!==A.blobSha&&u.push({path:A.path,uid:A.uid,blobSha:A.blobSha})):l.push({path:A.path,uid:A.uid,blobSha:A.blobSha})}for(let A of x.values())f.push({path:A.path,uid:A.uid,blobSha:A.blobSha});return{kind:"changes",added:l,modified:u,deleted:f,warnings:d,diskBlobShas:c,duplicateUids:y}}a(mH,"detectChanges")});var ad=v(Sc=>{"use strict";Object.defineProperty(Sc,"__esModule",{value:!0});Sc.getHeadSha=yH;Sc.getCommitInfo=bH;Sc.getTree=_H;Sc.getBlobText=wH;Sc.getBlobBytes=SH;var aP=nl(),gH="https://api.github.com";function od(n){return(n??gH).replace(/\/$/,"")}a(od,"api");function wc(n){return n!==null&&typeof n=="object"?n:void 0}a(wc,"asRecord");function Cs(n,e){let r=wc(n)?.[e];return typeof r=="string"?r:void 0}a(Cs,"readString");async function yH(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/refs/heads/${encodeURIComponent(r)}`}),o=Cs(wc(s?.json)?.object,"sha");if(typeof o!="string"||o.length===0)throw new Error(`ExoSync: missing object.sha for ref heads/${r}`);return o}a(yH,"getHeadSha");async function bH(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/commits/${encodeURIComponent(r)}`}),o=wc(s?.json),c=Cs(o,"sha"),l=Cs(o?.tree,"sha");if(!c||!l)throw new Error(`ExoSync: malformed commit response for ${r}`);let u=o?.parents,f=Array.isArray(u)?u.map(d=>Cs(d,"sha")).filter(d=>typeof d=="string"):[];return{sha:c,treeSha:l,parents:f}}a(bH,"getCommitInfo");async function _H(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/trees/${encodeURIComponent(r)}?recursive=1`}),o=wc(s?.json);if(o?.truncated===!0)throw new Error(`ExoSync: tree ${r} is truncated by GitHub (repo too large for recursive listing) \u2014 refusing to diff`);let c=o?.tree;if(!Array.isArray(c))throw new Error(`ExoSync: malformed tree response for ${r}`);let l=[];for(let u of c){let f=wc(u);if(f?.type!=="blob")continue;let d=Cs(f,"path"),h=Cs(f,"sha"),p=typeof f.size=="number"?f.size:void 0;d&&h&&l.push({path:d,blobSha:h,...p!==void 0?{size:p}:{}})}return l}a(_H,"getTree");async function wH(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/blobs/${encodeURIComponent(r)}`}),o=wc(s?.json),c=Cs(o,"content");if(typeof c!="string")throw new Error(`ExoSync: malformed blob response for ${r}`);return Cs(o,"encoding")==="utf-8"?c:(0,aP.base64ToUtf8)(c)}a(wH,"getBlobText");async function SH(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/blobs/${encodeURIComponent(r)}`}),o=wc(s?.json),c=Cs(o,"content");if(typeof c!="string")throw new Error(`ExoSync: malformed blob response for ${r}`);return Cs(o,"encoding")==="utf-8"?new TextEncoder().encode(c):(0,aP.base64ToBytes)(c)}a(SH,"getBlobBytes")});var rT=v(Yt=>{"use strict";Object.defineProperty(Yt,"__esModule",{value:!0});Yt.SyncPhaseTimer=Yt.SYNC_PHASES=void 0;Yt.classifyRestPhase=vH;Yt.emptyTimings=lP;Yt.totalMs=my;Yt.addTimings=uP;Yt.aggregateTimings=EH;Yt.dominantPhase=TH;Yt.fmtMs=cd;Yt.formatTimingsLine=AH;Yt.formatRepoTimings=xH;Yt.SYNC_PHASES=["localList","localRead","localWrite","hash","restHead","restCommit","restTree","restBlob","restPush"];function tT(){let n={};for(let e of Yt.SYNC_PHASES)n[e]=0;return n}a(tT,"zeroDurations");function cP(){return{filesRead:0,filesHashed:0,filesWritten:0,restCalls:0}}a(cP,"zeroCounts");function vH(n){if(n.method!=="GET")return"restPush";let e=n.url;return e.includes("/git/blobs/")?"restBlob":e.includes("/git/trees/")?"restTree":e.includes("/git/commits/")?"restCommit":e.includes("/git/refs/")?"restHead":"restCommit"}a(vH,"classifyRestPhase");var eT=class{static{a(this,"SyncPhaseTimer")}constructor(e){this.now=e,this.durations=tT(),this.counts=cP()}async time(e,t){let r=this.now();try{return await t()}finally{this.durations[e]+=this.now()-r}}bumpRead(){this.counts.filesRead++}bumpHashed(){this.counts.filesHashed++}bumpWritten(){this.counts.filesWritten++}bumpRest(){this.counts.restCalls++}snapshot(){return{durations:{...this.durations},counts:{...this.counts}}}};Yt.SyncPhaseTimer=eT;function lP(){return{durations:tT(),counts:cP()}}a(lP,"emptyTimings");function my(n){let e=0;for(let t of Yt.SYNC_PHASES)e+=n.durations[t];return e}a(my,"totalMs");function uP(n,e){let t=tT();for(let r of Yt.SYNC_PHASES)t[r]=n.durations[r]+e.durations[r];return{durations:t,counts:{filesRead:n.counts.filesRead+e.counts.filesRead,filesHashed:n.counts.filesHashed+e.counts.filesHashed,filesWritten:n.counts.filesWritten+e.counts.filesWritten,restCalls:n.counts.restCalls+e.counts.restCalls}}}a(uP,"addTimings");function EH(n){let e=lP();for(let t of n)t.timings!==void 0&&(e=uP(e,t.timings));return e}a(EH,"aggregateTimings");function TH(n){let e=my(n);if(e<=0)return null;let t=Yt.SYNC_PHASES[0],r=-1;for(let i of Yt.SYNC_PHASES)n.durations[i]>r&&(r=n.durations[i],t=i);return{phase:t,ms:r,pct:r/e*100}}a(TH,"dominantPhase");function cd(n){return n>=1e3?`${(n/1e3).toFixed(1)}s`:`${Math.round(n)}ms`}a(cd,"fmtMs");function AH(n){let e=my(n);if(e<=0)return"";let t=Yt.SYNC_PHASES.filter(r=>n.durations[r]>0).sort((r,i)=>n.durations[i]-n.durations[r]).map(r=>`${r} ${cd(n.durations[r])} ${Math.round(n.durations[r]/e*100)}%`);return`\u23F1 ExoSync ${cd(e)} \u2014 ${t.join(" \xB7 ")} (${n.counts.filesHashed} hashed, ${n.counts.filesRead} read, ${n.counts.restCalls} REST)`}a(AH,"formatTimingsLine");function xH(n,e){let t=Yt.SYNC_PHASES.map(r=>`${r}=${cd(e.durations[r])}`);return`[ExoSync timings] ${n}: total ${cd(my(e))} \u2014 ${t.join(" ")} | hashed ${e.counts.filesHashed} read ${e.counts.filesRead} written ${e.counts.filesWritten} REST ${e.counts.restCalls}`}a(xH,"formatRepoTimings")});var gy=v(da=>{"use strict";Object.defineProperty(da,"__esModule",{value:!0});da.LocalOutboxStore=da.OUTBOX_REMOTE_ABSENT=da.OUTBOX_STORE_FILENAME=void 0;da.OUTBOX_STORE_FILENAME="exosync-outbox.local.json";da.OUTBOX_REMOTE_ABSENT=" absent";function nT(n,e){return`${n}\0${e}`}a(nT,"outboxKey");function fP(n){if(n===null||typeof n!="object")return!1;let e=n;return typeof e.repoKey=="string"&&typeof e.path=="string"&&typeof e.chosenContent=="string"&&typeof e.baseRemoteSha=="string"}a(fP,"isEntry");var iT=class{static{a(this,"LocalOutboxStore")}constructor(e){this.writeChain=Promise.resolve(),this.io=e.io,this.now=e.now??(()=>new Date().toISOString())}async enqueue(e){await this.mutate(t=>{t.entries[nT(e.repoKey,e.path)]={version:1,...e,resolvedAt:e.resolvedAt.length>0?e.resolvedAt:this.now()}})}async remove(e,t){await this.mutate(r=>{delete r.entries[nT(e,t)]})}async list(){let e=await this.read();return Object.values(e.entries).filter(fP)}async listForRepo(e){return(await this.list()).filter(t=>t.repoKey===e)}async has(e,t){let i=(await this.read()).entries[nT(e,t)];return i!==void 0&&fP(i)}async mutate(e){let t=this.writeChain.then(async()=>{let r=await this.read();e(r),await this.io.writeAtomic(JSON.stringify(r,null,2))});return this.writeChain=t.catch(()=>{}),t}async read(){try{let e=await this.io.read();if(e===null)return{version:1,entries:{}};let t=JSON.parse(e);if(t===null||typeof t!="object")return{version:1,entries:{}};let r=t.entries;return r===null||typeof r!="object"?{version:1,entries:{}}:{version:1,entries:{...r}}}catch{return{version:1,entries:{}}}}};da.LocalOutboxStore=iT});var yy=v(sT=>{"use strict";Object.defineProperty(sT,"__esModule",{value:!0});sT.isAuthError=IH;function IH(n){let e=n instanceof Error?n.message:String(n);return/HTTP 401/.test(e)?!0:/HTTP 403/.test(e)&&!/rate limit/i.test(e)&&!/abuse detection/i.test(e)}a(IH,"isAuthError")});var oT=v(by=>{"use strict";Object.defineProperty(by,"__esModule",{value:!0});by.scanForSecrets=RH;by.redactSecrets=CH;var dP=[{kind:"github-token",re:/gh[pousr]_[A-Za-z0-9_]{36,}/},{kind:"github-fine-grained-token",re:/github_pat_[A-Za-z0-9_]{22,}_[A-Za-z0-9_]{59,}/},{kind:"private-key",re:/-----BEGIN [A-Z ]*PRIVATE KEY-----/}];function RH(n){let e=[];for(let[t,r]of n)for(let{kind:i,re:s}of dP)s.test(r)&&e.push({path:t,kind:i});return e}a(RH,"scanForSecrets");function CH(n){let e=n;for(let{kind:t,re:r}of dP)e=e.replace(new RegExp(r.source,"g"),`[REDACTED:${t}]`);return e}a(CH,"redactSecrets")});var wy=v(_y=>{"use strict";Object.defineProperty(_y,"__esModule",{value:!0});_y.isRateLimitError=hP;_y.withRateLimitBackoff=PH;function hP(n){let e=n instanceof Error?n.message:String(n);return/HTTP 429/.test(e)?!0:/HTTP 403/.test(e)&&(/rate limit/i.test(e)||/abuse detection/i.test(e))}a(hP,"isRateLimitError");var OH=a(n=>new Promise(e=>setTimeout(e,n)),"defaultSleep");function PH(n,e={}){let t=e.maxRetries??3,r=e.baseDelayMs??1e3,i=e.sleep??OH,s=e.random??Math.random;return async o=>{let c=0;for(;;)try{return await n(o)}catch(l){if(!hP(l)||c>=t)throw l;let u=r*2**c*(1+s());c++,await i(u)}}}a(PH,"withRateLimitBackoff")});var Sy=v(Ao=>{"use strict";Object.defineProperty(Ao,"__esModule",{value:!0});Ao.DEFAULT_MAX_FILE_BYTES=Ao.InMemoryQuarantineStore=void 0;Ao.contentEquals=FH;Ao.isSyncablePath=DH;Ao.isFileSpaceSyncablePath=LH;function FH(n,e){if(n===void 0||e===void 0||typeof n=="string"&&typeof e=="string")return n===e;if(typeof n=="string"||typeof e=="string"||n.byteLength!==e.byteLength)return!1;for(let t=0;t<n.byteLength;t++)if(n[t]!==e[t])return!1;return!0}a(FH,"contentEquals");var aT=class{static{a(this,"InMemoryQuarantineStore")}constructor(){this.entries=[]}async quarantine(e){this.entries.push(e)}};Ao.InMemoryQuarantineStore=aT;function DH(n){return n.endsWith(".md")&&!n.includes(".local.")&&!n.includes(".conflict.")}a(DH,"isSyncablePath");function LH(n){return!n.includes(".local.")&&!n.includes(".conflict.")}a(LH,"isFileSpaceSyncablePath");Ao.DEFAULT_MAX_FILE_BYTES=30*1024*1024});var wP=v(Zn=>{"use strict";Object.defineProperty(Zn,"__esModule",{value:!0});Zn.SyncEngine=Zn.DEFAULT_LOCAL_MANIFEST_REHASH_MS=Zn.DEFAULT_MAX_PUSH_RETRIES=void 0;Zn.isNonFastForwardError=_P;Zn.orderChildrenFirst=VH;var pP=fy(),mP=rT(),ot=ad(),xo=py(),NH=nl(),vc=su(),cT=gy(),kH=yy(),MH=oT(),jH=wy(),Os=Sy();Zn.DEFAULT_MAX_PUSH_RETRIES=3;Zn.DEFAULT_LOCAL_MANIFEST_REHASH_MS=720*60*1e3;function $H(n){try{return new TextDecoder("utf-8",{fatal:!0}).decode(n)}catch{return null}}a($H,"decodeUtf8Strict");function UH(n){return typeof n=="string"?n:{base64:(0,NH.bytesToBase64)(n)}}a(UH,"toCommitContent");async function gP(n,e){if(n.readBinary===void 0)throw new Error("LocalFilesPort.readBinary is required for file-mode sync (Phase C)");return n.readBinary(e)}a(gP,"readBinaryStrict");async function BH(n,e,t){if(n.writeBinary===void 0)throw new Error("LocalFilesPort.writeBinary is required for file-mode sync (Phase C)");return n.writeBinary(e,t)}a(BH,"writeBinaryStrict");function yP(n){return n.length===0||n.startsWith("/")||n.includes("\\")?!1:n.split("/").every(e=>e.length>0&&e!=="."&&e!=="..")}a(yP,"isSafeRepoRelativePath");function _P(n){let e=n instanceof Error?n.message:String(n);return/HTTP 422/.test(e)&&/git\/refs/.test(e)||/ref update mismatch/.test(e)||/HTTP 422/.test(e)&&/git\/trees/.test(e)&&/BadObjectState/.test(e)}a(_P,"isNonFastForwardError");function VH(n){let e=a(t=>t.split("/").filter(r=>r.length>0).length,"depth");return[...n].sort((t,r)=>e(r.localPath)-e(t.localPath))}a(VH,"orderChildrenFirst");function bP(n,e){let t=new Map(n.map(o=>[o.path,o])),r=new Set,i=[];for(let o of e){r.add(o.path);let c=t.get(o.path);(c===void 0||c.blobSha!==o.blobSha)&&i.push(o)}let s=n.filter(o=>!r.has(o.path));return{changed:i,deleted:s}}a(bP,"diffTrees");function ha(n){return n instanceof Error?n.message:String(n)}a(ha,"errMsg");function qH(n,e,t){if(t.size===0)return n;let r=new Map(e.files.map(o=>[o.path,o])),i=new Set(n.map(o=>o.path)),s=[];for(let o of n){if(!t.has(o.path)){s.push(o);continue}let c=r.get(o.path);c!==void 0&&s.push(c)}for(let o of t){if(i.has(o))continue;let c=r.get(o);c!==void 0&&s.push(c)}return s}a(qH,"applyWatermarkPins");var lT={mergedFiles:new Map,mergedWrites:[],quarantineEntries:[],resolvedQuarantineEntries:[],mergedCount:0,mergedPaths:[],warnings:[]};function uT(n){return new Map(n.map(e=>[e.path,e.blobSha]))}a(uT,"treeByPath");function vy(n){return[...n.quarantineEntries.map(e=>e.path),...n.resolvedQuarantineEntries.map(e=>e.path)]}a(vy,"quarantinedPathsOf");var fT=class{static{a(this,"SyncEngine")}constructor(e){this.activeTimer=null,this.opInProgress=!1,this.deps=e,this.now=e.now??(()=>Date.now()),this.transport=this.instrumentTransport((0,jH.withRateLimitBackoff)(e.transport,e.backoff)),this.sha1=this.instrumentSha1(e.sha1)}instrumentTransport(e){return async t=>{let r=this.activeTimer;return r===null?e(t):(r.bumpRest(),r.time((0,mP.classifyRestPhase)(t),()=>e(t)))}}instrumentSha1(e){return t=>{let r=this.activeTimer;return r===null?e(t):(r.bumpHashed(),r.time("hash",()=>e(t)))}}instrumentLocalFiles(e){let t=a((c,l)=>{let u=this.activeTimer;return u===null?l():u.time(c,l)},"timed"),r={list:a(()=>t("localList",()=>e.list()),"list"),read:a(c=>(this.activeTimer?.bumpRead(),t("localRead",()=>e.read(c))),"read"),write:a((c,l)=>t("localWrite",()=>(this.activeTimer?.bumpWritten(),e.write(c,l))),"write"),delete:a(c=>e.delete(c),"delete")},i=e.readBinary?.bind(e);i!==void 0&&(r.readBinary=c=>(this.activeTimer?.bumpRead(),t("localRead",()=>i(c))));let s=e.writeBinary?.bind(e);s!==void 0&&(r.writeBinary=(c,l)=>t("localWrite",()=>(this.activeTimer?.bumpWritten(),s(c,l))));let o=e.stat?.bind(e);return o!==void 0&&(r.stat=c=>t("localList",()=>o(c))),r}busyResult(e){return{repoKey:e.repoKey,status:"busy",pulledCount:0,pushedCount:0,mergedCount:0,quarantinedCount:0,warnings:[],deferredDeletes:[],detail:"another sync operation is in progress (D11 guard) \u2014 retry after it finishes"}}modeOps(e){let t=e.spaceKind==="file",r=t?Os.isFileSpaceSyncablePath:Os.isSyncablePath,i=this.deps.maxFileBytes??Os.DEFAULT_MAX_FILE_BYTES;return{fileMode:t,syncable:r,treeFilter:a(s=>r(s.path)&&(!t||s.size===void 0||s.size<=i),"treeFilter")}}async buildFileModeFirstSyncBase(e,t,r,i){let s=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),o=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,s,this.deps.baseURL),c=(await(0,ot.getTree)(this.transport,e.owner,e.repo,o.treeSha,this.deps.baseURL)).filter(r.treeFilter),l=[];for(let u of c){let f=t.get(u.path);f!==void 0&&await(0,vc.gitBlobSha)(f,this.sha1)===u.blobSha&&l.push({path:u.path,blobSha:u.blobSha})}return i.push(`first-sync (file mode): synthetic base from ${l.length} already-identical file(s) at head ${s} \u2014 divergence resolves through the remote-wins layer (D22)`),{lastSyncedSha:s,rootTreeSha:o.treeSha,files:l,spaceKind:"file"}}async syncAll(e,t="sync",r){if(this.opInProgress)return e.map(i=>this.busyResult(i));this.opInProgress=!0;try{let i=[];for(let s of e)i.push(await this.syncLocked(s,t,r));return i}finally{this.opInProgress=!1}}async sync(e,t="sync",r){if(this.opInProgress)return this.busyResult(e);this.opInProgress=!0;try{return await this.syncLocked(e,t,r)}finally{this.opInProgress=!1}}emitProgress(e,t,r){if(e!==void 0)try{e({repoKey:t,phase:r})}catch{}}async syncLocked(e,t="sync",r){let i=new mP.SyncPhaseTimer(this.now),s=this.activeTimer;this.activeTimer=i;let o=[],c=[],l=0,u=0,f=[],d=a((h,p={})=>({repoKey:e.repoKey,status:h,pulledCount:0,pushedCount:0,mergedCount:0,quarantinedCount:0,warnings:o,deferredDeletes:c,...l>0?{outboxPushedCount:l}:{},...u>0?{outboxReconflictedCount:u}:{},timings:i.snapshot(),...p}),"result");try{let h=await this.deps.materializationCheck.check(e);if(!h.fullyMaterialized)return o.push(`skipped: repo not fully materialized${h.reason?` (${h.reason})`:""} \u2014 deletes NOT inferred (D19)`),d("skipped-not-materialized");let p=this.modeOps(e),y=this.instrumentLocalFiles(this.deps.localFilesFor(e));if(p.fileMode&&(y.readBinary===void 0||y.writeBinary===void 0))return d("error",{detail:"file-mode repo requires a LocalFilesPort with readBinary/writeBinary \u2014 refusing to sync through the text-only port (binary would corrupt)"});if(p.fileMode&&this.deps.quarantine===void 0)return d("error",{detail:"file-mode repo requires a quarantine sink (D18 remote-wins preserves losing local bytes there) \u2014 configure the quarantine repo before syncing FileSpaces"});let g=this.deps.maxFileBytes??Os.DEFAULT_MAX_FILE_BYTES;if(t!=="pull"&&this.deps.outbox!==void 0){let G=await this.flushOutbox(e,o);l=G.pushed,u=G.reconflicted}let b=await this.deps.watermarkStore.get(e.repoKey);if(b?.spaceKind==="file"&&!p.fileMode)return d("error",{detail:"watermark was written by a FILE-mode sync but the spec now resolves to asset mode \u2014 refusing (fix the conflicting Space declarations, or clear the watermark to restart)"});b!==null&&p.fileMode&&b.spaceKind!=="file"&&(o.push("watermark was written by an ASSET-mode sync \u2014 rebuilding the base through the file-mode first-sync layer (kind flip)"),b=null);let w=this.deps.localManifestStore!==void 0?y.stat?.bind(y):void 0,S=w!==void 0&&b!==null&&!p.fileMode,x=S&&this.deps.localManifestStore!==void 0?await this.deps.localManifestStore.get(e.repoKey):null,A=this.deps.localManifestFullRehashMs??Zn.DEFAULT_LOCAL_MANIFEST_REHASH_MS,T=S&&(x===null||this.now()-x.lastFullRehashMs>=A),R=new Map,B=new Set,L=new Map,P=new Map,M=new Map,O=!1;for(let G of(await y.list()).filter(p.syncable)){if(p.fileMode){let se=await gP(y,G);if(se.byteLength>g){B.add(G),o.push(`skipped oversized file ${G} (${se.byteLength} bytes > ${g} cap) \u2014 excluded from sync symmetrically (Phase C size cap)`);continue}R.set(G,se);continue}if(!S||w===void 0){R.set(G,await y.read(G));continue}let ie=await w(G),J=!T&&ie!==null?x?.files[G]:void 0;if(ie!==null&&J!==void 0&&J.mtimeMs===ie.mtimeMs&&J.size===ie.size){L.set(G,{blobSha:J.blobSha,...J.uid!==void 0?{uid:J.uid}:{}}),P.set(G,J.blobSha),M.set(G,ie);continue}O=!0,R.set(G,await y.read(G)),ie!==null&&M.set(G,ie)}let Q=!1;if(b===null)if(p.fileMode)Q=!0,b=await this.buildFileModeFirstSyncBase(e,R,p,o);else{let G=await this.bootstrapWatermark(e,R,o,d);if(G.kind==="settled")return G.outcome;Q=!0,b=G.base}let oe=b;p.fileMode&&B.size>0&&(b={...b,files:b.files.filter(G=>!B.has(G.path))});let Y,be;S&&!T?(Y=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),be=Y===b.lastSyncedSha?b.rootTreeSha:await this.resolveBaseTreeSha(e,b)):be=await this.resolveBaseTreeSha(e,b),this.emitProgress(r,e.repoKey,"detecting");let le=await(0,xo.detectChanges)({localFiles:R,...S?{cachedEntries:L}:{},watermark:b,actualBaseTreeSha:be,sha1:this.sha1});if(le.kind==="full-conflict")return d("full-conflict",{detail:`${le.reason}${le.detail?`: ${le.detail}`:""} \u2014 divergence must go through merge/quarantine (A2/A3), not overwrite`});if(o.push(...le.warnings),S&&this.deps.localManifestStore!==void 0){let G={};for(let[ie,J]of R){let se=M.get(ie),_e=le.diskBlobShas.get(ie);if(se===void 0||_e===void 0)continue;let Ee=typeof J=="string"?(0,xo.extractAssetUid)(J):void 0;G[ie]={mtimeMs:se.mtimeMs,size:se.size,blobSha:_e,...Ee!==void 0?{uid:Ee}:{}}}for(let[ie,J]of L){let se=M.get(ie);se!==void 0&&(G[ie]={mtimeMs:se.mtimeMs,size:se.size,blobSha:J.blobSha,...J.uid!==void 0?{uid:J.uid}:{}})}if(x!==null&&Object.keys(x.files).some(ie=>!(ie in G))&&(O=!0),O||T||x===null){let ie={version:1,files:G,lastFullRehashMs:T||x===null?this.now():x.lastFullRehashMs};await this.deps.localManifestStore.set(e.repoKey,ie)}}let ue=this.pinLocalChanges(le,R,o,c,t);f=[...ue.pushDeletionsAll.keys()];let k=await this.runPushLoop(e,b,ue,R,o,p,Q,B,t,r,Y);if(f=[],k.kind!=="done"&&ue.pushDeletionsAll.size>0&&c.push(...ue.pushDeletionsAll.keys()),k.kind==="conflict")return d("conflict",{detail:k.detail});if(k.kind==="secret-detected")return d("error",{detail:k.detail});if(k.kind==="retry-exhausted"){o.push(...k.merge.warnings);let G=await this.buildTerminalQuarantineEntries(e,b,k.pushFiles,k.merge.quarantineEntries,R),ie=[...k.merge.quarantineEntries,...k.merge.resolvedQuarantineEntries,...G];return await this.flushQuarantine(ie,o),d("retry-exhausted",{detail:k.detail,quarantinedCount:ie.length,...ie.length>0?{quarantinedPaths:ie.map(J=>J.path)}:{}})}let{examinedHead:W,pushedSha:je,applyWrites:X,applyDeletes:q,pushFiles:ee}=k,Z=k.merge;o.push(...Z.warnings),o.push(...k.deferredWarnings),c.push(...k.withheldDeletions);let ge=k.deferredPaths.size>0?{deferredPaths:[...k.deferredPaths]}:{},$e=k.pushedDeletions.length>0?{pushedDeletes:k.pushedDeletions}:{},Ve=await this.flushQuarantine([...Z.quarantineEntries,...Z.resolvedQuarantineEntries],o),j=new Set;if(!Ve&&Z.resolvedQuarantineEntries.length>0){for(let G of Z.resolvedQuarantineEntries)j.add(G.path);o.push(`quarantine flush failed \u2014 remote-wins apply withheld for ${j.size} path(s); local files untouched, conflict re-derives next sync (D18 durability gate)`)}if(je===void 0&&W===b.lastSyncedSha&&X.length===0&&q.length===0&&Z.mergedWrites.length===0&&Z.quarantineEntries.length===0&&Z.resolvedQuarantineEntries.length===0&&(b.pinnedPaths?.length??0)===0&&k.alreadyInHead.length===0&&k.deferredPaths.size===0&&!Q)return d("synced");let te=je??W,pe=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,te,this.deps.baseURL);if(je!==void 0&&pe.parents[0]!==W)return await this.checkRaceWindow(e,b,W,pe.parents[0],ee,new Set(k.pushedDeletions),o,p),o.push(`race-window: watermark NOT advanced (pushed commit's parent ${pe.parents[0]} != examined head ${W}) \u2014 next sync reconciles the concurrent change`),d("synced",{pushedSha:je,pushedCount:ee.size,mergedCount:Z.mergedCount,quarantinedCount:Z.quarantineEntries.length+Z.resolvedQuarantineEntries.length,...Z.mergedPaths.length>0?{mergedPaths:Z.mergedPaths}:{},...vy(Z).length>0?{quarantinedPaths:vy(Z)}:{},...ge,...$e});let{pulledCount:Ae,pinnedPaths:ye}=await this.applyRemoteChanges(y,R,[...X,...Z.mergedWrites].filter(G=>!j.has(G.path)),q.filter(G=>!j.has(G.path)),o,P);for(let G of Z.quarantineEntries)ye.add(G.path);for(let G of k.deferredPaths)ye.add(G);for(let G of j)ye.add(G);if(p.fileMode){for(let G of B)ye.add(G);for(let G of k.remoteOversized)ye.add(G)}return await this.advanceWatermark(e,te,pe.treeSha,R,[...X,...Z.mergedWrites,...k.deferredRemoteChanges],oe,ye,le.diskBlobShas,p,B),await this.resolveClearedPins(e,oe,ye,o,new Set(Z.resolvedQuarantineEntries.map(G=>G.path))),d("synced",{pushedSha:je,pulledCount:Ae,pushedCount:ee.size,mergedCount:Z.mergedCount,quarantinedCount:Z.quarantineEntries.length+Z.resolvedQuarantineEntries.length,...Z.mergedPaths.length>0?{mergedPaths:Z.mergedPaths}:{},...vy(Z).length>0?{quarantinedPaths:vy(Z)}:{},...ge,...$e})}catch(h){let p=this.deps.redact??(y=>y);return f.length>0&&c.push(...f),(0,kH.isAuthError)(h)?d("auth-required",{detail:p(`authentication failed: ${ha(h)} \u2014 the PAT is expired, revoked or under-scoped; update it in the per-device secure storage (R8). Never treated as success.`)}):(o.push(`sync failed: ${p(ha(h))}`),d("error",{detail:p(ha(h))}))}finally{this.activeTimer=s}}async flushQuarantine(e,t){if(e.length===0)return!0;let r=this.deps.redact??(s=>s);for(let s of e)t.push(r(`quarantined ${s.path}: ${s.reason}`));let i=this.deps.quarantine;if(i===void 0)return!1;try{if(i.quarantineAll!==void 0)await i.quarantineAll(e);else for(let s of e)await i.quarantine(s);return!0}catch(s){let o=this.deps.redact??(c=>c);return t.push(`quarantine sink failed: ${o(ha(s))} \u2014 files untouched on disk; the conflict re-derives next sync (D17 degradation)`),!1}}async flushOutbox(e,t){let r=this.deps.outbox;if(r===void 0)return{pushed:0,reconflicted:0};let i=await r.listForRepo(e.repoKey);if(i.length===0)return{pushed:0,reconflicted:0};let s=this.deps.redact??(f=>f),o,c;try{({head:o,shaByPath:c}=await this.outboxHeadTreeShas(e))}catch(f){return t.push(`outbox flush deferred (${i.length} resolution(s) awaiting push): ${s(ha(f))}`),{pushed:0,reconflicted:0}}let l=0,u=0;for(let f of i){let d=c.get(f.path)??cT.OUTBOX_REMOTE_ABSENT,h=d===cT.OUTBOX_REMOTE_ABSENT&&f.baseRemoteSha!==cT.OUTBOX_REMOTE_ABSENT?[...c].filter(([p,y])=>p!==f.path&&y===f.baseRemoteSha).map(([p])=>p):[];if(d!==f.baseRemoteSha&&h.length===0){await r.remove(f.repoKey,f.path),u++,t.push(s(`outbox: remote moved for ${f.path} since you resolved it \u2014 NOT pushed; resolve again (your choice is preserved on disk)`));continue}try{await(0,pP.restCreateCommit)(this.transport,{owner:e.owner,repo:e.repo,branch:e.branch,files:new Map([[f.path,f.chosenContent]]),...h.length>0?{deletions:h}:{},message:h.length>0?`chore(exosync): resolve cross-path conflict for ${f.path} (consolidate ${h.length} stale remote path(s))`:`chore(exosync): push resolved conflict for ${f.path}`,expectedHeadSha:o,...this.deps.baseURL!==void 0?{baseURL:this.deps.baseURL}:{},...this.deps.redact!==void 0?{redact:this.deps.redact}:{}})}catch(p){t.push(`outbox: push deferred for ${f.path}, will retry next sync: ${s(ha(p))}`);continue}await this.snapOutboxWatermark(e,f.path,f.chosenContent,h),await this.deps.quarantine?.markResolved?.(f.repoKey,f.path);for(let p of h)await this.deps.quarantine?.markResolved?.(f.repoKey,p);await r.remove(f.repoKey,f.path),l++,h.length>0&&t.push(`consolidated cross-path conflict for ${f.path} \u2014 removed ${h.length} stale remote copy/copies (recoverable in git history)`)}return l>0&&t.push(`pushed ${l} resolved conflict(s)`),{pushed:l,reconflicted:u}}async outboxHeadTreeShas(e){let t=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),r=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,t,this.deps.baseURL),i=await(0,ot.getTree)(this.transport,e.owner,e.repo,r.treeSha,this.deps.baseURL),s=new Map;for(let o of i)s.set(o.path,o.blobSha);return{head:t,shaByPath:s}}async snapOutboxWatermark(e,t,r,i=[]){let s=await this.deps.watermarkStore.get(e.repoKey);if(s===null)return;let o=new Set([t,...i]),c=(s.pinnedPaths??[]).filter(g=>!o.has(g)),l=await(0,vc.gitBlobSha)(r,this.sha1),u=(0,xo.extractAssetUid)(r),f={path:t,blobSha:l,...u!==void 0?{uid:u}:{}},d=new Set(i),h=s.files.filter(g=>!d.has(g.path)),p=h.findIndex(g=>g.path===t),y=p>=0?h.map((g,b)=>b===p?f:g):[...h,f];await this.deps.watermarkStore.set(e.repoKey,{...s,files:y,...c.length>0?{pinnedPaths:c}:{pinnedPaths:void 0}})}async buildTerminalQuarantineEntries(e,t,r,i,s){let o=new Set(i.map(u=>u.path)),c=new Map;try{let u=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),f=(await(0,ot.getTree)(this.transport,e.owner,e.repo,(await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,u,this.deps.baseURL)).treeSha,this.deps.baseURL)).filter(d=>r.has(d.path));for(let d of f)c.set(d.path,await(0,ot.getBlobText)(this.transport,e.owner,e.repo,d.blobSha,this.deps.baseURL))}catch{}let l=[];for(let[u,f]of r){if(o.has(u))continue;let d=s.get(u),h=d??f,p=d!==void 0&&!(0,Os.contentEquals)(d,f),y=typeof h=="string"?(0,xo.extractAssetUid)(h):void 0,g=c.get(u);l.push({repoKey:e.repoKey,path:u,...y!==void 0?{uid:y}:{},reason:`non-fast-forward push failed after ${this.deps.maxPushRetries??Zn.DEFAULT_MAX_PUSH_RETRIES} retries (D16) \u2014 a concurrent writer keeps moving ${e.branch}; base recoverable from git history at ${t.lastSyncedSha}${p?"; the contended push payload was a merged proposal (never applied to disk) \u2014 the merge re-derives next sync":""}`,...typeof h=="string"?{localContent:h}:{localContentBytes:h},...g!==void 0?{remoteContent:g}:{}})}return l}async resolveClearedPins(e,t,r,i,s=new Set){let o=this.deps.quarantine;if(o===void 0||o.markResolved===void 0)return;let c=(t.pinnedPaths??[]).filter(l=>!r.has(l)&&!s.has(l));for(let l of c)try{await o.markResolved?.(e.repoKey,l)}catch(u){let f=this.deps.redact??(d=>d);i.push(`quarantine markResolved failed for ${l}: ${f(ha(u))} \u2014 unresolved-count may overcount until the resolver UI reconciles (CQ4)`)}}async resolveBaseTreeSha(e,t){try{return(await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,t.lastSyncedSha,this.deps.baseURL)).treeSha}catch{return null}}pinLocalChanges(e,t,r,i,s){let o=e.modified.filter(h=>h.basePath!==void 0),c=[...e.added,...e.modified.filter(h=>h.basePath===void 0)],l=new Map;if(s==="pull"){for(let h of o)h.basePath!==void 0&&i.push(h.basePath),r.push(`pull-only: rename (uid ${h.uid??"?"}) ${h.basePath} \u2192 ${h.path} not pushed \u2014 propagates on the next push/Sync (#3473)`);for(let h of e.deleted)i.push(h.path),r.push(`pull-only: delete of ${h.path} not pushed \u2014 propagates on the next push/Sync (#3473)`)}else{for(let h of o)h.basePath!==void 0&&l.set(h.basePath,h.path);for(let h of e.deleted)l.set(h.path,h.path)}let u=[...c,...o,...e.deleted.map(h=>({...h}))],f=new Set(e.deleted.map(h=>h.path)),d=new Map;for(let h of[...c,...s==="pull"?[]:o]){let p=t.get(h.path);p!==void 0&&d.set(h.path,p)}return{localChanges:u,localDeletedPaths:f,pushFilesAll:d,pushDeletionsAll:l,dupUids:e.duplicateUids}}async runPushLoop(e,t,r,i,s,o,c=!1,l=new Set,u="sync",f,d){let{localChanges:h,localDeletedPaths:p,pushFilesAll:y,pushDeletionsAll:g,dupUids:b}=r,w=this.deps.maxPushRetries??Zn.DEFAULT_MAX_PUSH_RETRIES,S=0,x="",A,T=[],R=[],B=new Map,L=new Set,P=[],M=lT,O=[],Q=new Set,oe=[],Y=[],be=new Set;for(;;){x=S===0&&d!==void 0&&y.size===0&&g.size===0?d:await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),T=[],R=[],M=lT,O=[],Q=new Set,oe=[],Y=[];let le,ue=new Set,k=(t.pinnedPaths?.length??0)>0;if(x!==t.lastSyncedSha||k||c){this.emitProgress(f,e.repoKey,"pulling-remote");let X=await this.collectRemoteChanges(e,t,x,o,l,s,be);le=X.headTreeByPath;let q=this.matchLocalVsRemote(h,p,i,X.changes,ue,b,X.headTreeByPath);if(q.conflicts.length>0){if(u==="sync"&&this.emitProgress(f,e.repoKey,"merging"),u!=="sync"){for(let ee of q.conflicts){Q.add(ee.local.path),ee.local.basePath!==void 0&&Q.add(ee.local.basePath);for(let Z of ee.remotes)Q.add(Z.path),Z.kind==="change"&&oe.push(Z)}Y.push(`${u}-only: ${q.conflicts.length} conflict(s) deferred to a full Sync (${q.conflicts.map(ee=>ee.desc).join("; ")}) \u2014 paths pinned, nothing merged`)}else if(o.fileMode)M=this.resolveFileModeConflicts(e,q.conflicts,i,q.applyWrites,q.applyDeletes);else{if(this.deps.mergeLayer===void 0)return{kind:"conflict",detail:`overlapping change on ${q.conflicts[0].desc} \u2014 merge layer (A2/A3) required; nothing pushed, nothing written`};M=await this.resolveMergeConflicts(e,t,q.conflicts,i)}if(u==="sync")for(let ee of q.conflicts)for(let Z of ee.remotes)Z.path!==ee.local.path&&(Q.add(Z.path),Z.kind==="change"&&oe.push(Z),Y.push(`conflict group ${ee.desc}: remote change at ${Z.path} NOT applied \u2014 pinned to re-derive on the next sync (#3477)`))}if(T=q.applyWrites,R=q.applyDeletes,u==="push"&&(T.length>0||R.length>0)){for(let ee of T)Q.add(ee.path),oe.push(ee);for(let ee of R)Q.add(ee.path);Y.push(`push-only: ${T.length+R.length} remote change(s) NOT applied \u2014 pinned to re-derive on the next pull/Sync`),T=[],R=[]}}B=u==="pull"?new Map:new Map([...[...y].filter(([X])=>!ue.has(X)),...M.mergedFiles]),L=new Set,P=[];for(let[X,q]of g){if(ue.has(q)){P.push(X);continue}B.has(X)||L.add(X)}if((B.size>0||L.size>0)&&le===void 0&&(le=uT(await(0,ot.getTree)(this.transport,e.owner,e.repo,t.rootTreeSha,this.deps.baseURL))),B.size>0&&le!==void 0){for(let[X,q]of B){let ee=le.get(X);ee!==void 0&&ee===await(0,vc.gitBlobSha)(q,this.sha1)&&(B.delete(X),O.push(X))}O.length>0&&s.push(`phantom push skipped: ${O.length} file(s) already identical in remote HEAD (${O.join(", ")}) \u2014 excluded from the commit (#3475)`)}if(L.size>0&&le!==void 0){for(let X of[...L])le.has(X)||L.delete(X);B.size===0&&L.size>=le.size&&(P.push(...L),Y.push(`deletion of ALL ${L.size} remaining file(s) deferred \u2014 GitHub cannot create an empty tree; the deletes re-derive and propagate once the repo has at least one surviving file`),L.clear())}if(B.size===0&&L.size===0)break;let W=new Map;for(let[X,q]of B)if(typeof q=="string")W.set(X,q);else{let ee=$H(q);ee!==null&&W.set(X,ee)}let je=(0,MH.scanForSecrets)(W);if(je.length>0)return{kind:"secret-detected",detail:`secret-scan: refusing to push \u2014 ${je.map(X=>`${X.path} (${X.kind})`).join(", ")} (R5); remove the secret and re-sync`};try{A=await(0,pP.restCreateCommit)(this.transport,{owner:e.owner,repo:e.repo,branch:e.branch,files:new Map([...B].map(([X,q])=>[X,UH(q)])),deletions:[...L],message:this.deps.commitMessage?.(e,B.size,L.size)??`chore(exosync): sync ${B.size} file(s)${L.size>0?`, ${L.size} deletion(s)`:""}`,baseURL:this.deps.baseURL,redact:this.deps.redact});break}catch(X){if(!_P(X))throw X;if(S++,S>w)return{kind:"retry-exhausted",detail:`non-fast-forward push failed after ${w} retries (D16 cap) \u2014 contended files routed to quarantine (D17)`,pushFiles:B,merge:M};s.push(`non-fast-forward push (attempt ${S}/${w}) \u2014 re-pulling and retrying (D16)`)}}return{kind:"done",examinedHead:x,pushedSha:A,applyWrites:T,applyDeletes:R,pushFiles:B,pushedDeletions:A!==void 0?[...L]:[],withheldDeletions:P,merge:M,remoteOversized:be,alreadyInHead:O,deferredPaths:Q,deferredRemoteChanges:oe,deferredWarnings:Y}}async resolveMergeConflicts(e,t,r,i){let s=this.deps.mergeLayer;if(s===void 0)return lT;let o=new Map(t.files.map(g=>[g.path,g])),c=new Map,l=[],u=[],f=[],d=[],h=0,p=a(g=>typeof g=="string"?g:void 0,"asText"),y=a((g,b,w)=>{let S=p(i.get(g.local.path)),x=p(g.remotes[0]?.content);return{repoKey:e.repoKey,path:g.local.path,...g.local.uid!==void 0?{uid:g.local.uid}:{},reason:b,...w!==void 0?{baseContent:w}:{},...S!==void 0?{localContent:S}:{},...x!==void 0?{remoteContent:x}:{}}},"entry");for(let g of r){let b=o.get(g.local.basePath??g.local.path)??o.get(g.remotes[0]?.path??""),w;if(b!==void 0&&(w=await(0,ot.getBlobText)(this.transport,e.owner,e.repo,b.blobSha,this.deps.baseURL)),g.remotes.length>1){u.push(y(g,`ambiguous conflict: local change overlaps ${g.remotes.length} remote changes (${g.remotes.map(R=>R.path).join(", ")})`,w));continue}let S=g.remotes[0],x=p(i.get(g.local.path)),A=await s.resolve({path:g.local.path,...g.local.uid!==void 0?{uid:g.local.uid}:{},...w!==void 0?{base:w}:{},...x!==void 0?{local:x}:{},...S.kind==="change"&&typeof S.content=="string"?{remote:S.content}:{}});if(A.action==="quarantine"){u.push(y(g,A.reason,w));continue}h++,d.push(g.local.path);for(let R of A.warnings??[])f.push(`merge(${g.local.path}): ${R}`);let T=S.kind==="change"?S.content:void 0;if(A.content!==T&&c.set(g.local.path,A.content),A.content!==i.get(g.local.path)){let R=(0,xo.extractAssetUid)(A.content)??g.local.uid;l.push({path:g.local.path,kind:"change",content:A.content,blobSha:await(0,vc.gitBlobSha)(A.content,this.sha1),...R!==void 0?{uid:R}:{}})}}return{mergedFiles:c,mergedWrites:l,quarantineEntries:u,resolvedQuarantineEntries:[],mergedCount:h,mergedPaths:d,warnings:f}}resolveFileModeConflicts(e,t,r,i,s){let o=[],c=[];for(let l of t){l.remotes.length>1&&c.push(`file-mode conflict on ${l.local.path} unexpectedly overlaps ${l.remotes.length} remote changes \u2014 resolving against the first`);let u=l.remotes[0],f=r.get(l.local.path);u.kind==="change"?i.push(u):s.push(u),!(l.localIsDelete||f===void 0)&&o.push({repoKey:e.repoKey,path:l.local.path,reason:`file-mode remote-wins (D18): remote ${u.kind==="change"?`version ${u.blobSha}`:"delete"} wins; this is the losing LOCAL version, preserved byte-exact`,...typeof f=="string"?{localContent:f}:{localContentBytes:f}})}return{mergedFiles:new Map,mergedWrites:[],quarantineEntries:[],resolvedQuarantineEntries:o,mergedCount:0,mergedPaths:[],warnings:c}}async applyRemoteChanges(e,t,r,i,s,o=new Map){let c=0,l=new Set,u=a(async(h,p)=>{try{return p?await gP(e,h):await e.read(h)}catch{return}},"tryRead"),f=a(async(h,p)=>{typeof p=="string"?await e.write(h,p):await BH(e,h,p)},"writeContent"),d=a(async h=>{let p=await u(h,!1);return p===void 0?!0:await(0,vc.gitBlobSha)(p,this.sha1)===o.get(h)},"cacheHitUnchanged");for(let h of r){if(h.content===void 0)continue;if(!yP(h.path)){s.push(`unsafe remote path skipped on pull-apply: ${h.path}`),l.add(h.path);continue}let p=t.get(h.path);if(p===void 0&&o.has(h.path)){if(!await d(h.path)){s.push(`pull-apply skipped: ${h.path} changed on disk mid-sync (TOCTOU) \u2014 remote change re-derives next sync`),l.add(h.path);continue}await f(h.path,h.content),c++;continue}let y=await u(h.path,typeof(p??h.content)!="string");if(!(0,Os.contentEquals)(y,p)){s.push(`pull-apply skipped: ${h.path} changed on disk mid-sync (TOCTOU) \u2014 remote change re-derives next sync`),l.add(h.path);continue}await f(h.path,h.content),c++}for(let h of i){if(!yP(h.path)){s.push(`unsafe remote path skipped on pull-delete: ${h.path}`),l.add(h.path);continue}let p=t.get(h.path);if(p===void 0&&o.has(h.path)){if(!await d(h.path)){s.push(`pull-delete skipped: ${h.path} changed on disk mid-sync (TOCTOU) \u2014 delete-vs-modify re-derives next sync`),l.add(h.path);continue}await e.delete(h.path),c++;continue}if(p!==void 0){let y=await u(h.path,typeof p!="string");if(y!==void 0&&!(0,Os.contentEquals)(y,p)){s.push(`pull-delete skipped: ${h.path} changed on disk mid-sync (TOCTOU) \u2014 delete-vs-modify re-derives next sync`),l.add(h.path);continue}await e.delete(h.path),c++}}return{pulledCount:c,pinnedPaths:l}}async advanceWatermark(e,t,r,i,s,o,c,l,u,f=new Set){let d=(await(0,ot.getTree)(this.transport,e.owner,e.repo,r,this.deps.baseURL)).filter(p=>u.treeFilter(p)&&!f.has(p.path)),h=qH(await this.buildWatermarkFiles(e,d,i,s,o,l,u),o,c);await this.deps.watermarkStore.set(e.repoKey,{lastSyncedSha:t,rootTreeSha:r,files:h,...c.size>0?{pinnedPaths:[...c]}:{},...u.fileMode?{spaceKind:"file"}:{}})}async tryMountBaseBootstrap(e,t,r,i,s){let o=this.deps.mountBaseStore,c=null;if(o!==void 0)try{c=await o.get(e.repoKey)}catch{return null}let l=!1;if(c===null&&this.deps.localBaseShaProvider!==void 0)try{let b=await this.deps.localBaseShaProvider(e);typeof b=="string"&&b.length>0&&(c=b,l=!0)}catch{}if(c===null||t.startsWith(c))return null;let u=300,f=null;try{let b=t;for(let w=0;w<u;w++){let S=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,b,this.deps.baseURL);if(S.sha===c||S.sha.startsWith(c)){f=S;break}if(S.parents.length===0)break;b=S.parents[0]}}catch{return null}if(f===null)return null;let d;try{d=(await(0,ot.getTree)(this.transport,e.owner,e.repo,f.treeSha,this.deps.baseURL)).filter(b=>(0,Os.isSyncablePath)(b.path))}catch{return null}let h;try{let b=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,t,this.deps.baseURL);h=uT((await(0,ot.getTree)(this.transport,e.owner,e.repo,b.treeSha,this.deps.baseURL)).filter(w=>(0,Os.isSyncablePath)(w.path)))}catch{return null}let p=d.filter(b=>!r.has(b.path)&&h.get(b.path)===b.blobSha);if(p.length>0){let b=p.slice(0,3).map(w=>w.path).join(", ")+(p.length>3?", \u2026":"");return i.push(`first-sync (asset mode): base-tree\u2286working-tree sanity guard fired \u2014 ${p.length} base file(s) absent from the working tree but UNCHANGED on remote head (${b}); the verified-ancestor base may not match the working tree's derivation commit (out-of-band submodule manipulation) \u2192 routing to merge/quarantine instead of inferring a silent deletion (#3610)`),{kind:"settled",outcome:s("full-conflict",{detail:`first-sync: base-tree\u2286working-tree sanity guard \u2014 ${p.length} base file(s) absent from the working tree are unchanged on remote head (${b}); refusing to infer a silent deletion from a base that may not match the derivation commit \u2014 divergence must go through merge/quarantine (A2/A3), never a silent delete (#3610)`})}}let y=d.map(b=>({path:b.path,blobSha:b.blobSha})),g={lastSyncedSha:f.sha,rootTreeSha:f.treeSha,files:y};if(l&&o!==void 0)try{await o.set(e.repoKey,f.sha)}catch{}return i.push(l?`first-sync (asset mode): BACKFILLED the 3-way base from the locally checked-out commit ${f.sha} (no recorded mount base) \u2014 remote head ${t} advanced since; local edits 3-way merge against it instead of false-conflicting (#3590)`:`first-sync (asset mode): reconciling against the recorded mount base ${f.sha} \u2014 remote head ${t} advanced since mount; local edits 3-way merge against it instead of false-conflicting (#3590)`),{kind:"additive-base",base:g}}async bootstrapWatermark(e,t,r,i){let s=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),o=await this.tryMountBaseBootstrap(e,s,t,r,i);if(o!==null)return o;let c=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,s,this.deps.baseURL),l=(await(0,ot.getTree)(this.transport,e.owner,e.repo,c.treeSha,this.deps.baseURL)).filter(h=>(0,Os.isSyncablePath)(h.path)),u=[],f;for(let h of l){let p=t.get(h.path);if(p===void 0||await(0,vc.gitBlobSha)(p,this.sha1)!==h.blobSha){f===void 0&&(f=h.path);continue}let y=typeof p=="string"?(0,xo.extractAssetUid)(p):void 0;u.push({path:h.path,blobSha:h.blobSha,...y?{uid:y}:{}})}let d={lastSyncedSha:s,rootTreeSha:c.treeSha,files:u};return f!==void 0?this.deps.mergeLayer===void 0?{kind:"settled",outcome:i("full-conflict",{detail:`first-sync: no watermark and local content diverges from remote head at ${f} \u2014 A2/A3 scope`})}:(r.push(`first-sync (asset mode): no 3-way merge base and local diverges from remote head (first at ${f}) \u2014 reconciling ZERO-LOSS against ${u.length} byte-identical file(s) as a synthetic base: remote-only files pull, local-only files push, overlapping divergences route to the merge/quarantine layer (both versions preserved), never a silent overwrite or delete`),{kind:"additive-base",base:d}):t.size===l.length?(await this.deps.watermarkStore.set(e.repoKey,d),r.push(`watermark bootstrapped from head ${s} (local tree identical to remote)`),{kind:"settled",outcome:i("synced")}):(r.push(`first-sync (asset mode): local tree (${t.size} files) is a pure superset of remote head ${s} (${l.length} files) \u2014 ${t.size-l.length} local-only addition(s) derive as pushable adds (#3565)`),{kind:"additive-base",base:d})}async collectRemoteChanges(e,t,r,i,s=new Set,o=[],c=new Set){let l=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,r,this.deps.baseURL),u=await(0,ot.getTree)(this.transport,e.owner,e.repo,l.treeSha,this.deps.baseURL);if(i.fileMode)for(let g of u)i.syncable(g.path)&&!i.treeFilter(g)&&!c.has(g.path)&&(c.add(g.path),o.push(`skipped oversized REMOTE file ${g.path} (${g.size??"?"} bytes over cap) \u2014 excluded from sync symmetrically (Phase C size cap)`));let f=u.filter(g=>i.treeFilter(g)&&!s.has(g.path)),d=t.files.filter(g=>!c.has(g.path)&&!s.has(g.path)),{changed:h,deleted:p}=bP(d,f),y=[];for(let g of h){if(i.fileMode){let w=await(0,ot.getBlobBytes)(this.transport,e.owner,e.repo,g.blobSha,this.deps.baseURL);y.push({path:g.path,kind:"change",blobSha:g.blobSha,content:w});continue}let b=await(0,ot.getBlobText)(this.transport,e.owner,e.repo,g.blobSha,this.deps.baseURL);y.push({path:g.path,kind:"change",blobSha:g.blobSha,content:b,uid:(0,xo.extractAssetUid)(b)})}for(let g of p)y.push({path:g.path,kind:"delete",uid:g.uid});return{changes:y,headTreeByPath:uT(u)}}matchLocalVsRemote(e,t,r,i,s,o=new Set,c){let l=new Set,u=[],f=new Map;for(let g of i)g.kind==="change"&&g.uid!==void 0&&f.set(g.uid,(f.get(g.uid)??0)+1);let d=new Set(o);for(let[g,b]of f)b>1&&d.add(g);let h=new Map,p=new Map;for(let g of i){if(g.uid!==void 0&&!d.has(g.uid)){let b=h.get(g.uid)??[];b.push(g),h.set(g.uid,b)}p.set(g.path,g)}for(let g of e){let b=new Set;if(g.uid!==void 0&&!d.has(g.uid))for(let A of h.get(g.uid)??[])A.kind==="change"&&A.path!==g.path&&(c?.has(g.path)===!0||g.basePath!==void 0&&c?.has(g.basePath)===!0)||b.add(A);let w=p.get(g.path);if(w!==void 0&&b.add(w),g.basePath!==void 0){let A=p.get(g.basePath);A!==void 0&&b.add(A)}let S=[],x=!1;for(let A of b){if(x=t.has(g.path)&&!r.has(g.path),x&&A.kind==="delete"){l.add(A);continue}if(!x&&A.kind==="change"&&A.path===g.path&&A.blobSha===g.blobSha){l.add(A),s.add(g.path);continue}if(A.kind==="delete"&&g.basePath!==void 0&&A.path===g.basePath){let T=p.get(g.path);if(T!==void 0&&T.kind==="change"&&T.blobSha===g.blobSha){l.add(A);continue}}S.push(A),l.add(A)}S.length>0&&(u.push({local:g,localIsDelete:x,remotes:S,desc:`${g.uid!==void 0&&!d.has(g.uid)?g.uid:g.path} (local ${x?"delete":"change"} vs remote ${S[0].kind} at ${S[0].path})`}),s.add(g.path))}let y=i.filter(g=>!l.has(g));return{conflicts:u,applyWrites:y.filter(g=>g.kind==="change"),applyDeletes:y.filter(g=>g.kind==="delete")}}async checkRaceWindow(e,t,r,i,s,o,c,l){try{let u=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,i,this.deps.baseURL),f=(await(0,ot.getTree)(this.transport,e.owner,e.repo,u.treeSha,this.deps.baseURL)).filter(l.treeFilter),d=r===t.lastSyncedSha?t.files:(await(0,ot.getTree)(this.transport,e.owner,e.repo,(await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,r,this.deps.baseURL)).treeSha,this.deps.baseURL)).filter(l.treeFilter),{changed:h,deleted:p}=bP(d,f);for(let y of h)s.has(y.path)&&c.push(`race-window: concurrent commit ${i} changed ${y.path} between conflict check (head ${r}) and push \u2014 local version won; previous version recoverable from git history`),o.has(y.path)&&c.push(`race-window: concurrent commit ${i} changed ${y.path} which this push DELETED \u2014 the delete won; the concurrent version is recoverable from git history`);for(let y of p)s.has(y.path)&&c.push(`race-window: concurrent commit ${i} deleted ${y.path}; push re-created it`)}catch(u){let f=this.deps.redact??(d=>d);c.push(`race-window check failed: ${f(ha(u))}`)}}async buildWatermarkFiles(e,t,r,i,s,o,c){if(c.fileMode)return t.map(f=>({path:f.path,blobSha:f.blobSha}));let l=new Map;for(let f of i)f.kind==="change"&&f.blobSha!==void 0&&l.set(f.blobSha,f.uid);for(let[f,d]of r){let h=o?.get(f)??await(0,vc.gitBlobSha)(d,this.sha1);l.set(h,typeof d=="string"?(0,xo.extractAssetUid)(d):void 0)}for(let f of s.files)l.has(f.blobSha)||l.set(f.blobSha,f.uid);let u=[];for(let f of t){let d;if(l.has(f.blobSha))d=l.get(f.blobSha);else{let h=await(0,ot.getBlobText)(this.transport,e.owner,e.repo,f.blobSha,this.deps.baseURL);d=(0,xo.extractAssetUid)(h)}u.push({path:f.path,blobSha:f.blobSha,...d?{uid:d}:{}})}return u}};Zn.SyncEngine=fT});var vP=v(fd=>{"use strict";Object.defineProperty(fd,"__esModule",{value:!0});fd.QuarantineResolver=void 0;fd.backupPathFor=SP;var GH=fy(),Ey=ad(),ld=su(),ud=py(),WH=gy(),Ps="\0absent",dT=class{static{a(this,"QuarantineResolver")}constructor(e){this.deps=e}async listOpenConflicts(e){let t=[];for(let r of e)t.push(...await this.listRepoConflicts(r));return t}async listRepoConflicts(e){if(e.spaceKind==="file")return[];let t=await this.deps.watermarkStore.get(e.repoKey),r=t?.pinnedPaths??[];if(r.length===0)return[];if(this.deps.outbox!==void 0){let p=await this.deps.outbox.listForRepo(e.repoKey);if(p.length>0){let y=new Set(p.map(g=>g.path));if(r=r.filter(g=>!y.has(g)),r.length===0)return[]}}let i=new Map;for(let p of t?.files??[])i.set(p.path,p.blobSha);let s=this.deps.conflictCache!==void 0,o=await this.cachedRecordsFor(e,r),c=r.some(p=>!o.has(p)),l=new Map,u=!0;if(c)if(s)try{l=await this.remoteTreeShas(e)}catch{u=!1}else l=await this.remoteTreeShas(e);let f=this.deps.localFilesFor(e),d=new Set(await f.list()),h=[];for(let p of r){let y=o.get(p),g,b;if(y!==void 0)b=y.remoteContent!==void 0?await(0,ld.gitBlobSha)(y.remoteContent,this.deps.sha1):Ps,g=y.baseContent!==void 0?await(0,ld.gitBlobSha)(y.baseContent,this.deps.sha1):i.get(p)??Ps;else{if(!u)continue;b=l.get(p)??Ps,g=i.get(p)??Ps}let w=Ps,S;if(d.has(p)&&(S=await f.read(p),w=await(0,ld.gitBlobSha)(S,this.deps.sha1)),!(w!==b&&w!==g&&b!==g))continue;let A=(S!==void 0?(0,ud.extractAssetUid)(S):void 0)??y?.uid;h.push({repoKey:e.repoKey,path:p,...A!==void 0?{uid:A}:{},hasLocal:w!==Ps,hasRemote:b!==Ps})}return h}async cachedRecordsFor(e,t){let r=new Map,i=this.deps.conflictCache;if(i===void 0)return r;for(let s of t){let o=await i.get(e.repoKey,s);o!==null&&r.set(s,o)}return r}async detectDuplicateUids(e){let t=new Map;for(let i of e){let s=this.deps.localFilesFor(i);for(let o of await s.list()){if(!o.endsWith(".md"))continue;let c;try{c=await s.read(o)}catch{continue}let l=(0,ud.extractAssetUid)(c);l!==void 0&&t.set(l,(t.get(l)??0)+1)}}let r=0;for(let i of t.values())i>1&&r++;return r}async loadConflict(e,t){let r=this.deps.localFilesFor(e),s=new Set(await r.list()).has(t)?await r.read(t):void 0,o=await this.deps.conflictCache?.get(e.repoKey,t)??null,c,l;if(o!==null)c=o.remoteContent,l=o.baseContent;else{let d=(await this.remoteTreeShas(e)).get(t);c=d!==void 0?await this.blobText(e,d):void 0;let p=((await this.deps.watermarkStore.get(e.repoKey))?.files??[]).find(y=>y.path===t)?.blobSha;if(p!==void 0)try{l=await this.blobText(e,p)}catch{l=void 0}}let u=(s!==void 0?(0,ud.extractAssetUid)(s):void 0)??(c!==void 0?(0,ud.extractAssetUid)(c):void 0)??o?.uid;return{repoKey:e.repoKey,path:t,...u!==void 0?{uid:u}:{},hasLocal:s!==void 0,hasRemote:c!==void 0,...l!==void 0?{base:l}:{},...s!==void 0?{local:s}:{},...c!==void 0?{remote:c}:{}}}async resolve(e,t,r){let i=this.deps.localFilesFor(e),o=new Set(await i.list()).has(t)?await i.read(t):void 0,c=this.deps.outbox!==void 0,{remote:l,remoteSha:u}=c?await this.remoteForResolve(e,t):await this.liveRemoteForResolve(e,t),f=this.chosenContent(r,o,l),d;r.take!=="local"&&o!==void 0&&o!==f&&(d=SP(t),await i.write(d,o)),f===void 0?await i.delete(t):await i.write(t,f);let p=f===void 0&&l===void 0||f===l;if(c&&this.deps.outbox!==void 0&&!p&&f!==void 0)return await this.deps.outbox.enqueue({repoKey:e.repoKey,path:t,chosenContent:f,resolvedTo:r.take==="merged"?"merged":"local",baseRemoteSha:u===Ps?WH.OUTBOX_REMOTE_ABSENT:u,resolvedAt:""}),{repoKey:e.repoKey,path:t,resolvedTo:r.take,awaitingPush:!0,...d!==void 0?{discardedLocalBackupPath:d}:{}};let y;return p||(y=await this.commitChoice(e,t,f)),await this.snapWatermark(e,t,f),this.deps.quarantine?.markResolved!==void 0&&await this.deps.quarantine.markResolved(e.repoKey,t),{repoKey:e.repoKey,path:t,resolvedTo:r.take,...y!==void 0?{pushedSha:y}:{},...d!==void 0?{discardedLocalBackupPath:d}:{}}}async remoteForResolve(e,t){let r=await this.deps.conflictCache?.get(e.repoKey,t)??null;if(r!==null){let i=r.remoteContent,s=i!==void 0?await(0,ld.gitBlobSha)(i,this.deps.sha1):Ps;return{remote:i,remoteSha:s}}return this.liveRemoteForResolve(e,t)}async liveRemoteForResolve(e,t){let i=(await this.remoteTreeShas(e)).get(t);return{remote:i!==void 0?await this.blobText(e,i):void 0,remoteSha:i??Ps}}chosenContent(e,t,r){switch(e.take){case"local":if(t===void 0)throw new Error("resolve: cannot keep local \u2014 no local version exists on disk");return t;case"remote":return r;case"merged":return e.content}}async commitChoice(e,t,r){let i=this.deps.commitMessage?.(e,t)??`chore(exosync): resolve conflict for ${t}`;if(r===void 0)throw new Error(`resolve: cannot push an empty resolution for ${t}`);return(0,GH.restCreateCommit)(this.deps.transport,{owner:e.owner,repo:e.repo,branch:e.branch,files:new Map([[t,r]]),message:i,...this.deps.baseURL!==void 0?{baseURL:this.deps.baseURL}:{},...this.deps.redact!==void 0?{redact:this.deps.redact}:{}})}async snapWatermark(e,t,r){let i=await this.deps.watermarkStore.get(e.repoKey);if(i===null)return;let s=(i.pinnedPaths??[]).filter(c=>c!==t),o=i.files;if(r===void 0)o=o.filter(c=>c.path!==t);else{let c=await(0,ld.gitBlobSha)(r,this.deps.sha1),l=(0,ud.extractAssetUid)(r),u={path:t,blobSha:c,...l!==void 0?{uid:l}:{}},f=o.findIndex(d=>d.path===t);o=f>=0?o.map((d,h)=>h===f?u:d):[...o,u]}await this.deps.watermarkStore.set(e.repoKey,{...i,files:o,...s.length>0?{pinnedPaths:s}:{pinnedPaths:void 0}})}async remoteTreeShas(e){let t=await(0,Ey.getHeadSha)(this.deps.transport,e.owner,e.repo,e.branch,this.deps.baseURL),r=await(0,Ey.getCommitInfo)(this.deps.transport,e.owner,e.repo,t,this.deps.baseURL),i=await(0,Ey.getTree)(this.deps.transport,e.owner,e.repo,r.treeSha,this.deps.baseURL),s=new Map;for(let o of i)s.set(o.path,o.blobSha);return s}async blobText(e,t){return(0,Ey.getBlobText)(this.deps.transport,e.owner,e.repo,t,this.deps.baseURL)}};fd.QuarantineResolver=dT;function SP(n){return`${n}.conflict.local.txt`}a(SP,"backupPathFor")});var EP=v(ou=>{"use strict";Object.defineProperty(ou,"__esModule",{value:!0});ou.FileLocalManifestStore=ou.LOCAL_MANIFEST_STORE_FILENAME=void 0;ou.LOCAL_MANIFEST_STORE_FILENAME="exosync-localmanifest.local.json";function zH(n){if(n===null||typeof n!="object")return!1;let e=n;return e.version===1&&typeof e.lastFullRehashMs=="number"&&e.files!==null&&typeof e.files=="object"}a(zH,"isLocalManifestRecord");var hT=class{static{a(this,"FileLocalManifestStore")}constructor(e){this.io=e,this.writeChain=Promise.resolve()}async get(e){let r=(await this.readRepos())[e];return zH(r)?r:null}async set(e,t){let r=this.writeChain.then(async()=>{let i=await this.readRepos();i[e]=t;let s={version:1,repos:i};await this.io.writeAtomic(JSON.stringify(s))});return this.writeChain=r.catch(()=>{}),r}async readRepos(){try{let e=await this.io.read();if(e===null)return{};let t=JSON.parse(e);if(t===null||typeof t!="object")return{};let r=t.repos;return r===null||typeof r!="object"?{}:{...r}}catch{return{}}}};ou.FileLocalManifestStore=hT});var gT=v(mT=>{"use strict";Object.defineProperty(mT,"__esModule",{value:!0});mT.diff3=HH;function TP(n,e){let t=n.length,r=e.length,i=Array.from({length:t+1},()=>new Int32Array(r+1));for(let l=t-1;l>=0;l--)for(let u=r-1;u>=0;u--)i[l][u]=n[l]===e[u]?i[l+1][u+1]+1:Math.max(i[l+1][u],i[l][u+1]);let s=new Map,o=0,c=0;for(;o<t&&c<r;)n[o]===e[c]?(s.set(o,c),o++,c++):i[o+1][c]>=i[o][c+1]?o++:c++;return s}a(TP,"lcsMatch");function pT(n,e){if(n.length!==e.length)return!1;for(let t=0;t<n.length;t++)if(n[t]!==e[t])return!1;return!0}a(pT,"sliceEq");function HH(n,e,t){let r=TP(n,e),i=TP(n,t),s=[],o=0,c=0,l=0;for(;;){let u=o;for(;u<n.length&&!(r.has(u)&&i.has(u));)u++;let f=u<n.length?r.get(u):e.length,d=u<n.length?i.get(u):t.length,h=n.slice(o,u),p=e.slice(c,f),y=t.slice(l,d),g=!pT(p,h),b=!pT(y,h);if(!g&&!b)s.push(...h);else if(!g)s.push(...y);else if(!b)s.push(...p);else if(pT(p,y))s.push(...p);else return{ok:!1,conflict:{base:h,local:p,remote:y}};if(u>=n.length)break;s.push(n[u]),o=u+1,c=f+1,l=d+1}return{ok:!0,merged:s}}a(HH,"diff3")});var xP=v(pd=>{"use strict";Object.defineProperty(pd,"__esModule",{value:!0});pd.StructuredMerger=void 0;pd.splitSections=Ty;var AP=gT(),KH=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/,dd="exo__Instance_class";function hd(n){if(n===null||typeof n!="object")return!0;if(Array.isArray(n))return n.every(hd);let e=Object.getPrototypeOf(n);return e!==Object.prototype&&e!==null?!1:Object.values(n).every(hd)}a(hd,"isPlainValue");function pa(n,e){if(n===e)return!0;if(n===null||e===null||n===void 0||e===void 0||typeof n!="object"||typeof e!="object"||Array.isArray(n)!==Array.isArray(e))return!1;if(Array.isArray(n)&&Array.isArray(e))return n.length!==e.length?!1:n.every((s,o)=>pa(s,e[o]));let t=n,r=e,i=Object.keys(t);return i.length!==Object.keys(r).length?!1:i.every(s=>pa(t[s],r[s]))}a(pa,"deepEqual");function Ec(n){return typeof n=="string"?`s:${n}`:`j:${JSON.stringify(n)}`}a(Ec,"setKey");function ui(n){return n==null?[]:Array.isArray(n)?n:[n]}a(ui,"toElements");function YH(n,e,t){let r=new Set(ui(n).map(Ec)),i=ui(e),s=ui(t),o=new Set(i.map(Ec)),c=new Set(s.map(Ec)),l=a(d=>o.has(d)&&c.has(d)||o.has(d)&&!r.has(d)||c.has(d)&&!r.has(d),"keep"),u=[],f=new Set;for(let d of[...i,...s]){let h=Ec(d);f.has(h)||!l(h)||(f.add(h),u.push(d))}return u}a(YH,"mergeSet");function QH(n,e,t){let r=[],i=[],s=new Set;for(let c of[...Object.keys(n),...Object.keys(e),...Object.keys(t)])s.has(c)||(s.add(c),i.push(c));let o={};for(let c of i){let l=n[c],u=e[c],f=t[c];if(!hd(l)||!hd(u)||!hd(f))return{ok:!1,reason:`frontmatter key "${c}" contains a non-plain value (Date?) \u2014 the codec must round-trip scalars as strings (CORE_SCHEMA contract)`};if(Array.isArray(l)||Array.isArray(u)||Array.isArray(f)){if(!(c in e)&&!(c in t))continue;let d=YH(l,u,f),h=new Set(ui(l).map(Ec)),p=ui(u).some(g=>!h.has(Ec(g))),y=ui(f).some(g=>!h.has(Ec(g)));p&&y&&!pa(ui(u),ui(f))&&r.push(`both sides added values to multi-valued key "${c}" \u2014 union kept (D20)`),d.length>0&&(o[c]=d);continue}if(pa(u,f)){u!==void 0&&(o[c]=u);continue}if(pa(u,l)){f!==void 0&&(o[c]=f);continue}if(pa(f,l)){u!==void 0&&(o[c]=u);continue}return{ok:!1,reason:`frontmatter key "${c}" changed differently on both sides`}}return{ok:!0,value:o,warnings:r}}a(QH,"mergeFrontmatter");var XH=/^(```|~~~)/,JH=/^#{1,6}\s/;function Ty(n){let e=n.split(`
308
+ `)}a(dH,"stripGitmodulesEntry")});var su=v(ZE=>{"use strict";Object.defineProperty(ZE,"__esModule",{value:!0});ZE.gitBlobSha=hH;async function hH(n,e){let t=new TextEncoder,r=typeof n=="string"?t.encode(n):n,i=t.encode(`blob ${r.byteLength}\0`),s=new Uint8Array(i.byteLength+r.byteLength);return s.set(i,0),s.set(r,i.byteLength),e(s)}a(hH,"gitBlobSha")});var py=v(hy=>{"use strict";Object.defineProperty(hy,"__esModule",{value:!0});hy.extractAssetUid=oP;hy.detectChanges=mH;var pH=su();function oP(n){let e=/^---\r?\n([\s\S]*?)\r?\n---(?=\r?\n|$)/.exec(n);if(!e)return;let t=/^exo__Asset_uid:[ \t]*["']?([^\s"']+)["']?[ \t]*$/m.exec(e[1]);return t?t[1]:void 0}a(oP,"extractAssetUid");async function mH(n){let{localFiles:e,cachedEntries:t,watermark:r,actualBaseTreeSha:i,sha1:s}=n;if(r===null)return{kind:"full-conflict",reason:"first-sync"};if(i===null)return{kind:"full-conflict",reason:"base-mismatch",detail:`watermark commit ${r.lastSyncedSha} not resolvable on remote`};if(i!==r.rootTreeSha)return{kind:"full-conflict",reason:"base-mismatch",detail:`stored root tree ${r.rootTreeSha} != actual ${i} at ${r.lastSyncedSha}`};let o=[],c=new Map;for(let[A,T]of e){let R=await(0,pH.gitBlobSha)(T,s);c.set(A,R),o.push({path:A,blobSha:R,uid:typeof T=="string"?oP(T):void 0})}if(t!==void 0)for(let[A,T]of t)c.set(A,T.blobSha),o.push({path:A,blobSha:T.blobSha,uid:T.uid});let l=[],u=[],f=[],d=[],h=new Map;for(let A of o){if(A.uid===void 0)continue;let T=h.get(A.uid)??[];T.push(A.path),h.set(A.uid,T)}let p=new Map;for(let A of r.files){if(A.uid===void 0)continue;let T=p.get(A.uid)??[];T.push(A.path),p.set(A.uid,T)}let y=new Set;for(let[A,T]of h)T.length>1&&y.add(A);for(let[A,T]of p)T.length>1&&y.add(A);for(let A of[...y].sort()){let T=h.get(A)??[],R=T.length>1?`on disk (${T.join(", ")})`:`in the sync base (${(p.get(A)??[]).join(", ")})`;d.push(`duplicate uid ${A} ${R} \u2014 uid identity suppressed for the group; every path matched by path identity (#3477)`)}let g=new Map,b=[];for(let A of r.files)A.uid!==void 0&&!y.has(A.uid)?g.set(A.uid,A):b.push(A);let w=[],S=new Set;for(let A of o){let T=A.uid!==void 0&&!y.has(A.uid)?g.get(A.uid):void 0;A.uid!==void 0&&T!==void 0?(S.add(A.uid),(T.blobSha!==A.blobSha||T.path!==A.path)&&u.push({path:A.path,uid:A.uid,blobSha:A.blobSha,...T.path!==A.path?{basePath:T.path}:{}})):w.push(A)}let x=new Map;for(let A of b)x.set(A.path,A);for(let[A,T]of g)S.has(A)||x.set(T.path,T);for(let A of w){let T=x.get(A.path);T!==void 0?(x.delete(A.path),T.blobSha!==A.blobSha&&u.push({path:A.path,uid:A.uid,blobSha:A.blobSha})):l.push({path:A.path,uid:A.uid,blobSha:A.blobSha})}for(let A of x.values())f.push({path:A.path,uid:A.uid,blobSha:A.blobSha});return{kind:"changes",added:l,modified:u,deleted:f,warnings:d,diskBlobShas:c,duplicateUids:y}}a(mH,"detectChanges")});var ad=v(Sc=>{"use strict";Object.defineProperty(Sc,"__esModule",{value:!0});Sc.getHeadSha=yH;Sc.getCommitInfo=bH;Sc.getTree=_H;Sc.getBlobText=wH;Sc.getBlobBytes=SH;var aP=nl(),gH="https://api.github.com";function od(n){return(n??gH).replace(/\/$/,"")}a(od,"api");function wc(n){return n!==null&&typeof n=="object"?n:void 0}a(wc,"asRecord");function Cs(n,e){let r=wc(n)?.[e];return typeof r=="string"?r:void 0}a(Cs,"readString");async function yH(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/refs/heads/${encodeURIComponent(r)}`}),o=Cs(wc(s?.json)?.object,"sha");if(typeof o!="string"||o.length===0)throw new Error(`ExoSync: missing object.sha for ref heads/${r}`);return o}a(yH,"getHeadSha");async function bH(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/commits/${encodeURIComponent(r)}`}),o=wc(s?.json),c=Cs(o,"sha"),l=Cs(o?.tree,"sha");if(!c||!l)throw new Error(`ExoSync: malformed commit response for ${r}`);let u=o?.parents,f=Array.isArray(u)?u.map(d=>Cs(d,"sha")).filter(d=>typeof d=="string"):[];return{sha:c,treeSha:l,parents:f}}a(bH,"getCommitInfo");async function _H(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/trees/${encodeURIComponent(r)}?recursive=1`}),o=wc(s?.json);if(o?.truncated===!0)throw new Error(`ExoSync: tree ${r} is truncated by GitHub (repo too large for recursive listing) \u2014 refusing to diff`);let c=o?.tree;if(!Array.isArray(c))throw new Error(`ExoSync: malformed tree response for ${r}`);let l=[];for(let u of c){let f=wc(u);if(f?.type!=="blob")continue;let d=Cs(f,"path"),h=Cs(f,"sha"),p=typeof f.size=="number"?f.size:void 0;d&&h&&l.push({path:d,blobSha:h,...p!==void 0?{size:p}:{}})}return l}a(_H,"getTree");async function wH(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/blobs/${encodeURIComponent(r)}`}),o=wc(s?.json),c=Cs(o,"content");if(typeof c!="string")throw new Error(`ExoSync: malformed blob response for ${r}`);return Cs(o,"encoding")==="utf-8"?c:(0,aP.base64ToUtf8)(c)}a(wH,"getBlobText");async function SH(n,e,t,r,i){let s=await n({method:"GET",url:`${od(i)}/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}/git/blobs/${encodeURIComponent(r)}`}),o=wc(s?.json),c=Cs(o,"content");if(typeof c!="string")throw new Error(`ExoSync: malformed blob response for ${r}`);return Cs(o,"encoding")==="utf-8"?new TextEncoder().encode(c):(0,aP.base64ToBytes)(c)}a(SH,"getBlobBytes")});var rT=v(Yt=>{"use strict";Object.defineProperty(Yt,"__esModule",{value:!0});Yt.SyncPhaseTimer=Yt.SYNC_PHASES=void 0;Yt.classifyRestPhase=vH;Yt.emptyTimings=lP;Yt.totalMs=my;Yt.addTimings=uP;Yt.aggregateTimings=EH;Yt.dominantPhase=TH;Yt.fmtMs=cd;Yt.formatTimingsLine=AH;Yt.formatRepoTimings=xH;Yt.SYNC_PHASES=["localList","localRead","localWrite","hash","restHead","restCommit","restTree","restBlob","restPush"];function tT(){let n={};for(let e of Yt.SYNC_PHASES)n[e]=0;return n}a(tT,"zeroDurations");function cP(){return{filesRead:0,filesHashed:0,filesWritten:0,restCalls:0}}a(cP,"zeroCounts");function vH(n){if(n.method!=="GET")return"restPush";let e=n.url;return e.includes("/git/blobs/")?"restBlob":e.includes("/git/trees/")?"restTree":e.includes("/git/commits/")?"restCommit":e.includes("/git/refs/")?"restHead":"restCommit"}a(vH,"classifyRestPhase");var eT=class{static{a(this,"SyncPhaseTimer")}constructor(e){this.now=e,this.durations=tT(),this.counts=cP()}async time(e,t){let r=this.now();try{return await t()}finally{this.durations[e]+=this.now()-r}}bumpRead(){this.counts.filesRead++}bumpHashed(){this.counts.filesHashed++}bumpWritten(){this.counts.filesWritten++}bumpRest(){this.counts.restCalls++}snapshot(){return{durations:{...this.durations},counts:{...this.counts}}}};Yt.SyncPhaseTimer=eT;function lP(){return{durations:tT(),counts:cP()}}a(lP,"emptyTimings");function my(n){let e=0;for(let t of Yt.SYNC_PHASES)e+=n.durations[t];return e}a(my,"totalMs");function uP(n,e){let t=tT();for(let r of Yt.SYNC_PHASES)t[r]=n.durations[r]+e.durations[r];return{durations:t,counts:{filesRead:n.counts.filesRead+e.counts.filesRead,filesHashed:n.counts.filesHashed+e.counts.filesHashed,filesWritten:n.counts.filesWritten+e.counts.filesWritten,restCalls:n.counts.restCalls+e.counts.restCalls}}}a(uP,"addTimings");function EH(n){let e=lP();for(let t of n)t.timings!==void 0&&(e=uP(e,t.timings));return e}a(EH,"aggregateTimings");function TH(n){let e=my(n);if(e<=0)return null;let t=Yt.SYNC_PHASES[0],r=-1;for(let i of Yt.SYNC_PHASES)n.durations[i]>r&&(r=n.durations[i],t=i);return{phase:t,ms:r,pct:r/e*100}}a(TH,"dominantPhase");function cd(n){return n>=1e3?`${(n/1e3).toFixed(1)}s`:`${Math.round(n)}ms`}a(cd,"fmtMs");function AH(n){let e=my(n);if(e<=0)return"";let t=Yt.SYNC_PHASES.filter(r=>n.durations[r]>0).sort((r,i)=>n.durations[i]-n.durations[r]).map(r=>`${r} ${cd(n.durations[r])} ${Math.round(n.durations[r]/e*100)}%`);return`\u23F1 ExoSync ${cd(e)} \u2014 ${t.join(" \xB7 ")} (${n.counts.filesHashed} hashed, ${n.counts.filesRead} read, ${n.counts.restCalls} REST)`}a(AH,"formatTimingsLine");function xH(n,e){let t=Yt.SYNC_PHASES.map(r=>`${r}=${cd(e.durations[r])}`);return`[ExoSync timings] ${n}: total ${cd(my(e))} \u2014 ${t.join(" ")} | hashed ${e.counts.filesHashed} read ${e.counts.filesRead} written ${e.counts.filesWritten} REST ${e.counts.restCalls}`}a(xH,"formatRepoTimings")});var gy=v(da=>{"use strict";Object.defineProperty(da,"__esModule",{value:!0});da.LocalOutboxStore=da.OUTBOX_REMOTE_ABSENT=da.OUTBOX_STORE_FILENAME=void 0;da.OUTBOX_STORE_FILENAME="exosync-outbox.local.json";da.OUTBOX_REMOTE_ABSENT=" absent";function nT(n,e){return`${n}\0${e}`}a(nT,"outboxKey");function fP(n){if(n===null||typeof n!="object")return!1;let e=n;return typeof e.repoKey=="string"&&typeof e.path=="string"&&typeof e.chosenContent=="string"&&typeof e.baseRemoteSha=="string"}a(fP,"isEntry");var iT=class{static{a(this,"LocalOutboxStore")}constructor(e){this.writeChain=Promise.resolve(),this.io=e.io,this.now=e.now??(()=>new Date().toISOString())}async enqueue(e){await this.mutate(t=>{t.entries[nT(e.repoKey,e.path)]={version:1,...e,resolvedAt:e.resolvedAt.length>0?e.resolvedAt:this.now()}})}async remove(e,t){await this.mutate(r=>{delete r.entries[nT(e,t)]})}async list(){let e=await this.read();return Object.values(e.entries).filter(fP)}async listForRepo(e){return(await this.list()).filter(t=>t.repoKey===e)}async has(e,t){let i=(await this.read()).entries[nT(e,t)];return i!==void 0&&fP(i)}async mutate(e){let t=this.writeChain.then(async()=>{let r=await this.read();e(r),await this.io.writeAtomic(JSON.stringify(r,null,2))});return this.writeChain=t.catch(()=>{}),t}async read(){try{let e=await this.io.read();if(e===null)return{version:1,entries:{}};let t=JSON.parse(e);if(t===null||typeof t!="object")return{version:1,entries:{}};let r=t.entries;return r===null||typeof r!="object"?{version:1,entries:{}}:{version:1,entries:{...r}}}catch{return{version:1,entries:{}}}}};da.LocalOutboxStore=iT});var yy=v(sT=>{"use strict";Object.defineProperty(sT,"__esModule",{value:!0});sT.isAuthError=IH;function IH(n){let e=n instanceof Error?n.message:String(n);return/HTTP 401/.test(e)?!0:/HTTP 403/.test(e)&&!/rate limit/i.test(e)&&!/abuse detection/i.test(e)}a(IH,"isAuthError")});var oT=v(by=>{"use strict";Object.defineProperty(by,"__esModule",{value:!0});by.scanForSecrets=RH;by.redactSecrets=CH;var dP=[{kind:"github-token",re:/gh[pousr]_[A-Za-z0-9_]{36,}/},{kind:"github-fine-grained-token",re:/github_pat_[A-Za-z0-9_]{22,}_[A-Za-z0-9_]{59,}/},{kind:"private-key",re:/-----BEGIN [A-Z ]*PRIVATE KEY-----/}];function RH(n){let e=[];for(let[t,r]of n)for(let{kind:i,re:s}of dP)s.test(r)&&e.push({path:t,kind:i});return e}a(RH,"scanForSecrets");function CH(n){let e=n;for(let{kind:t,re:r}of dP)e=e.replace(new RegExp(r.source,"g"),`[REDACTED:${t}]`);return e}a(CH,"redactSecrets")});var wy=v(_y=>{"use strict";Object.defineProperty(_y,"__esModule",{value:!0});_y.isRateLimitError=hP;_y.withRateLimitBackoff=PH;function hP(n){let e=n instanceof Error?n.message:String(n);return/HTTP 429/.test(e)?!0:/HTTP 403/.test(e)&&(/rate limit/i.test(e)||/abuse detection/i.test(e))}a(hP,"isRateLimitError");var OH=a(n=>new Promise(e=>setTimeout(e,n)),"defaultSleep");function PH(n,e={}){let t=e.maxRetries??3,r=e.baseDelayMs??1e3,i=e.sleep??OH,s=e.random??Math.random;return async o=>{let c=0;for(;;)try{return await n(o)}catch(l){if(!hP(l)||c>=t)throw l;let u=r*2**c*(1+s());c++,await i(u)}}}a(PH,"withRateLimitBackoff")});var Sy=v(Ao=>{"use strict";Object.defineProperty(Ao,"__esModule",{value:!0});Ao.DEFAULT_MAX_FILE_BYTES=Ao.InMemoryQuarantineStore=void 0;Ao.contentEquals=FH;Ao.isSyncablePath=DH;Ao.isFileSpaceSyncablePath=LH;function FH(n,e){if(n===void 0||e===void 0||typeof n=="string"&&typeof e=="string")return n===e;if(typeof n=="string"||typeof e=="string"||n.byteLength!==e.byteLength)return!1;for(let t=0;t<n.byteLength;t++)if(n[t]!==e[t])return!1;return!0}a(FH,"contentEquals");var aT=class{static{a(this,"InMemoryQuarantineStore")}constructor(){this.entries=[]}async quarantine(e){this.entries.push(e)}};Ao.InMemoryQuarantineStore=aT;function DH(n){return n.endsWith(".md")&&!n.includes(".local.")&&!n.includes(".conflict.")}a(DH,"isSyncablePath");function LH(n){return!n.includes(".local.")&&!n.includes(".conflict.")}a(LH,"isFileSpaceSyncablePath");Ao.DEFAULT_MAX_FILE_BYTES=30*1024*1024});var wP=v(Zn=>{"use strict";Object.defineProperty(Zn,"__esModule",{value:!0});Zn.SyncEngine=Zn.DEFAULT_LOCAL_MANIFEST_REHASH_MS=Zn.DEFAULT_MAX_PUSH_RETRIES=void 0;Zn.isNonFastForwardError=_P;Zn.orderChildrenFirst=VH;var pP=fy(),mP=rT(),ot=ad(),xo=py(),NH=nl(),vc=su(),cT=gy(),kH=yy(),MH=oT(),jH=wy(),Os=Sy();Zn.DEFAULT_MAX_PUSH_RETRIES=3;Zn.DEFAULT_LOCAL_MANIFEST_REHASH_MS=720*60*1e3;function $H(n){try{return new TextDecoder("utf-8",{fatal:!0}).decode(n)}catch{return null}}a($H,"decodeUtf8Strict");function UH(n){return typeof n=="string"?n:{base64:(0,NH.bytesToBase64)(n)}}a(UH,"toCommitContent");async function gP(n,e){if(n.readBinary===void 0)throw new Error("LocalFilesPort.readBinary is required for file-mode sync (Phase C)");return n.readBinary(e)}a(gP,"readBinaryStrict");async function BH(n,e,t){if(n.writeBinary===void 0)throw new Error("LocalFilesPort.writeBinary is required for file-mode sync (Phase C)");return n.writeBinary(e,t)}a(BH,"writeBinaryStrict");function yP(n){return n.length===0||n.startsWith("/")||n.includes("\\")?!1:n.split("/").every(e=>e.length>0&&e!=="."&&e!=="..")}a(yP,"isSafeRepoRelativePath");function _P(n){let e=n instanceof Error?n.message:String(n);return/HTTP 422/.test(e)&&/git\/refs/.test(e)||/ref update mismatch/.test(e)||/HTTP 422/.test(e)&&/git\/trees/.test(e)&&/BadObjectState/.test(e)}a(_P,"isNonFastForwardError");function VH(n){let e=a(t=>t.split("/").filter(r=>r.length>0).length,"depth");return[...n].sort((t,r)=>e(r.localPath)-e(t.localPath))}a(VH,"orderChildrenFirst");function bP(n,e){let t=new Map(n.map(o=>[o.path,o])),r=new Set,i=[];for(let o of e){r.add(o.path);let c=t.get(o.path);(c===void 0||c.blobSha!==o.blobSha)&&i.push(o)}let s=n.filter(o=>!r.has(o.path));return{changed:i,deleted:s}}a(bP,"diffTrees");function ha(n){return n instanceof Error?n.message:String(n)}a(ha,"errMsg");function qH(n,e,t){if(t.size===0)return n;let r=new Map(e.files.map(o=>[o.path,o])),i=new Set(n.map(o=>o.path)),s=[];for(let o of n){if(!t.has(o.path)){s.push(o);continue}let c=r.get(o.path);c!==void 0&&s.push(c)}for(let o of t){if(i.has(o))continue;let c=r.get(o);c!==void 0&&s.push(c)}return s}a(qH,"applyWatermarkPins");var lT={mergedFiles:new Map,mergedWrites:[],quarantineEntries:[],resolvedQuarantineEntries:[],mergedCount:0,mergedPaths:[],warnings:[]};function uT(n){return new Map(n.map(e=>[e.path,e.blobSha]))}a(uT,"treeByPath");function vy(n){return[...n.quarantineEntries.map(e=>e.path),...n.resolvedQuarantineEntries.map(e=>e.path)]}a(vy,"quarantinedPathsOf");var fT=class{static{a(this,"SyncEngine")}constructor(e){this.activeTimer=null,this.opInProgress=!1,this.deps=e,this.now=e.now??(()=>Date.now()),this.transport=this.instrumentTransport((0,jH.withRateLimitBackoff)(e.transport,e.backoff)),this.sha1=this.instrumentSha1(e.sha1)}instrumentTransport(e){return async t=>{let r=this.activeTimer;return r===null?e(t):(r.bumpRest(),r.time((0,mP.classifyRestPhase)(t),()=>e(t)))}}instrumentSha1(e){return t=>{let r=this.activeTimer;return r===null?e(t):(r.bumpHashed(),r.time("hash",()=>e(t)))}}instrumentLocalFiles(e){let t=a((c,l)=>{let u=this.activeTimer;return u===null?l():u.time(c,l)},"timed"),r={list:a(()=>t("localList",()=>e.list()),"list"),read:a(c=>(this.activeTimer?.bumpRead(),t("localRead",()=>e.read(c))),"read"),write:a((c,l)=>t("localWrite",()=>(this.activeTimer?.bumpWritten(),e.write(c,l))),"write"),delete:a(c=>e.delete(c),"delete")},i=e.readBinary?.bind(e);i!==void 0&&(r.readBinary=c=>(this.activeTimer?.bumpRead(),t("localRead",()=>i(c))));let s=e.writeBinary?.bind(e);s!==void 0&&(r.writeBinary=(c,l)=>t("localWrite",()=>(this.activeTimer?.bumpWritten(),s(c,l))));let o=e.stat?.bind(e);return o!==void 0&&(r.stat=c=>t("localList",()=>o(c))),r}busyResult(e){return{repoKey:e.repoKey,status:"busy",pulledCount:0,pushedCount:0,mergedCount:0,quarantinedCount:0,warnings:[],deferredDeletes:[],detail:"another sync operation is in progress (D11 guard) \u2014 retry after it finishes"}}modeOps(e){let t=e.spaceKind==="file",r=t?Os.isFileSpaceSyncablePath:Os.isSyncablePath,i=this.deps.maxFileBytes??Os.DEFAULT_MAX_FILE_BYTES;return{fileMode:t,syncable:r,treeFilter:a(s=>r(s.path)&&(!t||s.size===void 0||s.size<=i),"treeFilter")}}async buildFileModeFirstSyncBase(e,t,r,i){let s=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),o=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,s,this.deps.baseURL),c=(await(0,ot.getTree)(this.transport,e.owner,e.repo,o.treeSha,this.deps.baseURL)).filter(r.treeFilter),l=[];for(let u of c){let f=t.get(u.path);f!==void 0&&await(0,vc.gitBlobSha)(f,this.sha1)===u.blobSha&&l.push({path:u.path,blobSha:u.blobSha})}return i.push(`first-sync (file mode): synthetic base from ${l.length} already-identical file(s) at head ${s} \u2014 divergence resolves through the remote-wins layer (D22)`),{lastSyncedSha:s,rootTreeSha:o.treeSha,files:l,spaceKind:"file"}}async syncAll(e,t="sync",r){if(this.opInProgress)return e.map(i=>this.busyResult(i));this.opInProgress=!0;try{let i=[];for(let s of e)i.push(await this.syncLocked(s,t,r));return i}finally{this.opInProgress=!1}}async sync(e,t="sync",r){if(this.opInProgress)return this.busyResult(e);this.opInProgress=!0;try{return await this.syncLocked(e,t,r)}finally{this.opInProgress=!1}}emitProgress(e,t,r){if(e!==void 0)try{e({repoKey:t,phase:r})}catch{}}async syncLocked(e,t="sync",r){let i=new mP.SyncPhaseTimer(this.now),s=this.activeTimer;this.activeTimer=i;let o=[],c=[],l=0,u=0,f=[],d=a((h,p={})=>({repoKey:e.repoKey,status:h,pulledCount:0,pushedCount:0,mergedCount:0,quarantinedCount:0,warnings:o,deferredDeletes:c,...l>0?{outboxPushedCount:l}:{},...u>0?{outboxReconflictedCount:u}:{},timings:i.snapshot(),...p}),"result");try{let h=await this.deps.materializationCheck.check(e);if(!h.fullyMaterialized)return o.push(`skipped: repo not fully materialized${h.reason?` (${h.reason})`:""} \u2014 deletes NOT inferred (D19)`),d("skipped-not-materialized");let p=this.modeOps(e),y=this.instrumentLocalFiles(this.deps.localFilesFor(e));if(p.fileMode&&(y.readBinary===void 0||y.writeBinary===void 0))return d("error",{detail:"file-mode repo requires a LocalFilesPort with readBinary/writeBinary \u2014 refusing to sync through the text-only port (binary would corrupt)"});if(p.fileMode&&this.deps.quarantine===void 0)return d("error",{detail:"file-mode repo requires a quarantine sink (D18 remote-wins preserves losing local bytes there) \u2014 configure the quarantine repo before syncing FileSpaces"});let g=this.deps.maxFileBytes??Os.DEFAULT_MAX_FILE_BYTES;if(t!=="pull"&&this.deps.outbox!==void 0){let G=await this.flushOutbox(e,o);l=G.pushed,u=G.reconflicted}let b=await this.deps.watermarkStore.get(e.repoKey);if(b?.spaceKind==="file"&&!p.fileMode)return d("error",{detail:"watermark was written by a FILE-mode sync but the spec now resolves to asset mode \u2014 refusing (fix the conflicting Space declarations, or clear the watermark to restart)"});b!==null&&p.fileMode&&b.spaceKind!=="file"&&(o.push("watermark was written by an ASSET-mode sync \u2014 rebuilding the base through the file-mode first-sync layer (kind flip)"),b=null);let w=this.deps.localManifestStore!==void 0?y.stat?.bind(y):void 0,S=w!==void 0&&b!==null&&!p.fileMode,x=S&&this.deps.localManifestStore!==void 0?await this.deps.localManifestStore.get(e.repoKey):null,A=this.deps.localManifestFullRehashMs??Zn.DEFAULT_LOCAL_MANIFEST_REHASH_MS,T=S&&(x===null||this.now()-x.lastFullRehashMs>=A),R=new Map,B=new Set,L=new Map,P=new Map,M=new Map,O=!1;for(let G of(await y.list()).filter(p.syncable)){if(p.fileMode){let se=await gP(y,G);if(se.byteLength>g){B.add(G),o.push(`skipped oversized file ${G} (${se.byteLength} bytes > ${g} cap) \u2014 excluded from sync symmetrically (Phase C size cap)`);continue}R.set(G,se);continue}if(!S||w===void 0){R.set(G,await y.read(G));continue}let ie=await w(G),J=!T&&ie!==null?x?.files[G]:void 0;if(ie!==null&&J!==void 0&&J.mtimeMs===ie.mtimeMs&&J.size===ie.size){L.set(G,{blobSha:J.blobSha,...J.uid!==void 0?{uid:J.uid}:{}}),P.set(G,J.blobSha),M.set(G,ie);continue}O=!0,R.set(G,await y.read(G)),ie!==null&&M.set(G,ie)}let Q=!1;if(b===null)if(p.fileMode)Q=!0,b=await this.buildFileModeFirstSyncBase(e,R,p,o);else{let G=await this.bootstrapWatermark(e,R,o,d);if(G.kind==="settled")return G.outcome;Q=!0,b=G.base}let oe=b;p.fileMode&&B.size>0&&(b={...b,files:b.files.filter(G=>!B.has(G.path))});let Y,be;S&&!T?(Y=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),be=Y===b.lastSyncedSha?b.rootTreeSha:await this.resolveBaseTreeSha(e,b)):be=await this.resolveBaseTreeSha(e,b),this.emitProgress(r,e.repoKey,"detecting");let le=await(0,xo.detectChanges)({localFiles:R,...S?{cachedEntries:L}:{},watermark:b,actualBaseTreeSha:be,sha1:this.sha1});if(le.kind==="full-conflict")return d("full-conflict",{detail:`${le.reason}${le.detail?`: ${le.detail}`:""} \u2014 divergence must go through merge/quarantine (A2/A3), not overwrite`});if(o.push(...le.warnings),S&&this.deps.localManifestStore!==void 0){let G={};for(let[ie,J]of R){let se=M.get(ie),_e=le.diskBlobShas.get(ie);if(se===void 0||_e===void 0)continue;let Ee=typeof J=="string"?(0,xo.extractAssetUid)(J):void 0;G[ie]={mtimeMs:se.mtimeMs,size:se.size,blobSha:_e,...Ee!==void 0?{uid:Ee}:{}}}for(let[ie,J]of L){let se=M.get(ie);se!==void 0&&(G[ie]={mtimeMs:se.mtimeMs,size:se.size,blobSha:J.blobSha,...J.uid!==void 0?{uid:J.uid}:{}})}if(x!==null&&Object.keys(x.files).some(ie=>!(ie in G))&&(O=!0),O||T||x===null){let ie={version:1,files:G,lastFullRehashMs:T||x===null?this.now():x.lastFullRehashMs};await this.deps.localManifestStore.set(e.repoKey,ie)}}let ue=this.pinLocalChanges(le,R,o,c,t);f=[...ue.pushDeletionsAll.keys()];let k=await this.runPushLoop(e,b,ue,R,o,p,Q,B,t,r,Y);if(f=[],k.kind!=="done"&&ue.pushDeletionsAll.size>0&&c.push(...ue.pushDeletionsAll.keys()),k.kind==="conflict")return d("conflict",{detail:k.detail});if(k.kind==="secret-detected")return d("error",{detail:k.detail});if(k.kind==="retry-exhausted"){o.push(...k.merge.warnings);let G=await this.buildTerminalQuarantineEntries(e,b,k.pushFiles,k.merge.quarantineEntries,R),ie=[...k.merge.quarantineEntries,...k.merge.resolvedQuarantineEntries,...G];return await this.flushQuarantine(ie,o),d("retry-exhausted",{detail:k.detail,quarantinedCount:ie.length,...ie.length>0?{quarantinedPaths:ie.map(J=>J.path)}:{}})}let{examinedHead:W,pushedSha:je,applyWrites:X,applyDeletes:q,pushFiles:ee}=k,Z=k.merge;o.push(...Z.warnings),o.push(...k.deferredWarnings),c.push(...k.withheldDeletions);let ge=k.deferredPaths.size>0?{deferredPaths:[...k.deferredPaths]}:{},$e=k.pushedDeletions.length>0?{pushedDeletes:k.pushedDeletions}:{},Ve=await this.flushQuarantine([...Z.quarantineEntries,...Z.resolvedQuarantineEntries],o),j=new Set;if(!Ve&&Z.resolvedQuarantineEntries.length>0){for(let G of Z.resolvedQuarantineEntries)j.add(G.path);o.push(`quarantine flush failed \u2014 remote-wins apply withheld for ${j.size} path(s); local files untouched, conflict re-derives next sync (D18 durability gate)`)}if(je===void 0&&W===b.lastSyncedSha&&X.length===0&&q.length===0&&Z.mergedWrites.length===0&&Z.quarantineEntries.length===0&&Z.resolvedQuarantineEntries.length===0&&(b.pinnedPaths?.length??0)===0&&k.alreadyInHead.length===0&&k.deferredPaths.size===0&&!Q)return d("synced");let te=je??W,pe=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,te,this.deps.baseURL);if(je!==void 0&&pe.parents[0]!==W)return await this.checkRaceWindow(e,b,W,pe.parents[0],ee,new Set(k.pushedDeletions),o,p),o.push(`race-window: watermark NOT advanced (pushed commit's parent ${pe.parents[0]} != examined head ${W}) \u2014 next sync reconciles the concurrent change`),d("synced",{pushedSha:je,pushedCount:ee.size,mergedCount:Z.mergedCount,quarantinedCount:Z.quarantineEntries.length+Z.resolvedQuarantineEntries.length,...Z.mergedPaths.length>0?{mergedPaths:Z.mergedPaths}:{},...vy(Z).length>0?{quarantinedPaths:vy(Z)}:{},...ge,...$e});let{pulledCount:Ae,pinnedPaths:ye}=await this.applyRemoteChanges(y,R,[...X,...Z.mergedWrites].filter(G=>!j.has(G.path)),q.filter(G=>!j.has(G.path)),o,P);for(let G of Z.quarantineEntries)ye.add(G.path);for(let G of k.deferredPaths)ye.add(G);for(let G of j)ye.add(G);if(p.fileMode){for(let G of B)ye.add(G);for(let G of k.remoteOversized)ye.add(G)}return await this.advanceWatermark(e,te,pe.treeSha,R,[...X,...Z.mergedWrites,...k.deferredRemoteChanges],oe,ye,le.diskBlobShas,p,B),await this.resolveClearedPins(e,oe,ye,o,new Set(Z.resolvedQuarantineEntries.map(G=>G.path))),d("synced",{pushedSha:je,pulledCount:Ae,pushedCount:ee.size,mergedCount:Z.mergedCount,quarantinedCount:Z.quarantineEntries.length+Z.resolvedQuarantineEntries.length,...Z.mergedPaths.length>0?{mergedPaths:Z.mergedPaths}:{},...vy(Z).length>0?{quarantinedPaths:vy(Z)}:{},...ge,...$e})}catch(h){let p=this.deps.redact??(y=>y);return f.length>0&&c.push(...f),(0,kH.isAuthError)(h)?d("auth-required",{detail:p(`authentication failed: ${ha(h)} \u2014 the PAT is expired, revoked or under-scoped; update it in the per-device secure storage (R8). Never treated as success.`)}):(o.push(`sync failed: ${p(ha(h))}`),d("error",{detail:p(ha(h))}))}finally{this.activeTimer=s}}async flushQuarantine(e,t){if(e.length===0)return!0;let r=this.deps.redact??(s=>s);for(let s of e)t.push(r(`quarantined ${s.path}: ${s.reason}`));let i=this.deps.quarantine;if(i===void 0)return!1;try{if(i.quarantineAll!==void 0)await i.quarantineAll(e);else for(let s of e)await i.quarantine(s);return!0}catch(s){let o=this.deps.redact??(c=>c);return t.push(`quarantine sink failed: ${o(ha(s))} \u2014 files untouched on disk; the conflict re-derives next sync (D17 degradation)`),!1}}async flushOutbox(e,t){let r=this.deps.outbox;if(r===void 0)return{pushed:0,reconflicted:0};let i=await r.listForRepo(e.repoKey);if(i.length===0)return{pushed:0,reconflicted:0};let s=this.deps.redact??(y=>y),o,c;try{({head:o,shaByPath:c}=await this.outboxHeadTreeShas(e))}catch(y){return t.push(`outbox flush deferred (${i.length} resolution(s) awaiting push): ${s(ha(y))}`),{pushed:0,reconflicted:0}}let l=0,u=[];for(let y of i){let g=c.get(y.path)??cT.OUTBOX_REMOTE_ABSENT,b=g===cT.OUTBOX_REMOTE_ABSENT&&y.baseRemoteSha!==cT.OUTBOX_REMOTE_ABSENT?[...c].filter(([w,S])=>w!==y.path&&S===y.baseRemoteSha).map(([w])=>w):[];if(g!==y.baseRemoteSha&&b.length===0){await r.remove(y.repoKey,y.path),l++,t.push(s(`outbox: remote moved for ${y.path} since you resolved it \u2014 NOT pushed; resolve again (your choice is preserved on disk)`));continue}u.push({entry:y,stalePaths:b})}if(u.length===0)return{pushed:0,reconflicted:l};let f=new Map;for(let{entry:y}of u)f.set(y.path,y.chosenContent);let d=new Set;for(let{stalePaths:y}of u)for(let g of y)f.has(g)||d.add(g);let h=[...d];try{await(0,pP.restCreateCommit)(this.transport,{owner:e.owner,repo:e.repo,branch:e.branch,files:f,...h.length>0?{deletions:h}:{},message:h.length>0?`chore(exosync): resolve ${u.length} keep-local conflict(s) (consolidate ${h.length} stale remote path(s))`:`chore(exosync): push ${u.length} resolved conflict(s)`,expectedHeadSha:o,...this.deps.baseURL!==void 0?{baseURL:this.deps.baseURL}:{},...this.deps.redact!==void 0?{redact:this.deps.redact}:{}})}catch(y){return t.push(`outbox: batch push deferred for ${u.length} resolution(s), will retry next sync: ${s(ha(y))}`),{pushed:0,reconflicted:l}}let p=0;for(let{entry:y,stalePaths:g}of u){let b=g.filter(w=>!f.has(w));await this.snapOutboxWatermark(e,y.path,y.chosenContent,b),await this.deps.quarantine?.markResolved?.(y.repoKey,y.path);for(let w of b)await this.deps.quarantine?.markResolved?.(y.repoKey,w);await r.remove(y.repoKey,y.path),p++,b.length>0&&t.push(`consolidated cross-path conflict for ${y.path} \u2014 removed ${b.length} stale remote copy/copies (recoverable in git history)`)}return p>0&&t.push(`pushed ${p} resolved conflict(s)`),{pushed:p,reconflicted:l}}async outboxHeadTreeShas(e){let t=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),r=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,t,this.deps.baseURL),i=await(0,ot.getTree)(this.transport,e.owner,e.repo,r.treeSha,this.deps.baseURL),s=new Map;for(let o of i)s.set(o.path,o.blobSha);return{head:t,shaByPath:s}}async snapOutboxWatermark(e,t,r,i=[]){let s=await this.deps.watermarkStore.get(e.repoKey);if(s===null)return;let o=new Set([t,...i]),c=(s.pinnedPaths??[]).filter(g=>!o.has(g)),l=await(0,vc.gitBlobSha)(r,this.sha1),u=(0,xo.extractAssetUid)(r),f={path:t,blobSha:l,...u!==void 0?{uid:u}:{}},d=new Set(i),h=s.files.filter(g=>!d.has(g.path)),p=h.findIndex(g=>g.path===t),y=p>=0?h.map((g,b)=>b===p?f:g):[...h,f];await this.deps.watermarkStore.set(e.repoKey,{...s,files:y,...c.length>0?{pinnedPaths:c}:{pinnedPaths:void 0}})}async buildTerminalQuarantineEntries(e,t,r,i,s){let o=new Set(i.map(u=>u.path)),c=new Map;try{let u=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),f=(await(0,ot.getTree)(this.transport,e.owner,e.repo,(await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,u,this.deps.baseURL)).treeSha,this.deps.baseURL)).filter(d=>r.has(d.path));for(let d of f)c.set(d.path,await(0,ot.getBlobText)(this.transport,e.owner,e.repo,d.blobSha,this.deps.baseURL))}catch{}let l=[];for(let[u,f]of r){if(o.has(u))continue;let d=s.get(u),h=d??f,p=d!==void 0&&!(0,Os.contentEquals)(d,f),y=typeof h=="string"?(0,xo.extractAssetUid)(h):void 0,g=c.get(u);l.push({repoKey:e.repoKey,path:u,...y!==void 0?{uid:y}:{},reason:`non-fast-forward push failed after ${this.deps.maxPushRetries??Zn.DEFAULT_MAX_PUSH_RETRIES} retries (D16) \u2014 a concurrent writer keeps moving ${e.branch}; base recoverable from git history at ${t.lastSyncedSha}${p?"; the contended push payload was a merged proposal (never applied to disk) \u2014 the merge re-derives next sync":""}`,...typeof h=="string"?{localContent:h}:{localContentBytes:h},...g!==void 0?{remoteContent:g}:{}})}return l}async resolveClearedPins(e,t,r,i,s=new Set){let o=this.deps.quarantine;if(o===void 0||o.markResolved===void 0)return;let c=(t.pinnedPaths??[]).filter(l=>!r.has(l)&&!s.has(l));for(let l of c)try{await o.markResolved?.(e.repoKey,l)}catch(u){let f=this.deps.redact??(d=>d);i.push(`quarantine markResolved failed for ${l}: ${f(ha(u))} \u2014 unresolved-count may overcount until the resolver UI reconciles (CQ4)`)}}async resolveBaseTreeSha(e,t){try{return(await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,t.lastSyncedSha,this.deps.baseURL)).treeSha}catch{return null}}pinLocalChanges(e,t,r,i,s){let o=e.modified.filter(h=>h.basePath!==void 0),c=[...e.added,...e.modified.filter(h=>h.basePath===void 0)],l=new Map;if(s==="pull"){for(let h of o)h.basePath!==void 0&&i.push(h.basePath),r.push(`pull-only: rename (uid ${h.uid??"?"}) ${h.basePath} \u2192 ${h.path} not pushed \u2014 propagates on the next push/Sync (#3473)`);for(let h of e.deleted)i.push(h.path),r.push(`pull-only: delete of ${h.path} not pushed \u2014 propagates on the next push/Sync (#3473)`)}else{for(let h of o)h.basePath!==void 0&&l.set(h.basePath,h.path);for(let h of e.deleted)l.set(h.path,h.path)}let u=[...c,...o,...e.deleted.map(h=>({...h}))],f=new Set(e.deleted.map(h=>h.path)),d=new Map;for(let h of[...c,...s==="pull"?[]:o]){let p=t.get(h.path);p!==void 0&&d.set(h.path,p)}return{localChanges:u,localDeletedPaths:f,pushFilesAll:d,pushDeletionsAll:l,dupUids:e.duplicateUids}}async runPushLoop(e,t,r,i,s,o,c=!1,l=new Set,u="sync",f,d){let{localChanges:h,localDeletedPaths:p,pushFilesAll:y,pushDeletionsAll:g,dupUids:b}=r,w=this.deps.maxPushRetries??Zn.DEFAULT_MAX_PUSH_RETRIES,S=0,x="",A,T=[],R=[],B=new Map,L=new Set,P=[],M=lT,O=[],Q=new Set,oe=[],Y=[],be=new Set;for(;;){x=S===0&&d!==void 0&&y.size===0&&g.size===0?d:await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),T=[],R=[],M=lT,O=[],Q=new Set,oe=[],Y=[];let le,ue=new Set,k=(t.pinnedPaths?.length??0)>0;if(x!==t.lastSyncedSha||k||c){this.emitProgress(f,e.repoKey,"pulling-remote");let X=await this.collectRemoteChanges(e,t,x,o,l,s,be);le=X.headTreeByPath;let q=this.matchLocalVsRemote(h,p,i,X.changes,ue,b,X.headTreeByPath);if(q.conflicts.length>0){if(u==="sync"&&this.emitProgress(f,e.repoKey,"merging"),u!=="sync"){for(let ee of q.conflicts){Q.add(ee.local.path),ee.local.basePath!==void 0&&Q.add(ee.local.basePath);for(let Z of ee.remotes)Q.add(Z.path),Z.kind==="change"&&oe.push(Z)}Y.push(`${u}-only: ${q.conflicts.length} conflict(s) deferred to a full Sync (${q.conflicts.map(ee=>ee.desc).join("; ")}) \u2014 paths pinned, nothing merged`)}else if(o.fileMode)M=this.resolveFileModeConflicts(e,q.conflicts,i,q.applyWrites,q.applyDeletes);else{if(this.deps.mergeLayer===void 0)return{kind:"conflict",detail:`overlapping change on ${q.conflicts[0].desc} \u2014 merge layer (A2/A3) required; nothing pushed, nothing written`};M=await this.resolveMergeConflicts(e,t,q.conflicts,i)}if(u==="sync")for(let ee of q.conflicts)for(let Z of ee.remotes)Z.path!==ee.local.path&&(Q.add(Z.path),Z.kind==="change"&&oe.push(Z),Y.push(`conflict group ${ee.desc}: remote change at ${Z.path} NOT applied \u2014 pinned to re-derive on the next sync (#3477)`))}if(T=q.applyWrites,R=q.applyDeletes,u==="push"&&(T.length>0||R.length>0)){for(let ee of T)Q.add(ee.path),oe.push(ee);for(let ee of R)Q.add(ee.path);Y.push(`push-only: ${T.length+R.length} remote change(s) NOT applied \u2014 pinned to re-derive on the next pull/Sync`),T=[],R=[]}}B=u==="pull"?new Map:new Map([...[...y].filter(([X])=>!ue.has(X)),...M.mergedFiles]),L=new Set,P=[];for(let[X,q]of g){if(ue.has(q)){P.push(X);continue}B.has(X)||L.add(X)}if((B.size>0||L.size>0)&&le===void 0&&(le=uT(await(0,ot.getTree)(this.transport,e.owner,e.repo,t.rootTreeSha,this.deps.baseURL))),B.size>0&&le!==void 0){for(let[X,q]of B){let ee=le.get(X);ee!==void 0&&ee===await(0,vc.gitBlobSha)(q,this.sha1)&&(B.delete(X),O.push(X))}O.length>0&&s.push(`phantom push skipped: ${O.length} file(s) already identical in remote HEAD (${O.join(", ")}) \u2014 excluded from the commit (#3475)`)}if(L.size>0&&le!==void 0){for(let X of[...L])le.has(X)||L.delete(X);B.size===0&&L.size>=le.size&&(P.push(...L),Y.push(`deletion of ALL ${L.size} remaining file(s) deferred \u2014 GitHub cannot create an empty tree; the deletes re-derive and propagate once the repo has at least one surviving file`),L.clear())}if(B.size===0&&L.size===0)break;let W=new Map;for(let[X,q]of B)if(typeof q=="string")W.set(X,q);else{let ee=$H(q);ee!==null&&W.set(X,ee)}let je=(0,MH.scanForSecrets)(W);if(je.length>0)return{kind:"secret-detected",detail:`secret-scan: refusing to push \u2014 ${je.map(X=>`${X.path} (${X.kind})`).join(", ")} (R5); remove the secret and re-sync`};try{A=await(0,pP.restCreateCommit)(this.transport,{owner:e.owner,repo:e.repo,branch:e.branch,files:new Map([...B].map(([X,q])=>[X,UH(q)])),deletions:[...L],message:this.deps.commitMessage?.(e,B.size,L.size)??`chore(exosync): sync ${B.size} file(s)${L.size>0?`, ${L.size} deletion(s)`:""}`,baseURL:this.deps.baseURL,redact:this.deps.redact});break}catch(X){if(!_P(X))throw X;if(S++,S>w)return{kind:"retry-exhausted",detail:`non-fast-forward push failed after ${w} retries (D16 cap) \u2014 contended files routed to quarantine (D17)`,pushFiles:B,merge:M};s.push(`non-fast-forward push (attempt ${S}/${w}) \u2014 re-pulling and retrying (D16)`)}}return{kind:"done",examinedHead:x,pushedSha:A,applyWrites:T,applyDeletes:R,pushFiles:B,pushedDeletions:A!==void 0?[...L]:[],withheldDeletions:P,merge:M,remoteOversized:be,alreadyInHead:O,deferredPaths:Q,deferredRemoteChanges:oe,deferredWarnings:Y}}async resolveMergeConflicts(e,t,r,i){let s=this.deps.mergeLayer;if(s===void 0)return lT;let o=new Map(t.files.map(g=>[g.path,g])),c=new Map,l=[],u=[],f=[],d=[],h=0,p=a(g=>typeof g=="string"?g:void 0,"asText"),y=a((g,b,w)=>{let S=p(i.get(g.local.path)),x=p(g.remotes[0]?.content);return{repoKey:e.repoKey,path:g.local.path,...g.local.uid!==void 0?{uid:g.local.uid}:{},reason:b,...w!==void 0?{baseContent:w}:{},...S!==void 0?{localContent:S}:{},...x!==void 0?{remoteContent:x}:{}}},"entry");for(let g of r){let b=o.get(g.local.basePath??g.local.path)??o.get(g.remotes[0]?.path??""),w;if(b!==void 0&&(w=await(0,ot.getBlobText)(this.transport,e.owner,e.repo,b.blobSha,this.deps.baseURL)),g.remotes.length>1){u.push(y(g,`ambiguous conflict: local change overlaps ${g.remotes.length} remote changes (${g.remotes.map(R=>R.path).join(", ")})`,w));continue}let S=g.remotes[0],x=p(i.get(g.local.path)),A=await s.resolve({path:g.local.path,...g.local.uid!==void 0?{uid:g.local.uid}:{},...w!==void 0?{base:w}:{},...x!==void 0?{local:x}:{},...S.kind==="change"&&typeof S.content=="string"?{remote:S.content}:{}});if(A.action==="quarantine"){u.push(y(g,A.reason,w));continue}h++,d.push(g.local.path);for(let R of A.warnings??[])f.push(`merge(${g.local.path}): ${R}`);let T=S.kind==="change"?S.content:void 0;if(A.content!==T&&c.set(g.local.path,A.content),A.content!==i.get(g.local.path)){let R=(0,xo.extractAssetUid)(A.content)??g.local.uid;l.push({path:g.local.path,kind:"change",content:A.content,blobSha:await(0,vc.gitBlobSha)(A.content,this.sha1),...R!==void 0?{uid:R}:{}})}}return{mergedFiles:c,mergedWrites:l,quarantineEntries:u,resolvedQuarantineEntries:[],mergedCount:h,mergedPaths:d,warnings:f}}resolveFileModeConflicts(e,t,r,i,s){let o=[],c=[];for(let l of t){l.remotes.length>1&&c.push(`file-mode conflict on ${l.local.path} unexpectedly overlaps ${l.remotes.length} remote changes \u2014 resolving against the first`);let u=l.remotes[0],f=r.get(l.local.path);u.kind==="change"?i.push(u):s.push(u),!(l.localIsDelete||f===void 0)&&o.push({repoKey:e.repoKey,path:l.local.path,reason:`file-mode remote-wins (D18): remote ${u.kind==="change"?`version ${u.blobSha}`:"delete"} wins; this is the losing LOCAL version, preserved byte-exact`,...typeof f=="string"?{localContent:f}:{localContentBytes:f}})}return{mergedFiles:new Map,mergedWrites:[],quarantineEntries:[],resolvedQuarantineEntries:o,mergedCount:0,mergedPaths:[],warnings:c}}async applyRemoteChanges(e,t,r,i,s,o=new Map){let c=0,l=new Set,u=a(async(h,p)=>{try{return p?await gP(e,h):await e.read(h)}catch{return}},"tryRead"),f=a(async(h,p)=>{typeof p=="string"?await e.write(h,p):await BH(e,h,p)},"writeContent"),d=a(async h=>{let p=await u(h,!1);return p===void 0?!0:await(0,vc.gitBlobSha)(p,this.sha1)===o.get(h)},"cacheHitUnchanged");for(let h of r){if(h.content===void 0)continue;if(!yP(h.path)){s.push(`unsafe remote path skipped on pull-apply: ${h.path}`),l.add(h.path);continue}let p=t.get(h.path);if(p===void 0&&o.has(h.path)){if(!await d(h.path)){s.push(`pull-apply skipped: ${h.path} changed on disk mid-sync (TOCTOU) \u2014 remote change re-derives next sync`),l.add(h.path);continue}await f(h.path,h.content),c++;continue}let y=await u(h.path,typeof(p??h.content)!="string");if(!(0,Os.contentEquals)(y,p)){s.push(`pull-apply skipped: ${h.path} changed on disk mid-sync (TOCTOU) \u2014 remote change re-derives next sync`),l.add(h.path);continue}await f(h.path,h.content),c++}for(let h of i){if(!yP(h.path)){s.push(`unsafe remote path skipped on pull-delete: ${h.path}`),l.add(h.path);continue}let p=t.get(h.path);if(p===void 0&&o.has(h.path)){if(!await d(h.path)){s.push(`pull-delete skipped: ${h.path} changed on disk mid-sync (TOCTOU) \u2014 delete-vs-modify re-derives next sync`),l.add(h.path);continue}await e.delete(h.path),c++;continue}if(p!==void 0){let y=await u(h.path,typeof p!="string");if(y!==void 0&&!(0,Os.contentEquals)(y,p)){s.push(`pull-delete skipped: ${h.path} changed on disk mid-sync (TOCTOU) \u2014 delete-vs-modify re-derives next sync`),l.add(h.path);continue}await e.delete(h.path),c++}}return{pulledCount:c,pinnedPaths:l}}async advanceWatermark(e,t,r,i,s,o,c,l,u,f=new Set){let d=(await(0,ot.getTree)(this.transport,e.owner,e.repo,r,this.deps.baseURL)).filter(p=>u.treeFilter(p)&&!f.has(p.path)),h=qH(await this.buildWatermarkFiles(e,d,i,s,o,l,u),o,c);await this.deps.watermarkStore.set(e.repoKey,{lastSyncedSha:t,rootTreeSha:r,files:h,...c.size>0?{pinnedPaths:[...c]}:{},...u.fileMode?{spaceKind:"file"}:{}})}async tryMountBaseBootstrap(e,t,r,i,s){let o=this.deps.mountBaseStore,c=null;if(o!==void 0)try{c=await o.get(e.repoKey)}catch{return null}let l=!1;if(c===null&&this.deps.localBaseShaProvider!==void 0)try{let b=await this.deps.localBaseShaProvider(e);typeof b=="string"&&b.length>0&&(c=b,l=!0)}catch{}if(c===null||t.startsWith(c))return null;let u=300,f=null;try{let b=t;for(let w=0;w<u;w++){let S=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,b,this.deps.baseURL);if(S.sha===c||S.sha.startsWith(c)){f=S;break}if(S.parents.length===0)break;b=S.parents[0]}}catch{return null}if(f===null)return null;let d;try{d=(await(0,ot.getTree)(this.transport,e.owner,e.repo,f.treeSha,this.deps.baseURL)).filter(b=>(0,Os.isSyncablePath)(b.path))}catch{return null}let h;try{let b=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,t,this.deps.baseURL);h=uT((await(0,ot.getTree)(this.transport,e.owner,e.repo,b.treeSha,this.deps.baseURL)).filter(w=>(0,Os.isSyncablePath)(w.path)))}catch{return null}let p=d.filter(b=>!r.has(b.path)&&h.get(b.path)===b.blobSha);if(p.length>0){let b=p.slice(0,3).map(w=>w.path).join(", ")+(p.length>3?", \u2026":"");return i.push(`first-sync (asset mode): base-tree\u2286working-tree sanity guard fired \u2014 ${p.length} base file(s) absent from the working tree but UNCHANGED on remote head (${b}); the verified-ancestor base may not match the working tree's derivation commit (out-of-band submodule manipulation) \u2192 routing to merge/quarantine instead of inferring a silent deletion (#3610)`),{kind:"settled",outcome:s("full-conflict",{detail:`first-sync: base-tree\u2286working-tree sanity guard \u2014 ${p.length} base file(s) absent from the working tree are unchanged on remote head (${b}); refusing to infer a silent deletion from a base that may not match the derivation commit \u2014 divergence must go through merge/quarantine (A2/A3), never a silent delete (#3610)`})}}let y=d.map(b=>({path:b.path,blobSha:b.blobSha})),g={lastSyncedSha:f.sha,rootTreeSha:f.treeSha,files:y};if(l&&o!==void 0)try{await o.set(e.repoKey,f.sha)}catch{}return i.push(l?`first-sync (asset mode): BACKFILLED the 3-way base from the locally checked-out commit ${f.sha} (no recorded mount base) \u2014 remote head ${t} advanced since; local edits 3-way merge against it instead of false-conflicting (#3590)`:`first-sync (asset mode): reconciling against the recorded mount base ${f.sha} \u2014 remote head ${t} advanced since mount; local edits 3-way merge against it instead of false-conflicting (#3590)`),{kind:"additive-base",base:g}}async bootstrapWatermark(e,t,r,i){let s=await(0,ot.getHeadSha)(this.transport,e.owner,e.repo,e.branch,this.deps.baseURL),o=await this.tryMountBaseBootstrap(e,s,t,r,i);if(o!==null)return o;let c=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,s,this.deps.baseURL),l=(await(0,ot.getTree)(this.transport,e.owner,e.repo,c.treeSha,this.deps.baseURL)).filter(h=>(0,Os.isSyncablePath)(h.path)),u=[],f;for(let h of l){let p=t.get(h.path);if(p===void 0||await(0,vc.gitBlobSha)(p,this.sha1)!==h.blobSha){f===void 0&&(f=h.path);continue}let y=typeof p=="string"?(0,xo.extractAssetUid)(p):void 0;u.push({path:h.path,blobSha:h.blobSha,...y?{uid:y}:{}})}let d={lastSyncedSha:s,rootTreeSha:c.treeSha,files:u};return f!==void 0?this.deps.mergeLayer===void 0?{kind:"settled",outcome:i("full-conflict",{detail:`first-sync: no watermark and local content diverges from remote head at ${f} \u2014 A2/A3 scope`})}:(r.push(`first-sync (asset mode): no 3-way merge base and local diverges from remote head (first at ${f}) \u2014 reconciling ZERO-LOSS against ${u.length} byte-identical file(s) as a synthetic base: remote-only files pull, local-only files push, overlapping divergences route to the merge/quarantine layer (both versions preserved), never a silent overwrite or delete`),{kind:"additive-base",base:d}):t.size===l.length?(await this.deps.watermarkStore.set(e.repoKey,d),r.push(`watermark bootstrapped from head ${s} (local tree identical to remote)`),{kind:"settled",outcome:i("synced")}):(r.push(`first-sync (asset mode): local tree (${t.size} files) is a pure superset of remote head ${s} (${l.length} files) \u2014 ${t.size-l.length} local-only addition(s) derive as pushable adds (#3565)`),{kind:"additive-base",base:d})}async collectRemoteChanges(e,t,r,i,s=new Set,o=[],c=new Set){let l=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,r,this.deps.baseURL),u=await(0,ot.getTree)(this.transport,e.owner,e.repo,l.treeSha,this.deps.baseURL);if(i.fileMode)for(let g of u)i.syncable(g.path)&&!i.treeFilter(g)&&!c.has(g.path)&&(c.add(g.path),o.push(`skipped oversized REMOTE file ${g.path} (${g.size??"?"} bytes over cap) \u2014 excluded from sync symmetrically (Phase C size cap)`));let f=u.filter(g=>i.treeFilter(g)&&!s.has(g.path)),d=t.files.filter(g=>!c.has(g.path)&&!s.has(g.path)),{changed:h,deleted:p}=bP(d,f),y=[];for(let g of h){if(i.fileMode){let w=await(0,ot.getBlobBytes)(this.transport,e.owner,e.repo,g.blobSha,this.deps.baseURL);y.push({path:g.path,kind:"change",blobSha:g.blobSha,content:w});continue}let b=await(0,ot.getBlobText)(this.transport,e.owner,e.repo,g.blobSha,this.deps.baseURL);y.push({path:g.path,kind:"change",blobSha:g.blobSha,content:b,uid:(0,xo.extractAssetUid)(b)})}for(let g of p)y.push({path:g.path,kind:"delete",uid:g.uid});return{changes:y,headTreeByPath:uT(u)}}matchLocalVsRemote(e,t,r,i,s,o=new Set,c){let l=new Set,u=[],f=new Map;for(let g of i)g.kind==="change"&&g.uid!==void 0&&f.set(g.uid,(f.get(g.uid)??0)+1);let d=new Set(o);for(let[g,b]of f)b>1&&d.add(g);let h=new Map,p=new Map;for(let g of i){if(g.uid!==void 0&&!d.has(g.uid)){let b=h.get(g.uid)??[];b.push(g),h.set(g.uid,b)}p.set(g.path,g)}for(let g of e){let b=new Set;if(g.uid!==void 0&&!d.has(g.uid))for(let A of h.get(g.uid)??[])A.kind==="change"&&A.path!==g.path&&(c?.has(g.path)===!0||g.basePath!==void 0&&c?.has(g.basePath)===!0)||b.add(A);let w=p.get(g.path);if(w!==void 0&&b.add(w),g.basePath!==void 0){let A=p.get(g.basePath);A!==void 0&&b.add(A)}let S=[],x=!1;for(let A of b){if(x=t.has(g.path)&&!r.has(g.path),x&&A.kind==="delete"){l.add(A);continue}if(!x&&A.kind==="change"&&A.path===g.path&&A.blobSha===g.blobSha){l.add(A),s.add(g.path);continue}if(A.kind==="delete"&&g.basePath!==void 0&&A.path===g.basePath){let T=p.get(g.path);if(T!==void 0&&T.kind==="change"&&T.blobSha===g.blobSha){l.add(A);continue}}S.push(A),l.add(A)}S.length>0&&(u.push({local:g,localIsDelete:x,remotes:S,desc:`${g.uid!==void 0&&!d.has(g.uid)?g.uid:g.path} (local ${x?"delete":"change"} vs remote ${S[0].kind} at ${S[0].path})`}),s.add(g.path))}let y=i.filter(g=>!l.has(g));return{conflicts:u,applyWrites:y.filter(g=>g.kind==="change"),applyDeletes:y.filter(g=>g.kind==="delete")}}async checkRaceWindow(e,t,r,i,s,o,c,l){try{let u=await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,i,this.deps.baseURL),f=(await(0,ot.getTree)(this.transport,e.owner,e.repo,u.treeSha,this.deps.baseURL)).filter(l.treeFilter),d=r===t.lastSyncedSha?t.files:(await(0,ot.getTree)(this.transport,e.owner,e.repo,(await(0,ot.getCommitInfo)(this.transport,e.owner,e.repo,r,this.deps.baseURL)).treeSha,this.deps.baseURL)).filter(l.treeFilter),{changed:h,deleted:p}=bP(d,f);for(let y of h)s.has(y.path)&&c.push(`race-window: concurrent commit ${i} changed ${y.path} between conflict check (head ${r}) and push \u2014 local version won; previous version recoverable from git history`),o.has(y.path)&&c.push(`race-window: concurrent commit ${i} changed ${y.path} which this push DELETED \u2014 the delete won; the concurrent version is recoverable from git history`);for(let y of p)s.has(y.path)&&c.push(`race-window: concurrent commit ${i} deleted ${y.path}; push re-created it`)}catch(u){let f=this.deps.redact??(d=>d);c.push(`race-window check failed: ${f(ha(u))}`)}}async buildWatermarkFiles(e,t,r,i,s,o,c){if(c.fileMode)return t.map(f=>({path:f.path,blobSha:f.blobSha}));let l=new Map;for(let f of i)f.kind==="change"&&f.blobSha!==void 0&&l.set(f.blobSha,f.uid);for(let[f,d]of r){let h=o?.get(f)??await(0,vc.gitBlobSha)(d,this.sha1);l.set(h,typeof d=="string"?(0,xo.extractAssetUid)(d):void 0)}for(let f of s.files)l.has(f.blobSha)||l.set(f.blobSha,f.uid);let u=[];for(let f of t){let d;if(l.has(f.blobSha))d=l.get(f.blobSha);else{let h=await(0,ot.getBlobText)(this.transport,e.owner,e.repo,f.blobSha,this.deps.baseURL);d=(0,xo.extractAssetUid)(h)}u.push({path:f.path,blobSha:f.blobSha,...d?{uid:d}:{}})}return u}};Zn.SyncEngine=fT});var vP=v(fd=>{"use strict";Object.defineProperty(fd,"__esModule",{value:!0});fd.QuarantineResolver=void 0;fd.backupPathFor=SP;var GH=fy(),Ey=ad(),ld=su(),ud=py(),WH=gy(),Ps="\0absent",dT=class{static{a(this,"QuarantineResolver")}constructor(e){this.deps=e}async listOpenConflicts(e){let t=[];for(let r of e)t.push(...await this.listRepoConflicts(r));return t}async listRepoConflicts(e){if(e.spaceKind==="file")return[];let t=await this.deps.watermarkStore.get(e.repoKey),r=t?.pinnedPaths??[];if(r.length===0)return[];if(this.deps.outbox!==void 0){let p=await this.deps.outbox.listForRepo(e.repoKey);if(p.length>0){let y=new Set(p.map(g=>g.path));if(r=r.filter(g=>!y.has(g)),r.length===0)return[]}}let i=new Map;for(let p of t?.files??[])i.set(p.path,p.blobSha);let s=this.deps.conflictCache!==void 0,o=await this.cachedRecordsFor(e,r),c=r.some(p=>!o.has(p)),l=new Map,u=!0;if(c)if(s)try{l=await this.remoteTreeShas(e)}catch{u=!1}else l=await this.remoteTreeShas(e);let f=this.deps.localFilesFor(e),d=new Set(await f.list()),h=[];for(let p of r){let y=o.get(p),g,b;if(y!==void 0)b=y.remoteContent!==void 0?await(0,ld.gitBlobSha)(y.remoteContent,this.deps.sha1):Ps,g=y.baseContent!==void 0?await(0,ld.gitBlobSha)(y.baseContent,this.deps.sha1):i.get(p)??Ps;else{if(!u)continue;b=l.get(p)??Ps,g=i.get(p)??Ps}let w=Ps,S;if(d.has(p)&&(S=await f.read(p),w=await(0,ld.gitBlobSha)(S,this.deps.sha1)),!(w!==b&&w!==g&&b!==g))continue;let A=(S!==void 0?(0,ud.extractAssetUid)(S):void 0)??y?.uid;h.push({repoKey:e.repoKey,path:p,...A!==void 0?{uid:A}:{},hasLocal:w!==Ps,hasRemote:b!==Ps})}return h}async cachedRecordsFor(e,t){let r=new Map,i=this.deps.conflictCache;if(i===void 0)return r;for(let s of t){let o=await i.get(e.repoKey,s);o!==null&&r.set(s,o)}return r}async detectDuplicateUids(e){let t=new Map;for(let i of e){let s=this.deps.localFilesFor(i);for(let o of await s.list()){if(!o.endsWith(".md"))continue;let c;try{c=await s.read(o)}catch{continue}let l=(0,ud.extractAssetUid)(c);l!==void 0&&t.set(l,(t.get(l)??0)+1)}}let r=0;for(let i of t.values())i>1&&r++;return r}async loadConflict(e,t){let r=this.deps.localFilesFor(e),s=new Set(await r.list()).has(t)?await r.read(t):void 0,o=await this.deps.conflictCache?.get(e.repoKey,t)??null,c,l;if(o!==null)c=o.remoteContent,l=o.baseContent;else{let d=(await this.remoteTreeShas(e)).get(t);c=d!==void 0?await this.blobText(e,d):void 0;let p=((await this.deps.watermarkStore.get(e.repoKey))?.files??[]).find(y=>y.path===t)?.blobSha;if(p!==void 0)try{l=await this.blobText(e,p)}catch{l=void 0}}let u=(s!==void 0?(0,ud.extractAssetUid)(s):void 0)??(c!==void 0?(0,ud.extractAssetUid)(c):void 0)??o?.uid;return{repoKey:e.repoKey,path:t,...u!==void 0?{uid:u}:{},hasLocal:s!==void 0,hasRemote:c!==void 0,...l!==void 0?{base:l}:{},...s!==void 0?{local:s}:{},...c!==void 0?{remote:c}:{}}}async resolve(e,t,r){let i=this.deps.localFilesFor(e),o=new Set(await i.list()).has(t)?await i.read(t):void 0,c=this.deps.outbox!==void 0,{remote:l,remoteSha:u}=c?await this.remoteForResolve(e,t):await this.liveRemoteForResolve(e,t),f=this.chosenContent(r,o,l),d;r.take!=="local"&&o!==void 0&&o!==f&&(d=SP(t),await i.write(d,o)),f===void 0?await i.delete(t):await i.write(t,f);let p=f===void 0&&l===void 0||f===l;if(c&&this.deps.outbox!==void 0&&!p&&f!==void 0)return await this.deps.outbox.enqueue({repoKey:e.repoKey,path:t,chosenContent:f,resolvedTo:r.take==="merged"?"merged":"local",baseRemoteSha:u===Ps?WH.OUTBOX_REMOTE_ABSENT:u,resolvedAt:""}),{repoKey:e.repoKey,path:t,resolvedTo:r.take,awaitingPush:!0,...d!==void 0?{discardedLocalBackupPath:d}:{}};let y;return p||(y=await this.commitChoice(e,t,f)),await this.snapWatermark(e,t,f),this.deps.quarantine?.markResolved!==void 0&&await this.deps.quarantine.markResolved(e.repoKey,t),{repoKey:e.repoKey,path:t,resolvedTo:r.take,...y!==void 0?{pushedSha:y}:{},...d!==void 0?{discardedLocalBackupPath:d}:{}}}async remoteForResolve(e,t){let r=await this.deps.conflictCache?.get(e.repoKey,t)??null;if(r!==null){let i=r.remoteContent,s=i!==void 0?await(0,ld.gitBlobSha)(i,this.deps.sha1):Ps;return{remote:i,remoteSha:s}}return this.liveRemoteForResolve(e,t)}async liveRemoteForResolve(e,t){let i=(await this.remoteTreeShas(e)).get(t);return{remote:i!==void 0?await this.blobText(e,i):void 0,remoteSha:i??Ps}}chosenContent(e,t,r){switch(e.take){case"local":if(t===void 0)throw new Error("resolve: cannot keep local \u2014 no local version exists on disk");return t;case"remote":return r;case"merged":return e.content}}async commitChoice(e,t,r){let i=this.deps.commitMessage?.(e,t)??`chore(exosync): resolve conflict for ${t}`;if(r===void 0)throw new Error(`resolve: cannot push an empty resolution for ${t}`);return(0,GH.restCreateCommit)(this.deps.transport,{owner:e.owner,repo:e.repo,branch:e.branch,files:new Map([[t,r]]),message:i,...this.deps.baseURL!==void 0?{baseURL:this.deps.baseURL}:{},...this.deps.redact!==void 0?{redact:this.deps.redact}:{}})}async snapWatermark(e,t,r){let i=await this.deps.watermarkStore.get(e.repoKey);if(i===null)return;let s=(i.pinnedPaths??[]).filter(c=>c!==t),o=i.files;if(r===void 0)o=o.filter(c=>c.path!==t);else{let c=await(0,ld.gitBlobSha)(r,this.deps.sha1),l=(0,ud.extractAssetUid)(r),u={path:t,blobSha:c,...l!==void 0?{uid:l}:{}},f=o.findIndex(d=>d.path===t);o=f>=0?o.map((d,h)=>h===f?u:d):[...o,u]}await this.deps.watermarkStore.set(e.repoKey,{...i,files:o,...s.length>0?{pinnedPaths:s}:{pinnedPaths:void 0}})}async remoteTreeShas(e){let t=await(0,Ey.getHeadSha)(this.deps.transport,e.owner,e.repo,e.branch,this.deps.baseURL),r=await(0,Ey.getCommitInfo)(this.deps.transport,e.owner,e.repo,t,this.deps.baseURL),i=await(0,Ey.getTree)(this.deps.transport,e.owner,e.repo,r.treeSha,this.deps.baseURL),s=new Map;for(let o of i)s.set(o.path,o.blobSha);return s}async blobText(e,t){return(0,Ey.getBlobText)(this.deps.transport,e.owner,e.repo,t,this.deps.baseURL)}};fd.QuarantineResolver=dT;function SP(n){return`${n}.conflict.local.txt`}a(SP,"backupPathFor")});var EP=v(ou=>{"use strict";Object.defineProperty(ou,"__esModule",{value:!0});ou.FileLocalManifestStore=ou.LOCAL_MANIFEST_STORE_FILENAME=void 0;ou.LOCAL_MANIFEST_STORE_FILENAME="exosync-localmanifest.local.json";function zH(n){if(n===null||typeof n!="object")return!1;let e=n;return e.version===1&&typeof e.lastFullRehashMs=="number"&&e.files!==null&&typeof e.files=="object"}a(zH,"isLocalManifestRecord");var hT=class{static{a(this,"FileLocalManifestStore")}constructor(e){this.io=e,this.writeChain=Promise.resolve()}async get(e){let r=(await this.readRepos())[e];return zH(r)?r:null}async set(e,t){let r=this.writeChain.then(async()=>{let i=await this.readRepos();i[e]=t;let s={version:1,repos:i};await this.io.writeAtomic(JSON.stringify(s))});return this.writeChain=r.catch(()=>{}),r}async readRepos(){try{let e=await this.io.read();if(e===null)return{};let t=JSON.parse(e);if(t===null||typeof t!="object")return{};let r=t.repos;return r===null||typeof r!="object"?{}:{...r}}catch{return{}}}};ou.FileLocalManifestStore=hT});var gT=v(mT=>{"use strict";Object.defineProperty(mT,"__esModule",{value:!0});mT.diff3=HH;function TP(n,e){let t=n.length,r=e.length,i=Array.from({length:t+1},()=>new Int32Array(r+1));for(let l=t-1;l>=0;l--)for(let u=r-1;u>=0;u--)i[l][u]=n[l]===e[u]?i[l+1][u+1]+1:Math.max(i[l+1][u],i[l][u+1]);let s=new Map,o=0,c=0;for(;o<t&&c<r;)n[o]===e[c]?(s.set(o,c),o++,c++):i[o+1][c]>=i[o][c+1]?o++:c++;return s}a(TP,"lcsMatch");function pT(n,e){if(n.length!==e.length)return!1;for(let t=0;t<n.length;t++)if(n[t]!==e[t])return!1;return!0}a(pT,"sliceEq");function HH(n,e,t){let r=TP(n,e),i=TP(n,t),s=[],o=0,c=0,l=0;for(;;){let u=o;for(;u<n.length&&!(r.has(u)&&i.has(u));)u++;let f=u<n.length?r.get(u):e.length,d=u<n.length?i.get(u):t.length,h=n.slice(o,u),p=e.slice(c,f),y=t.slice(l,d),g=!pT(p,h),b=!pT(y,h);if(!g&&!b)s.push(...h);else if(!g)s.push(...y);else if(!b)s.push(...p);else if(pT(p,y))s.push(...p);else return{ok:!1,conflict:{base:h,local:p,remote:y}};if(u>=n.length)break;s.push(n[u]),o=u+1,c=f+1,l=d+1}return{ok:!0,merged:s}}a(HH,"diff3")});var xP=v(pd=>{"use strict";Object.defineProperty(pd,"__esModule",{value:!0});pd.StructuredMerger=void 0;pd.splitSections=Ty;var AP=gT(),KH=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/,dd="exo__Instance_class";function hd(n){if(n===null||typeof n!="object")return!0;if(Array.isArray(n))return n.every(hd);let e=Object.getPrototypeOf(n);return e!==Object.prototype&&e!==null?!1:Object.values(n).every(hd)}a(hd,"isPlainValue");function pa(n,e){if(n===e)return!0;if(n===null||e===null||n===void 0||e===void 0||typeof n!="object"||typeof e!="object"||Array.isArray(n)!==Array.isArray(e))return!1;if(Array.isArray(n)&&Array.isArray(e))return n.length!==e.length?!1:n.every((s,o)=>pa(s,e[o]));let t=n,r=e,i=Object.keys(t);return i.length!==Object.keys(r).length?!1:i.every(s=>pa(t[s],r[s]))}a(pa,"deepEqual");function Ec(n){return typeof n=="string"?`s:${n}`:`j:${JSON.stringify(n)}`}a(Ec,"setKey");function ui(n){return n==null?[]:Array.isArray(n)?n:[n]}a(ui,"toElements");function YH(n,e,t){let r=new Set(ui(n).map(Ec)),i=ui(e),s=ui(t),o=new Set(i.map(Ec)),c=new Set(s.map(Ec)),l=a(d=>o.has(d)&&c.has(d)||o.has(d)&&!r.has(d)||c.has(d)&&!r.has(d),"keep"),u=[],f=new Set;for(let d of[...i,...s]){let h=Ec(d);f.has(h)||!l(h)||(f.add(h),u.push(d))}return u}a(YH,"mergeSet");function QH(n,e,t){let r=[],i=[],s=new Set;for(let c of[...Object.keys(n),...Object.keys(e),...Object.keys(t)])s.has(c)||(s.add(c),i.push(c));let o={};for(let c of i){let l=n[c],u=e[c],f=t[c];if(!hd(l)||!hd(u)||!hd(f))return{ok:!1,reason:`frontmatter key "${c}" contains a non-plain value (Date?) \u2014 the codec must round-trip scalars as strings (CORE_SCHEMA contract)`};if(Array.isArray(l)||Array.isArray(u)||Array.isArray(f)){if(!(c in e)&&!(c in t))continue;let d=YH(l,u,f),h=new Set(ui(l).map(Ec)),p=ui(u).some(g=>!h.has(Ec(g))),y=ui(f).some(g=>!h.has(Ec(g)));p&&y&&!pa(ui(u),ui(f))&&r.push(`both sides added values to multi-valued key "${c}" \u2014 union kept (D20)`),d.length>0&&(o[c]=d);continue}if(pa(u,f)){u!==void 0&&(o[c]=u);continue}if(pa(u,l)){f!==void 0&&(o[c]=f);continue}if(pa(f,l)){u!==void 0&&(o[c]=u);continue}return{ok:!1,reason:`frontmatter key "${c}" changed differently on both sides`}}return{ok:!0,value:o,warnings:r}}a(QH,"mergeFrontmatter");var XH=/^(```|~~~)/,JH=/^#{1,6}\s/;function Ty(n){let e=n.split(`
309
309
  `),t=[],r=null,i="",s=!1,o=a(()=>{r!==null&&t.push({heading:i,text:r.join(`
310
310
  `)})},"flush");for(let c of e){if(XH.test(c.trimStart())&&(s=!s),!s&&JH.test(c)){o(),r=[c],i=c.trim();continue}r===null&&(r=[],i=""),r.push(c)}return o(),t}a(Ty,"splitSections");function yT(n){return n.split(/\n{2,}/)}a(yT,"splitParagraphs");function ZH(n){return n.join(`
311
311
 
@@ -620,7 +620,7 @@ Duplicate bindings (${n.duplicates.length}) \u2014 uid claimed by >1 test (warni
620
620
  Skipped floor check for ${n.unknownPriority} requirement(s) with unparseable priority (fail-open).`),n.clean?e==="hard"&&!n.rampReady?console.error(`
621
621
  FAIL (hard gate): ramp not ready \u2014 ${n.p0Orphans} P0 requirement(s) unbound`+(n.p0Total===0?" (no P0 requirements found)":"")+"."):console.log(`
622
622
  OK: no hard findings (dangling tags + binding-class floor are clean).`):console.error(`
623
- FAIL: ${n.dangling.length} dangling + ${n.floorViolations.length} floor violation(s) + ${n.activeViolations.length} active-requirement invariant violation(s) + ${n.danglingEvidence.length} dangling evidence link(s).`)}a(Vse,"renderText");function qse(n,e,t){return!n.clean||t&&n.orphans.length>0||e==="hard"&&!n.rampReady}a(qse,"isHardFail");function aj(){return new xe("audit").description("Audit requirement\u2194test traceability: orphans, dangling @req tags, duplicate bindings, binding-class floor, coverage, P0 ramp-readiness").requiredOption("--reqs <path>","Directory tree containing req__Requirement assets (a vault or a reqs assetspace clone)").option("--tests <path>","Test-corpus root scanned for @req:<uid> tags",".").option("--output <type>","Response format: text|json","text").option("--strict","Also exit 1 on orphan requirements",!1).option("--gate <mode>","Gate mode: soft (warn only on hard findings) | hard (also block when the P0 checklist is not ramp-ready)","soft").action(async n=>{let e=n.output??"text";he.setFormat(e);let t=n.gate==="hard"?"hard":"soft";try{let r=(0,Da.resolve)(n.reqs);if(!(0,La.existsSync)(r)||!(0,La.statSync)(r).isDirectory())throw new He(r);let i=(0,Da.resolve)(n.tests??".");if(!(0,La.existsSync)(i)||!(0,La.statSync)(i).isDirectory())throw new He(i);let[s,o]=await Promise.all([Mse(r),$se(i)]),c=Use(s,o);e==="json"?console.log(JSON.stringify({...c,gate:t},null,2)):Vse(c,t),qse(c,t,n.strict===!0)&&(process.exitCode=1)}catch(r){he.handle(r)}})}a(aj,"requirementsAuditCommand");function cj(){let n=new xe("requirements").description("Requirements-management tooling (RFC 0003): traceability checker");return n.addCommand(aj()),n}a(cj,"requirementsCommand");function ub(n){let e=new xe;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"16.149.3"),e.addCommand(s4()),e.addCommand(m4()),e.addCommand(iM()),e.addCommand(cM()),e.addCommand(RM()),e.addCommand(lM()),e.addCommand(PM()),e.addCommand(UM()),e.addCommand(VM()),e.addCommand(r4()),e.addCommand(P4()),e.addCommand(K4()),e.addCommand(Y4()),e.addCommand(J4()),e.addCommand(Z4()),e.addCommand(nj()),e.addCommand(j4()),e.addCommand(W4()),e.addCommand(cj()),e}a(ub,"createProgram");ub().parse();0&&(module.exports={createProgram});
623
+ FAIL: ${n.dangling.length} dangling + ${n.floorViolations.length} floor violation(s) + ${n.activeViolations.length} active-requirement invariant violation(s) + ${n.danglingEvidence.length} dangling evidence link(s).`)}a(Vse,"renderText");function qse(n,e,t){return!n.clean||t&&n.orphans.length>0||e==="hard"&&!n.rampReady}a(qse,"isHardFail");function aj(){return new xe("audit").description("Audit requirement\u2194test traceability: orphans, dangling @req tags, duplicate bindings, binding-class floor, coverage, P0 ramp-readiness").requiredOption("--reqs <path>","Directory tree containing req__Requirement assets (a vault or a reqs assetspace clone)").option("--tests <path>","Test-corpus root scanned for @req:<uid> tags",".").option("--output <type>","Response format: text|json","text").option("--strict","Also exit 1 on orphan requirements",!1).option("--gate <mode>","Gate mode: soft (warn only on hard findings) | hard (also block when the P0 checklist is not ramp-ready)","soft").action(async n=>{let e=n.output??"text";he.setFormat(e);let t=n.gate==="hard"?"hard":"soft";try{let r=(0,Da.resolve)(n.reqs);if(!(0,La.existsSync)(r)||!(0,La.statSync)(r).isDirectory())throw new He(r);let i=(0,Da.resolve)(n.tests??".");if(!(0,La.existsSync)(i)||!(0,La.statSync)(i).isDirectory())throw new He(i);let[s,o]=await Promise.all([Mse(r),$se(i)]),c=Use(s,o);e==="json"?console.log(JSON.stringify({...c,gate:t},null,2)):Vse(c,t),qse(c,t,n.strict===!0)&&(process.exitCode=1)}catch(r){he.handle(r)}})}a(aj,"requirementsAuditCommand");function cj(){let n=new xe("requirements").description("Requirements-management tooling (RFC 0003): traceability checker");return n.addCommand(aj()),n}a(cj,"requirementsCommand");function ub(n){let e=new xe;return e.name("exocortex").description("CLI tool for Exocortex knowledge management system").version(n??"16.149.5"),e.addCommand(s4()),e.addCommand(m4()),e.addCommand(iM()),e.addCommand(cM()),e.addCommand(RM()),e.addCommand(lM()),e.addCommand(PM()),e.addCommand(UM()),e.addCommand(VM()),e.addCommand(r4()),e.addCommand(P4()),e.addCommand(K4()),e.addCommand(Y4()),e.addCommand(J4()),e.addCommand(Z4()),e.addCommand(nj()),e.addCommand(j4()),e.addCommand(W4()),e.addCommand(cj()),e}a(ub,"createProgram");ub().parse();0&&(module.exports={createProgram});
624
624
  /*! Bundled license information:
625
625
 
626
626
  reflect-metadata/Reflect.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitelev/exocortex-cli",
3
- "version": "16.149.3",
3
+ "version": "16.149.5",
4
4
  "description": "CLI tool for Exocortex knowledge management system - SPARQL queries, task management, and more",
5
5
  "main": "dist/index.js",
6
6
  "bin": {