@inkeep/open-knowledge 0.50.0-beta.12 → 0.50.0-beta.13

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 (36) hide show
  1. package/dist/{acp-harness-probe-e-SewXXi.mjs → acp-harness-probe-BRzTGQPW.mjs} +2 -2
  2. package/dist/cli.mjs +6 -6
  3. package/dist/constants-COPfVWti.mjs +2 -0
  4. package/dist/index.d.mts +17 -17
  5. package/dist/index.mjs +1 -1
  6. package/dist/init-BvRbf5jC.mjs +1 -0
  7. package/dist/{init-C3TNy6IA.mjs → init-pIJddeyG.mjs} +3 -3
  8. package/dist/{launch-json-removal-BVtKDFyi.mjs → launch-json-removal-CnIk3WE-.mjs} +2 -2
  9. package/dist/loader-B2V-uVIv.mjs +1 -0
  10. package/dist/{loader-97Nspw6q.mjs → loader-BeDgboJk.mjs} +2 -2
  11. package/dist/{open-browser-Bb773NFh.mjs → open-browser-OsCLGa-m.mjs} +2 -2
  12. package/dist/preview-B9gSOFlh.mjs +1 -0
  13. package/dist/{preview-Dqh79pLV.mjs → preview-hjy0gI0i.mjs} +2 -2
  14. package/dist/{repair-launch-json-ChORzYOl.mjs → repair-launch-json-BocgwEI5.mjs} +2 -2
  15. package/dist/{repair-mcp-configs-DqtCFQdR.mjs → repair-mcp-configs-BrBkt_hT.mjs} +2 -2
  16. package/dist/repair-skills-BMZ7VleT.mjs +1 -0
  17. package/dist/{repair-skills-C_mOgSqu.mjs → repair-skills-C-3CmI5S.mjs} +2 -2
  18. package/dist/{skill-teardown-DT0sY6o-.mjs → skill-teardown-CH2C4nmj.mjs} +2 -2
  19. package/dist/src-BxyYlbvx.mjs +1 -0
  20. package/dist/{src-DTvTnYPi.mjs → src-DFKvCzqo.mjs} +2 -2
  21. package/dist/{src-YVZCV4Ux.mjs → src-Dg0jHVcz.mjs} +1 -1
  22. package/dist/{src-DJhexTh5.mjs → src-y0X27yQX.mjs} +2 -2
  23. package/dist/start-C9fu-159.mjs +1 -0
  24. package/dist/{start-RRmOhFPJ.mjs → start-Dtt8oak3.mjs} +4 -4
  25. package/dist/{ui-BBDdhHyy.mjs → ui-B35mCBIN.mjs} +3 -3
  26. package/dist/ui-D9Vnv2aH.mjs +1 -0
  27. package/dist/{write-project-skill-__SzqfoP.mjs → write-project-skill-BP9EVRr-.mjs} +2 -2
  28. package/package.json +4 -4
  29. package/dist/constants-COvJwYpX.mjs +0 -2
  30. package/dist/init-CN1ckCOc.mjs +0 -1
  31. package/dist/loader-BFlcv3EZ.mjs +0 -1
  32. package/dist/preview-DY343j5c.mjs +0 -1
  33. package/dist/repair-skills-qAm1agyb.mjs +0 -1
  34. package/dist/src-GnIWqWdP.mjs +0 -1
  35. package/dist/start-BRgtKVYb.mjs +0 -1
  36. package/dist/ui-BEwSKtfp.mjs +0 -1
@@ -2026,7 +2026,7 @@ $$`,guidance:"Write LaTeX in `$…$` (inline) or `$$…$$` (block) — OK auto-p
2026
2026
  native-divergence-injected
2027
2027
  `,`utf-8`),o&&E!==void 0){let r=null;try{V(te)&&(r=H(te,`utf-8`))}catch(e){r=null,j7.warn({err:e,documentName:i},`[persistence] L3 disk-read failed; divergence check skipped for this store`)}if(r!==null&&fi(r)!==fi(E)){let a=r;console.warn(JSON.stringify({event:`agent-write-content-divergence`,"doc.name":i,outcome:`reverted`,diskBytes:a.length,baseBytes:E.length,candidateBytes:S.length})),ve(n,i,S,a);let o=e?.getLossRing?.(),s={baselineFullMd:a,report:e=>{try{let t=$x(e);if(t.length===0)return;o?.record({event:Cb,docName:i,writerId:Vx.id,direction:`b`,site:de,lostLen:t.reduce((e,t)=>e+t.length,0),digest:Xn(t.join(`
2028
2028
  `))})}catch(e){j7.warn({documentName:i,err:e},`[persistence] divergence-realign loss detection failed`)}}};try{n.transact(()=>{x(n,a,void 0,void 0,void 0,s)},MR)}catch(e){throw t.recordStoreFailure(i,P7(e)),C.delete(i),e}t.setReconciledBase(i,a),t.recordStoreDivergence(i),C.delete(i);return}}e?.isRecentlyRemoved?.(i)&&(Gb(),console.warn(JSON.stringify({event:`persistence-store-removed-doc`,"doc.name":i})));let ne=`${te}.tmp.${crypto.randomUUID()}`;try{if(process.env.NODE_ENV===`test`&&process.env.OK_TEST_STORE_FAULT===i){let e=Error(`OK_TEST_STORE_FAULT: simulated disk failure for ${i}`);throw e.code=`ENOSPC`,e}await Ho(ne,S,`utf-8`),await ss(ne,te),tz(te,rz(S)),t.clearStoreFailure(i),tx();try{d?.(i,f,S,E??null)}catch(e){j7.warn({err:e,documentName:i},`[persistence] onDiskFlush callback failed for ${i}`)}}catch(e){try{Jo(ne)}catch{}throw C.delete(i),t.recordStoreFailure(i,P7(e)),j7.error({err:e,documentName:i},`[persistence] Failed to save ${i}`),e}j7.info({filePath:te,bytes:S.length},`[persistence] Wrote ${te} (${S.length} bytes)`),t.setReconciledBase(i,S),b.add(i),y.delete(i),C.delete(i);try{await s?.recordDurableStore(i,S)}catch(e){j7.warn({err:e,documentName:i},`[derived-index] durable-store projection failed; disk write remains authoritative`)}Po({"persistence.bytes":S.length}),A()}).finally(()=>{l!==void 0&&t.finishInFlightFlush(i,l),xe?.record((Date.now()-o)/1e3)})}function Te({document:e,documentName:n,lastTransactionOrigin:r}){re.set(n,{branch:t.getActiveBranch(),document:e,lastTransactionOrigin:r})}async function Ee(e=`within-branch`){return ne?(S=S===`discard-stale`||e===`discard-stale`?`discard-stale`:`within-branch`,ne):(ne=(async()=>{let n=e;for(;;){let e=[...re.entries()];if(re.clear(),n!==`discard-stale`){for(let[n,r]of e)if(r.branch===t.getActiveBranch())try{await we({document:r.document,documentName:n,lastTransactionOrigin:r.lastTransactionOrigin})}catch(e){let t=process.env.OK_TELEMETRY_VERBOSE===`1`,r=``;try{r=String(e?.message??``)}catch{r=``}let i=Xn(r),a;try{a=RDe(e)}catch(e){let r=String(e?.message??``);console.warn(JSON.stringify({event:`deferred-store-classifier-failed`,"doc.name":n,classifyErrorHash:Xn(r),errorMessageHash:i,...t?{classifyErrorMessage:r}:{},timestamp:new Date().toISOString()})),a=`unknown`}koe(),console.warn(JSON.stringify({event:`deferred-store-failed`,"doc.name":n,errorClass:a,errorMessageHash:i,...t?{errorMessage:r}:{},timestamp:new Date().toISOString()})),j7.error({err:e,documentName:n},`[persistence] Deferred store failed for ${n}`)}}let r=S;if(S=null,re.size===0&&r===null)break;n=r??`within-branch`}})().finally(()=>{ne=null}),ne)}let De={async onLoadDocument({document:n,documentName:i,context:a}){if(b.delete(i),pS(i))return;if(mS(i)){nDe(n,i,h);return}if(hS(i)){CK(n,i,_);return}if(gS(i)||_S(i)){MDe(n,i,v);return}Ce();let o=Date.now();return Vo(`persistence.onLoadDocument`,{attributes:{"doc.name":i}},async()=>{j7.info({documentName:i,connections:n.getConnectionsCount?.()??`?`},`[persistence] onLoadDocument called for ${i} (connections: ${n.getConnectionsCount?.()??`?`})`);let a=uN(i,r);if(!V(a))return;let o=a;try{let e=U(a);if(!dN(e,r)){j7.warn({path:a,canonical:e},`[persistence] symlink-escape on load: ${a} → ${e}, refusing`);return}o=e}catch(e){if(Ns(e)===`ELOOP`){j7.warn({path:a},`[persistence] Symlink cycle on load: ${a}, refusing`);return}}let s=au(o).size;if(s>524288)throw j7.warn({documentName:i,fileSize:s,limit:Fr},`[persistence] Document exceeds open byte limit; refusing to load`),new IDe(i,s);let c=H(a,`utf-8`),l=n.getXmlFragment(`default`);j7.info({documentName:i,fragmentLength:l.length},`[persistence] onLoadDocument ${i}: fragment.length=${l.length} before update`),l.length===0?(n.transact(()=>{NR(n,c,e?.resolveEmbed,i,e?.resolveSize),n.getMap(`lifecycle`).set(ba,crypto.randomUUID())},MR),j7.info({filePath:a,children:l.length},`[persistence] Loaded ${a} into Y.Doc (${l.length} children)`),l.observeDeep(()=>{j7.info({documentName:i,fragmentLength:l.length},`[persistence] MUTATION on ${i}: fragment.length=${l.length}`)})):j7.info({documentName:i,children:l.length},`[persistence] Skipped load for ${i} — fragment already has ${l.length} children`),t.setReconciledBase(i,c)}).finally(()=>{N?.record((Date.now()-o)/1e3)})},async onStoreDocument({document:e,documentName:n,lastTransactionOrigin:r,lastContext:i}){if(!pS(n)){if(mS(n)){let t=await iDe(e,n,r,h);if(t===`persisted`||t===`reconciled`)try{f?.(n)}catch(e){j7.warn({err:e,documentName:n},`[persistence] onConfigPersisted callback failed`)}return}if(hS(n)){if(await EK(e,n,r,_)===`persisted`){let e=M7(r,c);if(e&&e.id!==Ux.id&&!e.id.startsWith(`agent-`)){let t=hK(n);t&&(Tj(t.docKey,e.id,e.name,e.id,t.subject),A())}}return}if(gS(n)||_S(n)){await NDe(e,n,r,v);return}if(t.isBatchInProgress()){Te({document:e,documentName:n,lastTransactionOrigin:r});return}return we({document:e,documentName:n,lastTransactionOrigin:r})}}};async function Oe(){k&&await k}async function ke(){if(k){await k;return}Nj()!==0&&(k=ie().finally(()=>{k=null,te&&(te=!1,A())}),await k)}function Ae(){return{branchDeferred:re.size,quiescenceDeferred:C.size}}async function je(e,n){if(!bS(n)){if(t.isBatchInProgress()){Te({document:e,documentName:n,lastTransactionOrigin:null});return}return we({document:e,documentName:n,lastTransactionOrigin:null})}}return{extension:De,durabilityState:t,flushDeferredStores:Ee,flushPendingGitCommit:j,flushContributors:ke,waitForPendingCommits:Oe,getQueueDepths:Ae,forceStore:je,configPersistenceCtx:h,managedArtifactCtx:_}}const I7=I(`persistence-staleness`);var L7=class extends Error{constructor(e){super(e),this.name=`StructuralDiskReadError`}};function BDe(e){let t=e.graceMs??3e5,n=e.sweepIntervalMs??6e4,r=e.now??Date.now,{getBase:i,isBatchActive:a,peekInFlight:o}=e,s=e.msSinceLastUserTx??vC,c=new Map,l=!1,u=null;function d(e){return N7(e)}function f(e){return e===void 0?void 0:fi(e)}function p(e,t,n,r){return t===void 0?e!==``:e===t?r!==void 0&&Za(r,n):!0}async function m(){if(l||a())return;let n=r(),u=0,m=0,h=0,g=0,_=new Set;for(let[n,v]of e.getLoadedDocuments()){if(l)return;if(_.add(n),bS(n)||jS(v)!==null||o(n)!==void 0)continue;u++;let y=v.getText(`source`).toString(),b=i(n);if(b!==void 0&&y===b){c.delete(n);continue}let x=d(y),S=f(b);if(!p(x,S,y,b)){c.delete(n);continue}m++;let C=r(),w=s(v,C);if(w!==null&&w<t)continue;let T=c.get(n);if(T&&T.fingerprint===x&&(T.declined||C-T.atMs<t))continue;let E=T?.fingerprint!==x;E&&qae();let ee=!E&&T?T.firstDetectedAtMs:C,D=C-ee,O=null,k=!1;try{let t=e.readDiskBytes(n);S===void 0?t!==null&&(O=`disk-file-never-loaded`):t===null?O=`disk-file-missing`:fi(t)!==S&&(O=`disk-diverged-from-base`)}catch(e){e instanceof L7?(O=`disk-read-refused`,I7.error({err:e,docName:n},`[persistence-staleness] disk read refused; standing down until content changes`)):(O=`disk-read-failed`,k=!0,I7.warn({err:e,docName:n},`[persistence-staleness] disk read failed; standing down`))}if(O!==null){g++,Yae(),c.set(n,{fingerprint:x,atMs:C,firstDetectedAtMs:ee,declined:!k}),I7.warn({docName:n,ageMs:w,staleForMs:D,candidateBytes:x.length,baseBytes:b?.length??0,action:`stood-down`,reason:O},`[persistence-staleness] Unflushed edits detected for ${n} but disk state is unverified or unreconciled; not overwriting`);continue}I7.warn({docName:n,ageMs:w,staleForMs:D,candidateBytes:x.length,baseBytes:b?.length??0,action:`forced-store`},`[persistence-staleness] Doc ${n} has unpersisted edits past the grace window with no pending store; forcing a store`),c.set(n,{fingerprint:x,atMs:C,firstDetectedAtMs:ee,declined:!1}),Jae(),h++;try{await e.forceStore(v,n)}catch(e){I7.error({err:e,docName:n,staleForMs:D},`[persistence-staleness] Forced store failed for ${n}; will retry`);continue}if(l||a())return;let te=v.getText(`source`).toString(),ne=i(n),re=d(te);p(re,f(ne),te,ne)&&re===x?(c.set(n,{fingerprint:x,atMs:C,firstDetectedAtMs:ee,declined:!0}),I7.info({docName:n},`[persistence-staleness] Store completed without clearing divergence for ${n}; suppressing until content changes`)):c.delete(n)}for(let e of c.keys())_.has(e)||c.delete(e);let v={scanned:u,divergent:m,forced:h,stoodDown:g,elapsedMs:r()-n};m>0||h>0||g>0?I7.info(v,`[persistence-staleness] sweep complete`):I7.debug(v,`[persistence-staleness] sweep complete`)}function h(){return u||(u=m().finally(()=>{u=null}),u)}let g=setInterval(()=>{h().catch(e=>{I7.error({err:e},`[persistence-staleness] sweep failed`)})},n);return g.unref?.(),{sweep:h,dispose:()=>(l=!0,clearInterval(g),u??Promise.resolve())}}async function VDe(e){try{let t=Cs({baseDir:e,timeout:{block:3e3}});return{name:(await t.raw(`config`,`--get`,`user.name`)).trim()||null,email:(await t.raw(`config`,`--get`,`user.email`)).trim()||null}}catch{return{name:null,email:null}}}async function R7(e){let t=IO(e),n=B(t,`principal.json`),{name:r,email:i}=await VDe(e);if(V(n)){let e;try{e=JSON.parse(H(n,`utf-8`))}catch{e={}}let t=typeof e.id==`string`&&e.id.startsWith(`principal-`)?e.id:`principal-${Tu()}`,a=typeof e.created_at==`string`?e.created_at:new Date().toISOString(),o=t.slice(10,18),s={id:t,display_name:r?vh(r):typeof e.display_name==`string`?e.display_name:`Local User`,display_email:i?vh(i):typeof e.display_email==`string`?e.display_email:`principal-${o}@openknowledge.local`,source:r||i?`git-config`:`synthesized`,created_at:a};return su(n,JSON.stringify(s,null,2),`utf-8`),s}Jl(t,{recursive:!0});let a=`principal-${Tu()}`,o=a.slice(10,18),s={id:a,display_name:r?vh(r):`Local User`,display_email:i?vh(i):`principal-${o}@openknowledge.local`,source:r||i?`git-config`:`synthesized`,created_at:new Date().toISOString()};return su(n,JSON.stringify(s,null,2),`utf-8`),s}var HDe=class{map=new Map;capacity;onEviction;onSizeChange;onMutate;now;constructor(e=1e4,t={}){this.capacity=Math.max(0,Math.floor(e)),this.onEviction=t.onEviction,this.onSizeChange=t.onSizeChange,this.onMutate=t.onMutate,this.now=t.now??Date.now}setRenamed(e,t){this.put(e,{kind:`renamed`,newDocName:t,addedAt:this.now()})}setDeleted(e){this.put(e,{kind:`deleted`,addedAt:this.now()})}get(e){let t=this.map.get(e);if(t!==void 0)return this.map.delete(e),this.map.set(e,t),t}has(e){return this.map.has(e)}peek(e){return this.map.get(e)}delete(e){this.map.delete(e)&&(this.onSizeChange?.(this.map.size),this.onMutate?.())}get size(){return this.map.size}entries(){return[...this.map.entries()]}restore(e,t){this.put(e,t)}put(e,t){if(this.capacity===0){this.onSizeChange?.(0);return}for(this.map.delete(e),this.map.set(e,t);this.map.size>this.capacity;){let e=this.map.keys().next().value;if(e===void 0)break;this.map.delete(e),this.onEviction?.()}this.onSizeChange?.(this.map.size),this.onMutate?.()}};function z7(e,t){let n=e.resolveFilePath(t);return n!==null&&e.fileExists(n)}async function UDe(e,t){try{if(vS(e))return;let n=t.recentlyRemovedDocs.get(e);if(n===void 0)return;if(n.kind===`deleted`){if(z7(t,e)){t.recentlyRemovedDocs.delete(e);return}throw yx(),Po({"auth.reason":`doc-deleted`}),new EQ(`doc-deleted`,`removed-doc rejection for deleted ${e}`)}let r=new Set([e]),i=n.newDocName;for(;;){if(r.has(i)){Noe(),console.warn(JSON.stringify({event:`removal-redirect-chain-cycle`,documentName:e,target:i}));return}r.add(i);let n=t.recentlyRemovedDocs.get(i);if(n===void 0)throw vx(),Po({"auth.reason":`rename-redirect`}),new EQ(`rename-redirect`,`removed-doc redirect for ${e} → ${i}`,i);if(n.kind===`deleted`)throw z7(t,i)?(t.recentlyRemovedDocs.delete(i),vx(),Po({"auth.reason":`rename-redirect`}),new EQ(`rename-redirect`,`removed-doc redirect for ${e} → ${i}`,i)):(yx(),Po({"auth.reason":`doc-deleted`}),new EQ(`doc-deleted`,`removed-doc rejection for deleted ${e}`));i=n.newDocName}}catch(t){if(t instanceof EQ)throw t;Moe(),console.warn(JSON.stringify({event:`removal-redirect-extension-error`,documentName:e,message:t instanceof Error?t.message:String(t)}))}}const B7=I(`removed-docs-journal`);function V7(e){return R(IO(e),`removed-docs.json`)}function WDe(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.docName!=`string`||t.docName.length===0||typeof t.addedAt!=`number`?!1:t.kind===`deleted`?!0:t.kind===`renamed`?typeof t.newDocName==`string`:!1}function GDe(e){let t=V7(e);if(!V(t))return[];try{let e=JSON.parse(H(t,`utf-8`));if(e.version!==1||!Array.isArray(e.entries))return B7.warn({path:t},`[removed-docs-journal] unrecognized journal shape — ignoring`),[];let n=[];for(let t of e.entries){if(!WDe(t))continue;let{docName:e,...r}=t;n.push([e,r])}return n}catch(e){return B7.warn({path:t,err:e},`[removed-docs-journal] failed to read journal — ignoring`),[]}}function H7(e,t){let n=V7(e),r={version:1,entries:t.map(([e,t])=>({docName:e,...t}))};$o(L(n),{recursive:!0});let i=`${n}.tmp`;cs(i,JSON.stringify(r),`utf-8`),Ko(i,n)}const U7=I(`server-observers`);function W7(e){let t=new Map,n=new Map;return{async afterLoadDocument({documentName:r,document:i}){if(pS(r)||mS(r)||gS(r)||_S(r)||t.has(r))return;let a=i,o=a.getXmlFragment(`default`),s=a.getText(`source`),c=()=>{try{let n=Fw({doc:a,xmlFragment:o,ytext:s,mdManager:e.mdManager,schema:e.schema,docName:r,shadow:e.shadowRef?()=>e.shadowRef?.current:void 0,getBranch:e.getCurrentBranch?()=>e.getCurrentBranch?.()??`main`:void 0,contentRoot:e.contentRoot,resolveEmbed:e.resolveEmbed,resolveSize:e.resolveSize,deferGuardEnabled:e.deferGuardEnabled,lossDetectorEnabled:e.lossDetectorEnabled,fixedPointBackstopEnabled:e.fixedPointBackstopEnabled,preDrainEnabled:e.preDrainEnabled,lossRing:e.lossRing});return t.set(r,n),!0}catch(e){return U7.error({docName:r,err:e},`[ServerObserverExtension] Failed to attach observers for '${r}'`),nx(`a`),nx(`b`),!1}};if(!c()){let e=setTimeout(()=>{n.delete(r),!t.has(r)&&(U7.warn({docName:r},`[ServerObserverExtension] Retrying observer attachment for '${r}'`),c())},5e3);n.set(r,e)}},async afterUnloadDocument({documentName:e}){let r=n.get(e);r&&(clearTimeout(r),n.delete(e));let i=t.get(e);i&&(i(),t.delete(e))},async onDestroy(){for(let e of n.values())clearTimeout(e);n.clear();for(let[e,n]of t.entries())try{n()}catch(t){U7.error({docName:e,err:t},`[ServerObserverExtension] Cleanup failed for '${e}'`)}t.clear()}}}const G7=`state.json`;function K7(e){return e.lockDir,V(e.shadowRepoDir)?`adopt`:`fresh`}function q7(e){return B(e,G7)}function KDe(e,t){return e===t||e===0&&t===1}var J7=class extends Error{kind;path;constructor(e){super(e.message),this.name=`StateManifestError`,this.kind=e.kind,this.path=e.path}};function qDe(e){if(!e||typeof e!=`object`)return!1;let t=e;if(typeof t.stateSchemaVersion!=`number`||typeof t.createdAt!=`string`||!t.createdBy||typeof t.createdBy!=`object`)return!1;let n=t.createdBy;return!(typeof n.runtimeVersion!=`string`||n.protocolVersion!==void 0&&typeof n.protocolVersion!=`number`)}function Y7(e){let t=q7(e);if(!V(t))return{status:`absent`};let n;try{n=H(t,`utf-8`)}catch(e){throw new J7({kind:`corrupt`,path:t,message:`Failed to read state manifest at ${t}: ${e instanceof Error?e.message:String(e)}`})}let r;try{r=JSON.parse(n)}catch(e){throw new J7({kind:`corrupt`,path:t,message:`State manifest at ${t} is not valid JSON: ${e instanceof Error?e.message:String(e)}`})}if(!qDe(r))throw new J7({kind:`corrupt`,path:t,message:`State manifest at ${t} has invalid shape (missing or wrong-typed required fields)`});return{status:`present`,manifest:r}}function X7(e,t){let n=q7(e);Jl(L(n),{recursive:!0}),su(n,JSON.stringify(t,null,2),{encoding:`utf-8`,mode:384})}function Z7(e){let t=I(`state-manifest`),n=e.currentStateSchemaVersion??1,r=e.currentRuntimeVersion??js,i=e.currentProtocolVersion??1,a=(e.now??(()=>new Date))().toISOString(),o=q7(e.lockDir),s=Y7(e.lockDir);if(s.status===`present`){let c=s.manifest;if(!KDe(c.stateSchemaVersion,n))throw new J7({kind:`incompatible`,path:o,message:`State manifest at ${o} declares stateSchemaVersion=${c.stateSchemaVersion} but this binary supports ${n}. Refusing to boot — on-the-fly migration is out of scope. (Manifest written by runtime ${c.createdBy.runtimeVersion}, protocol ${c.createdBy.protocolVersion}.)`});try{let t={...c,lastWriteBy:{runtimeVersion:r,protocolVersion:i,at:a}};return X7(e.lockDir,t),t}catch(e){return t.warn({err:e},`[state-manifest] failed to update lastWriteBy — proceeding`),c}}if(K7({lockDir:e.lockDir,shadowRepoDir:e.shadowRepoDir})===`fresh`){let s={stateSchemaVersion:n,createdAt:a,createdBy:{runtimeVersion:r,protocolVersion:i}};return X7(e.lockDir,s),t.info({path:o,stateSchemaVersion:n},`[state-manifest] fresh project — wrote manifest`),s}let c={stateSchemaVersion:0,createdAt:a,createdBy:{runtimeVersion:r,protocolVersion:i,adoptedAt:a}};return X7(e.lockDir,c),t.warn({path:o,runtimeVersion:r},`[state-manifest] adopting pre-versioned project — wrote schema-0 manifest. Future binaries with STATE_SCHEMA_VERSION>=2 may refuse if they cannot read schema-0 state.`),c}function JDe(e,t){return e===`auth`&&t===`403`?`auth-403`:e===`auth`&&t===`401`?`auth-401`:e===`auth`&&t===`scope-mismatch`?`auth-scope-mismatch`:e===`auth`&&t===`no-credential`?`auth-no-credential`:e===`semantic`&&t===`protected-branch`?`semantic-protected-branch`:null}function YDe(e){return e.git?.toString()??e.message??``}function Q7(e,t){return t.some(t=>t.test(e))}const XDe={"no-credential":`No GitHub credential available — reconnect to resume syncing`,401:`Authentication failed — token may be expired`,403:`Access denied (403)`,"scope-mismatch":`GitHub token missing required scopes`,"ssh-auth":`SSH authentication failed — check your SSH key or host-key trust`,"unknown-auth":`Authentication failed`},ZDe=[/non-fast-forward/i,/rejected.*non-fast-forward/i,/would overwrite.*commits/i,/\[rejected\]/,/fetch first/i,/updates were rejected/i],$7=[/protected branch/i,/refusing to allow/i,/at least \d+ approving review/i,/required status check/i,/branch policy/i,/GH001/i,/GH002/i,/GH003/i,/GH004/i,/push declined due to repository rule/i,/cannot push to a protected branch/i],QDe=[/\bmerge conflict\b/i,/automatic merge failed/i,/CONFLICT \(/,/\bconflict\b.*\bmerge\b/i,/(?:^|\n)CONFLICTS:\s/i],$De=[/lfs.*quota/i,/exceeded.*bandwidth/i,/lfs storage/i],eOe=[/file.*too large/i,/exceeded.*file size/i,/push file size limit/i],tOe=[/pre-receive hook/i,/remote:.*rejected/i,/hook declined/i],nOe=[/secret.*detected/i,/push.*secret/i,/secret scanning/i,/leaking.*credentials/i,/token.*detected/i],rOe=[/\.git\/index\.lock/i,/another git process/i,/unable to create.*\.lock/i],iOe=[/dirty.*working tree/i,/working tree.*not clean/i,/untracked.*files.*would be overwritten/i,/local changes.*would be overwritten/i,/uncommitted changes/i,/changes.*not staged/i,/please.*commit.*changes/i,/please.*stash/i,/commit your changes or stash/i],aOe=[/no space left on device/i,/disk quota exceeded/i,/ENOSPC/i],oOe=[/could not resolve host/i,/name.*resolution/i,/connection.*timed out/i,/operation timed out/i,/connection refused/i,/network.*unreachable/i,/ssl.*handshake/i,/unable to connect/i,/getaddrinfo/i,/econnrefused/i,/enotfound/i,/etimedout/i,/ehostunreach/i],sOe=[/\bHTTP[\s/]*5[0-9]{2}\b/i,/\bstatus:?\s*5[0-9]{2}\b/i,/\berror\s*5[0-9]{2}\b/i,/\bresponse.*?\b5[0-9]{2}\b/i],cOe=[/\bHTTP[\s/]*429\b/i,/\bstatus:?\s*429\b/i,/\berror\s*429\b/i,/rate.?limit/i,/too many requests/i];function e9(e){let t=lOe(e);return{...t,userFacingCode:JDe(t.class,t.subclass)}}function lOe(e){let t=e instanceof Error?e:Error(String(e)),n=YDe(t),r=`${t.message}\n${n}`.toLowerCase();if(Q7(r,rOe))return{class:`local`,subclass:`index-lock`,retryable:!0,message:`Git index locked by another process`,rawStderr:n};if(Q7(r,iOe))return{class:`local`,subclass:`dirty-tree`,retryable:!0,message:`Working tree has uncommitted changes`,rawStderr:n};if(Q7(r,aOe))return{class:`local`,subclass:`disk-full`,retryable:!0,message:`Disk full or quota exceeded`,rawStderr:n};let i=Ta(t);return i.kind===`auth`?i.subclass===`403`&&Q7(r,$7)?{class:`semantic`,subclass:`protected-branch`,retryable:!1,message:`Push rejected — branch is protected`,rawStderr:n}:{class:`auth`,subclass:i.subclass,retryable:!1,message:XDe[i.subclass],rawStderr:n}:Q7(r,$7)?{class:`semantic`,subclass:`protected-branch`,retryable:!1,message:`Push rejected — branch is protected`,rawStderr:n}:Q7(r,ZDe)?{class:`semantic`,subclass:`non-fast-forward`,retryable:!1,message:`Push rejected — remote has diverged (non-fast-forward)`,rawStderr:n}:Q7(r,QDe)?{class:`semantic`,subclass:`merge-conflict`,retryable:!1,message:`Merge conflict — manual resolution required`,rawStderr:n}:Q7(r,$De)?{class:`structural`,subclass:`lfs-quota`,retryable:!1,message:`Git LFS quota exceeded`,rawStderr:n}:Q7(r,eOe)?{class:`structural`,subclass:`large-file`,retryable:!1,message:`File exceeds size limit`,rawStderr:n}:Q7(r,nOe)?{class:`structural`,subclass:`secret-detected`,retryable:!1,message:`Push blocked — secret or credential detected in content`,rawStderr:n}:Q7(r,tOe)?{class:`structural`,subclass:`pre-receive-hook`,retryable:!1,message:`Push rejected by server pre-receive hook`,rawStderr:n}:Q7(r,cOe)?{class:`network`,subclass:`429`,retryable:!0,message:`Rate limited — too many requests`,rawStderr:n}:Q7(r,sOe)?{class:`network`,subclass:`5xx`,retryable:!0,message:`Server error (5xx)`,rawStderr:n}:Q7(r,oOe)?/timed? out/i.test(r)?{class:`network`,subclass:`timeout`,retryable:!0,message:`Connection timed out`,rawStderr:n}:/refused/i.test(r)||/econnrefused/i.test(r)?{class:`network`,subclass:`connection-refused`,retryable:!0,message:`Connection refused`,rawStderr:n}:/resolve.*host/i.test(r)||/enotfound/i.test(r)||/getaddrinfo/i.test(r)?{class:`network`,subclass:`dns`,retryable:!0,message:`DNS resolution failed`,rawStderr:n}:{class:`network`,subclass:`unknown-network`,retryable:!0,message:`Network error`,rawStderr:n}:{class:`local`,subclass:`unknown-local`,retryable:!0,message:t.message||`Unknown git error`,rawStderr:n}}function uOe(e,t={}){let n=t.ttlMs??6e4,r=t.now??Date.now,i=new Map;return{get(t){if(!e)return null;let a=r(),o=i.get(t);if(o&&o.expiresAt>a)return o.token==null?null:{token:o.token,host:t};let s=e(t),c=s.available&&s.token?s.token:null;return i.set(t,{token:c,expiresAt:a+n}),c==null?null:{token:c,host:t}},invalidate(){i.clear()}}}const t9=I(`github-permissions`);function dOe(e){return e===`github.com`?`https://api.github.com`:`https://${e}/api/v3`}function fOe(e){let t={"User-Agent":`open-knowledge-server`,Accept:`application/vnd.github+json`};return e&&(t.Authorization=`Bearer ${e}`),t}function pOe(e){if(typeof e!=`object`||!e)return null;let t=e.permissions;if(typeof t!=`object`||!t)return null;let n=t.push;return typeof n==`boolean`?n:null}async function mOe(e,t){switch(e.status){case 200:{let t;try{t=await e.json()}catch(e){return t9.warn({err:e},`[permissions] probe got 200 with unparseable JSON body`),{kind:`unknown`,error:`malformed-response`}}let n=pOe(t);return n===null?(t9.warn({bodyKeys:typeof t==`object`&&t?Object.keys(t):[]},`[permissions] probe got 200 without permissions.push field`),{kind:`unknown`,error:`malformed-response`}):n?{kind:`allowed`}:{kind:`denied`,reason:`no-collaborator`}}case 401:return{kind:`unknown`,error:`token-invalid`};case 403:return e.headers.get(`x-ratelimit-remaining`)===`0`?{kind:`unknown`,error:`rate-limit`}:{kind:`unknown`,error:`token-invalid`};case 429:return{kind:`unknown`,error:`rate-limit`};case 404:return t?{kind:`denied`,reason:`private-no-access`}:{kind:`denied`,reason:`repo-not-found`};default:return t9.warn({httpStatus:e.status},`[permissions] probe got unexpected HTTP status`),{kind:`unknown`,error:`malformed-response`}}}async function hOe(e,t,n){let r=t(e);if(r.available&&r.token)return{token:r.token,source:`gh`};if(n)try{let t=await n.get(e);if(t?.token)return{token:t.token,source:`token-store`}}catch(t){t9.warn({err:t,host:e},`[permissions] tokenStore.get threw; falling through to anonymous`)}return{token:void 0,source:`anonymous`}}async function gOe(e){let{owner:t,repo:n,host:r=`github.com`,transport:i=`https`,detectGh:a=()=>({available:!1}),tokenStore:o,_fetchFn:s=fetch,_timeoutMs:c=5e3}=e,{token:l,source:u}=await hOe(r,a,o);if(u===`anonymous`)return i===`ssh`||i===`git`?(t9.info({host:r,transport:i},`[permissions] no credential resolved for ssh/git origin — abstaining (push auths with SSH keys, not tokens)`),{kind:`unknown`,error:`ssh-unverified`}):(t9.info({host:r},`[permissions] no credential resolved — denying push (read-only)`),{kind:`denied`,reason:`not-authenticated`});let d=`${dOe(r)}/repos/${encodeURIComponent(t)}/${encodeURIComponent(n)}`;t9.info({host:r,tokenSource:u,tokenLen:l===void 0?0:l.length},`[permissions] probe starting`);let f=new AbortController,p=setTimeout(()=>f.abort(),c);try{let e=await s(d,{signal:f.signal,headers:fOe(l)}),t=await mOe(e,l!==void 0);return t9.info({host:r,tokenSource:u,httpStatus:e.status,kind:t.kind,reason:t.kind===`denied`?t.reason:void 0,error:t.kind===`unknown`?t.error:void 0},`[permissions] probe classified`),t}catch(e){return f.signal.aborted?(t9.warn({host:r,timeoutMs:c},`[permissions] probe timed out`),{kind:`unknown`,error:`timeout`}):(t9.warn({err:e,host:r},`[permissions] probe failed`),{kind:`unknown`,error:`network`})}finally{clearTimeout(p)}}async function _Oe(e){let t=performance.now(),n=await gOe(e);return xOe(n,performance.now()-t),n}function vOe(e){return{outcome:e.kind,denied_reason:e.kind===`denied`?e.reason:`none`,error_class:e.kind===`unknown`?e.error:`none`}}let n9=null;function yOe(){return n9||=ds().createCounter(`ok.permissions.probe.outcome_total`,{description:`Push-permission probe outcomes. Bounded labels: outcome ∈ {allowed,denied,unknown}; denied_reason ∈ {no-collaborator,private-no-access,repo-not-found,not-authenticated,none}; error_class ∈ {network,timeout,rate-limit,token-invalid,malformed-response,ssh-unverified,none}.`}),n9}let r9=null;function bOe(){return r9||=ds().createHistogram(`ok.permissions.probe.duration_ms`,{description:`Push-permission probe wall-clock duration.`,unit:`ms`}),r9}function xOe(e,t){let n=vOe(e);yOe().add(1,n),bOe().record(t,{outcome:n.outcome})}function i9(e,t,n=Date.now()){if(!e)return 0;let r=new Date(e).getTime();if(Number.isNaN(r))return 0;let i=r+t*1e3;return Math.max(0,i-n)}function SOe(e,t){return t===`anonymous`?Math.max(180,e):e}const a9=I(`sync-engine`),o9=/^[0-9a-f]{40}$/i,COe=ju(Sl);function wOe(e){let{exitCode:t,stderr:n}=e,r=n??``;return t===128||/^fatal:/m.test(r)&&/not possible to fast-forward/i.test(r)?`divergence`:/^error:/m.test(r)&&/would be overwritten by merge/i.test(r)?`overlay-overlap`:`unknown`}function TOe(e){return e.kind===`allowed`?{checkStatus:`allowed`}:e.kind===`denied`?{checkStatus:`denied`,deniedReason:e.reason}:{checkStatus:`unknown`,unknownError:e.error}}function s9(e,t){return e===t?!0:e===null||t===null||e.checkStatus!==t.checkStatus?!1:e.checkStatus===`denied`&&t.checkStatus===`denied`?e.deniedReason===t.deniedReason:e.checkStatus===`unknown`&&t.checkStatus===`unknown`?e.unknownError===t.unknownError:!0}function c9(e){let t=e*1e3,n=t*.15*(2*Math.random()-1);return Math.round(t+n)}function l9(e){let t=Fu(e);if(t.kind!==`repository`)return!1;let n=t.repository.readHead();return n.kind===`branch`?t.repository.readRef(n.ref).kind===`absent`:!1}function EOe(e){return e>=8?3600*1e3:e>=5?900*1e3:e>=3?300*1e3:0}const u9=12e4;var DOe=class{state=`dormant`;projectDir;contentDir;contentFilter;contentRoot;pullIntervalSeconds;pushIntervalSeconds;mode;credentialArgs;cc1Broadcaster;onStateChange;onContentConflictsDetected;onContentConflictsResolved;setBatchInProgress;onAutoDisable;checkpointBeforeStrandedConversion;checkpointBeforeOverlayRestore;detectGh;ghTokenSource;tokenStore;checkPushPermissionFn;pushPermission=null;pushPermissionProbeInFlight=!1;authTier=`unknown`;pullTimer=null;pushTimer=null;stateSaveTimer=null;lastSyncUtc=null;lastFetchUtc=null;lastPushedSha=null;lastPullUtc=null;lastPullOutcome=null;consecutiveFailures=0;ahead=0;behind=0;conflictCount=0;pushError;pushErrorCode;pullError;pullErrorCode;pausedReason;currentBranch=`main`;pullInFlight=!1;pushInFlight=!1;hasRemote=!1;identityUnresolved=!1;statePath;conflictStore;constructor(e){this.projectDir=e.projectDir,this.contentDir=e.contentDir,this.contentFilter=e.contentFilter,this.contentRoot=e.contentRoot??``,this.pullIntervalSeconds=e.pullIntervalSeconds??30,this.pushIntervalSeconds=e.pushIntervalSeconds??60,this.mode=e.mode??(e.syncEnabled===!0?`full`:`off`),this.credentialArgs=e.credentialArgs??[],this.cc1Broadcaster=e.cc1Broadcaster??null,this.onStateChange=e.onStateChange,this.onContentConflictsDetected=e.onContentConflictsDetected,this.onContentConflictsResolved=e.onContentConflictsResolved,this.setBatchInProgress=e.setBatchInProgress,this.onAutoDisable=e.onAutoDisable,this.checkpointBeforeStrandedConversion=e.checkpointBeforeStrandedConversion,this.checkpointBeforeOverlayRestore=e.checkpointBeforeOverlayRestore,this.detectGh=e.detectGh,this.ghTokenSource=uOe(e.detectGh),this.tokenStore=e.tokenStore,this.checkPushPermissionFn=e.checkPushPermissionFn??_Oe,this.statePath=B(IO(this.projectDir),`sync-state.json`),this.conflictStore=new AQ(this.projectDir,this.currentBranch)}syncGhTokenHost(){return MF(this.projectDir)}gitHandle(e){return Es(this.projectDir,{credentialArgs:this.credentialArgs,gitIndexFile:e,ghToken:this.ghTokenSource.get(this.syncGhTokenHost())??void 0,timeoutMs:12e4})}async start(){if(this.state!==`dormant`)return;this.loadState();let e=!1;try{let t=this.gitHandle();e=(await t.git.raw(`remote`,`-v`)).trim().length>0,this.hasRemote=e;try{let e=(await t.git.raw(`rev-parse`,`--abbrev-ref`,`HEAD`)).trim();e&&e!==`HEAD`&&(this.currentBranch=e,this.conflictStore.setBranch(e))}catch{}}catch(e){a9.warn({err:e},`[sync] remote detection failed`)}if(e&&this.probePushPermissionInternal(`start`),this.mode===`off`){e&&this.transitionTo(`disabled`),a9.info({hasRemote:e,mode:this.mode},`[sync] sync not enabled — staying inactive`);return}if(!e){a9.info({},`[sync] no remote detected — staying dormant`);return}this.transitionTo(`idle`);let t=Hu(this.projectDir),n=t?R(t,`MERGE_HEAD`):null,r=n!==null&&V(n);this.conflictCount=this.conflictStore.count();let i=()=>this.conflictStore.list().filter(e=>e.variant!==`working-tree`);if(i().length>0&&!r){a9.warn({count:i().length},`[sync] persisted merge conflicts but no MERGE_HEAD — clearing stale state`);for(let e of i())this.conflictStore.removeConflict(e.file);this.conflictCount=this.conflictStore.count()}else if(i().length>0&&r)try{let e=this.gitHandle(),t=new Set(await Lb(e.git,[`diff`,`--name-only`,`--diff-filter=U`])),n=this.conflictCount;for(let e of i())t.has(e.file)||this.conflictStore.removeConflict(e.file);this.conflictCount=this.conflictStore.count(),this.conflictCount<n&&a9.info({cleared:n-this.conflictCount,remaining:this.conflictCount},`[sync] reconciled conflicts.json against git unmerged index`)}catch(e){a9.warn({err:e},`[sync] failed to reconcile conflicts with git index`)}if(r&&i().length===0){a9.warn({},`[sync] stale MERGE_HEAD detected with no tracked conflicts — aborting merge`);try{await this.gitHandle().git.raw([`merge`,`--abort`])}catch(e){a9.warn({err:e},`[sync] git merge --abort for stale MERGE_HEAD failed`)}}if(i().length>0){await this.notifyContentConflictsDetected(this.conflictStore.list().map(e=>e.file)),this.transitionTo(`conflict`),a9.warn({count:this.conflictCount},`[sync] restarted with active conflicts — sync paused`);return}let a=this.conflictStore.list().filter(e=>e.variant===`working-tree`);a.length>0&&await this.notifyContentConflictsDetected(a.map(e=>e.file)),this.mode===`follow`&&await this.refreshAuthTier();let o=i9(this.lastFetchUtc,this.currentPullIntervalSeconds()),s=i9(this.lastSyncUtc,this.pushIntervalSeconds);this.schedulePull(o>0?o:void 0),this.schedulePush(s>0?s:void 0),a9.info({branch:this.currentBranch,pullDelayMs:o,pushDelayMs:s},`[sync] started`)}stop(){this.pullTimer!==null&&(clearTimeout(this.pullTimer),this.pullTimer=null),this.pushTimer!==null&&(clearTimeout(this.pushTimer),this.pushTimer=null),this.stateSaveTimer!==null&&(clearTimeout(this.stateSaveTimer),this.stateSaveTimer=null),this.state!==`dormant`&&this.transitionTo(`dormant`)}async destroy(){this.stop(),this.saveStateNow()}async setMode(e,t=`config`){if(this.mode===e)return;let n=this.mode;if(this.mode=e,a9.info({from:n,to:e,source:t},`[sync] mode changed`),e===`off`){this.cancelScheduledCycles(),await this.drainInFlightCycles(),this.pausedReason=void 0,this.clearPushError(),this.clearPullError(),this.transitionTo(this.hasRemote?`disabled`:`dormant`),this.saveStateNow();return}if(this.hasRemote=await this.probeRemote(),this.pausedReason=void 0,this.clearPushError(),this.clearPullError(),this.consecutiveFailures=0,!this.hasRemote){this.transitionTo(`dormant`),this.saveStateNow();return}e===`follow`&&(await this.drainInFlightCycles(),this.cancelScheduledCycles(),await this.convertStrandedCommitsToOverlay()),this.transitionTo(`idle`),this.schedulePull(0),this.schedulePush(),this.saveStateNow(),this.probePushPermissionInternal(`refresh`)}async setEnabled(e){await this.setMode(e?`full`:`off`)}cancelScheduledCycles(){this.pullTimer!==null&&(clearTimeout(this.pullTimer),this.pullTimer=null),this.pushTimer!==null&&(clearTimeout(this.pushTimer),this.pushTimer=null)}async drainInFlightCycles(){let e=Date.now();for(;this.pullInFlight||this.pushInFlight;){if(Date.now()-e>3e4){a9.warn({pullInFlight:this.pullInFlight,pushInFlight:this.pushInFlight},`[sync] drain: timed out waiting for in-flight cycle`);break}await Au(50)}}async probeUnpushedCommitCount(){return!this.hasRemote||l9(this.projectDir)?0:this.unpushedCommitCount(this.gitHandle())}async unpushedCommitCount(e){try{let t=await e.git.status();if(t.tracking)return t.ahead}catch{}try{let t=(await e.git.raw([`rev-list`,`--count`,`origin/${this.currentBranch}..HEAD`])).trim(),n=Number.parseInt(t,10);return Number.isFinite(n)?n:0}catch{return 0}}async convertStrandedCommitsToOverlay(){if(!this.hasRemote||l9(this.projectDir))return;let e=this.gitHandle(),t;try{t=await this.unpushedCommitCount(e)}catch(e){a9.warn({err:e},`[sync] pull-only: could not probe stranded commits — skipping conversion`);return}if(t!==0){try{await this.checkpointBeforeStrandedConversion?.({branch:this.currentBranch,ahead:t})}catch(e){a9.warn({err:e},`[sync] pull-only: stranded-commit checkpoint failed — proceeding`)}try{let n=(await e.git.raw([`merge-base`,`HEAD`,`origin/${this.currentBranch}`])).trim();this.setBatchInProgress?.(!0);try{await ws(()=>e.git.raw([`reset`,`--mixed`,n]))}finally{this.setBatchInProgress?.(!1)}let r=await e.git.status();this.ahead=r.ahead,this.behind=r.behind,this.pausedReason=void 0,a9.info({ahead:t,behind:this.behind},`[sync] pull-only: folded stranded local commits into a working-tree overlay`)}catch(e){this.pausedReason=`diverged-local-commits`,a9.warn({err:e},`[sync] pull-only: stranded-commit conversion failed — leaving branch as-is`)}}}async notifyCredentialsChanged(){if(this.mode!==`off`&&(this.ghTokenSource.invalidate(),!(this.state!==`auth-error`&&this.pausedReason!==`auth-error`))){if(this.pausedReason=void 0,this.clearPushError(),this.clearPullError(),this.consecutiveFailures=0,this.hasRemote=await this.probeRemote(),!this.hasRemote){this.transitionTo(`dormant`),this.saveStateNow();return}this.transitionTo(`idle`),this.schedulePull(0),this.schedulePush(),this.saveStateNow(),this.probePushPermissionInternal(`refresh`)}}async trigger(e=`sync`){if(this.consecutiveFailures=0,(this.pausedReason===`dirty-tree`||this.pausedReason===`external-changes-pending`||this.pausedReason===`non-content-merge-failure`)&&(this.pausedReason=void 0,this.clearPullError()),this.probePushPermissionInternal(`refresh`),e===`pull`){await this.pullOnce();return}this.state===`dormant`||this.state===`disabled`||this.state===`conflict`||this.state===`auth-error`?a9.warn({op:e,state:this.state,mode:this.mode,hasRemote:this.hasRemote,pausedReason:this.pausedReason,conflictCount:this.conflictCount},`[sync] trigger(${e}) ignored — state=${this.state}`):a9.info({op:e,state:this.state},`[sync] trigger(${e}) running`),e===`push`?await this.runPushCycle():(await this.runPushCycle(),await this.runPullCycle())}async pullOnce(){let e=this.mode,t=await this.runOneShotPull();return a9.info({mode:e,outcome:t},`[sync] one-shot pull complete`),t}async runOneShotPull(){if(this.pullInFlight||this.pushInFlight||this.state===`conflict`||!this.hasRemote||l9(this.projectDir))return this.recordPullOutcome(`refused`);let e=this.mode,t=this.state,n=this.pausedReason;this.pullInFlight=!0;try{return this.recordPullOutcome(await this.doPullCycle())}finally{this.pullInFlight=!1,e===`off`?(this.pausedReason=n,this.transitionTo(t)):this.schedulePull()}}recordPullOutcome(e){return this.lastPullUtc=new Date().toISOString(),this.lastPullOutcome=e,this.cc1Broadcaster?.signal(`sync-status`),e}getStatus(){return{state:this.state,lastSyncUtc:this.lastSyncUtc,lastFetchUtc:this.lastFetchUtc,lastPushedSha:this.lastPushedSha,lastPullUtc:this.lastPullUtc,lastPullOutcome:this.lastPullOutcome,ahead:this.ahead,behind:this.behind,consecutiveFailures:this.consecutiveFailures,conflictCount:this.conflictCount,hasRemote:this.hasRemote,syncEnabled:this.mode!==`off`,syncMode:this.mode,identityUnresolved:this.identityUnresolved,remote:this.hasRemote?Cfe(this.projectDir):null,...this.pushError===void 0?{}:{pushError:this.pushError},...this.pushErrorCode===void 0?{}:{pushErrorCode:this.pushErrorCode},...this.pullError===void 0?{}:{pullError:this.pullError},...this.pullErrorCode===void 0?{}:{pullErrorCode:this.pullErrorCode},pausedReason:this.pausedReason,...this.pushPermission===null?{}:{pushPermission:this.pushPermission}}}async refreshPushPermission(){return this.probePushPermissionInternal(`refresh`)}async refreshIdentity(){let e=await tB(this.projectDir)===null;this.identityUnresolved!==e&&(this.identityUnresolved=e,this.cc1Broadcaster?.signal(`sync-status`))}async probePushPermissionInternal(e){if(!this.hasRemote||this.pushPermissionProbeInFlight)return null;let t=jF(this.projectDir);if(t.kind!==`ok`){let e={checkStatus:`unknown`},t=this.pushPermission;return this.pushPermission=e,s9(t,e)||this.cc1Broadcaster?.signal(`sync-status`),e}this.pushPermissionProbeInFlight=!0,a9.info({caller:e,host:t.host,hasDetectGh:this.detectGh!==void 0,hasTokenStore:this.tokenStore!==void 0&&this.tokenStore!==null},`[sync] push-permission probe dispatching`);let n;try{n=await this.checkPushPermissionFn({owner:t.owner,repo:t.repo,host:t.host,transport:t.transport,detectGh:this.detectGh,tokenStore:this.tokenStore})}catch(t){a9.warn({err:t,caller:e},`[sync] push-permission probe threw — recording unknown/network`),n={kind:`unknown`,error:`network`}}finally{this.pushPermissionProbeInFlight=!1}let r=TOe(n),i=this.pushPermission;this.pushPermission=r;let a=!1;return r.checkStatus===`denied`&&this.mode===`full`?(this.pausedReason!==`no-push-permission`||this.state!==`disabled`)&&(this.pausedReason=`no-push-permission`,this.transitionTo(`disabled`),a=!0,a9.info({reason:r.deniedReason,caller:e},`[sync] paused — no push permission on origin`)):r.checkStatus===`allowed`&&this.pausedReason===`no-push-permission`&&(this.pausedReason=void 0,this.state===`disabled`&&this.mode===`full`&&this.transitionTo(`idle`),a=!0,a9.info({caller:e,priorState:this.state},`[sync] push permission restored`)),!a&&!s9(i,r)&&this.cc1Broadcaster?.signal(`sync-status`),r}async refreshRemote(){this.hasRemote||await this.probeRemote()&&(this.hasRemote=!0,a9.info({mode:this.mode},`[sync] remote detected post-boot — re-evaluating state`),this.mode===`off`?this.transitionTo(`disabled`):(this.transitionTo(`idle`),this.schedulePull(0),this.schedulePush()))}async probeRemote(){if(!V(R(this.projectDir,`.git`)))return!1;try{return(await this.gitHandle().git.raw(`remote`,`-v`)).trim().length>0}catch(e){return a9.warn({err:e},`[sync] remote detection failed`),!1}}getConflicts(){return this.conflictStore.list()}async reconcileConflictsFromGit(){let e=this.conflictStore.list().filter(e=>e.variant!==`working-tree`);if(e.length===0)return;let t=this.conflictCount,n=Hu(this.projectDir),r=n?R(n,`MERGE_HEAD`):null;if(r!==null&&V(r))try{let n=this.gitHandle(),r=new Set(await Lb(n.git,[`diff`,`--name-only`,`--diff-filter=U`]));for(let t of e)r.has(t.file)||this.conflictStore.removeConflict(t.file);this.conflictCount=this.conflictStore.count(),this.conflictCount<t&&a9.info({cleared:t-this.conflictCount,remaining:this.conflictCount},`[sync] external resolve detected (mid-merge) — pruned resolved entries`)}catch(e){a9.warn({err:e},`[sync] reconcileConflictsFromGit: git probe failed`);return}else{a9.info({cleared:e.length},`[sync] external resolve detected (no MERGE_HEAD) — clearing merge-native conflicts`);for(let t of e)this.conflictStore.removeConflict(t.file);this.conflictCount=this.conflictStore.count()}this.conflictCount!==t&&(this.conflictCount===0&&this.state===`conflict`?(this.transitionTo(`idle`),this.pausedReason=void 0,this.schedulePull(),this.schedulePush()):this.cc1Broadcaster?.signal(`sync-status`),this.scheduleSaveState())}async resolveConflict(e,t,n){let r=this.conflictStore.list().find(t=>t.file===e)?.variant===`working-tree`;this.setBatchInProgress?.(!0);try{try{await this.conflictStore.resolveConflict(e,t,n)}catch(e){throw this.conflictCount=this.conflictStore.count(),this.scheduleSaveState(),e}r&&(a9.info({choice:t},`[sync] pull-only: conflict resolved by choice`),await this.notifyContentConflictsResolved([e])),this.conflictCount=this.conflictStore.count(),this.conflictCount===0&&this.state===`conflict`?(this.transitionTo(`idle`),this.pausedReason=void 0,this.schedulePull(),this.schedulePush()):this.cc1Broadcaster?.signal(`sync-status`),this.scheduleSaveState()}finally{this.setBatchInProgress?.(!1)}}updateCurrentBranch(e){e===null?this.state!==`dormant`&&this.state!==`disabled`&&(this.transitionTo(`disabled`),this.pausedReason=`detached-head`,this.scheduleSaveState()):this.currentBranch!==e&&(this.currentBranch=e,this.conflictStore.setBranch(e),this.state===`disabled`&&this.pausedReason===`detached-head`&&(this.pausedReason=void 0,this.transitionTo(`idle`),this.schedulePull(),this.schedulePush()))}schedulePull(e){this.pullTimer!==null&&clearTimeout(this.pullTimer);let t=e??this.effectivePullDelayMs();this.pullTimer=setTimeout(()=>{this.pullTimer=null,this.runPullCycle().catch(e=>{a9.error({err:e},`[sync] pull cycle uncaught error`)})},t)}schedulePush(e){if(this.mode!==`full`)return;this.pushTimer!==null&&clearTimeout(this.pushTimer);let t=e??c9(this.pushIntervalSeconds);this.pushTimer=setTimeout(()=>{this.pushTimer=null,this.runPushCycle().catch(e=>{a9.error({err:e},`[sync] push cycle uncaught error`)})},t)}async resolveAuthTier(){let e=this.syncGhTokenHost();if(this.ghTokenSource.get(e)!==null)return`authenticated`;if(this.tokenStore)try{if((await this.tokenStore.get(e))?.token)return`authenticated`}catch(e){a9.warn({err:e},`[sync] auth-tier token-store lookup threw — treating as anonymous`)}return`anonymous`}async refreshAuthTier(){this.authTier=await this.resolveAuthTier()}currentPullIntervalSeconds(){return this.mode===`follow`?SOe(this.pullIntervalSeconds,this.authTier===`anonymous`?`anonymous`:`authenticated`):this.pullIntervalSeconds}effectivePullDelayMs(){let e=EOe(this.consecutiveFailures);return c9(e>0?e/1e3:this.currentPullIntervalSeconds())}async runPullCycle(){if(!this.pullInFlight&&!(this.state===`dormant`||this.state===`disabled`||this.state===`auth-error`)){if(this.state===`conflict`){this.schedulePull();return}if(l9(this.projectDir)){this.schedulePull();return}this.mode===`follow`&&await this.refreshAuthTier(),this.pullInFlight=!0;try{this.recordPullOutcome(await this.doPullCycle())}finally{this.pullInFlight=!1,this.schedulePull()}}}async doPullCycle(){let e=this.gitHandle(),t;try{let n=(await e.git.raw(`rev-parse`,`--abbrev-ref`,`HEAD`)).trim();if(!n||n===`HEAD`)return this.transitionTo(`disabled`),this.pausedReason=`detached-head`,a9.warn({},`[sync] detached HEAD — pausing sync`),`refused`;t=n,this.currentBranch=t}catch(e){return this.handleError(e9(e instanceof Error?e:Error(String(e))),`pull`),`error`}this.transitionTo(`fetching`);try{await e.git.fetch(`origin`),this.lastFetchUtc=new Date().toISOString(),this.consecutiveFailures=0,this.clearPullError()}catch(e){let t=e9(e instanceof Error?e:Error(String(e)));return this.handleError(t,`pull`),`error`}try{let t=await e.git.status();this.ahead=t.ahead,this.behind=t.behind}catch{}if(this.behind>0&&this.mode!==`full`){let n=await this.doPullCycleB1(e,t);return this.scheduleSaveState(),n}if(this.behind>0&&this.conflictCount===0){this.transitionTo(`pulling`),this.setBatchInProgress?.(!0);try{await this.commitDirtyContentFilesToHead(e);let n=await this.prepareForMerge(e,t);if(!n.proceed)return`refused`;try{await e.git.merge([`origin/${t}`]),this.lastSyncUtc=new Date().toISOString(),this.behind=0,this.transitionTo(`idle`)}finally{n.needsStashPop&&await this.popPreMergeStash(e)}return this.scheduleSaveState(),`succeeded`}catch(e){let t=e9(e instanceof Error?e:Error(String(e)));return t.class===`semantic`&&t.subclass===`merge-conflict`?(await this.handleMergeConflict(),this.state===`conflict`?`conflict`:this.pullError?`error`:`succeeded`):(this.handleError(t,`pull`),`error`)}finally{this.setBatchInProgress?.(!1)}}return this.transitionTo(`idle`),this.scheduleSaveState(),this.behind===0?`up-to-date`:`conflict`}async doPullCycleB1(e,t){if(this.transitionTo(`pulling`),this.ahead>0)return this.clearPullError(),this.pausedReason=`diverged-local-commits`,this.transitionTo(`idle`),a9.warn({ahead:this.ahead,behind:this.behind},`[sync] pull-only: local history diverged — not fast-forwardable, skipping cycle`),`refused`;let n,r;try{n=(await e.git.revparse([`HEAD`])).trim();let i=await Lb(e.git,[`diff-index`,`--name-only`,`HEAD`]),a=new Set(await Lb(e.git,[`diff`,`--name-only`,`HEAD..origin/${t}`]));r=i.filter(e=>a.has(e))}catch(e){return this.handleError(e9(e instanceof Error?e:Error(String(e))),`pull`),`error`}let i=new Map;for(let e of this.conflictStore.list())e.variant===`working-tree`&&i.set(e.file,e);let a;try{a=await this.planOverlapReconciliation(e,t,n,r,i)}catch(e){return this.handleError(e9(e instanceof Error?e:Error(String(e))),`pull`),`error`}this.setBatchInProgress?.(!0);try{if(r.length>0){try{await this.checkpointBeforeOverlayRestore?.({branch:t,paths:r.length})}catch(e){a9.warn({err:e,paths:r.length},`[sync] pull-only: overlay checkpoint failed before restore — proceeding`)}try{await e.git.raw([`restore`,`--source=HEAD`,`--staged`,`--worktree`,`--`,...r])}catch(e){return a9.warn({err:e},`[sync] pull-only: failed to restore overlay before fast-forward — skipping cycle`),this.handleError(e9(e instanceof Error?e:Error(String(e))),`pull`),`error`}}let n=await this.fastForwardOnly(e,t);if(!n.ok){try{this.applyOverlayPlan(a.mineRestore,a.deletions)}catch(e){return a9.error({err:e,refusal:n.refusal},`[sync] pull-only: failed to restore overlay after fast-forward refusal`),this.handleError(e9(e instanceof Error?e:Error(String(e))),`pull`),`error`}return n.timedOut?(a9.warn({},`[sync] pull-only: fast-forward timed out — backing off`),this.handleError(e9(Error(`git merge --ff-only timed out after ${u9}ms`)),`pull`),`error`):(n.refusal===`divergence`&&(this.pausedReason=`diverged-local-commits`),this.transitionTo(`idle`),a9.warn({refusal:n.refusal,stderr:n.stderr.slice(0,200)},`[sync] pull-only: fast-forward refused — skipping cycle`),`refused`)}try{this.applyOverlayPlan(a.writes,a.deletions)}catch(e){return a9.error({err:e},`[sync] pull-only: failed to apply overlay after fast-forward`),this.handleError(e9(e instanceof Error?e:Error(String(e))),`pull`),`error`}let i=!0;for(let e of a.upserts)i=this.conflictStore.addConflict(e)&&i;for(let e of a.dissolved)i=this.conflictStore.removeConflict(e)&&i;if(this.conflictCount=this.conflictStore.count(),!i)return a9.error({},`[sync] pull-only: failed to persist conflict state after fast-forward — surfacing as error`),this.handleError(e9(Error(`failed to persist conflict state after fast-forward`)),`pull`),`error`;this.lastSyncUtc=new Date().toISOString(),this.behind=0,this.clearPullError(),this.pausedReason=void 0,this.transitionTo(`idle`),a.newConflicts.length>0&&await this.notifyContentConflictsDetected(a.newConflicts),a.dissolved.length>0&&await this.notifyContentConflictsResolved(a.dissolved),(a.newConflicts.length>0||a.dissolved.length>0)&&this.cc1Broadcaster?.signal(`sync-status`);let o=await this.countStandingOverlay(e);return a9.info({created:a.newConflicts.length,autoCombined:a.autoCombined.length,autoDissolved:a.dissolved.length,autoRestored:a.autoRestored.length,overlayStock:o},`[sync] pull-only: fast-forwarded to origin tip`),a.newConflicts.length>0?`conflict`:`succeeded`}finally{this.setBatchInProgress?.(!1)}}async fastForwardOnly(e,t){try{return await COe(`git`,[`-c`,`core.autocrlf=false`,`merge`,`--ff-only`,`origin/${t}`],{cwd:this.projectDir,env:e.env,windowsHide:!0,timeout:u9}),{ok:!0}}catch(e){let t=e,n=t.killed===!0||t.signal===`SIGTERM`,r=typeof t.code==`number`?t.code:null,i=typeof t.stderr==`string`?t.stderr:e instanceof Error?e.message:String(e);return{ok:!1,refusal:wOe({exitCode:r,stderr:i}),stderr:i,exitCode:r,timedOut:n}}}async planOverlapReconciliation(e,t,n,r,i){let a=[],o=[],s=[],c=[],l=[],u=[],d=[],f=[];for(let p of r){let r=i.get(p),m=r!==void 0;if(!V(R(this.projectDir,p))){try{await e.git.revparse([`origin/${t}:${p}`])}catch(e){if(this.classifyRefReadFailure(e)===`error`){s.push(p),a9.warn({err:e,path:p},`[sync] pull-only: unexpected error probing origin for a deleted overlay — deferring reconcile`);continue}s.push(p),m&&l.push(p);continue}if(!this.isContentConflictPath(p)){s.push(p);continue}f.push(p),m&&l.push(p);continue}let h;try{h=H(R(this.projectDir,p))}catch{continue}o.push({path:p,bytes:h});let g=h.toString(`utf-8`),_=null;try{_=await e.git.raw([`show`,`origin/${t}:${p}`])}catch(e){this.classifyRefReadFailure(e)===`error`&&a9.warn({err:e,path:p},`[sync] pull-only: unexpected error reading origin blob — keeping overlay, deferring reconcile`),_=null}if(_!==null&&_===g){m&&l.push(p);continue}if(_===null||!this.isContentConflictPath(p)){a.push({path:p,bytes:h});continue}let v=m?r.baseSha:await this.gitBlobSha(e,`${n}:${p}`),y=yi(v?await this.gitBlobContent(e,v):``,g,_);if(y.clean){a.push({path:p,bytes:Buffer.from(y.merged,`utf-8`)}),d.push(p),m&&l.push(p);continue}a.push({path:p,bytes:h});let b=await this.gitBlobSha(e,`origin/${t}:${p}`);if(b===void 0){a9.warn({path:p},`[sync] pull-only: could not pin origin blob for a collision — keeping overlay, deferring`);continue}c.push({file:p,detectedAt:r?.detectedAt??new Date().toISOString(),variant:`working-tree`,theirsSha:b,baseSha:v}),m||u.push(p)}return{writes:a,mineRestore:o,deletions:s,upserts:c,dissolved:l,newConflicts:u,autoCombined:d,autoRestored:f}}applyOverlayPlan(e,t){for(let{path:t,bytes:n}of e){let e=R(this.projectDir,t);dL(e,this.projectDir),cs(e,n)}for(let e of t){let t=R(this.projectDir,e);dL(t,this.projectDir);try{Jo(t)}catch(e){if(e.code!==`ENOENT`)throw e}}}isContentConflictPath(e){let t=R(this.projectDir,e),n=cN(z(this.contentDir,t));return!n.startsWith(`..`)&&tS(n)&&!this.contentFilter.isExcluded(n)}async gitBlobSha(e,t){try{return(await e.git.revparse([t])).trim()}catch{return}}classifyRefReadFailure(e){let t=e instanceof Error?e.message:String(e);return/does not exist in|exists on disk, but not in/i.test(t)?`absent`:`error`}async gitBlobContent(e,t){return e.git.raw([`cat-file`,`blob`,t])}async countStandingOverlay(e){try{return(await Lb(e.git,[`diff-index`,`--name-only`,`HEAD`])).filter(e=>this.isContentConflictPath(e)).length}catch{return null}}async runPushCycle(){if(!this.pushInFlight&&this.mode===`full`&&!(this.state===`dormant`||this.state===`disabled`)&&!(this.state===`conflict`||this.state===`auth-error`)){if(l9(this.projectDir)){this.schedulePush();return}this.pushInFlight=!0;try{await this.doPushCycle(1)}finally{this.pushInFlight=!1,this.schedulePush()}}}async doPushCycle(e=0){let t=this.gatherContentFilesSync(),n=R(mu(),`ok-sync-idx-${process.pid}-${Date.now()}.idx`),r=null;this.transitionTo(`pushing`);try{await ws(async()=>{let e=this.gitHandle(n);if(l9(this.projectDir)){a9.info({},`[sync] repo has no commits yet — skipping push cycle`),this.transitionTo(`idle`);return}let i;try{i=(await e.git.revparse(`HEAD`)).trim()}catch(e){let t=e instanceof Error?e.message:String(e),n=`${t}\n${e.git?.toString()??t}`;if(/unknown revision or path not in the working tree/i.test(n)||/ambiguous argument 'HEAD'/i.test(n)||/does not have any commits yet/i.test(n)){a9.info({},`[sync] repo has no commits yet — skipping push cycle`),this.transitionTo(`idle`);return}this.handleError(e9(e instanceof Error?e:Error(String(e))),`push`);return}await e.git.raw([`read-tree`,i]);let a=await this.listHeadContentPaths(e,i),o=await this.stageContentFiles(e,t),s=new Set(o.map(e=>e.projectRelPath)),c=[...a].filter(e=>!s.has(e));await this.removePathsFromIndex(e,c);let l=(await e.git.raw([`write-tree`])).trim(),u=``;try{u=(await e.git.raw([`rev-parse`,`${i}^{tree}`])).trim()}catch{}if(u&&u===l){let n=null;try{n=(await e.git.raw([`rev-parse`,`origin/${this.currentBranch}`])).trim()}catch{}if(n===i){a9.info({contentFileCount:t.length,headSha:i},`[sync] push cycle: nothing to commit (tree unchanged, origin matches HEAD)`),this.lastPushedSha=i,this.lastSyncUtc=new Date().toISOString(),this.clearPushError(),this.transitionTo(`idle`);return}a9.info({headSha:i,upstreamSha:n},`[sync] push cycle: tree unchanged but local ahead of origin — pushing existing commits`);let a=!1;try{await e.git.raw([`rev-parse`,`--abbrev-ref`,`${this.currentBranch}@{u}`]),a=!0}catch{}a?await e.git.raw([`push`,`origin`,this.currentBranch]):await e.git.raw([`push`,`--set-upstream`,`origin`,this.currentBranch]),r=i;return}let d=[],f=[];try{let n=await Lb(e.git,[`diff-tree`,`--name-only`,`-r`,i,l]);if(n.length>0){let e=new Map(t.map(e=>[e.projectRelPath,e.contentRelPath]));for(let t of n){d.push(t);let n=e.get(t)??cN(z(this.contentDir,R(this.projectDir,t)));n&&!n.startsWith(`..`)&&f.push(n)}}}catch{d=t.map(e=>e.projectRelPath).concat(c),f=t.map(e=>e.contentRelPath)}let p=this.buildCommitMessage(f),m=await tB(this.projectDir),h=m===null;this.identityUnresolved!==h&&(this.identityUnresolved=h,this.cc1Broadcaster?.signal(`sync-status`));let g=m?.name??`OpenKnowledge`,_=m?.email??`sync@open-knowledge.local`;Os(e,{GIT_AUTHOR_NAME:g,GIT_AUTHOR_EMAIL:_,GIT_COMMITTER_NAME:g,GIT_COMMITTER_EMAIL:_});let v=(await e.git.raw([`commit-tree`,l,`-p`,i,`-m`,p])).trim();if(!v||!o9.test(v)){a9.warn({raw:v},`[sync] commit-tree returned invalid SHA — aborting push`),this.transitionTo(`idle`);return}await e.git.raw([`update-ref`,`refs/heads/${this.currentBranch}`,v,i]),await this.resetRealIndexForPaths(d);let y=!1;try{await e.git.raw([`rev-parse`,`--abbrev-ref`,`${this.currentBranch}@{u}`]),y=!0}catch{}y?await e.git.raw([`push`,`origin`,this.currentBranch]):await e.git.raw([`push`,`--set-upstream`,`origin`,this.currentBranch]),r=v}),r&&(this.lastPushedSha=r,this.lastSyncUtc=new Date().toISOString(),this.ahead=0,this.clearPushError(),this.state===`pushing`&&this.transitionTo(`idle`),this.pausedReason===`dirty-tree`&&(this.pausedReason=void 0,this.clearPullError(),this.schedulePull(0)))}catch(t){let n=e9(t instanceof Error?t:Error(String(t)));if(n.class===`semantic`&&n.subclass===`non-fast-forward`){if(e>0){a9.info({},`[sync] push rejected (non-fast-forward) — fetching, merging, retrying`);let e=this.gitHandle();this.setBatchInProgress?.(!0);try{await e.git.fetch(`origin`),await this.commitDirtyContentFilesToHead(e);let t=await this.prepareForMerge(e,this.currentBranch);if(!t.proceed){this.setBatchInProgress?.(!1);return}try{await e.git.merge([`origin/${this.currentBranch}`])}finally{t.needsStashPop&&await this.popPreMergeStash(e)}}catch(e){let t=e9(e instanceof Error?e:Error(String(e)));t.class===`semantic`&&t.subclass===`merge-conflict`?await this.handleMergeConflict():this.handleError(t,`pull`),this.scheduleSaveState();return}finally{this.setBatchInProgress?.(!1)}await this.doPushCycle(0);return}a9.info({},`[sync] push still rejected after retry — waiting for next pull cycle`),this.consecutiveFailures++,this.state===`pushing`&&this.transitionTo(`idle`)}else this.handleError(n,`push`)}finally{try{ou(n)}catch{}}this.scheduleSaveState()}async commitDirtyContentFilesToHead(e){if((await e.git.status()).files.length===0)return null;let t=(await e.git.revparse(`HEAD`)).trim(),n=this.gatherContentFilesSync(),r=await this.listHeadContentPaths(e,t);if(n.length===0&&r.size===0)return null;let i=R(mu(),`ok-sync-retry-idx-${process.pid}-${Date.now()}.idx`),a=this.gitHandle(i);try{await a.git.raw([`read-tree`,t]);let i=await this.stageContentFiles(a,n),o=new Set(i.map(e=>e.projectRelPath)),s=[...r].filter(e=>!o.has(e));await this.removePathsFromIndex(a,s);let c=(await a.git.raw([`write-tree`])).trim();if(c===(await a.git.raw([`rev-parse`,`${t}^{tree}`])).trim())return null;let l=[];try{l=await Lb(a.git,[`diff-tree`,`--name-only`,`-r`,t,c])}catch{l=n.map(e=>e.projectRelPath).concat(s)}let u=await tB(this.projectDir),d=u?.name??`OpenKnowledge`,f=u?.email??`sync@open-knowledge.local`;Os(a,{GIT_AUTHOR_NAME:d,GIT_AUTHOR_EMAIL:f,GIT_COMMITTER_NAME:d,GIT_COMMITTER_EMAIL:f});let p=(await a.git.raw([`commit-tree`,c,`-p`,t,`-m`,`Auto-save: interim before merge`])).trim();return!p||!o9.test(p)?(a9.warn({raw:p},`[sync] commit-tree returned invalid SHA in commitDirtyContentFilesToHead`),null):(await e.git.raw([`update-ref`,`refs/heads/${this.currentBranch}`,p,t]),await this.resetRealIndexForPaths(l,e),p)}finally{try{ou(i)}catch{}}}async prepareForMerge(e,t){let n;try{n=await Lb(e.git,[`diff-index`,`--name-only`,`HEAD`])}catch(e){return a9.warn({err:e,branch:t},`[sync] diff-index failed — allowing merge attempt`),{proceed:!0,needsStashPop:!1}}if(n.length===0)return{proceed:!0,needsStashPop:!1};let r;try{r=new Set(await Lb(e.git,[`diff`,`--name-only`,`HEAD..origin/${t}`]))}catch(e){return a9.warn({err:e,branch:t},`[sync] merge-path diff failed — allowing merge attempt`),{proceed:!0,needsStashPop:!1}}let i=n.filter(e=>r.has(e));if(i.length>0){let e=i.slice(0,3).join(`, `),t=i.length>3?`, +${i.length-3} more`:``;return this.pullErrorCode=void 0,this.pullError=`Sync paused — your local changes to ${e}${t} conflict with incoming changes. Commit, stash, or discard them before syncing.`,this.pausedReason=`external-changes-pending`,this.consecutiveFailures=0,this.transitionTo(`idle`),this.scheduleSaveState(),a9.warn({files:i},`[sync] paused — dirty paths overlap incoming merge`),{proceed:!1,needsStashPop:!1}}let a=`ok-sync: pre-merge stash @ ${new Date().toISOString()}`;try{await e.git.raw([`stash`,`push`,`-m`,a])}catch(e){return a9.warn({err:e},`[sync] stash push failed — proceeding without stash`),{proceed:!0,needsStashPop:!1}}return{proceed:!0,needsStashPop:!0}}async popPreMergeStash(e){try{await e.git.raw([`stash`,`pop`])}catch(e){a9.warn({err:e},`[sync] stash pop failed — stash remains on stack`)}}async stageContentFiles(e,t){if(t.length===0)return t;let n=new Set,r=!0;for(let i=0;i<t.length;i+=100){let a=t.slice(i,i+100).map(e=>e.projectRelPath);try{let t=await Lb(e.git,[`ls-files`,`--others`,`--ignored`,`--exclude-standard`,`--`,...a]);for(let e of t)n.add(e)}catch(e){r=!1,a9.warn({err:e},`[sync] ignored-path probe failed — staging unfiltered without -f`)}}n.size>0&&a9.info({count:n.size,sample:[...n].slice(0,5)},`[sync] skipping gitignored untracked path(s) — in content scope but excluded from git`);let i=r?t.filter(e=>!n.has(e.projectRelPath)):t,a=e=>e.startsWith(`.ok/`)||e.includes(`/.ok/`),o=r?i.filter(e=>a(e.projectRelPath)):[],s=r?i.filter(e=>!a(e.projectRelPath)):i;for(let[t,n]of[[[`add`,`--`],s],[[`add`,`-f`,`--`],o]])for(let r=0;r<n.length;r+=100){let i=n.slice(r,r+100).map(e=>e.projectRelPath);await e.git.raw([...t,...i])}return i}gatherContentFilesSync(){let e=[],t=n=>{let r;try{r=eu(n,{withFileTypes:!0})}catch{return}for(let i of r){let r=R(n,i.name);if(i.isDirectory()){let e=cN(z(this.contentDir,r));if(!e.startsWith(`..`)&&this.contentFilter.isDirExcluded(e))continue;t(r)}else if(i.isFile()||i.isSymbolicLink()){let t=cN(z(this.contentDir,r));if(!t.startsWith(`..`)&&!this.contentFilter.isExcluded(t)){let n=cN(z(this.projectDir,r));e.push({contentRelPath:t,projectRelPath:n})}}}};return V(this.contentDir)&&t(this.contentDir),e}async listHeadContentPaths(e,t){let n=new Set;try{let r=await Lb(e.git,[`ls-tree`,`-r`,`--name-only`,t]);for(let e of r){let t=R(this.projectDir,e),r=cN(z(this.contentDir,t));!r.startsWith(`..`)&&!this.contentFilter.isExcluded(r)&&n.add(e)}}catch{}return n}async removePathsFromIndex(e,t){if(t.length===0)return;let n=[...new Set(t)];for(let t=0;t<n.length;t+=100){let r=n.slice(t,t+100);await e.git.raw([`rm`,`--cached`,`--`,...r])}}async resetRealIndexForPaths(e,t){if(e.length===0)return;let n=t??this.gitHandle(),r=[...new Set(e)];for(let e=0;e<r.length;e+=100){let t=r.slice(e,e+100);try{await n.git.raw([`reset`,`HEAD`,`--`,...t])}catch{}}}buildCommitMessage(e){return e.length===0?`Auto-save: changes saved`:e.length<=3?`Auto-save: Updated ${e.join(`, `)}`:`Auto-save: ${e.length} files changed`}async handleMergeConflict(){let e=this.gitHandle(),t=[];try{t=await Lb(e.git,[`diff`,`--name-only`,`--diff-filter=U`])}catch(t){a9.error({err:t},`[sync] failed to list conflicted files — aborting merge to avoid committing unresolved state`);try{await e.git.raw([`merge`,`--abort`])}catch(e){a9.warn({err:e},`[sync] git merge --abort failed during cleanup`)}this.pullErrorCode=void 0,this.pullError=`Failed to detect conflict files — merge aborted`,this.pausedReason=void 0,this.transitionTo(`idle`);return}let n=[],r=[];for(let e of t){let t=R(this.projectDir,e),i=cN(z(this.contentDir,t));!i.startsWith(`..`)&&tS(i)&&!this.contentFilter.isExcluded(i)?n.push(e):r.push(e)}let i=[];for(let t of r)try{await e.git.raw([`checkout`,`--theirs`,`--`,t]),await e.git.raw([`add`,`--`,t]),a9.info({file:t},`[sync] auto-resolved non-content conflict with theirs`)}catch(e){a9.warn({err:e,file:t},`[sync] non-content auto-resolve failed — will abort merge and pause sync`),i.push({file:t,err:e})}if(i.length>0){let t=i.map(e=>e.file);try{await e.git.raw([`merge`,`--abort`])}catch(e){a9.warn({err:e,files:t},`[sync] git merge --abort failed during non-content cleanup`)}let n=t.slice(0,3).join(`, `),r=t.length>3?`, +${t.length-3} more`:``;this.pullErrorCode=void 0,this.pullError=`Sync paused — couldn't auto-resolve ${n}${r}. Resolve in your terminal (e.g. \`git rm <file>\` or \`git checkout --ours/--theirs <file> && git add <file>\`), then retry sync.`,this.pausedReason=`non-content-merge-failure`,this.consecutiveFailures=0,this.transitionTo(`idle`),this.scheduleSaveState(),a9.warn({files:t},`[sync] non-content auto-resolve failed — merge aborted, sync paused`);return}if(n.length>0){for(let e of n)this.conflictStore.addConflict({file:e,detectedAt:new Date().toISOString()});this.conflictCount=this.conflictStore.count(),await this.notifyContentConflictsDetected(n),this.pullTimer!==null&&(clearTimeout(this.pullTimer),this.pullTimer=null),this.pushTimer!==null&&(clearTimeout(this.pushTimer),this.pushTimer=null),this.transitionTo(`conflict`),a9.warn({files:n},`[sync] content conflicts — sync paused until resolved`)}else{let t=!1;try{await e.git.raw([`commit`,`--no-edit`]);let n=Hu(this.projectDir);t=n===null||!V(R(n,`MERGE_HEAD`))}catch(e){a9.warn({err:e},`[sync] failed to commit after auto-resolving conflicts`)}if(t)this.lastSyncUtc=new Date().toISOString(),this.behind=0,this.transitionTo(`idle`),a9.info({},`[sync] all conflicts auto-resolved — merge committed`);else{try{await e.git.raw([`merge`,`--abort`])}catch(e){a9.warn({err:e},`[sync] git merge --abort failed during cleanup`)}this.pullError=`Sync paused — could not finalize the merge. Retry sync to try again.`,this.transitionTo(`idle`),a9.warn({},`[sync] could not finalize merge after auto-resolving conflicts — merge aborted`)}}}async notifyContentConflictsDetected(e){if(e.length!==0)try{await this.onContentConflictsDetected?.(e)}catch(t){a9.warn({err:t,files:e},`[sync] content conflict callback failed`)}}async notifyContentConflictsResolved(e){if(e.length!==0)try{await this.onContentConflictsResolved?.(e)}catch(t){a9.warn({err:t,files:e},`[sync] content conflict resolved callback failed`)}}clearPushError(){this.pushError=void 0,this.pushErrorCode=void 0}clearPullError(){this.pullError=void 0,this.pullErrorCode=void 0}handleError(e,t){e.userFacingCode===null?t===`push`?(this.pushErrorCode=void 0,this.pushError=e.message):(this.pullErrorCode=void 0,this.pullError=e.message):t===`push`?(this.pushErrorCode=e.userFacingCode,this.pushError=void 0):(this.pullErrorCode=e.userFacingCode,this.pullError=void 0),a9.warn({class:e.class,subclass:e.subclass,retryable:e.retryable,rawStderr:e.rawStderr},`[sync-error] ${e.message}`),e.class===`auth`?(this.ghTokenSource.invalidate(),this.transitionTo(`auth-error`),this.pausedReason=`auth-error`):e.class===`semantic`&&e.subclass===`protected-branch`?(this.mode=`off`,this.transitionTo(`disabled`),this.pausedReason=`protected-branch`,this.onAutoDisable?.(`protected-branch`)):e.class===`local`&&e.subclass===`dirty-tree`?(this.consecutiveFailures++,this.transitionTo(`idle`),this.pausedReason=`dirty-tree`,this.schedulePush(0)):e.retryable?(this.consecutiveFailures++,this.transitionTo(`offline`)):(this.consecutiveFailures++,this.transitionTo(`idle`))}transitionTo(e){if(this.state===e)return;let t=this.state;this.state=e,a9.info({from:t,to:e},`[sync] state: ${t} → ${e}`),this.onStateChange?.(e),this.cc1Broadcaster?.signal(`sync-status`)}scheduleSaveState(){this.stateSaveTimer===null&&(this.stateSaveTimer=setTimeout(()=>{this.stateSaveTimer=null,this.saveStateNow()},5e3))}saveStateNow(){try{let e=this.pausedReason===`no-push-permission`||this.pausedReason===`auth-error`?void 0:this.pausedReason,t={version:1,lastSyncUtc:this.lastSyncUtc,lastFetchUtc:this.lastFetchUtc,lastPushedSha:this.lastPushedSha,consecutiveFailures:this.consecutiveFailures,pausedReason:e,pausedSinceUtc:e?new Date().toISOString():void 0,inflightConflicts:this.conflictStore.list().map(e=>e.file)};su(this.statePath,JSON.stringify(t,null,2),`utf-8`)}catch(e){a9.warn({err:e},`[sync] failed to persist sync state`)}}loadState(){if(V(this.statePath))try{let e=H(this.statePath,`utf-8`),t=JSON.parse(e);if(t.version!==1)return;this.lastSyncUtc=t.lastSyncUtc??null,this.lastFetchUtc=t.lastFetchUtc??null,this.lastPushedSha=t.lastPushedSha??null,this.consecutiveFailures=t.consecutiveFailures??0,this.pausedReason=t.pausedReason===`no-push-permission`||t.pausedReason===`auth-error`?void 0:t.pausedReason;let n=t.inflightConflicts??[];if(n.length>0){for(let e of n)this.conflictStore.list().some(t=>t.file===e)||this.conflictStore.addConflict({file:e,detectedAt:new Date().toISOString()});this.conflictCount=this.conflictStore.count()}}catch(e){a9.warn({err:e},`[sync] failed to load sync state`)}}};ko();const OOe=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function kOe(){return{async afterLoadDocument({documentName:e,requestParameters:t}){if(pS(e)||mS(e))return;let n=t?.get(`mountId`)??void 0,r={"doc.name":e};n!==void 0&&OOe.test(n)&&(r[`mount.id`]=n);try{let e=()=>{Fo(`sync.handshake`,{attributes:r},()=>{})},n=t?.get(`traceparent`);if(n!=null){let r={traceparent:n},i=t?.get(`tracestate`);i!=null&&(r.tracestate=i),Ao.with(Do.extract(Ao.active(),r),e)}else e()}catch(e){I(`sync-handshake-span`).warn({err:e instanceof Error?e:Error(String(e))},`emission failed`)}}}}let d9=!1;function f9(){if(d9)return;let e=Xte;if(typeof e.getCACertificates!=`function`||typeof e.setDefaultCACertificates!=`function`){d9=!0;return}try{e.setDefaultCACertificates([...e.getCACertificates(`default`),...e.getCACertificates(`system`)]),d9=!0}catch(e){I(`trust-system-ca`).warn({err:e},`system CA setup failed; falling back to the bundled CA set`)}}const AOe=(()=>{let e=Object.freeze({origin:`park-snapshot`,paired:!0});return Object.freeze({source:`local`,skipStoreHooks:!1,context:e})})();function jOe(e){return[`-c`,`credential.helper=!${(e&&e.length>0?e:[`open-knowledge`]).map(y8).join(` `)} auth git-credential`]}function MOe(e,t,n,r){let i=new Map;if(!n)return i;let a;try{a=Tl(`git`,[`-c`,`core.quotePath=false`,`log`,`${n}..${r}`,`--no-merges`,`--name-only`,`--format=C%x00%an%x00%ae`],mN({cwd:e,encoding:`utf-8`,timeout:5e3}))}catch(e){return I(`upstream-attribution`).warn({err:e,oldHead:n,newHead:r},`git log spawn threw; upstream docs keep file-system attribution`),i}if(a.error||a.status!==0||typeof a.stdout!=`string`)return I(`upstream-attribution`).warn({err:a.error,status:a.status,signal:a.signal,stderr:typeof a.stderr==`string`?a.stderr.slice(0,500):void 0,oldHead:n,newHead:r},`git log failed; upstream docs keep file-system attribution`),i;let o=null;for(let n of a.stdout.split(`
2029
- `)){let r=n.trim();if(r===``)continue;if(r.startsWith(`C\0`)){let[,e,t]=r.split(`\0`);o=e&&t?{name:e,email:t}:null;continue}if(!o||!r.endsWith(`.md`)&&!r.endsWith(`.mdx`))continue;let a=B(e,r);if(!dN(a,t))continue;let s=mz(a,t);i.has(s)||V(a)&&i.set(s,o)}return i}function p9(e){f9();let{contentDir:t,projectDir:n=t,quiet:r=!0,debounce:i=2e3,maxDebounce:a=1e4,gitEnabled:o=!0,commitDebounceMs:s=3e4,wipRef:c=`refs/wip/main`,configHomedirOverride:l,enableTestRoutes:u=!1,shadowRepo:d,contentRoot:f,destroyTimeoutMs:p=1e4,localOpCliArgs:m,authStreamHeartbeatMs:h,skipStateManifestCheck:g=!1,singleDocRelPath:_,ephemeral:v=!1}=e,y=I(`server`),b=new l7,x=()=>b.getActiveBranch(),S=e=>b.getReconciledBase(e),C=(e,t)=>b.setReconciledBase(e,t),w=e=>b.deleteReconciledBase(e),T=e=>b.switchReconciledBaseScope(e),E=e=>b.setBatchInProgress(e),ee=()=>b.isBatchInProgress();function D(){let e=Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config`)});if(!e.valid){let t=me(e.error)&&e.error.code===`SCHEMA_INVALID`?e.error.issues.filter(e=>e.path.map(String).join(`.`)===`content.attachmentFolderPath`):[];if(t.length>0){let e=t.map(e=>e.message).join(`; `);throw Error(`Invalid content.attachmentFolderPath in project config: ${e}`)}y.warn({},`[config] committed content.attachmentFolderPath unavailable (project config invalid) — using default attachment placement`)}return e.value.content.attachmentFolderPath??`./`}function O(){let e=Io({absPath:Qo(`project-local`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project-local config`)}),t=de(e.value.autoSync);if(t!==null)return{mode:t,source:`config`};e.valid||y.warn({},`[config] project-local autoSync.mode unavailable (config invalid) — falling back to the committed project default`);let r=Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config`)});return r.valid||y.warn({},`[config] committed autoSync.default unavailable (project config invalid) — defaulting to disabled`),{mode:je(r.value.autoSync?.default)??`off`,source:`committed-default`}}function k(){let e=Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config for linter`)}).value.contentRules;return e?Sn(e):Ui}function te(){return Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config for link validation`)}).value.validation?.links??`warning`}function ne(){return CM(n,{configHomedirOverride:l,onWarn:e=>y.warn({message:e},`[config] could not read project-local config`)})}function re(){let e=Io({absPath:Qo(`project-local`,n,l),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project-local config`)});return e.valid?e.value.linkPreviews?.enabled===!0:!1}function ie(){return Ro({cwd:n,homedirOverride:l,warn:e=>y.debug({message:e},`[config] diagnostics read`)})}function ae(){for(let e of ie().diagnostics)e.code===`REMOVED_KEY`&&y.warn({scope:e.scope,file:e.file,path:e.path.join(`.`)},`[config] ${e.path.join(`.`)} is no longer read and was ignored. ${e.redirect}`)}function oe(e){return`${fM(e.baseUrl)}|${e.model}|${e.dimensions??`auto`}`}function A(e){let t;if(e===`__config__/project`||e===`__local__/project`){let n=O();t=n.mode,ft?.setMode(n.mode,n.source).catch(t=>{y.warn({err:t,mode:n.mode,docName:e},`[sync] failed to apply autoSync mode from config`)})}let n=ne();F.applyConfig({enabled:n.enabled,providerFingerprint:oe(n)}),e===`__config__/project`&&Te?.signal(`lint-config`),y.info({docName:e,autoSyncMode:t,semanticEnabled:n.enabled},`[config] applied persisted config to in-process consumers`)}us();let j=Tu(),se=IO(n),ce=new md({localDir:se,log:I(`acp-registry`)}),le=new cd(se,I(`acp-permissions`));if(Bs(se,{port:e.port??0,worktreeRoot:n,kind:e.lockKind??`interactive`,capabilities:e.capabilities??[`http`,`ws`]}),!g)try{Z7({lockDir:se,shadowRepoDir:Uu(n)})}catch(e){throw Ms(se),e}let ue=Ma(),fe=(e,t)=>ue.resolveEmbed(e,t),pe=(e,n)=>{let r=ue.resolveEmbed(e,n);if(!r&&e.includes(`/`)&&(r=e.replace(/^\.?\//,``)),!r)return null;let i=B(t,r);if(!lN(i,B(t)))return null;try{let e=au(i);return e.isFile()?e.size:null}catch{return null}},he,ge,_e,M,ve,ye,N,xe,Se,Ce,we,Te=null,Ee=null,De=null,Oe=null,ke=null,Ae=null,P=ne(),F=new aue({loadEmbedder:e.embedderLoader??(()=>{let t=ne();return Gle({keyStore:e.embeddingsKeyStore??null,projectDir:n,config:{baseUrl:t.baseUrl,model:t.model,dimensions:t.dimensions}})}),cacheDir:R(IO(n),`embeddings`),enabled:P.enabled,providerFingerprint:oe(P)}),Me=null,Ne=new Set,Pe=!1,Fe=[],Ie,Le,Re,ze=new Promise((e,t)=>{Le=e,Re=t});function Be(e){Te?.signal(e)}let Ve=null,He=!1,Ue=()=>{try{H7(n,We.entries())}catch(e){y.warn({err:e},`[removed-docs-journal] failed to persist removal journal`)}},We=new HDe(void 0,{onEviction:()=>Aoe(),onSizeChange:e=>joe(e),onMutate:()=>{!He||Ve!==null||(Ve=setTimeout(()=>{Ve=null,Ue()},2e3))}});for(let[e,r]of GDe(n))vS(e)||_Q(e)&&([`.md`,`.mdx`].some(n=>{let r=B(t,`${e}${n}`);return lN(r,B(t))&&V(r)})||We.restore(e,r));He=!0;let Ge={current:null},Ke=(e,t)=>{vS(e)||We.setRenamed(e,t)},qe=e=>{if(!vS(e)){if(We.peek(e)?.kind===`renamed`){console.info(JSON.stringify({event:`recently-removed-docs-unpaired-delete-suppressed`,docName:e,source:`watcher-delete`}));return}We.setDeleted(e),Ge.current?.deleted(e)}},Je=e=>{vS(e)||We.delete(e)};try{he=dP({projectDir:n,contentDir:t,singleDocRelPath:_,inPlaceSkillDirs:lL(t),rescanInPlaceSkillDirs:()=>lL(t),onAfterRebuild:()=>{ge.refreshContentScope().catch(e=>{I(`server-factory`).warn({err:e},`[content-filter] derived-index rebuild failed after onAfterRebuild`)}),Lz(ut).then(({prunedFiles:e,prunedFolders:t})=>{let n=e+t;n>0?I(`server-factory`).info({pruned:n,prunedFiles:e,prunedFolders:t},`[content-filter] reconciled file indexes after onAfterRebuild`):I(`server-factory`).debug({prunedFiles:e,prunedFolders:t},`[content-filter] file index reconcile completed after onAfterRebuild (no entries pruned; rescan may have added entries)`)}).catch(e=>{I(`server-factory`).warn({err:e},`[content-filter] file index reconcile failed after onAfterRebuild`)})}}),ge=new jR({projectDir:n,contentDir:t,contentFilter:he,getGlobalSkillRoots:()=>_K(ve.managedArtifactCtx),signalChannel:Be}),_e={current:d},M=o?ADe({getShadow:()=>_e.current??null,getCurrentBranch:()=>dt?.getLastKnownBranch()??null,contentRoot:f??``,projectGitDir:Hu(n)??void 0,isWriterLive:e=>{if(!Oe&&!xe)return I(`server-factory`).debug({writerId:e},`[server-factory] isWriterLive called before liveness deps populated — treating writer as dead`),!1;if(Oe?.getPresenceMap()[e])return!0;let t=e.startsWith(`agent-`)?e.slice(6):e;for(let e of xe?.sessionsForConnection(t)??[])return!0;return!1}}):void 0,ve=F7({contentDir:t,projectDir:n,gitEnabled:o,commitDebounceMs:s,wipRef:c,shadowRef:_e,ephemeral:v,contentRoot:f,derivedDocumentIndex:ge,configHomedirOverride:l,getCurrentBranch:()=>dt?.getLastKnownBranch()??null,resolveEmbed:fe,resolveSize:pe,getPrincipal:()=>Me,onAgentCommit:()=>Te?.signal(`session-activity`),onFlushCommit:()=>M?.noteFlushCommit(),onDiskFlush:(e,t,n,r)=>{Te?.emitDiskAck(e,t),!vS(e)&&TB(r,n)&&(ke?.(),Be(`files`))},onConfigRejected:(e,t)=>Te?.emitConfigValidationRejected(e,t),onConfigPersisted:A,isRecentlyRemoved:e=>We.has(e),mdManager:e.mdManager,getLossRing:()=>ye,durabilityState:b}),N=new KEe({quiet:r,debounce:i,maxDebounce:a,extensions:[ve.extension]});let p=N;Fe.push(iw(()=>p.documents.size),aw(()=>ve.getQueueDepths()),sw(()=>{let e=0;for(let t of p.documents.values())e+=t.directConnectionsCount;return{websocket:p.getConnectionsCount()-e,direct:e}})),lw(),v||(Ae=BDe({getLoadedDocuments:()=>p.documents,forceStore:(e,t)=>ve.forceStore(e,t),getBase:e=>b.getReconciledBase(e),isBatchActive:()=>b.isBatchInProgress(),peekInFlight:e=>b.peekInFlightFlush(e),readDiskBytes:e=>{let n=uN(e,t),r,i;try{r=U(n),i=au(r).size}catch(t){let n=Ns(t);if(n===`ENOENT`)return null;throw n===`ELOOP`?new L7(`symlink cycle at content path: ${e}`):t}if(!dN(r,t))throw new L7(`symlink-escape: ${n} resolves outside the content dir`);if(i>524288)throw new L7(`document exceeds the open byte limit: ${e}`);try{return H(r,`utf-8`)}catch(e){if(Ns(e)===`ENOENT`)return null;throw e}},graceMs:e.stalenessGraceMs,sweepIntervalMs:e.stalenessSweepIntervalMs}));let g=N.shouldUnloadDocument.bind(N);N.shouldUnloadDocument=e=>{if(Ne.has(e)||Pe&&g(e))return!0;let t=e.name;return vS(t)||S(t)!==void 0||e.getXmlFragment(`default`).length!==0||e.getText(`source`).length!==0?!1:g(e)},Ie=async e=>{Ne.add(e);try{await N.unloadDocument(e)}finally{Ne.delete(e)}},Te=new xS(N),De=new qE(N),Oe=new JE(N),xe=new qw(N,e.agentSessionOptions);let C=xe;Fe.push(cw(()=>({active:C.liveSessionCount,limit:C.sessionLimit})));let w=p7({derivedDocumentIndex:ge,onDocumentSettled:e=>Ge.current?.changed(e)});N.configuration.extensions.push(w),N.configuration.extensions.push({__kind:`principal-auth`,async onAuthenticate(e){let t=e.token,n=DQ(t),r=n?.expectedServerInstanceId;if(typeof r==`string`&&r.length>0&&r!==j)throw new EQ(`server-instance-mismatch`,`server instance mismatch: client claimed ${r}, this server is ${j}`);let i=n?.expectedBranch,a=x();if(typeof i==`string`&&i.length>0&&i!==a)throw new EQ(`branch-mismatch`,`branch mismatch: client claimed ${i}, server is on ${a}`);if(!n)return;let o=e.context;typeof n.principalId==`string`&&(Me&&n.principalId===Me.id?o.principalId=Me.id:Me?console.warn(JSON.stringify({event:`principal-token-mismatch`,claimed:n.principalId,loaded:Me.id})):o.principalId=n.principalId),typeof n.tabSessionId==`string`&&(o.tabSessionId=n.tabSessionId),o.kind=`human`}}),N.configuration.extensions.push({__kind:`config-doc-admission-guard`,async onAuthenticate(t){if(!mS(t.documentName)&&!hS(t.documentName))return;let n=t.request,r=n.socket?.remoteAddress;if(r!==void 0&&!rB(r))throw Error(`config-doc admission requires loopback peer (peer=${r}, doc=${t.documentName})`);let i=t.requestHeaders,a=(i&&typeof i.get==`function`?i.get(`host`):null)??n.headers?.host??void 0,o=e.remotePublicHost!==void 0&&lB(a,e.remotePublicHost);if(!iB(a)&&!o)throw Error(`config-doc admission requires a loopback or remote Host header (host=${a??`<absent>`}, doc=${t.documentName})`)}});let T=B(t);function E(e){if(!_Q(e))return null;let t=B(T,uS(e));return lN(t,T)?t:null}N.configuration.extensions.push({__kind:`removal-redirect-guard`,async onAuthenticate(e){await UDe(e.documentName,{recentlyRemovedDocs:We,resolveFilePath:E,fileExists:V})}}),N.configuration.extensions.push({__kind:`doc-lineage-guard`,async onAuthenticate(e){let t=DQ(e.token);cDe(e.documentName,t?.expectedDocLineageEpoch,{getLoadedDoc:e=>N.documents.get(e)})}}),N.configuration.extensions.push({__kind:`system-doc-broadcast-guard`,async beforeHandleMessage(e){if(e.documentName!==`__system__`)return;let t=new D5(e.update);if(t.readVarString(),t.readVarUint()===R5.BroadcastStateless)throw Error(`inbound BroadcastStateless on ${eo} rejected — server-only channel`)}});let ee=vQ({hocuspocus:N,durabilityState:b,remotePublicHost:e.remotePublicHost,sessionManager:xe,commentDocHooksRef:Ge,contentDir:t,contentFilter:he,serverInstanceId:j,getFileIndex:()=>ut?ut.getFileIndex():new Map,getAttachmentFolderPath:D,getAllFilesIndex:()=>ut?ut.getAllFilesIndex():new Map,getFileIndexGeneration:()=>ut?.getFileIndexGeneration()??0,mutateFileIndex:e=>ut?.mutateFileIndex(e),getFolderIndex:()=>ut?ut.getFolderIndex():new Map,getAliasMap:()=>ut?ut.getAliasMap():new Map,getFolderAliasIndex:()=>ut?ut.getFolderAliasIndex():new Map,rescanFiles:()=>ut?.rescanFromDisk(),enableTestRoutes:u,shadowRef:_e,flushGitCommit:()=>ve.flushPendingGitCommit(),flushContributors:()=>ve.flushContributors(),getCurrentBranch:()=>dt?.getLastKnownBranch()??null,getDiskAckSVs:()=>Te?.getLatestDiskAckSVsAsBase64()??{},contentRoot:f,derivedDocumentIndex:ge,signalChannel:Be,agentFocusBroadcaster:De,agentPresenceBroadcaster:Oe,onAgentWrite:e.onAgentWrite,getSyncEngine:()=>ft,localOpCliArgs:m,authStreamHeartbeatMs:h,projectDir:n,resolveEmbed:fe,getBridgeLossReporter:()=>we,getPrincipal:()=>Me,acpRegistry:ce,loadAcpCustomAgents:()=>hd(se,I(`acp-registry`)),homeDirOverride:l,forceUnloadDocument:Ie,ready:ze,recentlyRemovedDocs:We,serializeDoc:$e,evictManagedArtifactLkg:e=>{ve.managedArtifactCtx.lkgCache.delete(e)},semanticSearch:F,getSemanticSimilarityFloor:()=>ne().similarityFloor,getLinterBaseConfig:()=>k(),getLinksValidationSetting:()=>te(),getLinkPreviewsEnabled:re,getConfigDiagnostics:ie,embeddingsSecretsFile:bM(l),readSemanticProviderConfig:ne,ephemeral:v,onReferencedAssetsCacheInvalidator:e=>{ke=e}});N.configuration.extensions.push(ee),Se=ee.nativeApi,Ce=ee.localApi;let O=Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config for bridge guards`)}),ae=O.value.bridge.deferGuard.enabled,oe=O.value.bridge.fixedPoint.enabled,le=O.value.bridge.preDrain.enabled;ye=O.value.lossCapture.enabled?new kb({projectDir:n,maxBytes:O.value.lossCapture.maxBytes}):void 0,O.value.bridge.lossDetector.enabled&&(we=use({shadow:()=>_e.current,ring:ye,getBranch:()=>dt?.getLastKnownBranch()??`main`,contentRoot:f??``}),xe.attachBridgeLossReporter(we)),N.configuration.extensions.push(W7({mdManager:Mo,schema:jo,shadowRef:_e,contentRoot:f,getCurrentBranch:()=>dt?.getLastKnownBranch()??null,resolveEmbed:fe,resolveSize:pe,deferGuardEnabled:ae,lossDetectorEnabled:O.value.bridge.lossDetector.enabled,fixedPointBackstopEnabled:oe,preDrainEnabled:le,lossRing:ye})),N.configuration.extensions.push(kOe()),N.configuration.extensions.push(sDe({getSyncEngine:()=>ft,projectDir:n,contentDir:t}))}catch(e){for(let e of Fe.splice(0))e();throw Ae?.dispose(),Ae=null,Ms(se),e}let Ye=null,Xe=new Map,Ze=[];function Qe(e,t){let n=B(e,`rescue`),r=B(n,uS(t));return lN(r,n)?r:null}function $e(e){let t=N.documents.get(e);return t?WR(t):null}let et=(e,t)=>VR(b,N,e,t,fe,pe,we);function tt(e){if(!AS(e)||ft?.getConflicts().some(r=>c7(r,e.name,n,t)))return;let r=e.getMap(`lifecycle`);r.delete(`status`),r.delete(`reason`)}let nt=e=>{if(!e)return;let t=`[[${e}]]`;for(let[n]of N.documents){if(vS(n))continue;let r=N.documents.get(n);if(!r)continue;let i=r.getText(`source`).toString();if(i.includes(t))try{r.transact(()=>{NR(r,i,fe,n)},MR)}catch(t){y.error({err:t,docName:n,assetBasename:e},`[asset-event] failed to re-render ${n} for asset basename ${e}`)}}},rt=null,it=e=>{e&&(rt===null&&(rt=new Set,setImmediate(()=>{let e=rt;if(rt=null,e)try{for(let t of e)nt(t)}catch(t){y.error({err:t,basenames:[...e]},`[asset-event] dedup rerender pass crashed`)}})),rt.add(e))};function at(e){switch(e.kind){case`rename`:return e.newDocName;case`asset-create`:case`asset-delete`:case`folder-create`:case`folder-delete`:case`file-create`:case`file-update`:case`file-delete`:return e.relativePath;case`create`:case`update`:case`delete`:case`conflict`:return e.docName;default:return XR(e)}}async function ot(e){try{switch(e.kind){case`create`:y.info({docName:e.docName},`[reconcile] create: ${e.docName}`),await ge.recordDiskUpsert(e.docName,e.content),Be(`files`),Je(e.docName);break;case`update`:{let{docName:t,content:n}=e,r=N.documents.get(t);if(!r){await ge.recordDiskUpsert(t,n);return}let i=S(t)??``,a=$e(t)??i,o=LR({docName:t,base:i,ours:a,theirs:n}),s=rz(i).slice(0,6),c=rz(a).slice(0,6),l=rz(n).slice(0,6);switch(y.info({docName:t,base:s,ours:c,theirs:l,result:o.kind},`[reconcile] ${t} base=${s} ours=${c} theirs=${l} result=${o.kind}`),o.kind){case`noop`:tt(r),await ge.recordDiskUpsert(t,n);break;case`clean`:{let e=!1;try{et(t,o.newContent),C(t,o.newContent),Vb(),tt(r),e=!0}catch(e){y.error({err:e,docName:t},`[reconcile] failed to apply clean content to Y.Doc for ${t}`),C(t,n),tt(r)}e&&await ge.recordDiskUpsert(t,n)}break;case`merged`:{let e=!1;try{et(t,o.newContent),C(t,n),Vb(),tt(r),e=!0}catch(e){y.error({err:e,docName:t},`[reconcile] failed to apply merged content to Y.Doc for ${t}`),C(t,n),tt(r)}e&&await ge.recordDiskUpsert(t,n)}break;case`conflicts`:{let e=!1;try{et(t,o.newContent),C(t,o.newContent),Vb(),Hb(),e=!0}catch(e){y.error({err:e,docName:t},`[reconcile] failed to apply conflict content to Y.Doc for ${t}`),C(t,n)}{let e=r.getMap(`lifecycle`);e.set(`status`,`conflict`),e.set(`reason`,`merged-with-markers`)}e&&await ge.recordDiskUpsert(t,n);break}case`refused`:{Hb();let e=r.getMap(`lifecycle`);e.set(`status`,`conflict`),e.set(`reason`,o.reason);break}}break}case`delete`:{let{docName:t}=e,n=N.documents.get(t);if(!n){await ge.recordDiskDelete(t),Be(`files`),qe(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));return}let r=S(t)??``,i=$e(t)??``,a=i!==r;if(a&&_e.current){let e=_e.current,n=dt?.getLastKnownBranch()??`main`;queueMicrotask(()=>{Jx(e,f??``,{kind:`external-change-rescue`,docName:t,contents:i,label:`External change recovered @ ${new Date().toISOString()}`,branch:n,metadata:{incomingDiskSha:``}}).then(()=>{Kb(),y.info({docName:t},`[reconcile] rescue checkpoint saved (delete): ${t}`)}).catch(e=>{y.error({docName:t,err:e},`[reconcile] rescue checkpoint write failed: ${t}`)})})}n.getMap(`lifecycle`).set(`status`,`deleted-upstream`),w(t),await ge.recordDiskDelete(t),y.info({docName:t,isDirty:a},`[reconcile] delete: ${t} (dirty=${a})`),N.closeConnections(t),await Ie(n),Be(`files`),qe(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));break}case`rename`:{let{oldDocName:t,newDocName:n,content:r}=e,i=N.documents.get(t);if(w(t),C(n,r),await ge.recordDiskRename(t,n,r),i){let e=i.getMap(`lifecycle`);e.set(`status`,`renamed`),e.set(`newPath`,n)}y.info({oldDocName:t,newDocName:n},`[reconcile] rename: ${t} → ${n}`),Be(`files`),Ke(t,n),console.info(JSON.stringify({event:`recently-removed-docs-populate`,from:t,to:n,kind:`renamed`,source:`watcher-rename`}));break}case`conflict`:{let{docName:t}=e,n=N.documents.get(t);if(!n)return;let r=$e(t);r===null?y.warn({docName:t},`[reconcile] case 'conflict': serializeDoc returned null for ${t}; reconciledBase snapshot skipped — post-resolution reconcile may degrade to 3-way merge`):C(t,r);let i=n.getMap(`lifecycle`);i.set(`status`,`conflict`),i.set(`reason`,`conflict-markers`),y.info({docName:t},`[reconcile] conflict markers detected: ${t}`);break}case`asset-create`:ue.add(e.relativePath),Be(`files`),it(Dl(e.relativePath));break;case`asset-delete`:ue.remove(e.relativePath),Be(`files`),it(Dl(e.relativePath));break;case`folder-create`:case`folder-delete`:Be(`files`);break;case`file-create`:case`file-update`:case`file-delete`:Be(`files`);break;default:XR(e)}}catch(t){let n=at(e);y.error({err:t,kind:e.kind,label:n},`[reconcile] failed to handle ${e.kind} for ${n}`)}}let st=[];async function ct(e){if(ee()){st.push(e);return}await ot(e)}async function lt(){let e=st.splice(0,st.length);for(let t of e)await ot(t)}let ut=null,dt=null,ft=null,pt=null;async function mt(e){if(N.documents.size===0)return;let t=!1,n=new Promise(e=>{N.configuration.extensions.push({async afterUnloadDocument({instance:n}){!t&&n.getDocumentsCount()===0&&(t=!0,e())}})}),r=Array.from(N.documents.keys());N.closeConnections(),N.flushPendingStores();for(let e of N.documents.values())e.getConnectionsCount()===0&&N.unloadDocument(e).catch(t=>{console.warn(JSON.stringify({event:`ok-shutdown-unload-document-failed`,docName:e.name,reason:t instanceof Error?t.message:String(t)}))});let i,a=new Promise((n,a)=>{i=setTimeout(()=>{t=!0;let n=Array.from(N.documents.keys()),i=[],o=[];if(_e.current){for(let e of n)if(!vS(e))try{let t=$e(e);if(t===null){y.warn({docName:e},`[rescue] skipping ${e} — document dropped from map mid-rescue`),o.push(e);continue}let n=Qe(_e.current.gitDir,e);if(!n){y.warn({docName:e,gitDir:_e.current.gitDir},`[rescue] path-traversal guard rejected docName: ${e}`),o.push(e);continue}Jl(L(n),{recursive:!0}),su(n,t,`utf-8`),Kb(),i.push(e),y.info({docName:e},`[rescue] rescue buffer saved on flush timeout: ${e}`)}catch(t){o.push(e),y.error({err:t,docName:e},`[rescue] failed to write rescue buffer for ${e}`)}}else y.warn({stillLoadedCount:n.length},`[rescue] shadow repo unavailable at flush timeout — ${n.length} doc(s) will be lost: [${n.join(`, `)}]`),o.push(...n);let s=i.length>0||o.length>0?` — rescued [${i.join(`, `)}]${o.length>0?`, lost [${o.join(`, `)}]`:``}`:``;a(Error(`flushAllStoresAndWait timeout after ${e}ms — ${n.length}/${r.length} docs did not unload: [${n.join(`, `)}]${s}`))},e)});try{await Promise.race([n,a])}finally{i!==void 0&&clearTimeout(i)}}async function ht(){return pt||(pt=(async()=>{let e=Date.now(),t=[];Pe=!0;for(let e of Fe.splice(0))e();try{await Ae?.dispose()}catch(e){y.warn({err:e},`[server] staleness watchdog drain failed during destroy`)}Ae=null;try{Hs(se)}catch(e){y.warn({err:e},`[server] failed to mark server.lock draining`)}if(Ve!==null&&(clearTimeout(Ve),Ve=null),He)try{H7(n,We.entries())}catch(e){y.warn({err:e},`[removed-docs-journal] failed to persist removal journal during shutdown`),t.push({phase:`removed-docs-journal-flush`,error:String(e)})}let r,i=await Promise.race([ze.then(()=>`completed`,e=>(y.debug({err:e},`[server] init incomplete during shutdown`),`failed`)),new Promise(e=>{r=setTimeout(()=>e(`timeout`),5e3)})]);r!==void 0&&clearTimeout(r),i===`timeout`&&y.warn({},`[server] init did not complete within 5s during shutdown`);let a=N.documents.size;M?.destroy();try{try{try{Ee&&=(clearTimeout(Ee),null),dt&&=(await dt.unsubscribe(),null),ut&&=(await ut.unsubscribe(),null);for(let{docName:e,cleanup:t}of Ze)try{await t()}catch(t){y.warn({err:t,docName:e},`[server] failed to stop config-file-watcher for ${e}`)}Ze.length=0}catch(e){t.push({phase:`watcher-unsubscribe`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-1 watcher unsubscribe failed`)}try{Te?.destroy(),Oe?.destroy(),Ye&&=(await Ye.disconnect(),null);for(let[e,t]of Xe)try{await t.disconnect()}catch(t){y.warn({err:t,docName:e},`[server] failed to disconnect ${e} during shutdown`)}Xe.clear()}catch(e){t.push({phase:`cc1-teardown`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-1b CC1 teardown failed`)}try{await xe.closeAll()}catch(e){t.push({phase:`agent-session-drain`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-2 agent session drain failed`)}try{await Ese()}catch(e){t.push({phase:`parse-pool-teardown`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-2b parse pool teardown failed`)}try{await mt(p)}catch(e){t.push({phase:`flush-all-stores`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-3 flush failed`)}ge.close();let e;try{await Promise.race([(async()=>{await ve.flushPendingGitCommit(),await ve.waitForPendingCommits()})(),new Promise((t,n)=>{e=setTimeout(()=>n(Error(`L2 git flush timeout`)),p)})])}catch(e){t.push({phase:`git-commit-flush`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-4 git commit flush failed`)}finally{e!==void 0&&clearTimeout(e)}try{ft&&=(await ft.destroy(),null)}catch(e){t.push({phase:`sync-engine-stop`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown sync-engine-stop failed`)}}finally{if(_e.current){let e;try{await Promise.race([Ox(_e.current).drain(),new Promise((t,n)=>{e=setTimeout(()=>n(Error(`shadow mutator drain timeout`)),p)})])}catch(e){t.push({phase:`shadow-mutator-drain`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-5 shadow mutator drain failed`)}finally{e!==void 0&&clearTimeout(e)}try{let e=(await Cs({baseDir:n,timeout:{block:5e3}}).revparse(`HEAD`)).trim();e&&su(B(_e.current.gitDir,`last-known-head`),e,`utf-8`)}catch{}try{Goe(_e.current)}catch(e){t.push({phase:`shadow-repo-release`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-5 destroyShadowRepo failed`)}}let r=Date.now()-e;t.length===0?y.info({documentCount:a,durationMs:r},`[server] shutdown flushed ${a} documents in ${r}ms`):y.warn({documentCount:a,durationMs:r,phaseErrors:t},`[server] shutdown flushed ${a} documents in ${r}ms with ${t.length} phase error(s)`)}}finally{try{Ms(se,{deferUnlinkToExit:!0})}catch(e){t.push({phase:`server-lock-release`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-6 releaseServerLock failed`)}try{await ls()}catch(e){t.push({phase:`telemetry-shutdown`,error:e instanceof Error?e.message:String(e)})}}})(),pt)}let gt=[];async function _t(){try{Me=await R7(n),y.info({principalId:Me.id},`[server] principal loaded`)}catch(e){y.warn({err:e},`[server] principal load failed — browser writes will use SERVICE_WRITER`)}if(!_e.current)try{_e.current=await Px(n),y.info({gitDir:_e.current.gitDir},`[server] history repo initialized at ${_e.current.gitDir}`)}catch(e){y.error({err:e},`[server] history repo init failed`),gt.push(`shadow-repo`)}if(_e.current){let e=null;try{e=sq(_e.current.gitDir),Aq(_e.current.gitDir,e),fq(_e.current.gitDir,e),y.info({entries:e.byTo.size},`[server] rename log loaded (${e.byTo.size} entries)`)}catch(e){y.warn({err:e},`[rename-log] boot-time load/sweep failed; rename history unavailable`)}if(e){let t=1e4;try{await Promise.race([jq(_e.current,e,{rebuild:!0}),new Promise((e,n)=>setTimeout(()=>n(Error(`boot-time GC exceeded ${t}ms`)),t))])}catch(e){y.warn({err:e},`[rename-log] boot-time GC/rebuild failed; index loaded without GC`)}}try{await M?.runBootMaintenance()}catch(e){y.warn({err:e},`[shadow-maintenance] boot maintenance failed (non-fatal)`)}}if(_e.current)try{await Mx(_e.current).raw(`rev-parse`,`--git-dir`)}catch(e){let t=e instanceof Error?e.message:String(e);if(t.includes(`not a git repository`)||t.includes(`invalid object`)){y.warn({},`[server] history repo appears corrupted — reinitializing`);try{_e.current=await Px(n)}catch(e){y.error({err:e},`[server] history repo reinit failed`),_e.current=void 0,gt.includes(`shadow-repo`)||gt.push(`shadow-repo`)}}else y.error({err:e},`[server] history repo check failed (transient?)`)}if(_e.current)try{let e=B(_e.current.gitDir,`last-known-head`),t=null;try{t=H(e,`utf-8`).trim()||null}catch{}let r=null;try{r=(await Cs({baseDir:n,timeout:{block:1e4}}).revparse(`HEAD`)).trim()||null}catch{}if(r!==null){if(r!==t){let e=`main`;try{let t=(await Cs({baseDir:n,timeout:{block:1e4}}).raw(`rev-parse`,`--abbrev-ref`,`HEAD`)).trim();t&&t!==`HEAD`&&(e=t)}catch{}y.info({lastKnownHead:t,currentHead:r,branch:e},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${r}, action=import`);try{await Gx(_e.current,f??``,t,r,e),Wb()}catch(e){y.warn({err:e},`[head-drift] commitUpstreamImport failed — continuing`)}}else y.info({currentHead:r},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${r}, action=noop`);try{su(e,r,`utf-8`)}catch(e){y.warn({err:e},`[head-drift] failed to write last-known-head`)}}}catch(e){y.warn({err:e},`[head-drift] check failed — continuing`)}try{let e=qK(t,n);if(e.recovered&&e.journal){let t=e.journal.version===2?e.journal.fromPath:e.journal.sourceDocName,n=e.journal.version===2?e.journal.toPath:e.journal.destinationDocName;y.warn({journalVersion:e.journal.version,fromPath:t,toPath:n,restoredDocNames:e.restoredDocNames},`[managed-rename] recovered pending rename ${t} -> ${n}`)}}catch(e){y.error({err:e},`[server] managed rename recovery failed`),gt.push(`managed-rename-recovery`)}try{let e=OL(n);(e.deleted>0||e.errors>0)&&y.info({scanned:e.scanned,deleted:e.deleted,errors:e.errors},`[upload-tempfile-sweep] swept ${e.deleted} orphan tempfile(s)`)}catch(e){y.error({err:e},`[server] upload-tempfile sweep failed`),gt.push(`upload-tempfile-sweep`)}try{Ye=await N.openDirectConnection(eo),Te?.emitServerInfo(j,x())}catch(e){y.error({err:e},`[server] failed to open __system__ direct connection — CC1 push disabled`),gt.push(`cc1-push`)}let r=v?[]:$i;for(let e of r)try{let t=await N.openDirectConnection(e);Xe.set(e,t)}catch(t){y.error({err:t,docName:e},`[server] failed to open ${e} direct connection — config bind degraded`),gt.push(`config-doc:${e}`)}let i=new Map([[Qr,Qo(`project`,n)],[di,Qo(`project-local`,n)],[Da,Qo(`user`,n,l)]]);for(let e of r){let t=i.get(e);if(t)try{y.info({docName:e,path:t},`[config-file-watcher] starting`);let n=await Z5(t,t=>{let n=N.documents.get(e);y.info({docName:e,hasDocument:n!==void 0,contentLength:t.length},`[config-file-watcher] file changed`);let r=s7(n??null,e,t,ve.configPersistenceCtx);y.info({docName:e,outcome:r},`[config-file-watcher] applyExternalConfigChange outcome`),A(e)});Ze.push({docName:e,cleanup:n}),y.info({docName:e,path:t},`[config-file-watcher] started`)}catch(n){y.warn({err:n,docName:e,path:t},`[config-file-watcher] failed to start for ${e}`),gt.push(`config-file-watcher:${e}`)}}if(!v){let e=(e,t)=>{let n=SK(e,ve.managedArtifactCtx);if(!n)return;let r=DK(N.documents.get(n)??null,n,t,ve.managedArtifactCtx);y.info({docName:n,outcome:r},`[managed-artifact-watcher] external change`),Be(`files`),Un(n)&&ge.refreshGlobalSkillNodes().catch(e=>{y.warn({err:e,docName:n},`[backlinks] global skill bundle re-ingest failed`)})},t=e=>{let t=SK(e,ve.managedArtifactCtx);Be(`files`),t&&Un(t)&&ge.refreshGlobalSkillNodes().catch(e=>{y.warn({err:e,docName:t},`[backlinks] global skill bundle prune failed`)})};try{let n=_K(ve.managedArtifactCtx),r=await jDe(n,e,t);Ze.push({docName:`__skill-files__`,cleanup:r}),y.info({roots:n},`[managed-artifact-watcher] skills started`)}catch(e){y.warn({err:e},`[managed-artifact-watcher] skills failed to start`),gt.push(`managed-artifact-watcher:skills`)}try{let e=B(mK(ve.managedArtifactCtx),`.ok`,`skill-state.yml`),t=await Z5(e,()=>{Be(`files`)});Ze.push({docName:`__skill-state__`,cleanup:t}),y.info({path:e},`[skill-state-watcher] started`)}catch(e){y.warn({err:e},`[skill-state-watcher] failed to start`),gt.push(`skill-state-watcher`)}}try{let e=B(t,`.okignore`),r=B(n,`.gitignore`),i=null;try{let e=Tl(`git`,[`rev-parse`,`--git-common-dir`],mN({cwd:n,encoding:`utf-8`,timeout:5e3}));if(e.status===0&&e.stdout){let t=R(B(n,e.stdout.trim()),`info`,`exclude`);V(L(t))&&(i=t)}}catch{}let a=i?[e,r,i]:[e,r],o=y;o.info({okignorePath:e,gitignorePath:r,gitInfoExcludePath:i,ephemeral:v},`[ignore-watcher] starting multi-path watcher for .okignore + .gitignore (+ .git/info/exclude when present)`);let s=v?null:await QEe(a,(t,r)=>{(async()=>{if(t===e)try{let e=s7(N.documents.get(`__config__/okignore`)??null,Xa,r,ve.configPersistenceCtx);o.info({docName:Xa,outcome:e},`[ignore-watcher] applyExternalConfigChange outcome`)}catch(e){o.error({err:e,changedPath:z(n,t)},`[ignore-watcher] applyExternalConfigChange failed; rebuild proceeds independently`)}let i=await he.rebuildIgnorePatterns();if(i.ok)o.info({changedPath:z(n,t),patternCount:i.patternCount,nestedFileCount:i.nestedFileCount,durationMs:i.durationMs},`[ignore-watcher] rebuild succeeded — broadcasting files channel`),Te?.signal(`files`);else{let e=z(n,t)||`.`;o.warn({changedPath:e,error:i.error.message},`[ignore-watcher] rebuild failed — emitting config-ignore-nested-error`),Te?.emitConfigIgnoreNestedError(e,i.error.message)}})().catch(e=>{o.error({err:e,changedPath:z(n,t)||`.`},`[ignore-watcher] handler threw`)})});s&&(Ze.push({docName:`__ignore-files__`,cleanup:s}),o.info({okignorePath:e,gitignorePath:r},`[ignore-watcher] multi-path watcher started`))}catch(e){y.warn({err:e,projectDir:n,contentDir:t},`[ignore-watcher] failed to start multi-path watcher`),gt.push(`ignore-files-watcher`)}let a=f7(n).branch??`main`;T(a);let o=ge.beginStartup(a),s=!1,c=performance.now();try{await Vo(`ok.boot.indexes`,void 0,async()=>{let{deletedDocNames:e,backlinkIndexDegraded:r}=await o.backlinksReady;r&&gt.push(`backlink-index`);let i=0;for(let t of e)vS(t)||We.peek(t)?.kind!==`renamed`&&(We.setDeleted(t),i++);i>0&&y.info({count:i},`[removal-guard] tombstoned docs deleted while the server was down`);let a=performance.now(),c=/^\.(?!ok\/)[A-Za-z0-9_-]+\/skills\//,u=he?lL(t):new Set,d=e=>{e.some(e=>c.test(z(t,e).split(Pl).join(`/`)))&&(Ee&&clearTimeout(Ee),Ee=setTimeout(()=>{Ee=null;try{aZ(n,t).then(e=>{e>0&&(y.info({refreshed:e},`[in-place-skills] re-synced recorded copies`),Te?.signal(`files`))}).catch(e=>y.warn({err:e},`[in-place-skills] copy re-sync failed`));let e=lL(t);if(!(e.size!==u.size||[...e].some(e=>!u.has(e))))return;u=e,he.rebuildIgnorePatterns().then(t=>{t.ok?(y.info({skillDirs:e.size},`[in-place-skills] canonical set changed — filter rebuilt`),Te?.signal(`files`)):y.warn({error:t.error.message},`[in-place-skills] filter rebuild failed after skill re-scan`)}).catch(e=>y.warn({err:e},`[in-place-skills] rebuild threw`))}catch(e){y.warn({err:e},`[in-place-skills] re-scan trigger failed`)}},500))};ut=await Vo(`ok.boot.seed-walk`,void 0,async()=>Iz(t,ct,he,{onRawBatch:d})),aZ(n,t).then(e=>{e>0&&y.info({refreshed:e},`[in-place-skills] boot copy re-sync`)}).catch(e=>y.warn({err:e},`[in-place-skills] boot copy re-sync failed`));{let e=l??du();aZ(e,e,sL(e)).then(e=>{e>0&&y.info({refreshed:e},`[in-place-skills] global boot copy re-sync`)}).catch(e=>y.warn({err:e},`[in-place-skills] global copy re-sync failed`))}mR(`seedWalkMs`,Math.round(performance.now()-a));{let e=B(t),n=0;for(let[t]of We.entries()){if(!_Q(t))continue;let r=B(e,`${t}${cS(t)}`);lN(r,e)&&V(r)&&(We.delete(t),n++)}n>0&&y.info({count:n},`[removal-guard] dropped journaled removal entries whose file re-appeared while the server was down`)}let f=await ge.settleStartupAfterWatcherSeed();s=!0,f.tagIndexDegraded&&gt.push(`tag-index`);let p=0;try{_===void 0?await xQ({contentDir:t,contentFilter:he,basenameIndex:ue,onSkip:(e,t,n)=>{p++,y.warn({reason:e,code:t,path:n},`[basename-index] skipped entry during seed (${e}${t?` ${t}`:``})`)}}):Pme({contentDir:t,basenameIndex:ue,onSkip:(e,t,n)=>{p++,y.warn({reason:e,code:t,path:n},`[basename-index] skipped entry during single-file seed (${e}${t?` ${t}`:``})`)}}),p>0&&(y.warn({count:p},`[basename-index] startup seed completed with ${p} skipped entries — embeds under inaccessible subtrees will not resolve`),gt.push(`basename-index-partial`))}catch(e){y.error({err:e},`[basename-index] startup seed failed`),gt.push(`basename-index`)}})}catch(e){if(y.error({err:e},`[server] disk bridge watcher failed to start`),gt.push(`file-watcher`),!s){let e=await ge.settleStartupAfterWatcherSeed();s=!0,e.tagIndexDegraded&&gt.push(`tag-index`)}}finally{mR(`indexesMs`,Math.round(performance.now()-c)),ut&&hR(`fileCount`,ut.getFileIndex().size)}try{dt=await pDe(n,async({trigger:e})=>{if(y.info({trigger:e},`[batch] begin trigger=${e}`),Ub(),N.flushPendingStores(),await ve.flushPendingGitCommit(),E(!0),_e.current){let e=x(),t=f7(n).branch??e,r=[];for(let[e,t]of N.documents){if(vS(e))continue;let n=null;if(t.transact(()=>{n=$e(e)},AOe),n===null)continue;let i=S(e)??n;r.push({docName:e,markdown:n,diskSnapshot:i})}if(r.length>0)try{let n=await tse(_e.current,e,Ux.id,r,t);n&&(Jb(),y.info({count:r.length,branch:e,sha:n.slice(0,8)},`[history] parked ${r.length} docs on ${e} → ${n.slice(0,8)}`))}catch(e){y.error({err:e},`[shadow] park failed`)}}},async e=>{let r=st.length,i=e.newBranch??`main`;if(y.info({kind:e.batchKind,headMoved:e.headMoved,docs:r,timeout:!!e.timeout},`[batch] end kind=${e.batchKind} headMoved=${e.headMoved} docs=${r}${e.timeout?` timeout`:``}`),e.batchKind===`within-branch`){if(E(!1),await lt(),e.headMoved&&e.newHead){let r=MOe(n,B(t),e.oldHead,e.newHead);if(r.size>0){Ej(r.keys());for(let[e,t]of r)Tj(e,rne(t.email),t.name,t.email,ed(e));await ve.flushContributors()}}if(await ve.flushDeferredStores(`within-branch`),ft!==null)try{await ft.reconcileConflictsFromGit()}catch(e){y.warn({err:e},`[head-watcher] sync engine conflict reconcile failed`)}}else{qb(),st.splice(0,st.length);let n=!1,r;try{T(i),r=await ge.beginBranchSwitch(i),he.rebuildDirCount();try{let e=0;ue.clear(),await xQ({contentDir:t,contentFilter:he,basenameIndex:ue,onSkip:(t,n,r)=>{e++,y.warn({reason:t,code:n,path:r,branch:i},`[basename-index] skipped entry during branch-switch reseed (${t}${n?` ${n}`:``})`)}}),e>0&&(y.warn({count:e,branch:i},`[basename-index] branch-switch reseed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve on this branch`),gt.includes(`basename-index-partial`)||gt.push(`basename-index-partial`))}catch(e){y.error({err:e,branch:i},`[basename-index] branch-switch reseed failed`)}for(let[e,n]of N.documents)if(!vS(e))try{let r=uN(e,t);if(!V(r)){let t=S(e)??``,r=$e(e)??``;if(r!==t&&_e.current){let t=_e.current;queueMicrotask(()=>{Jx(t,f??``,{kind:`external-change-rescue`,docName:e,contents:r,label:`External change recovered @ ${new Date().toISOString()}`,branch:i,metadata:{incomingDiskSha:``}}).then(()=>{Kb(),y.info({docName:e},`[reconcile] rescue checkpoint saved on branch switch: ${e}`)}).catch(t=>{y.error({docName:e,err:t},`[reconcile] rescue checkpoint write failed: ${e}`)})})}n.getMap(`lifecycle`).set(`status`,`deleted-upstream`),y.info({docName:e,branch:i},`[branch-switch] tombstone: ${e} (not on ${i})`);continue}let a=H(r,`utf-8`);et(e,a),C(e,a),y.info({docName:e},`[branch-switch] reset: ${e}`)}catch(t){y.error({err:t,docName:e},`[branch-switch] failed to reset ${e}`)}y.info({branch:i,docCount:N.documents.size},`[branch-switch] loaded branch ${i} (${N.documents.size} docs)`);try{await ge.settleBranchFromDisk(r)}catch(e){ge.abortBranchSwitch(r),y.error({err:e,branch:i},`[derived-index] branch-switch rebuild failed; relationship views may be stale`)}if(_e.current&&e.batchKind===`cross-branch`){let e=0;for(let[t]of N.documents)if(!vS(t))try{let n=await rse(_e.current,i,Ux.id,t);if(!n||n.markdown===n.diskSnapshot)continue;let r=S(t);if(!r)continue;let a=LR({docName:t,base:n.diskSnapshot,ours:n.markdown,theirs:r});switch(a.kind){case`merged`:case`clean`:et(t,a.newContent),C(t,a.newContent),e++;break;case`conflicts`:et(t,a.newContent),C(t,a.newContent),Hb(),e++;{let e=N.documents.get(t);if(e){let t=e.getMap(`lifecycle`);t.set(`status`,`conflict`),t.set(`reason`,`merged-with-markers`)}}break;case`noop`:case`refused`:break}}catch(e){y.error({err:e,docName:t},`[branch-switch] restore WIP failed for ${t}`)}e>0&&y.info({count:e,branch:i},`[branch-switch] restored ${e} parked docs on ${i}`)}if(e.oldBranch?.startsWith(`detached-`)&&_e.current)try{let t=Mx(_e.current),n=(await t.raw(`for-each-ref`,`refs/wip/${e.oldBranch}/`,`--format=%(refname)`)).trim();n&&(await Ox(_e.current).withMutator(async()=>{for(let e of n.split(`
2029
+ `)){let r=n.trim();if(r===``)continue;if(r.startsWith(`C\0`)){let[,e,t]=r.split(`\0`);o=e&&t?{name:e,email:t}:null;continue}if(!o||!r.endsWith(`.md`)&&!r.endsWith(`.mdx`))continue;let a=B(e,r);if(!dN(a,t))continue;let s=mz(a,t);i.has(s)||V(a)&&i.set(s,o)}return i}function p9(e){f9();let{contentDir:t,projectDir:n=t,quiet:r=!0,debounce:i=2e3,maxDebounce:a=1e4,gitEnabled:o=!0,commitDebounceMs:s=3e4,wipRef:c=`refs/wip/main`,configHomedirOverride:l,enableTestRoutes:u=!1,shadowRepo:d,contentRoot:f,destroyTimeoutMs:p=1e4,localOpCliArgs:m,authStreamHeartbeatMs:h,skipStateManifestCheck:g=!1,singleDocRelPath:_,ephemeral:v=!1}=e,y=I(`server`),b=new l7,x=()=>b.getActiveBranch(),S=e=>b.getReconciledBase(e),C=(e,t)=>b.setReconciledBase(e,t),w=e=>b.deleteReconciledBase(e),T=e=>b.switchReconciledBaseScope(e),E=e=>b.setBatchInProgress(e),ee=()=>b.isBatchInProgress();function D(){let e=Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config`)});if(!e.valid){let t=me(e.error)&&e.error.code===`SCHEMA_INVALID`?e.error.issues.filter(e=>e.path.map(String).join(`.`)===`content.attachmentFolderPath`):[];if(t.length>0){let e=t.map(e=>e.message).join(`; `);throw Error(`Invalid content.attachmentFolderPath in project config: ${e}`)}y.warn({},`[config] committed content.attachmentFolderPath unavailable (project config invalid) — using default attachment placement`)}return e.value.content.attachmentFolderPath??`./`}function O(){let e=Io({absPath:Qo(`project-local`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project-local config`)}),t=de(e.value.autoSync);if(t!==null)return{mode:t,source:`config`};e.valid||y.warn({},`[config] project-local autoSync.mode unavailable (config invalid) — falling back to the committed project default`);let r=Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config`)});return r.valid||y.warn({},`[config] committed autoSync.default unavailable (project config invalid) — defaulting to disabled`),{mode:je(r.value.autoSync?.default)??`off`,source:`committed-default`}}function k(){let e=Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config for linter`)}).value.contentRules;return e?Sn(e):Ui}function te(){return Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config for link validation`)}).value.validation?.links??`warning`}function ne(){return CM(n,{configHomedirOverride:l,onWarn:e=>y.warn({message:e},`[config] could not read project-local config`)})}function re(){let e=Io({absPath:Qo(`project-local`,n,l),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project-local config`)});return e.valid?e.value.linkPreviews?.enabled===!0:!1}function ie(){return Ro({cwd:n,homedirOverride:l,warn:e=>y.debug({message:e},`[config] diagnostics read`)})}function ae(){for(let e of ie().diagnostics)e.code===`REMOVED_KEY`&&y.warn({scope:e.scope,file:e.file,path:e.path.join(`.`)},`[config] ${e.path.join(`.`)} is no longer read and was ignored. ${e.redirect}`)}function oe(e){return`${fM(e.baseUrl)}|${e.model}|${e.dimensions??`auto`}`}function A(e){let t;if(e===`__config__/project`||e===`__local__/project`){let n=O();t=n.mode,ft?.setMode(n.mode,n.source).catch(t=>{y.warn({err:t,mode:n.mode,docName:e},`[sync] failed to apply autoSync mode from config`)})}let n=ne();F.applyConfig({enabled:n.enabled,providerFingerprint:oe(n)}),e===`__config__/project`&&Te?.signal(`lint-config`),y.info({docName:e,autoSyncMode:t,semanticEnabled:n.enabled},`[config] applied persisted config to in-process consumers`)}us();let j=Tu(),se=IO(n),ce=new md({localDir:se,log:I(`acp-registry`)}),le=new cd(se,I(`acp-permissions`));if(Bs(se,{port:e.port??0,worktreeRoot:n,kind:e.lockKind??`interactive`,capabilities:e.capabilities??[`http`,`ws`]}),!g)try{Z7({lockDir:se,shadowRepoDir:Uu(n)})}catch(e){throw Ms(se),e}let ue=Ma(),fe=(e,t)=>ue.resolveEmbed(e,t),pe=(e,n)=>{let r=ue.resolveEmbed(e,n);if(!r&&e.includes(`/`)&&(r=e.replace(/^\.?\//,``)),!r)return null;let i=B(t,r);if(!lN(i,B(t)))return null;try{let e=au(i);return e.isFile()?e.size:null}catch{return null}},he,ge,_e,M,ve,ye,N,xe,Se,Ce,we,Te=null,Ee=null,De=null,Oe=null,ke=null,Ae=null,P=ne(),F=new aue({loadEmbedder:e.embedderLoader??(()=>{let t=ne();return Gle({keyStore:e.embeddingsKeyStore??null,projectDir:n,config:{baseUrl:t.baseUrl,model:t.model,dimensions:t.dimensions}})}),cacheDir:R(IO(n),`embeddings`),enabled:P.enabled,providerFingerprint:oe(P)}),Me=null,Ne=new Set,Pe=!1,Fe=[],Ie,Le,Re,ze=new Promise((e,t)=>{Le=e,Re=t});function Be(e){Te?.signal(e)}let Ve=null,He=!1,Ue=()=>{try{H7(n,We.entries())}catch(e){y.warn({err:e},`[removed-docs-journal] failed to persist removal journal`)}},We=new HDe(void 0,{onEviction:()=>Aoe(),onSizeChange:e=>joe(e),onMutate:()=>{!He||Ve!==null||(Ve=setTimeout(()=>{Ve=null,Ue()},2e3))}});for(let[e,r]of GDe(n))vS(e)||_Q(e)&&([`.md`,`.mdx`].some(n=>{let r=B(t,`${e}${n}`);return lN(r,B(t))&&V(r)})||We.restore(e,r));He=!0;let Ge={current:null},Ke=(e,t)=>{vS(e)||We.setRenamed(e,t)},qe=e=>{if(!vS(e)){if(We.peek(e)?.kind===`renamed`){console.info(JSON.stringify({event:`recently-removed-docs-unpaired-delete-suppressed`,docName:e,source:`watcher-delete`}));return}We.setDeleted(e),Ge.current?.deleted(e)}},Je=e=>{vS(e)||We.delete(e)};try{he=dP({projectDir:n,contentDir:t,singleDocRelPath:_,inPlaceSkillDirs:lL(t),rescanInPlaceSkillDirs:()=>lL(t),onAfterRebuild:()=>{ge.refreshContentScope().catch(e=>{I(`server-factory`).warn({err:e},`[content-filter] derived-index rebuild failed after onAfterRebuild`)}),Lz(ut).then(({prunedFiles:e,prunedFolders:t})=>{let n=e+t;n>0?I(`server-factory`).info({pruned:n,prunedFiles:e,prunedFolders:t},`[content-filter] reconciled file indexes after onAfterRebuild`):I(`server-factory`).debug({prunedFiles:e,prunedFolders:t},`[content-filter] file index reconcile completed after onAfterRebuild (no entries pruned; rescan may have added entries)`)}).catch(e=>{I(`server-factory`).warn({err:e},`[content-filter] file index reconcile failed after onAfterRebuild`)})}}),ge=new jR({projectDir:n,contentDir:t,contentFilter:he,getGlobalSkillRoots:()=>_K(ve.managedArtifactCtx),signalChannel:Be}),_e={current:d},M=o?ADe({getShadow:()=>_e.current??null,getCurrentBranch:()=>dt?.getLastKnownBranch()??null,contentRoot:f??``,projectGitDir:Hu(n)??void 0,isWriterLive:e=>{if(!Oe&&!xe)return I(`server-factory`).debug({writerId:e},`[server-factory] isWriterLive called before liveness deps populated — treating writer as dead`),!1;if(Oe?.getPresenceMap()[e])return!0;let t=e.startsWith(`agent-`)?e.slice(6):e;for(let e of xe?.sessionsForConnection(t)??[])return!0;return!1}}):void 0,ve=F7({contentDir:t,projectDir:n,gitEnabled:o,commitDebounceMs:s,wipRef:c,shadowRef:_e,ephemeral:v,contentRoot:f,derivedDocumentIndex:ge,configHomedirOverride:l,getCurrentBranch:()=>dt?.getLastKnownBranch()??null,resolveEmbed:fe,resolveSize:pe,getPrincipal:()=>Me,onAgentCommit:()=>Te?.signal(`session-activity`),onFlushCommit:()=>M?.noteFlushCommit(),onDiskFlush:(e,t,n,r)=>{Te?.emitDiskAck(e,t),!vS(e)&&TB(r,n)&&(ke?.(),Be(`files`))},onConfigRejected:(e,t)=>Te?.emitConfigValidationRejected(e,t),onConfigPersisted:A,isRecentlyRemoved:e=>We.has(e),mdManager:e.mdManager,getLossRing:()=>ye,durabilityState:b}),N=new KEe({quiet:r,debounce:i,maxDebounce:a,extensions:[ve.extension]});let p=N;Fe.push(iw(()=>p.documents.size),aw(()=>ve.getQueueDepths()),sw(()=>{let e=0;for(let t of p.documents.values())e+=t.directConnectionsCount;return{websocket:p.getConnectionsCount()-e,direct:e}})),lw(),v||(Ae=BDe({getLoadedDocuments:()=>p.documents,forceStore:(e,t)=>ve.forceStore(e,t),getBase:e=>b.getReconciledBase(e),isBatchActive:()=>b.isBatchInProgress(),peekInFlight:e=>b.peekInFlightFlush(e),readDiskBytes:e=>{let n=uN(e,t),r,i;try{r=U(n),i=au(r).size}catch(t){let n=Ns(t);if(n===`ENOENT`)return null;throw n===`ELOOP`?new L7(`symlink cycle at content path: ${e}`):t}if(!dN(r,t))throw new L7(`symlink-escape: ${n} resolves outside the content dir`);if(i>524288)throw new L7(`document exceeds the open byte limit: ${e}`);try{return H(r,`utf-8`)}catch(e){if(Ns(e)===`ENOENT`)return null;throw e}},graceMs:e.stalenessGraceMs,sweepIntervalMs:e.stalenessSweepIntervalMs}));let g=N.shouldUnloadDocument.bind(N);N.shouldUnloadDocument=e=>{if(Ne.has(e)||Pe&&g(e))return!0;let t=e.name;return vS(t)||S(t)!==void 0||e.getXmlFragment(`default`).length!==0||e.getText(`source`).length!==0?!1:g(e)},Ie=async e=>{Ne.add(e);try{await N.unloadDocument(e)}finally{Ne.delete(e)}},Te=new xS(N),De=new qE(N),Oe=new JE(N),xe=new qw(N,e.agentSessionOptions);let C=xe;Fe.push(cw(()=>({active:C.liveSessionCount,limit:C.sessionLimit})));let w=p7({derivedDocumentIndex:ge,onDocumentSettled:e=>Ge.current?.changed(e)});N.configuration.extensions.push(w);function T(e,t,n={}){y.warn({reason:e,docName:t,...n},`[auth-rejection] ${e}`)}N.configuration.extensions.push({__kind:`principal-auth`,async onAuthenticate(e){let t=e.token,n=DQ(t),r=n?.expectedServerInstanceId;if(typeof r==`string`&&r.length>0&&r!==j)throw T(`server-instance-mismatch`,e.documentName,{claimedServerInstanceId:r,currentServerInstanceId:j}),new EQ(`server-instance-mismatch`,`server instance mismatch: client claimed ${r}, this server is ${j}`);let i=n?.expectedBranch,a=x();if(typeof i==`string`&&i.length>0&&i!==a)throw T(`branch-mismatch`,e.documentName,{claimedBranch:i,currentBranch:a}),new EQ(`branch-mismatch`,`branch mismatch: client claimed ${i}, server is on ${a}`);if(!n)return;let o=e.context;typeof n.principalId==`string`&&(Me&&n.principalId===Me.id?o.principalId=Me.id:Me?console.warn(JSON.stringify({event:`principal-token-mismatch`,claimed:n.principalId,loaded:Me.id})):o.principalId=n.principalId),typeof n.tabSessionId==`string`&&(o.tabSessionId=n.tabSessionId),o.kind=`human`}}),N.configuration.extensions.push({__kind:`config-doc-admission-guard`,async onAuthenticate(t){if(!mS(t.documentName)&&!hS(t.documentName))return;let n=t.request,r=n.socket?.remoteAddress;if(r!==void 0&&!rB(r))throw T(`config-doc-admission-denied`,t.documentName,{check:`peer`}),Error(`config-doc admission requires loopback peer (peer=${r}, doc=${t.documentName})`);let i=t.requestHeaders,a=(i&&typeof i.get==`function`?i.get(`host`):null)??n.headers?.host??void 0,o=e.remotePublicHost!==void 0&&lB(a,e.remotePublicHost);if(!iB(a)&&!o)throw T(`config-doc-admission-denied`,t.documentName,{check:`host`}),Error(`config-doc admission requires a loopback or remote Host header (host=${a??`<absent>`}, doc=${t.documentName})`)}});let E=B(t);function ee(e){if(!_Q(e))return null;let t=B(E,uS(e));return lN(t,E)?t:null}N.configuration.extensions.push({__kind:`removal-redirect-guard`,async onAuthenticate(e){await UDe(e.documentName,{recentlyRemovedDocs:We,resolveFilePath:ee,fileExists:V})}}),N.configuration.extensions.push({__kind:`doc-lineage-guard`,async onAuthenticate(e){let t=DQ(e.token);cDe(e.documentName,t?.expectedDocLineageEpoch,{getLoadedDoc:e=>N.documents.get(e)})}}),N.configuration.extensions.push({__kind:`system-doc-broadcast-guard`,async beforeHandleMessage(e){if(e.documentName!==`__system__`)return;let t=new D5(e.update);if(t.readVarString(),t.readVarUint()===R5.BroadcastStateless)throw Error(`inbound BroadcastStateless on ${eo} rejected — server-only channel`)}});let O=vQ({hocuspocus:N,durabilityState:b,remotePublicHost:e.remotePublicHost,sessionManager:xe,commentDocHooksRef:Ge,contentDir:t,contentFilter:he,serverInstanceId:j,getFileIndex:()=>ut?ut.getFileIndex():new Map,getAttachmentFolderPath:D,getAllFilesIndex:()=>ut?ut.getAllFilesIndex():new Map,getFileIndexGeneration:()=>ut?.getFileIndexGeneration()??0,mutateFileIndex:e=>ut?.mutateFileIndex(e),getFolderIndex:()=>ut?ut.getFolderIndex():new Map,getAliasMap:()=>ut?ut.getAliasMap():new Map,getFolderAliasIndex:()=>ut?ut.getFolderAliasIndex():new Map,rescanFiles:()=>ut?.rescanFromDisk(),enableTestRoutes:u,shadowRef:_e,flushGitCommit:()=>ve.flushPendingGitCommit(),flushContributors:()=>ve.flushContributors(),getCurrentBranch:()=>dt?.getLastKnownBranch()??null,getDiskAckSVs:()=>Te?.getLatestDiskAckSVsAsBase64()??{},contentRoot:f,derivedDocumentIndex:ge,signalChannel:Be,agentFocusBroadcaster:De,agentPresenceBroadcaster:Oe,onAgentWrite:e.onAgentWrite,getSyncEngine:()=>ft,localOpCliArgs:m,authStreamHeartbeatMs:h,projectDir:n,resolveEmbed:fe,getBridgeLossReporter:()=>we,getPrincipal:()=>Me,acpRegistry:ce,loadAcpCustomAgents:()=>hd(se,I(`acp-registry`)),homeDirOverride:l,forceUnloadDocument:Ie,ready:ze,recentlyRemovedDocs:We,serializeDoc:$e,evictManagedArtifactLkg:e=>{ve.managedArtifactCtx.lkgCache.delete(e)},semanticSearch:F,getSemanticSimilarityFloor:()=>ne().similarityFloor,getLinterBaseConfig:()=>k(),getLinksValidationSetting:()=>te(),getLinkPreviewsEnabled:re,getConfigDiagnostics:ie,embeddingsSecretsFile:bM(l),readSemanticProviderConfig:ne,ephemeral:v,onReferencedAssetsCacheInvalidator:e=>{ke=e}});N.configuration.extensions.push(O),Se=O.nativeApi,Ce=O.localApi;let ae=Io({absPath:Qo(`project`,n),sideline:!1,warn:e=>y.warn({message:e},`[config] could not read project config for bridge guards`)}),oe=ae.value.bridge.deferGuard.enabled,le=ae.value.bridge.fixedPoint.enabled,ue=ae.value.bridge.preDrain.enabled;ye=ae.value.lossCapture.enabled?new kb({projectDir:n,maxBytes:ae.value.lossCapture.maxBytes}):void 0,ae.value.bridge.lossDetector.enabled&&(we=use({shadow:()=>_e.current,ring:ye,getBranch:()=>dt?.getLastKnownBranch()??`main`,contentRoot:f??``}),xe.attachBridgeLossReporter(we)),N.configuration.extensions.push(W7({mdManager:Mo,schema:jo,shadowRef:_e,contentRoot:f,getCurrentBranch:()=>dt?.getLastKnownBranch()??null,resolveEmbed:fe,resolveSize:pe,deferGuardEnabled:oe,lossDetectorEnabled:ae.value.bridge.lossDetector.enabled,fixedPointBackstopEnabled:le,preDrainEnabled:ue,lossRing:ye})),N.configuration.extensions.push(kOe()),N.configuration.extensions.push(sDe({getSyncEngine:()=>ft,projectDir:n,contentDir:t}))}catch(e){for(let e of Fe.splice(0))e();throw Ae?.dispose(),Ae=null,Ms(se),e}let Ye=null,Xe=new Map,Ze=[];function Qe(e,t){let n=B(e,`rescue`),r=B(n,uS(t));return lN(r,n)?r:null}function $e(e){let t=N.documents.get(e);return t?WR(t):null}let et=(e,t)=>VR(b,N,e,t,fe,pe,we);function tt(e){if(!AS(e)||ft?.getConflicts().some(r=>c7(r,e.name,n,t)))return;let r=e.getMap(`lifecycle`);r.delete(`status`),r.delete(`reason`)}let nt=e=>{if(!e)return;let t=`[[${e}]]`;for(let[n]of N.documents){if(vS(n))continue;let r=N.documents.get(n);if(!r)continue;let i=r.getText(`source`).toString();if(i.includes(t))try{r.transact(()=>{NR(r,i,fe,n)},MR)}catch(t){y.error({err:t,docName:n,assetBasename:e},`[asset-event] failed to re-render ${n} for asset basename ${e}`)}}},rt=null,it=e=>{e&&(rt===null&&(rt=new Set,setImmediate(()=>{let e=rt;if(rt=null,e)try{for(let t of e)nt(t)}catch(t){y.error({err:t,basenames:[...e]},`[asset-event] dedup rerender pass crashed`)}})),rt.add(e))};function at(e){switch(e.kind){case`rename`:return e.newDocName;case`asset-create`:case`asset-delete`:case`folder-create`:case`folder-delete`:case`file-create`:case`file-update`:case`file-delete`:return e.relativePath;case`create`:case`update`:case`delete`:case`conflict`:return e.docName;default:return XR(e)}}async function ot(e){try{switch(e.kind){case`create`:y.info({docName:e.docName},`[reconcile] create: ${e.docName}`),await ge.recordDiskUpsert(e.docName,e.content),Be(`files`),Je(e.docName);break;case`update`:{let{docName:t,content:n}=e,r=N.documents.get(t);if(!r){await ge.recordDiskUpsert(t,n);return}let i=S(t)??``,a=$e(t)??i,o=LR({docName:t,base:i,ours:a,theirs:n}),s=rz(i).slice(0,6),c=rz(a).slice(0,6),l=rz(n).slice(0,6);switch(y.info({docName:t,base:s,ours:c,theirs:l,result:o.kind},`[reconcile] ${t} base=${s} ours=${c} theirs=${l} result=${o.kind}`),o.kind){case`noop`:tt(r),await ge.recordDiskUpsert(t,n);break;case`clean`:{let e=!1;try{et(t,o.newContent),C(t,o.newContent),Vb(),tt(r),e=!0}catch(e){y.error({err:e,docName:t},`[reconcile] failed to apply clean content to Y.Doc for ${t}`),C(t,n),tt(r)}e&&await ge.recordDiskUpsert(t,n)}break;case`merged`:{let e=!1;try{et(t,o.newContent),C(t,n),Vb(),tt(r),e=!0}catch(e){y.error({err:e,docName:t},`[reconcile] failed to apply merged content to Y.Doc for ${t}`),C(t,n),tt(r)}e&&await ge.recordDiskUpsert(t,n)}break;case`conflicts`:{let e=!1;try{et(t,o.newContent),C(t,o.newContent),Vb(),Hb(),e=!0}catch(e){y.error({err:e,docName:t},`[reconcile] failed to apply conflict content to Y.Doc for ${t}`),C(t,n)}{let e=r.getMap(`lifecycle`);e.set(`status`,`conflict`),e.set(`reason`,`merged-with-markers`)}e&&await ge.recordDiskUpsert(t,n);break}case`refused`:{Hb();let e=r.getMap(`lifecycle`);e.set(`status`,`conflict`),e.set(`reason`,o.reason);break}}break}case`delete`:{let{docName:t}=e,n=N.documents.get(t);if(!n){await ge.recordDiskDelete(t),Be(`files`),qe(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));return}let r=S(t)??``,i=$e(t)??``,a=i!==r;if(a&&_e.current){let e=_e.current,n=dt?.getLastKnownBranch()??`main`;queueMicrotask(()=>{Jx(e,f??``,{kind:`external-change-rescue`,docName:t,contents:i,label:`External change recovered @ ${new Date().toISOString()}`,branch:n,metadata:{incomingDiskSha:``}}).then(()=>{Kb(),y.info({docName:t},`[reconcile] rescue checkpoint saved (delete): ${t}`)}).catch(e=>{y.error({docName:t,err:e},`[reconcile] rescue checkpoint write failed: ${t}`)})})}n.getMap(`lifecycle`).set(`status`,`deleted-upstream`),w(t),await ge.recordDiskDelete(t),y.info({docName:t,isDirty:a},`[reconcile] delete: ${t} (dirty=${a})`),N.closeConnections(t),await Ie(n),Be(`files`),qe(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));break}case`rename`:{let{oldDocName:t,newDocName:n,content:r}=e,i=N.documents.get(t);if(w(t),C(n,r),await ge.recordDiskRename(t,n,r),i){let e=i.getMap(`lifecycle`);e.set(`status`,`renamed`),e.set(`newPath`,n)}y.info({oldDocName:t,newDocName:n},`[reconcile] rename: ${t} → ${n}`),Be(`files`),Ke(t,n),console.info(JSON.stringify({event:`recently-removed-docs-populate`,from:t,to:n,kind:`renamed`,source:`watcher-rename`}));break}case`conflict`:{let{docName:t}=e,n=N.documents.get(t);if(!n)return;let r=$e(t);r===null?y.warn({docName:t},`[reconcile] case 'conflict': serializeDoc returned null for ${t}; reconciledBase snapshot skipped — post-resolution reconcile may degrade to 3-way merge`):C(t,r);let i=n.getMap(`lifecycle`);i.set(`status`,`conflict`),i.set(`reason`,`conflict-markers`),y.info({docName:t},`[reconcile] conflict markers detected: ${t}`);break}case`asset-create`:ue.add(e.relativePath),Be(`files`),it(Dl(e.relativePath));break;case`asset-delete`:ue.remove(e.relativePath),Be(`files`),it(Dl(e.relativePath));break;case`folder-create`:case`folder-delete`:Be(`files`);break;case`file-create`:case`file-update`:case`file-delete`:Be(`files`);break;default:XR(e)}}catch(t){let n=at(e);y.error({err:t,kind:e.kind,label:n},`[reconcile] failed to handle ${e.kind} for ${n}`)}}let st=[];async function ct(e){if(ee()){st.push(e);return}await ot(e)}async function lt(){let e=st.splice(0,st.length);for(let t of e)await ot(t)}let ut=null,dt=null,ft=null,pt=null;async function mt(e){if(N.documents.size===0)return;let t=!1,n=new Promise(e=>{N.configuration.extensions.push({async afterUnloadDocument({instance:n}){!t&&n.getDocumentsCount()===0&&(t=!0,e())}})}),r=Array.from(N.documents.keys());N.closeConnections(),N.flushPendingStores();for(let e of N.documents.values())e.getConnectionsCount()===0&&N.unloadDocument(e).catch(t=>{console.warn(JSON.stringify({event:`ok-shutdown-unload-document-failed`,docName:e.name,reason:t instanceof Error?t.message:String(t)}))});let i,a=new Promise((n,a)=>{i=setTimeout(()=>{t=!0;let n=Array.from(N.documents.keys()),i=[],o=[];if(_e.current){for(let e of n)if(!vS(e))try{let t=$e(e);if(t===null){y.warn({docName:e},`[rescue] skipping ${e} — document dropped from map mid-rescue`),o.push(e);continue}let n=Qe(_e.current.gitDir,e);if(!n){y.warn({docName:e,gitDir:_e.current.gitDir},`[rescue] path-traversal guard rejected docName: ${e}`),o.push(e);continue}Jl(L(n),{recursive:!0}),su(n,t,`utf-8`),Kb(),i.push(e),y.info({docName:e},`[rescue] rescue buffer saved on flush timeout: ${e}`)}catch(t){o.push(e),y.error({err:t,docName:e},`[rescue] failed to write rescue buffer for ${e}`)}}else y.warn({stillLoadedCount:n.length},`[rescue] shadow repo unavailable at flush timeout — ${n.length} doc(s) will be lost: [${n.join(`, `)}]`),o.push(...n);let s=i.length>0||o.length>0?` — rescued [${i.join(`, `)}]${o.length>0?`, lost [${o.join(`, `)}]`:``}`:``;a(Error(`flushAllStoresAndWait timeout after ${e}ms — ${n.length}/${r.length} docs did not unload: [${n.join(`, `)}]${s}`))},e)});try{await Promise.race([n,a])}finally{i!==void 0&&clearTimeout(i)}}async function ht(){return pt||(pt=(async()=>{let e=Date.now(),t=[];Pe=!0;for(let e of Fe.splice(0))e();try{await Ae?.dispose()}catch(e){y.warn({err:e},`[server] staleness watchdog drain failed during destroy`)}Ae=null;try{Hs(se)}catch(e){y.warn({err:e},`[server] failed to mark server.lock draining`)}if(Ve!==null&&(clearTimeout(Ve),Ve=null),He)try{H7(n,We.entries())}catch(e){y.warn({err:e},`[removed-docs-journal] failed to persist removal journal during shutdown`),t.push({phase:`removed-docs-journal-flush`,error:String(e)})}let r,i=await Promise.race([ze.then(()=>`completed`,e=>(y.debug({err:e},`[server] init incomplete during shutdown`),`failed`)),new Promise(e=>{r=setTimeout(()=>e(`timeout`),5e3)})]);r!==void 0&&clearTimeout(r),i===`timeout`&&y.warn({},`[server] init did not complete within 5s during shutdown`);let a=N.documents.size;M?.destroy();try{try{try{Ee&&=(clearTimeout(Ee),null),dt&&=(await dt.unsubscribe(),null),ut&&=(await ut.unsubscribe(),null);for(let{docName:e,cleanup:t}of Ze)try{await t()}catch(t){y.warn({err:t,docName:e},`[server] failed to stop config-file-watcher for ${e}`)}Ze.length=0}catch(e){t.push({phase:`watcher-unsubscribe`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-1 watcher unsubscribe failed`)}try{Te?.destroy(),Oe?.destroy(),Ye&&=(await Ye.disconnect(),null);for(let[e,t]of Xe)try{await t.disconnect()}catch(t){y.warn({err:t,docName:e},`[server] failed to disconnect ${e} during shutdown`)}Xe.clear()}catch(e){t.push({phase:`cc1-teardown`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-1b CC1 teardown failed`)}try{await xe.closeAll()}catch(e){t.push({phase:`agent-session-drain`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-2 agent session drain failed`)}try{await Ese()}catch(e){t.push({phase:`parse-pool-teardown`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-2b parse pool teardown failed`)}try{await mt(p)}catch(e){t.push({phase:`flush-all-stores`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-3 flush failed`)}ge.close();let e;try{await Promise.race([(async()=>{await ve.flushPendingGitCommit(),await ve.waitForPendingCommits()})(),new Promise((t,n)=>{e=setTimeout(()=>n(Error(`L2 git flush timeout`)),p)})])}catch(e){t.push({phase:`git-commit-flush`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-4 git commit flush failed`)}finally{e!==void 0&&clearTimeout(e)}try{ft&&=(await ft.destroy(),null)}catch(e){t.push({phase:`sync-engine-stop`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown sync-engine-stop failed`)}}finally{if(_e.current){let e;try{await Promise.race([Ox(_e.current).drain(),new Promise((t,n)=>{e=setTimeout(()=>n(Error(`shadow mutator drain timeout`)),p)})])}catch(e){t.push({phase:`shadow-mutator-drain`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-5 shadow mutator drain failed`)}finally{e!==void 0&&clearTimeout(e)}try{let e=(await Cs({baseDir:n,timeout:{block:5e3}}).revparse(`HEAD`)).trim();e&&su(B(_e.current.gitDir,`last-known-head`),e,`utf-8`)}catch{}try{Goe(_e.current)}catch(e){t.push({phase:`shadow-repo-release`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-5 destroyShadowRepo failed`)}}let r=Date.now()-e;t.length===0?y.info({documentCount:a,durationMs:r},`[server] shutdown flushed ${a} documents in ${r}ms`):y.warn({documentCount:a,durationMs:r,phaseErrors:t},`[server] shutdown flushed ${a} documents in ${r}ms with ${t.length} phase error(s)`)}}finally{try{Ms(se,{deferUnlinkToExit:!0})}catch(e){t.push({phase:`server-lock-release`,error:e instanceof Error?e.message:String(e)}),y.error({err:e},`[server] shutdown phase-6 releaseServerLock failed`)}try{await ls()}catch(e){t.push({phase:`telemetry-shutdown`,error:e instanceof Error?e.message:String(e)})}}})(),pt)}let gt=[];async function _t(){try{Me=await R7(n),y.info({principalId:Me.id},`[server] principal loaded`)}catch(e){y.warn({err:e},`[server] principal load failed — browser writes will use SERVICE_WRITER`)}if(!_e.current)try{_e.current=await Px(n),y.info({gitDir:_e.current.gitDir},`[server] history repo initialized at ${_e.current.gitDir}`)}catch(e){y.error({err:e},`[server] history repo init failed`),gt.push(`shadow-repo`)}if(_e.current){let e=null;try{e=sq(_e.current.gitDir),Aq(_e.current.gitDir,e),fq(_e.current.gitDir,e),y.info({entries:e.byTo.size},`[server] rename log loaded (${e.byTo.size} entries)`)}catch(e){y.warn({err:e},`[rename-log] boot-time load/sweep failed; rename history unavailable`)}if(e){let t=1e4;try{await Promise.race([jq(_e.current,e,{rebuild:!0}),new Promise((e,n)=>setTimeout(()=>n(Error(`boot-time GC exceeded ${t}ms`)),t))])}catch(e){y.warn({err:e},`[rename-log] boot-time GC/rebuild failed; index loaded without GC`)}}try{await M?.runBootMaintenance()}catch(e){y.warn({err:e},`[shadow-maintenance] boot maintenance failed (non-fatal)`)}}if(_e.current)try{await Mx(_e.current).raw(`rev-parse`,`--git-dir`)}catch(e){let t=e instanceof Error?e.message:String(e);if(t.includes(`not a git repository`)||t.includes(`invalid object`)){y.warn({},`[server] history repo appears corrupted — reinitializing`);try{_e.current=await Px(n)}catch(e){y.error({err:e},`[server] history repo reinit failed`),_e.current=void 0,gt.includes(`shadow-repo`)||gt.push(`shadow-repo`)}}else y.error({err:e},`[server] history repo check failed (transient?)`)}if(_e.current)try{let e=B(_e.current.gitDir,`last-known-head`),t=null;try{t=H(e,`utf-8`).trim()||null}catch{}let r=null;try{r=(await Cs({baseDir:n,timeout:{block:1e4}}).revparse(`HEAD`)).trim()||null}catch{}if(r!==null){if(r!==t){let e=`main`;try{let t=(await Cs({baseDir:n,timeout:{block:1e4}}).raw(`rev-parse`,`--abbrev-ref`,`HEAD`)).trim();t&&t!==`HEAD`&&(e=t)}catch{}y.info({lastKnownHead:t,currentHead:r,branch:e},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${r}, action=import`);try{await Gx(_e.current,f??``,t,r,e),Wb()}catch(e){y.warn({err:e},`[head-drift] commitUpstreamImport failed — continuing`)}}else y.info({currentHead:r},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${r}, action=noop`);try{su(e,r,`utf-8`)}catch(e){y.warn({err:e},`[head-drift] failed to write last-known-head`)}}}catch(e){y.warn({err:e},`[head-drift] check failed — continuing`)}try{let e=qK(t,n);if(e.recovered&&e.journal){let t=e.journal.version===2?e.journal.fromPath:e.journal.sourceDocName,n=e.journal.version===2?e.journal.toPath:e.journal.destinationDocName;y.warn({journalVersion:e.journal.version,fromPath:t,toPath:n,restoredDocNames:e.restoredDocNames},`[managed-rename] recovered pending rename ${t} -> ${n}`)}}catch(e){y.error({err:e},`[server] managed rename recovery failed`),gt.push(`managed-rename-recovery`)}try{let e=OL(n);(e.deleted>0||e.errors>0)&&y.info({scanned:e.scanned,deleted:e.deleted,errors:e.errors},`[upload-tempfile-sweep] swept ${e.deleted} orphan tempfile(s)`)}catch(e){y.error({err:e},`[server] upload-tempfile sweep failed`),gt.push(`upload-tempfile-sweep`)}try{Ye=await N.openDirectConnection(eo),Te?.emitServerInfo(j,x())}catch(e){y.error({err:e},`[server] failed to open __system__ direct connection — CC1 push disabled`),gt.push(`cc1-push`)}let r=v?[]:$i;for(let e of r)try{let t=await N.openDirectConnection(e);Xe.set(e,t)}catch(t){y.error({err:t,docName:e},`[server] failed to open ${e} direct connection — config bind degraded`),gt.push(`config-doc:${e}`)}let i=new Map([[Qr,Qo(`project`,n)],[di,Qo(`project-local`,n)],[Da,Qo(`user`,n,l)]]);for(let e of r){let t=i.get(e);if(t)try{y.info({docName:e,path:t},`[config-file-watcher] starting`);let n=await Z5(t,t=>{let n=N.documents.get(e);y.info({docName:e,hasDocument:n!==void 0,contentLength:t.length},`[config-file-watcher] file changed`);let r=s7(n??null,e,t,ve.configPersistenceCtx);y.info({docName:e,outcome:r},`[config-file-watcher] applyExternalConfigChange outcome`),A(e)});Ze.push({docName:e,cleanup:n}),y.info({docName:e,path:t},`[config-file-watcher] started`)}catch(n){y.warn({err:n,docName:e,path:t},`[config-file-watcher] failed to start for ${e}`),gt.push(`config-file-watcher:${e}`)}}if(!v){let e=(e,t)=>{let n=SK(e,ve.managedArtifactCtx);if(!n)return;let r=DK(N.documents.get(n)??null,n,t,ve.managedArtifactCtx);y.info({docName:n,outcome:r},`[managed-artifact-watcher] external change`),Be(`files`),Un(n)&&ge.refreshGlobalSkillNodes().catch(e=>{y.warn({err:e,docName:n},`[backlinks] global skill bundle re-ingest failed`)})},t=e=>{let t=SK(e,ve.managedArtifactCtx);Be(`files`),t&&Un(t)&&ge.refreshGlobalSkillNodes().catch(e=>{y.warn({err:e,docName:t},`[backlinks] global skill bundle prune failed`)})};try{let n=_K(ve.managedArtifactCtx),r=await jDe(n,e,t);Ze.push({docName:`__skill-files__`,cleanup:r}),y.info({roots:n},`[managed-artifact-watcher] skills started`)}catch(e){y.warn({err:e},`[managed-artifact-watcher] skills failed to start`),gt.push(`managed-artifact-watcher:skills`)}try{let e=B(mK(ve.managedArtifactCtx),`.ok`,`skill-state.yml`),t=await Z5(e,()=>{Be(`files`)});Ze.push({docName:`__skill-state__`,cleanup:t}),y.info({path:e},`[skill-state-watcher] started`)}catch(e){y.warn({err:e},`[skill-state-watcher] failed to start`),gt.push(`skill-state-watcher`)}}try{let e=B(t,`.okignore`),r=B(n,`.gitignore`),i=null;try{let e=Tl(`git`,[`rev-parse`,`--git-common-dir`],mN({cwd:n,encoding:`utf-8`,timeout:5e3}));if(e.status===0&&e.stdout){let t=R(B(n,e.stdout.trim()),`info`,`exclude`);V(L(t))&&(i=t)}}catch{}let a=i?[e,r,i]:[e,r],o=y;o.info({okignorePath:e,gitignorePath:r,gitInfoExcludePath:i,ephemeral:v},`[ignore-watcher] starting multi-path watcher for .okignore + .gitignore (+ .git/info/exclude when present)`);let s=v?null:await QEe(a,(t,r)=>{(async()=>{if(t===e)try{let e=s7(N.documents.get(`__config__/okignore`)??null,Xa,r,ve.configPersistenceCtx);o.info({docName:Xa,outcome:e},`[ignore-watcher] applyExternalConfigChange outcome`)}catch(e){o.error({err:e,changedPath:z(n,t)},`[ignore-watcher] applyExternalConfigChange failed; rebuild proceeds independently`)}let i=await he.rebuildIgnorePatterns();if(i.ok)o.info({changedPath:z(n,t),patternCount:i.patternCount,nestedFileCount:i.nestedFileCount,durationMs:i.durationMs},`[ignore-watcher] rebuild succeeded — broadcasting files channel`),Te?.signal(`files`);else{let e=z(n,t)||`.`;o.warn({changedPath:e,error:i.error.message},`[ignore-watcher] rebuild failed — emitting config-ignore-nested-error`),Te?.emitConfigIgnoreNestedError(e,i.error.message)}})().catch(e=>{o.error({err:e,changedPath:z(n,t)||`.`},`[ignore-watcher] handler threw`)})});s&&(Ze.push({docName:`__ignore-files__`,cleanup:s}),o.info({okignorePath:e,gitignorePath:r},`[ignore-watcher] multi-path watcher started`))}catch(e){y.warn({err:e,projectDir:n,contentDir:t},`[ignore-watcher] failed to start multi-path watcher`),gt.push(`ignore-files-watcher`)}let a=f7(n).branch??`main`;T(a);let o=ge.beginStartup(a),s=!1,c=performance.now();try{await Vo(`ok.boot.indexes`,void 0,async()=>{let{deletedDocNames:e,backlinkIndexDegraded:r}=await o.backlinksReady;r&&gt.push(`backlink-index`);let i=0;for(let t of e)vS(t)||We.peek(t)?.kind!==`renamed`&&(We.setDeleted(t),i++);i>0&&y.info({count:i},`[removal-guard] tombstoned docs deleted while the server was down`);let a=performance.now(),c=/^\.(?!ok\/)[A-Za-z0-9_-]+\/skills\//,u=he?lL(t):new Set,d=e=>{e.some(e=>c.test(z(t,e).split(Pl).join(`/`)))&&(Ee&&clearTimeout(Ee),Ee=setTimeout(()=>{Ee=null;try{aZ(n,t).then(e=>{e>0&&(y.info({refreshed:e},`[in-place-skills] re-synced recorded copies`),Te?.signal(`files`))}).catch(e=>y.warn({err:e},`[in-place-skills] copy re-sync failed`));let e=lL(t);if(!(e.size!==u.size||[...e].some(e=>!u.has(e))))return;u=e,he.rebuildIgnorePatterns().then(t=>{t.ok?(y.info({skillDirs:e.size},`[in-place-skills] canonical set changed — filter rebuilt`),Te?.signal(`files`)):y.warn({error:t.error.message},`[in-place-skills] filter rebuild failed after skill re-scan`)}).catch(e=>y.warn({err:e},`[in-place-skills] rebuild threw`))}catch(e){y.warn({err:e},`[in-place-skills] re-scan trigger failed`)}},500))};ut=await Vo(`ok.boot.seed-walk`,void 0,async()=>Iz(t,ct,he,{onRawBatch:d})),aZ(n,t).then(e=>{e>0&&y.info({refreshed:e},`[in-place-skills] boot copy re-sync`)}).catch(e=>y.warn({err:e},`[in-place-skills] boot copy re-sync failed`));{let e=l??du();aZ(e,e,sL(e)).then(e=>{e>0&&y.info({refreshed:e},`[in-place-skills] global boot copy re-sync`)}).catch(e=>y.warn({err:e},`[in-place-skills] global copy re-sync failed`))}mR(`seedWalkMs`,Math.round(performance.now()-a));{let e=B(t),n=0;for(let[t]of We.entries()){if(!_Q(t))continue;let r=B(e,`${t}${cS(t)}`);lN(r,e)&&V(r)&&(We.delete(t),n++)}n>0&&y.info({count:n},`[removal-guard] dropped journaled removal entries whose file re-appeared while the server was down`)}let f=await ge.settleStartupAfterWatcherSeed();s=!0,f.tagIndexDegraded&&gt.push(`tag-index`);let p=0;try{_===void 0?await xQ({contentDir:t,contentFilter:he,basenameIndex:ue,onSkip:(e,t,n)=>{p++,y.warn({reason:e,code:t,path:n},`[basename-index] skipped entry during seed (${e}${t?` ${t}`:``})`)}}):Pme({contentDir:t,basenameIndex:ue,onSkip:(e,t,n)=>{p++,y.warn({reason:e,code:t,path:n},`[basename-index] skipped entry during single-file seed (${e}${t?` ${t}`:``})`)}}),p>0&&(y.warn({count:p},`[basename-index] startup seed completed with ${p} skipped entries — embeds under inaccessible subtrees will not resolve`),gt.push(`basename-index-partial`))}catch(e){y.error({err:e},`[basename-index] startup seed failed`),gt.push(`basename-index`)}})}catch(e){if(y.error({err:e},`[server] disk bridge watcher failed to start`),gt.push(`file-watcher`),!s){let e=await ge.settleStartupAfterWatcherSeed();s=!0,e.tagIndexDegraded&&gt.push(`tag-index`)}}finally{mR(`indexesMs`,Math.round(performance.now()-c)),ut&&hR(`fileCount`,ut.getFileIndex().size)}try{dt=await pDe(n,async({trigger:e})=>{if(y.info({trigger:e},`[batch] begin trigger=${e}`),Ub(),N.flushPendingStores(),await ve.flushPendingGitCommit(),E(!0),_e.current){let e=x(),t=f7(n).branch??e,r=[];for(let[e,t]of N.documents){if(vS(e))continue;let n=null;if(t.transact(()=>{n=$e(e)},AOe),n===null)continue;let i=S(e)??n;r.push({docName:e,markdown:n,diskSnapshot:i})}if(r.length>0)try{let n=await tse(_e.current,e,Ux.id,r,t);n&&(Jb(),y.info({count:r.length,branch:e,sha:n.slice(0,8)},`[history] parked ${r.length} docs on ${e} → ${n.slice(0,8)}`))}catch(e){y.error({err:e},`[shadow] park failed`)}}},async e=>{let r=st.length,i=e.newBranch??`main`;if(y.info({kind:e.batchKind,headMoved:e.headMoved,docs:r,timeout:!!e.timeout},`[batch] end kind=${e.batchKind} headMoved=${e.headMoved} docs=${r}${e.timeout?` timeout`:``}`),e.batchKind===`within-branch`){if(E(!1),await lt(),e.headMoved&&e.newHead){let r=MOe(n,B(t),e.oldHead,e.newHead);if(r.size>0){Ej(r.keys());for(let[e,t]of r)Tj(e,rne(t.email),t.name,t.email,ed(e));await ve.flushContributors()}}if(await ve.flushDeferredStores(`within-branch`),ft!==null)try{await ft.reconcileConflictsFromGit()}catch(e){y.warn({err:e},`[head-watcher] sync engine conflict reconcile failed`)}}else{qb(),st.splice(0,st.length);let n=!1,r;try{T(i),r=await ge.beginBranchSwitch(i),he.rebuildDirCount();try{let e=0;ue.clear(),await xQ({contentDir:t,contentFilter:he,basenameIndex:ue,onSkip:(t,n,r)=>{e++,y.warn({reason:t,code:n,path:r,branch:i},`[basename-index] skipped entry during branch-switch reseed (${t}${n?` ${n}`:``})`)}}),e>0&&(y.warn({count:e,branch:i},`[basename-index] branch-switch reseed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve on this branch`),gt.includes(`basename-index-partial`)||gt.push(`basename-index-partial`))}catch(e){y.error({err:e,branch:i},`[basename-index] branch-switch reseed failed`)}for(let[e,n]of N.documents)if(!vS(e))try{let r=uN(e,t);if(!V(r)){let t=S(e)??``,r=$e(e)??``;if(r!==t&&_e.current){let t=_e.current;queueMicrotask(()=>{Jx(t,f??``,{kind:`external-change-rescue`,docName:e,contents:r,label:`External change recovered @ ${new Date().toISOString()}`,branch:i,metadata:{incomingDiskSha:``}}).then(()=>{Kb(),y.info({docName:e},`[reconcile] rescue checkpoint saved on branch switch: ${e}`)}).catch(t=>{y.error({docName:e,err:t},`[reconcile] rescue checkpoint write failed: ${e}`)})})}n.getMap(`lifecycle`).set(`status`,`deleted-upstream`),y.info({docName:e,branch:i},`[branch-switch] tombstone: ${e} (not on ${i})`);continue}let a=H(r,`utf-8`);et(e,a),C(e,a),y.info({docName:e},`[branch-switch] reset: ${e}`)}catch(t){y.error({err:t,docName:e},`[branch-switch] failed to reset ${e}`)}y.info({branch:i,docCount:N.documents.size},`[branch-switch] loaded branch ${i} (${N.documents.size} docs)`);try{await ge.settleBranchFromDisk(r)}catch(e){ge.abortBranchSwitch(r),y.error({err:e,branch:i},`[derived-index] branch-switch rebuild failed; relationship views may be stale`)}if(_e.current&&e.batchKind===`cross-branch`){let e=0;for(let[t]of N.documents)if(!vS(t))try{let n=await rse(_e.current,i,Ux.id,t);if(!n||n.markdown===n.diskSnapshot)continue;let r=S(t);if(!r)continue;let a=LR({docName:t,base:n.diskSnapshot,ours:n.markdown,theirs:r});switch(a.kind){case`merged`:case`clean`:et(t,a.newContent),C(t,a.newContent),e++;break;case`conflicts`:et(t,a.newContent),C(t,a.newContent),Hb(),e++;{let e=N.documents.get(t);if(e){let t=e.getMap(`lifecycle`);t.set(`status`,`conflict`),t.set(`reason`,`merged-with-markers`)}}break;case`noop`:case`refused`:break}}catch(e){y.error({err:e,docName:t},`[branch-switch] restore WIP failed for ${t}`)}e>0&&y.info({count:e,branch:i},`[branch-switch] restored ${e} parked docs on ${i}`)}if(e.oldBranch?.startsWith(`detached-`)&&_e.current)try{let t=Mx(_e.current),n=(await t.raw(`for-each-ref`,`refs/wip/${e.oldBranch}/`,`--format=%(refname)`)).trim();n&&(await Ox(_e.current).withMutator(async()=>{for(let e of n.split(`
2030
2030
  `))e&&await t.raw(`update-ref`,`-d`,e)}),y.info({context:e.oldBranch},`[branch-switch] cleaned up detached context ${e.oldBranch}`))}catch(e){y.error({err:e},`[branch-switch] detached cleanup failed`)}E(!1),await ve.flushDeferredStores(`discard-stale`),n=!0,Te?.emitBranchSwitched(i)}finally{ge.abortBranchSwitch(r),n||(E(!1),await ve.flushDeferredStores(`discard-stale`))}}if(e.headMoved&&e.newHead&&_e.current&&r>0){let t=f??`.`;try{let n=await Gx(_e.current,t,e.oldHead,e.newHead,i);Wb(),y.info({oldHead:e.oldHead?.slice(0,8)??`null`,newHead:e.newHead.slice(0,8),sha:n.slice(0,8)},`[history] upstream-import from ${e.oldHead?.slice(0,8)??`null`}..${e.newHead.slice(0,8)} → ${n.slice(0,8)}`)}catch(e){y.error({err:e},`[shadow] upstream-import failed`)}}})}catch(e){y.error({err:e},`[server] HEAD watcher failed to start`),gt.push(`head-watcher`)}function u(e){for(let r of e)try{let e=cN(z(t,R(n,r)));if(e.startsWith(`..`))continue;let i=rS(e),a=N.documents.get(i);if(!a)continue;let o=$e(i);o===null?y.warn({docName:i,file:r},`[sync] content conflict: serializeDoc returned null; reconciledBase snapshot skipped`):C(i,o);let s=a.getMap(`lifecycle`);s.set(`status`,`conflict`),s.set(`reason`,`sync-merge-conflict`),y.info({docName:i,file:r},`[sync] marked loaded content conflict`)}catch(e){y.warn({err:e,file:r},`[sync] failed to mark loaded content conflict`)}}function d(e){for(let r of e)try{let e=cN(z(t,R(n,r)));if(e.startsWith(`..`))continue;let i=N.documents.get(rS(e));i&&tt(i)}catch(e){y.warn({err:e,file:r},`[sync] failed to clear resolved content conflict`)}}let p=jOe(m),h=O();h.mode!==`off`&&y.info({mode:h.mode,source:h.source},`[sync] mode active at boot`);try{ft=new DOe({projectDir:n,contentDir:t,contentFilter:he,contentRoot:f,mode:h.mode,pullIntervalSeconds:e.pullIntervalSeconds,pushIntervalSeconds:e.pushIntervalSeconds,credentialArgs:p,cc1Broadcaster:Te,detectGh:e.detectGh,tokenStore:e.tokenStore,checkPushPermissionFn:e.checkPushPermissionFn,setBatchInProgress:e=>{E(e),e||ve.flushDeferredStores(`within-branch`).catch(e=>{y.error({err:e},`[persistence] deferred store drain failed after sync batch`)})},onStateChange:e=>{y.info({state:e},`[sync] state → ${e}`)},onContentConflictsDetected:u,onContentConflictsResolved:d,checkpointBeforeStrandedConversion:async({branch:e,ahead:t})=>{let n=_e.current;n&&await qx(n,f??``,{action:`pull-only-stranded-conversion`,context:{ahead:t}},e)},checkpointBeforeOverlayRestore:async({branch:e,paths:t})=>{let n=_e.current;n&&await qx(n,f??``,{action:`pull-only-overlay-restore`,context:{paths:t}},e)},onAutoDisable:async e=>{y.warn({reason:e},`[sync] auto-disabled — persisting to project-local config`);let t=await No({cwd:n,scope:`project-local`,patch:{autoSync:{enabled:!1}}});t.ok||y.error({result:t,reason:e,humanError:be(t.error),configPath:Qo(`project-local`,n)},`[sync] failed to persist auto-disable — next restart WILL re-enable sync and re-trigger the same failure. Check permissions on the config path.`)}}),await ft.start()}catch(e){y.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),ft=null}Be(`files`),ge.announceReadyViews();let g=pR();g!==void 0&&mR(`readyMs`,g),ae()}return _t().then(Le,e=>{ge.close(),Re(e)}),{hocuspocus:N,durabilityState:b,sessionManager:xe,nativeApi:Se,localApi:Ce,cc1Broadcaster:Te,agentFocusBroadcaster:De,agentPresenceBroadcaster:Oe,maintenanceCoordinator:M,contentFilter:he,basenameIndex:ue,serverInstanceId:j,destroy:ht,ready:ze,degraded:gt,lockDir:se,get syncEngine(){return ft},getLinkPreviewsEnabled:re,resolveEmbed:fe,acpRegistry:ce,acpPermissions:le}}function m9(e){return e/1048576}function NOe(){let e=process.memoryUsage();return{schemaVersion:1,capturedAt:new Date().toISOString(),snapshot:{rssMb:m9(e.rss),heapTotalMb:m9(e.heapTotal),heapUsedMb:m9(e.heapUsed),externalMb:m9(e.external),arrayBuffersMb:m9(e.arrayBuffers)}}}let h9=null,g9=null,_9=null;const v9=1e6;let y9=null,b9=null;Bo(()=>{h9=null,g9=null,_9=null,y9?.disable(),y9=null,b9=null});function POe(){if(h9)return;let e=ds().createObservableGauge(`ok.server.memory.usage_megabytes`,{description:`Server process memory by section. Bounded labels: section ∈ {heap_used, heap_total, rss, external, array_buffers}.`,unit:`MB`});e.addCallback(e=>{let{snapshot:t}=NOe();e.observe(t.heapUsedMb,{section:`heap_used`}),e.observe(t.heapTotalMb,{section:`heap_total`}),e.observe(t.rssMb,{section:`rss`}),e.observe(t.externalMb,{section:`external`}),e.observe(t.arrayBuffersMb,{section:`array_buffers`})}),h9=e}function FOe(){if(!g9){let e=ds().createObservableGauge(`ok.server.event_loop.delay_ms`,{description:`Event-loop delay percentiles over the last export window. Bounded labels: stat ∈ {p50, p99}.`,unit:`ms`});e.addCallback(e=>{if(!y9){y9=Lte({resolution:20}),y9.enable();return}e.observe(y9.percentile(50)/v9,{stat:`p50`}),e.observe(y9.percentile(99)/v9,{stat:`p99`}),y9.reset()}),g9=e}if(!_9){let e=ds().createObservableGauge(`ok.server.cpu.utilization`,{description:`Process CPU time as a fraction of wall time since the previous export. Bounded labels: mode ∈ {user, system}.`,unit:`1`});e.addCallback(e=>{let t=process.cpuUsage(),n=process.hrtime.bigint(),r=b9;if(b9={cpu:t,hrtimeNs:n},!r)return;let i=Number(n-r.hrtimeNs)/1e3;i<=0||(e.observe((t.user-r.cpu.user)/i,{mode:`user`}),e.observe((t.system-r.cpu.system)/i,{mode:`system`}))}),_9=e}}const x9=I(`skill-migrate`);function S9(e){return[{host:`agents`,root:`.agents/skills`},...Object.entries(e).filter(e=>e[1]!==null).map(([e,t])=>({host:e,root:t}))].sort((e,t)=>{let n=xD.indexOf(e.host),r=xD.indexOf(t.host);return(n===-1?xD.length:n)-(r===-1?xD.length:r)||e.host.localeCompare(t.host)})}const IOe=S9(Ve),LOe=S9(ri);function ROe(e,t){$o(L(t),{recursive:!0});try{Ko(e,t)}catch(n){if(!(n instanceof Error)||n.code!==`EXDEV`)throw n;ns(e,t,{recursive:!0}),rs(e,{recursive:!0,force:!0})}}function zOe(e,t,n){let r=wI(e,t,n);switch(r.kind){case`absent`:return{kind:`absent`};case`other`:return{kind:`occupied`,by:`different`};case`symlink`:return r.resolution===`target`?{kind:`store-link`}:{kind:`occupied`,by:`foreign-link`};case`dir`:return r.identity===`different`?{kind:`occupied`,by:`different`}:{kind:`same-copy`}}}function C9(e,t){let n;try{n=U(B(e,`.ok`,`skills`))}catch{n=B(e,`.ok`,`skills`)}return new Set(t.filter(t=>{try{return!U(B(e,t.dir)).startsWith(n+Pl)}catch{return!0}}).map(e=>e.name))}async function w9(e){let{projectDir:t,skillsRoot:n}=e,r=e.inPlaceNames??new Set,i=e.hostRoots??IOe,a={migrated:[],skipped:[]};if(!V(n))return a;let o;try{o=eu(n)}catch{return a}let s=z(t,n).split(Pl).join(`/`),c=new Set;for(let[e,n]of Object.entries(nZ(t)))for(let t of n)t.path.split(`/`).slice(0,-1).join(`/`)===s&&c.add(e);for(let e of o)try{if(!Ue.test(e)||GF.has(e))continue;if(r.has(e)){a.skipped.push({name:e,reason:`placement-of-in-place`});continue}if(c.has(e)){a.skipped.push({name:e,reason:`recorded-placement`});continue}let o=B(n,e);if(!V(R(o,`SKILL.md`)))continue;let s=hD(o)?.contentHash;if(s===void 0)continue;let l=U(o),u=i.map(({host:n,root:r})=>{let i=B(t,r);return{host:n,root:r,path:R(i,e),escapes:MI(t,i),state:zOe(R(i,e),l,s)}}).filter(e=>!e.escapes),d=u.find(e=>e.state.kind===`store-link`||e.state.kind===`same-copy`)??u.find(e=>e.state.kind===`absent`&&V(B(t,e.root)))??u.find(e=>e.host===`claude`);if(!d){a.skipped.push({name:e,reason:`no-usable-target`});continue}if(d.state.kind===`occupied`){a.skipped.push({name:e,reason:`target-occupied:${d.root} (${d.state.by})`});continue}d.state.kind===`same-copy`?rs(o,{recursive:!0,force:!0}):(d.state.kind===`store-link`&&rs(d.path,{recursive:!0,force:!0}),ROe(o,d.path));for(let e of u)e===d||e.state.kind!==`store-link`||(rs(e.path,{recursive:!0,force:!0}),ns(d.path,e.path,{recursive:!0}));await UN(t,e),a.migrated.push({name:e,to:`${d.root}/${e}`}),x9.info({skill:e,to:`${d.root}/${e}`},`migrated store skill in place`)}catch(t){a.skipped.push({name:e,reason:`error`}),x9.warn({err:t,skill:e},`store-skill migration skipped one entry after error`)}return a}const T9=I(`skill-reconcile`),BOe=GF;function E9(){let e=[];for(let t of fa){let n=Ve[t];n!==null&&e.push({rel:n,editor:t})}return e.push({rel:`.agents/skills`,editor:null}),e}function VOe(e,t){let n=z(e,B(t));return Al(n)?B(t):n}function D9(e){let{frontmatter:t,body:n}=qn(e),r={};if(t!==``)try{let e=(0,WD.parse)(bt(t));e&&typeof e==`object`&&!Array.isArray(e)&&(r=e)}catch{}return{fm:r,body:n}}function HOe(e,t){let n=D9(e),r=D9(t);if(n.body!==r.body)return!1;for(let e of Object.keys(n.fm))if(e in r.fm&&JSON.stringify(n.fm[e])!==JSON.stringify(r.fm[e]))return!1;return!0}function O9(e,t){let n=k9(e),r=k9(t);if(n.length!==r.length)return!1;let i=0;for(let a=0;a<n.length;a+=1){if(n[a]!==r[a])return!1;let o=n[a],s=R(e,o),c=R(t,o);if(i+=au(s).size+au(c).size,i>1048576)return!1;let l=H(s),u=H(c);if(!l.equals(u)&&(o!==`SKILL.md`||!HOe(l.toString(`utf8`),u.toString(`utf8`))))return!1}return!0}function k9(e,t=``){let n=[];for(let r of eu(e,{withFileTypes:!0})){let i=t?`${t}/${r.name}`:r.name;r.isDirectory()?n.push(...k9(R(e,r.name),i)):r.isFile()&&n.push(i)}return n.sort()}function A9(e,t,n){rs(t,{recursive:!0,force:!0}),$o(e,{recursive:!0}),Yo(VOe(e,n),t,`dir`)}function j9(e,t){try{let n=tu(e);return B(Al(n)?n:B(L(e),n))===B(t)}catch{return!1}}function UOe(e,t){try{let n=tu(e),r=Al(n)?B(n):B(L(e),n);if(!V(r))return!1;let i=z(B(t),r);return i!==``&&(i.startsWith(`..`)||Al(i))}catch(t){return T9.warn({linkPath:e,err:t},`isForeignSymlink: could not resolve symlink; treating as reconcile-managed`),!1}}const WOe=[...fa,`agents`];function GOe(e){for(let t of WOe){let n=`-${t}`;if(e.length>n.length&&e.endsWith(n))return e.slice(0,-n.length)}return null}function KOe(e){let{projectDir:t,skillsRoot:n}=e;if(!V(n))return;let r;try{r=eu(n)}catch{return}let i=E9();for(let e of r){let r=GOe(e);if(r===null)continue;let a=B(n,e),o=B(n,r);if(V(o))try{let n=ql(a);if(n.isSymbolicLink()||!n.isDirectory()||!V(R(a,`SKILL.md`))||!V(R(o,`SKILL.md`))||!O9(o,a))continue;for(let{rel:n}of i){let r=B(t,n);if(MI(t,r))continue;let i=R(r,e);j9(i,a)&&A9(r,i,o)}rs(a,{recursive:!0,force:!0}),T9.info({base:r,suffixed:e},`collapsed accreted suffix-duplicate skill into its base`)}catch(t){T9.warn({err:t,base:r,suffixed:e},`suffix-dupe collapse skipped one entry after error`)}}}async function qOe(e){let{projectDir:t,skillsRoot:n}=e,r={healed:[],replaced:[],orphansRemoved:[],skipped:[]},i=new Map,a=(e,t)=>{if(t===null)return;let n=i.get(e)??new Set;n.add(t),i.set(e,n)};for(let{rel:e,editor:i}of E9()){let o=B(t,e);if(!V(o)||MI(t,o))continue;let s;try{s=eu(o)}catch(e){T9.warn({hostRoot:o,err:e},`reconcile: skipped unreadable host skills root`);continue}for(let e of s){if(BOe.has(e))continue;let t=R(o,e),s=B(n,e),c=V(s);try{let l=ql(t);if(l.isSymbolicLink()){if(j9(t,s)&&c)continue;if(UOe(t,n)){r.skipped.push({name:e,editor:i});continue}c?(A9(o,t,s),r.healed.push({name:e,editor:i})):(rs(t,{recursive:!0,force:!0}),r.orphansRemoved.push({name:e,editor:i}));continue}if(!l.isDirectory())continue;if(!Ue.test(e)){T9.warn({skill:e,editor:i},`reconcile: skipping host-dir entry with a non-skill name`);continue}if(c&&O9(t,s)){A9(o,t,s),r.replaced.push({name:e,editor:i}),a(e,i);continue}r.skipped.push({name:e,editor:i})}catch(t){T9.warn({err:t,skill:e,editor:i},`reconcile skipped one skill entry after error`)}}}if(i.size>0){let e=BN(t);for(let[r,a]of i){let i=B(n,r);if(!V(i))continue;let o=e.skills[r],s=Array.from(new Set([...o?.hosts??[],...a]));try{await HN(t,r,{hosts:s,scope:o?.scope??`project`,scripts:o?.scripts??DI(i,r).hasScripts,installedAt:o?.installedAt??new Date().toISOString()})}catch(e){T9.warn({err:e,skill:r},`reconcile marker update failed (non-fatal)`)}}}try{KOe({projectDir:t,skillsRoot:n})}catch(e){T9.warn({err:e},`suffix-dupe collapse pass failed (non-fatal)`)}return r}let M9=null,N9=!1;function P9(e=process.env){return e.OK_BRIDGE_TOLERANCE_TELEMETRY===`1`}function F9(e){if(!P9())return;let t=IO(e);M9=new bs({currentPath:B(t,`tolerance-telemetry.jsonl`),previousPath:B(t,`tolerance-telemetry.prev.jsonl`),maxBytes:8388608}),xa(e=>{let t={event:`bridge-tolerance-fire`,timestamp:e.timestamp,class:e.className,document:e.documentName??null,codeUnitPosition:e.codeUnitPosition,severity:e.severity};M9?.append(`${JSON.stringify(t)}\n`).catch(e=>{N9||(N9=!0,I(`tolerance-telemetry`).warn({err:e instanceof Error?e:Error(String(e))},`append failed; further failures are silent`))})})}async function I9(){xa(null),await M9?.drain(),M9=null,N9=!1}ko();const JOe=[`server.lock`,`ui.lock`,`state.json`,`principal.json`,`sync-state.json`,`conflicts.json`,`last-spawn-error.log`],YOe=[`cache`,`tmp`];function XOe(e){let t=B(e,ge);if(!(()=>{if(!V(t))return!0;try{return eu(t).length===0}catch{return!0}})())return[];let n=[];for(let t of JOe)V(B(e,t))&&n.push(t);for(let t of YOe){let r=B(e,t);try{V(r)&&au(r).isDirectory()&&n.push(`${t}/`)}catch{}}return n}function ZOe(e){let t=Vu(e);switch(t.kind){case`directory`:return{kind:`main`,gitdir:t.path};case`linked`:return{kind:`linked`,gitdir:t.path};case`malformed-pointer`:return{kind:`linked`,gitdir:null};case`inaccessible`:case`absent`:return{kind:`main`,gitdir:null}}}const L9=Number(process.env.OK_DESTROY_STEP_TIMEOUT_MS)||5e3;async function QOe(e){fR();let t=e.projectDir??e.contentDir,n=Vme({projectDir:t});if(n){let e=n.telemetry.attributeDenylist,t=[];for(let n of e){t.push(n);for(let e=1;e<=5;e++)t.push(`${`*.`.repeat(e)}${n}`)}gs.configure({pinoConfig:{fileSink:n.logs,redactPaths:t}})}us({localSink:n?.telemetry}),F9(t),POe(),FOe();let{kind:r,gitdir:i}=ZOe(e.projectDir??e.contentDir),a={"ok.worktree.kind":r};i!==null&&(a[`ok.worktree.gitdir`]=ts(i));let o=zme(t),s=process.env.OK_STARTUP_TRACEPARENT,c=()=>Vo(`ok.boot`,{attributes:a},async()=>$Oe(e)),l=()=>{if(s)try{let e=Do.extract(Ao.active(),{traceparent:s});return Ao.with(e,c)}catch(e){I(`boot`).warn({err:e},`ok.boot trace-join failed — starting unparented boot`)}return c()},u;try{u=await l()}catch(e){throw o.uninstall(),e}let d=u.destroy;return u.destroy=async()=>{try{await d()}finally{o.uninstall()}},u}async function $Oe(e){let t=e.skipAutoInit??!1,n=e.attachUiSibling??!0,r=e.log??I(`boot`),i=e.enableRemote===!0&&e.ephemeral!==!0?oB(e.config):null;if(e.enableRemote===!0&&e.ephemeral!==!0&&i===null)throw new aB("remote access was requested but remote.url is not set — pass a url (`ok start --remote <url>`) or set remote.url in .ok/config.yml.");let a=i===null?e.idleShutdownMs:null,o=process.env.OK_LOCK_KIND===`mcp-spawned`||process.env.OK_LOCK_KIND===`interactive`?process.env.OK_LOCK_KIND:void 0,s=e.lockKind??o??`interactive`,{createServer:c}=await import(`node:http`),{markServerLockDraining:l,releaseServerLock:u,updateServerLockPort:d}=await import(`./server-lock-C_lebUd3.mjs`),f=!1;if(!t&&e.autoInitFn)try{f=!!await e.autoInitFn()}catch(e){r.warn({err:e},`autoInitFn failed`)}let p=e.projectDir??e.contentDir,h=B(p,`.ok`);if(!V(B(h,`config.yml`)))throw new X8(V(h)?`config`:`okdir`,p);let g=B(h,`.gitignore`);V(g)||I(`boot`).warn({path:g},"Note: .ok/.gitignore is missing — per-machine state files in .ok/ may show up as untracked changes. Run `ok init` to add the recommended ignore entries.");let _=e.gitPreflight??MG;try{e.gitEnabled!==!1&&_()}catch(e){if(e instanceof kG||e instanceof AG){let t=e instanceof AG?e.detected:``,n=e instanceof AG?`too_old`:`not_available`;ZG(e),r.warn({event:`git_preflight_fail`,platform:e.platform,reason:n,detectedVersion:t},n===`not_available`?`git binary not found`:`git binary too old`),process.stderr.write(`${e.message}\n`)}throw await ls(),await Promise.race([I9(),new Promise(e=>setTimeout(e,L9))]),e}let v=XOe(h);v.length>0&&I(`boot`).warn({files:v},`Found legacy runtime files at .ok/${v.join(`, `)}. Delete .ok/ and re-init — these files moved to .ok/${ge}/.`);let y=p9({contentDir:e.contentDir,projectDir:e.projectDir,remotePublicHost:i?.publicHost,contentRoot:e.contentRoot,port:e.port,host:e.host,quiet:e.quiet??!1,debounce:e.debounce,maxDebounce:e.maxDebounce,gitEnabled:e.gitEnabled,commitDebounceMs:e.commitDebounceMs,wipRef:e.wipRef,enableTestRoutes:e.enableTestRoutes,shadowRepo:e.shadowRepo,destroyTimeoutMs:e.destroyTimeoutMs,localOpCliArgs:e.localOpCliArgs,authStreamHeartbeatMs:e.authStreamHeartbeatMs,onAgentWrite:e.onAgentWrite,lockKind:s,capabilities:e.reactShellDistDir?[`http`,`ws`,`ui`]:[`http`,`ws`],skipStateManifestCheck:e.skipStateManifestCheck,detectGh:e.detectGh,tokenStore:e.tokenStore,embeddingsKeyStore:e.embeddingsKeyStore,singleDocRelPath:e.singleDocRelPath,ephemeral:e.ephemeral}),{hocuspocus:b,destroy:x,ready:S,degraded:C,lockDir:w,sessionManager:T,agentFocusBroadcaster:E,agentPresenceBroadcaster:ee,maintenanceCoordinator:D}=y,O=(()=>{let t=e.host??`localhost`;return t===`0.0.0.0`||t===`::`?`localhost`:t.includes(`:`)&&!t.startsWith(`[`)?`[${t}]`:t})(),k=e.port??0,te=e.ephemeral?void 0:U8({contentDir:e.contentDir,projectDir:e.projectDir??e.contentDir,config:e.config,getServerUrl:()=>`http://${O}:${k}`,localApi:y.localApi,log:r}),ne=c();ne.headersTimeout=3e4,ne.requestTimeout=6e4;let re=e.serveContentAssets===!1?void 0:yQ({contentFilter:y.contentFilter,contentSirv:Js(e.contentDir,{dev:!0,dotfiles:!1}),inlineExtensions:fe,assetExtensions:m,blocklistExtensions:ae}),ie=!1;if(e.reactShellDistDir)try{mL(w,{port:0,worktreeRoot:e.projectDir??e.contentDir}),ie=!0}catch(e){if(e instanceof pL)r.info({event:`ui-lock-yielded-to-live-holder`,pid:process.pid,existingPid:e.existing.pid,existingPort:e.existing.port,lockDir:w},`ui.lock already held by a live process — yielding (advertisement is fulfilled)`);else throw await x().catch(()=>{}),u(w),e}let oe=e.reactShellDistDir?Js(e.reactShellDistDir,{single:!0,gzip:!0,etag:!0,dev:!0}):void 0,A=e.ephemeral?null:new RE({contentDir:e.contentDir,localDir:w,globalDir:B(du(),`.ok`),registry:y.acpRegistry,permissions:y.acpPermissions,sessionManager:T,agentPresenceBroadcaster:ee,resolveEmbed:y.resolveEmbed,isExcludedPath:e=>y.contentFilter.isExcluded(e),isIgnoredPath:e=>y.contentFilter.isPathIgnored(e),getLoadedDocText:e=>b.documents.get(e)?.getText(`source`).toString()??null,getServerUrl:()=>`http://${O}:${k}`,getMcpStdioCommand:()=>LE(e.localOpCliArgs,k),probeHarnessManagedMcpEntry:e.probeHarnessManagedMcpEntry,log:r});A!==null&&await A.init(),i!==null&&r.info({url:i.url},`[remote] remote access enabled (trust-the-tunnel)`);let j=`pending`;S.then(()=>{j=`ready`},()=>{j=`failed`});let se=J8({httpServer:ne,hocuspocus:b,nativeApi:y.nativeApi,mcpHttpHandler:te,remoteAccess:i,health:{readiness:()=>j,degraded:()=>C},log:r,sessionManager:T,agentFocusBroadcaster:E,agentPresenceBroadcaster:ee,maintenanceCoordinator:D,keepaliveGraceMs:e.keepaliveGraceMs,contentAssetMiddleware:re,reactShellMiddleware:oe,ephemeral:e.ephemeral,acpThreadManager:A}),ce=async()=>{throw Error(`bootServer: destroy() invoked before initialization — boot did not complete`)},le=null;a!==null&&(le=NQ({httpServer:ne,thresholdMs:a??18e5,log:r,onShutdown:(e.idleShutdownHandler??(e=>async()=>{await e()}))(async()=>{await ce()})})),await R9({hocuspocus:b,projectDir:e.projectDir??e.contentDir,log:r});try{await new Promise((t,n)=>{let r=e=>n(e);ne.once(`error`,r),ne.listen(e.port,e.host,()=>{ne.removeListener(`error`,r),t()})})}catch(e){if(ie)try{_L(w)}catch(e){r.warn({err:e},`releaseUiLock failed during listen-error cleanup`)}throw await x().catch(()=>{}),u(w),e}let ue=pR();ue!==void 0&&mR(`httpListenMs`,ue);let de=ne.address(),pe=typeof de==`object`&&de?de.port:e.port??0;k=pe;let me=`http://${O}:${pe}`;if(d(w,pe,me),ie&&hL(w,pe,me),n&&e.spawnUiSiblingFn)try{await e.spawnUiSiblingFn({lockDir:w,log:r})}catch(e){r.warn({err:e},`spawnUiSiblingFn failed`)}let he=!1,_e=async(e,t)=>{let n;try{await Promise.race([t(),new Promise((t,r)=>{n=setTimeout(()=>{r(Error(`${e} timed out after ${L9}ms`))},L9),n.unref?.()})])}finally{n!==void 0&&clearTimeout(n)}};ce=async()=>{if(he)return;he=!0,j=`draining`;let e=[],t=async(t,n)=>{try{await _e(t,n)}catch(n){e.push(n),r.warn({err:n,step:t},`bootServer destroy step failed`)}};try{l(w),ie&&vL(w)}catch(e){r.warn({err:e,step:`markLocksDraining`},`bootServer destroy step failed`)}try{le?.detach()}catch(t){e.push(t),r.warn({err:t,step:`idleHandle.detach`},`bootServer destroy step failed`)}if(A!==null&&await t(`acpThreads.destroy`,()=>A.destroy()),await t(`mount.shutdown`,()=>se.shutdown()),te!==void 0&&await t(`mcpHttpHandler.close`,()=>te.close()),await t(`mount.wss.close`,()=>new Promise((e,t)=>{se.wss.close(n=>n?t(n):e())})),await t(`httpServer.closeAllConnections`,async()=>{ne.closeAllConnections?.()}),await t(`httpServer.close`,()=>new Promise((e,t)=>{ne.close(n=>n&&n.code!==`ERR_SERVER_NOT_RUNNING`?t(n):e())})),await t(`destroyHocuspocus`,()=>x()),ie&&await t(`releaseUiLock`,async()=>_L(w,{deferUnlinkToExit:!0})),await t(`shutdownTelemetry`,()=>ls()),await t(`teardownToleranceTelemetry`,()=>I9()),await t(`flushLogFileSinks`,()=>gs.flushAllFileSinks()),e.length>0)throw AggregateError(e,`bootServer destroy completed with errors`)};try{let t=await w9({projectDir:p,skillsRoot:B(e.contentDir,`.ok`,`skills`),inPlaceNames:C9(e.contentDir,oL(e.contentDir))});t.migrated.length+t.skipped.length>0&&r.info?.({event:`store-skills-migrated-in-place`,migrated:t.migrated,skipped:t.skipped},`Migrated ${t.migrated.length} store skill(s) in place (${t.skipped.length} skipped).`)}catch(e){r.warn?.({err:e,event:`store-skill-migration-failed`},`Store-skill in-place migration failed (non-fatal).`)}try{let e=du(),t=await w9({projectDir:e,skillsRoot:B(e,`.ok`,`skills`),hostRoots:LOe,inPlaceNames:C9(e,sL(e))});t.migrated.length+t.skipped.length>0&&r.info?.({event:`global-store-skills-migrated-in-place`,migrated:t.migrated,skipped:t.skipped},`Migrated ${t.migrated.length} global store skill(s) in place (${t.skipped.length} skipped).`)}catch(e){r.warn?.({err:e,event:`global-store-skill-migration-failed`},`Global store-skill in-place migration failed (non-fatal).`)}try{let t=await qOe({projectDir:p,skillsRoot:B(e.contentDir,`.ok`,`skills`)}),n=t.healed.length+t.replaced.length+t.orphansRemoved.length;n>0&&r.info?.({event:`installed-skills-reconciled`,healed:t.healed.length,replaced:t.replaced.length,orphansRemoved:t.orphansRemoved.length},`Reconciled ${n} editor skill entr${n===1?`y`:`ies`} to the symlink model.`)}catch(e){r.warn?.({event:`installed-skills-reconcile-failed`,err:e},`Installed-skills reconcile failed (non-fatal).`)}return{httpServer:ne,destroy:ce,lockDir:w,contentDir:e.contentDir,port:pe,ready:S,degraded:C,didAutoInit:f,serverInstance:y,runtime:YTe(y,{contentDir:e.contentDir,projectDir:p}),acpThreadManager:A}}async function R9(e){let{hocuspocus:t,projectDir:n,log:r}=e,i,a;try{i=new AQ(n),a=i.list()}catch(e){r.warn({err:e,projectDir:n},`[boot] lifecycle restore: failed to read conflicts.json — skipping`);return}if(a.length===0)return;let o=e=>e.variant===`working-tree`,s=null;try{let e=Hu(n),t=e?R(e,`MERGE_HEAD`):null;if(!t||!V(t)){let e=a.filter(e=>!o(e));for(let t of e)i.removeConflict(t.file);if(a=a.filter(o),e.length>0&&console.warn(JSON.stringify({event:`lifecycle-restore-cleared-stale-conflicts`,reason:`no-merge-head`,count:e.length})),a.length===0)return}else{let e=Ts({baseDir:n,timeout:{block:5e3}});s=new Set(await Lb(e,[`diff`,`--name-only`,`--diff-filter=U`]))}}catch(e){r.warn({err:e,projectDir:n},`[boot] lifecycle restore: git unmerged probe failed — restoring all entries`)}if(s!==null){let e=0;for(let t of a)!o(t)&&!s.has(t.file)&&(i.removeConflict(t.file),e++);if(e>0&&console.warn(JSON.stringify({event:`lifecycle-restore-pruned-resolved-entries`,pruned:e,remaining:a.length-e})),a=a.filter(e=>o(e)||s?.has(e.file)),a.length===0)return}for(let e of a){let n=rS(e.file),i=null,a=!1;try{i=await t.openDirectConnection(n);let e=i.document;if(!e)continue;let r=e.getMap(`lifecycle`);r.set(`status`,`conflict`),r.set(`reason`,`conflict-markers`),a=!0,console.warn(JSON.stringify({event:`lifecycle-restored-from-conflicts-json`,"doc.name":n}))}catch(e){r.warn({err:e,docName:n},`[boot] lifecycle restore: failed to set lifecycle for doc — skipping`)}finally{if(i)try{await i.disconnect()}catch(e){r.warn({err:e,docName:n,restored:a},`[boot] lifecycle restore: disconnect failed after lifecycle write`)}}}}const eke=ee;function tke(e={}){let t=e.home??du(),n=e.platformName??process.platform,r=e.env??process.env;return n===`darwin`?V(R(t,`Library`,`Application Support`,`Claude`)):n===`win32`?V(R(r.APPDATA??R(t,`AppData`,`Roaming`),`Claude`)):!1}var z9=t(ys(),1);const B9=R(du(),`.ok`,`logs`),nke=[`authorization`,`password`,`token`,`apiKey`,`secret`,`*.authorization`,`*.password`,`*.token`,`*.apiKey`,`*.secret`];function rke(){let e=process.env.OK_LOG_LEVEL??process.env.LOG_LEVEL;if(e){let t=[`fatal`,`error`,`warn`,`info`,`debug`],n=e.toLowerCase();if(t.includes(n))return n}return process.env.NODE_ENV===`test`?`silent`:`info`}function ike(e){Jl(e,{recursive:!0})}function V9(){return new Date().toISOString().slice(0,10)}function ake(e){try{if(au(e).size<5242880)return}catch{return}for(let t=2;t>=1;t--){let n=t===1?e:`${e}.${t-1}`,r=`${e}.${t}`;try{nu(n,r)}catch{}}try{ou(`${e}.3`)}catch{}}function oke(e){try{let t=Date.now(),n=10080*60*1e3,r=eu(e).filter(e=>e.endsWith(`.log`)||/\.log\.\d+$/.test(e)).map(t=>{try{let n=au(R(e,t));return{name:t,mtime:n.mtimeMs,size:n.size}}catch{return null}}).filter(Boolean);for(let i of r)if(t-i.mtime>n)try{ou(R(e,i.name))}catch{}let i=r.filter(e=>t-e.mtime<=n).sort((e,t)=>e.mtime-t.mtime),a=i.reduce((e,t)=>e+t.size,0);for(let t of i){if(a<=47185920)break;try{ou(R(e,t.name)),a-=t.size}catch{}}}catch{}}function ske(e){ike(B9);let t=V9(),n=e.filePath??R(B9,`${e.name}.${t}.log`);ake(n),(e._setTimeout??setTimeout)(()=>oke(B9),5e3).unref();let r=z9.default.destination({dest:n,append:!0,sync:!0});return(0,z9.default)({level:rke(),name:e.name,redact:{paths:nke,censor:`[REDACTED]`},base:{pid:process.pid,hostname:void 0,runtime:`cli`,project:e.project??`<no-project>`},timestamp:z9.default.stdTimeFunctions.isoTime,...e.additionalOptions},r)}function cke(e,t=250){return new Promise(n=>{if(!e){n();return}let r=e[z9.default.symbols.streamSym],i=!1,a=()=>{i||(i=!0,n())};if(!r||typeof r.flushSync!=`function`){a();return}let o=()=>{try{r.flushSync?.()}catch{}a()},s=setTimeout(a,t);typeof s.unref==`function`&&s.unref(),typeof r.fd==`number`&&r.fd>=0?(clearTimeout(s),o()):typeof r.once==`function`?r.once(`ready`,()=>{clearTimeout(s),o()}):(clearTimeout(s),o())})}function lke(e){return R(B9,`${e}.${V9()}.log`)}function uke(){return B9}function dke(e){let t=B(e),n=0;for(;n<30;){let e=!1;try{e=V(B(t,`.git`))}catch{e=!1}if(e)return{gitRoot:t,distance:n};let r=L(t);if(r===t)return null;t=r,n+=1}return null}const H9=ju(Sl),U9=I(`project-git`);var W9=class extends Error{stderr;constructor(e,t=``,n){super(e,n),this.name=`ProjectGitInitError`,this.stderr=t}};async function fke(e,t){try{let{stdout:n}=await H9(e,[`rev-parse`,`--is-inside-work-tree`],mN({cwd:t,encoding:`utf-8`}));return n.trim()===`true`}catch{return!1}}async function pke(e){let t=B(e),n=B(t,`.git`),r=B(n,`HEAD`),i=!1;if(V(n)){if(!au(n).isDirectory()||V(r))return{didInit:!1};U9.info({},`detected partial .git/ — running git init to repair`),i=!0}let a;try{a=MG()}catch(e){throw e instanceof kG||e instanceof AG?(ZG(e),U9.warn({event:`git_preflight_fail`,platform:e.platform,reason:e instanceof AG?`too_old`:`not_available`,detectedVersion:e instanceof AG?e.detected:``},e instanceof AG?`git binary too old`:`git binary not found`)):U9.warn({event:`git_preflight_unexpected_error`,err:e},`unexpected error during git preflight`),e}let o=a.resolvedPath;if(!i&&await fke(o,t))return{didInit:!1};let s=``;try{s=(await H9(o,[`init`,`--initial-branch=main`,t],mN({encoding:`utf-8`}))).stderr??``}catch(e){let n=typeof e==`object`&&e&&`stderr`in e?String(e.stderr??``):``;throw new W9(`git init failed at ${t}: ${e instanceof Error?e.message:String(e)}`,n,{cause:e})}if(!V(r))throw new W9(`git init reported success but ${n}/HEAD is missing (partial init detected)`,s);return i?(U9.info({path:t},`backfilled missing .git/HEAD`),{didInit:!0,repaired:!0}):(U9.info({path:t,branch:`main`},`initialized .git/`),{didInit:!0})}const G9=I(`project-skill-git`),K9=/^[0-9a-f]{40}$/,mke=Pa.map(e=>e.replace(/\/$/,``));async function hke(e){let t=Hu(e);if(t===null)return{kind:`skipped`,reason:`no-git`};if(yke(t))return{kind:`skipped`,reason:`operation-in-progress`};let n=Es(e);if((await q9(n)).length===0)return{kind:`nothing-tracked`};try{return await ws(async()=>{let t=await gke(n);if(t===null)return{kind:`skipped`,reason:`detached-head`};let r=await _ke(n);if(r===null)return{kind:`skipped`,reason:`unborn-head`};let i=await q9(n);if(i.length===0)return{kind:`nothing-tracked`};let a=Es(e,{gitIndexFile:R(mu(),`ok-untrack-idx-${process.pid}-${Date.now()}.idx`)});await a.git.raw([`read-tree`,r]),await a.git.raw([`rm`,`--cached`,`-r`,`--ignore-unmatch`,`--`,...i]);let o=(await a.git.raw([`write-tree`])).trim(),s=await vke(n,r);if(s!==null&&s===o)return{kind:`nothing-tracked`};let c=await tB(e),l=c?.name??`OpenKnowledge`,u=c?.email??`sync@open-knowledge.local`;Os(a,{GIT_AUTHOR_NAME:l,GIT_AUTHOR_EMAIL:u,GIT_COMMITTER_NAME:l,GIT_COMMITTER_EMAIL:u});let d=`Stop tracking the OpenKnowledge project skill\n\nThe \`${Ni}\` skill is regenerated per machine and version-stamped per app build, so tracking it causes recurring sync conflicts. It is now git-ignored.`,f=(await a.git.raw([`commit-tree`,o,`-p`,r,`-m`,d])).trim();if(!K9.test(f))return G9.warn({raw:f},`commit-tree returned invalid SHA — aborting untrack`),{kind:`failed`,error:`commit-tree returned invalid SHA`};try{await n.git.raw([`update-ref`,`refs/heads/${t}`,f,r])}catch(e){return G9.info({branch:t,err:J9(e)},`update-ref CAS failed — ref moved, retry next open`),{kind:`skipped`,reason:`ref-race`}}try{await n.git.raw([`reset`,`-q`,f,`--`,...i])}catch(e){G9.info({err:J9(e)},`real-index reset after untrack failed (cosmetic)`)}return G9.info({dirs:i,commitSha:f},`untracked project-skill projection`),{kind:`untracked`,dirs:i,commitSha:f}})}catch(e){return{kind:`failed`,error:J9(e)}}}async function q9(e){let t=[];for(let n of mke){let r=``;try{r=(await e.git.raw([`ls-files`,`--`,n])).trim()}catch{r=``}r.length>0&&t.push(n)}return t}async function gke(e){try{let t=(await e.git.raw([`rev-parse`,`--abbrev-ref`,`HEAD`])).trim();return t.length===0||t===`HEAD`?null:t}catch{return null}}async function _ke(e){try{let t=(await e.git.raw([`rev-parse`,`--verify`,`HEAD`])).trim();return K9.test(t)?t:null}catch{return null}}async function vke(e,t){try{let n=(await e.git.raw([`rev-parse`,`${t}^{tree}`])).trim();return K9.test(n)?n:null}catch{return null}}function yke(e){return V(R(e,`MERGE_HEAD`))||V(R(e,`rebase-merge`))||V(R(e,`rebase-apply`))||V(R(e,`CHERRY_PICK_HEAD`))||V(R(e,`REVERT_HEAD`))}function J9(e){return e instanceof Error?e.message:String(e)}async function bke(e,t){let n;try{n=xl(t).resolve(e)}catch(e){if(e?.code===`MODULE_NOT_FOUND`)return;throw e}for(let t=L(n),r=0;r<32;r+=1){let n=R(t,`package.json`);if(V(n))try{let t=JSON.parse(await vu(n,`utf-8`));if(t.name===e&&typeof t.version==`string`)return t.version}catch{}let r=L(t);if(r===t)return;t=r}}const xke=[{regex:/\/Users\/[^/]+\//g,replacement:`~/`},{regex:/\/home\/[^/]+\//g,replacement:`~/`},{regex:/C:\\\\Users\\\\[^\\\\]+\\\\/g,replacement:`~\\`},{regex:/C:\\Users\\[^\\]+\\/g,replacement:`~\\`}];function Y9(e){if(e===void 0)return;let t=e;for(let{regex:e,replacement:n}of xke)t=t.replace(e,n);return t}function X9(e,t=0,n=new WeakSet){if(t>=5)return{name:`SerializedError.CauseDepthExceeded`,message:`cause chain depth > 5; truncated`};if(typeof e==`object`&&e){if(n.has(e))return{name:`SerializedError.CauseCycle`,message:`cyclic cause; truncated`};n.add(e)}if(e instanceof Error)return{name:e.name,message:Y9(e.message)??``,stack:Y9(e.stack),code:e.code,cause:e.cause===void 0?void 0:X9(e.cause,t+1,n)};if(e==null)return{name:`UnknownError`,message:String(e)};if(typeof e==`string`)return{name:`StringError`,message:Y9(e)??e};if(typeof e==`object`){let r=e;return{name:String(r.name??`ObjectError`),message:Y9(String(r.message??``))??``,stack:Y9(r.stack),code:r.code,cause:r.cause===void 0?void 0:X9(r.cause,t+1,n)}}return{name:`UnknownError`,message:String(e)}}var Z9=class extends Error{constructor(e){super(`File not found: ${e}`),this.filePath=e,this.name=`SingleFileNotFoundError`}},Q9=class extends Error{constructor(e){super(`Not a file: ${e}. \`ok <file>\` opens a single markdown file.`),this.filePath=e,this.name=`SingleFileNotAFileError`}},$9=class extends Error{constructor(e){super(`OpenKnowledge edits markdown files (.md / .mdx): ${e}`),this.filePath=e,this.name=`SingleFileNotMarkdownError`}};function Ske(e){if(!tS(e))throw new $9(e);let t;try{t=U(B(e))}catch(t){throw t.code===`ENOENT`?new Z9(e):t}if(!au(t).isFile())throw new Q9(e);let n=L(t),r=zz(n);if(r){let e=r.rootPath;return{mode:`project`,projectRoot:e,docName:rS(z(Cke(e),t).split(Pl).join(`/`)),canonicalFilePath:t}}let i=Dl(t);return{mode:`ephemeral`,canonicalFilePath:t,contentDir:n,singleDocRelPath:i,docName:rS(i)}}function Cke(e){return B(e,Io({absPath:Qo(`project`,e),sideline:!1,warn:()=>{}}).value.content?.dir??`.`)}function wke(e){let t=Yl(B(mu(),`ok-ephemeral-`)),n=B(t,`.ok`);return Jl(n,{recursive:!0}),su(B(n,`config.yml`),`# Ephemeral single-file session (\`ok <file>\`). Throwaway — safe to delete.\ncontent:\n dir: ${JSON.stringify(e)}\n`,`utf-8`),su(B(n,`.gitignore`),`local/
2031
2031
  `,`utf-8`),t}export{X2 as $,Zx as $i,hL as $n,SM as $r,kG as $t,X7 as A,Jse as Ai,nz as An,BP as Ar,gQ as At,f7 as B,mS as Bi,HR as Bn,CN as Br,sJ as Bt,p9 as C,Iu as Ca,AE as Ci,iB as Cn,MF as Cr,xQ as Ct,Z7 as D,Lw as Di,XR as Dn,YP as Dr,xme as Dt,J7 as E,Xw as Ei,Rz as En,JP as Er,zZ as Et,EDe as F,Fw as Fi,xz as Fn,RP as Fr,nJ as Ft,q8 as G,Xx as Gi,MR as Gn,bN as Gr,fJ as Gt,Y8 as H,hS as Hi,FR as Hn,EN as Hr,vJ as Ht,x7 as I,kS as Ii,Iz as In,LP as Ir,gJ as It,B8 as J,Ux as Ji,tR as Jn,mN as Jr,$q as Jt,G8 as K,Vx as Ki,TR as Kn,hN as Kr,cJ as Kt,b7 as L,K as Li,bz as Ln,wde as Lr,mJ as Lt,R7 as M,Hw as Mi,yz as Mn,VP as Mr,kJ as Mt,F7 as N,fw as Ni,mz as Nn,zP as Nr,EJ as Nt,K7 as O,Gw as Oi,Sz as On,KP as Or,Sme as Ot,y7 as P,pw as Pi,tz as Pn,Tde as Pr,xJ as Pt,G2 as Q,Bx as Qi,_L as Qn,CM as Qr,ZG as Qt,mDe as R,OS as Ri,$R as Rn,dP as Rr,_J as Rt,I9 as S,Uu as Sa,RE as Si,oB as Sn,Pfe as Sr,DQ as St,G7 as T,Jw as Ti,zz as Tn,qP as Tr,BZ as Tt,X8 as U,vS as Ui,LR as Un,wN as Ur,uJ as Ut,l7 as V,yS as Vi,PR as Vn,SN as Vr,hJ as Vt,J8 as W,pS as Wi,IR as Wn,TN as Wr,lJ as Wt,U2 as X,Gx as Xi,mL as Xn,XM as Xr,$G as Xt,A8 as Y,Rx as Yi,pL as Yn,uN as Yr,tK as Yt,W2 as Z,Ix as Zi,gL as Zn,YM as Zr,XG as Zt,eke as _,hd as _a,LO as _i,sW as _n,eI as _r,EQ as _t,Ske as a,Mx as aa,iM as ai,RG as an,mI as ar,pve as at,F9 as b,Gu as ba,qE as bi,pB as bn,WF as br,wQ as bt,hke as c,xx as ca,Mj as ci,CG as cn,fI as cr,q0 as ct,dke as d,qre as da,kj as di,iW as dn,pI as dr,jhe as dt,Px as ea,yM as ei,AG as en,CI as er,Tve as et,ske as f,yh as fa,Tj as fi,aW as fn,iI as fr,g1 as ft,tke as g,ld as ga,FO as gi,QU as gn,QF as gr,CQ as gt,uke as h,md as ha,IO as hi,oW as hn,tI as hr,OQ as ht,wke as i,Qx as ia,Xle as ii,jG as in,_I as ir,fve as it,W7 as j,Yse as ji,Cz as jn,HP as jr,UZ as jt,Y7 as k,qw as ki,rz as kn,Ade as kr,vQ as kt,W9 as l,ex as la,Nj as li,bG as ln,dI as lr,C1 as lt,lke as m,bh as ma,Dj as mi,lW as mn,rI as mr,NQ as mt,Z9 as n,qx as na,Yle as ni,MG as nn,Qfe as nr,I2 as nt,X9 as o,Tx as oa,aM as oi,PG as on,hI as or,mve as ot,cke as p,xh as pa,Oj as pi,eW as pn,nI as pr,y1 as pt,U8 as q,Hx as qi,lR as qn,vN as qr,Qq as qt,$9 as r,Jx as ra,Zle as ri,YG as rn,yI as rr,j2 as rt,bke as s,Cx as sa,hM as si,wG as sn,gI as sr,T2 as st,Q9 as t,Yx as ta,Qle as ti,DG as tn,SI as tr,L2 as tt,pke as u,Roe as ua,Aj as ui,XU as un,Bfe as ur,t1 as ut,QOe as v,cd as va,BD as vi,mB as vn,qF as vr,SQ as vt,f9 as w,LE as wi,rB as wn,sF as wr,yQ as wt,P9 as x,od as xa,KE as xi,dB as xn,YF as xr,Fme as xt,R9 as y,Ku as ya,JE as yi,aB as yn,JF as yr,TQ as yt,p7 as z,xS as zi,VR as zn,lde as zr,oJ as zt};
2032
- //# sourceMappingURL=src-DJhexTh5.mjs.map
2032
+ //# sourceMappingURL=src-y0X27yQX.mjs.map
@@ -0,0 +1 @@
1
+ import{E as e,g as t,r as n,v as r}from"./start-Dtt8oak3.mjs";export{n as bootStartServer,t as resolveBundledReactShellDir,r as resolveHost,e as startCommand};
@@ -1,10 +1,10 @@
1
- import"./sleep-DdJljU3h.mjs";import{Q as e,Y as t}from"./src-c73kUNxd.mjs";import{En as n,a as r,ii as i}from"./src-DJhexTh5.mjs";import{n as a,r as o,t as s}from"./esm-DmX1RzAi.mjs";import{a as c,c as l,d as u,i as d,o as f,r as p,t as m}from"./acp-harness-probe-e-SewXXi.mjs";import{n as h}from"./constants-COvJwYpX.mjs";import{spawn as g}from"node:child_process";import{basename as _,join as v,posix as y,resolve as b}from"node:path";import{closeSync as x,existsSync as S,mkdirSync as C,openSync as w}from"node:fs";import{rm as T}from"node:fs/promises";import{setTimeout as E}from"node:timers/promises";function D(e){return y.join(y.dirname(e),`..`,`Frameworks`,`OpenKnowledge Server.app`,`Contents`,`MacOS`,`OpenKnowledge Helper`)}const O=/\/[^/]+\.app\/Contents\/MacOS\/[^/]+$/;function k(e){if(e.platform!==`darwin`||!O.test(e.execPath))return null;let t=D(e.execPath);return e.exists(t)?t:null}function A(e={}){let t=e.execPath??process.execPath,n=e.platform??process.platform,r=e.argv??process.argv,i=e.exists??S,a=r[1];return a?{command:k({execPath:t,platform:n,exists:i})??t,prefixArgs:[a]}:(console.warn(`[self-spawn] process.argv[1] is empty — falling back to \`npx -y @inkeep/open-knowledge@latest\`. This re-introduces the registry-fetch surface that re-exec was fixing. Observed argv: ${JSON.stringify(r)}`),{command:`npx`,prefixArgs:[`-y`,`@inkeep/open-knowledge@latest`]})}function j(e,t){return e.bind?.[0]??e.host??t.HOST??`127.0.0.1`}function M(e){if(e===`ui`||e===`server`)return e;throw new a(`--only must be 'ui' or 'server'`)}function N(e=S){let t=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[b(t,`public`),b(t,`../../app/dist`),b(t,`../../../app/dist`)].find(t=>e(t))}function P(e){if(e.explicitDir!==void 0)return{dir:e.explicitDir,missingBundle:!1};if(e.only===`server`||e.uiPortSet&&!e.remoteEnabled)return{dir:void 0,missingBundle:!1};let t=e.findBundledDir();return{dir:t,missingBundle:t===void 0}}function F(e){if(e===`off`)return null;let t=/^([1-9]\d*)(s|m|h)$/.exec(e);if(t===null)throw new a(`--idle-shutdown must be 'off' or a duration like 90s, 30m, 2h`);let n=Number(t[1]);switch(t[2]){case`s`:return n*1e3;case`m`:return n*6e4;default:return n*36e5}}function I(e){return e===`localhost`||e===`::1`||e===`[::1]`||e.startsWith(`127.`)}function L(e){return!e.openBrowser||e.remoteEnabled||e.ephemeral||e.only===`server`||!e.servesUi?!1:e.legacyOpen?!0:I(e.host)&&e.isTTY}function R(e,t){return t&&(e===`::`||e===`::1`||e===`[::1]`||e===`localhost`||e===`0.0.0.0`)?{host:`127.0.0.1`,coerced:!0}:{host:e,coerced:!1}}function z(e){let t=_(e).replace(/[^\x20-\x7E]/g,``).trim().slice(0,64);return`open-knowledge-server ${t.length>0?t:`unknown`}`}var B=class extends Error{cwd;constructor(e){super("This directory isn't set up yet. Run `ok init` first, then `ok start` again."),this.name=`OkDirMissingError`,this.cwd=e}};function V(e){return e.uiLock?e.isAlive(e.uiLock.pid)?{action:`skip`,reason:`alive`,pid:e.uiLock.pid,port:e.uiLock.port}:{action:`spawn`,reason:`stale`,stalePid:e.uiLock.pid}:{action:`spawn`,reason:`absent`}}function H(t){S(t.lockDir)||C(t.lockDir,{recursive:!0});let n=w(v(t.lockDir,e),`w`),r=t.spawn??g,{PORT:i,...a}=process.env,o=A();try{let e=r(o.command,[...o.prefixArgs,...t.args??[`ui`]],{detached:!0,stdio:[`ignore`,`ignore`,n],windowsHide:!0,cwd:t.cwd,env:{...a,ELECTRON_RUN_AS_NODE:`1`}});return e.unref(),e}finally{try{x(n)}catch{}}}function U(e,t,n,r=!1){return e??(n!==void 0||r?void 0:t)}function ee(e,t){return e!==void 0&&t!==null&&t.port>0&&t.draining!==!0}function W(e,t,n){return e??+(t!=null&&!n)}async function G(e){let t=e.spawn??g,n=A(),{PORT:r,...i}=process.env,a=t(n.command,[...n.prefixArgs,`ui`,`--port`,String(e.uiPort)],{cwd:e.cwd,stdio:`inherit`,windowsHide:!0,env:{...i,ELECTRON_RUN_AS_NODE:`1`}}),o=!1,s=e=>{o=!0;try{a.kill(e)}catch{}},c=()=>s(`SIGINT`),l=()=>s(`SIGTERM`);process.once(`SIGINT`,c),process.once(`SIGTERM`,l),await new Promise(e=>{a.on(`exit`,(t,n)=>{process.exitCode=W(t,n,o),e()}),a.on(`error`,t=>{console.error(`[start] connect fallback: failed to spawn ok ui — ${t instanceof Error?t.message:String(t)}`),process.exitCode=1,e()})}),process.removeListener(`SIGINT`,c),process.removeListener(`SIGTERM`,l)}async function K(e){let t=e.now()+e.timeoutMs;for(;e.now()<t;){let t=e.readUiLock();if(t&&t.port>0)return t.port;await e.sleep(e.pollIntervalMs)}let n=e.readUiLock();return n&&n.port>0?n.port:null}const te=t;function q(e,t,n=e=>T(e,{recursive:!0,force:!0})){return async()=>{try{await e()}finally{try{await n(t)}catch(e){process.stderr.write(`[start] ephemeral temp dir reap failed for ${t}: ${e instanceof Error?e.message:String(e)}\n`)}}}}function J(e,t={}){let n=t.exit??(e=>process.exit(e)),r=t.getActiveHandles??(()=>{let e=process._getActiveHandles;return e?e.call(process):null});return async()=>{let i=!1;try{await e()}catch(e){i=!0,t.log?.error({err:e},`idle-shutdown: destroy failed — exiting anyway`)}finally{let e=null;try{let t=r();if(t!==null){e={};for(let n of t){let t=n?.constructor?.name??`unknown`;e[t]=(e[t]??0)+1}}}catch{e=null}t.log?.info({event:`idle-shutdown-exit`,exitCode:+!!i,openHandles:e??{},handlesAvailable:e!==null},`idle-shutdown: teardown finished — exiting process`),n(+!!i)}}}async function Y(e){let t=e.sigtermGraceMs??te,n=e.sigtermPollIntervalMs??200,r=e.sleep??(e=>E(e)),i=e.reason??`teardown`;try{let a=e.readUiLock(),o=e.spawnedUiPid();if(a&&e.isAlive(a.pid)&&a.pid!==o)e.log?.info({pid:a.pid,port:a.port,spawnedUiPid:o},`${i}: ui.lock holder is not our spawned sibling — leaving it alone`);else if(a&&e.isAlive(a.pid))try{e.killPid(a.pid,`SIGTERM`),e.log?.info({pid:a.pid,port:a.port},`${i}: SIGTERM UI sibling`);let o=Date.now()+t;for(;Date.now()<o&&e.isAlive(a.pid);)await r(n);if(e.isAlive(a.pid))try{e.killPid(a.pid,`SIGKILL`),e.log?.warn({pid:a.pid,graceMs:t},`${i}: SIGTERM grace expired — escalated to SIGKILL`)}catch(t){e.log?.error({pid:a.pid,err:t},`${i}: SIGKILL failed`)}}catch(t){e.log?.warn({pid:a.pid,err:t},`${i}: failed to SIGTERM UI sibling`)}}catch(t){e.log?.warn({err:t},`${i}: UI lookup failed; proceeding`)}}function X(e){let{destroy:t,...n}=e;return async()=>{await Y({...n,reason:`idle-shutdown`}),await t()}}async function Z(e){let{config:t,cwd:a,host:o}=e,s=e.skipAutoInit??!1,c=e.skipUiAutoSpawn??!1,d=e.idleThresholdMs===void 0?18e5:e.idleThresholdMs,{existsSync:f,mkdirSync:p}=await import(`node:fs`),{basename:h,dirname:g}=await import(`node:path`),{bootServer:_,getLogger:v,isProcessAlive:y,readUiLock:b,resolveContentDir:x,resolveLockDir:S,waitForServerLockDrain:C}=await import(`./src-YVZCV4Ux.mjs`),w=e.log??v(`start`),T=e.singleFile!==void 0,D=e.projectDir??a,O=T?r(e.singleFile).canonicalFilePath:void 0,k=O?g(O):void 0,A=O?h(O):void 0;if(!T){if(!s&&!n(a))throw new B(a);let t=process.env.OK_RECLAIM_DISABLE??null,r=e=>{let t=typeof e.event==`string`?e.event:``;(t.endsWith(`-failed`)||t.endsWith(`-error`)||t.endsWith(`-missing`))&&w.warn({event:e},`[start] reclaim sweep reported a problem`)};try{(e.repairMcpConfigsFn??(await import(`./repair-mcp-configs-DqtCFQdR.mjs`)).repairMcpConfigs)({projectDir:a,reclaimDisableEnv:t,logger:r})}catch(e){w.warn({err:e},`[start] mcp-config repair sweep failed; continuing`)}try{(e.repairLaunchJsonFn??(await import(`./repair-launch-json-ChORzYOl.mjs`)).repairLaunchJson)({projectDir:a,reclaimDisableEnv:t,logger:r})}catch(e){w.warn({err:e},`[start] launch.json repair sweep failed; continuing`)}try{await(e.repairSkillsFn??(await import(`./repair-skills-qAm1agyb.mjs`)).repairSkills)({projectDir:a,reclaimDisableEnv:t,logger:r})}catch(e){w.warn({err:e},`[start] skill repair sweep failed; continuing`)}}let j=k??x(t,a);!T&&!f(j)&&(p(j,{recursive:!0}),w.info({contentDir:j},`Created content directory`));let M=null,N=null,P=async({lockDir:t})=>{if(M=V({uiLock:b(t),isAlive:y}),M.action===`spawn`&&!c)try{let n=e.uiPort===void 0?void 0:[`ui`,`--port`,String(e.uiPort)];N=H({lockDir:t,cwd:a,spawn:e.spawn,args:n}).pid??null,w.info({reason:M.reason,uiPort:e.uiPort},`[start] auto-spawned ok ui sibling`)}catch(e){console.warn(`[start] failed to auto-spawn ok ui: ${e instanceof Error?e.message:String(e)}`)}else M.action===`skip`&&w.info({port:M.port,pid:M.pid},`UI already running at port ${M.port}`)},F=e.reactShellDistDir===void 0,I=u(),L=i();{let e=S(T?D:a),t=Date.now(),n=await C(e);n!==`no-drain`&&w.info({event:`start-waited-for-draining-predecessor`,outcome:n,waitedMs:Date.now()-t,drainLockDir:e},n===`released`?`[start] predecessor server finished draining — proceeding`:`[start] predecessor server still draining after wait — proceeding to collide`)}let R=await _({config:t,contentDir:j,projectDir:T?D:a,contentRoot:T?void 0:t.content.dir,port:e.port,host:o,...e.enableRemote===!0?{enableRemote:!0}:{},quiet:!1,detectGh:l,tokenStore:I,embeddingsKeyStore:L,...T?{ephemeral:!0,singleDocRelPath:A,gitEnabled:!1,gitPreflight:()=>({ok:!0,version:`0.0.0`,resolvedPath:`git`,source:`PATH`})}:{},localOpCliArgs:[process.execPath,process.argv[1]],probeHarnessManagedMcpEntry:(e,t)=>m(e,t),attachUiSibling:F,idleShutdownMs:d,skipAutoInit:!0,...F?{spawnUiSiblingFn:P}:{},idleShutdownHandler:t=>{let n=X({readUiLock:()=>b(R.lockDir),spawnedUiPid:()=>N,isAlive:y,killPid:(e,t)=>{process.kill(e,t)},destroy:t,log:w});return J(T?q(n,D):n,{log:w,exit:e.idleExit})},log:w,...e.serveContentAssets===void 0?{}:{serveContentAssets:e.serveContentAssets},...e.reactShellDistDir?{reactShellDistDir:e.reactShellDistDir}:{}});M||={action:`skip`,reason:`alive`,pid:0,port:0};let z=M,U=null;if(z.action===`skip`)U=z.port>0?z.port:null;else if(!c){let t=e.uiBindTimeoutMs??3e3;U=await K({readUiLock:()=>b(R.lockDir),now:Date.now,sleep:e=>E(e),timeoutMs:t,pollIntervalMs:50}),U===null&&w.warn({timeoutMs:t},`[start] ok ui did not bind within timeout — banner falls back to API URL`)}return{httpServer:R.httpServer,destroy:R.destroy,lockDir:R.lockDir,contentDir:j,port:R.port,ready:R.ready,degraded:R.degraded,uiSpawnDecision:M,spawnedUiPid:N,resolvedUiPort:U}}function ne(e){if(e===`browser`||e===`app`)return e;throw new a(`--mode must be 'browser' or 'app'`)}function re(e){let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<1||t>65535)throw new a(`--ui-port must be a port number between 1 and 65535`);return t}function Q(e){return e.OK_CONSOLE_LEVEL!==void 0||e.LOG_LEVEL!==void 0?null:`warn`}function ie(e){let t=[`Stopping OpenKnowledge…`,`Saving pending changes and releasing the server lock — this can take a few seconds.`];return e===`SIGINT`&&t.push(`Press Ctrl+C again to force quit.`),t}async function ae(e,t){let n=Q(process.env);n!==null&&(process.env.OK_CONSOLE_LEVEL=n);let{renderBanner:r}=await import(`./banner-B6HYYw6k.mjs`),{accent:i,dim:a,error:o,warning:s}=await import(`./colors-MGDi6UGf.mjs`),c=process.cwd(),l=t.remote!==void 0&&t.remote!==!1,u=typeof t.remote==`string`?t.remote:void 0,d=u===void 0?e:{...e,remote:{...e.remote,url:u}};process.title=z(c),l&&(typeof d.remote?.url!=`string`||d.remote.url===``)&&(console.error(o("--remote requires a public tunnel URL — pass it (`ok start --remote https://<your-tunnel-host>`) or set remote.url in .ok/config.yml.")),process.exit(78)),l&&console.warn(s([``,`⚠ REMOTE ACCESS ENABLED — no server-side authentication.`,` Anyone who can reach ${d.remote?.url} has FULL control of this`,` knowledge base, including sync, publishing, credentials, and local operations.`,` Restrict who can reach it at the tunnel: ngrok OAuth, Cloudflare Access,`,` Tailscale ACLs, or equivalent edge auth.`,``].join(`
2
- `)));let f=j(t,process.env),p=R(f,l);p.coerced&&console.warn(`remote access is enabled and ${f} is not an IPv4 loopback bind — tunnels proxy to 127.0.0.1, so binding ${f} would leave the tunnel dialing a dead port. Using 127.0.0.1.`);let m=p.host,g=t.port===void 0?void 0:Number(t.port),_=process.env.PORT?Number(process.env.PORT):void 0,v=t.uiPort===void 0?void 0:Number(t.uiPort);l&&g===void 0&&_!==void 0&&console.warn(`remote access is enabled — ignoring env PORT=${process.env.PORT}; the tunnel's port mapping targets the stable remote port (${d.remote?.port??24550}). Pass --port to override deliberately.`);let y=U(g,_,v,l)??(l?d.remote?.port??24550:void 0);if(v!==void 0){let{readServerLock:e,resolveLockDir:t}=await import(`./src-YVZCV4Ux.mjs`);if(ee(v,e(t(c)))){await G({cwd:c,uiPort:v});return}}let b=P({explicitDir:t.reactShellDistDir,only:t.only,uiPortSet:v!==void 0,remoteEnabled:l,findBundledDir:N}),x=b.dir;b.missingBundle&&console.warn(l?`remote access: bundled web UI not found — serving /mcp and /api only over the tunnel.`:`bundled web UI not found — serving /api and /mcp only. Reinstall @inkeep/open-knowledge, or build packages/app in a source checkout.`);let S;try{S=await Z({config:d,cwd:c,host:m,port:y,...v===void 0?{}:{uiPort:v},...t.serveContentAssets===void 0?{}:{serveContentAssets:t.serveContentAssets},...x?{reactShellDistDir:x}:{},...t.only===`server`||b.missingBundle?{skipUiAutoSpawn:!0}:{},...t.idleShutdown===void 0?{}:{idleThresholdMs:t.idleShutdown},...t.singleFile?{singleFile:t.singleFile}:{},...t.projectDir?{projectDir:t.projectDir}:{},...l?{enableRemote:!0}:{}})}catch(e){e instanceof B&&(console.error(o(e.message)),process.exit(1));let t=await import(`./src-YVZCV4Ux.mjs`);if((e instanceof t.GitNotAvailableError||e instanceof t.GitTooOldError)&&process.exit(78),e instanceof t.RemoteConfigError&&(console.error(o(e.message)),process.exit(78)),(e instanceof t.SingleFileNotFoundError||e instanceof t.SingleFileNotAFileError||e instanceof t.SingleFileNotMarkdownError)&&(console.error(o(e.message)),process.exit(1)),v!==void 0&&$(e,t)){await G({cwd:c,uiPort:v});return}if(v===void 0&&$(e,t)){let e=t.resolveLockDir(c),n=null;try{n=await oe({readServerLock:()=>t.readServerLock(e),readUiLock:()=>t.readUiLock(e),now:Date.now,sleep:e=>E(e),timeoutMs:3e3,pollIntervalMs:50})}catch(e){process.stderr.write(`[start] spawn-or-reuse: lock poll failed (${e instanceof Error?e.message:String(e)}) — falling back to the collision message\n`)}if(n!==null){let[e,...t]=se(n);console.log(i(e));for(let e of t)console.log(a(e));process.exit(0)}}let n=ce(e,c,t);n!==null&&(console.error(o(n)),process.exit(1)),console.error(`${o(`Failed to start:`)} ${e instanceof Error?e.stack??e.message:String(e)}`),process.exit(1)}let C=!1,w=async e=>{if(C)return;C=!0;let[t,...n]=ie(e);console.log(i(`\n${t}`));for(let e of n)console.log(a(` ${e}`));if(S.spawnedUiPid!==null)try{let{getLogger:e,isProcessAlive:t,readUiLock:n}=await import(`./src-YVZCV4Ux.mjs`);await Y({readUiLock:()=>n(S.lockDir),spawnedUiPid:()=>S.spawnedUiPid,isAlive:t,killPid:(e,t)=>process.kill(e,t),log:e(`start`),reason:`shutdown`})}catch(e){console.error(`${o(`ui sibling teardown failed:`)} ${e instanceof Error?e.stack??e.message:String(e)}`)}try{await S.destroy()}catch(e){console.error(`${o(`destroy() failed:`)} ${e instanceof Error?e.stack??e.message:String(e)}`),process.exitCode=1}process.exit(process.exitCode??0)};process.once(`SIGINT`,()=>{w(`SIGINT`)}),process.once(`SIGTERM`,()=>{w(`SIGTERM`)});let T=m.includes(`:`)&&!m.startsWith(`[`)?`[${m}]`:m,D=`http://${T}:${S.port}`,O=m===`0.0.0.0`||m===`::`?`http://0.0.0.0:${S.port}`:void 0,k=S.resolvedUiPort,A=k!==null&&k>0?`http://${T}:${k}`:D;console.log(r({name:`open-knowledge`,version:h,localUrl:A,apiUrl:A===D?void 0:D,networkUrl:O,nextSteps:[`Open the Editor URL in your browser to start editing.`]}));let M={"shadow-repo":`Version history and branch-switch safety unavailable`,"file-watcher":`External file changes will not sync to the editor`,"head-watcher":`Git branch switches may cause document inconsistency`};S.ready.then(async()=>{if(S.degraded.length>0){console.log();for(let e of S.degraded){let t=M[e]??`${e} (check server logs for details)`;console.warn(` ${s(`⚠`)} ${s(e)}: ${a(t)}`)}console.log()}if(L({openBrowser:t.openBrowser!==!1,legacyOpen:t.open===!0,host:m,isTTY:process.stdout.isTTY===!0,remoteEnabled:l,ephemeral:t.singleFile!==void 0,only:t.only,servesUi:x!==void 0})){let{openBrowser:e}=await import(`./open-browser-Bb773NFh.mjs`);e(A)}}).catch(e=>{console.error(` ${o(`Server initialization failed:`)} ${e instanceof Error?e.message:String(e)}`)})}async function oe(e){let t=e.now()+e.timeoutMs,n=e.readServerLock();for(;n!==null&&n.draining!==!0&&n.port<=0&&e.now()<t;)await e.sleep(e.pollIntervalMs),n=e.readServerLock();if(n===null||n.draining===!0||n.port<=0)return null;if(n.capabilities?.includes(`ui`)===!0&&n.url!==void 0)return{url:n.url,kind:n.kind,pid:n.pid,servesUi:!0};let r=e.readUiLock();return r!==null&&r.port>0?{url:r.url??`http://localhost:${r.port}`,kind:n.kind,pid:n.pid,servesUi:!1}:{url:n.url??`http://127.0.0.1:${n.port}`,kind:n.kind,pid:n.pid,servesUi:!1}}function se(e){return[`${e.kind===`mcp-spawned`?`An MCP-spawned OpenKnowledge server is already running on this project`:`OpenKnowledge is already running on this project`} (pid ${e.pid}).`,` ${e.url}`,"Leaving it running — run `ok stop` first if you want a fresh server."]}function $(e,t){let n=t.ServerLockCollisionError;return n!==void 0&&e instanceof n}function ce(e,t,n){let r=n.ServerLockCollisionError;if(r===void 0||!(e instanceof r))return null;try{let e=n.readServerLock(n.resolveLockDir(t));return e&&e.kind===`mcp-spawned`?"An MCP-spawned server holds this lock; it should release on idle-shutdown (~30 min). Or run `ok stop`.":"OpenKnowledge server is already running on this project — check `ok status` or `ok stop`."}catch{return null}}function le(e){return new s(`start`).description(`Start the OpenKnowledge server (UI + API + MCP + collab on one port)`).option(`-p, --port <port>`,`Server port`,void 0).option(`--ui-port <port>`,`Pin the ok ui sibling to <port> and connect (not exit) if a server already runs here — the worktree-preview recipe path`,re).option(`--bind <address>`,`Bind address (repeatable; default 127.0.0.1 — loopback only)`,(e,t)=>[...t??[],e]).addOption(new o(`-H, --host <host>`,`Deprecated alias of --bind`).hideHelp()).option(`--no-open-browser`,`Do not open the browser after start (interactive loopback starts open it by default)`).addOption(new o(`--open`,`Deprecated: force-open the browser after start`).hideHelp()).option(`--only <module>`,`Serve one module: 'server' (API + MCP only, no shell or browser) or 'ui' (shell + proxy only; requires --server-url)`,M).option(`--server-url <url>`,`Project-server URL the --only ui process proxies to (e.g. http://127.0.0.1:24550)`).option(`--idle-shutdown <duration>`,`Shut the server down after this long with no connected clients ('off', or a duration like 90s, 30m, 2h; default 30m)`,F).option(`--mode <mode>`,`Force dispatch mode: 'browser' or 'app'`,ne).option(`--serve-content-assets`,`Serve content assets from this server (now the default; kept for compatibility)`).option(`--react-shell-dist-dir <path>`,`Serve React shell from <path> (suppresses ok ui sibling)`).option(`--single-file <path>`,`No-project ephemeral single-file mode: scope the server to one markdown file (git + MCP off)`).option(`--project-dir <dir>`,`Throwaway project root for --single-file (where ephemeral .ok/ state lives)`).option(`--remote [url]`,`Serve through a tunnel: admit requests carrying the tunnel Host with NO server-side auth (anyone who can reach the URL has full control — restrict access at the tunnel with edge auth). Bare --remote uses remote.url from .ok/config.yml; --remote <url> supplies it for this run.`).action(async t=>{let n=e();if(t.bind!==void 0&&t.bind.length>1&&(process.stderr.write(`error: multiple --bind addresses are not supported yet — pass a single address
1
+ import"./sleep-DdJljU3h.mjs";import{Q as e,Y as t}from"./src-c73kUNxd.mjs";import{En as n,a as r,ii as i}from"./src-y0X27yQX.mjs";import{n as a,r as o,t as s}from"./esm-DmX1RzAi.mjs";import{a as c,c as l,d as u,i as d,o as f,r as p,t as m}from"./acp-harness-probe-BRzTGQPW.mjs";import{n as h}from"./constants-COPfVWti.mjs";import{spawn as g}from"node:child_process";import{basename as _,join as v,posix as y,resolve as b}from"node:path";import{closeSync as x,existsSync as S,mkdirSync as C,openSync as w}from"node:fs";import{rm as T}from"node:fs/promises";import{setTimeout as E}from"node:timers/promises";function D(e){return y.join(y.dirname(e),`..`,`Frameworks`,`OpenKnowledge Server.app`,`Contents`,`MacOS`,`OpenKnowledge Helper`)}const O=/\/[^/]+\.app\/Contents\/MacOS\/[^/]+$/;function k(e){if(e.platform!==`darwin`||!O.test(e.execPath))return null;let t=D(e.execPath);return e.exists(t)?t:null}function A(e={}){let t=e.execPath??process.execPath,n=e.platform??process.platform,r=e.argv??process.argv,i=e.exists??S,a=r[1];return a?{command:k({execPath:t,platform:n,exists:i})??t,prefixArgs:[a]}:(console.warn(`[self-spawn] process.argv[1] is empty — falling back to \`npx -y @inkeep/open-knowledge@latest\`. This re-introduces the registry-fetch surface that re-exec was fixing. Observed argv: ${JSON.stringify(r)}`),{command:`npx`,prefixArgs:[`-y`,`@inkeep/open-knowledge@latest`]})}function j(e,t){return e.bind?.[0]??e.host??t.HOST??`127.0.0.1`}function M(e){if(e===`ui`||e===`server`)return e;throw new a(`--only must be 'ui' or 'server'`)}function N(e=S){let t=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[b(t,`public`),b(t,`../../app/dist`),b(t,`../../../app/dist`)].find(t=>e(t))}function P(e){if(e.explicitDir!==void 0)return{dir:e.explicitDir,missingBundle:!1};if(e.only===`server`||e.uiPortSet&&!e.remoteEnabled)return{dir:void 0,missingBundle:!1};let t=e.findBundledDir();return{dir:t,missingBundle:t===void 0}}function F(e){if(e===`off`)return null;let t=/^([1-9]\d*)(s|m|h)$/.exec(e);if(t===null)throw new a(`--idle-shutdown must be 'off' or a duration like 90s, 30m, 2h`);let n=Number(t[1]);switch(t[2]){case`s`:return n*1e3;case`m`:return n*6e4;default:return n*36e5}}function I(e){return e===`localhost`||e===`::1`||e===`[::1]`||e.startsWith(`127.`)}function L(e){return!e.openBrowser||e.remoteEnabled||e.ephemeral||e.only===`server`||!e.servesUi?!1:e.legacyOpen?!0:I(e.host)&&e.isTTY}function R(e,t){return t&&(e===`::`||e===`::1`||e===`[::1]`||e===`localhost`||e===`0.0.0.0`)?{host:`127.0.0.1`,coerced:!0}:{host:e,coerced:!1}}function z(e){let t=_(e).replace(/[^\x20-\x7E]/g,``).trim().slice(0,64);return`open-knowledge-server ${t.length>0?t:`unknown`}`}var B=class extends Error{cwd;constructor(e){super("This directory isn't set up yet. Run `ok init` first, then `ok start` again."),this.name=`OkDirMissingError`,this.cwd=e}};function V(e){return e.uiLock?e.isAlive(e.uiLock.pid)?{action:`skip`,reason:`alive`,pid:e.uiLock.pid,port:e.uiLock.port}:{action:`spawn`,reason:`stale`,stalePid:e.uiLock.pid}:{action:`spawn`,reason:`absent`}}function H(t){S(t.lockDir)||C(t.lockDir,{recursive:!0});let n=w(v(t.lockDir,e),`w`),r=t.spawn??g,{PORT:i,...a}=process.env,o=A();try{let e=r(o.command,[...o.prefixArgs,...t.args??[`ui`]],{detached:!0,stdio:[`ignore`,`ignore`,n],windowsHide:!0,cwd:t.cwd,env:{...a,ELECTRON_RUN_AS_NODE:`1`}});return e.unref(),e}finally{try{x(n)}catch{}}}function U(e,t,n,r=!1){return e??(n!==void 0||r?void 0:t)}function ee(e,t){return e!==void 0&&t!==null&&t.port>0&&t.draining!==!0}function W(e,t,n){return e??+(t!=null&&!n)}async function G(e){let t=e.spawn??g,n=A(),{PORT:r,...i}=process.env,a=t(n.command,[...n.prefixArgs,`ui`,`--port`,String(e.uiPort)],{cwd:e.cwd,stdio:`inherit`,windowsHide:!0,env:{...i,ELECTRON_RUN_AS_NODE:`1`}}),o=!1,s=e=>{o=!0;try{a.kill(e)}catch{}},c=()=>s(`SIGINT`),l=()=>s(`SIGTERM`);process.once(`SIGINT`,c),process.once(`SIGTERM`,l),await new Promise(e=>{a.on(`exit`,(t,n)=>{process.exitCode=W(t,n,o),e()}),a.on(`error`,t=>{console.error(`[start] connect fallback: failed to spawn ok ui — ${t instanceof Error?t.message:String(t)}`),process.exitCode=1,e()})}),process.removeListener(`SIGINT`,c),process.removeListener(`SIGTERM`,l)}async function K(e){let t=e.now()+e.timeoutMs;for(;e.now()<t;){let t=e.readUiLock();if(t&&t.port>0)return t.port;await e.sleep(e.pollIntervalMs)}let n=e.readUiLock();return n&&n.port>0?n.port:null}const te=t;function q(e,t,n=e=>T(e,{recursive:!0,force:!0})){return async()=>{try{await e()}finally{try{await n(t)}catch(e){process.stderr.write(`[start] ephemeral temp dir reap failed for ${t}: ${e instanceof Error?e.message:String(e)}\n`)}}}}function J(e,t={}){let n=t.exit??(e=>process.exit(e)),r=t.getActiveHandles??(()=>{let e=process._getActiveHandles;return e?e.call(process):null});return async()=>{let i=!1;try{await e()}catch(e){i=!0,t.log?.error({err:e},`idle-shutdown: destroy failed — exiting anyway`)}finally{let e=null;try{let t=r();if(t!==null){e={};for(let n of t){let t=n?.constructor?.name??`unknown`;e[t]=(e[t]??0)+1}}}catch{e=null}t.log?.info({event:`idle-shutdown-exit`,exitCode:+!!i,openHandles:e??{},handlesAvailable:e!==null},`idle-shutdown: teardown finished — exiting process`),n(+!!i)}}}async function Y(e){let t=e.sigtermGraceMs??te,n=e.sigtermPollIntervalMs??200,r=e.sleep??(e=>E(e)),i=e.reason??`teardown`;try{let a=e.readUiLock(),o=e.spawnedUiPid();if(a&&e.isAlive(a.pid)&&a.pid!==o)e.log?.info({pid:a.pid,port:a.port,spawnedUiPid:o},`${i}: ui.lock holder is not our spawned sibling — leaving it alone`);else if(a&&e.isAlive(a.pid))try{e.killPid(a.pid,`SIGTERM`),e.log?.info({pid:a.pid,port:a.port},`${i}: SIGTERM UI sibling`);let o=Date.now()+t;for(;Date.now()<o&&e.isAlive(a.pid);)await r(n);if(e.isAlive(a.pid))try{e.killPid(a.pid,`SIGKILL`),e.log?.warn({pid:a.pid,graceMs:t},`${i}: SIGTERM grace expired — escalated to SIGKILL`)}catch(t){e.log?.error({pid:a.pid,err:t},`${i}: SIGKILL failed`)}}catch(t){e.log?.warn({pid:a.pid,err:t},`${i}: failed to SIGTERM UI sibling`)}}catch(t){e.log?.warn({err:t},`${i}: UI lookup failed; proceeding`)}}function X(e){let{destroy:t,...n}=e;return async()=>{await Y({...n,reason:`idle-shutdown`}),await t()}}async function Z(e){let{config:t,cwd:a,host:o}=e,s=e.skipAutoInit??!1,c=e.skipUiAutoSpawn??!1,d=e.idleThresholdMs===void 0?18e5:e.idleThresholdMs,{existsSync:f,mkdirSync:p}=await import(`node:fs`),{basename:h,dirname:g}=await import(`node:path`),{bootServer:_,getLogger:v,isProcessAlive:y,readUiLock:b,resolveContentDir:x,resolveLockDir:S,waitForServerLockDrain:C}=await import(`./src-Dg0jHVcz.mjs`),w=e.log??v(`start`),T=e.singleFile!==void 0,D=e.projectDir??a,O=T?r(e.singleFile).canonicalFilePath:void 0,k=O?g(O):void 0,A=O?h(O):void 0;if(!T){if(!s&&!n(a))throw new B(a);let t=process.env.OK_RECLAIM_DISABLE??null,r=e=>{let t=typeof e.event==`string`?e.event:``;(t.endsWith(`-failed`)||t.endsWith(`-error`)||t.endsWith(`-missing`))&&w.warn({event:e},`[start] reclaim sweep reported a problem`)};try{(e.repairMcpConfigsFn??(await import(`./repair-mcp-configs-BrBkt_hT.mjs`)).repairMcpConfigs)({projectDir:a,reclaimDisableEnv:t,logger:r})}catch(e){w.warn({err:e},`[start] mcp-config repair sweep failed; continuing`)}try{(e.repairLaunchJsonFn??(await import(`./repair-launch-json-BocgwEI5.mjs`)).repairLaunchJson)({projectDir:a,reclaimDisableEnv:t,logger:r})}catch(e){w.warn({err:e},`[start] launch.json repair sweep failed; continuing`)}try{await(e.repairSkillsFn??(await import(`./repair-skills-BMZ7VleT.mjs`)).repairSkills)({projectDir:a,reclaimDisableEnv:t,logger:r})}catch(e){w.warn({err:e},`[start] skill repair sweep failed; continuing`)}}let j=k??x(t,a);!T&&!f(j)&&(p(j,{recursive:!0}),w.info({contentDir:j},`Created content directory`));let M=null,N=null,P=async({lockDir:t})=>{if(M=V({uiLock:b(t),isAlive:y}),M.action===`spawn`&&!c)try{let n=e.uiPort===void 0?void 0:[`ui`,`--port`,String(e.uiPort)];N=H({lockDir:t,cwd:a,spawn:e.spawn,args:n}).pid??null,w.info({reason:M.reason,uiPort:e.uiPort},`[start] auto-spawned ok ui sibling`)}catch(e){console.warn(`[start] failed to auto-spawn ok ui: ${e instanceof Error?e.message:String(e)}`)}else M.action===`skip`&&w.info({port:M.port,pid:M.pid},`UI already running at port ${M.port}`)},F=e.reactShellDistDir===void 0,I=u(),L=i();{let e=S(T?D:a),t=Date.now(),n=await C(e);n!==`no-drain`&&w.info({event:`start-waited-for-draining-predecessor`,outcome:n,waitedMs:Date.now()-t,drainLockDir:e},n===`released`?`[start] predecessor server finished draining — proceeding`:`[start] predecessor server still draining after wait — proceeding to collide`)}let R=await _({config:t,contentDir:j,projectDir:T?D:a,contentRoot:T?void 0:t.content.dir,port:e.port,host:o,...e.enableRemote===!0?{enableRemote:!0}:{},quiet:!1,detectGh:l,tokenStore:I,embeddingsKeyStore:L,...T?{ephemeral:!0,singleDocRelPath:A,gitEnabled:!1,gitPreflight:()=>({ok:!0,version:`0.0.0`,resolvedPath:`git`,source:`PATH`})}:{},localOpCliArgs:[process.execPath,process.argv[1]],probeHarnessManagedMcpEntry:(e,t)=>m(e,t),attachUiSibling:F,idleShutdownMs:d,skipAutoInit:!0,...F?{spawnUiSiblingFn:P}:{},idleShutdownHandler:t=>{let n=X({readUiLock:()=>b(R.lockDir),spawnedUiPid:()=>N,isAlive:y,killPid:(e,t)=>{process.kill(e,t)},destroy:t,log:w});return J(T?q(n,D):n,{log:w,exit:e.idleExit})},log:w,...e.serveContentAssets===void 0?{}:{serveContentAssets:e.serveContentAssets},...e.reactShellDistDir?{reactShellDistDir:e.reactShellDistDir}:{}});M||={action:`skip`,reason:`alive`,pid:0,port:0};let z=M,U=null;if(z.action===`skip`)U=z.port>0?z.port:null;else if(!c){let t=e.uiBindTimeoutMs??3e3;U=await K({readUiLock:()=>b(R.lockDir),now:Date.now,sleep:e=>E(e),timeoutMs:t,pollIntervalMs:50}),U===null&&w.warn({timeoutMs:t},`[start] ok ui did not bind within timeout — banner falls back to API URL`)}return{httpServer:R.httpServer,destroy:R.destroy,lockDir:R.lockDir,contentDir:j,port:R.port,ready:R.ready,degraded:R.degraded,uiSpawnDecision:M,spawnedUiPid:N,resolvedUiPort:U}}function ne(e){if(e===`browser`||e===`app`)return e;throw new a(`--mode must be 'browser' or 'app'`)}function re(e){let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<1||t>65535)throw new a(`--ui-port must be a port number between 1 and 65535`);return t}function Q(e){return e.OK_CONSOLE_LEVEL!==void 0||e.LOG_LEVEL!==void 0?null:`warn`}function ie(e){let t=[`Stopping OpenKnowledge…`,`Saving pending changes and releasing the server lock — this can take a few seconds.`];return e===`SIGINT`&&t.push(`Press Ctrl+C again to force quit.`),t}async function ae(e,t){let n=Q(process.env);n!==null&&(process.env.OK_CONSOLE_LEVEL=n);let{renderBanner:r}=await import(`./banner-B6HYYw6k.mjs`),{accent:i,dim:a,error:o,warning:s}=await import(`./colors-MGDi6UGf.mjs`),c=process.cwd(),l=t.remote!==void 0&&t.remote!==!1,u=typeof t.remote==`string`?t.remote:void 0,d=u===void 0?e:{...e,remote:{...e.remote,url:u}};process.title=z(c),l&&(typeof d.remote?.url!=`string`||d.remote.url===``)&&(console.error(o("--remote requires a public tunnel URL — pass it (`ok start --remote https://<your-tunnel-host>`) or set remote.url in .ok/config.yml.")),process.exit(78)),l&&console.warn(s([``,`⚠ REMOTE ACCESS ENABLED — no server-side authentication.`,` Anyone who can reach ${d.remote?.url} has FULL control of this`,` knowledge base, including sync, publishing, credentials, and local operations.`,` Restrict who can reach it at the tunnel: ngrok OAuth, Cloudflare Access,`,` Tailscale ACLs, or equivalent edge auth.`,``].join(`
2
+ `)));let f=j(t,process.env),p=R(f,l);p.coerced&&console.warn(`remote access is enabled and ${f} is not an IPv4 loopback bind — tunnels proxy to 127.0.0.1, so binding ${f} would leave the tunnel dialing a dead port. Using 127.0.0.1.`);let m=p.host,g=t.port===void 0?void 0:Number(t.port),_=process.env.PORT?Number(process.env.PORT):void 0,v=t.uiPort===void 0?void 0:Number(t.uiPort);l&&g===void 0&&_!==void 0&&console.warn(`remote access is enabled — ignoring env PORT=${process.env.PORT}; the tunnel's port mapping targets the stable remote port (${d.remote?.port??24550}). Pass --port to override deliberately.`);let y=U(g,_,v,l)??(l?d.remote?.port??24550:void 0);if(v!==void 0){let{readServerLock:e,resolveLockDir:t}=await import(`./src-Dg0jHVcz.mjs`);if(ee(v,e(t(c)))){await G({cwd:c,uiPort:v});return}}let b=P({explicitDir:t.reactShellDistDir,only:t.only,uiPortSet:v!==void 0,remoteEnabled:l,findBundledDir:N}),x=b.dir;b.missingBundle&&console.warn(l?`remote access: bundled web UI not found — serving /mcp and /api only over the tunnel.`:`bundled web UI not found — serving /api and /mcp only. Reinstall @inkeep/open-knowledge, or build packages/app in a source checkout.`);let S;try{S=await Z({config:d,cwd:c,host:m,port:y,...v===void 0?{}:{uiPort:v},...t.serveContentAssets===void 0?{}:{serveContentAssets:t.serveContentAssets},...x?{reactShellDistDir:x}:{},...t.only===`server`||b.missingBundle?{skipUiAutoSpawn:!0}:{},...t.idleShutdown===void 0?{}:{idleThresholdMs:t.idleShutdown},...t.singleFile?{singleFile:t.singleFile}:{},...t.projectDir?{projectDir:t.projectDir}:{},...l?{enableRemote:!0}:{}})}catch(e){e instanceof B&&(console.error(o(e.message)),process.exit(1));let t=await import(`./src-Dg0jHVcz.mjs`);if((e instanceof t.GitNotAvailableError||e instanceof t.GitTooOldError)&&process.exit(78),e instanceof t.RemoteConfigError&&(console.error(o(e.message)),process.exit(78)),(e instanceof t.SingleFileNotFoundError||e instanceof t.SingleFileNotAFileError||e instanceof t.SingleFileNotMarkdownError)&&(console.error(o(e.message)),process.exit(1)),v!==void 0&&$(e,t)){await G({cwd:c,uiPort:v});return}if(v===void 0&&$(e,t)){let e=t.resolveLockDir(c),n=null;try{n=await oe({readServerLock:()=>t.readServerLock(e),readUiLock:()=>t.readUiLock(e),now:Date.now,sleep:e=>E(e),timeoutMs:3e3,pollIntervalMs:50})}catch(e){process.stderr.write(`[start] spawn-or-reuse: lock poll failed (${e instanceof Error?e.message:String(e)}) — falling back to the collision message\n`)}if(n!==null){let[e,...t]=se(n);console.log(i(e));for(let e of t)console.log(a(e));process.exit(0)}}let n=ce(e,c,t);n!==null&&(console.error(o(n)),process.exit(1)),console.error(`${o(`Failed to start:`)} ${e instanceof Error?e.stack??e.message:String(e)}`),process.exit(1)}let C=!1,w=async e=>{if(C)return;C=!0;let[t,...n]=ie(e);console.log(i(`\n${t}`));for(let e of n)console.log(a(` ${e}`));if(S.spawnedUiPid!==null)try{let{getLogger:e,isProcessAlive:t,readUiLock:n}=await import(`./src-Dg0jHVcz.mjs`);await Y({readUiLock:()=>n(S.lockDir),spawnedUiPid:()=>S.spawnedUiPid,isAlive:t,killPid:(e,t)=>process.kill(e,t),log:e(`start`),reason:`shutdown`})}catch(e){console.error(`${o(`ui sibling teardown failed:`)} ${e instanceof Error?e.stack??e.message:String(e)}`)}try{await S.destroy()}catch(e){console.error(`${o(`destroy() failed:`)} ${e instanceof Error?e.stack??e.message:String(e)}`),process.exitCode=1}process.exit(process.exitCode??0)};process.once(`SIGINT`,()=>{w(`SIGINT`)}),process.once(`SIGTERM`,()=>{w(`SIGTERM`)});let T=m.includes(`:`)&&!m.startsWith(`[`)?`[${m}]`:m,D=`http://${T}:${S.port}`,O=m===`0.0.0.0`||m===`::`?`http://0.0.0.0:${S.port}`:void 0,k=S.resolvedUiPort,A=k!==null&&k>0?`http://${T}:${k}`:D;console.log(r({name:`open-knowledge`,version:h,localUrl:A,apiUrl:A===D?void 0:D,networkUrl:O,nextSteps:[`Open the Editor URL in your browser to start editing.`]}));let M={"shadow-repo":`Version history and branch-switch safety unavailable`,"file-watcher":`External file changes will not sync to the editor`,"head-watcher":`Git branch switches may cause document inconsistency`};S.ready.then(async()=>{if(S.degraded.length>0){console.log();for(let e of S.degraded){let t=M[e]??`${e} (check server logs for details)`;console.warn(` ${s(`⚠`)} ${s(e)}: ${a(t)}`)}console.log()}if(L({openBrowser:t.openBrowser!==!1,legacyOpen:t.open===!0,host:m,isTTY:process.stdout.isTTY===!0,remoteEnabled:l,ephemeral:t.singleFile!==void 0,only:t.only,servesUi:x!==void 0})){let{openBrowser:e}=await import(`./open-browser-OsCLGa-m.mjs`);e(A)}}).catch(e=>{console.error(` ${o(`Server initialization failed:`)} ${e instanceof Error?e.message:String(e)}`)})}async function oe(e){let t=e.now()+e.timeoutMs,n=e.readServerLock();for(;n!==null&&n.draining!==!0&&n.port<=0&&e.now()<t;)await e.sleep(e.pollIntervalMs),n=e.readServerLock();if(n===null||n.draining===!0||n.port<=0)return null;if(n.capabilities?.includes(`ui`)===!0&&n.url!==void 0)return{url:n.url,kind:n.kind,pid:n.pid,servesUi:!0};let r=e.readUiLock();return r!==null&&r.port>0?{url:r.url??`http://localhost:${r.port}`,kind:n.kind,pid:n.pid,servesUi:!1}:{url:n.url??`http://127.0.0.1:${n.port}`,kind:n.kind,pid:n.pid,servesUi:!1}}function se(e){return[`${e.kind===`mcp-spawned`?`An MCP-spawned OpenKnowledge server is already running on this project`:`OpenKnowledge is already running on this project`} (pid ${e.pid}).`,` ${e.url}`,"Leaving it running — run `ok stop` first if you want a fresh server."]}function $(e,t){let n=t.ServerLockCollisionError;return n!==void 0&&e instanceof n}function ce(e,t,n){let r=n.ServerLockCollisionError;if(r===void 0||!(e instanceof r))return null;try{let e=n.readServerLock(n.resolveLockDir(t));return e&&e.kind===`mcp-spawned`?"An MCP-spawned server holds this lock; it should release on idle-shutdown (~30 min). Or run `ok stop`.":"OpenKnowledge server is already running on this project — check `ok status` or `ok stop`."}catch{return null}}function le(e){return new s(`start`).description(`Start the OpenKnowledge server (UI + API + MCP + collab on one port)`).option(`-p, --port <port>`,`Server port`,void 0).option(`--ui-port <port>`,`Pin the ok ui sibling to <port> and connect (not exit) if a server already runs here — the worktree-preview recipe path`,re).option(`--bind <address>`,`Bind address (repeatable; default 127.0.0.1 — loopback only)`,(e,t)=>[...t??[],e]).addOption(new o(`-H, --host <host>`,`Deprecated alias of --bind`).hideHelp()).option(`--no-open-browser`,`Do not open the browser after start (interactive loopback starts open it by default)`).addOption(new o(`--open`,`Deprecated: force-open the browser after start`).hideHelp()).option(`--only <module>`,`Serve one module: 'server' (API + MCP only, no shell or browser) or 'ui' (shell + proxy only; requires --server-url)`,M).option(`--server-url <url>`,`Project-server URL the --only ui process proxies to (e.g. http://127.0.0.1:24550)`).option(`--idle-shutdown <duration>`,`Shut the server down after this long with no connected clients ('off', or a duration like 90s, 30m, 2h; default 30m)`,F).option(`--mode <mode>`,`Force dispatch mode: 'browser' or 'app'`,ne).option(`--serve-content-assets`,`Serve content assets from this server (now the default; kept for compatibility)`).option(`--react-shell-dist-dir <path>`,`Serve React shell from <path> (suppresses ok ui sibling)`).option(`--single-file <path>`,`No-project ephemeral single-file mode: scope the server to one markdown file (git + MCP off)`).option(`--project-dir <dir>`,`Throwaway project root for --single-file (where ephemeral .ok/ state lives)`).option(`--remote [url]`,`Serve through a tunnel: admit requests carrying the tunnel Host with NO server-side auth (anyone who can reach the URL has full control — restrict access at the tunnel with edge auth). Bare --remote uses remote.url from .ok/config.yml; --remote <url> supplies it for this run.`).action(async t=>{let n=e();if(t.bind!==void 0&&t.bind.length>1&&(process.stderr.write(`error: multiple --bind addresses are not supported yet — pass a single address
3
3
  `),process.exit(2)),t.serverUrl!==void 0&&t.only!==`ui`&&(process.stderr.write(`error: option '--server-url' requires '--only ui'
4
4
  `),process.exit(2)),t.only===`server`&&t.reactShellDistDir!==void 0&&(process.stderr.write(`error: option '--only server' cannot be combined with '--react-shell-dist-dir'
5
5
  `),process.exit(2)),t.only===`ui`){t.serverUrl===void 0&&(process.stderr.write(`error: '--only ui' requires '--server-url <url>' (where the project server runs)
6
6
  `),process.exit(2)),t.mode===`app`&&(process.stderr.write(`error: option '--only ui' cannot be combined with '--mode app'
7
7
  `),process.exit(2)),t.remote!==void 0&&t.remote!==!1&&(process.stderr.write(`error: option '--only ui' cannot be combined with '--remote'
8
- `),process.exit(2));let{runUiCommand:e}=await import(`./ui-BEwSKtfp.mjs`);await e(n,{...t.port===void 0?{}:{port:String(t.port)},...t.bind?.[0]===void 0?t.host===void 0?{}:{host:t.host}:{host:t.bind[0]},upstreamUrl:t.serverUrl});return}if(t.mode===`app`){t.open&&(process.stderr.write(`error: option '--mode=app' cannot be combined with '--open' (--open opens a browser tab against the local server, which app mode does not boot)
8
+ `),process.exit(2));let{runUiCommand:e}=await import(`./ui-D9Vnv2aH.mjs`);await e(n,{...t.port===void 0?{}:{port:String(t.port)},...t.bind?.[0]===void 0?t.host===void 0?{}:{host:t.host}:{host:t.bind[0]},upstreamUrl:t.serverUrl});return}if(t.mode===`app`){t.open&&(process.stderr.write(`error: option '--mode=app' cannot be combined with '--open' (--open opens a browser tab against the local server, which app mode does not boot)
9
9
  `),process.exit(2));let e=[];if(t.port!==void 0&&e.push(`--port`),t.uiPort!==void 0&&e.push(`--ui-port`),t.bind!==void 0&&e.push(`--bind`),t.host!==void 0&&e.push(`--host`),t.only!==void 0&&e.push(`--only`),t.serverUrl!==void 0&&e.push(`--server-url`),t.idleShutdown!==void 0&&e.push(`--idle-shutdown`),t.openBrowser===!1&&e.push(`--no-open-browser`),e.length>0){let t=process.env.OK_LOG_LEVEL??`info`;(t===`debug`||t===`trace`)&&console.error(`--mode=app: ignoring ${e.join(`, `)}`)}let n=d(p());if(n.available){c({spawn:g},n);return}console.error(f(n.reason)),process.exit(1)}await ae(n,t)})}export{J as A,ee as C,Y as D,le as E,ce as O,ae as S,H as T,U as _,R as a,Q as b,V as c,ie as d,I as f,N as g,M as h,X as i,A as j,q as k,z as l,F as m,K as n,W as o,$ as p,Z as r,G as s,B as t,se as u,j as v,L as w,P as x,oe as y};
10
- //# sourceMappingURL=start-RRmOhFPJ.mjs.map
10
+ //# sourceMappingURL=start-Dtt8oak3.mjs.map