@inkeep/open-knowledge 0.21.0-beta.0 → 0.21.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/skills/discovery/SKILL.md +1 -1
- package/dist/assets/skills/project/SKILL.md +1 -1
- package/dist/cli.mjs +6 -6
- package/dist/constants-B1kUAGNO.mjs +2 -0
- package/dist/{dist-BOoSXzXj.mjs → dist-BXkqG4_t.mjs} +1 -1
- package/dist/{dist-B3Nl3Djt.mjs → dist-nP_B5M33.mjs} +6 -6
- package/dist/index.mjs +1 -1
- package/dist/{init-eaHzzLcd.mjs → init-Ak9suQ75.mjs} +4 -4
- package/dist/init-CxrOs0W4.mjs +1 -0
- package/dist/{loader-DcKU2Suk.mjs → loader-BVs0WYpU.mjs} +2 -2
- package/dist/loader-xdAClmEv.mjs +1 -0
- package/dist/native/native-config.darwin-arm64.node +0 -0
- package/dist/native/native-config.darwin-x64.node +0 -0
- package/dist/native/native-config.linux-arm64-gnu.node +0 -0
- package/dist/native/native-config.linux-arm64-musl.node +0 -0
- package/dist/native/native-config.linux-x64-gnu.node +0 -0
- package/dist/native/native-config.linux-x64-musl.node +0 -0
- package/dist/native/native-config.win32-arm64-msvc.node +0 -0
- package/dist/native/native-config.win32-x64-msvc.node +0 -0
- package/dist/preview-Bagt5mHL.mjs +1 -0
- package/dist/{preview-Df40RFQg.mjs → preview-CPgs08By.mjs} +2 -2
- package/dist/{repair-launch-json-C6ZO5Cqt.mjs → repair-launch-json-CqFPyLPp.mjs} +2 -2
- package/dist/{repair-mcp-configs-D6D3yZP6.mjs → repair-mcp-configs-m-qKZ1di.mjs} +2 -2
- package/dist/{repair-skills-DrDTStak.mjs → repair-skills-BoKqLpQM.mjs} +2 -2
- package/dist/repair-skills-ryoDc1DM.mjs +1 -0
- package/dist/{src-DYiP4t4O.mjs → src-CUvh3EvH.mjs} +2 -2
- package/dist/start-Dxf_HWcT.mjs +1 -0
- package/dist/{start-n0uv2kHZ.mjs → start-PlBOTbZt.mjs} +2 -2
- package/dist/{write-project-skill-DzjgQ8XK.mjs → write-project-skill-CIinFCKZ.mjs} +2 -2
- package/package.json +1 -1
- package/dist/constants-x0acspSh.mjs +0 -2
- package/dist/init-DOCf2MYY.mjs +0 -1
- package/dist/loader-Bx2WWZdB.mjs +0 -1
- package/dist/preview-Bob5z4VP.mjs +0 -1
- package/dist/repair-skills-ClESzPry.mjs +0 -1
- package/dist/start-B4FrQZ1j.mjs +0 -1
|
@@ -851,7 +851,7 @@ Karpathy's insight: "The tedious part of maintaining a knowledge base is not the
|
|
|
851
851
|
`,`
|
|
852
852
|
`).replaceAll(`\r`,`
|
|
853
853
|
`).split(`
|
|
854
|
-
`),D=[],O=new Set,k=null,j=(e,t,s)=>{O.has(e)||(O.add(e),D.push({href:e,resolvedTo:t,reason:s}))},F=e=>{let s=e.trim();if(s.startsWith(`#`))return;let w=classifyMarkdownHref(s,t);if(!w){j(s,null,`unresolvable`);return}if(w.kind===`doc`){S.has(w.docName)||j(s,w.docName,`no-such-doc`);return}if(w.kind===`asset`){if(!g)return;let e=resolveAssetProjectPath(w.url,t);if(e===null){j(s,null,`unresolvable`);return}g(e)||j(s,e,`no-such-file`);return}},L=(e,t)=>{let s=classifyWikiLinkTarget(e,t);!s||s.kind!==`doc`||S.has(s.docName)||j(`[[${e}${t?`#${t}`:``}]]`,s.docName,`no-such-doc`)};for(let e of E){if(k){isFenceClose$1(e,k)&&(k=null);continue}let t=matchFence$1(e);if(t){k=t;continue}let s=leadingMarkdownPrefixLength$1(e);for(;s<e.length;){if(e[s]===`\\`&&s+1<e.length){s+=2;continue}if(e[s]==="`"){let t=readInlineCode$1(e,s);if(t){s=t.nextIndex;continue}}if(e[s]===`[`&&e[s+1]===`[`){let t=readWikiLink$1(e,s);if(t){L(t.target,t.anchor),s=t.nextIndex;continue}}if(e[s]===`[`&&e[s-1]!==`!`){let t=readMarkdownLink$1(e,s);if(t){F(t.href),s=t.nextIndex;continue}}s++}}return D}function serializeState(e){return{backward:Object.fromEntries([...e.backward.entries()].map(([e,t])=>[e,[...t.entries()].map(([e,t])=>({source:e,anchor:t.anchor,snippet:t.snippet}))])),forward:Object.fromEntries([...e.forward.entries()].map(([e,t])=>[e,[...t].sort()])),externalForward:Object.fromEntries([...e.externalForward.entries()].map(([e,t])=>[e,[...t.entries()].map(([e,t])=>({url:e,label:t.label,snippet:t.snippet})).sort((e,t)=>e.url.localeCompare(t.url))]))}}function buildExternalBackward(e){let t=new Map;for(let[s,g]of e)for(let[e,S]of g){let g=t.get(e);g||(g=new Map,t.set(e,g)),g.set(s,S)}return t}function deserializeState(e){let t=new Map(Object.entries(e.externalForward??{}).map(([e,t])=>[e,new Map(t.map(e=>[e.url,{label:e.label??null,snippet:e.snippet??null}]))]));return{backward:new Map(Object.entries(e.backward??{}).map(([e,t])=>[e,new Map(t.map(e=>[e.source,{anchor:e.anchor??null,snippet:e.snippet??null}]))])),forward:new Map(Object.entries(e.forward??{}).map(([e,t])=>[e,new Set(t)])),externalForward:t,externalBackward:buildExternalBackward(t)}}var BacklinkIndex=class{projectDir;contentDir;contentFilter;states=new Map;mtimesByBranch=new Map;activeBranch=`main`;constructor(e){this.projectDir=e.projectDir,this.contentDir=e.contentDir,this.contentFilter=e.contentFilter,this.states.set(this.activeBranch,createEmptyState$1())}getState(e=this.activeBranch){let t=this.states.get(e);return t||(t=createEmptyState$1(),this.states.set(e,t)),t}structuralBundleNeighbors(e,t=this.activeBranch){let s=parseSkillBundleDocAnyScope(e),g=new Set;if(!s)return g;let S=this.getState(t);if(!S.forward.has(e))return g;if(s.kind===`skill`)for(let t of S.forward.keys()){let s=parseSkillBundleDocAnyScope(t);s?.kind===`reference`&&s.skillDocName===e&&g.add(t)}else S.forward.has(s.skillDocName)&&g.add(s.skillDocName);return g}getActiveBranch(){return this.activeBranch}switchBranch(e){this.activeBranch=e,this.getState(e)}cachePath(e=this.activeBranch){return resolve(getLocalDir(this.projectDir),`cache`,e,`backlinks.json`)}registerNodeOnly(e,t=this.activeBranch){let s=this.getState(t),g=s.forward.get(e)??new Set,S=s.externalForward.get(e)??new Map;for(let t of g){let g=s.backward.get(t);g&&(g.delete(e),g.size===0&&s.backward.delete(t))}for(let t of S.keys()){let g=s.externalBackward.get(t);g&&(g.delete(e),g.size===0&&s.externalBackward.delete(t))}s.forward.set(e,new Set),s.externalForward.set(e,new Map)}registerGlobalSkillBundleNode(e,t=this.activeBranch){parseGlobalSkillBundleDoc(e)&&this.registerNodeOnly(e,t)}updateDocument(e,t,s=[],g=this.activeBranch){if(isLinkIndexExcludedDoc(e))return;if(parseGlobalSkillBundleDoc(e)){this.registerNodeOnly(e,g);return}let S=this.getState(g),w=S.forward.get(e)??new Set,E=S.externalForward.get(e)??new Map;for(let t of w){let s=S.backward.get(t);s&&(s.delete(e),s.size===0&&S.backward.delete(t))}for(let t of E.keys()){let s=S.externalBackward.get(t);s&&(s.delete(e),s.size===0&&S.externalBackward.delete(t))}let D=new Set,O=new Map;S.forward.set(e,D),S.externalForward.set(e,O);for(let s of t){if(!s.target)continue;let t=managedArtifactDocNameFromContentTarget(s.target)??s.target;D.add(t);let g=S.backward.get(t);g||(g=new Map,S.backward.set(t,g)),g.set(e,mergeLinkMeta(g.get(e),{anchor:s.anchor,snippet:s.snippet}))}for(let t of s){if(!t.url)continue;O.set(t.url,{label:t.label,snippet:t.snippet});let s=S.externalBackward.get(t.url);s||(s=new Map,S.externalBackward.set(t.url,s)),(!s.has(e)||!s.get(e)?.snippet&&t.snippet)&&s.set(e,{label:t.label,snippet:t.snippet})}}updateDocumentFromMarkdown(e,t,s=this.activeBranch){try{let{body:g}=stripFrontmatter(t),S=extractWikiLinksFromMarkdown(g,e),w=extractMarkdownLinksFromMarkdown(g,e),E=extractExternalWikiLinksFromMarkdown(g),D=extractExternalMarkdownLinksFromMarkdown(g,e),O=new Set(S.map(e=>e.target)),k=[...S,...w.filter(e=>!O.has(e.target))],j=new Set(E.map(e=>e.url)),F=[...E,...D.filter(e=>!j.has(e.url))];this.updateDocument(e,k,F,s)}catch(t){console.warn(`[backlinks] Failed to scan ${e} for link extraction:`,t),this.deleteDocument(e,s)}}deleteDocument(e,t=this.activeBranch){if(isLinkIndexExcludedDoc(e))return;let s=this.getState(t),g=s.forward.get(e)??new Set,S=s.externalForward.get(e)??new Map;for(let t of g){let g=s.backward.get(t);g&&(g.delete(e),g.size===0&&s.backward.delete(t))}for(let t of S.keys()){let g=s.externalBackward.get(t);g&&(g.delete(e),g.size===0&&s.externalBackward.delete(t))}s.forward.delete(e),s.externalForward.delete(e)}renameDocument(e,t,s,g=this.activeBranch){this.deleteDocument(e,g),this.updateDocumentFromMarkdown(t,s,g)}getBacklinks(e,t=this.activeBranch){let s=this.getState(t).backward.get(e),g=new Map;if(s)for(let[e,t]of s)g.set(e,{source:e,anchor:t.anchor,snippet:t.snippet});for(let s of this.structuralBundleNeighbors(e,t))g.has(s)||g.set(s,{source:s,anchor:null,snippet:null});return[...g.values()].sort((e,t)=>e.source.localeCompare(t.source))}getBacklinkCount(e,t=this.activeBranch){let s=this.getState(t).backward.get(e),g=this.structuralBundleNeighbors(e,t);if(g.size===0)return s?.size??0;let S=new Set(s?.keys()??[]);for(let e of g)S.add(e);return S.size}getForwardLinks(e,t=this.activeBranch){let s=this.getState(t),g=new Set(s.forward.get(e)??new Set);for(let s of this.structuralBundleNeighbors(e,t))g.add(s);return[...g].sort((e,t)=>e.localeCompare(t))}getForwardLinkEntries(e,t=this.activeBranch){let s=this.getState(t),g=this.getForwardLinks(e,t).map(t=>({kind:`doc`,target:t,anchor:s.backward.get(t)?.get(e)?.anchor??null,snippet:s.backward.get(t)?.get(e)?.snippet??null})),S=[...(s.externalForward.get(e)??new Map).entries()].map(([e,t])=>({kind:`external`,url:e,label:t.label,snippet:t.snippet})).sort((e,t)=>e.url.localeCompare(t.url));return[...g,...S]}getOrphans(e,t=`both`,s=this.activeBranch){let g=this.getState(s),S=new Set;for(let e of g.forward.keys()){let t=parseSkillBundleDocAnyScope(e);t?.kind===`reference`&&S.add(t.skillDocName)}let w=e=>{let t=parseSkillBundleDocAnyScope(e);return!t||!g.forward.has(e)?!1:t.kind===`skill`?S.has(e):g.forward.has(t.skillDocName)};return[...e].filter(e=>{let s=w(e),S=s||(g.backward.get(e)?.size??0)>0,E=s||(g.forward.get(e)?.size??0)>0;return t===`incoming`?!S:(t===`outgoing`||!S)&&!E}).sort((e,t)=>e.localeCompare(t))}getHubs(e=20,t=this.activeBranch){return[...this.getState(t).backward.entries()].map(([e,t])=>({docName:e,count:t.size})).sort((e,t)=>t.count===e.count?e.docName.localeCompare(t.docName):t.count-e.count).slice(0,e)}getDeadLinks(e,t,s=this.activeBranch){let g=this.getState(s),S=new Set(e),w=t?.length?new Set(t):null;return[...g.backward.entries()].filter(([e,t])=>{if(S.has(e)||g.forward.has(e))return!1;if(!w)return t.size>0;for(let e of t.keys())if(w.has(e))return!0;return!1}).map(([e,t])=>({target:e,sources:[...t.entries()].filter(([e])=>!w||w.has(e)).map(([e,t])=>({source:e,anchor:t.anchor,snippet:t.snippet})).sort((e,t)=>e.source.localeCompare(t.source))})).filter(e=>e.sources.length>0).sort((e,t)=>t.sources.length===e.sources.length?e.target.localeCompare(t.target):t.sources.length-e.sources.length)}getLinkGraph(e=this.activeBranch){let t=this.getState(e),s=new Map,g=[];for(let[e,S]of t.forward){s.set(e,{kind:`doc`,id:e,docName:e,anchor:getRepresentativeAnchor(t.backward.get(e))});for(let w of S)s.set(w,{kind:`doc`,id:w,docName:w,anchor:getRepresentativeAnchor(t.backward.get(w))}),g.push({source:e,target:w})}for(let[e,S]of t.externalForward){s.set(e,{kind:`doc`,id:e,docName:e,anchor:getRepresentativeAnchor(t.backward.get(e))});for(let[t,w]of S){let S=externalNodeId(t);s.set(S,{kind:`external`,id:S,url:t,label:w.label}),g.push({source:e,target:S})}}for(let S of t.forward.keys())if(parseSkillBundleDocAnyScope(S)?.kind===`skill`)for(let w of this.structuralBundleNeighbors(S,e))t.forward.get(S)?.has(w)||t.forward.get(w)?.has(S)||(s.set(S,{kind:`doc`,id:S,docName:S,anchor:getRepresentativeAnchor(t.backward.get(S))}),s.set(w,{kind:`doc`,id:w,docName:w,anchor:getRepresentativeAnchor(t.backward.get(w))}),g.push({source:S,target:w}));return{nodes:[...s.values()].sort((e,t)=>e.id.localeCompare(t.id)),links:g}}getLinkGraphNeighborhood(e,t,s=this.activeBranch){let g=this.getState(s),S=new Map;for(let e of g.externalForward.values())for(let[t,s]of e)S.has(t)||S.set(t,s.label);let w=new Set([e]),E=[{nodeId:e,degree:0}],D=0;for(;D<E.length;){let e=E[D++];if(e.degree>=t)continue;let S=externalUrlFromNodeId(e.nodeId),O=new Set;if(S)for(let e of g.externalBackward.get(S)?.keys()??[])O.add(e);else{for(let t of g.forward.get(e.nodeId)??new Set)O.add(t);for(let t of g.externalForward.get(e.nodeId)?.keys()??[])O.add(externalNodeId(t));for(let t of g.backward.get(e.nodeId)?.keys()??[])O.add(t);for(let t of this.structuralBundleNeighbors(e.nodeId,s))O.add(t)}for(let t of O)w.has(t)||(w.add(t),E.push({nodeId:t,degree:e.degree+1}))}let O=[];for(let[e,t]of g.forward)if(w.has(e))for(let s of t)w.has(s)&&O.push({source:e,target:s});for(let[e,t]of g.externalForward)if(w.has(e))for(let s of t.keys()){let t=externalNodeId(s);w.has(t)&&O.push({source:e,target:t})}for(let e of w)if(parseSkillBundleDocAnyScope(e)?.kind===`skill`)for(let t of this.structuralBundleNeighbors(e,s))w.has(t)&&(g.forward.get(e)?.has(t)||g.forward.get(t)?.has(e)||O.push({source:e,target:t}));return{nodes:[...w].sort().map(e=>{let t=externalUrlFromNodeId(e);return t?{kind:`external`,id:e,url:t,label:S.get(t)??null}:{kind:`doc`,id:e,docName:e,anchor:getRepresentativeAnchor(g.backward.get(e))}}),links:O}}async saveToDisk(e=this.activeBranch){let t=this.cachePath(e);mkdirSync(dirname(t),{recursive:!0});let s=this.getState(e),g=this.mtimesByBranch.get(e),S={...serializeState(s),...g?{mtimes:Object.fromEntries(g)}:{}};await writeFile(t,JSON.stringify(S,null,2),`utf-8`)}async loadFromDisk(e=this.activeBranch){let t=this.cachePath(e);if(!existsSync(t))return!1;try{let s=await readFile$1(t,`utf-8`),g=JSON.parse(s);return this.states.set(e,deserializeState(g)),g.mtimes?this.mtimesByBranch.set(e,new Map(Object.entries(g.mtimes))):this.mtimesByBranch.delete(e),!0}catch(t){return console.warn(`[backlinks] Failed to load cache for ${e}:`,t),!1}}clear(e=this.activeBranch){this.states.set(e,createEmptyState$1()),this.mtimesByBranch.delete(e)}async rebuildFromDisk(e=this.activeBranch){let t=createEmptyState$1(),s=new Map,g=[];await this.walkForPaths(this.contentDir,g);let S=new Set,w=g.filter(({docName:e})=>S.has(e)?!1:(S.add(e),!0)),E=50;for(let e=0;e<w.length;e+=50){let g=w.slice(e,e+50),S=await Promise.allSettled(g.map(async({docName:e,filePath:t})=>{let[s,g]=await Promise.all([stat$1(t),readFile$1(t,`utf-8`)]);return{docName:e,mtimeMs:s.mtimeMs,markdown:g}}));for(let e of S){if(e.status===`rejected`){console.warn(`[backlinks] Failed to rebuild entry:`,e.reason);continue}let{docName:g,mtimeMs:S,markdown:w}=e.value;s.set(g,S);let{body:E}=stripFrontmatter(w),D=extractWikiLinksFromMarkdown(E,g),O=extractMarkdownLinksFromMarkdown(E,g),k=extractExternalWikiLinksFromMarkdown(E),j=extractExternalMarkdownLinksFromMarkdown(E,g),F=new Set(D.map(e=>e.target)),L=[...D,...O.filter(e=>!F.has(e.target))],B=new Set(k.map(e=>e.url)),H=[...k,...j.filter(e=>!B.has(e.url))],q=new Set,ee=new Map;t.forward.set(g,q),t.externalForward.set(g,ee);for(let e of L){if(!e.target)continue;let s=managedArtifactDocNameFromContentTarget(e.target)??e.target;q.add(s);let S=t.backward.get(s);S||(S=new Map,t.backward.set(s,S)),S.set(g,mergeLinkMeta(S.get(g),{anchor:e.anchor,snippet:e.snippet}))}for(let e of H){if(!e.url)continue;ee.set(e.url,{label:e.label,snippet:e.snippet});let s=t.externalBackward.get(e.url);s||(s=new Map,t.externalBackward.set(e.url,s)),s.set(g,{label:e.label,snippet:e.snippet})}}}this.states.set(e,t),this.mtimesByBranch.set(e,s)}async walkForPaths(e,t){let s;try{s=await readdir(e,{withFileTypes:!0})}catch(t){console.warn(`[backlinks] Failed to read directory ${e}:`,t);return}for(let g of s){let s=join(e,g.name);if(g.isDirectory()){let e=toPosix(relative(this.contentDir,s));if(this.contentFilter&&e&&this.contentFilter.isDirExcluded(e))continue;await this.walkForPaths(s,t)}else if(g.isFile()&&isSupportedDocFile(g.name)){let e=toPosix(relative(this.contentDir,s));if(this.contentFilter?.isExcluded(e))continue;t.push({docName:stripDocExtension(e),filePath:s})}}}async reconcileWithDisk(e=this.activeBranch){if(!existsSync(this.contentDir))return{added:0,updated:0,deleted:0};let t=this.mtimesByBranch.get(e)??new Map,s=[];await this.walkForPaths(this.contentDir,s);let g=new Set,S=s.filter(({docName:e})=>g.has(e)?!1:(g.add(e),!0)),w=new Set(S.map(e=>e.docName)),E=new Map,D=0,O=0,k=[],j=await Promise.allSettled(S.map(async({docName:e,filePath:t})=>({docName:e,filePath:t,mtimeMs:(await stat$1(t)).mtimeMs})));for(let e of j){if(e.status===`rejected`)continue;let{docName:s,filePath:g,mtimeMs:S}=e.value,w=t.get(s);if(w!==void 0&&w===S){E.set(s,S);continue}k.push({docName:s,filePath:g,mtimeMs:S,isNew:w===void 0})}let F=50;for(let t=0;t<k.length;t+=50){let s=k.slice(t,t+50),g=await Promise.allSettled(s.map(async({docName:e,filePath:t,mtimeMs:s,isNew:g})=>({docName:e,mtimeMs:s,isNew:g,markdown:await readFile$1(t,`utf-8`)})));for(let t of g){if(t.status===`rejected`){console.warn(`[backlinks] Failed to reconcile file:`,t.reason);continue}let{docName:s,mtimeMs:g,isNew:S,markdown:w}=t.value;this.updateDocumentFromMarkdown(s,w,e),E.set(s,g),S?D++:O++}}let L=0,B=new Set([...t.keys(),...this.getState(e).forward.keys()]);for(let t of B)parseGlobalSkillBundleDoc(t)||w.has(t)||(this.deleteDocument(t,e),L++);return this.mtimesByBranch.set(e,E),{added:D,updated:O,deleted:L}}async ingestGlobalSkillBundles(e,t=this.activeBranch){let s=new Set;for(let g of e){if(!existsSync(g))continue;let e;try{e=await readdir(g,{withFileTypes:!0})}catch(e){console.warn(`[backlinks] Failed to read global skills root ${g}:`,e);continue}for(let S of e){if(!S.isDirectory())continue;let e=S.name,w=join(g,e),E=skillLiveDocName(`global`,e);existsSync(join(w,`SKILL.md`))&&parseGlobalSkillBundleDoc(E)&&(this.registerNodeOnly(E,t),s.add(E));let D=[];await this.walkGlobalSkillReferences(join(w,`references`),e,``,D);for(let{docName:e}of D)this.registerNodeOnly(e,t),s.add(e)}}let g=[];for(let e of this.getState(t).forward.keys())parseGlobalSkillBundleDoc(e)&&!s.has(e)&&g.push(e);for(let e of g)this.deleteDocument(e,t)}async walkGlobalSkillReferences(e,t,s,g){let S;try{S=await readdir(e,{withFileTypes:!0})}catch(t){t?.code!==`ENOENT`&&console.warn(`[backlinks] Failed to read skill references dir ${e}:`,t);return}for(let w of S){let S=s?`${s}/${w.name}`:w.name;if(w.isDirectory())await this.walkGlobalSkillReferences(join(e,w.name),t,S,g);else if(w.isFile()&&isSupportedDocFile(w.name)){let e=stripDocExtension(S);g.push({docName:`${MANAGED_ARTIFACT_PREFIX_SKILL}global/${t}/references/${e}`})}}}};function extractActorIdentity(e,t){let s=normalizeSummary(e.summary);if(s.kind===`invalid`)return{kind:`invalid-summary`};let g=parseAgentBodyFields(e),S=t?.()??null;return g.rawAgentId!==void 0&&g.writerId!==void 0?{kind:`agent`,writerId:g.writerId,displayName:g.displayName,colorSeed:g.colorSeed??g.rawAgentId,clientName:g.clientName,clientVersion:g.clientVersion,label:g.label,actor:{principalId:S?.id,agentType:resolveAgentType(g.clientName),clientName:g.clientName,clientVersion:g.clientVersion,label:g.label},summary:s}:S?{kind:`principal`,writerId:S.id,displayName:S.display_name,colorSeed:S.id,actor:{principalId:S.id},summary:s}:{kind:`anonymous`,summary:s}}const ANCESTOR_WALK_DEPTH_LIMIT$1=30;function isProjectRoot(e){try{return statSync(resolve(e,OK_PROJECT_MARKER)).isFile()}catch(e){let t=e?.code;if(t===`ENOENT`||t===`ENOTDIR`)return!1;throw e}}function findEnclosingProjectRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT$1;){let e=!1;try{e=isProjectRoot(t)}catch{e=!1}if(e)return{rootPath:t,distance:s};let g=dirname(t);if(g===t)return null;t=g,s+=1}return null}function parsePorcelainPaths(e){let t=[];for(let s of e.split(`
|
|
854
|
+
`),D=[],O=new Set,k=null,j=(e,t,s)=>{O.has(e)||(O.add(e),D.push({href:e,resolvedTo:t,reason:s}))},F=e=>{let s=e.trim();if(s.startsWith(`#`))return;let w=classifyMarkdownHref(s,t);if(!w){j(s,null,`unresolvable`);return}if(w.kind===`doc`){S.has(w.docName)||j(s,w.docName,`no-such-doc`);return}if(w.kind===`asset`){if(!g)return;let e=resolveAssetProjectPath(w.url,t);if(e===null){j(s,null,`unresolvable`);return}g(e)||j(s,e,`no-such-file`);return}},L=(e,t)=>{let s=classifyWikiLinkTarget(e,t);!s||s.kind!==`doc`||S.has(s.docName)||j(`[[${e}${t?`#${t}`:``}]]`,s.docName,`no-such-doc`)};for(let e of E){if(k){isFenceClose$1(e,k)&&(k=null);continue}let t=matchFence$1(e);if(t){k=t;continue}let s=leadingMarkdownPrefixLength$1(e);for(;s<e.length;){if(e[s]===`\\`&&s+1<e.length){s+=2;continue}if(e[s]==="`"){let t=readInlineCode$1(e,s);if(t){s=t.nextIndex;continue}}if(e[s]===`[`&&e[s+1]===`[`){let t=readWikiLink$1(e,s);if(t){L(t.target,t.anchor),s=t.nextIndex;continue}}if(e[s]===`[`&&e[s-1]!==`!`){let t=readMarkdownLink$1(e,s);if(t){F(t.href),s=t.nextIndex;continue}}s++}}return D}function serializeState(e){return{backward:Object.fromEntries([...e.backward.entries()].map(([e,t])=>[e,[...t.entries()].map(([e,t])=>({source:e,anchor:t.anchor,snippet:t.snippet}))])),forward:Object.fromEntries([...e.forward.entries()].map(([e,t])=>[e,[...t].sort()])),externalForward:Object.fromEntries([...e.externalForward.entries()].map(([e,t])=>[e,[...t.entries()].map(([e,t])=>({url:e,label:t.label,snippet:t.snippet})).sort((e,t)=>e.url.localeCompare(t.url))]))}}function buildExternalBackward(e){let t=new Map;for(let[s,g]of e)for(let[e,S]of g){let g=t.get(e);g||(g=new Map,t.set(e,g)),g.set(s,S)}return t}function deserializeState(e){let t=new Map(Object.entries(e.externalForward??{}).map(([e,t])=>[e,new Map(t.map(e=>[e.url,{label:e.label??null,snippet:e.snippet??null}]))]));return{backward:new Map(Object.entries(e.backward??{}).map(([e,t])=>[e,new Map(t.map(e=>[e.source,{anchor:e.anchor??null,snippet:e.snippet??null}]))])),forward:new Map(Object.entries(e.forward??{}).map(([e,t])=>[e,new Set(t)])),externalForward:t,externalBackward:buildExternalBackward(t)}}var BacklinkIndex=class{projectDir;contentDir;contentFilter;states=new Map;mtimesByBranch=new Map;activeBranch=`main`;constructor(e){this.projectDir=e.projectDir,this.contentDir=e.contentDir,this.contentFilter=e.contentFilter,this.states.set(this.activeBranch,createEmptyState$1())}getState(e=this.activeBranch){let t=this.states.get(e);return t||(t=createEmptyState$1(),this.states.set(e,t)),t}structuralBundleNeighbors(e,t=this.activeBranch){let s=parseSkillBundleDocAnyScope(e),g=new Set;if(!s)return g;let S=this.getState(t);if(!S.forward.has(e))return g;if(s.kind===`skill`)for(let t of S.forward.keys()){let s=parseSkillBundleDocAnyScope(t);s?.kind===`reference`&&s.skillDocName===e&&g.add(t)}else S.forward.has(s.skillDocName)&&g.add(s.skillDocName);return g}getActiveBranch(){return this.activeBranch}switchBranch(e){this.activeBranch=e,this.getState(e)}cachePath(e=this.activeBranch){return resolve(getLocalDir(this.projectDir),`cache`,e,`backlinks.json`)}registerNodeOnly(e,t=this.activeBranch){let s=this.getState(t),g=s.forward.get(e)??new Set,S=s.externalForward.get(e)??new Map;for(let t of g){let g=s.backward.get(t);g&&(g.delete(e),g.size===0&&s.backward.delete(t))}for(let t of S.keys()){let g=s.externalBackward.get(t);g&&(g.delete(e),g.size===0&&s.externalBackward.delete(t))}s.forward.set(e,new Set),s.externalForward.set(e,new Map)}registerGlobalSkillBundleNode(e,t=this.activeBranch){parseGlobalSkillBundleDoc(e)&&this.registerNodeOnly(e,t)}updateDocument(e,t,s=[],g=this.activeBranch){if(isLinkIndexExcludedDoc(e))return;if(parseGlobalSkillBundleDoc(e)){this.registerNodeOnly(e,g);return}let S=this.getState(g),w=S.forward.get(e)??new Set,E=S.externalForward.get(e)??new Map;for(let t of w){let s=S.backward.get(t);s&&(s.delete(e),s.size===0&&S.backward.delete(t))}for(let t of E.keys()){let s=S.externalBackward.get(t);s&&(s.delete(e),s.size===0&&S.externalBackward.delete(t))}let D=new Set,O=new Map;S.forward.set(e,D),S.externalForward.set(e,O);for(let s of t){if(!s.target)continue;let t=managedArtifactDocNameFromContentTarget(s.target)??s.target;D.add(t);let g=S.backward.get(t);g||(g=new Map,S.backward.set(t,g)),g.set(e,mergeLinkMeta(g.get(e),{anchor:s.anchor,snippet:s.snippet}))}for(let t of s){if(!t.url)continue;O.set(t.url,{label:t.label,snippet:t.snippet});let s=S.externalBackward.get(t.url);s||(s=new Map,S.externalBackward.set(t.url,s)),(!s.has(e)||!s.get(e)?.snippet&&t.snippet)&&s.set(e,{label:t.label,snippet:t.snippet})}}updateDocumentFromMarkdown(e,t,s=this.activeBranch){try{let{body:g}=stripFrontmatter(t),S=extractWikiLinksFromMarkdown(g,e),w=extractMarkdownLinksFromMarkdown(g,e),E=extractExternalWikiLinksFromMarkdown(g),D=extractExternalMarkdownLinksFromMarkdown(g,e),O=new Set(S.map(e=>e.target)),k=[...S,...w.filter(e=>!O.has(e.target))],j=new Set(E.map(e=>e.url)),F=[...E,...D.filter(e=>!j.has(e.url))];this.updateDocument(e,k,F,s)}catch(t){console.warn(`[backlinks] Failed to scan ${e} for link extraction:`,t),this.deleteDocument(e,s)}}deleteDocument(e,t=this.activeBranch){if(isLinkIndexExcludedDoc(e))return;let s=this.getState(t),g=s.forward.get(e)??new Set,S=s.externalForward.get(e)??new Map;for(let t of g){let g=s.backward.get(t);g&&(g.delete(e),g.size===0&&s.backward.delete(t))}for(let t of S.keys()){let g=s.externalBackward.get(t);g&&(g.delete(e),g.size===0&&s.externalBackward.delete(t))}s.forward.delete(e),s.externalForward.delete(e)}renameDocument(e,t,s,g=this.activeBranch){this.deleteDocument(e,g),this.updateDocumentFromMarkdown(t,s,g)}getBacklinks(e,t=this.activeBranch){let s=this.getState(t).backward.get(e),g=new Map;if(s)for(let[e,t]of s)g.set(e,{source:e,anchor:t.anchor,snippet:t.snippet});for(let s of this.structuralBundleNeighbors(e,t))g.has(s)||g.set(s,{source:s,anchor:null,snippet:null});return[...g.values()].sort((e,t)=>e.source.localeCompare(t.source))}getBacklinkCount(e,t=this.activeBranch){let s=this.getState(t).backward.get(e),g=this.structuralBundleNeighbors(e,t);if(g.size===0)return s?.size??0;let S=new Set(s?.keys()??[]);for(let e of g)S.add(e);return S.size}getForwardLinks(e,t=this.activeBranch){let s=this.getState(t),g=new Set(s.forward.get(e)??new Set);for(let s of this.structuralBundleNeighbors(e,t))g.add(s);return[...g].sort((e,t)=>e.localeCompare(t))}getForwardLinkEntries(e,t=this.activeBranch){let s=this.getState(t),g=this.getForwardLinks(e,t).map(t=>({kind:`doc`,target:t,anchor:s.backward.get(t)?.get(e)?.anchor??null,snippet:s.backward.get(t)?.get(e)?.snippet??null})),S=[...(s.externalForward.get(e)??new Map).entries()].map(([e,t])=>({kind:`external`,url:e,label:t.label,snippet:t.snippet})).sort((e,t)=>e.url.localeCompare(t.url));return[...g,...S]}getOrphans(e,t=`both`,s=this.activeBranch){let g=this.getState(s),S=new Set;for(let e of g.forward.keys()){let t=parseSkillBundleDocAnyScope(e);t?.kind===`reference`&&S.add(t.skillDocName)}let w=e=>{let t=parseSkillBundleDocAnyScope(e);return!t||!g.forward.has(e)?!1:t.kind===`skill`?S.has(e):g.forward.has(t.skillDocName)};return[...e].filter(e=>{let s=w(e),S=s||(g.backward.get(e)?.size??0)>0,E=s||(g.forward.get(e)?.size??0)>0;return t===`incoming`?!S:(t===`outgoing`||!S)&&!E}).sort((e,t)=>e.localeCompare(t))}getHubs(e=20,t=this.activeBranch){return[...this.getState(t).backward.entries()].map(([e,t])=>({docName:e,count:t.size})).sort((e,t)=>t.count===e.count?e.docName.localeCompare(t.docName):t.count-e.count).slice(0,e)}getIndexedDocNames(e=this.activeBranch){return[...this.getState(e).forward.keys()]}getDeadLinks(e,t,s=this.activeBranch){let g=this.getState(s),S=new Set(e),w=t?.length?new Set(t):null;return[...g.backward.entries()].filter(([e,t])=>{if(S.has(e)||g.forward.has(e))return!1;if(!w)return t.size>0;for(let e of t.keys())if(w.has(e))return!0;return!1}).map(([e,t])=>({target:e,sources:[...t.entries()].filter(([e])=>!w||w.has(e)).map(([e,t])=>({source:e,anchor:t.anchor,snippet:t.snippet})).sort((e,t)=>e.source.localeCompare(t.source))})).filter(e=>e.sources.length>0).sort((e,t)=>t.sources.length===e.sources.length?e.target.localeCompare(t.target):t.sources.length-e.sources.length)}getLinkGraph(e=this.activeBranch){let t=this.getState(e),s=new Map,g=[];for(let[e,S]of t.forward){s.set(e,{kind:`doc`,id:e,docName:e,anchor:getRepresentativeAnchor(t.backward.get(e))});for(let w of S)s.set(w,{kind:`doc`,id:w,docName:w,anchor:getRepresentativeAnchor(t.backward.get(w))}),g.push({source:e,target:w})}for(let[e,S]of t.externalForward){s.set(e,{kind:`doc`,id:e,docName:e,anchor:getRepresentativeAnchor(t.backward.get(e))});for(let[t,w]of S){let S=externalNodeId(t);s.set(S,{kind:`external`,id:S,url:t,label:w.label}),g.push({source:e,target:S})}}for(let S of t.forward.keys())if(parseSkillBundleDocAnyScope(S)?.kind===`skill`)for(let w of this.structuralBundleNeighbors(S,e))t.forward.get(S)?.has(w)||t.forward.get(w)?.has(S)||(s.set(S,{kind:`doc`,id:S,docName:S,anchor:getRepresentativeAnchor(t.backward.get(S))}),s.set(w,{kind:`doc`,id:w,docName:w,anchor:getRepresentativeAnchor(t.backward.get(w))}),g.push({source:S,target:w}));return{nodes:[...s.values()].sort((e,t)=>e.id.localeCompare(t.id)),links:g}}getLinkGraphNeighborhood(e,t,s=this.activeBranch){let g=this.getState(s),S=new Map;for(let e of g.externalForward.values())for(let[t,s]of e)S.has(t)||S.set(t,s.label);let w=new Set([e]),E=[{nodeId:e,degree:0}],D=0;for(;D<E.length;){let e=E[D++];if(e.degree>=t)continue;let S=externalUrlFromNodeId(e.nodeId),O=new Set;if(S)for(let e of g.externalBackward.get(S)?.keys()??[])O.add(e);else{for(let t of g.forward.get(e.nodeId)??new Set)O.add(t);for(let t of g.externalForward.get(e.nodeId)?.keys()??[])O.add(externalNodeId(t));for(let t of g.backward.get(e.nodeId)?.keys()??[])O.add(t);for(let t of this.structuralBundleNeighbors(e.nodeId,s))O.add(t)}for(let t of O)w.has(t)||(w.add(t),E.push({nodeId:t,degree:e.degree+1}))}let O=[];for(let[e,t]of g.forward)if(w.has(e))for(let s of t)w.has(s)&&O.push({source:e,target:s});for(let[e,t]of g.externalForward)if(w.has(e))for(let s of t.keys()){let t=externalNodeId(s);w.has(t)&&O.push({source:e,target:t})}for(let e of w)if(parseSkillBundleDocAnyScope(e)?.kind===`skill`)for(let t of this.structuralBundleNeighbors(e,s))w.has(t)&&(g.forward.get(e)?.has(t)||g.forward.get(t)?.has(e)||O.push({source:e,target:t}));return{nodes:[...w].sort().map(e=>{let t=externalUrlFromNodeId(e);return t?{kind:`external`,id:e,url:t,label:S.get(t)??null}:{kind:`doc`,id:e,docName:e,anchor:getRepresentativeAnchor(g.backward.get(e))}}),links:O}}async saveToDisk(e=this.activeBranch){let t=this.cachePath(e);mkdirSync(dirname(t),{recursive:!0});let s=this.getState(e),g=this.mtimesByBranch.get(e),S={...serializeState(s),...g?{mtimes:Object.fromEntries(g)}:{}};await writeFile(t,JSON.stringify(S,null,2),`utf-8`)}async loadFromDisk(e=this.activeBranch){let t=this.cachePath(e);if(!existsSync(t))return!1;try{let s=await readFile$1(t,`utf-8`),g=JSON.parse(s);return this.states.set(e,deserializeState(g)),g.mtimes?this.mtimesByBranch.set(e,new Map(Object.entries(g.mtimes))):this.mtimesByBranch.delete(e),!0}catch(t){return console.warn(`[backlinks] Failed to load cache for ${e}:`,t),!1}}clear(e=this.activeBranch){this.states.set(e,createEmptyState$1()),this.mtimesByBranch.delete(e)}async rebuildFromDisk(e=this.activeBranch){let t=createEmptyState$1(),s=new Map,g=[];await this.walkForPaths(this.contentDir,g);let S=new Set,w=g.filter(({docName:e})=>S.has(e)?!1:(S.add(e),!0)),E=50;for(let e=0;e<w.length;e+=50){let g=w.slice(e,e+50),S=await Promise.allSettled(g.map(async({docName:e,filePath:t})=>{let[s,g]=await Promise.all([stat$1(t),readFile$1(t,`utf-8`)]);return{docName:e,mtimeMs:s.mtimeMs,markdown:g}}));for(let e of S){if(e.status===`rejected`){console.warn(`[backlinks] Failed to rebuild entry:`,e.reason);continue}let{docName:g,mtimeMs:S,markdown:w}=e.value;s.set(g,S);let{body:E}=stripFrontmatter(w),D=extractWikiLinksFromMarkdown(E,g),O=extractMarkdownLinksFromMarkdown(E,g),k=extractExternalWikiLinksFromMarkdown(E),j=extractExternalMarkdownLinksFromMarkdown(E,g),F=new Set(D.map(e=>e.target)),L=[...D,...O.filter(e=>!F.has(e.target))],B=new Set(k.map(e=>e.url)),H=[...k,...j.filter(e=>!B.has(e.url))],q=new Set,ee=new Map;t.forward.set(g,q),t.externalForward.set(g,ee);for(let e of L){if(!e.target)continue;let s=managedArtifactDocNameFromContentTarget(e.target)??e.target;q.add(s);let S=t.backward.get(s);S||(S=new Map,t.backward.set(s,S)),S.set(g,mergeLinkMeta(S.get(g),{anchor:e.anchor,snippet:e.snippet}))}for(let e of H){if(!e.url)continue;ee.set(e.url,{label:e.label,snippet:e.snippet});let s=t.externalBackward.get(e.url);s||(s=new Map,t.externalBackward.set(e.url,s)),s.set(g,{label:e.label,snippet:e.snippet})}}}this.states.set(e,t),this.mtimesByBranch.set(e,s)}async walkForPaths(e,t){let s;try{s=await readdir(e,{withFileTypes:!0})}catch(t){console.warn(`[backlinks] Failed to read directory ${e}:`,t);return}for(let g of s){let s=join(e,g.name);if(g.isDirectory()){let e=toPosix(relative(this.contentDir,s));if(this.contentFilter&&e&&this.contentFilter.isDirExcluded(e))continue;await this.walkForPaths(s,t)}else if(g.isFile()&&isSupportedDocFile(g.name)){let e=toPosix(relative(this.contentDir,s));if(this.contentFilter?.isExcluded(e))continue;t.push({docName:stripDocExtension(e),filePath:s})}}}async reconcileWithDisk(e=this.activeBranch){if(!existsSync(this.contentDir))return{added:0,updated:0,deleted:0};let t=this.mtimesByBranch.get(e)??new Map,s=[];await this.walkForPaths(this.contentDir,s);let g=new Set,S=s.filter(({docName:e})=>g.has(e)?!1:(g.add(e),!0)),w=new Set(S.map(e=>e.docName)),E=new Map,D=0,O=0,k=[],j=await Promise.allSettled(S.map(async({docName:e,filePath:t})=>({docName:e,filePath:t,mtimeMs:(await stat$1(t)).mtimeMs})));for(let e of j){if(e.status===`rejected`)continue;let{docName:s,filePath:g,mtimeMs:S}=e.value,w=t.get(s);if(w!==void 0&&w===S){E.set(s,S);continue}k.push({docName:s,filePath:g,mtimeMs:S,isNew:w===void 0})}let F=50;for(let t=0;t<k.length;t+=50){let s=k.slice(t,t+50),g=await Promise.allSettled(s.map(async({docName:e,filePath:t,mtimeMs:s,isNew:g})=>({docName:e,mtimeMs:s,isNew:g,markdown:await readFile$1(t,`utf-8`)})));for(let t of g){if(t.status===`rejected`){console.warn(`[backlinks] Failed to reconcile file:`,t.reason);continue}let{docName:s,mtimeMs:g,isNew:S,markdown:w}=t.value;this.updateDocumentFromMarkdown(s,w,e),E.set(s,g),S?D++:O++}}let L=0,B=new Set([...t.keys(),...this.getState(e).forward.keys()]);for(let t of B)parseGlobalSkillBundleDoc(t)||w.has(t)||(this.deleteDocument(t,e),L++);return this.mtimesByBranch.set(e,E),{added:D,updated:O,deleted:L}}async ingestGlobalSkillBundles(e,t=this.activeBranch){let s=new Set;for(let g of e){if(!existsSync(g))continue;let e;try{e=await readdir(g,{withFileTypes:!0})}catch(e){console.warn(`[backlinks] Failed to read global skills root ${g}:`,e);continue}for(let S of e){if(!S.isDirectory())continue;let e=S.name,w=join(g,e),E=skillLiveDocName(`global`,e);existsSync(join(w,`SKILL.md`))&&parseGlobalSkillBundleDoc(E)&&(this.registerNodeOnly(E,t),s.add(E));let D=[];await this.walkGlobalSkillReferences(join(w,`references`),e,``,D);for(let{docName:e}of D)this.registerNodeOnly(e,t),s.add(e)}}let g=[];for(let e of this.getState(t).forward.keys())parseGlobalSkillBundleDoc(e)&&!s.has(e)&&g.push(e);for(let e of g)this.deleteDocument(e,t)}async walkGlobalSkillReferences(e,t,s,g){let S;try{S=await readdir(e,{withFileTypes:!0})}catch(t){t?.code!==`ENOENT`&&console.warn(`[backlinks] Failed to read skill references dir ${e}:`,t);return}for(let w of S){let S=s?`${s}/${w.name}`:w.name;if(w.isDirectory())await this.walkGlobalSkillReferences(join(e,w.name),t,S,g);else if(w.isFile()&&isSupportedDocFile(w.name)){let e=stripDocExtension(S);g.push({docName:`${MANAGED_ARTIFACT_PREFIX_SKILL}global/${t}/references/${e}`})}}}};function extractActorIdentity(e,t){let s=normalizeSummary(e.summary);if(s.kind===`invalid`)return{kind:`invalid-summary`};let g=parseAgentBodyFields(e),S=t?.()??null;return g.rawAgentId!==void 0&&g.writerId!==void 0?{kind:`agent`,writerId:g.writerId,displayName:g.displayName,colorSeed:g.colorSeed??g.rawAgentId,clientName:g.clientName,clientVersion:g.clientVersion,label:g.label,actor:{principalId:S?.id,agentType:resolveAgentType(g.clientName),clientName:g.clientName,clientVersion:g.clientVersion,label:g.label},summary:s}:S?{kind:`principal`,writerId:S.id,displayName:S.display_name,colorSeed:S.id,actor:{principalId:S.id},summary:s}:{kind:`anonymous`,summary:s}}const ANCESTOR_WALK_DEPTH_LIMIT$1=30;function isProjectRoot(e){try{return statSync(resolve(e,OK_PROJECT_MARKER)).isFile()}catch(e){let t=e?.code;if(t===`ENOENT`||t===`ENOTDIR`)return!1;throw e}}function findEnclosingProjectRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT$1;){let e=!1;try{e=isProjectRoot(t)}catch{e=!1}if(e)return{rootPath:t,distance:s};let g=dirname(t);if(g===t)return null;t=g,s+=1}return null}function parsePorcelainPaths(e){let t=[];for(let s of e.split(`
|
|
855
855
|
`)){if(s.length<4)continue;let e=s.slice(3),g=e.indexOf(` -> `),S=g>=0?e.slice(g+4):e;S.length>0&&t.push(S)}return t}function parseDiffPaths(e){return e.split(`
|
|
856
856
|
`).map(e=>e.trim()).filter(e=>e.length>0)}async function dirtyFilesOverlapWith(e,t){let{git:s}=createGitInstance(e),[g,S]=await Promise.all([s.raw([`status`,`--porcelain`]),s.raw([`diff`,`--name-only`,`HEAD..${t}`])]),w=new Set(parsePorcelainPaths(g));if(w.size===0)return{conflicts:!1,files:[]};let E=parseDiffPaths(S);if(E.length===0)return{conflicts:!1,files:[]};let D=new Set;for(let e of E)w.has(e)&&D.add(e);return D.size===0?{conflicts:!1,files:[]}:{conflicts:!0,files:Array.from(D).sort()}}function isValidBranchInfoPath(e,t){if(typeof e!=`string`)return!1;if(e.length===0)return t===`folder`;if(e.startsWith(`/`)||e.includes(`\\`)||/[\x00-\x1F\x7F]/.test(e))return!1;for(let t of e.split(`/`))if(t.length===0||t===`..`||t===`.git`)return!1;return!0}async function computeBranchInfo(e,t,s,g){let{git:S}=createGitInstance(e);await S.raw([`rev-parse`,`--git-dir`]);let w=(async()=>{try{let e=(await S.raw([`symbolic-ref`,`HEAD`])).trim(),t=/^refs\/heads\/(.+)$/.exec(e);return{detached:!1,currentBranch:t?t[1]:null,currentHeadSha:null}}catch{let e=(await S.raw([`rev-parse`,`--short=7`,`HEAD`])).trim();return e.length===0?{detached:!1,currentBranch:null,currentHeadSha:null}:{detached:!0,currentBranch:null,currentHeadSha:e}}})(),E=w.then(async e=>{if(g===`folder`&&s===``)return!0;let t=e.detached?`HEAD`:e.currentBranch;if(!t)return!1;try{return await S.raw([`cat-file`,`-e`,`${t}:${s}`]),!0}catch{return!1}}),D=S.raw([`rev-parse`,`--verify`,`refs/heads/${t}`]).then(()=>!0).catch(()=>!1),O=dirtyFilesOverlapWith(e,t).catch(e=>{if(isBranchResolutionError(e))return{conflicts:!1,files:[]};let s=e instanceof Error?e.message:String(e),g=s.length>500?`${s.slice(0,500)}…`:s;return console.warn(`[git-branch-info] action=dirty-overlap-failed branch=${t} error=${g}`),{conflicts:!1,files:[]}}),[k,j,F,L]=await Promise.all([w,E,D,O]);return k.detached?{detached:!0,currentBranch:null,currentHeadSha:k.currentHeadSha,shareTargetExists:j,dirtyConflicts:L,branchIsLocal:F}:{detached:!1,currentBranch:k.currentBranch,currentHeadSha:null,shareTargetExists:j,dirtyConflicts:L,branchIsLocal:F}}const BRANCH_INFO_HANDLER_TAG=`git-branch-info`;function isBranchResolutionError(e){let t=e instanceof Error?e.message:String(e);return/unknown revision|bad revision|ambiguous argument/i.test(t)}const BRANCH_IN_OTHER_WORKTREE_RE=/'[^']+' is already (?:checked out|used by worktree) at '([^']+)'/;function isBranchInOtherWorktreeError(e){let t=(e instanceof Error?e.message:typeof e==`string`?e:``).match(BRANCH_IN_OTHER_WORKTREE_RE);if(t===null)return{held:!1};let s=t[1];if(s===void 0||s.length===0)return{held:!1};let g;try{g=realpathSync(s)}catch{g=s}return{held:!0,path:g}}const CHECKOUT_HANDLER_TAG=`git-checkout`,isBranchNotFoundFetchError=isBranchNotFoundGitError;async function runCheckoutFlow(e,t){let{git:s}=createGitInstance(e),g=await s.raw([`rev-parse`,`--verify`,`refs/heads/${t}`]).then(()=>!0).catch(()=>!1);if(!g)try{await s.raw([`fetch`,`origin`,t])}catch(e){return{ok:!1,reason:isBranchNotFoundFetchError(e)?`branch-not-found`:`fetch-failed`}}let S=await dirtyFilesOverlapWith(e,g?t:`origin/${t}`);if(S.conflicts)return{ok:!1,reason:`dirty-conflict`,files:S.files};try{return await s.raw([`checkout`,t]),{ok:!0}}catch(e){let s=isBranchInOtherWorktreeError(e);if(s.held)return console.warn(`[git-checkout] reason=branch-in-other-worktree branch=${t} held_at=${s.path}`),{ok:!1,reason:`branch-in-other-worktree`,otherWorktreePath:s.path};let g=e instanceof Error?e.message:String(e),S=g.length>500?`${g.slice(0,500)}…`:g;return console.warn(`[git-checkout] action=checkout-failed branch=${t} error=${S}`),{ok:!1,reason:`checkout-failed`}}}const defaultGitConfigReader=(e,t,s)=>{let g=spawnSync(`git`,[`config`,s===`worktree`?`--worktree`:s===`local`?`--local`:`--global`,t],{cwd:e,encoding:`utf-8`,timeout:5e3});return g.status!==0||!g.stdout?null:g.stdout.trim()||null};function isLinkedWorktree(e){let t=spawnSync(`git`,[`rev-parse`,`--git-dir`],{cwd:e,encoding:`utf-8`,timeout:5e3}),s=spawnSync(`git`,[`rev-parse`,`--git-common-dir`],{cwd:e,encoding:`utf-8`,timeout:5e3});return t.status!==0||s.status!==0?!1:resolve(e,t.stdout.trim())!==resolve(e,s.stdout.trim())}function ensureWorktreeConfigExtension(e){let t=spawnSync(`git`,[`config`,`--local`,`--get`,`extensions.worktreeConfig`],{cwd:e,encoding:`utf-8`,timeout:5e3});if(t.status===0&&/^(true|yes|on|1)$/i.test(t.stdout.trim()))return;let s=spawnSync(`git`,[`config`,`--local`,`extensions.worktreeConfig`,`true`],{cwd:e,encoding:`utf-8`,timeout:5e3});if(s.status!==0){let e=s.stderr?.trim()??``,t=s.error?` [${s.error.message}]`:``;throw Error(`failed to enable extensions.worktreeConfig: ${e}${t}`)}}async function resolveGitIdentity(e,t,s,g=defaultGitConfigReader){let S=g(e,`user.name`,`worktree`),w=g(e,`user.email`,`worktree`);if(S&&w)return{name:S,email:w};let E=g(e,`user.name`,`local`),D=g(e,`user.email`,`local`);if(E&&D)return{name:E,email:D};let O=g(e,`user.name`,`global`),k=g(e,`user.email`,`global`);if(O&&k)return{name:O,email:k};if(t&&s){let e=await t.get(s);if(e){let t=e.name??e.login,s=e.email??`${e.login}@users.noreply.github.com`;if(t)return{name:t,email:s}}}return null}function writeGitIdentity(e,t,s){let g=`--local`;isLinkedWorktree(e)&&(ensureWorktreeConfigExtension(e),g=`--worktree`);let S=(t,s)=>{let S=spawnSync(`git`,[`config`,g,t,s],{cwd:e,encoding:`utf-8`,timeout:5e3});if(S.status!==0){let e=S.stderr?.trim()??``,s=S.error?` [${S.error.message}]`:``;throw Error(`git config ${g} ${t} failed: ${e}${s}`)}};S(`user.name`,t),S(`user.email`,s)}const CONFIG_FILENAME=`config.yml`;function assertNotSymlink(e,t){let s;try{s=lstatSync(e)}catch(e){if(e.code===`ENOENT`)return;throw e}if(s.isSymbolicLink())throw Error(`Refusing to follow symlink at ${t} (${e}). An untrusted upstream may have committed this symlink to redirect writes outside the project. Remove the symlink and re-run.`)}function packageVersionMajorMinor(e){let[t=`0`,s=`0`]=e.split(`.`);return`${t.length>0?t:`0`}.${s.length>0?s:`0`}`}function quoteYamlScalar(e){return/^[A-Za-z0-9._\-/]+$/.test(e)?e:JSON.stringify(e)}function buildConfigYmlContent(e,t){let s=`# yaml-language-server: $schema=https://unpkg.com/@inkeep/open-knowledge@latest/dist/schemas/${CONFIG_SCHEMA_MAJOR_PATH}/config.project.schema.json
|
|
857
857
|
# OpenKnowledge — project configuration
|
|
@@ -1935,11 +1935,11 @@ Change history for this knowledge base, newest entry first. Add a dated entry (\
|
|
|
1935
1935
|
`).filter(Boolean);ce.push(...e)}catch{}if(ce.length===0&&se.length===0&&de.length===0)return EMPTY;let fe=[...se,...de],me=[];if(fe.length>0){let t=parseGitLogOutput(await oe.raw(`log`,`--no-walk`,`--author-date-order`,`--format=${GIT_LOG_FORMAT}`,...fe)).map(e=>({...e,type:`checkpoint`}));if(ne&&(t=await filterEntriesByChain(e,t,O,S,ee,ae,Y)),ue&&se.length>0&&de.length>0){let e=new Set(se),s=t.filter(t=>e.has(t.sha)),g=t.filter(t=>!e.has(t.sha)),S=s.reduce((e,t)=>{let s=new Date(t.timestamp).getTime();return s<e?s:e},1/0);me=[...s,...g.filter(e=>new Date(e.timestamp).getTime()<S)]}else me=t}let ge=[...ce];for(let e of fe)ge.push(e);let _e=[];if(ge.length>0&&(_e=parseGitLogOutput(await oe.raw(`log`,`--full-history`,`--author-date-order`,`--format=${GIT_LOG_FORMAT}`,`-n`,String(D),...ge,...ne?[`--`,ne]:[])),_e.length>=D&&(k=!0),J))for(let t=0;t<O.length-1;t++){let s=O[t];if(s.renameCommit!==null)try{let t=await buildSeeds(e,s.renameCommit,S,Y);if(t.length===0)continue;let g=ee(s.path),w=parseGitLogOutput(await logSeededReachable(e,[`--full-history`,`--author-date-order`,`--format=${GIT_LOG_FORMAT}`,`-n`,String(D)],t,g));w.length>=D&&(k=!0),_e=[..._e,...w]}catch(e){console.warn(`[timeline] predecessor walk failed for step ${t} (${s.path}); skipping:`,e)}}let ve=[...me,..._e],ye=new Set,Ce=[];for(let e of ve)ye.has(e.sha)||(ye.add(e.sha),Ce.push(e));let we=Ce;Ce.length>0&&O.length>0&&(we=filterEntriesByOkActorDocs(Ce,O,await Promise.all(O.map(async t=>{if(t.renameCommit===null)return null;let s=await buildSeeds(e,t.renameCommit,S,Y);return s.length===0?new Set:buildAncestorShaSet(e,s,S,ae)})))),we.sort((e,t)=>new Date(t.timestamp).getTime()-new Date(e.timestamp).getTime());let Te=we;Te=Te.filter(e=>e.type!==`park`),H||(Te=Te.filter(e=>e.checkpoint?.kind!==`auto-consolidation`)),F.length>0&&(Te=Te.filter(e=>F.includes(e.type))),L.length>0&&(Te=Te.filter(e=>matchesAuthor(e,L))),B.length>0&&(Te=Te.filter(e=>!matchesAuthor(e,B)));let De=Te.length,je=Te.slice(E,E+w),Me=je.map(({rawBody:e,...t})=>t);return j(ge.length,Ce.length),{entries:Me,total:De,hasMore:k&&je.length>0||E+w<De}}catch(e){return console.warn(`[timeline] getDocumentHistory failed, returning empty result:`,e),j(0,0,!0),EMPTY}}async function getFolderTimeline(e,t,s=`.`,g){if(!existsSync(e.workTree)||!existsSync(e.gitDir)||t.includes(`..`)||t.includes(`\0`))return EMPTY;let S=g?.branch??`main`,w=Math.max(1,g?.limit??50),E=Math.max(0,g?.offset??0),D=s===`.`?``:s.replace(/^\.\//,``),O=t.replace(/^\.?\/+/,``).replace(/\/+$/,``),k=[D,O,`.ok`].filter(Boolean).join(`/`),j=shadowGit(e);try{let e=[];for(let t of[`refs/wip/${S}/`,`refs/checkpoints/${S}/`])try{let s=(await j.raw(`for-each-ref`,`--format=%(refname)`,t)).trim().split(`
|
|
1936
1936
|
`).filter(Boolean);e.push(...s)}catch{}if(e.length===0)return EMPTY;let t=historyWalkCap(E,w),s=parseGitLogOutput(await j.raw(`log`,`--full-history`,`--author-date-order`,`--format=${GIT_LOG_FORMAT}`,`-n`,String(t),...e,`--`,k)),g=s.length>=t,D=O?`${O}/.ok/`:`.ok/`,F=new Set,L=[];for(let e of s){if(F.has(e.sha)||!isFolderArtifactSubject(e.message)||!e.contributors.some(e=>e.docs.some(e=>e.startsWith(D))))continue;F.add(e.sha);let{rawBody:t,...s}=e;L.push(s)}let B=L.length,H=L.slice(E,E+w);return{entries:H,total:B,hasMore:g&&H.length>0||E+w<B}}catch(e){return console.warn(`[timeline] getFolderTimeline failed, returning empty result:`,e),EMPTY}}let _httpDurationHist=null;function httpDurationHist(){return _httpDurationHist||=getMeter().createHistogram(`http.server.request.duration`,{description:`HTTP server request duration in seconds`,unit:`s`}),_httpDurationHist}let _hintEmittedCounter=null;function hintEmittedCounter(){return _hintEmittedCounter||=getMeter().createCounter(`ok.preview_attach.hint_emitted`,{description:`Count of preview-attach hints emitted on write-tool responses when no editor is attached to __system__. Covers both attach-preview-once (URL exists, no browser) and start-ui (no UI running anywhere) variants — the tool side disambiguates via the warning action; the metric name is retained as-is so existing dashboards keep working.`}),_hintEmittedCounter}let _agentPatchFmTouchCounter=null;function agentPatchFmTouchCounter(){return _agentPatchFmTouchCounter||=getMeter().createCounter(`ok.frontmatter.agent_patch_fm_touch_total`,{description:`Count of agent-patch calls whose find string targets the frontmatter region. Measures incidence during the soft-deprecation window before agent-patch FM-intersecting calls are enforced as 400. Bounded label: result ∈ {rejected, pre_deprecation_passthrough}.`}),_agentPatchFmTouchCounter}function findLooksLikeFrontmatter(e){return!!(/(^|\n)---(\s|\n|$)/.test(e)||/^\s*[\w-]+:\s+\S/.test(e))}let _renameAttributionCounter=null;function renameAttributionCounter(){return _renameAttributionCounter||=getMeter().createCounter(`ok.rename.attribution_kind`,{description:`Count of rename and rollback handler dispatches by attribution kind (agent | principal | anonymous)`}),_renameAttributionCounter}let _agentWriteGateFiredCounter=null;function agentWriteGateFiredCounter(){return _agentWriteGateFiredCounter||=getMeter().createCounter(`ok.agent_write.gate_fired_total`,{description:`Count of agent writes that ran the Site A content-divergence gate (denominator for the divergence rate). Bounded label: handler ∈ {agent-write-md, agent-patch, rollback}.`}),_agentWriteGateFiredCounter}let _agentWriteContentDivergenceCounter=null;function agentWriteContentDivergenceCounter(){return _agentWriteContentDivergenceCounter||=getMeter().createCounter(`ok.agent_write.content_divergence_total`,{description:`Count of agent writes whose converged Y.Text diverged from the composed intent (numerator for the divergence rate). Bounded labels: handler ∈ {agent-write-md, agent-patch, rollback}, divergence_type.`}),_agentWriteContentDivergenceCounter}let _searchCorpusTruncatedCounter=null;function searchCorpusTruncatedCounter(){return _searchCorpusTruncatedCounter||=getMeter().createCounter(`ok.search.corpus_truncated_total`,{description:`Count of search-corpus rebuilds where the name-only file tier hit OK_SEARCH_MAX_ENTRIES and dropped deepest-tail paths. One increment per truncated build; non-truncated builds do not increment.`}),_searchCorpusTruncatedCounter}function recordContentDivergenceGate(e,t){agentWriteGateFiredCounter().add(1,{handler:e}),t!==void 0&&agentWriteContentDivergenceCounter().add(1,{handler:e,divergence_type:t.divergenceType})}function resumeSyncOnAuthEvent(e,t){e.type===`complete`&&t?.()?.notifyCredentialsChanged().catch(()=>{})}const ROLLBACK_ORIGIN={source:`local`,skipStoreHooks:!1,context:{origin:`rollback-apply`,paired:!0}},MANAGED_RENAME_ORIGIN={source:`local`,skipStoreHooks:!1,context:{origin:`managed-rename`,paired:!0}},log$6=getLogger(`api`);function ytextHasConflictMarkers(e){return/^<{7} /m.test(e)&&/^={7}$/m.test(e)&&/^>{7} /m.test(e)}function safeDocPath(e,t){if(!e||e.includes(`..`)||e.includes(`\0`))return{error:`Invalid document name.`};let s=t===`.`?``:t.replace(/^\.\//,``),g=managedArtifactTimelinePaths(e);if(g.managed&&g.versioned)return{path:s?`${s}/${g.filePath}`:g.filePath};let S=getDocExtension(e);return{path:s?`${s}/${e}${S}`:`${e}${S}`}}const GENERIC_PASTE_NAMES=/^(image\.(png|jpe?g|gif|webp)|Clipboard.*|Untitled.*)$/i,SAFE_FILENAME_CHARS=/[^\p{L}\p{N}\p{M}\p{Extended_Pictographic}.\-_ ]/gu,STRIP_ON_SIGHT=/[/\\\x00-\x1f\x7f]/g;function sanitizeFilename(e){let t=e.replace(STRIP_ON_SIGHT,``);if(t=t.replace(SAFE_FILENAME_CHARS,`_`),t=t.replace(/_+/g,`_`).replace(/\.{2,}/g,`.`),t=t.replace(/^[._]+/,``),t=t.replace(/\.+$/,``),t===``)return`upload`;let s=255,g=new TextEncoder;if(g.encode(t).length>255){let e=t.lastIndexOf(`.`),s=e>=0?t.slice(e):``,S=e>=0?t.slice(0,e):t;for(;g.encode(S+s).length>255&&S.length>0;)S=S.slice(0,-1);t=(S||`upload`)+s,g.encode(t).length>255&&(t=`upload`)}return t}function resolveUploadDestDir(e,t,s){let g=t.trim();return g===``||g===`./`?resolve(s,dirname(e)):g===`/`?s:g.startsWith(`./`)?resolve(s,dirname(e),g.slice(2)):resolve(s,g)}function readTempFileHead(e,t){let s=openSync(e,`r`);try{let e=Buffer.alloc(t),g=readSync(s,e,0,t,0);return e.subarray(0,g)}finally{closeSync(s)}}const MAX_DEDUP_SCAN_CANDIDATES=1e3;async function streamingHashFile(e){let t=createHash(`sha256`);return await pipeline(createReadStream(e),t),t.digest(`hex`)}async function findDuplicateAsset(e,t,s){let g;try{g=await readdir(e)}catch{return null}let S=getLogger(`upload`),w=0;for(let E of g){let g=extname(E).slice(1).toLowerCase();if(!ASSET_EXTENSIONS.has(g))continue;let D=resolve(e,E),O;try{O=await stat$1(D)}catch{continue}if(!O.isFile()||O.size!==s)continue;if(w++,w>MAX_DEDUP_SCAN_CANDIDATES)return S.warn({event:`upload-dedup-skip`,reason:`scan-cap-exceeded`,destDir:e,scanned:MAX_DEDUP_SCAN_CANDIDATES,expectedSize:s},`[upload-dedup] candidate scan exceeded ${MAX_DEDUP_SCAN_CANDIDATES} same-size siblings — degrading to no-dedup for this upload`),null;let k;try{k=await streamingHashFile(D)}catch(e){let t=e.code;t!==`ENOENT`&&S.warn({event:`upload-dedup-skip`,reason:`read-failed`,code:t,entry:E},`[upload-dedup] skipped candidate — read failed`);continue}if(k===t)return E}return null}function readUploadBody(e,t){return new Promise((s,g)=>{let S;try{S=(0,import_lib.default)({headers:e.headers,limits:{files:1,fields:10,fieldSize:2*1024}})}catch(e){g(new UploadWriteError(`urn:ok:error:malformed-upload`,e));return}let w=!1,E=`upload`,D=``,O=``,k,j,F=!1,L=(e,t)=>{if(!w){if(w=!0,k)try{unlinkSync(k)}catch{}g(t instanceof UploadWriteError?t:new UploadWriteError(e,t))}},B=classifyUploadErrno;S.on(`field`,(e,t)=>{e===`parentDocName`&&(O=t)}),S.on(`file`,(e,g,S)=>{F=!0,E=S.filename||`upload`,D=S.mimeType||``;let H;try{H=mintTempUploadPath(t)}catch(e){L(B(e),e),g.resume();return}k=H;let q=new HashingPassThrough;pipeline(g,q,createWriteStream(H)).then(()=>{w||(w=!0,s({filename:E,mimeType:D,parentDocName:O,tempPath:H,sha:q.digest(),byteLength:q.byteLength()}))}).catch(e=>{j=e,L(B(e),e)})}),S.on(`error`,e=>{L(`urn:ok:error:malformed-upload`,e)}),S.on(`close`,()=>{w||j||F||(w=!0,s({filename:``,mimeType:``,parentDocName:O,tempPath:``,sha:``,byteLength:0}))}),e.on(`close`,()=>{w||j||e.complete||L(`urn:ok:error:malformed-upload`,Error(`client disconnected`))}),e.pipe(S)})}function safeSubdir(e,t){let s=resolve(e,t);if(!isWithinDir(s,e))throw Error(`Invalid directory: ${t}`);return s}function synthesizeShowAllAssetExt(e){let t=extname(e);return t?t.slice(1).toLowerCase():e.startsWith(`.`)&&e.length>1?e.slice(1).toLowerCase():`file`}const DEFAULT_SHOWALL_MAX_ENTRIES=5e4;function getShowAllMaxEntries(){let e=process.env.OK_SHOWALL_MAX_ENTRIES;if(e===void 0)return DEFAULT_SHOWALL_MAX_ENTRIES;let t=Number(e);return Number.isInteger(t)&&t>0?t:DEFAULT_SHOWALL_MAX_ENTRIES}const DEFAULT_SEARCH_MAX_ENTRIES=5e4;function getSearchMaxEntries(){let e=process.env.OK_SEARCH_MAX_ENTRIES;if(e===void 0)return DEFAULT_SEARCH_MAX_ENTRIES;let t=Number(e);return Number.isInteger(t)&&t>0?t:DEFAULT_SEARCH_MAX_ENTRIES}let showAllWalkInvocations=0,showAllWalkAborts=0;function __getShowAllWalkStatsForTesting(){return{invocations:showAllWalkInvocations,aborts:showAllWalkAborts}}function __resetShowAllWalkStatsForTesting(){showAllWalkInvocations=0,showAllWalkAborts=0}function showAllWantsNdjson(e){let t=e.headers.accept;return typeof t==`string`&&t.includes(`application/x-ndjson`)}async function*streamShowAllEntries(e){let{contentDir:t,contentFilter:s,dirFilter:g,getDocExtension:S,maxEntries:w,signal:E}=e,D=e.maxDepth??1/0;showAllWalkInvocations+=1;let O=0,k=!1,j=!1,F=e=>g?e===g||e.startsWith(`${g}/`):!0,L;try{L=await realpath(t)}catch{L=t}let B=e=>isWithinDir(e,L);async function H(e,t){let g;try{g=await readdir(e,{withFileTypes:!0})}catch(t){return console.warn(`[document-list][showAll] probe readdir failed for ${e}:`,t),!1}for(let S of g){let g=t?`${t}/${S.name}`:S.name;if(S.isDirectory()){if(s.isDirExcluded(g,{bypassFilters:!0}))continue;try{if(!B(await realpath(join(e,S.name))))continue}catch(t){console.warn(`[document-list][showAll] probe realpath failed for ${e}/${S.name}:`,t);continue}return!0}if(S.isFile()&&!s.isExcluded(g,{bypassFilters:!0}))return!0}return!1}async function*q(e,g,L){let q=[{absDir:e,relDir:g,depth:L}];for(let e=0;e<q.length;e++){if(E?.aborted){j=!0;return}let{absDir:g,relDir:L,depth:ee}=q[e],J;try{J=await readdir(g,{withFileTypes:!0})}catch(e){console.warn(`[document-list][showAll] readdir failed for ${g}:`,e);continue}for(let e of J){if(E?.aborted){j=!0;return}if(O>=w){k=!0;return}let J=L?`${L}/${e.name}`:e.name;if(e.isDirectory()){if(s.isDirExcluded(J,{bypassFilters:!0}))continue;let t=join(g,e.name),S;try{S=await realpath(t)}catch(e){console.warn(`[document-list][showAll] realpath failed for ${t}:`,e);continue}if(!B(S)){console.warn(`[document-list][showAll] refusing symlink-escape ${t} -> ${S}`);continue}if(F(J)){let e=null;try{e=await stat$1(t)}catch(e){console.warn(`[document-list][showAll] stat failed for ${t}:`,e)}O+=1;let s=ee>=D?await H(t,J):void 0;yield{kind:`folder`,path:J,size:0,modified:e?e.mtime.toISOString():``,docExt:`.md`,isSymlink:!1,canonicalDocName:null,targetPath:null,...s===void 0?{}:{hasChildren:s}}}ee<D&&q.push({absDir:t,relDir:J,depth:ee+1});continue}if(e.isSymbolicLink()){let w=join(g,e.name),E;try{E=await realpath(w)}catch(e){console.warn(`[document-list][showAll] symlink realpath failed for ${w}:`,e);continue}if(!B(E)){console.warn(`[document-list][showAll] refusing symlink-escape ${w} -> ${E}`);continue}let D;try{D=await stat$1(E)}catch(e){console.warn(`[document-list][showAll] symlink target stat failed for ${w}:`,e);continue}let k=toPosix(relative(t,E));if(D.isDirectory()){if(s.isDirExcluded(J,{bypassFilters:!0})||!F(J))continue;O+=1,yield{kind:`folder`,path:J,size:0,modified:D.mtime.toISOString(),docExt:`.md`,isSymlink:!0,canonicalDocName:k,targetPath:k,hasChildren:await H(E,J)};continue}if(!D.isFile()||s.isExcluded(J,{bypassFilters:!0})||!F(J))continue;if(O+=1,isSupportedDocFile(e.name)){let e=J.replace(/\.(md|mdx)$/i,``);yield{kind:`document`,docName:e,docExt:S(e),size:D.size,modified:D.mtime.toISOString(),isSymlink:!0,canonicalDocName:k.replace(/\.(md|mdx)$/i,``),targetPath:k}}else{let t=synthesizeShowAllAssetExt(e.name);yield{kind:`asset`,docName:J,docExt:t,path:J,assetExt:t,mediaKind:mediaKindForSidebarAssetExtension(t),referencedBy:[],size:D.size,modified:D.mtime.toISOString(),isSymlink:!0,canonicalDocName:null,targetPath:k}}continue}if(!e.isFile()||s.isExcluded(J,{bypassFilters:!0})||!F(J))continue;let Y=null;try{Y=await stat$1(join(g,e.name))}catch(t){console.warn(`[document-list][showAll] stat failed for ${g}/${e.name}:`,t);continue}if(isSupportedDocFile(e.name)){let e=J.replace(/\.(md|mdx)$/i,``),t=S(e);O+=1,yield{kind:`document`,docName:e,docExt:t,size:Y.size,modified:Y.mtime.toISOString(),isSymlink:!1,canonicalDocName:null,targetPath:null};continue}let te=synthesizeShowAllAssetExt(e.name),ne=mediaKindForSidebarAssetExtension(te);O+=1,yield{kind:`asset`,docName:J,docExt:te,path:J,assetExt:te,mediaKind:ne,referencedBy:[],size:Y.size,modified:Y.mtime.toISOString(),isSymlink:!1,canonicalDocName:null,targetPath:null}}}}return yield*q(g?join(t,g):t,g??``,1),j&&(showAllWalkAborts+=1),{truncated:k}}async function walkContentDirForShowAll(e){let{documents:t,...s}=e,g=streamShowAllEntries(s),S=await g.next();for(;!S.done;)t.push(S.value),S=await g.next();return S.value}function isValidRelativeContentPath(e){return!e||e.startsWith(`/`)||e.includes(`\\`)||e.includes(`\0`)?!1:e.split(`/`).every(e=>e&&e!==`.`&&e!==`..`)}function isReservedProjectStatePath(e){return e===`.ok`||e.startsWith(`.ok/`)||e===`.git`||e.startsWith(`.git/`)}function isReservedSyntheticFolderPath(e){return e===`__system__`||e===`__config__`||e===`__user__`||e===`__local__`||e.startsWith(`__system__/`)||e.startsWith(`__config__/`)||e.startsWith(`__user__/`)||e.startsWith(`__local__/`)}function listAffectedDocNames(e,t,s){let g=[...e.keys()].filter(e=>t===`file`?e===s:e===s||e.startsWith(`${s}/`));return g.sort((e,t)=>e.localeCompare(t)),g}function remapDocNameForRename(e,t,s,g){return t===`file`||e===s?g:`${g}${e.slice(s.length)}`}function requireNonEmptyDocName(e,t,s){return e!==void 0&&e.length>0?e:(errorResponse(t,400,`urn:ok:error:invalid-request`,"`docName` must be a non-empty document name.",{handler:s}),null)}function assertNoSymlinkEscape(e,t){let s;try{s=realpathSync(t)}catch(e){throw e.code===`ENOENT`?new SymlinkEscapeError(`content directory does not exist`):e}let g=e;for(;;)try{if(!isWithinContentDir(realpathSync(g),s))throw new SymlinkEscapeError(`path resolves outside content directory`);return}catch(e){let s=e.code;if(s===`ELOOP`)throw new SymlinkEscapeError(`symlink cycle in path`);if(s!==`ENOENT`)throw e;let S=dirname(g);if(S===g||S!==t&&!S.startsWith(`${t}${sep}`))throw e;g=S}}function resolveContentEntryPath(e,t,s){if(!isValidRelativeContentPath(s))throw Error(`path must be a relative content path`);let g=resolve(e),S=resolve(g,t===`file`?isSupportedDocFile(s)?s:`${s}${getDocExtension(s)}`:s);if(S!==g&&!S.startsWith(`${g}${sep}`))throw Error(`path must not escape content directory`);return assertNoSymlinkEscape(S,g),S}function splitContentPath(e){let t=e.lastIndexOf(`/`);return t===-1?{parent:``,basename:e}:{parent:e.slice(0,t),basename:e.slice(t+1)}}function joinContentPath(e,t){return e?`${e}/${t}`:t}function duplicateBasename(e,t){return t===1?`${e} copy`:`${e} copy ${t}`}var DuplicateNameExhaustedError=class extends Error{constructor(e){super(`Could not find an available duplicate name for ${e}`),this.sourcePath=e,this.name=`DuplicateNameExhaustedError`}};function isAlreadyExistsError(e){let t=e.code;return t===`EEXIST`||t===`ERR_FS_CP_EEXIST`}function classifyDuplicatePathFilesystemProblem(e){let t=e.code;return t===`ENOSPC`||t===`EDQUOT`?{status:507,type:`urn:ok:error:storage-full`,title:`Could not duplicate path because storage is full.`}:t===`EPERM`||t===`EACCES`||t===`EROFS`?{status:500,type:`urn:ok:error:storage-readonly`,title:`Could not duplicate path because storage is not writable.`}:null}function docNameExistsWithAnySupportedExtension(e,t){return SUPPORTED_DOC_EXTENSIONS.some(s=>existsSync(resolve(e,`${t}${s}`)))}function resolveDuplicateDocPath(e,t,s){if(!isValidRelativeContentPath(t))throw Error(`path must be a relative content path`);let g=resolve(e),S=resolve(g,`${t}${s}`);if(S!==g&&!S.startsWith(`${g}${sep}`))throw Error(`path must not escape content directory`);return assertNoSymlinkEscape(S,g),S}function nextAvailableDuplicateDocName(e,t){let{parent:s,basename:g}=splitContentPath(t);for(let t=1;t<=1e4;t+=1){let S=joinContentPath(s,duplicateBasename(g,t));if(!docNameExistsWithAnySupportedExtension(e,S))return{docName:S,attempt:t}}throw new DuplicateNameExhaustedError(t)}function nextAvailableDuplicateFolderPath(e,t){let{parent:s,basename:g}=splitContentPath(t);for(let t=1;t<=1e4;t+=1){let S=joinContentPath(s,duplicateBasename(g,t));if(!existsSync(resolveContentEntryPath(e,`folder`,S)))return{folderPath:S,attempt:t}}throw new DuplicateNameExhaustedError(t)}function collectMarkdownCopies(e,t){let s=resolveContentEntryPath(e,`folder`,t),g=[];function S(e,t){for(let s of readdirSync(e,{withFileTypes:!0})){let w=resolve(e,s.name),E=t?`${t}/${s.name}`:s.name;if(s.isDirectory()){S(w,E);continue}!s.isFile()||!isSupportedDocFile(E)||g.push({docName:stripDocExtension(E),fullPath:w,content:readFileSync(w,`utf-8`)})}}return S(s,t),g.sort((e,t)=>e.docName.localeCompare(t.docName)),g}function collectFolderPaths(e,t){let s=resolveContentEntryPath(e,`folder`,t),g=[t];function S(e,t){for(let s of readdirSync(e,{withFileTypes:!0})){if(!s.isDirectory())continue;let w=resolve(e,s.name),E=t?`${t}/${s.name}`:s.name;g.push(E),S(w,E)}}return S(s,t),g.sort((e,t)=>e.localeCompare(t)),g}function probeAndRegisterSourceFileExtension(e,t){if(!isValidRelativeContentPath(t))return;let s=resolve(e);if(isSupportedDocFile(t)){let e=resolve(s,t);e!==s&&e.startsWith(`${s}${sep}`)&&existsSync(e)&®isterDocExtension(stripDocExtension(t),extname(t));return}for(let e of SUPPORTED_DOC_EXTENSIONS){let g=resolve(s,`${t}${e}`);if(!(g!==s&&!g.startsWith(`${s}${sep}`))&&existsSync(g)){registerDocExtension(t,e);return}}}function toGitRelativePath(e,t){let s=resolve(e),g=resolve(t);return g!==s&&!g.startsWith(`${s}${sep}`)?null:relative(s,g).split(sep).join(`/`)}function stringsDifferOnlyByCase(e,t){return e!==t&&e.toLowerCase()===t.toLowerCase()}function pathsDifferOnlyByCase(e,t){return stringsDifferOnlyByCase(resolve(e),resolve(t))}function isCaseOnlySelfCollision(e,t){if(!pathsDifferOnlyByCase(e,t)||!existsSync(e)||!existsSync(t))return!1;try{let s=statSync(e),g=statSync(t);return s.dev===g.dev&&s.ino===g.ino}catch{return!1}}function createCaseOnlyRenameTempPath(e){let t=dirname(e);for(let e=0;e<10;e+=1){let e=resolve(t,`.ok-case-rename-${randomUUID$1()}`);if(!existsSync(e))return e}throw Error(`Unable to allocate temporary path for case-only rename`)}function writeFileIfContentDiffers(e,t){(existsSync(e)?readFileSync(e,`utf-8`):null)!==t&&tracedWriteFileSync(e,t,`utf-8`)}function renamePathOnDisk(e,t){if(tracedMkdirSync(dirname(t),{recursive:!0}),!pathsDifferOnlyByCase(e,t)){tracedRenameSync(e,t);return}let s=createCaseOnlyRenameTempPath(e);tracedRenameSync(e,s);try{tracedRenameSync(s,t)}catch(t){try{let t=existsSync(s),g=existsSync(e);t&&!g?tracedRenameSync(s,e):console.warn(`[renamePathOnDisk] skipped case-only rollback due to unexpected state:`,{tempExists:t,sourceExists:g})}catch(e){console.warn(`[renamePathOnDisk] failed to roll back temporary case-only rename:`,e)}throw t}}async function renameTrackedPathInGit(e,t,s){if(!e)return!1;let g=toGitRelativePath(e,t),S=toGitRelativePath(e,s);return!g||!S?!1:await withParentLock(async()=>{let w=esm_default({baseDir:e,timeout:{block:15e3}}),E=``;try{E=(await w.raw(`ls-files`,`--`,g)).trim()}catch(e){return console.warn(`[renameTrackedPathInGit] git ls-files failed, falling back to fs rename:`,e),!1}if(!E)return!1;mkdirSync(dirname(s),{recursive:!0});let D=!1;try{if(pathsDifferOnlyByCase(t,s)){let s=toGitRelativePath(e,createCaseOnlyRenameTempPath(t));if(!s)return!1;await w.raw(`mv`,`--`,g,s);try{await w.raw(`mv`,`--`,s,S)}catch(e){try{await w.raw(`mv`,`--`,s,g)}catch(e){console.warn(`[renameTrackedPathInGit] case-only git rename failed and rollback also failed; git index and disk may have diverged:`,e),D=!0}throw e}}else await w.raw(`mv`,`--`,g,S);return!0}catch(e){if(D)throw e;return console.warn(`[renameTrackedPathInGit] git mv failed, falling back to fs rename:`,e),!1}})}const workspaceSearchCaches=new Map;function extractHeadings(e){let{body:t}=stripFrontmatter(e),s=[],g=new Map,S=createCodeFenceTracker();for(let e of t.split(`
|
|
1937
1937
|
`)){if(S(e))continue;let t=e.match(/^(#{1,6})\s+(.+)$/);if(t){let e=t[2].trim(),S=getHeadingSlug(e,g);S&&s.push({level:t[1].length,text:e,slug:S})}}return s}function isSafeDocName(e){return!(e.includes(`..`)||e.startsWith(`/`)||e.includes(`\0`)||e.includes(`\\`))}function applyDiskEventToLiveAllFilesIndex(e,t){let s=t();s instanceof Map&&updateFileIndex(e,s)}function createApiExtension(e){let{hocuspocus:t,sessionManager:s,contentDir:g,serverInstanceId:S,getFileIndex:w,getAllFilesIndex:E=w,mutateFileIndex:D=e=>applyDiskEventToLiveAllFilesIndex(e,E),getFileIndexGeneration:O,getFolderIndex:k,onReferencedAssetsCacheInvalidator:j,getAliasMap:F,getFolderAliasIndex:L,rescanFiles:B,enableTestRoutes:H=!1,shadowRef:q,flushGitCommit:ee,flushContributors:J,takeStoreFailure:Y,takeStoreDivergence:te,markAgentWriteStore:ne,getCurrentBranch:ae,getDiskAckSVs:oe,contentRoot:se,backlinkIndex:ce,tagIndex:ue,signalChannel:de,agentFocusBroadcaster:fe,agentPresenceBroadcaster:me,onAgentWrite:ge,getSyncEngine:_e,localOpCliArgs:ve=[`open-knowledge`],projectDir:ye,getPrincipal:Ce,homeDirOverride:we,contentFilter:Te,installedAgentsProbe:De,forceUnloadDocument:je,ready:Me,recentlyRemovedDocs:Pe,serializeDoc:Ie,evictManagedArtifactLkg:Re,semanticSearch:ze,getSemanticSimilarityFloor:Be,embeddingsSecretsFile:Ve,ephemeral:Ue=!1}=e,We=createConcurrencyGuard(),Ge=new Map,Ke=createSingleFlight(),Xe=null;function $e(){let e=k?.();return e instanceof Map?e:null}function nt(e){let t=$e();if(t)try{upsertFolderIndexEntry(t,g,e,statSync(e),e)}catch(t){console.warn(`[api-extension] folder index stat failed for ${e}:`,t)}}function rt(e){let t=e.split(`/`).filter(Boolean);for(let e=1;e<=t.length;e+=1)nt(resolve(g,t.slice(0,e).join(`/`)))}function it(e){let t=$e();t&&removeFolderIndexEntries(t,e)}function at(e,t){let s=$e();if(!s)return;let S=[];for(let[g,w]of s.entries()){if(g!==e&&!g.startsWith(`${e}/`))continue;s.delete(g);let E=g.slice(e.length);S.push([`${t}${E}`,w])}if(S.length===0){let e=resolveContentEntryPath(g,`folder`,t);existsSync(e)&&nt(e);return}for(let[e,t]of S)s.set(e,{...t,modified:new Date().toISOString(),canonicalPath:resolve(g,e)})}function st(e){return[...e.entries()].map(([e,t])=>`${e}\0${t.canonicalPath}\0${t.size}\0${t.modified}\0${t.aliases.join(`\0`)}`).sort().join(`
|
|
1938
|
-
`)}function vt(){Xe=null}j?.(vt);let Tt=createInstalledAgentsProbe({probe:De??createOsProbe(process.platform)});function Et(e){if(isManagedArtifactDocName(e))try{return managedArtifactAbsPath(e,{projectDir:ye??g,homedirOverride:we})}catch{return null}if(!isSafeDocName(e))return null;let t=resolve(g),s=resolve(t,`${e}${getDocExtension(e)}`);return isWithinDir(s,t)?s:null}function Dt(e){let t=Et(e);if(!t||!existsSync(t))return e;try{return extractPageTitle(readFileSync(t,`utf-8`),e)}catch{return e}}function jt(e,t){return t.has(e)?Dt(e):e}let Mt={cluster:void 0,category:void 0,tags:void 0};function Ft(e){try{let s=t.documents.get(e);if(s){let e=readFmMap(s.getText(`source`).toString());if(Object.keys(e).length>0){let t=typeof e.cluster==`string`?e.cluster:void 0,s=typeof e.category==`string`?e.category:void 0,g;if(Array.isArray(e.tags)){let t=e.tags.filter(e=>typeof e==`string`);g=t.length>0?t:void 0}else typeof e.tags==`string`&&e.tags&&(g=[e.tags]);return{cluster:t,category:s,tags:g}}}}catch{}try{let t=Et(e);if(!t||!existsSync(t))return Mt;let{frontmatter:s}=stripFrontmatter(readFileSync(t,`utf-8`));return s?parseFrontmatterMetadata(s):Mt}catch{return Mt}}function It(e,t){return t.has(e)?Ft(e):Mt}function Lt(e){if(ce)try{if(ce.getBacklinks(e).length>0)return;let t=performance.now(),s=findHubCandidates(e,w()),g=performance.now()-t;return g>5&&log$6.debug({docName:e,elapsedMs:g,candidateCount:s.length},`[orphan-hint] findHubCandidates slow`),s.length===0?void 0:[{type:`orphan`,parentCandidates:s,message:`This doc has no backlinks yet. To make it discoverable, consider linking from a parent hub doc (index/overview files in the folder tree): ${s.map(e=>`[[${e}]]`).join(`, `)}.`}]}catch(e){console.warn(`[orphan-hint] computeOrphanHints failed:`,e);return}}function Rt(e){return F?.().get(e)??e}function zt(e){try{return t.documents.get(e)?.connections.size??0}catch{return 0}}function Bt(){try{return t.documents.get(`__system__`)?.connections.size??0}catch{return 0}}function Vt(e,s){let g=`onStoreDocument-${e}`;(t.debouncer.isDebounced(g)?t.debouncer.executeNow(g):Promise.resolve()).then(()=>ee?.()).catch(e=>{log$6.warn({err:e},`[${s}] post-write flush failed`)})}async function Ht(e){let s=`onStoreDocument-${e}`;t.debouncer.isDebounced(s)&&(ne?.(e),await t.debouncer.executeNow(s));let g=Y?.(e)??null;return g?{kind:`failure`,failure:g}:te?.(e)?{kind:`divergence`}:null}function Ut(e,t,s){let g=classifyUploadErrno({code:t.code});errorResponse(e,uploadStatusFor(g),g,`Write applied in memory but failed to persist to disk (${t.code??`unknown error`}): ${t.message}. The content was NOT saved and will be lost if the server restarts.`,{handler:s})}function Wt(e,t){errorResponse(e,409,`urn:ok:error:disk-divergence`,`The document changed on disk after your edit was prepared; your edit was NOT applied, to avoid overwriting the newer on-disk content. Re-read the document and retry.`,{handler:t})}function Kt(e){if(e.reconciled)return{kind:`disk-edit-reconciled`,intendedBytes:e.baseBytes,actualBytes:e.diskBytes,byteDelta:e.diskBytes-e.baseBytes,...e.mergeOutcome?{mergeOutcome:e.mergeOutcome}:{},hint:e.mergeOutcome===`merged`?'An out-of-band edit was three-way merged into this document before your edit was applied on top; the merge may have interleaved content blocks. Re-read it (e.g. `exec("cat <path>")`) and review the combined result carefully before continuing.':'An out-of-band edit was reconciled into this document before your edit was applied on top; the document now reflects that edit plus yours. Re-read it (e.g. `exec("cat <path>")`) to see the combined result before continuing.'}}function $t(){let e=new Set;for(let[t,s]of w()){e.add(t);for(let t of s.aliases)e.add(t)}try{for(let t of[`project`,`global`]){let s=resolve(t===`global`?$l:g,`.ok`,`skills`);for(let g of ou(s,t).skills)e.add(`${MANAGED_ARTIFACT_PREFIX_SKILL}${t}/${g.name}`)}for(let t of resolveProjectTemplates(resolve(g)).templates)e.add(tu(t.source_folder,t.name))}catch(e){log$6.warn({err:e},`[collectAdmittedDocNames] managed-artifact enumeration failed`)}return e}let en=e=>existsSync(resolve(g,e));function jr(){let e=Promise.resolve();return async function(t){let s=e,g=()=>{};e=new Promise(e=>{g=e}),await s;try{return await t()}finally{g()}}}let Mr=jr(),Fr=e=>e.endsWith(`.`)?e:`${e}.`;function Ir(e){return e instanceof Error?e instanceof ManagedRenameSourceNotFoundError?{status:404,type:`urn:ok:error:doc-not-found`,error:Fr(e.message)}:e instanceof ManagedRenameDestinationExistsError?{status:409,type:`urn:ok:error:doc-already-exists`,error:Fr(e.message)}:e instanceof ManagedRenameSourceTypeMismatchError||e instanceof ManagedRenameInvalidRequestError?{status:400,type:`urn:ok:error:invalid-request`,error:Fr(e.message)}:e instanceof ManagedRenameReservedPathError?{status:400,type:`urn:ok:error:reserved-doc-name`,error:Fr(e.message)}:e instanceof ManagedRenameMissingDocumentError||e instanceof ManagedRenameSnapshotMissingError?{status:404,type:`urn:ok:error:doc-not-found`,error:Fr(e.message)}:e instanceof SymlinkEscapeError?{status:400,type:`urn:ok:error:path-escape`,error:Fr(e.message)}:e instanceof BacklinkIndexRequiredError?{status:503,type:`urn:ok:error:backlink-index-not-configured`,error:Fr(e.message)}:{status:500,type:`urn:ok:error:internal-server-error`,error:`Failed to rename document.`}:{status:500,type:`urn:ok:error:internal-server-error`,error:`Failed to rename document.`}}async function Lr(e){let g=new Map;for(let s of e){let e=t.documents.get(s);e&&g.set(s,e.getText(`source`).toString())}for(let t of e)await s.closeAllForDoc(t).catch(e=>{console.warn(`[file-ops] Failed to close agent session for ${t}:`,e)});for(let s of e){let e=t.documents.get(s);deleteReconciledBase(s),Re?.(s),e&&(t.closeConnections(s),await(je??t.unloadDocument.bind(t))(e))}return g}function zr(e,t){for(let{fromDocName:s,toDocName:S}of e){let e=safeContentPath(S,g),w=t.get(s);typeof w==`string`&&writeFileIfContentDiffers(e,w);let E=typeof w==`string`?w:existsSync(e)?readFileSync(e,`utf-8`):null;typeof E==`string`&®isterWrite(e,contentHash(E))}}function Br(e,t){return e.map(e=>{let s=t.get(e);if(typeof s==`string`)return{docName:e,content:s};let S=safeContentPath(e,g);if(!existsSync(S))throw new ManagedRenameSnapshotMissingError(e);return{docName:e,content:readFileSync(S,`utf-8`)}})}function Vr(e){let s=t.documents.get(e);if(s)return s.getText(`source`).toString();let S=resolveContentEntryPath(g,`file`,e);return existsSync(S)?readFileSync(S,`utf-8`):null}function Hr(e,t){let s=resolveContentEntryPath(g,`file`,e);tracedMkdirSync(dirname(s),{recursive:!0}),writeFileIfContentDiffers(s,t),registerWrite(s,contentHash(t)),setReconciledBase(e,t),D?.({kind:`update`,path:s,docName:e,content:t})}function Ur(e,s,g=[]){let S=t.documents.get(e);if(!S)throw Error(`Document is not loaded: ${e}`);let w={markdown:``,rewrites:0};return S.transact(()=>{w=Gr(S.getText(`source`).toString(),e,s.get(e)??e,s,g),w.rewrites!==0&&composeAndWriteRawBody(S,w.markdown,`managed-rename`,!1)},MANAGED_RENAME_ORIGIN),w}function Wr(e,t,s){let g=e,S=0;for(let{fromPath:e,toPath:w}of s){let s=rewriteAssetReferencesForRename(g,t,e,w);g=s.markdown,S+=s.rewrites}return{markdown:g,rewrites:S}}function Gr(e,t,s,g,S){let w=applyRenameMap(e,t,g),E=Wr(w.markdown,s,S);return{markdown:E.markdown,rewrites:E.markdown===e?0:w.rewrites+E.rewrites}}function Kr(e,s){let g=t.documents.get(e);if(!g)throw Error(`Document is not loaded: ${e}`);let S={markdown:``,rewrites:0};return g.transact(()=>{S=Wr(g.getText(`source`).toString(),e,s),S.rewrites!==0&&composeAndWriteRawBody(g,S.markdown,`managed-rename`,!1)},MANAGED_RENAME_ORIGIN),S}function qr(e){let t=[];if(e.length===0)return t;let s=[...w().keys()].sort((e,t)=>e.localeCompare(t));for(let g of s){let s=Vr(g);if(typeof s!=`string`)continue;let S=Wr(s,g,e);S.rewrites!==0&&t.push({docName:g,markdown:S.markdown,rewrites:S.rewrites})}return t}function Jr(e){let s=_e?.(),g=new Set(s?s.getConflicts().map(e=>e.file):[]);for(let s of e){let e=t.documents.get(s),S=`${s}${getDocExtension(s)}`,w=e!==void 0&&isDocInConflict(e),E=g.has(S);if(w||E)throw new DocInConflictError({file:S})}}function Yr(e,s){let g=[];for(let S of e){let e=t.documents.get(S.docName)?Kr(S.docName,s):S;e.rewrites!==0&&(Hr(S.docName,e.markdown),ce?.updateDocumentFromMarkdown(S.docName,e.markdown),g.push({docName:S.docName,rewrites:e.rewrites}))}return g}function Xr(e){if(extname(e))return{path:e,ambiguous:!1};let t=e.lastIndexOf(`/`),s=t===-1?``:e.slice(0,t),S=t===-1?e:e.slice(t+1),w=s?resolveContentEntryPath(g,`folder`,s):g,E;try{E=readdirSync(w,{withFileTypes:!0})}catch(t){let s=t.code;if(s===`ENOENT`||s===`ENOTDIR`)return{path:e,ambiguous:!1};throw t}let D=E.filter(e=>e.isFile()&&e.name.startsWith(`${S}.`)).map(e=>s?`${s}/${e.name}`:e.name).filter(e=>isSupportedAssetFile(e,LINKABLE_ASSET_EXTENSIONS));return D.length===1?{path:D[0],ambiguous:!1}:{path:e,ambiguous:D.length>1}}function Zr(e){let t=[];try{if(!statSync(e).isDirectory())return t}catch(e){let s=e.code;if(s===`ENOENT`||s===`ENOTDIR`)return t;throw e}function s(e){for(let S of readdirSync(e,{withFileTypes:!0})){let w=resolve(e,S.name),E=relative(g,w).split(sep).join(`/`);if(isReservedProjectStatePath(E))continue;if(S.isDirectory()){if(Te?.isDirExcluded(E))continue;s(w);continue}if(!S.isFile()||!isSupportedDocFile(E)||Te?.isExcluded(E))continue;let D=stripDocExtension(E);registerDocExtension(D,extname(E)),t.push(D)}}return s(e),t.sort((e,t)=>e.localeCompare(t)),t}function Qr(e,t,s){let S=[];function w(e){for(let E of readdirSync(e,{withFileTypes:!0})){let D=resolve(e,E.name),O=relative(g,D).split(sep).join(`/`);if(!isReservedProjectStatePath(O)){if(E.isDirectory()){if(Te?.isDirExcluded(O))continue;w(D);continue}!E.isFile()||isSupportedDocFile(O)||Te?.isExcluded(O)||(O===t?S.push({fromPath:O,toPath:s}):O.startsWith(`${t}/`)&&S.push({fromPath:O,toPath:`${s}${O.slice(t.length)}`}))}}}return w(e),S.sort((e,t)=>e.fromPath.localeCompare(t.fromPath)),S}async function ji(e,t){return Mr(async()=>withSpan(`rename.executeAssetRewrites`,{attributes:{"rename.kind":`asset`}},async s=>{if(!ce)throw new BacklinkIndexRequiredError;let S=extname(t)?t:`${t}${extname(e)}`;if(isReservedProjectStatePath(e)||isReservedProjectStatePath(S))throw new ManagedRenameReservedPathError(`.ok and .git are reserved directories.`);if(Te?.isPathIgnored(S))throw new ManagedRenameInvalidRequestError(`Destination asset is excluded by the project content config.`);let w=resolveContentEntryPath(g,`folder`,e),E=resolveContentEntryPath(g,`folder`,S);if(w===E)return{renamedAssets:[],rewrittenDocs:[]};if(stringsDifferOnlyByCase(e,S))throw new ManagedRenameInvalidRequestError(`Case-only renames are not supported.`);if(!existsSync(w))throw new ManagedRenameSourceNotFoundError(`asset`,`Asset does not exist.`);if(existsSync(E))throw new ManagedRenameDestinationExistsError;if(!statSync(w).isFile())throw new ManagedRenameSourceTypeMismatchError(`asset`,`Source path is not an asset file.`);let D=[{fromPath:e,toPath:S}],O=qr(D);s.setAttribute(`rename.rewrite_candidates`,O.length),Jr(O.map(e=>e.docName)),await renameTrackedPathInGit(ye,w,E)||renamePathOnDisk(w,E);let k=Yr(O,D);return ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist asset rename cache for ${e} -> ${S}:`,t)}),de?.(`files`),k.length>0&&(de?.(`backlinks`),de?.(`graph`)),k.sort((e,t)=>e.docName.localeCompare(t.docName)),s.setAttribute(`rename.rewrite_count`,k.length),{renamedAssets:D,rewrittenDocs:k}}))}async function Hi(e,s){return Mr(async()=>withSpan(`rename.executeDocumentToFileRewrites`,{attributes:{"rename.kind":`asset`,"rename.transition":`document-to-file`}},async S=>{if(!ce)throw new BacklinkIndexRequiredError;if(!isSupportedDocFile(e)||isSupportedDocFile(s))throw new ManagedRenameInvalidRequestError(`Document-to-file rename requires a markdown source and non-markdown destination.`);let w=stripDocExtension(e);if(isSystemDoc(w)||isConfigDoc(w))throw new ManagedRenameReservedPathError(`Reserved document names cannot be renamed.`);if(isReservedProjectStatePath(e)||isReservedProjectStatePath(s))throw new ManagedRenameReservedPathError(`.ok and .git are reserved directories.`);if(Te?.isPathIgnored(s))throw new ManagedRenameInvalidRequestError(`Destination file is excluded by the project content config.`);let E=resolveContentEntryPath(g,`folder`,e),O=resolveContentEntryPath(g,`folder`,s);if(E===O)return{renamedAssets:[],rewrittenDocs:[]};if(stringsDifferOnlyByCase(e,s))throw new ManagedRenameInvalidRequestError(`Case-only renames are not supported.`);if(!existsSync(E))throw new ManagedRenameSourceNotFoundError(`file`);if(existsSync(O))throw new ManagedRenameDestinationExistsError;if(!statSync(E).isFile())throw new ManagedRenameSourceTypeMismatchError(`file`,`Source path is not a document file.`);let k=_e?.(),j=new Set(k?k.getConflicts().map(e=>e.file):[]),F=t.documents.get(w);if(F!==void 0&&isDocInConflict(F)||j.has(e))throw new DocInConflictError({file:e});let L=[{fromPath:e,toPath:s}],B=qr(L).filter(e=>e.docName!==w);S.setAttribute(`rename.rewrite_candidates`,B.length),Jr(B.map(e=>e.docName)),reconcileDiskBeforeAgentWrite(t,w,g),Pe&&!isSystemDoc(w)&&!isConfigDoc(w)&&Pe.setDeleted(w);let H=(await Lr([w])).get(w),q=typeof H==`string`?H:readFileSync(E,`utf-8`),ee=createManagedRenameRecoveryJournal({fromPath:e,toPath:s,affectedDocs:[{from:w,to:w}],snapshots:[{docName:w,content:q}],cleanupPaths:[s]}),J=[];return await withManagedRenameRecovery(ye??g,ee,async()=>{writeFileIfContentDiffers(E,q),registerWrite(E,contentHash(q)),await renameTrackedPathInGit(ye,E,O)||renamePathOnDisk(E,O),ce.deleteDocument(w),forgetDocExtension(w),D?.({kind:`delete`,path:E,docName:w});let t=statSync(O);D?.({kind:`file-create`,path:O,relativePath:s,size:t.size,modifiedTs:t.mtimeMs,inode:t.ino}),J=Yr(B,L),ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist document-to-file rename cache for ${e} -> ${s}:`,t)}),de?.(`files`),J.length>0&&(de?.(`backlinks`),de?.(`graph`))}),J.sort((e,t)=>e.docName.localeCompare(t.docName)),S.setAttribute(`rename.rewrite_count`,J.length),{renamedAssets:L,rewrittenDocs:J}}))}async function Ui(e,s,S,E){return Mr(async()=>withSpan(`rename.executeRewrites`,{attributes:{"rename.kind":S}},async O=>{if(!ce)throw new BacklinkIndexRequiredError;let k=resolveContentEntryPath(g,S,e),j=resolveContentEntryPath(g,S,s);if(k===j)return{renamed:[],renamedAssets:[],rewrittenDocs:[]};if(!existsSync(k))throw new ManagedRenameSourceNotFoundError(S);if(existsSync(j)&&!isCaseOnlySelfCollision(k,j))throw new ManagedRenameDestinationExistsError;let F=statSync(k);if(S===`file`&&!F.isFile()||S===`folder`&&!F.isDirectory())throw new ManagedRenameSourceTypeMismatchError(S);let L=S===`folder`?Qr(k,e,s):[];O.setAttribute(`rename.affected_assets`,L.length);let B=(S===`file`?[stripDocExtension(e)]:Zr(k)).map(t=>({from:t,to:S===`file`?stripDocExtension(s):remapDocNameForRename(t,S,e,s)}));if(O.setAttribute(`rename.affected_docs`,B.length),B.length===0){let t=qr(L);Jr(t.map(e=>e.docName));let g=[];return S===`folder`&&(await renameTrackedPathInGit(ye,k,j)||renamePathOnDisk(k,j),at(e,s),de?.(`files`)),g.push(...Yr(t,L)),g.length>0&&(ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist managed rename cache for ${e} -> ${s}:`,t)}),de?.(`backlinks`),de?.(`graph`)),g.sort((e,t)=>e.docName.localeCompare(t.docName)),{renamed:[],renamedAssets:L,rewrittenDocs:g}}let H=buildRenameMap(B),ee=B.map(({from:e,to:t})=>({fromDocName:e,toDocName:t})),J=new Set;for(let{from:e}of B)for(let t of ce.getBacklinks(e))H.has(t.source)||J.add(t.source);let Y=[...J].sort((e,t)=>e.localeCompare(t)),te=new Map,ne=new Set,oe=new Set,se=[];for(let e of[...H.keys(),...Y]){if(te.has(e))continue;if(!H.has(e)&&!existsSync(resolveContentEntryPath(g,`file`,e))){se.push(e);continue}reconcileDiskBeforeAgentWrite(t,e,g);let s=Vr(e);typeof s==`string`?(te.set(e,s),H.has(e)||ne.add(e)):H.has(e)||se.push(e)}if(L.length>0){let e=[...w().keys()].sort((e,t)=>e.localeCompare(t));for(let t of e){let e=te.get(t)??Vr(t);typeof e==`string`&&Gr(e,t,H.get(t)??t,H,L).rewrites!==0&&(te.has(t)||te.set(t,e),oe.add(t),H.has(t)||ne.add(t))}}Jr(oe);for(let{from:e}of B)if(typeof te.get(e)!=`string`)throw new ManagedRenameMissingDocumentError(e);let ue=createManagedRenameRecoveryJournal({fromPath:e,toPath:s,affectedDocs:[...B],snapshots:Br([...te.keys()],te)}),fe=[],me=[...ne].sort((e,t)=>e.localeCompare(t));return await withManagedRenameRecovery(ye??g,ue,async()=>{for(let e of se)ce.deleteDocument(e);for(let e of me){let s=t.documents.get(e)?Ur(e,H,L):Gr(te.get(e)??``,e,e,H,L);s.rewrites>0&&(Hr(e,s.markdown),fe.push({docName:e,rewrites:s.rewrites})),ce.updateDocumentFromMarkdown(e,s.markdown)}if(Pe)for(let{from:e,to:t}of B)isSystemDoc(e)||isConfigDoc(e)||(Pe.setRenamed(e,t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,from:e,to:t,kind:`renamed`,source:`spine`})));let w=resolveContentEntryPath(g,S,e),O=resolveContentEntryPath(g,S,s);await renameTrackedPathInGit(ye,w,O)||renamePathOnDisk(w,O),S===`folder`&&at(e,s);let k=await Lr([...H.keys()]);if(process.env.NODE_ENV===`test`&&process.env.OK_TEST_RENAME_FAULT===`pre-append`)throw Error(`OK_TEST_RENAME_FAULT=pre-append`);if(q?.current){let e=q.current,t=B.filter(({from:e,to:t})=>e!==t);t.length>0&&withSpanSync(`rename.appendLog`,{attributes:{"rename.kind":S}},s=>{let g=randomUUID$1(),w=new Date().toISOString(),D=ae?.()??`main`,O=getOrLoadRenameLogIndex(e.gitDir),k=E?.actor?{writerId:E.actor.writerId,displayName:E.actor.displayName}:{writerId:SERVICE_WRITER.id,displayName:SERVICE_WRITER.name},j=0;for(let{from:s,to:F}of t){let t={v:1,from:s,to:F,at:w,commitSha:``,branch:D,groupId:g,kind:S,actor:k};appendRenameLogEntry(e.gitDir,t,O,e),j+=1,E?.actor?recordContributor(F,E.actor.writerId,E.actor.displayName,E.actor.colorSeed,formatRenameSubject(s,F),E.actor.actorMetadata,void 0,[{from:s,to:F}]):recordContributor(F,SERVICE_WRITER.id,SERVICE_WRITER.name,SERVICE_WRITER.id,formatRenameSubject(s,F),void 0,void 0,[{from:s,to:F}])}s.setAttribute(`rename.entries_appended`,j)})}let j=S===`file`&&isSupportedDocFile(s)?extname(s):null;for(let{from:e,to:t}of B){let s=getDocExtension(e);forgetDocExtension(e),registerDocExtension(t,j??s)}let F=[...B].sort((e,t)=>e.from.localeCompare(t.from));for(let{from:e,to:t}of F){let s=resolveContentEntryPath(g,`file`,e),S=resolveContentEntryPath(g,`file`,t),w=Gr(k.get(e)??te.get(e)??readFileSync(S,`utf-8`),e,t,H,L);zr([{fromDocName:e,toDocName:t}],new Map([[e,w.markdown]])),setReconciledBase(t,w.markdown),D?.({kind:`rename`,oldPath:s,newPath:S,oldDocName:e,newDocName:t,content:w.markdown}),ce.renameDocument(e,t,w.markdown),w.rewrites>0&&fe.push({docName:t,rewrites:w.rewrites})}if(process.env.NODE_ENV===`test`&&process.env.OK_TEST_RENAME_FAULT===`pre-journal-clear`)throw Error(`OK_TEST_RENAME_FAULT=pre-journal-clear`)}),ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist managed rename cache for ${e} -> ${s}:`,t)}),de?.(`files`),de?.(`backlinks`),de?.(`graph`),fe.sort((e,t)=>e.docName.localeCompare(t.docName)),O.setAttribute(`rename.rewrite_count`,fe.length),{renamed:ee,renamedAssets:L,rewrittenDocs:fe}}))}function Gi(e){let t=parseAgentBodyFields(e),s=t.writerId??`claude-1`;return{rawAgentId:t.rawAgentId,agentId:s,agentName:t.displayName,colorSeed:t.colorSeed??t.rawAgentId??s,clientName:t.clientName,clientVersion:t.clientVersion,label:t.label}}function Ki(e){return{principalId:Ce?.()?.id,agentType:resolveAgentType(e.clientName),clientName:e.clientName,clientVersion:e.clientVersion,label:e.label}}function Yi(e){return e.kind===`value`?e.truncatedFrom===void 0?{response:{value:e.value},stored:e.value}:{response:{value:e.value,truncatedFrom:e.truncatedFrom,hint:`Summary truncated from ${e.truncatedFrom} chars to 80 (max 80).`},stored:e.value}:{stored:void 0}}function Xi(e){return{value:e.value}}function Zi(e,t=!1){e.kind===`value`&&(incrementSummariesProvided(),e.truncatedFrom!==void 0&&!t&&incrementSummariesTruncated())}function ka(e,t,s,g){if(s.length!==0)switch(e.kind){case`agent`:{let g=e.summary.kind===`value`,S=g?e.summary:normalizeSummary(t),w=Yi(S),E=g||!w.response?w.response:Xi(w.response);for(let t=0;t<s.length;t++){let{docName:g,subject:S}=s[t];recordContributor(g,e.writerId,e.displayName,e.colorSeed,S,e.actor,t===0?w.stored:void 0)}incrementAgentWriteCalls(),Zi(S,!g);for(let{docName:e}of s)Vt(e,`rename-path`);return E}case`principal`:{let t=Yi(e.summary);for(let g=0;g<s.length;g++){let{docName:S,subject:w}=s[g];recordContributor(S,e.writerId,e.displayName,e.colorSeed,w,e.actor,g===0?t.stored:void 0)}Zi(e.summary,!1);for(let{docName:e}of s)Vt(e,`rename-path`);return t.response}case`anonymous`:g.onAnonymous?.();return;default:{let t=e;throw Error(`Unhandled actor kind in ${g.context}: ${String(t.kind)}`)}}}function _s(e,t,s){let g=t.replace(/\/$/,``),S=g===``?``:`${g}/`;return e===`template`?`${S}.ok/templates/${s}`:e===`skill`?`${S}.ok/skills/${s}`:e===`folder-frontmatter`?`${S}.ok/frontmatter`:g===``?`.`:g}function xs(e,t,s,g){if(e.kind!==`agent`&&e.kind!==`principal`)return;let S=Yi(e.summary);recordContributor(t,e.writerId,e.displayName,e.colorSeed,s,e.actor,S.stored,g)}async function Cs(e){if(J)try{await J()}catch(t){console.warn(`[${e}] flushContributors failed; attribution stays queued for the next flush:`,t)}}let Ts=withValidation(AgentWriteRequestSchema,async(S,w,E)=>{try{let S=requireNonEmptyDocName(E.docName,w,`agent-write`);if(S===null)return;let D=Rt(S),{agentId:O,agentName:k,colorSeed:j,clientName:F,clientVersion:L,label:B}=Gi(E);if(isSystemDoc(D)||isConfigDoc(D)){errorResponse(w,400,`urn:ok:error:reserved-doc-name`,`'${D}' is a reserved document name.`,{handler:`agent-write`});return}let H=normalizeSummary(E.summary),q=await s.getSession(D,O,{displayName:k,colorSeed:j,clientName:F}),ee=reconcileDiskBeforeAgentWrite(t,D,g,e.resolveEmbed),J=new Date().toISOString(),Y=typeof E.content==`string`?E.content:`Hello from the agent! ${J}`,{response:te,stored:ne}=Yi(H);try{let t=iconFromClientName(F),s=AGENT_ICON_COLORS[t]??colorFromSeed(j??O);me?.setPresence(O,{displayName:k,icon:t,color:s,currentDoc:D,mode:`writing`,ts:Date.now()}),captureEffect(q.dc.document.getText(`source`),O,j,F),q.dc.document.transact(()=>{applyAgentMarkdownWrite(q.dc.document,`${Y}\n`,`append`,e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:D}:void 0),q.dc.document.getMap(`agent-flash`).set(O,{agentId:O,timestamp:Date.now(),type:`insert`,description:`Added (${k}): ${Y.slice(0,50)}`})},q.origin),recordContributor(D,O,k,j,void 0,Ki({clientName:F,clientVersion:L,label:B}),ne),incrementAgentWriteCalls(),Zi(H)}finally{me?.touchMode(O,`idle`)}let ae=await Ht(D);if(ae?.kind===`failure`){Ut(w,ae.failure,`agent-write`);return}if(ae?.kind===`divergence`){Wt(w,`agent-write`);return}Vt(D,`agent-write`),ge?.();let oe=Kt(ee);successResponse(w,200,AgentWriteSuccessSchema,{timestamp:J,...te?{summary:te}:{},...oe?{warning:oe,warnings:[oe]}:{}},{handler:`agent-write`})}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(w,e,`agent-write`);return}if(e instanceof FrontmatterMalformedError){respondFrontmatterMalformed(w,e,`agent-write`);return}if(e instanceof AgentSessionCapacityError){errorResponse(w,503,`urn:ok:error:too-many-agent-sessions`,`Too many agent sessions.`,{handler:`agent-write`,cause:e,extraHeaders:{"Retry-After":`10`}});return}log$6.error({err:e},`[agent-write] handler failed`),errorResponse(w,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-write`,cause:e})}},{handler:`agent-write`,method:`POST`}),Ds=withValidation(AgentWriteMdRequestSchema,async(S,w,E)=>{try{let S=E.position??`append`,D=requireNonEmptyDocName(E.docName,w,`agent-write-md`);if(D===null)return;let O=Rt(D),{agentId:k,agentName:j,colorSeed:F,clientName:L,clientVersion:B,label:H}=Gi(E);if(isSystemDoc(O)||isConfigDoc(O)){errorResponse(w,400,`urn:ok:error:reserved-doc-name`,`'${O}' is a reserved document name.`,{handler:`agent-write-md`});return}E.extension!==void 0&&!docNameExistsWithAnySupportedExtension(g,O)&®isterDocExtension(O,E.extension);let q=normalizeSummary(E.summary),{response:ee,stored:J}=Yi(q),Y=await s.getSession(O,k,{displayName:j,colorSeed:F,clientName:L}),te=reconcileDiskBeforeAgentWrite(t,O,g,e.resolveEmbed),ne=new Date().toISOString(),ae;try{let t=iconFromClientName(L),s=AGENT_ICON_COLORS[t]??colorFromSeed(F??k);me?.setPresence(k,{displayName:j,icon:t,color:s,currentDoc:O,mode:`writing`,ts:Date.now()}),captureEffect(Y.dc.document.getText(`source`),k,F,L),Y.dc.document.transact(()=>{ae=applyAgentMarkdownWrite(Y.dc.document,E.markdown,S,e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:O}:void 0),Y.dc.document.getMap(`agent-flash`).set(k,{agentId:k,timestamp:Date.now(),type:`insert`,description:`Added (${j}): ${E.markdown.trim().slice(0,50)}`})},Y.origin),ae!==void 0&&console.warn(JSON.stringify({event:`agent-write-content-divergence`,"doc.name":O,position:S,intendedBytes:ae.intendedBytes,actualBytes:ae.actualBytes,byteDelta:ae.byteDelta,"agent.id":k,"agent.client_name":L})),recordContentDivergenceGate(`agent-write-md`,ae),recordContributor(O,k,j,F,void 0,Ki({clientName:L,clientVersion:B,label:H}),J),incrementAgentWriteCalls(),Zi(q)}finally{me?.touchMode(k,`idle`)}let oe=await Ht(O);if(oe?.kind===`failure`){Ut(w,oe.failure,`agent-write-md`);return}if(oe?.kind===`divergence`){Wt(w,`agent-write-md`);return}Vt(O,`agent-write-md`),fe?.setFocus(k,{agentName:j,currentDoc:O,writeKind:`write`,ts:Date.now()}),ge?.();let se=Lt(O),ce=Y.dc.document.getText(`source`).toString(),ue=await validateMermaidFences(ce,O),de=$t();de.add(O);let _e=computeBrokenOutboundLinks(ce,O,de,en),ve=zt(O),ye=Bt();ye===0&&hintEmittedCounter().add(1,{"shadow.writer":`agent`,"agent.type":resolveAgentType(L)});let Ce=Kt(te),we=ae===void 0?void 0:toContentDivergenceWarning(ae),Te=[...we?[we]:[],...Ce?[Ce]:[],...ue??[]];successResponse(w,200,AgentWriteMdSuccessSchema,{timestamp:ne,subscriberCount:ve,systemSubscriberCount:ye,...se?{hints:se}:{},...ee?{summary:ee}:{},...we?{warning:we}:Ce?{warning:Ce}:{},...Te.length>0?{warnings:Te}:{},brokenLinks:_e},{handler:`agent-write-md`})}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(w,e,`agent-write-md`);return}if(e instanceof FrontmatterMalformedError){respondFrontmatterMalformed(w,e,`agent-write-md`);return}if(e instanceof AgentSessionCapacityError){errorResponse(w,503,`urn:ok:error:too-many-agent-sessions`,`Too many agent sessions.`,{handler:`agent-write-md`,cause:e,extraHeaders:{"Retry-After":`10`}});return}log$6.error({err:e},`[agent-write-md] handler failed`),errorResponse(w,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-write-md`,cause:e})}},{handler:`agent-write-md`,method:`POST`}),Os=withValidation(FrontmatterPatchRequestSchema,async(S,w,E)=>{try{let S=requireNonEmptyDocName(E.docName,w,`frontmatter-patch`);if(S===null)return;let D=Rt(S),{agentId:O,agentName:k,colorSeed:j,clientName:F,clientVersion:L,label:B}=Gi(E);if(isSystemDoc(D)||isConfigDoc(D)){errorResponse(w,400,`urn:ok:error:reserved-doc-name`,`'${D}' is a reserved document name.`,{handler:`frontmatter-patch`});return}let H=E.patch??{},q=Object.keys(H),ee=normalizeSummary(E.summary),{response:J,stored:Y}=Yi(ee),te=await s.getSession(D,O,{displayName:k,colorSeed:j,clientName:F}),ne=reconcileDiskBeforeAgentWrite(t,D,g,e.resolveEmbed),ae=new Date().toISOString(),oe,se=!1,ce=!1,ue=[];try{let e=iconFromClientName(F),t=AGENT_ICON_COLORS[e]??colorFromSeed(j??O);me?.setPresence(O,{displayName:k,icon:e,color:t,currentDoc:D,mode:`writing`,ts:Date.now()}),withSpanSync(`ok.frontmatter_patch`,{attributes:{"doc.name":D,"frontmatter_patch.keys":q.length}},()=>{te.dc.document.transact(()=>{let{fenced:e,body:t}=detectFmRegion(te.dc.document.getText(`source`).toString()),s=applyPatchToFm(e,H);if(!s.ok){oe=s.error;return}for(let e of Object.keys(H))ue.push(e);if(s.nextFenced!==e){let g=e===``&&t!==``&&!t.startsWith(`
|
|
1938
|
+
`)}function vt(){Xe=null}j?.(vt);let Tt=createInstalledAgentsProbe({probe:De??createOsProbe(process.platform)});function Et(e){if(isManagedArtifactDocName(e))try{return managedArtifactAbsPath(e,{projectDir:ye??g,homedirOverride:we})}catch{return null}if(!isSafeDocName(e))return null;let t=resolve(g),s=resolve(t,`${e}${getDocExtension(e)}`);return isWithinDir(s,t)?s:null}function Dt(e){let t=Et(e);if(!t||!existsSync(t))return e;try{return extractPageTitle(readFileSync(t,`utf-8`),e)}catch{return e}}function jt(e,t){return t.has(e)?Dt(e):e}let Mt={cluster:void 0,category:void 0,tags:void 0};function Ft(e){try{let s=t.documents.get(e);if(s){let e=readFmMap(s.getText(`source`).toString());if(Object.keys(e).length>0){let t=typeof e.cluster==`string`?e.cluster:void 0,s=typeof e.category==`string`?e.category:void 0,g;if(Array.isArray(e.tags)){let t=e.tags.filter(e=>typeof e==`string`);g=t.length>0?t:void 0}else typeof e.tags==`string`&&e.tags&&(g=[e.tags]);return{cluster:t,category:s,tags:g}}}}catch{}try{let t=Et(e);if(!t||!existsSync(t))return Mt;let{frontmatter:s}=stripFrontmatter(readFileSync(t,`utf-8`));return s?parseFrontmatterMetadata(s):Mt}catch{return Mt}}function It(e,t){return t.has(e)?Ft(e):Mt}function Lt(e){if(ce)try{if(ce.getBacklinks(e).length>0)return;let t=performance.now(),s=findHubCandidates(e,w()),g=performance.now()-t;return g>5&&log$6.debug({docName:e,elapsedMs:g,candidateCount:s.length},`[orphan-hint] findHubCandidates slow`),s.length===0?void 0:[{type:`orphan`,parentCandidates:s,message:`This doc has no backlinks yet. To make it discoverable, consider linking from a parent hub doc (index/overview files in the folder tree): ${s.map(e=>`[[${e}]]`).join(`, `)}.`}]}catch(e){console.warn(`[orphan-hint] computeOrphanHints failed:`,e);return}}function Rt(e){return F?.().get(e)??e}function zt(e){try{return t.documents.get(e)?.connections.size??0}catch{return 0}}function Bt(){try{return t.documents.get(`__system__`)?.connections.size??0}catch{return 0}}function Vt(e,s){let g=`onStoreDocument-${e}`;(t.debouncer.isDebounced(g)?t.debouncer.executeNow(g):Promise.resolve()).then(()=>ee?.()).catch(e=>{log$6.warn({err:e},`[${s}] post-write flush failed`)})}async function Ht(e){let s=`onStoreDocument-${e}`;t.debouncer.isDebounced(s)&&(ne?.(e),await t.debouncer.executeNow(s));let g=Y?.(e)??null;return g?{kind:`failure`,failure:g}:te?.(e)?{kind:`divergence`}:null}function Ut(e,t,s){let g=classifyUploadErrno({code:t.code});errorResponse(e,uploadStatusFor(g),g,`Write applied in memory but failed to persist to disk (${t.code??`unknown error`}): ${t.message}. The content was NOT saved and will be lost if the server restarts.`,{handler:s})}function Wt(e,t){errorResponse(e,409,`urn:ok:error:disk-divergence`,`The document changed on disk after your edit was prepared; your edit was NOT applied, to avoid overwriting the newer on-disk content. Re-read the document and retry.`,{handler:t})}function Kt(e){if(e.reconciled)return{kind:`disk-edit-reconciled`,intendedBytes:e.baseBytes,actualBytes:e.diskBytes,byteDelta:e.diskBytes-e.baseBytes,...e.mergeOutcome?{mergeOutcome:e.mergeOutcome}:{},hint:e.mergeOutcome===`merged`?'An out-of-band edit was three-way merged into this document before your edit was applied on top; the merge may have interleaved content blocks. Re-read it (e.g. `exec("cat <path>")`) and review the combined result carefully before continuing.':'An out-of-band edit was reconciled into this document before your edit was applied on top; the document now reflects that edit plus yours. Re-read it (e.g. `exec("cat <path>")`) to see the combined result before continuing.'}}function $t(e){if(!Te)return!1;let t=isSupportedDocFile(e)?e:`${e}${getDocExtension(e)}`;return Te.isExcluded(t)}function en(){let e=new Set;for(let[t,s]of w()){e.add(t);for(let t of s.aliases)e.add(t)}try{for(let t of[`project`,`global`]){let s=resolve(t===`global`?tu:g,`.ok`,`skills`);for(let g of cu(s,t).skills)e.add(`${MANAGED_ARTIFACT_PREFIX_SKILL}${t}/${g.name}`)}for(let t of resolveProjectTemplates(resolve(g)).templates)e.add(ru(t.source_folder,t.name))}catch(e){log$6.warn({err:e},`[collectAdmittedDocNames] managed-artifact enumeration failed`)}for(let t of ce?.getIndexedDocNames()??[])e.has(t)||$t(t)||e.add(t);return e}let jr=e=>existsSync(resolve(g,e));function Mr(e,t){$t(e)||D?.({kind:w().has(e)?`update`:`create`,path:resolveContentEntryPath(g,`file`,e),docName:e,content:t})}function Fr(){let e=Promise.resolve();return async function(t){let s=e,g=()=>{};e=new Promise(e=>{g=e}),await s;try{return await t()}finally{g()}}}let Ir=Fr(),Lr=e=>e.endsWith(`.`)?e:`${e}.`;function zr(e){return e instanceof Error?e instanceof ManagedRenameSourceNotFoundError?{status:404,type:`urn:ok:error:doc-not-found`,error:Lr(e.message)}:e instanceof ManagedRenameDestinationExistsError?{status:409,type:`urn:ok:error:doc-already-exists`,error:Lr(e.message)}:e instanceof ManagedRenameSourceTypeMismatchError||e instanceof ManagedRenameInvalidRequestError?{status:400,type:`urn:ok:error:invalid-request`,error:Lr(e.message)}:e instanceof ManagedRenameReservedPathError?{status:400,type:`urn:ok:error:reserved-doc-name`,error:Lr(e.message)}:e instanceof ManagedRenameMissingDocumentError||e instanceof ManagedRenameSnapshotMissingError?{status:404,type:`urn:ok:error:doc-not-found`,error:Lr(e.message)}:e instanceof SymlinkEscapeError?{status:400,type:`urn:ok:error:path-escape`,error:Lr(e.message)}:e instanceof BacklinkIndexRequiredError?{status:503,type:`urn:ok:error:backlink-index-not-configured`,error:Lr(e.message)}:{status:500,type:`urn:ok:error:internal-server-error`,error:`Failed to rename document.`}:{status:500,type:`urn:ok:error:internal-server-error`,error:`Failed to rename document.`}}async function Br(e){let g=new Map;for(let s of e){let e=t.documents.get(s);e&&g.set(s,e.getText(`source`).toString())}for(let t of e)await s.closeAllForDoc(t).catch(e=>{console.warn(`[file-ops] Failed to close agent session for ${t}:`,e)});for(let s of e){let e=t.documents.get(s);deleteReconciledBase(s),Re?.(s),e&&(t.closeConnections(s),await(je??t.unloadDocument.bind(t))(e))}return g}function Vr(e,t){for(let{fromDocName:s,toDocName:S}of e){let e=safeContentPath(S,g),w=t.get(s);typeof w==`string`&&writeFileIfContentDiffers(e,w);let E=typeof w==`string`?w:existsSync(e)?readFileSync(e,`utf-8`):null;typeof E==`string`&®isterWrite(e,contentHash(E))}}function Hr(e,t){return e.map(e=>{let s=t.get(e);if(typeof s==`string`)return{docName:e,content:s};let S=safeContentPath(e,g);if(!existsSync(S))throw new ManagedRenameSnapshotMissingError(e);return{docName:e,content:readFileSync(S,`utf-8`)}})}function Ur(e){let s=t.documents.get(e);if(s)return s.getText(`source`).toString();let S=resolveContentEntryPath(g,`file`,e);return existsSync(S)?readFileSync(S,`utf-8`):null}function Wr(e,t){let s=resolveContentEntryPath(g,`file`,e);tracedMkdirSync(dirname(s),{recursive:!0}),writeFileIfContentDiffers(s,t),registerWrite(s,contentHash(t)),setReconciledBase(e,t),D?.({kind:`update`,path:s,docName:e,content:t})}function Gr(e,s,g=[]){let S=t.documents.get(e);if(!S)throw Error(`Document is not loaded: ${e}`);let w={markdown:``,rewrites:0};return S.transact(()=>{w=qr(S.getText(`source`).toString(),e,s.get(e)??e,s,g),w.rewrites!==0&&composeAndWriteRawBody(S,w.markdown,`managed-rename`,!1)},MANAGED_RENAME_ORIGIN),w}function Kr(e,t,s){let g=e,S=0;for(let{fromPath:e,toPath:w}of s){let s=rewriteAssetReferencesForRename(g,t,e,w);g=s.markdown,S+=s.rewrites}return{markdown:g,rewrites:S}}function qr(e,t,s,g,S){let w=applyRenameMap(e,t,g),E=Kr(w.markdown,s,S);return{markdown:E.markdown,rewrites:E.markdown===e?0:w.rewrites+E.rewrites}}function Jr(e,s){let g=t.documents.get(e);if(!g)throw Error(`Document is not loaded: ${e}`);let S={markdown:``,rewrites:0};return g.transact(()=>{S=Kr(g.getText(`source`).toString(),e,s),S.rewrites!==0&&composeAndWriteRawBody(g,S.markdown,`managed-rename`,!1)},MANAGED_RENAME_ORIGIN),S}function Yr(e){let t=[];if(e.length===0)return t;let s=[...w().keys()].sort((e,t)=>e.localeCompare(t));for(let g of s){let s=Ur(g);if(typeof s!=`string`)continue;let S=Kr(s,g,e);S.rewrites!==0&&t.push({docName:g,markdown:S.markdown,rewrites:S.rewrites})}return t}function Xr(e){let s=_e?.(),g=new Set(s?s.getConflicts().map(e=>e.file):[]);for(let s of e){let e=t.documents.get(s),S=`${s}${getDocExtension(s)}`,w=e!==void 0&&isDocInConflict(e),E=g.has(S);if(w||E)throw new DocInConflictError({file:S})}}function Zr(e,s){let g=[];for(let S of e){let e=t.documents.get(S.docName)?Jr(S.docName,s):S;e.rewrites!==0&&(Wr(S.docName,e.markdown),ce?.updateDocumentFromMarkdown(S.docName,e.markdown),g.push({docName:S.docName,rewrites:e.rewrites}))}return g}function Qr(e){if(extname(e))return{path:e,ambiguous:!1};let t=e.lastIndexOf(`/`),s=t===-1?``:e.slice(0,t),S=t===-1?e:e.slice(t+1),w=s?resolveContentEntryPath(g,`folder`,s):g,E;try{E=readdirSync(w,{withFileTypes:!0})}catch(t){let s=t.code;if(s===`ENOENT`||s===`ENOTDIR`)return{path:e,ambiguous:!1};throw t}let D=E.filter(e=>e.isFile()&&e.name.startsWith(`${S}.`)).map(e=>s?`${s}/${e.name}`:e.name).filter(e=>isSupportedAssetFile(e,LINKABLE_ASSET_EXTENSIONS));return D.length===1?{path:D[0],ambiguous:!1}:{path:e,ambiguous:D.length>1}}function ji(e){let t=[];try{if(!statSync(e).isDirectory())return t}catch(e){let s=e.code;if(s===`ENOENT`||s===`ENOTDIR`)return t;throw e}function s(e){for(let S of readdirSync(e,{withFileTypes:!0})){let w=resolve(e,S.name),E=relative(g,w).split(sep).join(`/`);if(isReservedProjectStatePath(E))continue;if(S.isDirectory()){if(Te?.isDirExcluded(E))continue;s(w);continue}if(!S.isFile()||!isSupportedDocFile(E)||Te?.isExcluded(E))continue;let D=stripDocExtension(E);registerDocExtension(D,extname(E)),t.push(D)}}return s(e),t.sort((e,t)=>e.localeCompare(t)),t}function Hi(e,t,s){let S=[];function w(e){for(let E of readdirSync(e,{withFileTypes:!0})){let D=resolve(e,E.name),O=relative(g,D).split(sep).join(`/`);if(!isReservedProjectStatePath(O)){if(E.isDirectory()){if(Te?.isDirExcluded(O))continue;w(D);continue}!E.isFile()||isSupportedDocFile(O)||Te?.isExcluded(O)||(O===t?S.push({fromPath:O,toPath:s}):O.startsWith(`${t}/`)&&S.push({fromPath:O,toPath:`${s}${O.slice(t.length)}`}))}}}return w(e),S.sort((e,t)=>e.fromPath.localeCompare(t.fromPath)),S}async function Ui(e,t){return Ir(async()=>withSpan(`rename.executeAssetRewrites`,{attributes:{"rename.kind":`asset`}},async s=>{if(!ce)throw new BacklinkIndexRequiredError;let S=extname(t)?t:`${t}${extname(e)}`;if(isReservedProjectStatePath(e)||isReservedProjectStatePath(S))throw new ManagedRenameReservedPathError(`.ok and .git are reserved directories.`);if(Te?.isPathIgnored(S))throw new ManagedRenameInvalidRequestError(`Destination asset is excluded by the project content config.`);let w=resolveContentEntryPath(g,`folder`,e),E=resolveContentEntryPath(g,`folder`,S);if(w===E)return{renamedAssets:[],rewrittenDocs:[]};if(stringsDifferOnlyByCase(e,S))throw new ManagedRenameInvalidRequestError(`Case-only renames are not supported.`);if(!existsSync(w))throw new ManagedRenameSourceNotFoundError(`asset`,`Asset does not exist.`);if(existsSync(E))throw new ManagedRenameDestinationExistsError;if(!statSync(w).isFile())throw new ManagedRenameSourceTypeMismatchError(`asset`,`Source path is not an asset file.`);let D=[{fromPath:e,toPath:S}],O=Yr(D);s.setAttribute(`rename.rewrite_candidates`,O.length),Xr(O.map(e=>e.docName)),await renameTrackedPathInGit(ye,w,E)||renamePathOnDisk(w,E);let k=Zr(O,D);return ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist asset rename cache for ${e} -> ${S}:`,t)}),de?.(`files`),k.length>0&&(de?.(`backlinks`),de?.(`graph`)),k.sort((e,t)=>e.docName.localeCompare(t.docName)),s.setAttribute(`rename.rewrite_count`,k.length),{renamedAssets:D,rewrittenDocs:k}}))}async function Gi(e,s){return Ir(async()=>withSpan(`rename.executeDocumentToFileRewrites`,{attributes:{"rename.kind":`asset`,"rename.transition":`document-to-file`}},async S=>{if(!ce)throw new BacklinkIndexRequiredError;if(!isSupportedDocFile(e)||isSupportedDocFile(s))throw new ManagedRenameInvalidRequestError(`Document-to-file rename requires a markdown source and non-markdown destination.`);let w=stripDocExtension(e);if(isSystemDoc(w)||isConfigDoc(w))throw new ManagedRenameReservedPathError(`Reserved document names cannot be renamed.`);if(isReservedProjectStatePath(e)||isReservedProjectStatePath(s))throw new ManagedRenameReservedPathError(`.ok and .git are reserved directories.`);if(Te?.isPathIgnored(s))throw new ManagedRenameInvalidRequestError(`Destination file is excluded by the project content config.`);let E=resolveContentEntryPath(g,`folder`,e),O=resolveContentEntryPath(g,`folder`,s);if(E===O)return{renamedAssets:[],rewrittenDocs:[]};if(stringsDifferOnlyByCase(e,s))throw new ManagedRenameInvalidRequestError(`Case-only renames are not supported.`);if(!existsSync(E))throw new ManagedRenameSourceNotFoundError(`file`);if(existsSync(O))throw new ManagedRenameDestinationExistsError;if(!statSync(E).isFile())throw new ManagedRenameSourceTypeMismatchError(`file`,`Source path is not a document file.`);let k=_e?.(),j=new Set(k?k.getConflicts().map(e=>e.file):[]),F=t.documents.get(w);if(F!==void 0&&isDocInConflict(F)||j.has(e))throw new DocInConflictError({file:e});let L=[{fromPath:e,toPath:s}],B=Yr(L).filter(e=>e.docName!==w);S.setAttribute(`rename.rewrite_candidates`,B.length),Xr(B.map(e=>e.docName)),reconcileDiskBeforeAgentWrite(t,w,g),Pe&&!isSystemDoc(w)&&!isConfigDoc(w)&&Pe.setDeleted(w);let H=(await Br([w])).get(w),q=typeof H==`string`?H:readFileSync(E,`utf-8`),ee=createManagedRenameRecoveryJournal({fromPath:e,toPath:s,affectedDocs:[{from:w,to:w}],snapshots:[{docName:w,content:q}],cleanupPaths:[s]}),J=[];return await withManagedRenameRecovery(ye??g,ee,async()=>{writeFileIfContentDiffers(E,q),registerWrite(E,contentHash(q)),await renameTrackedPathInGit(ye,E,O)||renamePathOnDisk(E,O),ce.deleteDocument(w),forgetDocExtension(w),D?.({kind:`delete`,path:E,docName:w});let t=statSync(O);D?.({kind:`file-create`,path:O,relativePath:s,size:t.size,modifiedTs:t.mtimeMs,inode:t.ino}),J=Zr(B,L),ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist document-to-file rename cache for ${e} -> ${s}:`,t)}),de?.(`files`),J.length>0&&(de?.(`backlinks`),de?.(`graph`))}),J.sort((e,t)=>e.docName.localeCompare(t.docName)),S.setAttribute(`rename.rewrite_count`,J.length),{renamedAssets:L,rewrittenDocs:J}}))}async function Ki(e,s,S,E){return Ir(async()=>withSpan(`rename.executeRewrites`,{attributes:{"rename.kind":S}},async O=>{if(!ce)throw new BacklinkIndexRequiredError;let k=resolveContentEntryPath(g,S,e),j=resolveContentEntryPath(g,S,s);if(k===j)return{renamed:[],renamedAssets:[],rewrittenDocs:[]};if(!existsSync(k))throw new ManagedRenameSourceNotFoundError(S);if(existsSync(j)&&!isCaseOnlySelfCollision(k,j))throw new ManagedRenameDestinationExistsError;let F=statSync(k);if(S===`file`&&!F.isFile()||S===`folder`&&!F.isDirectory())throw new ManagedRenameSourceTypeMismatchError(S);let L=S===`folder`?Hi(k,e,s):[];O.setAttribute(`rename.affected_assets`,L.length);let B=(S===`file`?[stripDocExtension(e)]:ji(k)).map(t=>({from:t,to:S===`file`?stripDocExtension(s):remapDocNameForRename(t,S,e,s)}));if(O.setAttribute(`rename.affected_docs`,B.length),B.length===0){let t=Yr(L);Xr(t.map(e=>e.docName));let g=[];return S===`folder`&&(await renameTrackedPathInGit(ye,k,j)||renamePathOnDisk(k,j),at(e,s),de?.(`files`)),g.push(...Zr(t,L)),g.length>0&&(ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist managed rename cache for ${e} -> ${s}:`,t)}),de?.(`backlinks`),de?.(`graph`)),g.sort((e,t)=>e.docName.localeCompare(t.docName)),{renamed:[],renamedAssets:L,rewrittenDocs:g}}let H=buildRenameMap(B),ee=B.map(({from:e,to:t})=>({fromDocName:e,toDocName:t})),J=new Set;for(let{from:e}of B)for(let t of ce.getBacklinks(e))H.has(t.source)||J.add(t.source);let Y=[...J].sort((e,t)=>e.localeCompare(t)),te=new Map,ne=new Set,oe=new Set,se=[];for(let e of[...H.keys(),...Y]){if(te.has(e))continue;if(!H.has(e)&&!existsSync(resolveContentEntryPath(g,`file`,e))){se.push(e);continue}reconcileDiskBeforeAgentWrite(t,e,g);let s=Ur(e);typeof s==`string`?(te.set(e,s),H.has(e)||ne.add(e)):H.has(e)||se.push(e)}if(L.length>0){let e=[...w().keys()].sort((e,t)=>e.localeCompare(t));for(let t of e){let e=te.get(t)??Ur(t);typeof e==`string`&&qr(e,t,H.get(t)??t,H,L).rewrites!==0&&(te.has(t)||te.set(t,e),oe.add(t),H.has(t)||ne.add(t))}}Xr(oe);for(let{from:e}of B)if(typeof te.get(e)!=`string`)throw new ManagedRenameMissingDocumentError(e);let ue=createManagedRenameRecoveryJournal({fromPath:e,toPath:s,affectedDocs:[...B],snapshots:Hr([...te.keys()],te)}),fe=[],me=[...ne].sort((e,t)=>e.localeCompare(t));return await withManagedRenameRecovery(ye??g,ue,async()=>{for(let e of se)ce.deleteDocument(e);for(let e of me){let s=t.documents.get(e)?Gr(e,H,L):qr(te.get(e)??``,e,e,H,L);s.rewrites>0&&(Wr(e,s.markdown),fe.push({docName:e,rewrites:s.rewrites})),ce.updateDocumentFromMarkdown(e,s.markdown)}if(Pe)for(let{from:e,to:t}of B)isSystemDoc(e)||isConfigDoc(e)||(Pe.setRenamed(e,t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,from:e,to:t,kind:`renamed`,source:`spine`})));let w=resolveContentEntryPath(g,S,e),O=resolveContentEntryPath(g,S,s);await renameTrackedPathInGit(ye,w,O)||renamePathOnDisk(w,O),S===`folder`&&at(e,s);let k=await Br([...H.keys()]);if(process.env.NODE_ENV===`test`&&process.env.OK_TEST_RENAME_FAULT===`pre-append`)throw Error(`OK_TEST_RENAME_FAULT=pre-append`);if(q?.current){let e=q.current,t=B.filter(({from:e,to:t})=>e!==t);t.length>0&&withSpanSync(`rename.appendLog`,{attributes:{"rename.kind":S}},s=>{let g=randomUUID$1(),w=new Date().toISOString(),D=ae?.()??`main`,O=getOrLoadRenameLogIndex(e.gitDir),k=E?.actor?{writerId:E.actor.writerId,displayName:E.actor.displayName}:{writerId:SERVICE_WRITER.id,displayName:SERVICE_WRITER.name},j=0;for(let{from:s,to:F}of t){let t={v:1,from:s,to:F,at:w,commitSha:``,branch:D,groupId:g,kind:S,actor:k};appendRenameLogEntry(e.gitDir,t,O,e),j+=1,E?.actor?recordContributor(F,E.actor.writerId,E.actor.displayName,E.actor.colorSeed,formatRenameSubject(s,F),E.actor.actorMetadata,void 0,[{from:s,to:F}]):recordContributor(F,SERVICE_WRITER.id,SERVICE_WRITER.name,SERVICE_WRITER.id,formatRenameSubject(s,F),void 0,void 0,[{from:s,to:F}])}s.setAttribute(`rename.entries_appended`,j)})}let j=S===`file`&&isSupportedDocFile(s)?extname(s):null;for(let{from:e,to:t}of B){let s=getDocExtension(e);forgetDocExtension(e),registerDocExtension(t,j??s)}let F=[...B].sort((e,t)=>e.from.localeCompare(t.from));for(let{from:e,to:t}of F){let s=resolveContentEntryPath(g,`file`,e),S=resolveContentEntryPath(g,`file`,t),w=qr(k.get(e)??te.get(e)??readFileSync(S,`utf-8`),e,t,H,L);Vr([{fromDocName:e,toDocName:t}],new Map([[e,w.markdown]])),setReconciledBase(t,w.markdown),D?.({kind:`rename`,oldPath:s,newPath:S,oldDocName:e,newDocName:t,content:w.markdown}),ce.renameDocument(e,t,w.markdown),w.rewrites>0&&fe.push({docName:t,rewrites:w.rewrites})}if(process.env.NODE_ENV===`test`&&process.env.OK_TEST_RENAME_FAULT===`pre-journal-clear`)throw Error(`OK_TEST_RENAME_FAULT=pre-journal-clear`)}),ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist managed rename cache for ${e} -> ${s}:`,t)}),de?.(`files`),de?.(`backlinks`),de?.(`graph`),fe.sort((e,t)=>e.docName.localeCompare(t.docName)),O.setAttribute(`rename.rewrite_count`,fe.length),{renamed:ee,renamedAssets:L,rewrittenDocs:fe}}))}function Yi(e){let t=parseAgentBodyFields(e),s=t.writerId??`claude-1`;return{rawAgentId:t.rawAgentId,agentId:s,agentName:t.displayName,colorSeed:t.colorSeed??t.rawAgentId??s,clientName:t.clientName,clientVersion:t.clientVersion,label:t.label}}function Xi(e){return{principalId:Ce?.()?.id,agentType:resolveAgentType(e.clientName),clientName:e.clientName,clientVersion:e.clientVersion,label:e.label}}function Zi(e){return e.kind===`value`?e.truncatedFrom===void 0?{response:{value:e.value},stored:e.value}:{response:{value:e.value,truncatedFrom:e.truncatedFrom,hint:`Summary truncated from ${e.truncatedFrom} chars to 80 (max 80).`},stored:e.value}:{stored:void 0}}function ka(e){return{value:e.value}}function _s(e,t=!1){e.kind===`value`&&(incrementSummariesProvided(),e.truncatedFrom!==void 0&&!t&&incrementSummariesTruncated())}function xs(e,t,s,g){if(s.length!==0)switch(e.kind){case`agent`:{let g=e.summary.kind===`value`,S=g?e.summary:normalizeSummary(t),w=Zi(S),E=g||!w.response?w.response:ka(w.response);for(let t=0;t<s.length;t++){let{docName:g,subject:S}=s[t];recordContributor(g,e.writerId,e.displayName,e.colorSeed,S,e.actor,t===0?w.stored:void 0)}incrementAgentWriteCalls(),_s(S,!g);for(let{docName:e}of s)Vt(e,`rename-path`);return E}case`principal`:{let t=Zi(e.summary);for(let g=0;g<s.length;g++){let{docName:S,subject:w}=s[g];recordContributor(S,e.writerId,e.displayName,e.colorSeed,w,e.actor,g===0?t.stored:void 0)}_s(e.summary,!1);for(let{docName:e}of s)Vt(e,`rename-path`);return t.response}case`anonymous`:g.onAnonymous?.();return;default:{let t=e;throw Error(`Unhandled actor kind in ${g.context}: ${String(t.kind)}`)}}}function Cs(e,t,s){let g=t.replace(/\/$/,``),S=g===``?``:`${g}/`;return e===`template`?`${S}.ok/templates/${s}`:e===`skill`?`${S}.ok/skills/${s}`:e===`folder-frontmatter`?`${S}.ok/frontmatter`:g===``?`.`:g}function Ts(e,t,s,g){if(e.kind!==`agent`&&e.kind!==`principal`)return;let S=Zi(e.summary);recordContributor(t,e.writerId,e.displayName,e.colorSeed,s,e.actor,S.stored,g)}async function Ds(e){if(J)try{await J()}catch(t){console.warn(`[${e}] flushContributors failed; attribution stays queued for the next flush:`,t)}}let Os=withValidation(AgentWriteRequestSchema,async(S,w,E)=>{try{let S=requireNonEmptyDocName(E.docName,w,`agent-write`);if(S===null)return;let D=Rt(S),{agentId:O,agentName:k,colorSeed:j,clientName:F,clientVersion:L,label:B}=Yi(E);if(isSystemDoc(D)||isConfigDoc(D)){errorResponse(w,400,`urn:ok:error:reserved-doc-name`,`'${D}' is a reserved document name.`,{handler:`agent-write`});return}let H=normalizeSummary(E.summary),q=await s.getSession(D,O,{displayName:k,colorSeed:j,clientName:F}),ee=reconcileDiskBeforeAgentWrite(t,D,g,e.resolveEmbed),J=new Date().toISOString(),Y=typeof E.content==`string`?E.content:`Hello from the agent! ${J}`,{response:te,stored:ne}=Zi(H);try{let t=iconFromClientName(F),s=AGENT_ICON_COLORS[t]??colorFromSeed(j??O);me?.setPresence(O,{displayName:k,icon:t,color:s,currentDoc:D,mode:`writing`,ts:Date.now()}),captureEffect(q.dc.document.getText(`source`),O,j,F),q.dc.document.transact(()=>{applyAgentMarkdownWrite(q.dc.document,`${Y}\n`,`append`,e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:D}:void 0),q.dc.document.getMap(`agent-flash`).set(O,{agentId:O,timestamp:Date.now(),type:`insert`,description:`Added (${k}): ${Y.slice(0,50)}`})},q.origin),recordContributor(D,O,k,j,void 0,Xi({clientName:F,clientVersion:L,label:B}),ne),incrementAgentWriteCalls(),_s(H)}finally{me?.touchMode(O,`idle`)}let ae=await Ht(D);if(ae?.kind===`failure`){Ut(w,ae.failure,`agent-write`);return}if(ae?.kind===`divergence`){Wt(w,`agent-write`);return}Vt(D,`agent-write`),ge?.();let oe=Kt(ee);successResponse(w,200,AgentWriteSuccessSchema,{timestamp:J,...te?{summary:te}:{},...oe?{warning:oe,warnings:[oe]}:{}},{handler:`agent-write`})}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(w,e,`agent-write`);return}if(e instanceof FrontmatterMalformedError){respondFrontmatterMalformed(w,e,`agent-write`);return}if(e instanceof AgentSessionCapacityError){errorResponse(w,503,`urn:ok:error:too-many-agent-sessions`,`Too many agent sessions.`,{handler:`agent-write`,cause:e,extraHeaders:{"Retry-After":`10`}});return}log$6.error({err:e},`[agent-write] handler failed`),errorResponse(w,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-write`,cause:e})}},{handler:`agent-write`,method:`POST`}),ks=withValidation(AgentWriteMdRequestSchema,async(S,w,E)=>{try{let S=E.position??`append`,D=requireNonEmptyDocName(E.docName,w,`agent-write-md`);if(D===null)return;let O=Rt(D),{agentId:k,agentName:j,colorSeed:F,clientName:L,clientVersion:B,label:H}=Yi(E);if(isSystemDoc(O)||isConfigDoc(O)){errorResponse(w,400,`urn:ok:error:reserved-doc-name`,`'${O}' is a reserved document name.`,{handler:`agent-write-md`});return}E.extension!==void 0&&!docNameExistsWithAnySupportedExtension(g,O)&®isterDocExtension(O,E.extension);let q=normalizeSummary(E.summary),{response:ee,stored:J}=Zi(q),Y=await s.getSession(O,k,{displayName:j,colorSeed:F,clientName:L}),te=reconcileDiskBeforeAgentWrite(t,O,g,e.resolveEmbed),ne=new Date().toISOString(),ae;try{let t=iconFromClientName(L),s=AGENT_ICON_COLORS[t]??colorFromSeed(F??k);me?.setPresence(k,{displayName:j,icon:t,color:s,currentDoc:O,mode:`writing`,ts:Date.now()}),captureEffect(Y.dc.document.getText(`source`),k,F,L),Y.dc.document.transact(()=>{ae=applyAgentMarkdownWrite(Y.dc.document,E.markdown,S,e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:O}:void 0),Y.dc.document.getMap(`agent-flash`).set(k,{agentId:k,timestamp:Date.now(),type:`insert`,description:`Added (${j}): ${E.markdown.trim().slice(0,50)}`})},Y.origin),ae!==void 0&&console.warn(JSON.stringify({event:`agent-write-content-divergence`,"doc.name":O,position:S,intendedBytes:ae.intendedBytes,actualBytes:ae.actualBytes,byteDelta:ae.byteDelta,"agent.id":k,"agent.client_name":L})),recordContentDivergenceGate(`agent-write-md`,ae),recordContributor(O,k,j,F,void 0,Xi({clientName:L,clientVersion:B,label:H}),J),incrementAgentWriteCalls(),_s(q)}finally{me?.touchMode(k,`idle`)}let oe=await Ht(O);if(oe?.kind===`failure`){Ut(w,oe.failure,`agent-write-md`);return}if(oe?.kind===`divergence`){Wt(w,`agent-write-md`);return}Vt(O,`agent-write-md`),fe?.setFocus(k,{agentName:j,currentDoc:O,writeKind:`write`,ts:Date.now()}),ge?.();let se=Lt(O),ce=Y.dc.document.getText(`source`).toString();Mr(O,ce);let ue=await validateMermaidFences(ce,O),de=en();de.add(O);let _e=computeBrokenOutboundLinks(ce,O,de,jr),ve=zt(O),ye=Bt();ye===0&&hintEmittedCounter().add(1,{"shadow.writer":`agent`,"agent.type":resolveAgentType(L)});let Ce=Kt(te),we=ae===void 0?void 0:toContentDivergenceWarning(ae),Te=[...we?[we]:[],...Ce?[Ce]:[],...ue??[]];successResponse(w,200,AgentWriteMdSuccessSchema,{timestamp:ne,subscriberCount:ve,systemSubscriberCount:ye,...se?{hints:se}:{},...ee?{summary:ee}:{},...we?{warning:we}:Ce?{warning:Ce}:{},...Te.length>0?{warnings:Te}:{},brokenLinks:_e},{handler:`agent-write-md`})}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(w,e,`agent-write-md`);return}if(e instanceof FrontmatterMalformedError){respondFrontmatterMalformed(w,e,`agent-write-md`);return}if(e instanceof AgentSessionCapacityError){errorResponse(w,503,`urn:ok:error:too-many-agent-sessions`,`Too many agent sessions.`,{handler:`agent-write-md`,cause:e,extraHeaders:{"Retry-After":`10`}});return}log$6.error({err:e},`[agent-write-md] handler failed`),errorResponse(w,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-write-md`,cause:e})}},{handler:`agent-write-md`,method:`POST`}),As=withValidation(FrontmatterPatchRequestSchema,async(S,w,E)=>{try{let S=requireNonEmptyDocName(E.docName,w,`frontmatter-patch`);if(S===null)return;let D=Rt(S),{agentId:O,agentName:k,colorSeed:j,clientName:F,clientVersion:L,label:B}=Yi(E);if(isSystemDoc(D)||isConfigDoc(D)){errorResponse(w,400,`urn:ok:error:reserved-doc-name`,`'${D}' is a reserved document name.`,{handler:`frontmatter-patch`});return}let H=E.patch??{},q=Object.keys(H),ee=normalizeSummary(E.summary),{response:J,stored:Y}=Zi(ee),te=await s.getSession(D,O,{displayName:k,colorSeed:j,clientName:F}),ne=reconcileDiskBeforeAgentWrite(t,D,g,e.resolveEmbed),ae=new Date().toISOString(),oe,se=!1,ce=!1,ue=[];try{let e=iconFromClientName(F),t=AGENT_ICON_COLORS[e]??colorFromSeed(j??O);me?.setPresence(O,{displayName:k,icon:e,color:t,currentDoc:D,mode:`writing`,ts:Date.now()}),withSpanSync(`ok.frontmatter_patch`,{attributes:{"doc.name":D,"frontmatter_patch.keys":q.length}},()=>{te.dc.document.transact(()=>{let{fenced:e,body:t}=detectFmRegion(te.dc.document.getText(`source`).toString()),s=applyPatchToFm(e,H);if(!s.ok){oe=s.error;return}for(let e of Object.keys(H))ue.push(e);if(s.nextFenced!==e){let g=e===``&&t!==``&&!t.startsWith(`
|
|
1939
1939
|
`),S=s.nextFenced+(g?`
|
|
1940
|
-
`:``)+t;composeAndWriteRawBody(te.dc.document,S,`agent`),recordFrontmatterEditSurface(`mcp-write`),ce=!0}se=!0},te.origin)})}finally{me?.touchMode(O,`idle`)}if(oe){let e;switch(oe.kind){case`invalid_value`:e={[oe.key]:oe.reason};break;case`reserved_key`:e={[oe.key]:`'${oe.key}' is reserved`};break;case`unknown_key`:e={[oe.key]:`'${oe.key}' is not a recognized key`};break;case`duplicate_target`:e={[oe.key]:`'${oe.key}' appears more than once`};break;case`reorder_mismatch`:e={__region__:`frontmatter reorder mismatch (expected: ${oe.expected.join(`, `)}; got: ${oe.got.join(`, `)})`};break;case`region_too_large`:e={__region__:`frontmatter region too large (${oe.bytes} > ${oe.limit} bytes)`};break;case`parse_failed`:e={__region__:`frontmatter region unparseable: ${oe.reason}`};break;case`invalid_path`:e={[oe.path.map(String).join(`.`)||`__path__`]:oe.reason};break;default:e={__region__:`unhandled frontmatter edit error (${String(oe)})`}}errorResponse(w,400,`urn:ok:error:invalid-frontmatter-patch`,`Frontmatter patch rejected: schema validation failed.`,{handler:`frontmatter-patch`,extensions:{fieldErrors:e}});return}if(se&&ue.length>0){if(recordContributor(D,O,k,j,void 0,Ki({clientName:F,clientVersion:L,label:B}),Y),incrementAgentWriteCalls(),Zi(ee),ce){let e=await Ht(D);if(e?.kind===`failure`){Ut(w,e.failure,`frontmatter-patch`);return}if(e?.kind===`divergence`){Wt(w,`frontmatter-patch`);return}}Vt(D,`frontmatter-patch`)}fe?.setFocus(O,{agentName:k,currentDoc:D,writeKind:`write`,ts:Date.now()}),ge?.();let de=zt(D),_e=Bt();_e===0&&hintEmittedCounter().add(1,{"shadow.writer":`agent`,"agent.type":resolveAgentType(F)});let ve=Kt(ne),ye=$t();ye.add(D);let Ce=computeBrokenOutboundLinks(te.dc.document.getText(`source`).toString(),D,ye,en);successResponse(w,200,FrontmatterPatchSuccessSchema,{timestamp:ae,subscriberCount:de,systemSubscriberCount:_e,appliedKeys:ue,...J?{summary:J}:{},...ve?{warning:ve,warnings:[ve]}:{},brokenLinks:Ce},{handler:`frontmatter-patch`})}catch(e){if(e instanceof AgentSessionCapacityError){errorResponse(w,503,`urn:ok:error:too-many-agent-sessions`,`Too many agent sessions.`,{handler:`frontmatter-patch`,cause:e,extraHeaders:{"Retry-After":`10`}});return}log$6.error({err:e},`[frontmatter-patch] handler failed`),errorResponse(w,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`frontmatter-patch`,cause:e})}},{handler:`frontmatter-patch`,method:`POST`});function ks(e){let t=e.getMap(`lifecycle`),s=t.get(`status`);if(typeof s!=`string`||s.length===0)return null;let g=t.get(`reason`);return{status:s,reason:typeof g==`string`?g:``}}let As=withValidation(EmptyRequestSchema,async(e,s)=>{try{let S=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`docName`)||`test-doc`;if(!isSafeDocName(S)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`document-read`});return}let w=Rt(S);if(isSystemDoc(w)||isConfigDoc(w)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`'${w}' is a reserved document name.`,{handler:`document-read`});return}let E=t.documents.get(w);if(E){successResponse(s,200,DocumentReadSuccessSchema,{docName:w,content:E.getText(`source`).toString(),lifecycle:ks(E)},{handler:`document-read`});return}if(!existsSync(resolveContentEntryPath(g,`file`,w))){errorResponse(s,404,`urn:ok:error:doc-not-found`,`Document not found: ${w}.`,{handler:`document-read`});return}let D=await t.openDirectConnection(w);try{let e=D.document;if(!e){errorResponse(s,500,`urn:ok:error:doc-not-available`,`Document is not available.`,{handler:`document-read`});return}successResponse(s,200,DocumentReadSuccessSchema,{docName:w,content:e.getText(`source`).toString(),lifecycle:ks(e)},{handler:`document-read`})}finally{await D.disconnect()}}catch(e){errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to read document.`,{handler:`document-read`,cause:e})}},{handler:`document-read`,method:`GET`,skipBodyParse:!0}),Ns=withValidation(EmptyRequestSchema,async(e,t)=>{try{Me&&await Me.catch(e=>{log$6.warn({err:e,handler:`document-list`},`[api] ready gate rejected — responding with partial index`)});let s=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),S=s.searchParams.get(`dir`),D=s.searchParams.get(`showAll`)===`true`,O=s.searchParams.get(`depth`)===`1`?1:1/0;if(S)try{safeSubdir(g,S)}catch{errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid directory parameter.`,{handler:`document-list`});return}if(D&&Te&&showAllWantsNdjson(e)){let e=new AbortController;t.on(`close`,()=>{t.writableEnded||e.abort()}),t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let s=createStreamingErrorWriter(t,`document-list`),w=async e=>{t.writableEnded||t.destroyed||t.write(e)||await new Promise(e=>{let s=()=>{t.off(`drain`,s),t.off(`close`,s),e()};t.once(`drain`,s),t.once(`close`,s)})};try{let t=getShowAllMaxEntries(),s=streamShowAllEntries({contentDir:g,contentFilter:Te,dirFilter:S,getDocExtension,maxEntries:t,maxDepth:O,signal:e.signal}),E=0,D=await s.next();for(;!D.done;)await w(`${JSON.stringify(D.value)}\n`),E+=1,D=await s.next();let{truncated:k}=D.value;k&&log$6.info({handler:`document-list`,maxEntries:t,count:E},`[document-list][showAll] stream truncated at entry cap`),await w(`${JSON.stringify({type:`complete`,truncated:k,count:E})}\n`)}catch(e){!t.writableEnded&&!t.destroyed?s(500,`urn:ok:error:internal-server-error`,`Failed to list documents (showAll stream).`,{cause:e}):log$6.error({err:e,handler:`document-list`},`[document-list][showAll] stream failed after response ended`)}finally{t.writableEnded||t.end()}return}if(D&&Te){let e=`showAll:${O===1?`d1:`:``}${S??``}`,s=Ge.get(e);if(!s){let t=new AbortController,w=(async()=>{let e=[],s=getShowAllMaxEntries(),{truncated:w}=await walkContentDirForShowAll({contentDir:g,contentFilter:Te,dirFilter:S,documents:e,getDocExtension,maxEntries:s,maxDepth:O,signal:t.signal});return e.sort((e,t)=>{let s=e.kind===`folder`?e.path??``:e.docName??e.path??``,g=t.kind===`folder`?t.path??``:t.docName??t.path??``;return s.localeCompare(g)}),w&&log$6.info({handler:`document-list`,maxEntries:s,count:e.length},`[document-list][showAll] walk truncated at entry cap`),{documents:e,truncated:w}})();s={promise:w,controller:t,waiters:0};let E=s;Ge.set(e,E),w.finally(()=>{Ge.get(e)===E&&Ge.delete(e)})}let w=s;w.waiters+=1;let E=!1,D=()=>{t.writableEnded||E||(E=!0,--w.waiters,w.waiters<=0&&(w.controller.abort(),Ge.get(e)===w&&Ge.delete(e)))};t.on(`close`,D);try{let{documents:e,truncated:s}=await w.promise;if(E)return;successResponse(t,200,DocumentListSuccessSchema,s?{documents:e,truncated:s}:{documents:e},{handler:`document-list`})}catch(e){if(E)return;errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list documents (showAll mode).`,{handler:`document-list`,cause:e})}finally{t.removeListener(`close`,D)}return}let j=w(),F=E(),B=k?.()??new Map,H=[];for(let[e,t]of B)S&&!e.startsWith(`${S}/`)&&e!==S||H.push({kind:`folder`,path:e,size:0,modified:t.modified,docExt:`.md`,isSymlink:!1,canonicalDocName:null,targetPath:null});let q=[];try{let e=st(j);Xe?.signature!==e&&(Xe={signature:e,assets:collectReferencedAssets({contentDir:g,fileIndex:j,readMarkdown:e=>{try{return readFileSync(e,`utf-8`)}catch{return null}},isExcluded:Te?e=>Te.isPathIgnored(e):void 0})}),q=Xe?.assets??[]}catch(e){Xe=null,console.warn(`[document-list] asset collection failed; returning documents only:`,e)}let ee=new Set;for(let e of q)S&&!e.path.startsWith(`${S}/`)&&e.path!==S||(ee.add(e.path),H.push({kind:`asset`,docName:e.path,docExt:e.assetExt,path:e.path,assetExt:e.assetExt,mediaKind:e.mediaKind,referencedBy:e.referencedBy,size:e.size,modified:e.modified,isSymlink:!1,canonicalDocName:null,targetPath:null}));for(let[e,t]of F){if(t.kind===`markdown`){if(S&&!e.startsWith(`${S}/`)&&e!==S)continue;let s=getDocExtension(e);H.push({kind:`document`,docName:e,docExt:s,size:t.size,modified:t.modified,isSymlink:!1,canonicalDocName:null,targetPath:null});for(let w of t.aliases){if(S&&!w.startsWith(`${S}/`)&&w!==S)continue;let E=toPosix(relative(g,t.canonicalPath));H.push({kind:`document`,docName:w,docExt:s,size:t.size,modified:t.modified,isSymlink:!0,canonicalDocName:e,targetPath:E})}continue}if((!S||e===S||e.startsWith(`${S}/`))&&!ee.has(e)){let s=synthesizeShowAllAssetExt(e);H.push({kind:`file`,docName:e,path:e,docExt:`.${s}`,assetExt:s,size:t.size,modified:t.modified,isSymlink:!1,canonicalDocName:null,targetPath:null})}for(let s of t.aliases){if(!(!S||s===S||s.startsWith(`${S}/`))||ee.has(s))continue;let w=toPosix(relative(g,t.canonicalPath)),E=synthesizeShowAllAssetExt(s);H.push({kind:`file`,docName:s,path:s,docExt:`.${E}`,assetExt:E,size:t.size,modified:t.modified,isSymlink:!0,canonicalDocName:e,targetPath:w})}}let J=L?.()??new Map;if(J.size>0){let e=e=>!S||e===S||e.startsWith(`${S}/`),t=new Map;for(let[e,s]of J){let g=t.get(s);g?g.push(e):t.set(s,[e])}for(let[s,S]of t){let t=B.get(s),w=t?toPosix(relative(g,t.canonicalPath)):s;for(let g of S)e(g)&&H.push({kind:`folder`,path:g,size:0,modified:t?.modified??`1970-01-01T00:00:00.000Z`,docExt:`.md`,isSymlink:!0,canonicalDocName:s,targetPath:w})}let s=(s,g)=>{for(let S=s.indexOf(`/`);S!==-1;S=s.indexOf(`/`,S+1)){let w=t.get(s.slice(0,S));if(!w)continue;let E=s.slice(S);for(let t of w){let s=`${t}${E}`;e(s)&&g(s)}}};for(let[e,t]of B)s(e,s=>{H.push({kind:`folder`,path:s,size:0,modified:t.modified,docExt:`.md`,isSymlink:!0,canonicalDocName:e,targetPath:toPosix(relative(g,t.canonicalPath))})});for(let[e,t]of F)s(e,s=>{let S=toPosix(relative(g,t.canonicalPath));if(t.kind===`markdown`)H.push({kind:`document`,docName:s,docExt:getDocExtension(e),size:t.size,modified:t.modified,isSymlink:!0,canonicalDocName:e,targetPath:S});else{let g=synthesizeShowAllAssetExt(s);H.push({kind:`file`,docName:s,path:s,docExt:`.${g}`,assetExt:g,size:t.size,modified:t.modified,isSymlink:!0,canonicalDocName:e,targetPath:S})}})}H.sort((e,t)=>{let s=e.kind===`folder`?e.path??``:e.docName??e.path??``,g=t.kind===`folder`?t.path??``:t.docName??t.path??``;return s.localeCompare(g)}),successResponse(t,200,DocumentListSuccessSchema,{documents:H},{handler:`document-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list documents.`,{handler:`document-list`,cause:e})}},{handler:`document-list`,method:`GET`,skipBodyParse:!0}),Ps=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`backlinks`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!s){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`backlinks`});return}if(!isSafeDocName(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`backlinks`});return}successResponse(t,200,BacklinksSuccessSchema,{docName:s,backlinks:ce.getBacklinks(s).map(e=>({source:e.source,anchor:e.anchor,title:Dt(e.source),snippet:e.snippet}))},{handler:`backlinks`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read backlinks.`,{handler:`backlinks`,cause:e})}},{handler:`backlinks`,method:`GET`,skipBodyParse:!0}),Is=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`backlink-counts`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`docNames`);if(!s){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docNames parameter.`,{handler:`backlink-counts`});return}let g={};for(let e of s.split(`,`)){let t=e.trim();!t||!isSafeDocName(t)||(g[t]=ce.getBacklinkCount(t))}successResponse(t,200,BacklinkCountsSuccessSchema,{counts:g},{handler:`backlink-counts`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read backlink counts.`,{handler:`backlink-counts`,cause:e})}},{handler:`backlink-counts`,method:`GET`,skipBodyParse:!0}),Rs=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`forward-links`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!s){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`forward-links`});return}if(!isSafeDocName(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`forward-links`});return}let g=$t();successResponse(t,200,ForwardLinksSuccessSchema,{docName:s,forwardLinks:ce.getForwardLinkEntries(s).map(e=>e.kind===`doc`?{kind:`doc`,docName:e.target,anchor:e.anchor,title:jt(e.target,g),snippet:e.snippet}:{kind:`external`,url:e.url,title:e.label??e.url,snippet:e.snippet})},{handler:`forward-links`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read forward links.`,{handler:`forward-links`,cause:e})}},{handler:`forward-links`,method:`GET`,skipBodyParse:!0}),$s=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`link-graph`});return}try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`docName`);if(g&&!isSafeDocName(g)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`link-graph`});return}let S=s.searchParams.get(`degrees`);if(S&&!g){errorResponse(t,400,`urn:ok:error:invalid-request`,`docName is required when degrees is provided.`,{handler:`link-graph`});return}let w,E;if(S&&g){let e=Number.parseInt(S,10);if(!Number.isFinite(e)||e<0){errorResponse(t,400,`urn:ok:error:invalid-request`,`degrees must be a non-negative integer.`,{handler:`link-graph`});return}({nodes:w,links:E}=ce.getLinkGraphNeighborhood(g,e))}else ({nodes:w,links:E}=ce.getLinkGraph());let D=$t();successResponse(t,200,LinkGraphSuccessSchema,{nodes:w.map(e=>{if(e.kind===`doc`){let t=It(e.docName,D);return{id:e.id,kind:`doc`,docName:e.docName,anchor:e.anchor??null,label:jt(e.docName,D),cluster:t.cluster??null,category:t.category??null,tags:t.tags??null}}return{id:e.id,kind:`external`,url:e.url,label:e.label??e.url}}),links:E},{handler:`link-graph`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read link graph.`,{handler:`link-graph`,cause:e})}},{handler:`link-graph`,method:`GET`,skipBodyParse:!0}),ec=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`orphans`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`mode`)??`both`;if(!isOrphanMode(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid orphan mode. Allowed values: incoming, outgoing, both.`,{handler:`orphans`});return}successResponse(t,200,OrphansSuccessSchema,{orphans:ce.getOrphans([...w().keys()],s).map(e=>({docName:e,title:Dt(e)}))},{handler:`orphans`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read orphan pages.`,{handler:`orphans`,cause:e})}},{handler:`orphans`,method:`GET`,skipBodyParse:!0}),tc=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`hubs`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`limit`),g=s?Number.parseInt(s,10):20,S=Number.isFinite(g)&&g>0?g:20,w=$t();successResponse(t,200,HubsSuccessSchema,{hubs:ce.getHubs(S).map(e=>({docName:e.docName,title:jt(e.docName,w),count:e.count}))},{handler:`hubs`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read hub pages.`,{handler:`hubs`,cause:e})}},{handler:`hubs`,method:`GET`,skipBodyParse:!0}),nc=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`dead-links`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.getAll(`sourceDocName`);if(s.some(e=>e.length===0||!isSafeDocName(e))){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid sourceDocName.`,{handler:`dead-links`});return}let g=s.length?[...new Set(s.map(e=>Rt(e)))]:void 0;successResponse(t,200,DeadLinksSuccessSchema,{deadLinks:ce.getDeadLinks($t(),g).map(e=>({target:e.target,sources:e.sources.map(e=>({source:e.source,title:Dt(e.source),snippet:e.snippet}))}))},{handler:`dead-links`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read dead links.`,{handler:`dead-links`,cause:e})}},{handler:`dead-links`,method:`GET`,skipBodyParse:!0}),rc=withValidation(AgentPatchRequestSchema,async(S,w,E)=>{try{let{find:S,replace:D,offset:O}=E,k=requireNonEmptyDocName(E.docName,w,`agent-patch`);if(k===null)return;let j=Rt(k),{agentId:F,agentName:L,colorSeed:B,clientName:H,clientVersion:q,label:ee}=Gi(E);if(findLooksLikeFrontmatter(S)){agentPatchFmTouchCounter().add(1,{result:`rejected`}),errorResponse(w,400,`urn:ok:error:frontmatter-edit-not-supported`,`Frontmatter edits are not supported via a body find/replace. Use edit({ document: { path, frontmatter } }) to change frontmatter, or write({ document: { path, content, position: "replace" } }) to rewrite the whole document including its YAML block.`,{handler:`agent-patch`});return}if(isSystemDoc(j)||isConfigDoc(j)){errorResponse(w,400,`urn:ok:error:reserved-doc-name`,`'${j}' is a reserved document name.`,{handler:`agent-patch`});return}let J=normalizeSummary(E.summary),Y=await s.getSession(j,F,{displayName:L,colorSeed:B,clientName:H}),te=reconcileDiskBeforeAgentWrite(t,j,g,e.resolveEmbed),ne=new Date().toISOString(),ae=!1,oe=!1,se=!1,ce;try{let t=iconFromClientName(H),s=AGENT_ICON_COLORS[t]??colorFromSeed(B??F);if(me?.setPresence(F,{displayName:L,icon:t,color:s,currentDoc:j,mode:`writing`,ts:Date.now()}),captureEffect(Y.dc.document.getText(`source`),F,B,H),Y.dc.document.transact(()=>{let{frontmatter:t,body:s}=stripFrontmatter(Y.dc.document.getText(`source`).toString()),g=prependFrontmatter(t,s),w=O==null?g.indexOf(S):g.slice(O,O+S.length)===S?O:-1;if(w===-1){O==null?ae=!0:oe=!0,console.warn(JSON.stringify({event:`agent-patch-find-mismatch`,"doc.name":j,findLength:S.length,replaceLength:D.length,hadOffset:O!=null})),incrementAgentPatchFindMismatches();return}if(w<t.length){se=!0;return}let{body:E}=stripFrontmatter(g.slice(0,w)+D+g.slice(w+S.length));ce=applyAgentMarkdownWrite(Y.dc.document,E,`patch`,e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:j}:void 0),Y.dc.document.getMap(`agent-flash`).set(F,{agentId:F,timestamp:Date.now(),type:`insert`,description:`Patched (${L}): ${S.slice(0,50)}`})},Y.origin),ce!==void 0&&console.warn(JSON.stringify({event:`agent-write-content-divergence`,"doc.name":j,position:`patch`,intendedBytes:ce.intendedBytes,actualBytes:ce.actualBytes,byteDelta:ce.byteDelta,"agent.id":F,"agent.client_name":H})),!ae&&!oe&&!se){let{stored:e}=Yi(J);recordContributor(j,F,L,B,void 0,Ki({clientName:H,clientVersion:q,label:ee}),e),incrementAgentWriteCalls(),Zi(J),recordContentDivergenceGate(`agent-patch`,ce)}}finally{me?.touchMode(F,`idle`)}if(oe){errorResponse(w,409,`urn:ok:error:stale-target`,`Target text no longer matches at the requested offset.`,{handler:`agent-patch`});return}if(ae){errorResponse(w,404,`urn:ok:error:target-not-found`,`Text not found in document.`,{handler:`agent-patch`});return}if(se){agentPatchFmTouchCounter().add(1,{result:`rejected`}),errorResponse(w,400,`urn:ok:error:frontmatter-edit-not-supported`,`Frontmatter edits are not supported via a body find/replace. Use edit({ document: { path, frontmatter } }) to change frontmatter, or write({ document: { path, content, position: "replace" } }) to rewrite the whole document including its YAML block.`,{handler:`agent-patch`});return}let ue=await Ht(j);if(ue?.kind===`failure`){Ut(w,ue.failure,`agent-patch`);return}if(ue?.kind===`divergence`){Wt(w,`agent-patch`);return}Vt(j,`agent-patch`),fe?.setFocus(F,{agentName:L,currentDoc:j,writeKind:`edit`,ts:Date.now()}),ge?.();let de=zt(j),_e=Bt();_e===0&&hintEmittedCounter().add(1,{"shadow.writer":`agent`,"agent.type":resolveAgentType(H)});let{response:ve}=Yi(J),ye=Y.dc.document.getText(`source`).toString(),Ce=await validateMermaidFences(ye,j),we=$t();we.add(j);let Te=computeBrokenOutboundLinks(ye,j,we,en),De=Kt(te),je=ce===void 0?void 0:toContentDivergenceWarning(ce),Me=[...je?[je]:[],...De?[De]:[],...Ce??[]];successResponse(w,200,AgentPatchSuccessSchema,{timestamp:ne,subscriberCount:de,systemSubscriberCount:_e,...ve?{summary:ve}:{},...je?{warning:je}:De?{warning:De}:{},...Me.length>0?{warnings:Me}:{},brokenLinks:Te},{handler:`agent-patch`})}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(w,e,`agent-patch`);return}if(e instanceof FrontmatterMalformedError){respondFrontmatterMalformed(w,e,`agent-patch`);return}if(e instanceof AgentSessionCapacityError){errorResponse(w,503,`urn:ok:error:too-many-agent-sessions`,`Too many agent sessions.`,{handler:`agent-patch`,cause:e,extraHeaders:{"Retry-After":`10`}});return}log$6.error({err:e},`[agent-patch] handler failed`),errorResponse(w,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-patch`,cause:e})}},{handler:`agent-patch`,method:`POST`}),ic=withValidation(AgentUndoRequestSchema,async(t,g,S)=>{try{let t=requireNonEmptyDocName(S.docName,g,`agent-undo`);if(t===null)return;let w=Rt(t),{agentId:E,agentName:D,colorSeed:O,clientName:k,clientVersion:j,label:F}=Gi(S);if(isSystemDoc(w)||isConfigDoc(w)){errorResponse(g,400,`urn:ok:error:reserved-doc-name`,`'${w}' is a reserved document name.`,{handler:`agent-undo`});return}let{connectionId:L}=S,B=S.scope===`session`||S.scope===`file`?`session`:`last`;if(!s.hasSession(w,L)){errorResponse(g,404,`urn:ok:error:no-active-session`,`No active session for this connectionId and docName.`,{handler:`agent-undo`});return}let H=await s.getSession(w,L),q=!1;try{let t=iconFromClientName(k),s=AGENT_ICON_COLORS[t]??colorFromSeed(O??E);me?.setPresence(E,{displayName:D,icon:t,color:s,currentDoc:w,mode:`writing`,ts:Date.now()}),q=applyAgentUndo(H,B,e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:w}:void 0),q&&recordContributor(w,L,D,O,void 0,Ki({clientName:k,clientVersion:j,label:F}))}finally{me?.touchMode(E,`idle`)}if(q){let e=await Ht(w);if(e?.kind===`failure`){Ut(g,e.failure,`agent-undo`);return}if(e?.kind===`divergence`){Wt(g,`agent-undo`);return}Vt(w,`agent-undo`)}fe?.setFocus(L,{agentName:L,currentDoc:w,writeKind:`undo`,ts:Date.now()}),successResponse(g,200,AgentUndoSuccessSchema,{docName:w,scope:B,undone:q},{handler:`agent-undo`})}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(g,e,`agent-undo`);return}log$6.error({err:e},`[agent-undo] handler failed`),errorResponse(g,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-undo`,cause:e})}},{handler:`agent-undo`,method:`POST`}),ac=withValidation(EmptyRequestSchema,async(e,t)=>{try{let g=validateAgentId(new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`agentId`));if(g===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`agentId required (alphanumeric/_/- only).`,{handler:`agent-activity`});return}successResponse(t,200,AgentActivitySuccessSchema,listAgentActivity(s,g),{handler:`agent-activity`})}catch(e){log$6.error({err:e},`[agent-activity] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-activity`,cause:e})}},{handler:`agent-activity`,method:`GET`,skipBodyParse:!0}),oc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let g=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),S=validateAgentId(g.searchParams.get(`agentId`)),w=g.searchParams.get(`docName`),E=g.searchParams.get(`stackIndex`);if(S===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`agentId required (alphanumeric/_/- only).`,{handler:`agent-burst-diff`});return}if(!w||w.trim()===``){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`agent-burst-diff`});return}if(!isSafeDocName(w)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`agent-burst-diff`});return}let D=Rt(w);if(isSystemDoc(D)||isConfigDoc(D)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${D}' is a reserved document name.`,{handler:`agent-burst-diff`});return}if(!E||Number.isNaN(Number(E))){errorResponse(t,400,`urn:ok:error:invalid-request`,`StackIndex must be a number.`,{handler:`agent-burst-diff`});return}let O=Number(E);if(!Number.isInteger(O)||O<0){errorResponse(t,400,`urn:ok:error:invalid-request`,`stackIndex must be a non-negative integer.`,{handler:`agent-burst-diff`});return}let k=s.getLiveSession(D,S);if(!k){errorResponse(t,404,`urn:ok:error:no-active-session`,`No active session for this agentId and docName.`,{handler:`agent-burst-diff`});return}let j=k.um;if(O>=j.undoStack.length){errorResponse(t,404,`urn:ok:error:not-found`,`stackIndex ${O} out of range (stack has ${j.undoStack.length} items).`,{handler:`agent-burst-diff`});return}let F=j.undoStack[O];successResponse(t,200,AgentBurstDiffSuccessSchema,{diff:synthesizeStackItemDiffText(F,k.dc.document.getText(`source`),D),generatedAt:Date.now()},{handler:`agent-burst-diff`})}catch(e){log$6.error({err:e},`[agent-burst-diff] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-burst-diff`,cause:e})}},{handler:`agent-burst-diff`,method:`GET`,skipBodyParse:!0}),sc=withValidation(EmptyRequestSchema,async(e,t)=>{try{await ee?.(),successResponse(t,200,TestFlushGitSuccessSchema,{},{handler:`test-flush-git`})}catch(e){log$6.error({err:e},`[test-flush-git] flush failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`test-flush-git`,cause:e})}},{handler:`test-flush-git`,method:`POST`,skipBodyParse:!0}),cc=withValidation(EmptyRequestSchema,async(e,S)=>{try{let w=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),E=Rt(w.searchParams.get(`docName`)??`test-doc`),D;try{D=safeContentPath(E,g)}catch(e){log$6.error({err:e,docName:E},`[test-reset] safeContentPath rejected docName`),errorResponse(S,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`test-reset`,cause:e});return}await s.closeAll(E),t.closeConnections(E);let O=`onStoreDocument-${E}`;t.debouncer.isDebounced(O)&&await t.debouncer.executeNow(O);let k=t.documents.get(E);if(k&&await(je??t.unloadDocument.bind(t))(k),writeFileSync(D,``,`utf-8`),ce&&(ce.deleteDocument(E),ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist cache after test-reset for ${E}:`,e)}),de?.(`backlinks`),de?.(`graph`)),w.searchParams.get(`reset-okignore`)!==`false`)try{let e=resolve(g,`.okignore`),s=t.documents.get(CONFIG_DOC_NAME_OKIGNORE);if(s){let e=s.getText(`source`);e.length>0&&s.transact(()=>{e.delete(0,e.length)},CONFIG_VALIDATION_REVERT_ORIGIN)}existsSync(e)&&writeFileSync(e,``,`utf-8`),Te&&await Te.rebuildIgnorePatterns()}catch(e){console.warn(`[test-reset] okignore reset partial failure:`,e)}de?.(`files`),successResponse(S,200,TestResetSuccessSchema,{},{handler:`test-reset`})}catch(e){errorResponse(S,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`test-reset`,cause:e})}},{handler:`test-reset`,method:`POST`,skipBodyParse:!0}),lc=withValidation(EmptyRequestSchema,async(e,t)=>{try{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`test-rescan-backlinks`});return}await ce.rebuildFromDisk(),await ce.ingestGlobalSkillBundles([resolve($l,`.ok`,`skills`)]),ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist cache after test-rescan-backlinks:`,e)}),de?.(`backlinks`),de?.(`graph`),successResponse(t,200,TestRescanBacklinksSuccessSchema,{},{handler:`test-rescan-backlinks`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`test-rescan-backlinks`,cause:e})}},{handler:`test-rescan-backlinks`,method:`POST`,skipBodyParse:!0}),uc=withValidation(EmptyRequestSchema,async(e,t)=>{try{if(!B){errorResponse(t,503,`urn:ok:error:file-rescan-not-configured`,`Watcher rescan capability is not configured.`,{handler:`test-rescan-files`});return}await B(),de?.(`files`),successResponse(t,200,TestRescanFilesSuccessSchema,{},{handler:`test-rescan-files`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`test-rescan-files`,cause:e})}},{handler:`test-rescan-files`,method:`POST`,skipBodyParse:!0}),dc=withValidation(SaveVersionRequestSchema,async(e,t,s)=>{try{let{rawAgentId:e,agentId:g,agentName:S,clientName:w}=Gi(s),E=q?.current;if(!E){errorResponse(t,503,`urn:ok:error:shadow-not-configured`,`Shadow repo not configured.`,{handler:`save-version`});return}let D=/^[a-zA-Z0-9_-]+$/,O=[],k=!1;if(Array.isArray(s.writers))try{O=s.writers.map(e=>{let t=e.id??`unknown`;if(!D.test(t))throw Error(`Invalid writer id: ${t}`);return{id:t,name:(e.name??`unknown`).replace(/[\r\n]/g,``),email:(e.email??`noreply@openknowledge.local`).replace(/[\r\n]/g,``)}})}catch(e){errorResponse(t,400,`urn:ok:error:invalid-request`,e instanceof Error?e.message:`Invalid writer id.`,{handler:`save-version`,cause:e});return}let j=ae?.()??`main`;if(O.length===0)if(e!==void 0)O=[{id:g,name:w?`${S} (${w})`:S,email:`${g}@openknowledge.local`}];else{let e=(await enumerateWipChains(E,j)).filter(e=>!e.isPark);O=e.length>0?e.map(e=>({id:e.writerId,name:e.writerId,email:`${e.writerId}@openknowledge.local`})):[SERVICE_WRITER],k=!0}let F=se??`.`,L=normalizeSummary(typeof s.summary==`string`?s.summary:void 0),B=await saveVersion(E,F,O,j,L.kind===`value`?L.value:void 0,k?{includeUpstream:!1}:void 0);getLogger(`history`).info({checkpointRef:B.checkpointRef},`checkpoint`);try{await gcRenameLog(E,getOrLoadRenameLogIndex(E.gitDir))}catch(e){console.warn(`[rename-log] post-saveVersion GC failed:`,e)}successResponse(t,200,SaveVersionSuccessSchema,{checkpointRef:B.checkpointRef},{handler:`save-version`})}catch(e){log$6.error({err:e},`[save-version] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`save-version`,cause:e})}},{handler:`save-version`,method:`POST`}),fc=withValidation(EmptyRequestSchema,async(e,t)=>{let s=q?.current;if(!s){errorResponse(t,503,`urn:ok:error:shadow-not-configured`,`Shadow repo not configured.`,{handler:`history`});return}let g=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),S=g.searchParams.get(`docName`)??``,w=g.searchParams.get(`folder`),E=g.searchParams.get(`branch`)??ae?.()??`main`;if(!S&&w===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`A docName or folder query parameter is required.`,{handler:`history`});return}if(E.includes(`..`)||!/^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/.test(E)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid branch name.`,{handler:`history`});return}if(w!==null&&!S){let e=Ml(w,t,`folder`,`history`);if(!e)return;let S=Number(g.searchParams.get(`limit`)??`50`),D=Math.min(200,Number.isFinite(S)?S:50),O=Number(g.searchParams.get(`offset`)??`0`),k=Math.max(0,Number.isFinite(O)?O:0),j=`folder\0${E}\0${e.folderRel}\0${D}\0${k}`,{promise:F,coalesced:L}=Ke.run(j,()=>getFolderTimeline(s,e.folderRel,se??`.`,{branch:E,limit:D,offset:k}));L&&recordTimelineCoalesced(`folder`),successResponse(t,200,HistorySuccessSchema,{...await F},{handler:`history`});return}let D=se??`.`,O=safeDocPath(S,D);if(`error`in O){errorResponse(t,400,`urn:ok:error:invalid-request`,O.error,{handler:`history`});return}let k=Number(g.searchParams.get(`limit`)??`50`),j=Number(g.searchParams.get(`offset`)??`0`),F=Math.min(200,Number.isFinite(k)?k:50),L=Number.isFinite(j)?j:0,B=g.searchParams.get(`type`)??void 0,H=g.searchParams.get(`author`)??void 0,ee=g.searchParams.get(`excludeAuthor`)??void 0,J=g.searchParams.get(`includeAutoCheckpoints`)===`true`,Y=`doc\0${E}\0${S}\0${F}\0${L}\0${B??``}\0${H??``}\0${ee??``}\0${J?`1`:`0`}`,te=Date.now();try{let{promise:e,coalesced:g}=Ke.run(Y,()=>getDocumentHistory(s,{docName:S,branch:E,limit:F,offset:L,type:B,author:H,excludeAuthor:ee,includeAutoCheckpoints:J},D));g&&recordTimelineCoalesced(`doc`);let w=await e,O=Date.now()-te;getLogger(`timeline`).info({docName:S,entries:w.entries.length,durationMs:O},`query`),successResponse(t,200,HistorySuccessSchema,{...w},{handler:`history`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read history.`,{handler:`history`,cause:e})}},{handler:`history`,method:`GET`,skipBodyParse:!0});async function pc(e,t,s){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`history-version`,extraHeaders:{Allow:`GET`}});return}let g=q?.current;if(!g){errorResponse(t,503,`urn:ok:error:shadow-not-configured`,`Shadow repo not configured.`,{handler:`history-version`});return}let S=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`docName`)??``,w=se??`.`,E=safeDocPath(S,w);if(`error`in E){errorResponse(t,400,`urn:ok:error:invalid-request`,E.error,{handler:`history-version`});return}let D=shadowGit(g),O=ae?.()??`main`;if(!/^[0-9a-f]{40}$/i.test(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid commit SHA.`,{handler:`history-version`});return}try{let e=await resolveDocPathAtCommit(g,S,s,O,getOrLoadRenameLogIndex(g.gitDir),e=>{let t=safeDocPath(e,w);return`error`in t?`${e}.md`:t.path},createAncestorShaSetCache());if(e===null){errorResponse(t,404,`urn:ok:error:doc-not-found`,`Document did not exist at this version.`,{handler:`history-version`});return}let E=await D.raw(`show`,`${s}:${e}`),[k=``,j=``]=(await D.raw(`log`,`-1`,`--format=%aI%x00%an`,s)).trim().split(`\0`);successResponse(t,200,HistoryVersionSuccessSchema,{sha:s,content:E,timestamp:k,author:j},{handler:`history-version`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`history-version`,cause:e})}}let mc=withValidation(RollbackRequestSchema,async(s,g,S)=>{let w=extractActorIdentity(S,Ce);if(w.kind===`invalid-summary`){errorResponse(g,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`rollback`});return}let E=t.documents.get(S.docName);if(E&&isDocInConflict(E)){respondDocInConflict(g,new DocInConflictError({file:`${S.docName}${getDocExtension(S.docName)}`}),`rollback`);return}let D=q?.current;if(!D){errorResponse(g,503,`urn:ok:error:rollback-not-configured`,`Shadow repo not configured.`,{handler:`rollback`});return}let{docName:O,commitSha:k}=S,j=se??`.`,F=safeDocPath(O,j);if(`error`in F){errorResponse(g,400,`urn:ok:error:invalid-request`,F.error,{handler:`rollback`});return}let L=shadowGit(D),B=Date.now();try{let s=getOrLoadRenameLogIndex(D.gitDir),S=createAncestorShaSetCache(),E=await resolveDocPathAtCommit(D,O,k,ae?.()??`main`,s,e=>{let t=safeDocPath(e,j);return`error`in t?`${e}.md`:t.path},S);if(E===null){errorResponse(g,404,`urn:ok:error:doc-not-found`,`Commit ${k.slice(0,7)} does not contain document ${O} at any known historical path.`,{handler:`rollback`});return}let F=await L.raw(`show`,`${k}:${E}`),H=new Date().toISOString();await safetyCheckpoint(D,j,{action:`rollback`,context:{docName:O,targetSha:k}});let q=t.documents.get(O);if(!q){errorResponse(g,409,`urn:ok:error:doc-not-open`,`Document is not currently open — open it in the editor first.`,{handler:`rollback`});return}let ee=e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:O}:void 0,J;q.transact(()=>{replaceRawBody(q,F,ee),J=evaluateContentDivergence(q.getText(`source`).toString(),F,`rollback`)},ROLLBACK_ORIGIN),J!==void 0&&console.warn(JSON.stringify({event:`agent-write-content-divergence`,"doc.name":O,position:`rollback`,intendedBytes:J.intendedBytes,actualBytes:J.actualBytes,byteDelta:J.byteDelta,"actor.kind":w.kind,...w.kind===`agent`||w.kind===`principal`?{"actor.writer_id":w.writerId}:{}})),recordContentDivergenceGate(`rollback`,J);let Y;switch(w.kind){case`agent`:{let e=k.slice(0,8),t=w.summary.kind===`value`,s=t?w.summary:normalizeSummary(`Restored to ${e}`),g=Yi(s);Y=t||!g.response?g.response:Xi(g.response),recordContributor(O,w.writerId,w.displayName,w.colorSeed,formatRollbackSubject(O,k),w.actor,g.stored),incrementAgentWriteCalls(),Zi(s,!t);break}case`principal`:{let e=Yi(w.summary);Y=e.response,recordContributor(O,w.writerId,w.displayName,w.colorSeed,formatRollbackSubject(O,k),w.actor,e.stored),Zi(w.summary,!1);break}case`anonymous`:log$6.debug({docName:O,commitSha:k.slice(0,8)},`[rollback] anonymous actor — no contributor recorded (no agentId in body and getPrincipal() returned null)`);break;default:throw Error(`Unhandled actor kind in handleRollback: ${String(w.kind)}`)}renameAttributionCounter().add(1,{kind:`rollback`,attribution_kind:w.kind});let te=await Ht(O);if(te?.kind===`failure`){Ut(g,te.failure,`rollback`);return}if(te?.kind===`divergence`){Wt(g,`rollback`);return}Vt(O,`rollback`);let ne=Date.now()-B;getLogger(`rollback`).info({docName:O,from:k.slice(0,8),durationMs:ne},`rollback`),w.kind===`agent`&&fe?.setFocus(w.writerId,{agentName:w.displayName,currentDoc:O,writeKind:`rollback-apply`,ts:Date.now()});let oe=J===void 0?void 0:toContentDivergenceWarning(J);successResponse(g,200,RollbackSuccessSchema,{restoredFrom:k,timestamp:H,...Y?{summary:Y}:{},...oe?{warning:oe,warnings:[oe]}:{}},{handler:`rollback`})}catch(e){errorResponse(g,500,`urn:ok:error:internal-server-error`,`Failed to roll back.`,{handler:`rollback`,cause:e})}},{handler:`rollback`,method:`POST`}),hc=withValidation(EmptyRequestSchema,async(e,t)=>{try{successResponse(t,200,MetricsReconciliationSuccessSchema,getMetrics(),{handler:`metrics-reconciliation`})}catch(e){log$6.error({err:e},`[metrics-reconciliation] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`metrics-reconciliation`,cause:e})}},{handler:`metrics-reconciliation`,method:`GET`,skipBodyParse:!0}),gc=withValidation(EmptyRequestSchema,async(e,t)=>{try{successResponse(t,200,MetricsParseHealthSuccessSchema,getParseHealth(),{handler:`metrics-parse-health`})}catch(e){log$6.error({err:e},`[metrics-parse-health] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`metrics-parse-health`,cause:e})}},{handler:`metrics-parse-health`,method:`GET`,skipBodyParse:!0}),_c=withValidation(EmptyRequestSchema,async(e,t)=>{try{Me&&await Me.catch(e=>{log$6.warn({err:e,handler:`server-info`},`[api] ready gate rejected — responding with current state`)});let e=getActiveBranch(),s=oe?.();successResponse(t,200,ServerInfoSuccessSchema,{serverInstanceId:S,currentBranch:e,...s===void 0?{}:{currentDiskAckSVs:s}},{handler:`server-info`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`server-info`,cause:e})}},{handler:`server-info`,method:`GET`,skipBodyParse:!0});async function vc(e,t){if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`principal`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`principal`});return}if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`principal`,extraHeaders:{Allow:`GET`}});return}let s=Ce?.()??null;if(!s){errorResponse(t,404,`urn:ok:error:principal-not-available`,`Principal not available.`,{handler:`principal`});return}successResponse(t,200,PrincipalSuccessSchema,s,{handler:`principal`})}async function yc(e,t){if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`metrics-agent-presence`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`metrics-agent-presence`});return}if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`metrics-agent-presence`,extraHeaders:{Allow:`GET`}});return}try{let e=me?.getPresenceMap()??{},s=Date.now(),g={};for(let[t,S]of Object.entries(e))s-S.ts<2e4&&(g[t]=S);successResponse(t,200,MetricsAgentPresenceSuccessSchema,{presence:g},{handler:`metrics-agent-presence`})}catch(e){log$6.error({err:e},`[metrics-agent-presence] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`metrics-agent-presence`,cause:e})}}async function bc(e,t){if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`embed-detect`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`embed-detect`});return}if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`embed-detect`,extraHeaders:{Allow:`GET`}});return}let s=embedProbeRing.read();successResponse(t,200,EmbedDetectSuccessSchema,{entries:s,count:s.length,detection:deriveDetection(s[0])},{handler:`embed-detect`})}async function xc(e,t){if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`workspace`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`workspace`});return}if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`workspace`,extraHeaders:{Allow:`GET`}});return}let s=resolve(g),S=s,w=!0;try{S=realpathSync(s)}catch(e){let g=e?.code;if(g===`ENOENT`)console.warn(`[workspace] contentDir does not exist; returning unresolved path`,{path:s}),w=!1;else{console.warn(`[workspace] realpath failed for contentDir`,{path:s,err:e}),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Workspace realpath failed.`,{handler:`workspace`,detail:g??void 0,cause:e});return}}successResponse(t,200,WorkspaceSuccessSchema,{contentDir:S,pathSeparator:sep,symlinkResolved:w},{handler:`workspace`})}let Sc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`path`);if(!s||s.includes(`\0`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing asset path.`,{handler:`asset`});return}let S=assetContentTypeForPath(s),w=extname(s).slice(1).toLowerCase();if(!S||!ASSET_EXTENSIONS.has(w)){errorResponse(t,415,`urn:ok:error:unsupported-asset-type`,`Unsupported asset type.`,{handler:`asset`});return}let E=realpathSync(g),D=resolve(E,s),O;try{O=realpathSync(D)}catch{errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset`});return}if(!isWithinContentDir(O,E)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid asset path.`,{handler:`asset`});return}let k;try{k=statSync(O)}catch{errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset`});return}if(!k.isFile()){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset`});return}let j=toContentRelativePath(E,O);if(j!==s.split(`\\`).join(`/`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid asset path.`,{handler:`asset`});return}if(Te?.isPathIgnored(j)){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset`});return}let F=SANDBOXED_HTML_EXTENSIONS.has(w),L={"Content-Type":S,"Content-Length":String(k.size),"X-Content-Type-Options":`nosniff`,"Content-Disposition":INLINE_RENDERABLE_EXTENSIONS.has(w)||F?`inline`:`attachment`,"Cache-Control":`no-store`};w===`svg`?L[`Content-Security-Policy`]=`sandbox; default-src 'none'; style-src 'unsafe-inline'`:F&&(L[`Content-Security-Policy`]=SANDBOXED_HTML_CSP),t.writeHead(200,L);try{await pipeline(createReadStream(O),t)}catch(e){log$6.error({event:`api.asset.pipeline-failed`,handler:`asset`,assetPath:s,err:e},`[asset] pipeline failed mid-stream`),t.destroyed||t.destroy(e instanceof Error?e:void 0)}}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`asset`,cause:e})}},{handler:`asset`,method:`GET`,skipBodyParse:!0}),Cc=1048576,wc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`path`);if(!s||s.includes(`\0`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing asset path.`,{handler:`asset-text`});return}let S=realpathSync(g),w=resolve(S,s),E;try{E=realpathSync(w)}catch(e){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset-text`,cause:e});return}if(!isWithinContentDir(E,S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid asset path.`,{handler:`asset-text`});return}let D;try{D=statSync(E)}catch(e){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset-text`,cause:e});return}if(!D.isFile()){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset-text`});return}if(toContentRelativePath(S,E)!==s.split(`\\`).join(`/`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid asset path.`,{handler:`asset-text`});return}if(D.size>Cc){errorResponse(t,413,`urn:ok:error:payload-too-large`,`File exceeds the ${Cc}-byte text-viewer cap.`,{handler:`asset-text`});return}let O=(await readFile$1(E)).toString(`utf-8`);t.writeHead(200,{"Content-Type":`text/plain; charset=utf-8`,"X-Content-Type-Options":`nosniff`,"Content-Disposition":`inline`,"Cache-Control":`no-store`}),t.end(O)}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`asset-text`,cause:e})}},{handler:`asset-text`,method:`GET`,skipBodyParse:!0}),Tc=1440*60*1e3,Ec=withValidation(EmptyRequestSchema,async(e,t)=>{try{if(!q?.current){successResponse(t,200,RescueListSuccessSchema,[],{handler:`rescue-list`});return}let e=Date.now(),s=[],g=resolve(q.current.gitDir,`rescue`);if(existsSync(g))try{let t=readdirSync(g).filter(e=>isSupportedDocFile(e));for(let S of t){let t=resolve(g,S),w=statSync(t);if(e-w.mtimeMs>864e5){try{unlinkSync(t)}catch(e){console.debug(`[rescue] cleanup failed (non-critical):`,e)}continue}s.push({docName:stripDocExtension(S),timestamp:w.mtime.toISOString(),size:w.size,source:`flat`})}}catch(e){log$6.error({err:e},`[rescue] Failed to list flat-file rescue buffers`)}try{let e=ae?.()??`main`,t=await listRescueCheckpoints(q.current,e);for(let e of t)s.push({...e,source:`timeline`})}catch(e){log$6.error({err:e},`[rescue] Failed to list timeline-ref rescue checkpoints`)}successResponse(t,200,RescueListSuccessSchema,s,{handler:`rescue-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`rescue-list`,cause:e})}},{handler:`rescue-list`,method:`GET`,skipBodyParse:!0}),Dc=withValidation(CreatePageRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`create-page`});return}let S=s.path;if(!isSupportedDocFile(S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must end with .md or .mdx.`,{handler:`create-page`});return}if(S.includes(`..`)||S.startsWith(`/`)||S.includes(`\0`)||S.includes(`\\`)){errorResponse(t,400,`urn:ok:error:path-escape`,`Invalid path.`,{handler:`create-page`,detail:`path must not contain .. or start with /`});return}let w=resolve(g),E=resolve(w,S);if(!isWithinDir(E,w)){errorResponse(t,400,`urn:ok:error:path-escape`,`path must not escape content directory.`,{handler:`create-page`});return}let O=stripDocExtension(S);if(isSystemDoc(O)||isConfigDoc(O)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${O}' is a reserved document name.`,{handler:`create-page`});return}if(S.split(`/`)[0]===`.ok`||isManagedArtifactDocName(O)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${O}' is a reserved document name.`,{handler:`create-page`,detail:`Cannot create a page under .ok/ — skills and templates are authored through their own validating flows.`});return}let k=typeof s.template==`string`?s.template.trim():``,j=``,F;if(k.length>0){if(!/^[A-Za-z0-9_-]+$/.test(k)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Template name must match [A-Za-z0-9_-]+.`,{handler:`create-page`});return}let s=S.includes(`/`)?S.slice(0,S.lastIndexOf(`/`)):``,g=resolveTemplatesAvailable(w,s),E=g.find(e=>e.name===k);if(!E){let e=g.length===0?`(none)`:g.map(e=>`"${e.name}" (${e.scope})`).join(`, `);errorResponse(t,400,`urn:ok:error:invalid-request`,`Template "${k}" does not resolve for folder "${s||`(root)`}". Available: ${e}`,{handler:`create-page`});return}let D=resolve(w,E.path),O;try{O=readFileSync(D,`utf-8`)}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read template at ${E.path}.`,{handler:`create-page`,cause:e});return}let L=instantiateDoc(O),B=e.kind===`agent`||e.kind===`principal`?e.displayName??``:``;j=applySubstitution(L,{date:todayIsoUtc(),user:B}),F=E.scope}mkdirSync(dirname(E),{recursive:!0});try{writeFileSync(E,j,{encoding:`utf-8`,flag:`wx`})}catch(e){if(isAlreadyExistsError(e)){errorResponse(t,409,`urn:ok:error:doc-already-exists`,`File already exists.`,{handler:`create-page`,cause:e});return}throw e}let L=stripDocExtension(S);switch(Pe?.delete(L),Te&&Te.incrementMdDir(dirname(L)),registerWrite(E,contentHash(j)),e.kind){case`agent`:case`principal`:recordContributor(L,e.writerId,e.displayName,e.colorSeed,void 0,e.actor);break;case`anonymous`:break;default:throw Error(`Unhandled actor kind in handleCreatePage: ${String(e.kind)}`)}D?.({kind:`create`,path:E,docName:L,content:j}),ce&&(ce.updateDocumentFromMarkdown(L,j),ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist create-page cache for ${L}:`,e)}),de?.(`backlinks`),de?.(`graph`)),de?.(`files`),F!==void 0&&console.warn(JSON.stringify({event:`template-instantiate`,templateName:k,templateScope:F,docName:L})),successResponse(t,200,CreatePageSuccessSchema,{docName:L},{handler:`create-page`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to create page.`,{handler:`create-page`,cause:e})}},{handler:`create-page`,method:`POST`}),Oc=withValidation(CreateFolderRequestSchema,async(e,t,s)=>{try{if(extractActorIdentity(s,Ce).kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`create-folder`});return}let e=s.path;if(!isValidRelativeContentPath(e)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`create-folder`});return}if(e===`.ok`||e.startsWith(`.ok/`)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'.ok' is a reserved directory.`,{handler:`create-folder`});return}if(Te?.isDirExcluded(e)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Destination folder is excluded by the workspace content config.`,{handler:`create-folder`});return}let S=resolveContentEntryPath(g,`folder`,e);if(existsSync(S)){errorResponse(t,409,`urn:ok:error:doc-already-exists`,`Folder already exists.`,{handler:`create-folder`});return}tracedMkdirSync(S,{recursive:!0}),rt(e),de?.(`files`),successResponse(t,200,CreateFolderSuccessSchema,{path:e},{handler:`create-folder`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to create folder.`,{handler:`create-folder`,cause:e})}},{handler:`create-folder`,method:`POST`}),kc=withValidation(DuplicatePathRequestSchema,async(e,s,S)=>{try{let e=extractActorIdentity(S,Ce);if(e.kind===`invalid-summary`){errorResponse(s,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`duplicate-path`});return}let{kind:w}=S,E=w===`file`?stripDocExtension(S.path):S.path;if(!isValidRelativeContentPath(E)){errorResponse(s,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`duplicate-path`});return}if(E===`.ok`||E.startsWith(`.ok/`)||w===`file`&&(isSystemDoc(E)||isConfigDoc(E))||w===`folder`&&isReservedSyntheticFolderPath(E)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`Reserved paths cannot be duplicated.`,{handler:`duplicate-path`});return}w===`file`&&probeAndRegisterSourceFileExtension(g,E);let O=resolveContentEntryPath(g,w,E);if(!existsSync(O)){if(w===`file`){let e=resolveContentEntryPath(g,`folder`,E);if(existsSync(e)&&statSync(e).isDirectory()){errorResponse(s,400,`urn:ok:error:invalid-request`,`Target path is not a ${w}.`,{handler:`duplicate-path`});return}}errorResponse(s,404,`urn:ok:error:doc-not-found`,`${w} does not exist.`,{handler:`duplicate-path`});return}let k=statSync(O);if(w===`file`&&!k.isFile()||w===`folder`&&!k.isDirectory()){errorResponse(s,400,`urn:ok:error:invalid-request`,`Target path is not a ${w}.`,{handler:`duplicate-path`});return}let j=w===`file`?[E]:Zr(resolveContentEntryPath(g,`folder`,E)),F=_e?.(),L=new Set(F?F.getConflicts().map(e=>e.file):[]);for(let e of j){let g=stripDocExtension(e),S=t.documents.get(g),w=`${g}${getDocExtension(g)}`,E=S!==void 0&&isDocInConflict(S),D=L.has(w);if(E||D){respondDocInConflict(s,new DocInConflictError({file:w}),`duplicate-path`);return}}let B,H=[];if(w===`file`){let e=extname(O);if(B=nextAvailableDuplicateDocName(g,E).docName,isSystemDoc(B)||isConfigDoc(B)||Te?.isExcluded(`${B}${e}`)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Duplicated document destination is excluded by the project content config.`,{handler:`duplicate-path`});return}let t=resolveDuplicateDocPath(g,B,e),S=readFileSync(O,`utf-8`),w=dirname(t),k=existsSync(w);try{tracedMkdirSync(w,{recursive:!0}),tracedWriteFileSync(t,S,{encoding:`utf-8`,flag:`wx`})}catch(e){if(isAlreadyExistsError(e)){errorResponse(s,409,`urn:ok:error:doc-already-exists`,`A file at the duplicate destination already exists.`,{handler:`duplicate-path`,cause:e});return}if(!k)try{tracedRmdirSync(w)}catch(e){let t=e.code;t!==`ENOENT`&&t!==`ENOTEMPTY`&&console.warn(`[duplicate-path] failed to clean duplicate parent directory:`,{destinationDir:w,err:e})}throw e}let j=!1;try{registerDocExtension(B,e),Pe?.delete(B),Te&&(Te.incrementMdDir(dirname(B)),j=!0),registerWrite(t,contentHash(S)),D?.({kind:`create`,path:t,docName:B,content:S}),ce?.updateDocumentFromMarkdown(B,S),H=[B]}catch(e){try{tracedRmSync(t,{force:!0})}catch(e){console.warn(`[duplicate-path] failed to clean partial file duplicate:`,{destinationPath:t,err:e})}throw forgetDocExtension(B),Te&&j&&Te.decrementMdDir(dirname(B)),D?.({kind:`delete`,path:t,docName:B}),e}}else{if(B=nextAvailableDuplicateFolderPath(g,E).folderPath,Te?.isDirExcluded(B)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Duplicated folder destination is excluded by the project content config.`,{handler:`duplicate-path`});return}let e=resolveContentEntryPath(g,`folder`,B);try{tracedCpSync(O,e,{recursive:!0,errorOnExist:!0,force:!1})}catch(e){if(isAlreadyExistsError(e)){errorResponse(s,409,`urn:ok:error:doc-already-exists`,`A folder at the duplicate destination already exists.`,{handler:`duplicate-path`,cause:e});return}throw e}try{for(let e of collectFolderPaths(g,B))rt(e);let e=collectMarkdownCopies(g,B);H=e.map(e=>e.docName);for(let t of e){let e=extname(t.fullPath);registerDocExtension(t.docName,e),Pe?.delete(t.docName),Te&&Te.incrementMdDir(dirname(t.docName)),registerWrite(t.fullPath,contentHash(t.content)),D?.({kind:`create`,path:t.fullPath,docName:t.docName,content:t.content}),ce?.updateDocumentFromMarkdown(t.docName,t.content)}}catch(t){try{tracedRmSync(e,{recursive:!0,force:!0})}catch(t){console.warn(`[duplicate-path] failed to clean partial folder duplicate:`,{destinationPath:e,err:t})}throw t}}switch(e.kind){case`agent`:case`principal`:for(let t of H)recordContributor(t,e.writerId,e.displayName,e.colorSeed,void 0,e.actor);break;case`anonymous`:break;default:throw Error(`Unhandled actor kind in handleDuplicatePath: ${String(e.kind)}`)}ce&&H.length>0&&(ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist duplicate-path cache:`,e)}),de?.(`backlinks`),de?.(`graph`)),de?.(`files`),successResponse(s,200,DuplicatePathSuccessSchema,{kind:w,path:B,duplicatedDocNames:H},{handler:`duplicate-path`})}catch(e){if(e instanceof DuplicateNameExhaustedError){errorResponse(s,409,`urn:ok:error:doc-already-exists`,`All available duplicate name slots are occupied for this path.`,{handler:`duplicate-path`,cause:e});return}let t=classifyDuplicatePathFilesystemProblem(e);if(t){errorResponse(s,t.status,t.type,t.title,{handler:`duplicate-path`,cause:e});return}errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to duplicate path.`,{handler:`duplicate-path`,cause:e})}},{handler:`duplicate-path`,method:`POST`}),Ac=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!s||s.length===0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docName query parameter.`,{handler:`page-headings`});return}if(!isSafeDocName(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`page-headings`});return}let g=Et(s);if(!g){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`page-headings`});return}if(!existsSync(g)){errorResponse(t,404,`urn:ok:error:doc-not-found`,`Page not found.`,{handler:`page-headings`});return}successResponse(t,200,PageHeadingsSuccessSchema,{docName:s,headings:extractHeadings(readFileSync(g,`utf-8`))},{handler:`page-headings`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read headings.`,{handler:`page-headings`,cause:e})}},{handler:`page-headings`,method:`GET`,skipBodyParse:!0}),jc=withValidation(RenamePathRequestSchema,async(e,s,S)=>{try{let e=extractActorIdentity(S,Ce);if(e.kind===`invalid-summary`){errorResponse(s,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`rename-path`});return}let{kind:w,fromPath:E,toPath:D}=S;if(!isValidRelativeContentPath(E)||!isValidRelativeContentPath(D)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Paths must be relative content paths.`,{handler:`rename-path`});return}if(w===`file`&&(isSystemDoc(E)||isSystemDoc(D)||isConfigDoc(E)||isConfigDoc(D))){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`Reserved document names cannot be renamed.`,{handler:`rename-path`});return}if(E===`.ok`||E.startsWith(`.ok/`)||D===`.ok`||D.startsWith(`.ok/`)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`.ok is a reserved directory.`,{handler:`rename-path`});return}if(E===D){successResponse(s,200,RenamePathSuccessSchema,{renamed:[],renamedAssets:[],rewrittenDocs:[]},{handler:`rename-path`});return}let O=w===`asset`&&isSupportedDocFile(E)&&isSupportedDocFile(D)?`file`:w;if(O===`asset`){let t;try{t=isSupportedDocFile(E)&&!isSupportedDocFile(D)?await Hi(E,D):await ji(E,D)}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(s,e,`rename-path`);return}let{status:t,type:g,error:S}=Ir(e);errorResponse(s,t,g,S,{handler:`rename-path`,cause:e});return}t.renamedAssets.length>0&&vt();let g;if(t.renamedAssets.length>0&&t.rewrittenDocs.length>0){let s=`Renamed asset ${E} → ${D}`;g=ka(e,s,t.rewrittenDocs.map(({docName:e})=>({docName:e,subject:s})),{context:`handleRenamePath asset branch`,onAnonymous:()=>{log$6.debug({kind:`asset`,fromPath:E,toPath:D,affectedDocs:t.rewrittenDocs.length,affectedAssets:t.renamedAssets.length},`[rename-path] anonymous actor; no contributor recorded (no agentId in body and getPrincipal() returned null)`)}})}if(renameAttributionCounter().add(1,{kind:`rename-asset`,attribution_kind:e.kind}),J)try{await J()}catch(e){console.warn(`[rename-path] flushContributors failed after asset rename (commitSha backfill may be deferred):`,e)}successResponse(s,200,RenamePathSuccessSchema,{renamed:[],renamedAssets:t.renamedAssets,rewrittenDocs:t.rewrittenDocs,...g?{summary:g}:{}},{handler:`rename-path`});return}let k=O===`file`?[stripDocExtension(E)]:Zr(resolveContentEntryPath(g,`folder`,E)),j=_e?.(),F=new Set(j?j.getConflicts().map(e=>e.file):[]);for(let e of k){let g=stripDocExtension(e),S=t.documents.get(g),w=O===`file`?E:`${g}${getDocExtension(e)}`,D=S!==void 0&&isDocInConflict(S),k=F.has(w);if(D||k){respondDocInConflict(s,new DocInConflictError({file:w}),`rename-path`);return}}if(O===`file`&&probeAndRegisterSourceFileExtension(g,E),Te&&(O===`file`?Te.isExcluded(isSupportedDocFile(D)?D:`${D}${getDocExtension(E)}`):Te.isDirExcluded(D))){errorResponse(s,400,`urn:ok:error:invalid-request`,`Destination ${O===`file`?`document`:`folder`} is excluded by the project content config.`,{handler:`rename-path`});return}let L=e.kind===`agent`||e.kind===`principal`?{writerId:e.writerId,displayName:e.displayName,colorSeed:e.colorSeed,actorMetadata:e.actor}:void 0,B;try{B=await Ui(E,D,O,L?{actor:L}:{})}catch(e){if(e instanceof ManagedRenameCollisionError){errorResponse(s,409,`urn:ok:error:doc-already-exists`,Fr(e.message),{handler:`rename-path`,extensions:{colliding:e.colliding},cause:e});return}throw e}if(B.renamed.length===0&&B.renamedAssets.length===0){successResponse(s,200,RenamePathSuccessSchema,{renamed:[],renamedAssets:[],rewrittenDocs:[]},{handler:`rename-path`});return}B.renamedAssets.length>0&&vt();let H,q=B.renamed.filter(({fromDocName:e,toDocName:t})=>e!==t);if(q.length>0&&(H=ka(e,`Renamed ${E} → ${D}`,q.map(({fromDocName:e,toDocName:t})=>({docName:t,subject:formatRenameSubject(e,t)})),{context:`handleRenamePath`,onAnonymous:()=>{log$6.debug({kind:w,fromPath:E,toPath:D,affectedDocs:B.renamed.length},`[rename-path] anonymous actor — no contributor recorded (no agentId in body and getPrincipal() returned null)`)}})),renameAttributionCounter().add(1,{kind:`rename-${O}`,attribution_kind:e.kind}),J)try{await J()}catch(e){console.warn(`[rename-path] flushContributors failed (commitSha backfill may be deferred):`,e)}successResponse(s,200,RenamePathSuccessSchema,{renamed:B.renamed,renamedAssets:B.renamedAssets,rewrittenDocs:B.rewrittenDocs,...H?{summary:H}:{}},{handler:`rename-path`})}catch(e){let{status:t,type:g,error:S}=Ir(e);errorResponse(s,t,g,S,{handler:`rename-path`,cause:e})}},{handler:`rename-path`,method:`POST`}),Mc=withValidation(DeletePathRequestSchema,async(e,s,S)=>{try{Gi(S);let{kind:e,path:w}=S;if(!isValidRelativeContentPath(w)){errorResponse(s,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`delete-path`});return}let E=e===`asset`?Xr(w):{path:w,ambiguous:!1};if(E.ambiguous){errorResponse(s,400,`urn:ok:error:invalid-request`,`Asset path without an extension matches multiple files.`,{handler:`delete-path`});return}let O=E.path,k=e===`asset`&&isSupportedDocFile(O)?`file`:e;if(k===`file`&&probeAndRegisterSourceFileExtension(g,O),k===`asset`&&isReservedProjectStatePath(O)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`.ok and .git are reserved directories.`,{handler:`delete-path`});return}let j=k===`asset`?resolveContentEntryPath(g,`folder`,O):resolveContentEntryPath(g,k,O);if(!existsSync(j)){errorResponse(s,404,`urn:ok:error:doc-not-found`,`${k} does not exist.`,{handler:`delete-path`});return}let F=statSync(j);if(k===`file`&&!F.isFile()||k===`asset`&&!F.isFile()||k===`folder`&&!F.isDirectory()){errorResponse(s,400,`urn:ok:error:invalid-request`,`Target path is not a ${k}.`,{handler:`delete-path`});return}let L=k===`asset`?[]:k===`file`?[stripDocExtension(O)]:Zr(resolveContentEntryPath(g,`folder`,O)),B=_e?.(),H=new Set(B?B.getConflicts().map(e=>e.file):[]);for(let e of L){let g=stripDocExtension(e),S=t.documents.get(g),w=k===`file`&&isSupportedDocFile(O)?O:`${g}${getDocExtension(g)}`,E=S!==void 0&&isDocInConflict(S),D=H.has(w);if(E||D){respondDocInConflict(s,new DocInConflictError({file:w}),`delete-path`);return}}if(await Lr(L),Pe)for(let e of L)isSystemDoc(e)||isConfigDoc(e)||(Pe.setDeleted(e),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:e,kind:`deleted`,source:`handleDeletePath`})));k===`file`||k===`asset`?tracedUnlinkSync(j):(tracedRmSync(j,{recursive:!0,force:!1}),it(O)),vt();for(let e of L)D?.({kind:`delete`,path:resolve(g,`${e}${getDocExtension(e)}`),docName:e});de?.(`files`),successResponse(s,200,DeletePathSuccessSchema,{deletedDocNames:L},{handler:`delete-path`})}catch(e){errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to delete path.`,{handler:`delete-path`,cause:e})}},{handler:`delete-path`,method:`POST`}),Nc=withValidation(TrashCleanupRequestSchema,async(e,t,s)=>withSpan(`ok.fs.trash_cleanup`,{attributes:{"ok.cleanup.kind":s.kind,"ok.cleanup.path":normalizeFsPath(s.path),"ok.cleanup.path.role":classifyFsPath(s.path)}},async()=>{try{if(extractActorIdentity(s,Ce).kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`trash-cleanup`});return}let{kind:e,path:S}=s;if(!isValidRelativeContentPath(S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`trash-cleanup`});return}let E=e===`asset`&&isSupportedDocFile(S)?`file`:e,O=stripDocExtension(S);E===`file`&&probeAndRegisterSourceFileExtension(g,S);let k=E===`folder`&&isReservedSyntheticFolderPath(S),j=E===`asset`&&isReservedProjectStatePath(S);if(E===`file`&&(isSystemDoc(O)||isConfigDoc(O))||k||j){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${S}' is a reserved document name.`,{handler:`trash-cleanup`});return}if(E===`asset`){vt(),de?.(`files`),successResponse(t,200,TrashCleanupSuccessSchema,{deletedDocNames:[]},{handler:`trash-cleanup`});return}let F=w(),L=E===`file`?F.has(O)?[O]:[]:listAffectedDocNames(F,E,S);if(vt(),L.length===0){successResponse(t,200,TrashCleanupSuccessSchema,{deletedDocNames:[]},{handler:`trash-cleanup`});return}if(await Lr(L),Pe)for(let e of L)isSystemDoc(e)||isConfigDoc(e)||(Pe.setDeleted(e),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:e,kind:`deleted`,source:`handleTrashCleanup`})));for(let e of L)D?.({kind:`delete`,path:resolve(g,`${e}${getDocExtension(e)}`),docName:e});E===`folder`&&it(S),de?.(`files`),successResponse(t,200,TrashCleanupSuccessSchema,{deletedDocNames:L},{handler:`trash-cleanup`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to clean up after trash.`,{handler:`trash-cleanup`,cause:e})}}),{handler:`trash-cleanup`,method:`POST`}),Pc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=w(),s=[];for(let[t,S]of e){let e=t,w,E=getDocExtension(t);try{let s=readFileSync(resolve(g,`${t}${E}`),`utf-8`);e=extractPageTitle(s,t),w=extractPageIcon(s)}catch(e){console.warn(`[pages] Failed to read title for ${t}:`,e)}s.push({docName:t,title:e,docExt:E,size:S.size,modified:S.modified,icon:w})}s.sort((e,t)=>e.docName.localeCompare(t.docName)),successResponse(t,200,PagesSuccessSchema,{pages:s},{handler:`pages`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list pages.`,{handler:`pages`,cause:e})}},{handler:`pages`,method:`GET`,skipBodyParse:!0}),Fc=withValidation(EmptyRequestSchema,async(e,s)=>{try{let g=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!g){errorResponse(s,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`suggest-links`});return}if(!isSafeDocName(g)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`suggest-links`});return}if(isSystemDoc(g)||isConfigDoc(g)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`'${g}' is a reserved document name.`,{handler:`suggest-links`});return}successResponse(s,200,SuggestLinksSuccessSchema,await suggestLinks({hocuspocus:t,fileIndex:w(),docName:g}),{handler:`suggest-links`})}catch(e){if(e instanceof SuggestLinksTargetNotFoundError){errorResponse(s,404,`urn:ok:error:doc-not-found`,`Page not found.`,{handler:`suggest-links`,cause:e});return}errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to suggest links.`,{handler:`suggest-links`,cause:e})}},{handler:`suggest-links`,method:`GET`,skipBodyParse:!0});async function Ic(e,t){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`upload-asset`,extraHeaders:{Allow:`POST`}});return}let s;try{s=await readUploadBody(e,ye??g)}catch(e){if(e instanceof UploadWriteError){errorResponse(t,uploadStatusFor(e.reason),e.reason,uploadTitleFor(e.reason),{handler:`upload-asset`,cause:e});return}errorResponse(t,400,`urn:ok:error:malformed-upload`,`Failed to parse upload.`,{handler:`upload-asset`,cause:e});return}let{filename:S,tempPath:w,sha:E,byteLength:D,parentDocName:O}=s,k=()=>{if(existsSync(w))try{unlinkSync(w)}catch{}},j=validateBody(UploadRequestSchema,{parentDocName:O},t,{handler:`upload-asset`});if(!j.ok){k();return}let{parentDocName:F}=j.value,{agentId:L,agentName:B}=Gi(Object.fromEntries(new URL(e.url??``,`http://localhost`).searchParams.entries()));if(D===0){k(),errorResponse(t,400,`urn:ok:error:no-file-received`,`No file received.`,{handler:`upload-asset`});return}if(F.includes(`\0`)||F.includes(`..`)||F.startsWith(`/`)){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}let H=resolve(g),q=resolveUploadDestDir(F,`./`,H);if(!isWithinContentDir(q,H)){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}try{assertNoSymlinkEscape(q,H)}catch(e){if(k(),(e instanceof Error?e.message:String(e)).startsWith(`symlink-escape:`)){errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}log$6.error({err:e,destDir:q},`[upload] failed to validate destination directory`),errorResponse(t,500,`urn:ok:error:storage-error`,`Storage error.`,{handler:`upload-asset`,cause:e});return}try{mkdirSync(q,{recursive:!0})}catch(e){if(!isAlreadyExistsError(e)){k();let s=classifyUploadErrno(e);errorResponse(t,uploadStatusFor(s),s,uploadTitleFor(s),{handler:`upload-asset`,cause:e,detail:`failed to create attachment directory`});return}}try{let e=realpathSync(q),s;try{s=realpathSync(H)}catch{s=H}if(!isWithinContentDir(e,s)){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}}catch(e){if(e.code!==`ENOENT`){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`,cause:e});return}}let ee=await fileTypeFromFile(w),J=ee?.mime,Y=ee?.ext;if(!J){let e=readTempFileHead(w,256).toString(`utf-8`).replace(/^/,``).trimStart();(e.startsWith(`<svg`)||e.startsWith(`<?xml`)&&e.includes(`<svg`))&&(J=`image/svg+xml`,Y=`svg`)}{let s=await findDuplicateAsset(q,E,D);if(s){k();let S=toPosix(relative(g,resolve(q,s)));log$6.info({event:`upload`,endpoint:e.url??`/api/upload`,agentId:L,agentName:B,dedup:!0,mime:J??null,size:D,destPath:S,httpStatus:200},`[upload] dedup hit`),successResponse(t,200,UploadAssetSuccessSchema,{src:s,path:S,deduped:!0},{handler:`upload-asset`});return}}let te;if(!S||S===`upload`||GENERIC_PASTE_NAMES.test(S)){let e=new Date().toISOString().replace(/[-:T]/g,``).slice(0,14).replace(/(\d{8})(\d{6})/,`$1-$2`),t=S?extname(S).slice(1):``,s=Y??t??``;te=s===``?`pasted-${e}`:`pasted-${e}.${s}`}else te=sanitizeFilename(S);try{let s=linkTempToFinalWithCollisionRetry(w,q,te),S=toPosix(relative(g,resolve(q,s)));log$6.info({event:`upload`,endpoint:e.url??`/api/upload`,agentId:L,agentName:B,dedup:!1,mime:J??null,size:D,destPath:S,httpStatus:200},`[upload] write ok`),successResponse(t,200,UploadAssetSuccessSchema,{src:s,path:S,deduped:!1},{handler:`upload-asset`})}catch(s){let g=s instanceof UploadWriteError?s.reason:`urn:ok:error:storage-error`;log$6.error({event:`upload`,endpoint:e.url??`/api/upload`,agentId:L,agentName:B,filename:te,size:D,reason:g,httpStatus:uploadStatusFor(g),err:s},`[upload] write failed`),errorResponse(t,uploadStatusFor(g),g,uploadTitleFor(g),{handler:`upload-asset`,cause:s})}}let Lc=`/api/local-op/clone`,Rc=`/api/local-op/ok-init`,zc=600*1e3,Bc=45e3,Vc=`local-op-clone`,Hc=withValidation(LocalOpCloneRequestSchema,Uc,{handler:Vc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Vc})});async function Uc(e,t,s){let{url:g,dir:S,branch:w}=s;if(!isAllowedGitUrl(g)){errorResponse(t,400,`urn:ok:error:url-not-allowed`,`URL protocol is not allowed for clone.`,{handler:Vc,cause:Error(`url=${g}`)});return}if(!isSafeLocalPath(S)){errorResponse(t,400,`urn:ok:error:dir-outside-home`,`Clone destination must be within the user home directory.`,{handler:Vc,cause:Error(`dir=${S}`)});return}if(!We.tryAcquire(Lc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A clone operation is already in progress.`,{handler:Vc,extraHeaders:{"Retry-After":`30`}});return}t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let E=createStreamingErrorWriter(t,Vc),D=null,O=runCloneSubprocess({cliArgs:ve,url:g,dir:S,branch:w,timeoutMs:zc,onEvent:e=>{if(e.type===`complete`){D=e.dir;return}if(e.type===`error`){e.message&&log$6.warn({stderr:redactShareSubprocessStderr(e.message),url:g,dir:S},`[local-op/clone] clone failed`);let t=classifyCloneError(e.message??``);E(500,`urn:ok:error:clone-failed`,t.title,{detail:t.detail||void 0,cause:e.message?Error(redactShareSubprocessStderr(e.message)):void 0});return}if(!t.writableEnded&&!t.destroyed)try{t.write(`${JSON.stringify(e)}\n`)}catch{}}});(async()=>{try{if(await O.done,D&&!t.writableEnded&&!t.destroyed){let e=await Wc(D);!t.writableEnded&&!t.destroyed&&(`port`in e?t.write(`${JSON.stringify({type:`complete`,port:e.port,dir:D})}\n`):E(500,`urn:ok:error:server-start-failed`,`Cloned successfully but failed to start the project server.`,{cause:Error(e.error)}))}}catch(e){!t.writableEnded&&!t.destroyed?E(500,`urn:ok:error:internal-server-error`,`Unexpected error during clone post-processing.`,{cause:e}):log$6.error({err:e,handler:Vc},`clone IIFE rejected after stream ended`)}finally{t.writableEnded||t.end(),We.release(Lc)}})(),t.on(`close`,()=>{O.cancel()})}async function Wc(e,t){let s=resolve(expandTilde(e)),g=getLocalDir(s),S=readUiLock(g);if(S&&S.port>0)return{port:S.port};let[w,...E]=ve,D=e=>{let s=t===void 0?[]:e===`ui`?[`--port`,String(t)]:[`--ui-port`,String(t)];return[...E,e,...s]},O=async e=>{let t=spawn(w,D(e),{cwd:s,detached:!0,stdio:[`ignore`,`ignore`,`pipe`],env:{...process.env,OK_LOCK_KIND:`interactive`}}),S=[];t.stderr?.on(`data`,t=>{S.push(t),log$6.warn({cwd:s,cliCmd:e,msg:t.toString(`utf-8`).trim()},`[local-op/clone] child stderr`)});let E=null,O=null,k=null;t.on(`exit`,(e,t)=>{E=e??-1,O=t??null}),t.on(`error`,t=>{k=t.message,E=-1,log$6.error({cwd:s,cliCmd:e,err:t.message},`[local-op/clone] failed to spawn child`)}),t.unref();let j=Date.now()+45e3;for(;Date.now()<j;){await setTimeout$1(500);let t=readUiLock(g);if(t&&t.port>0)return{port:t.port};if(E!==null){let t=Buffer.concat(S).toString(`utf-8`).trim();return{error:`\`ok ${e}\` exited (${k?`spawn failed: ${k}`:O?`killed by ${O}`:`code ${E}`})${t?` — ${t}`:``}`,exited:!0}}}let F=Buffer.concat(S).toString(`utf-8`).trim();return{error:`UI did not start within the expected time${F?` — ${F}`:``}`,exited:!1}},k=readServerLock(g),j=k&&k.port>0?`ui`:`start`,F=await O(j);if(j===`start`&&`error`in F&&F.exited){let e=readServerLock(g);if(e&&e.port>0){let e=await O(`ui`);return`port`in e?e:{error:`${F.error}; connect fallback failed: ${e.error}`}}}return`port`in F?F:{error:F.error}}let Gc=`local-op-ok-init`,Kc=withValidation(LocalOpOkInitRequestSchema,async(e,t,s)=>{let{projectPath:g}=s;if(!isAbsolute(g)){errorResponse(t,400,`urn:ok:error:invalid-request`,`projectPath must be an absolute path.`,{handler:Gc,cause:Error(`projectPath=${g}`)});return}let S;try{S=realpathSync(g)}catch(e){successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!1,reason:`not-a-git-worktree`,message:`projectPath does not exist or is not accessible: ${e.message}`},{handler:Gc});return}if(!isSafeLocalPath(S)){errorResponse(t,400,`urn:ok:error:dir-outside-home`,`projectPath must be within the user home directory.`,{handler:Gc,cause:Error(`projectPath=${g}`)});return}let w=resolveGitDirDetailed(S).kind;if(w!==`directory`&&w!==`linked`){console.warn(`[ok-init] action=init project=${basename(S)} result=not-a-git-worktree kind=${w}`),successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!1,reason:`not-a-git-worktree`,message:`projectPath is not a git working tree (.git is ${w}).`},{handler:Gc});return}if(isProjectRoot(S)){console.warn(`[ok-init] action=init project=${basename(S)} result=already-initialized`),successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!0,projectPath:S},{handler:Gc});return}if(!We.tryAcquire(Rc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An ok-init operation is already in progress.`,{handler:Gc,extraHeaders:{"Retry-After":`2`}});return}try{await withParentLock(async()=>{initContent(S)}),console.warn(`[ok-init] action=init project=${basename(S)} result=success`),successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!0,projectPath:S},{handler:Gc})}catch(e){let s=e instanceof Error?e.message:String(e);console.warn(`[ok-init] action=init project=${basename(S)} result=failed reason=${s}`),successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!1,reason:`init-failed`,message:s},{handler:Gc})}finally{We.release(Rc)}},{handler:Gc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Gc})}),qc=`/api/local-op/auth/login`,Jc=`/api/local-op/auth/status`,Yc=`/api/local-op/auth/repos`,Xc=`/api/local-op/auth/signout`,Zc=null,Qc=`local-op-auth-login`,$c=withValidation(LocalOpAuthHostRequestSchema,nl,{handler:Qc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Qc})});async function nl(e,t,s){let g=s.host??`github.com`;if(!We.tryAcquire(qc)){let e=Zc;if(!e){console.error(JSON.stringify({event:`ok-local-op:auth-login-slot-no-controller`,channel:`auth`,transport:`http`})),errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth login operation is already in progress.`,{handler:Qc,extraHeaders:{"Retry-After":`5`}});return}e.cancel(),Zc=null,console.warn(JSON.stringify({event:`ok-local-op:idempotent-start-replaced-stale-slot`,channel:`auth`,transport:`http`}))}t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let S=createStreamingErrorWriter(t,Qc),w=runDeviceFlowSubprocess({cliArgs:ve,host:g,timeoutMs:zc,onEvent:e=>{if(e.type===`error`){S(500,`urn:ok:error:auth-failed`,`Auth subprocess reported an error.`,{cause:e.message?Error(e.message):void 0});return}if(resumeSyncOnAuthEvent(e,_e),!t.writableEnded&&!t.destroyed)try{t.write(`${JSON.stringify(e)}\n`)}catch{}}});Zc=w;let E=()=>{w.cancel(),Zc===w&&(Zc=null,We.release(qc))};t.on(`close`,E),w.done.finally(()=>{if(t.off(`close`,E),!t.writableEnded&&!t.destroyed)try{t.end()}catch{}Zc===w&&(Zc=null,We.release(qc))})}let il=`local-op-auth-status`,al=withValidation(LocalOpAuthHostRequestSchema,async(e,t,s)=>{let g=s.host??`github.com`;if(!We.tryAcquire(Jc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth status operation is already in progress.`,{handler:il,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...s]=ve,S=[...s,`auth`,`status`,`--json`,`--host`,g],w=(await new Promise((t,s)=>{let g=spawn(e,S,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),w=!1,E=setTimeout(()=>{w=!0,g.kill(`SIGTERM`)},3e4),D=[];g.stdout.on(`data`,e=>D.push(e)),g.on(`close`,()=>{if(clearTimeout(E),w){s(Error(`auth status subprocess timed out after 30s`));return}t(Buffer.concat(D).toString(`utf-8`))}),g.on(`error`,e=>{clearTimeout(E),s(e)})})).split(`
|
|
1941
|
-
`).map(e=>e.trim()).filter(Boolean),E=null;for(let e=w.length-1;e>=0;e--)try{E=JSON.parse(w[e]);break}catch{}E===null?successResponse(t,200,LocalOpAuthStatusSuccessSchema,{authenticated:!1},{handler:
|
|
1942
|
-
`);k=s.pop()??``;for(let e of s){if(!e.trim())continue;let s=null;try{s=JSON.parse(e)}catch{}if(s&&s.type===`error`){S(500,`urn:ok:error:auth-failed`,`Auth repos subprocess reported an error.`,{detail:typeof s.message==`string`?s.message:void 0});continue}if(!t.writableEnded&&!t.destroyed)try{t.write(`${e}\n`)}catch{}}}),j.stderr.on(`data`,e=>{log$6.debug({msg:e.toString(`utf-8`).trim()},`[local-op/auth/repos] stderr`)}),j.on(`close`,e=>{clearTimeout(F),O||(O=!0,e!==0&&!t.writableEnded&&S(500,`urn:ok:error:auth-failed`,`Auth repos subprocess exited with code ${e}.`),t.end(),We.release(Yc))}),j.on(`error`,e=>{clearTimeout(F),O||(O=!0,t.writableEnded||(S(500,`urn:ok:error:auth-failed`,`Failed to spawn the auth repos subprocess.`,{cause:e}),t.end()),We.release(Yc))}),t.on(`close`,()=>{O||(O=!0,clearTimeout(F),j.kill(`SIGTERM`),We.release(Yc))})}let dl=`local-op-auth-signout`,fl=withValidation(LocalOpAuthHostRequestSchema,async(e,t,s)=>{let g=s.host??`github.com`;if(!We.tryAcquire(Xc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth signout operation is already in progress.`,{handler:dl,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...s]=ve,S=[...s,`auth`,`signout`,`--host`,g];await new Promise((t,s)=>{let g=spawn(e,S,{stdio:`ignore`,env:{...process.env}}),w=setTimeout(()=>{g.kill(`SIGTERM`)},3e4);g.on(`close`,()=>{clearTimeout(w),t()}),g.on(`error`,e=>{clearTimeout(w),s(e)})}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:dl})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth signout failed.`,{handler:dl,cause:e})}finally{We.release(Xc)}},{handler:dl,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:dl})}),pl=`/api/local-op/auth/set-identity`,ml=`local-op-auth-set-identity`,hl=withValidation(LocalOpAuthSetIdentityRequestSchema,async(e,t,s)=>{let g=s.name.trim(),S=s.email.trim();if(!ye){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:ml});return}if(!We.tryAcquire(pl)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A set-identity operation is already in progress.`,{handler:ml,extraHeaders:{"Retry-After":`5`}});return}try{writeGitIdentity(ye,g,S),_e?.()?.refreshIdentity().catch(()=>{}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:ml})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Set-identity failed.`,{handler:ml,cause:e})}finally{We.release(pl)}},{handler:ml,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:ml})});async function gl(e,t){if(checkLocalOpSecurity(e,t,{handler:`sync-status`})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-status`,extraHeaders:{Allow:`GET`}});return}try{let e=_e?.();if(!e){successResponse(t,200,SyncStatusSchema,{state:`dormant`,lastSyncUtc:null,lastFetchUtc:null,lastPushedSha:null,ahead:0,behind:0,consecutiveFailures:0,conflictCount:0,hasRemote:!1,syncEnabled:!1,identityUnresolved:!1,remote:null},{handler:`sync-status`});return}await e.refreshRemote(),successResponse(t,200,SyncStatusSchema,e.getStatus(),{handler:`sync-status`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`sync-status`,cause:e})}}}let _l=withValidation(SyncTriggerRequestSchema,async(e,t,s)=>{let g=_e?.();if(!g){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`});return}let S=s.op??`sync`;successResponse(t,202,SyncTriggerSuccessSchema,{op:S},{handler:`sync-trigger`}),g.trigger(S)},{handler:`sync-trigger`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-trigger`})?_e?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`}),!1):!1});async function vl(e,t){if(checkLocalOpSecurity(e,t,{handler:`sync-conflicts`})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflicts`,extraHeaders:{Allow:`GET`}});return}try{let e=_e?.();successResponse(t,200,SyncConflictsSuccessSchema,{conflicts:e?e.getConflicts():[]},{handler:`sync-conflicts`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`sync-conflicts`,cause:e})}}}let yl=withValidation(SyncResolveConflictRequestSchema,async(e,t,s)=>{let g=_e?.();if(!g){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`});return}let{file:S,strategy:w,content:E}=s;try{await g.resolveConflict(S,w,E),successResponse(t,200,SyncResolveConflictSuccessSchema,{},{handler:`sync-resolve-conflict`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to resolve conflict.`,{handler:`sync-resolve-conflict`,cause:e,detail:e instanceof Error?e.message:void 0})}},{handler:`sync-resolve-conflict`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-resolve-conflict`})?_e?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`}),!1):!1});async function xl(e,s){if(!checkLocalOpSecurity(e,s,{handler:`sync-conflict-content`}))return;if(e.method!==`GET`){errorResponse(s,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflict-content`,extraHeaders:{Allow:`GET`}});return}if(!ye){errorResponse(s,503,`urn:ok:error:project-repo-not-configured`,`Project repo not configured.`,{handler:`sync-conflict-content`});return}let g=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),S=g.searchParams.get(`file`);if(!S){errorResponse(s,400,`urn:ok:error:invalid-request`,`Missing required query param: file.`,{handler:`sync-conflict-content`});return}if(S.includes(`..`)||S.startsWith(`/`)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Invalid file path.`,{handler:`sync-conflict-content`});return}let w=stripDocExtension(S),E=t.documents.get(w)?.getMap(`lifecycle`).get(`status`)===`conflict`,D=_e?.(),O=D?D.getConflicts().some(e=>e.file===S):!1;if(!E&&!O){errorResponse(s,404,`urn:ok:error:no-conflict-tracked`,`No conflict is tracked for this path.`,{handler:`sync-conflict-content`,extensions:{file:S}});return}let k=g.searchParams.get(`source`),j=esm_default({baseDir:ye,timeout:{block:15e3}});async function F(e){try{return{present:!0,content:await j.raw([`show`,`:${e}:${S}`])}}catch(t){let s=t instanceof Error?t.message:String(t);if(!/pathspec|did not match|exists on disk, but not in|is in the index, but not at stage/i.test(s))throw console.warn(JSON.stringify({event:`showstage-unexpected-error`,stage:e,file:S,detail:s,handler:`sync-conflict-content`})),t;return{present:!1}}}try{let[e,g,w]=await Promise.all([F(1),F(2),F(3)]),E=e.present?e.content:``,D=w.present?w.content:``,O=g.present&&w.present?`both-modified`:!g.present&&w.present?`delete-modify`:g.present&&!w.present?`modify-delete`:`both-modified`,j=g.present?g.content:``,L=null;if(k===`ytext`){let e=stripDocExtension(S),s=t.documents.get(e);if(s){let t=s.getMap(`lifecycle`).get(`status`);if(L=typeof t==`string`&&t.length>0?t:null,O!==`delete-modify`){let t=Ie?Ie(e):null;t!==null&&!ytextHasConflictMarkers(t)?j=t:t!==null&&console.warn(JSON.stringify({event:`ytext-conflict-marker-detected`,"doc.name":e,handler:`sync-conflict-content`}))}}else console.warn(`[conflict-content] doc ${e} not loaded; lifecycleStatus unavailable`)}successResponse(s,200,SyncConflictContentSuccessSchema,{file:S,base:E,ours:j,theirs:D,kind:O,lifecycleStatus:L},{handler:`sync-conflict-content`})}catch(e){errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to read conflict content.`,{handler:`sync-conflict-content`,cause:e})}}async function Cl(e,t){if(!checkLocalOpSecurity(e,t,{handler:`seed-plan`}))return;if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`seed-plan`,extraHeaders:{Allow:`GET`}});return}let s=new URL(e.url??`/`,`http://localhost`),S=s.searchParams.get(`rootDir`)??void 0,w=s.searchParams.get(`packId`),E=coercePackId(w);if(w!==null&&w!==``&&E===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-plan`,detail:`Pack id "${w}" is not registered.`});return}try{successResponse(t,200,SeedPlanSuccessSchema,{plan:await planSeed({projectDir:g,rootDir:S,packId:E})},{handler:`seed-plan`})}catch(e){if(e instanceof SeedPrerequisiteError){errorResponse(t,422,`urn:ok:error:seed-prerequisite-missing`,`Seed prerequisite missing.`,{handler:`seed-plan`,cause:e});return}if(e instanceof SeedRootDirError){errorResponse(t,400,`urn:ok:error:seed-invalid-root`,`Invalid seed root directory.`,{handler:`seed-plan`,detail:`The provided root directory is not within the workspace content directory.`,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`seed-plan`,cause:e})}}let Tl=withValidation(SeedApplyRequestSchema,async(e,t,s)=>{let S=s.plan;if(!S||typeof S!=`object`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid plan payload.`,{handler:`seed-apply`});return}let w=S,E=s.packId,D=coercePackId(E);if(typeof E==`string`&&E.length>0&&D===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-apply`,detail:`Pack id "${E}" is not registered.`});return}try{successResponse(t,200,SeedApplySuccessSchema,{result:await applySeed(w,{projectDir:g,packId:D})},{handler:`seed-apply`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to apply seed plan.`,{handler:`seed-apply`,cause:e})}},{handler:`seed-apply`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`seed-apply`})});async function El(e,t){if(checkLocalOpSecurity(e,t,{handler:`seed-packs`})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`seed-packs`,extraHeaders:{Allow:`GET`}});return}successResponse(t,200,SeedListPacksSuccessSchema,{packs:listStarterPacks()},{handler:`seed-packs`})}}let Dl=withValidation(InstallSkillRequestSchema,async(e,t,s)=>{if(s.out!==void 0&&!isSafeLocalPath(s.out)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Output path must be within home directory.`,{handler:`install-skill`});return}try{successResponse(t,200,InstallSkillSuccessSchema,await buildAndOpenSkill({...s.noOpen===void 0?{}:{noOpen:s.noOpen},...s.out===void 0?{}:{out:s.out}}),{handler:`install-skill`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to install skill.`,{handler:`install-skill`,cause:e})}},{handler:`install-skill`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`install-skill`})});async function Ol(e,t){if(checkLocalOpSecurity(e,t,{handler:`installed-agents`}))try{await handleInstalledAgents(e,t,Tt.probeAll)}catch(e){t.headersSent||(log$6.error({err:e},`[installed-agents] route wrapper failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`installed-agents`,cause:e}))}}let kl=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ue){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-list`});return}try{successResponse(t,200,TagsListSuccessSchema,{tags:ue.getAllTags()},{handler:`tags-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read tags.`,{handler:`tags-list`,cause:e})}},{handler:`tags-list`,method:`GET`,skipBodyParse:!0});async function jl(e,t,s){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`tags-for-name`,extraHeaders:{Allow:`GET`}});return}if(!ue){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-for-name`});return}let g;try{g=decodeURIComponent(s)}catch{errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid tag name encoding.`,{handler:`tags-for-name`});return}if(!g){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing tag name.`,{handler:`tags-for-name`});return}try{let e=ue.getDocsForTagWithMatches(g).map(({docName:e,matchingTags:t})=>({docName:e,title:Dt(e),matchingTags:t,snippet:null}));successResponse(t,200,TagsForNameSuccessSchema,{name:g,docs:e},{handler:`tags-for-name`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read tag membership.`,{handler:`tags-for-name`,cause:e})}}function Ml(e,t,s=`path`,S=`folder-config`){let w=e.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``);if(w.split(`/`).some(e=>e===`..`)||e.startsWith(`/`))return errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid ${s}: must be project-root-relative.`,{handler:S}),null;let E=resolve(g),D=w===``?E:resolve(E,w);return D!==E&&!D.startsWith(`${E}${sep}`)?(errorResponse(t,400,`urn:ok:error:invalid-request`,`Path escapes content directory.`,{handler:S}),null):{folderRel:w,resolvedContentDir:E}}let Pl=/^[A-Za-z0-9_-]+$/;function Fl(e,t,s=`template`){return!e||!Pl.test(e)?(errorResponse(t,400,`urn:ok:error:invalid-request`,"Invalid name: must be letters / digits / `_` / `-` only (no `.md` extension).",{handler:s}),!1):!0}function Il(e,t,s){let g=t===``?[]:t.split(`/`);for(let t=g.length;t>=0;t--){let S=t===0?``:g.slice(0,t).join(`/`),w=S===``?e:resolve(e,S);if(w!==e&&!w.startsWith(`${e}${sep}`))continue;let E=resolve(w,`.ok`,`templates`,`${s}.md`);if(existsSync(E))return{abs:E,folder:S,scope:t===g.length?`local`:`inherited`}}return null}function Ll(e){let t={};if(!e||typeof e!=`object`||Array.isArray(e))return t;for(let[s,g]of Object.entries(e))g!==void 0&&(t[s]=g);return t}async function Rl(e,t){if(e.method===`GET`)return zl(e,t);if(e.method===`PUT`)return Bl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`folder-config`,extraHeaders:{Allow:`GET, PUT`}})}let zl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=Ml(new URL(e.url??``,`http://localhost`).searchParams.get(`path`)??``,t,`path`,`folder-config-get`);if(!s)return;let g=await enrichDirectory(s.folderRel,{projectDir:s.resolvedContentDir}),S=resolve(resolve(s.resolvedContentDir,s.folderRel,`.ok`),`frontmatter.yml`),w=null;if(existsSync(S))try{let e=(0,import_dist$1.parse)(await readFile$1(S,`utf-8`));w=e&&typeof e==`object`&&!Array.isArray(e)?e:{}}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[folder-config:get] malformed YAML in ${S}: ${t}`),w=null}successResponse(t,200,FolderConfigGetSuccessSchema,{folder:g,frontmatter_local:w},{handler:`folder-config-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read folder config.`,{handler:`folder-config-get`,cause:e})}},{handler:`folder-config-get`,method:`GET`,skipBodyParse:!0}),Bl=withValidation(FolderConfigPutRequestSchema,async(e,t,s)=>{try{if(Ue){errorResponse(t,403,`urn:ok:error:single-file-mode`,`Folder configuration is not available in single-file mode.`,{handler:`folder-config-put`});return}let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`folder-config-put`});return}let g=Ml(s.path,t,`path`,`folder-config-put`);if(!g)return;let S=[];if(s.frontmatter!==void 0){let w=applyFolderFrontmatterPatch({anchorDir:g.resolvedContentDir,folderRel:g.folderRel,patch:s.frontmatter});if(!w.ok){let e=w.error.code===`WRITE_ERROR`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to write folder config.`:w.error.message,{handler:`folder-config-put`,detail:w.error.code,cause:Error(w.error.message)});return}S.push({path:w.path,action:w.action}),w.action!==`noop`&&(xs(e,_s(`folder-frontmatter`,g.folderRel),`folder-frontmatter-${w.action===`deleted`?`delete`:`edit`}: ${w.path}`),await Cs(`folder-config-put`))}successResponse(t,200,FolderConfigPutSuccessSchema,{applied:S},{handler:`folder-config-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write folder config.`,{handler:`folder-config-put`,cause:e})}},{handler:`folder-config-put`,method:`PUT`});function Vl(e,s,g,S){if(!s)return!1;let w=e===``?`.ok/templates/${s}`:`${e.replace(/\/$/,``)}/.ok/templates/${s}`,E=t.documents.get(w);return E&&isDocInConflict(E)?(respondDocInConflict(S,new DocInConflictError({file:`${w}.md`}),g),!0):!1}function Hl(e,s,g){let S=t.documents.get(e);return S&&isDocInConflict(S)?(respondDocInConflict(g,new DocInConflictError({file:`${e}.md`}),s),!0):!1}let Ul=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=resolveProjectTemplates(resolve(g));successResponse(t,200,TemplatesListSuccessSchema,{templates:e.templates.map(e=>{let{scope:t,...s}=e;return s}),truncated:e.truncated},{handler:`templates-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list templates.`,{handler:`templates-list`,cause:e})}},{handler:`templates-list`,method:`GET`,skipBodyParse:!0});async function Wl(e,t){if(e.method===`GET`)return Kl(e,t);if(e.method===`PUT`)return ql(e,t);if(e.method===`POST`)return Yl(e,t);if(e.method===`DELETE`)return Jl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`template`,extraHeaders:{Allow:`GET, PUT, POST, DELETE`}})}let Gl=e=>{let{frontmatter:t,body:s}=stripFrontmatter(e),g={};if(t!==``)try{let e=(0,import_dist$1.parse)(unwrapFrontmatterFences(t));e&&typeof e==`object`&&!Array.isArray(e)&&(g=e)}catch{}return{frontmatter:g,body:s}},Kl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Fl(g,t,`template-get`))return;let S=Ml(s.searchParams.get(`folder`)??``,t,`folder`,`template-get`);if(!S)return;let{folderRel:w,resolvedContentDir:E}=S,D=Il(E,w,g);if(!D){errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-get`,detail:`Template "${g}" not found for folder "${w||`.`}". Walked leaf → root.`});return}let{abs:O,folder:k,scope:j}=D,F=parseTemplateFile(await readFile$1(O,`utf-8`)),L=F.identity,B=F.starterContent;successResponse(t,200,TemplateGetSuccessSchema,{template:{name:g,folder:k,scope:j,path:relative(E,O).split(/[\\/]/).filter(Boolean).join(`/`),frontmatter:L,body:B}},{handler:`template-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read template.`,{handler:`template-get`,cause:e})}},{handler:`template-get`,method:`GET`,skipBodyParse:!0}),ql=withValidation(TemplatePutRequestSchema,async(e,t,g)=>{try{if(Ue){errorResponse(t,403,`urn:ok:error:single-file-mode`,`Templates are not available in single-file mode.`,{handler:`template-put`});return}let e=extractActorIdentity(g,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`template-put`});return}let S=g.name;if(!Fl(S,t,`template-put`))return;let w=Ml(g.folder,t,`folder`,`template-put`);if(!w||Vl(w.folderRel,S,`template-put`,t))return;let E=composeTemplateContent({name:S,body:typeof g.body==`string`?g.body:``,frontmatter:Ll(g.frontmatter)});if(!E.ok){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid template request.`,{handler:`template-put`,detail:E.error.code,cause:Error(E.error.message)});return}let D=resolve(w.resolvedContentDir,w.folderRel,`.ok`,`templates`,`${S}.md`),O=!existsSync(D),k=relative(w.resolvedContentDir,D).split(/[\\/]/).filter(Boolean).join(`/`),j=tu(w.folderRel,S),{agentId:F,agentName:L,colorSeed:B,clientName:H}=Gi(g),q=await s.getSession(j,F,{displayName:L,colorSeed:B,clientName:H});q.dc.document.transact(()=>{composeAndWriteRawBody(q.dc.document,E.content,`agent`)},q.origin);let ee=await Ht(j);if(ee?.kind===`failure`){Ut(t,ee.failure,`template-put`);return}if(ee?.kind===`divergence`){Wt(t,`template-put`);return}xs(e,_s(`template`,w.folderRel,S),`${O?`template-create`:`template-edit`}: ${k}`),await Cs(`template-put`),successResponse(t,200,TemplatePutSuccessSchema,{path:k,created:O,warnings:E.warnings},{handler:`template-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write template.`,{handler:`template-put`,cause:e})}},{handler:`template-put`,method:`PUT`}),Jl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Fl(g,t,`template-delete`))return;let S=Ml(s.searchParams.get(`folder`)??``,t,`folder`,`template-delete`);if(!S)return;let w=s.searchParams,E=extractActorIdentity({agentId:w.get(`agentId`)??void 0,agentName:w.get(`agentName`)??void 0,colorSeed:w.get(`colorSeed`)??void 0,clientName:w.get(`clientName`)??void 0,clientVersion:w.get(`clientVersion`)??void 0,label:w.get(`label`)??void 0,summary:w.get(`summary`)??void 0},Ce);if(E.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`template-delete`});return}if(Vl(S.folderRel,g,`template-delete`,t))return;await Lr([tu(S.folderRel,g)]);let D=applyTemplateDelete({projectDir:S.resolvedContentDir,folder:S.folderRel,name:g});if(!D.ok){let e=D.error.code===`WRITE_ERROR`||D.error.code===`UNLINK_FAILED`||D.error.code===`BAD_PROJECT_DIR`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to delete template.`:`Invalid template request.`,{handler:`template-delete`,detail:D.error.code,cause:Error(D.error.message)});return}D.existed&&(xs(E,_s(`template`,S.folderRel,g),`template-delete: ${D.path}`),await Cs(`template-delete`)),successResponse(t,200,TemplateDeleteSuccessSchema,{existed:D.existed,path:D.path},{handler:`template-delete`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to delete template.`,{handler:`template-delete`,cause:e})}},{handler:`template-delete`,method:`DELETE`,skipBodyParse:!0}),Yl=withValidation(TemplateMoveRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`template-move`});return}if(!Fl(s.fromName,t,`template-move`)||!Fl(s.toName,t,`template-move`))return;let g=Ml(s.fromFolder,t,`folder`,`template-move`);if(!g)return;let S=Ml(s.toFolder,t,`folder`,`template-move`);if(!S||Vl(g.folderRel,s.fromName,`template-move`,t))return;await Lr([tu(g.folderRel,s.fromName)]);let w=await applyTemplateMove({projectDir:g.resolvedContentDir,fromFolder:g.folderRel,fromName:s.fromName,toFolder:S.folderRel,toName:s.toName,relocate:async(e,t)=>{let s=await renameTrackedPathInGit(ye,e,t);return s||renamePathOnDisk(e,t),s}});if(!w.ok){if(w.error.code===`TEMPLATE_NOT_FOUND`){let e=Il(g.resolvedContentDir,g.folderRel,s.fromName);if(e?.scope===`inherited`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Template "${s.fromName}" is inherited from "${e.folder||`(root)`}", not local to "${g.folderRel||`(root)`}". Move it from the folder that owns it, or create a local copy here first (then move that).`,{handler:`template-move`,detail:`TEMPLATE_INHERITED`});return}errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-move`,detail:w.error.message});return}if(w.error.code===`TEMPLATE_EXISTS`){errorResponse(t,409,`urn:ok:error:doc-already-exists`,w.error.message,{handler:`template-move`,detail:w.error.code});return}let e=w.error.code===`WRITE_ERROR`||w.error.code===`MOVE_FAILED`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to move template.`:`Invalid template move request.`,{handler:`template-move`,detail:w.error.code,cause:Error(w.error.message)});return}let E=null;if(s.body!==void 0||s.frontmatter!==void 0){let e;if(typeof s.body==`string`)e=s.body;else try{e=instantiateDoc(readFileSync(resolve(S.resolvedContentDir,w.toPath),`utf-8`))}catch{e=null}if(e===null)E={code:`READ_FAILED`,message:`could not read the moved template to apply the metadata change; the move succeeded with the original content intact — retry the edit`};else{let t=applyTemplateWrite({projectDir:S.resolvedContentDir,folder:S.folderRel,name:s.toName,body:e,frontmatter:Ll(s.frontmatter)});t.ok||(E=t.error)}}if(xs(e,_s(`template`,S.folderRel,s.toName),`template-rename: ${w.fromPath} -> ${w.toPath}`,[{from:w.fromPath,to:w.toPath}]),await Cs(`template-move`),de?.(`files`),E){let e=E.code===`WRITE_ERROR`||E.code===`READ_FAILED`;errorResponse(t,e?500:400,e?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,`Template moved to "${w.toPath}", but updating its content failed.`,{handler:`template-move`,detail:E.code,cause:Error(E.message)});return}successResponse(t,200,TemplateMoveSuccessSchema,{from:w.fromPath,to:w.toPath,committed:w.committed},{handler:`template-move`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to move template.`,{handler:`template-move`,cause:e})}},{handler:`template-move`,method:`POST`}),Xl=500;function Zl(e,t,s){return!e||e.length>64||!SKILL_NAME_REGEX.test(e)?(errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill name: lowercase letters, digits, and hyphens only (≤64 chars; no slashes, dots, spaces, or uppercase).`,{handler:s}),!1):!0}function Ql(e,t,s){let g=SkillScopeSchema.safeParse(e??`project`);return g.success?g.data:(errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill scope (expected "project" or "global").`,{handler:s}),null)}let $l=we??homedir();function eu(e){return resolve(e===`global`?$l:g,`.ok`,`skills`)}function tu(e,t){return`${MANAGED_ARTIFACT_PREFIX_TEMPLATE}${[...e?e.split(`/`).filter(Boolean).map(encodeURIComponent):[],encodeURIComponent(t)].join(`/`)}`}function nu(e){return e===`navigation`||e===`relevance`?e:void 0}function ru(e,t){return relative(t===`global`?$l:g,e).split(/[\\/]/).filter(Boolean).join(`/`)}function iu(e){return e===`global`?$l:ye}async function au(e,t){let s=await removeSkillInstall(e,t);return reverseProjectSkill(t,e,PROJECT_SKILL_EDITOR_IDS),s!==null}function ou(e,t){let s=[];if(!existsSync(e))return{skills:s,truncated:!1};let g;try{g=readdirSync(e,{withFileTypes:!0})}catch(g){return getLogger(`skills`).warn({err:g,skillsRoot:e,scope:t},`failed to read skills root — returning empty skills list`),{skills:s,truncated:!1}}let S=!1;for(let w of g.sort((e,t)=>e.name.localeCompare(t.name))){if(!w.isDirectory()||!SKILL_NAME_REGEX.test(w.name))continue;if(s.length>=500){S=!0;break}let g=resolve(e,w.name,`SKILL.md`);if(!existsSync(g))continue;let E,D;try{let{frontmatter:e}=Gl(readFileSync(g,`utf-8`));typeof e.description==`string`&&(E=e.description),typeof e.version==`string`&&e.version.trim()!==``&&(D=e.version)}catch{}s.push({name:w.name,...E===void 0?{}:{description:E},scope:t,path:ru(g,t),absolutePath:g,...D===void 0?{}:{installedVersion:D}})}return{skills:s,truncated:S}}let su=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=ou(eu(`project`),`project`),s=ou(eu(`global`),`global`),g=ye?readInstalledSkills(ye).skills:{},S=readInstalledSkills($l).skills,w=(e,t)=>e.skills.map(e=>{let s=t[e.name]?.hosts??[],g=computePackUpdateStatus(e.name,e.installedVersion);return{...e,installed:s.length>0,hosts:s,...g}});successResponse(t,200,SkillsListSuccessSchema,{skills:[...w(e,g),...w(s,S)],truncated:e.truncated||s.truncated},{handler:`skills-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list skills.`,{handler:`skills-list`,cause:e})}},{handler:`skills-list`,method:`GET`,skipBodyParse:!0});async function cu(e,t){if(e.method===`GET`)return mu(e,t);if(e.method===`PUT`)return hu(e,t);if(e.method===`POST`)return _u(e,t);if(e.method===`DELETE`)return gu(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`skill`,extraHeaders:{Allow:`GET, PUT, POST, DELETE`}})}let lu=object$1({managed:boolean().nullable(),importable:number().int().nonnegative()}),uu=()=>({managed:ye?readSkillManagement(ye)?.manageEditorSkills??null:null,importable:ye?countImportableEditorSkills({projectDir:ye,skillsRoot:eu(`project`)}):0}),du=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ye){errorResponse(t,400,`urn:ok:error:invalid-request`,`No project root resolved.`,{handler:`skills-management-get`,detail:`NO_PROJECT_ROOT`});return}successResponse(t,200,lu,uu(),{handler:`skills-management-get`})},{handler:`skills-management-get`,method:`GET`,skipBodyParse:!0}),fu=withValidation(object$1({manageEditorSkills:boolean()}),async(e,t,s)=>{if(!ye){errorResponse(t,400,`urn:ok:error:invalid-request`,`No project root resolved.`,{handler:`skills-management-put`,detail:`NO_PROJECT_ROOT`});return}if(await writeSkillManagement(ye,{manageEditorSkills:s.manageEditorSkills,surface:`ui`}),s.manageEditorSkills){let e=await reconcileSkillInstalls({projectDir:ye,skillsRoot:eu(`project`)});e.adopted.length+e.collided.length>0&&de?.(`files`)}successResponse(t,200,lu,uu(),{handler:`skills-management-put`})},{handler:`skills-management-put`,method:`PUT`});async function pu(e,t){if(e.method===`GET`)return du(e,t);if(e.method===`PUT`)return fu(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`skills-management`,extraHeaders:{Allow:`GET, PUT`}})}let mu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Zl(g,t,`skill-get`))return;let S=Ql(s.searchParams.get(`scope`),t,`skill-get`);if(S===null)return;let w=eu(S),E=resolve(w,g,`SKILL.md`);if(!existsSync(E)){errorResponse(t,404,`urn:ok:error:not-found`,`Skill not found.`,{handler:`skill-get`,detail:`Skill "${g}" not found in ${S} scope.`});return}let{frontmatter:D,body:O}=Gl(await readFile$1(E,`utf-8`));successResponse(t,200,SkillGetSuccessSchema,{skill:{name:g,scope:S,path:ru(E,S),frontmatter:{name:typeof D.name==`string`?D.name:g,description:typeof D.description==`string`?D.description:``},body:O,files:readSkillBundledFiles(resolve(w,g))}},{handler:`skill-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read skill.`,{handler:`skill-get`,cause:e})}},{handler:`skill-get`,method:`GET`,skipBodyParse:!0}),hu=withValidation(SkillPutRequestSchema,async(e,t,g)=>{try{let e=extractActorIdentity(g,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-put`});return}if(!Zl(g.name,t,`skill-put`))return;let S=composeSkillContent({name:g.name,body:typeof g.body==`string`?g.body:``,frontmatter:{name:g.frontmatter.name,description:g.frontmatter.description}});if(!S.ok){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill request.`,{handler:`skill-put`,detail:S.error.code,cause:Error(S.error.message)});return}let w=eu(g.scope),E=resolve(w,g.name,`SKILL.md`),D=!existsSync(E),O=relative(w,E).split(/[\\/]/).filter(Boolean).join(`/`),k=skillLiveDocName(g.scope,g.name);if(Hl(k,`skill-put`,t))return;let{agentId:j,agentName:F,colorSeed:L,clientName:B}=Gi(g),H=await s.getSession(k,j,{displayName:F,colorSeed:L,clientName:B});H.dc.document.transact(()=>{composeAndWriteRawBody(H.dc.document,S.content,`agent`)},H.origin);let q=await Ht(k);if(q?.kind===`failure`){Ut(t,q.failure,`skill-put`);return}if(q?.kind===`divergence`){Wt(t,`skill-put`);return}g.scope===`project`&&(xs(e,_s(`skill`,``,g.name),`${D?`skill-create`:`skill-edit`}: ${O}`),await Cs(`skill-put`)),de?.(`files`),successResponse(t,200,SkillPutSuccessSchema,{path:O,created:D,warnings:S.warnings},{handler:`skill-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write skill.`,{handler:`skill-put`,cause:e})}},{handler:`skill-put`,method:`PUT`}),gu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Zl(g,t,`skill-delete`))return;let S=Ql(s.searchParams.get(`scope`),t,`skill-delete`);if(S===null)return;let w=eu(S),E=s.searchParams,D=extractActorIdentity({agentId:E.get(`agentId`)??void 0,agentName:E.get(`agentName`)??void 0,colorSeed:E.get(`colorSeed`)??void 0,clientName:E.get(`clientName`)??void 0,clientVersion:E.get(`clientVersion`)??void 0,label:E.get(`label`)??void 0,summary:E.get(`summary`)??void 0},Ce);if(D.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-delete`});return}await Lr([skillLiveDocName(S,g)]);let O=applySkillDelete({skillsRoot:w,name:g});if(!O.ok){let e=O.error.code===`UNLINK_FAILED`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to delete skill.`:`Invalid skill request.`,{handler:`skill-delete`,detail:O.error.code,cause:Error(O.error.message)});return}O.existed&&(S===`project`&&(xs(D,_s(`skill`,``,g),`skill-delete: ${O.path}`),await Cs(`skill-delete`)),de?.(`files`));let k=iu(S);k&&await au(k,g),successResponse(t,200,SkillDeleteSuccessSchema,{existed:O.existed,path:O.path},{handler:`skill-delete`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to delete skill.`,{handler:`skill-delete`,cause:e})}},{handler:`skill-delete`,method:`DELETE`,skipBodyParse:!0}),_u=withValidation(SkillMoveRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-move`});return}if(!Zl(s.fromName,t,`skill-move`)||!Zl(s.toName,t,`skill-move`))return;let g=eu(s.scope);await Lr([skillLiveDocName(s.scope,s.fromName)]);let S=await applySkillMove({skillsRoot:g,fromName:s.fromName,toName:s.toName,relocate:async(e,t)=>{let s=await renameTrackedPathInGit(ye,e,t);return s||renamePathOnDisk(e,t),s}});if(!S.ok){if(S.error.code===`SKILL_NOT_FOUND`){errorResponse(t,404,`urn:ok:error:not-found`,`Skill not found.`,{handler:`skill-move`,detail:S.error.message});return}if(S.error.code===`SKILL_EXISTS`){errorResponse(t,409,`urn:ok:error:doc-already-exists`,S.error.message,{handler:`skill-move`,detail:S.error.code});return}let e=S.error.code===`MOVE_FAILED`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to move skill.`:`Invalid skill move request.`,{handler:`skill-move`,detail:S.error.code,cause:Error(S.error.message)});return}let w=null,E=resolve(g,s.toName,`SKILL.md`),D=``,O=``;try{let e=Gl(readFileSync(E,`utf-8`));D=e.body,typeof e.frontmatter.description==`string`&&(O=e.frontmatter.description)}catch{}let k=typeof s.body==`string`?s.body:D,j=s.frontmatter===void 0?O:s.frontmatter.description,F=applySkillWrite({skillsRoot:g,name:s.toName,body:k,frontmatter:{name:s.toName,description:j}});if(F.ok||(w=F.error),s.scope===`project`&&!w)try{Su(g,s.fromName,s.toName)}catch(e){getLogger(`skill-move`).warn({err:e,fromName:s.fromName,toName:s.toName},`reindex of moved project skill docs failed — rename succeeded, deferring to next rescan`)}let L=ru(resolve(g,s.fromName),s.scope),B=ru(resolve(g,s.toName),s.scope);s.scope===`project`&&(xs(e,_s(`skill`,``,s.toName),`skill-rename: ${L} -> ${B}`,[{from:L,to:B}]),await Cs(`skill-move`));let H=iu(s.scope);if(H){let e=await removeSkillInstall(H,s.fromName);if(e){let t=resolvedHosts(e.hosts);reverseProjectSkill(s.fromName,H,t);let S=projectSkill(resolve(g,s.toName),s.toName,H,t);await recordSkillInstall(H,s.toName,{...e,hosts:S})}}if(de?.(`files`),w){let e=w.code===`WRITE_ERROR`;errorResponse(t,e?500:400,e?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,`Skill renamed to "${s.toName}", but updating its SKILL.md failed — its name frontmatter may not match the new directory.`,{handler:`skill-move`,detail:w.code,cause:Error(w.message)});return}successResponse(t,200,SkillMoveSuccessSchema,{from:L,to:B,committed:S.committed},{handler:`skill-move`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to move skill.`,{handler:`skill-move`,cause:e})}},{handler:`skill-move`,method:`POST`});function vu(e){if(e.includes(`\0`))return null;let t=e.replace(/\\/g,`/`).split(`/`).filter(e=>e!==``&&e!==`.`);return t.length<2||t.some(e=>e===`..`)?null:t[0]===`references`?`reference`:t[0]===`scripts`?`script`:null}function yu(e,t,s){return e===`project`&&t===`reference`&&s.toLowerCase().endsWith(`.md`)}function bu(e,t){let s=t.replace(/\.md$/i,``);return`${projectSkillContentDocName(e).replace(/\/SKILL$/,``)}/${s}`}function xu(e,t){let s=resolve(e,t,`references`);if(!existsSync(s))return[];let g=[],S=(e,t)=>{for(let s of readdirSync(e,{withFileTypes:!0})){let w=t?`${t}/${s.name}`:s.name;s.isDirectory()?S(resolve(e,s.name),w):s.isFile()&&s.name.toLowerCase().endsWith(`.md`)&&g.push(`references/${w}`)}};return S(s,``),g}function Su(e,t,s){if(!ce)return;let g=(e,t,s)=>{let g;try{g=readFileSync(s,`utf-8`)}catch{ce.deleteDocument(e),ue?.deleteDocument(e);return}ce.renameDocument(e,t,g),ue?.renameDocument(e,t,g)};g(projectSkillContentDocName(t),projectSkillContentDocName(s),resolve(e,s,`SKILL.md`));for(let S of xu(e,s))g(bu(t,S),bu(s,S),resolve(e,s,S));de?.(`backlinks`),de?.(`graph`)}let Cu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Zl(g,t,`skill-file-get`))return;let S=Ql(s.searchParams.get(`scope`),t,`skill-file-get`);if(S===null)return;let w=s.searchParams.get(`path`)??``,E=vu(w);if(E===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill file path (must be a file under references/ or scripts/).`,{handler:`skill-file-get`});return}let D=resolve(eu(S),g),O=resolve(D,w);if(O!==D&&!O.startsWith(`${D}${sep}`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Skill file path escapes the skill dir.`,{handler:`skill-file-get`});return}let k=O,j=w;if(!existsSync(k)){let e=w.match(/^(.*)\.(?:md|mdx)$/),s=e?SUPPORTED_DOC_EXTENSIONS.map(t=>`${e[1]}${t}`).find(e=>e!==w&&existsSync(resolve(D,e))):void 0;if(s===void 0){errorResponse(t,404,`urn:ok:error:not-found`,`Skill file not found.`,{handler:`skill-file-get`,detail:`${w} not found in skill "${g}" (${S}).`});return}j=s,k=resolve(D,s)}let F=await readFile$1(k);if(F.includes(0)){errorResponse(t,415,`urn:ok:error:invalid-request`,`Skill file is binary — only text bundle files are readable via MCP.`,{handler:`skill-file-get`});return}successResponse(t,200,SkillFileGetSuccessSchema,{path:j.replace(/\\/g,`/`),kind:E,text:F.toString(`utf-8`)},{handler:`skill-file-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read skill file.`,{handler:`skill-file-get`,cause:e})}},{handler:`skill-file-get`,method:`GET`,skipBodyParse:!0}),wu=withValidation(SkillFilePutRequestSchema,async(e,t,g)=>{try{let e=extractActorIdentity(g,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-file-put`});return}if(!Zl(g.name,t,`skill-file-put`))return;let S=vu(g.path);if(S===null){errorResponse(t,400,`urn:ok:error:invalid-request`,"Invalid skill file path (must be a file under references/ or scripts/, no `..`).",{handler:`skill-file-put`});return}if(Buffer.byteLength(g.content,`utf-8`)>262144){errorResponse(t,400,`urn:ok:error:invalid-request`,`Skill file exceeds the 256 KB per-file cap.`,{handler:`skill-file-put`});return}let w=eu(g.scope);if(!existsSync(resolve(w,g.name,`SKILL.md`))){errorResponse(t,404,`urn:ok:error:not-found`,`Skill not found.`,{handler:`skill-file-put`,detail:`Create skill "${g.name}" before adding bundle files.`});return}let E=g.path.replace(/\\/g,`/`),D=yu(g.scope,S,E),O;if(D){let e=bu(g.name,E);if(Hl(e,`skill-file-put`,t))return;if(O=!existsSync(resolve(w,g.name,E)),O&&countBundleFiles(resolve(w,g.name))>=50){errorResponse(t,400,`urn:ok:error:invalid-request`,`Skill "${g.name}" already holds 50 bundle files (the cap) — delete one before adding another.`,{handler:`skill-file-put`});return}let{agentId:S,agentName:D,colorSeed:k,clientName:j}=Gi(g),F=await s.getSession(e,S,{displayName:D,colorSeed:k,clientName:j});F.dc.document.transact(()=>{composeAndWriteRawBody(F.dc.document,g.content,`agent`)},F.origin);let L=await Ht(e);if(L?.kind===`failure`){Ut(t,L.failure,`skill-file-put`);return}if(L?.kind===`divergence`){Wt(t,`skill-file-put`);return}}else{let e=applySkillBundleFileWrite({skillsRoot:w,name:g.name,relPath:E,content:g.content});if(!e.ok){let s=e.error.code===`WRITE_ERROR`?500:e.error.code===`SKILL_NOT_FOUND`?404:400;errorResponse(t,s,s===500?`urn:ok:error:internal-server-error`:s===404?`urn:ok:error:not-found`:`urn:ok:error:invalid-request`,s===500?`Failed to write skill file.`:`Invalid skill file request.`,{handler:`skill-file-put`,detail:e.error.code,cause:Error(e.error.message)});return}O=e.created}g.scope===`project`&&(xs(e,_s(`skill`,``,g.name),`${O?`skill-file-create`:`skill-file-edit`}: .ok/skills/${g.name}/${E}`),await Cs(`skill-file-put`)),de?.(`files`),successResponse(t,200,SkillFilePutSuccessSchema,{path:E,created:O,kind:S,content:D},{handler:`skill-file-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write skill file.`,{handler:`skill-file-put`,cause:e})}},{handler:`skill-file-put`,method:`PUT`}),Tu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`).searchParams,g=s.get(`name`)??``;if(!Zl(g,t,`skill-file-delete`))return;let S=Ql(s.get(`scope`),t,`skill-file-delete`);if(S===null)return;let w=(s.get(`path`)??``).replace(/\\/g,`/`),E=vu(w);if(E===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill file path (must be a file under references/ or scripts/).`,{handler:`skill-file-delete`});return}let D=extractActorIdentity({agentId:s.get(`agentId`)??void 0,agentName:s.get(`agentName`)??void 0,colorSeed:s.get(`colorSeed`)??void 0,clientName:s.get(`clientName`)??void 0,clientVersion:s.get(`clientVersion`)??void 0,label:s.get(`label`)??void 0,summary:s.get(`summary`)??void 0},Ce);if(D.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-file-delete`});return}let O=eu(S);yu(S,E,w)&&await Lr([bu(g,w)]);let k=applySkillBundleFileDelete({skillsRoot:O,name:g,relPath:w});if(!k.ok){let e=k.error.code===`UNLINK_FAILED`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to delete skill file.`:`Invalid skill file request.`,{handler:`skill-file-delete`,detail:k.error.code,cause:Error(k.error.message)});return}k.existed&&S===`project`&&(xs(D,_s(`skill`,``,g),`skill-file-delete: .ok/skills/${g}/${w}`),await Cs(`skill-file-delete`)),k.existed&&de?.(`files`),successResponse(t,200,SkillFileDeleteSuccessSchema,{path:w,existed:k.existed,kind:E},{handler:`skill-file-delete`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to delete skill file.`,{handler:`skill-file-delete`,cause:e})}},{handler:`skill-file-delete`,method:`DELETE`,skipBodyParse:!0});async function Eu(e,t){if(e.method===`GET`)return Cu(e,t);if(e.method===`PUT`)return wu(e,t);if(e.method===`DELETE`)return Tu(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`skill-file`,extraHeaders:{Allow:`GET, PUT, DELETE`}})}let Du=withValidation(SkillInstallRequestSchema,async(e,t,s)=>{try{let e=eu(s.scope);if(!Zl(s.name,t,`skill-install`))return;if(s.scope===`project`&&!ye){errorResponse(t,400,`urn:ok:error:invalid-request`,`Cannot install — no project root is resolved for this server. Skills project into editor host dirs at the project root.`,{handler:`skill-install`,detail:`NO_PROJECT_ROOT`});return}let g=iu(s.scope),S=resolve(e,s.name);if(!existsSync(S)){errorResponse(t,404,`urn:ok:error:not-found`,`Skill not found.`,{handler:`skill-install`,detail:`Skill "${s.name}" not found in ${s.scope} scope — create it with write({ skill }) first.`});return}let w=validateSkillForInstall(S,s.name);if(!w.ok){errorResponse(t,400,`urn:ok:error:invalid-request`,`Skill "${s.name}" cannot be installed: ${w.errors.join(` `)}`,{handler:`skill-install`,detail:`INVALID_SKILL_SOURCE`});return}let E=s.scope===`global`?s.targets?PROJECT_SKILL_EDITOR_IDS.filter(e=>s.targets?.some(t=>t===e)):[...PROJECT_SKILL_EDITOR_IDS]:s.targets===void 0?resolveSkillTargets(g,readSkillTargets(g)??void 0):PROJECT_SKILL_EDITOR_IDS.filter(e=>s.targets?.some(t=>t===e)),D=[],O=[];E.length===0&&s.targets===void 0&&(D.push(s.scope===`global`?`No editor skill folders are configured to install into.`:"No project-configured editors detected — nothing was projected. Set up an editor for this project (add .mcp.json / .cursor/mcp.json / .codex/config.toml) or pass explicit `targets`."),O.push(`no-targets`)),w.hasScripts&&(D.push("This skill includes executable `scripts/`. After you install it, the AI agent in your editor (Claude, Cursor, Codex) can run them — Open Knowledge itself never runs anything. Review the scripts before sharing."),O.push(`scripts-present`));let k=resolvedHosts(readInstalledSkills(g).skills[s.name]?.hosts??[]).filter(e=>!E.includes(e));k.length>0&&reverseProjectSkill(s.name,g,k);let j=projectSkill(S,s.name,g,E);j.length===0?await removeSkillInstall(g,s.name):await recordSkillInstall(g,s.name,{hosts:j,scope:s.scope,scripts:w.hasScripts,installedAt:new Date().toISOString()}),de?.(`files`),successResponse(t,200,SkillInstallSuccessSchema,{name:s.name,hosts:j,scripts:w.hasScripts,warnings:D,warningCodes:O},{handler:`skill-install`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to install skill.`,{handler:`skill-install`,cause:e})}},{handler:`skill-install`,method:`POST`}),Ou=withValidation(SkillUninstallRequestSchema,async(e,t,s)=>{try{if(!Zl(s.name,t,`skill-uninstall`))return;let e=iu(s.scope);if(!e){errorResponse(t,400,`urn:ok:error:invalid-request`,`Cannot uninstall — no project root is resolved for this server.`,{handler:`skill-uninstall`,detail:`NO_PROJECT_ROOT`});return}let g=await au(e,s.name);de?.(`files`),successResponse(t,200,SkillUninstallSuccessSchema,{name:s.name,uninstalled:g},{handler:`skill-uninstall`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to uninstall skill.`,{handler:`skill-uninstall`,cause:e})}},{handler:`skill-uninstall`,method:`POST`});async function ku(e,t){if(e.method===`GET`)return Au(e,t);if(e.method===`PUT`)return ju(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`skill-targets`,extraHeaders:{Allow:`GET, PUT`}})}let Au=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=ye?readSkillTargets(ye):null;successResponse(t,200,SkillTargetsGetSuccessSchema,{targets:resolveSkillTargets(ye??``,e??void 0),configured:e!==null},{handler:`skill-targets-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read skill targets.`,{handler:`skill-targets-get`,cause:e})}},{handler:`skill-targets-get`,method:`GET`,skipBodyParse:!0}),ju=withValidation(SkillTargetsPutRequestSchema,async(e,t,s)=>{try{if(!ye){errorResponse(t,400,`urn:ok:error:invalid-request`,`Cannot set skill targets — no project root is resolved for this server.`,{handler:`skill-targets-put`,detail:`NO_PROJECT_ROOT`});return}let e=s.targets,g=new Set(e),S=resolveSkillTargets(ye,readSkillTargets(ye)??void 0),w=eu(`project`);await writeSkillTargets(ye,e);let{reprojected:E,bundleHosts:D}=await reprojectAllManagedSkills({projectDir:ye,skillsRoot:w,targets:e});de?.(`files`),successResponse(t,200,SkillTargetsPutSuccessSchema,{targets:e,reprojected:E,bundleHosts:D,removedFrom:S.filter(e=>!g.has(e))},{handler:`skill-targets-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to set skill targets.`,{handler:`skill-targets-put`,cause:e})}},{handler:`skill-targets-put`,method:`PUT`}),Mu=withValidation(SkillRestoreRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-restore`});return}if(!Zl(s.name,t,`skill-restore`))return;if(s.scope===`global`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Global skills are unversioned — there is no version history to restore from.`,{handler:`skill-restore`,detail:`GLOBAL_SCOPE_UNVERSIONED`});return}let S=q?.current;if(!S){errorResponse(t,409,`urn:ok:error:shadow-not-configured`,`No version history available to restore from.`,{handler:`skill-restore`,detail:`NO_SHADOW_REPO`});return}let w=await restoreSkillVersion({shadow:S,contentDir:g,contentRoot:se??`.`,name:s.name,version:s.version});if(!w.ok){let[e,s]={"no-shadow":[409,`urn:ok:error:shadow-not-configured`],"version-not-found":[404,`urn:ok:error:not-found`],"skill-absent":[404,`urn:ok:error:not-found`],"io-error":[500,`urn:ok:error:storage-error`],"path-escape":[500,`urn:ok:error:path-escape`]}[w.code];errorResponse(t,e,s,w.error,{handler:`skill-restore`,detail:w.code});return}let E=[],D=validateSkillForInstall(resolve(g,`.ok`,`skills`,s.name),s.name);D.ok||E.push(`Restored, but the skill no longer validates: ${D.errors.join(` `)}`),E.push("Run `install` to push the restored version to your editors."),xs(e,_s(`skill`,``,s.name),`skill-restore: ${s.name} @ ${s.version.slice(0,8)}`),await Cs(`skill-restore`),de?.(`files`),successResponse(t,200,SkillRestoreSuccessSchema,{name:s.name,version:s.version,restoredFiles:w.restoredFiles,warnings:E},{handler:`skill-restore`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to restore skill.`,{handler:`skill-restore`,cause:e})}},{handler:`skill-restore`,method:`POST`}),Nu=withValidation(SkillUpdateRequestSchema,async(e,t,g)=>{try{let e=extractActorIdentity(g,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-update`});return}if(!Zl(g.name,t,`skill-update`))return;if(!isPackSkillName(g.name)){errorResponse(t,400,`urn:ok:error:invalid-request`,"Only starter-pack skills (`open-knowledge-pack-*`) can be updated from the bundle.",{handler:`skill-update`,detail:`NOT_A_PACK_SKILL`});return}if(g.scope===`global`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Pack skills are project-scope — there is no global-scope pack to update.`,{handler:`skill-update`,detail:`GLOBAL_SCOPE`});return}let S=readBundledPackSkill(g.name);if(S===null||S.version===void 0){errorResponse(t,404,`urn:ok:error:not-found`,`No bundled version is available for this pack skill.`,{handler:`skill-update`,detail:`NO_BUNDLED_VERSION`});return}let w=resolve(eu(`project`),g.name,`SKILL.md`);if(!existsSync(w)){errorResponse(t,404,`urn:ok:error:not-found`,`Skill is not installed.`,{handler:`skill-update`,detail:`SKILL_ABSENT`});return}let E;try{E=readSkillVersion(readFileSync(w,`utf-8`))}catch{}let D,O=q?.current;if(O)try{let e=ae?.()??`main`;D=(await saveVersion(O,se??`.`,[SERVICE_WRITER],e,`Before updating ${g.name} (${E??`unversioned`} → ${S.version})`)).checkpointRef}catch(e){getLogger(`skills`).warn({err:e,skill:g.name},`pre-update checkpoint failed — proceeding with overwrite`)}let k=skillLiveDocName(`project`,g.name);if(Hl(k,`skill-update`,t))return;let{agentId:j,agentName:F,colorSeed:L,clientName:B}=Gi(g),H=await s.getSession(k,j,{displayName:F,colorSeed:L,clientName:B});H.dc.document.transact(()=>{composeAndWriteRawBody(H.dc.document,S.content,`agent`)},H.origin);let ee=await Ht(k);if(ee?.kind===`failure`){Ut(t,ee.failure,`skill-update`);return}if(ee?.kind===`divergence`){Wt(t,`skill-update`);return}xs(e,_s(`skill`,``,g.name),`skill-pack-update: ${g.name} (${E??`unversioned`} → ${S.version})`),await Cs(`skill-update`),de?.(`files`),successResponse(t,200,SkillUpdateSuccessSchema,{name:g.name,version:S.version,...E===void 0?{}:{previousVersion:E},...D===void 0?{}:{checkpointRef:D}},{handler:`skill-update`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to update skill.`,{handler:`skill-update`,cause:e})}},{handler:`skill-update`,method:`POST`});function Pu(e){let t=new Map;for(let s of e){let e=s.path.split(`/`).filter(Boolean);e.pop();for(let g=1;g<=e.length;g++){let S=e.slice(0,g).join(`/`);t.set(S,Math.max(t.get(S)??0,s.modifiedTs))}}return[...t.entries()].map(([e,t])=>createWorkspaceSearchDocument({kind:`folder`,path:e,modifiedTs:t}))}function Fu(e,t){let s=t.trim().toLowerCase();if(!s||!e)return;let g=e.toLowerCase().indexOf(s);if(g<0)return;let S=Math.max(0,g-80),w=Math.min(e.length,g+s.length+120),E=S>0?`…`:``,D=w<e.length?`…`:``;return`${E}${e.slice(S,w).replace(/\s+/g,` `).trim()}${D}`}function Iu(e){return e===`autocomplete`||e===`full_text`||e===`omnibar`?e:`omnibar`}function Lu(e){let t=typeof e==`string`?e.split(`,`):Array.isArray(e)?e:void 0;if(!t)return;let s=t.filter(e=>e===`page`||e===`folder`||e===`content`||e===`file`);return s.length>0?s:void 0}function Ru(e){if(typeof e==`boolean`)return e;if(e===`true`)return!0;if(e===`false`)return!1}function zu(e){return e===`omnibar`||e===`mcp`||e===`http`?e:`http`}async function Bu(e,t,s,g){let S=g.documents.filter(e=>!isHiddenDocName(e.path)),w=S.reduce((e,t)=>e+(t.kind===`page`?1:0),0);if(!ze?.isEnabled()||s!==!0)return{queryEmbedMs:null,pageTotal:w,capable:!1};ze.embedCorpus(S);let E,D=null;if(t===`full_text`&&e.trim().length>=3){let t=performance.now(),s=await ze.queryScores(e,S);if(D=performance.now()-t,s&&s.size>0){let e=Be?.();E=e===void 0?{scores:s}:{scores:s,similarityFloor:e}}}let O=ze.getStatus();return{input:E,status:{capable:O.capable,applied:!1,coverage:{embedded:O.embeddedCount,total:w}},queryEmbedMs:D,pageTotal:w,capable:O.capable}}function Vu(e,t){return{kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?Fu(e.document.content,t):void 0}}async function Hu(e){let t=performance.now();if(Zu())return{query:e.query,intent:e.intent,results:[],elapsedMs:Math.max(0,performance.now()-t),ready:!1};let{corpus:s,truncated:g}=await Qu(),S=await Bu(e.query,e.intent,e.semanticParam,s),w=searchWorkspaceCorpus(s,e.query,{intent:e.intent,ranking:e.ranking,scopes:e.scopes,limit:e.limit,semantic:S.input}).map(t=>Vu(t,e.query)),E;if(S.status){let t=w.reduce((e,t)=>e+(t.signals.vector===void 0?0:1),0),s=t>0;E={...S.status,applied:s},recordSemanticQuery({outcome:S.capable?s?`applied`:S.status.coverage.embedded===0?`warming`:`no_match`:`incapable`,source:e.source,capable:S.capable,embedded:S.status.coverage.embedded,total:S.pageTotal,queryEmbedMs:S.queryEmbedMs,vectorContributors:t})}return{query:e.query,intent:e.intent,results:w,elapsedMs:Math.max(0,performance.now()-t),ready:!0,...E?{semantic:E}:{},...g?{truncated:!0}:{}}}function Uu(){let e=eu(`project`);if(!existsSync(e))return[];let t;try{t=readdirSync(e,{withFileTypes:!0})}catch{return[]}let s=[];for(let g of t.sort((e,t)=>e.name.localeCompare(t.name))){if(!g.isDirectory()||!SKILL_NAME_REGEX.test(g.name))continue;let t=resolve(e,g.name,`SKILL.md`);try{let e=statSync(t);s.push({name:g.name,absolutePath:t,mtimeMs:e.mtimeMs,size:e.size})}catch{}}return s}function Wu(){let e=[];for(let t of Uu()){let s=t.name,g=``;try{let{frontmatter:e,body:S}=Gl(readFileSync(t.absolutePath,`utf-8`));typeof e.name==`string`&&e.name&&(s=e.name),g=`${typeof e.description==`string`?e.description:``}\n\n${S}`.trim()}catch{}e.push(createWorkspaceSearchDocument({kind:`page`,path:skillLiveDocName(`project`,t.name),title:s,content:g,modifiedTs:t.mtimeMs}))}return e}function Gu(e){return`${e.modified}\0${e.size}\0${e.canonicalPath}\0${e.inode}\0${e.aliases.join(`\0`)}`}let Ku=new Map;async function qu(){let e=[],t=[],s=new Set;for(let[g,S]of E()){if(isSystemDoc(g)||isConfigDoc(g)||g.startsWith(`.ok/skills/`))continue;if(S.kind===`file`){t.push(createWorkspaceSearchDocument({kind:`file`,path:g,modifiedTs:Date.parse(S.modified),aliases:S.aliases}));continue}s.add(g);let w=Gu(S),E=Ku.get(g);if(E&&E.key===w){e.push(E.doc);continue}let D=``,O=g,k=!1;try{D=await readFile$1(S.canonicalPath,`utf-8`)}catch(e){k=!0,console.warn(`[search] Failed to read ${g}:`,e)}if(!k)try{O=extractPageTitle(D,g)}catch(e){console.warn(`[search] Failed to extract title for ${g}:`,e)}let j=createWorkspaceSearchDocument({kind:`page`,path:g,title:O,content:D,modifiedTs:Date.parse(S.modified),aliases:S.aliases});k||Ku.set(g,{key:w,doc:j}),e.push(j)}for(let e of Ku.keys())s.has(e)||Ku.delete(e);let g=getSearchMaxEntries(),S=t,w=!1;return t.length>g&&(w=!0,S=[...t].sort((e,t)=>e.path.split(`/`).length-t.path.split(`/`).length||e.path.localeCompare(t.path)).slice(0,g),getLogger(`search`).warn({dropped:t.length-S.length,retained:S.length,limit:g},`[search] corpus name-only file tier truncated at OK_SEARCH_MAX_ENTRIES`),searchCorpusTruncatedCounter().add(1)),{documents:[...e,...Wu(),...S,...Pu([...e,...S])],truncated:w}}function Ju(){return Uu().map(e=>`${e.name} ${e.mtimeMs} ${e.size}`).join(``)}function Yu(){return O?`gen:${O()}|skills${Ju()}`:`${[...E()].filter(([e])=>!isSystemDoc(e)&&!isConfigDoc(e)).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}\0${Gu(t)}`).join(``)}|skills${Ju()}`}let Xu=Me===void 0;Me?.then(()=>{Xu=!0},e=>{Xu=!0,log$6.warn({err:e,handler:`search`},`[api] ready gate rejected — search serves the partial index`)});function Zu(){return!Xu}async function Qu(){let e=`${g}${ye??``}`,t=Yu(),s=workspaceSearchCaches.get(e);if(s?.fingerprint===t&&s.corpus)return{corpus:s.corpus,truncated:s.truncated??!1};if(s?.fingerprint===t&&s.pending)return s.pending;let S=qu().then(({documents:e,truncated:t})=>({corpus:createWorkspaceSearchCorpus(e),truncated:t}));workspaceSearchCaches.set(e,{fingerprint:t,pending:S});try{let s=await S;return workspaceSearchCaches.get(e)?.pending===S&&workspaceSearchCaches.set(e,{fingerprint:t,corpus:s.corpus,truncated:s.truncated}),s}catch(t){throw workspaceSearchCaches.get(e)?.pending===S&&workspaceSearchCaches.delete(e),t}}function $u(){if(process.env.NODE_ENV!==`test`)for(let e of[0,1e3,3e3])setTimeout(()=>{Qu().catch(e=>{console.warn(`[search] Failed to prewarm workspace search cache:`,e)})},e)}$u();async function ed(e,t){if(e.method===`GET`)return td(e,t);if(e.method===`POST`)return nd(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`search`,extraHeaders:{Allow:`GET, POST`}})}let td=withValidation(EmptyRequestSchema,async(e,t)=>{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`limit`),S=s.searchParams.get(`query`)??``,w=Iu(s.searchParams.get(`intent`)),E=nu(s.searchParams.get(`ranking`)),D=Lu(s.searchParams.get(`scope`)??s.searchParams.get(`scopes`)),O=Ru(s.searchParams.get(`semantic`)),k=zu(s.searchParams.get(`source`)),j=g===null?void 0:Number(g);if(S.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-get`});return}try{successResponse(t,200,SearchSuccessSchema,await Hu({query:S,intent:w,ranking:E,scopes:D,limit:j,semanticParam:O,source:k}),{handler:`search-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to search workspace.`,{handler:`search-get`,cause:e})}},{handler:`search-get`,method:`GET`,skipBodyParse:!0}),nd=withValidation(SearchRequestSchema,async(e,t,s)=>{let g=typeof s.query==`string`?s.query:``,S=Iu(s.intent),w=nu(s.ranking),E=Lu(s.scopes??s.scope),D=typeof s.limit==`number`?s.limit:void 0,O=Ru(s.semantic),k=zu(s.source);if(g.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-post`});return}try{successResponse(t,200,SearchSuccessSchema,await Hu({query:g,intent:S,ranking:w,scopes:E,limit:D,semanticParam:O,source:k}),{handler:`search-post`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to search workspace.`,{handler:`search-post`,cause:e})}},{handler:`search-post`,method:`POST`}),rd=withValidation(EmptyRequestSchema,async(e,t)=>{try{successResponse(t,200,SkillInstallStateSuccessSchema,{...await readSkillInstallStateSnapshot(homedir())},{handler:`skill-install-state`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read skill install state.`,{handler:`skill-install-state`,cause:e})}},{handler:`skill-install-state`,method:`GET`,skipBodyParse:!0,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`skill-install-state`})});async function ad(e,t){if(checkLocalOpSecurity(e,t,{handler:`handoff`}))try{await handleHandoffDispatch(e,t,{contentDir:g,platform:process.platform,isSchemeRegistered:Tt.probeWithCache})}catch(e){t.headersSent||(log$6.error({err:e},`[handoff] route wrapper failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`handoff`,cause:e}))}}async function od(e,t){if(checkLocalOpSecurity(e,t,{handler:`spawn-cursor`}))try{await handleSpawnCursor(e,t,{contentDir:g,platform:process.platform})}catch(e){t.headersSent||(log$6.error({err:e},`[spawn-cursor] route wrapper failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`spawn-cursor`,cause:e}))}}let sd=withValidation(ShareConstructUrlRequestSchema,async(e,t,s)=>{try{if(!ye){emitShareConstructUrlLog(`no-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!isValidSharePath(s.kind===`doc`?s.docPath:s.folderPath,s.kind)){emitShareConstructUrlLog(`invalid-path`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`invalid-path`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let e=readGitHeadBranch(ye);if(e===null){if(readOriginGitHubRepo(ye).kind===`no-remote`){emitShareConstructUrlLog(`no-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}emitShareConstructUrlLog(`detached-head`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`detached-head`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let S=readOriginGitHubRepo(ye);if(S.kind===`no-remote`){emitShareConstructUrlLog(`no-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(S.kind===`non-github`){emitShareConstructUrlLog(`non-github-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`non-github-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!branchExistsOnOrigin(ye,e)){emitShareConstructUrlLog(`branch-not-on-origin`,{branchExists:!1,kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`branch-not-on-origin`,branch:e},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let w=toGitRelativePath(ye,g);if(w===null)throw Error(`content dir is not contained within the project dir`);let E=s.kind===`doc`?s.docPath!==``:s.folderPath!==``;w!==``&&E&&getLogger(`share`).warn({action:`construct-url`,kind:s.kind},`[share] content.dir != "." — non-root share URL omits the content.dir prefix; the github.com link may point at the wrong subtree. In-app receive navigation is content-relative and lands correctly.`);let D;if(s.kind===`doc`)D=buildGitHubBlobUrl(S.owner,S.repo,e,s.docPath);else{let t=s.folderPath===``?w:s.folderPath;D=buildGitHubTreeUrl(S.owner,S.repo,e,t)}let O=`${SHARE_BASE_URL}${encodeShareUrl(D)}`;emitShareConstructUrlLog(`ok`,{branchExists:!0,kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!0,shareUrl:O,sharedUrl:D,branch:e},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG,cause:e})}},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG})}),cd=withValidation(EmptyRequestSchema,async(e,t)=>{try{if(!ye){errorResponse(t,500,`urn:ok:error:internal-server-error`,`projectDir is not configured for this server.`,{handler:BRANCH_INFO_HANDLER_TAG});return}let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`branch`),S=s.searchParams.get(`path`),w=s.searchParams.get(`kind`)===`folder`?`folder`:`doc`;if(!isValidBranchName(g)){errorResponse(t,400,`urn:ok:error:invalid-request`,`branch query param missing or malformed.`,{handler:BRANCH_INFO_HANDLER_TAG});return}if(!isValidBranchInfoPath(S,w)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path query param missing or malformed.`,{handler:BRANCH_INFO_HANDLER_TAG});return}successResponse(t,200,BranchInfoResponseSchema,await computeBranchInfo(ye,g,S,w),{handler:BRANCH_INFO_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:BRANCH_INFO_HANDLER_TAG,cause:e})}},{handler:BRANCH_INFO_HANDLER_TAG,method:`GET`,skipBodyParse:!0}),ld=withValidation(CheckoutRequestSchema,async(e,t,s)=>{if(extractActorIdentity(s,Ce).kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:CHECKOUT_HANDLER_TAG});return}if(!ye){errorResponse(t,500,`urn:ok:error:internal-server-error`,`projectDir is not configured for this server.`,{handler:CHECKOUT_HANDLER_TAG});return}try{successResponse(t,200,CheckoutResponseSchema,await withParentLock(()=>runCheckoutFlow(ye,s.branch)),{handler:CHECKOUT_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:CHECKOUT_HANDLER_TAG,cause:e})}},{handler:CHECKOUT_HANDLER_TAG,method:`POST`});async function ud(e){let[t,...s]=ve,g=[...s,...e];return await new Promise((e,s)=>{let S=spawn(t,g,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),w=!1,E=setTimeout(()=>{w=!0,S.kill(`SIGTERM`)},SHARE_PUBLISH_TIMEOUT_MS),D=[],O=[];S.stdout.on(`data`,e=>D.push(e)),S.stderr.on(`data`,e=>O.push(e)),S.on(`close`,t=>{if(clearTimeout(E),w){s(Error(`share subprocess timed out after ${SHARE_PUBLISH_TIMEOUT_MS}ms`));return}let g=Buffer.concat(D).toString(`utf-8`);if(t!==0){let e=redactShareSubprocessStderr(Buffer.concat(O).toString(`utf-8`)).slice(0,500);console.warn(`[share] subprocess exited code=${t} stderr=${e}`)}e({stdout:g,code:t})}),S.on(`error`,e=>{clearTimeout(E),s(e)})})}let dd=withValidation(EmptyRequestSchema,async(e,t)=>{if(!We.tryAcquire(`/api/share/publish/owners`)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A share owners operation is already in progress.`,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG,extraHeaders:{"Retry-After":`5`}});return}try{let{stdout:e}=await ud([`share`,`owners`,`--json`]),s=parseOwnersEvent(pickTerminalJsonLine(e));emitSharePublishLog(`owners-list`,s.ok?`ok`:s.error,s.ok?{count:s.owners.length}:void 0),successResponse(t,200,SharePublishOwnersResponseSchema,s,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG,cause:e})}finally{We.release(SHARE_PUBLISH_OWNERS_KEY)}},{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG,method:`GET`,skipBodyParse:!0,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG})}),fd=withValidation(EmptyRequestSchema,async(e,t)=>{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`owner`)??``,S=s.searchParams.get(`name`)??``;if(!isValidShareOwnerName(g)||!isValidShareRepoName(S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`owner and name query params must be valid GitHub identifiers.`,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG});return}if(!We.tryAcquire(`/api/share/publish/name-check`)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A share name-check operation is already in progress.`,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG,extraHeaders:{"Retry-After":`5`}});return}try{let{stdout:e}=await ud([`share`,`name-check`,`--owner`,g,`--name`,S,`--json`]),s=parseNameCheckEvent(pickTerminalJsonLine(e));emitSharePublishLog(`name-check`,s.ok?`ok`:s.error,s.ok?{available:s.available}:void 0),successResponse(t,200,SharePublishNameCheckResponseSchema,s,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG,cause:e})}finally{We.release(SHARE_PUBLISH_NAME_CHECK_KEY)}},{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG,method:`GET`,skipBodyParse:!0,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG})}),pd=withValidation(SharePublishRequestSchema,async(e,t,s)=>{if(!ye){emitSharePublishLog(`publish-create`,`no-project`),successResponse(t,200,SharePublishResponseSchema,{ok:!1,error:`no-project`},{handler:SHARE_PUBLISH_HANDLER_TAG});return}if(!isValidShareOwnerName(s.owner)||!isValidShareRepoName(s.name)){errorResponse(t,400,`urn:ok:error:invalid-request`,`owner and name must be valid GitHub identifiers.`,{handler:SHARE_PUBLISH_HANDLER_TAG});return}if(!We.tryAcquire(`/api/share/publish`)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A share publish operation is already in progress.`,{handler:SHARE_PUBLISH_HANDLER_TAG,extraHeaders:{"Retry-After":`5`}});return}try{let e=[`share`,`publish`,`--owner`,s.owner,`--name`,s.name,`--visibility`,s.visibility,`--project-dir`,ye,`--json`];s.description!==void 0&&s.description.length>0&&e.push(`--description`,s.description);let{stdout:g}=await ud(e),S=parsePublishEvent(pickTerminalJsonLine(g));emitSharePublishLog(`publish-create`,S.ok?`ok`:S.error),S.ok&&_e?.()?.refreshRemote().catch(()=>{}),successResponse(t,200,SharePublishResponseSchema,S,{handler:SHARE_PUBLISH_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_PUBLISH_HANDLER_TAG,cause:e})}finally{We.release(SHARE_PUBLISH_KEY)}},{handler:SHARE_PUBLISH_HANDLER_TAG,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_HANDLER_TAG})}),md=withValidation(ClientLogsRequestSchema,async(e,t,s)=>{try{let e=getLogger(`renderer`);for(let t of s.entries)try{e[t.level]({...t.fields,source:`renderer-console`,transport:`web`,...t.sourceId?{sourceId:t.sourceId}:{},...t.lineNumber===void 0?{}:{lineNumber:t.lineNumber},...t.ts===void 0?{}:{clientTs:t.ts}},t.event??t.message)}catch{}successResponse(t,200,ClientLogsSuccessSchema,{accepted:s.entries.length},{handler:`client-logs`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`client-logs`,cause:e})}},{handler:`client-logs`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`client-logs`})}),hd=ye?getLocalDir(ye):null;async function gd(e,t){if(e.method===`DELETE`){let s=e.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`api-config`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`api-config`});return}hd&&clearArmedPaneTarget(hd),t.setHeader(`Cache-Control`,`no-store`),t.statusCode=204,t.end();return}if(e.method===`GET`||e.method===`HEAD`){try{let s=e.headers.host,g={collabUrl:s?`ws://${s}/collab`:null,previewUrl:null,port:hd?readServerLock(hd)?.port??0:0,paneTarget:hd?readArmedPaneTarget(hd):null,singleFile:Ue};if(e.method===`HEAD`){t.setHeader(`Content-Type`,`application/json`),t.setHeader(`Cache-Control`,`no-store`),t.setHeader(`X-Content-Type-Options`,`nosniff`),t.statusCode=200,t.end();return}successResponse(t,200,ApiConfigSuccessSchema,g,{handler:`api-config`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`api-config`,cause:e})}return}errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`api-config`,extraHeaders:{Allow:`GET, HEAD, DELETE`}})}let _d=`local-op-embeddings-set-key`,vd=`local-op-embeddings-clear-key`,yd=`/api/local-op/embeddings`,bd=withValidation(LocalOpEmbeddingsSetKeyRequestSchema,async(e,t,s)=>{if(!We.tryAcquire(yd)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An embeddings key operation is already in progress.`,{handler:_d,extraHeaders:{"Retry-After":`5`}});return}try{await new FileEmbeddingsBackend(Ve).set(s.key),successResponse(t,200,LocalOpEmbeddingsMutationSuccessSchema,{keyPresent:!0},{handler:_d,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to store the key.`,{handler:_d,cause:e})}finally{We.release(yd)}},{handler:_d,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:_d})}),xd=withValidation(EmptyRequestSchema,async(e,t)=>{if(!We.tryAcquire(yd)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An embeddings key operation is already in progress.`,{handler:vd,extraHeaders:{"Retry-After":`5`}});return}try{await clearEmbeddingsKeyFromAllBackends(Ve),successResponse(t,200,LocalOpEmbeddingsMutationSuccessSchema,{keyPresent:!1},{handler:vd,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to clear the key.`,{handler:vd,cause:e})}finally{We.release(yd)}},{handler:vd,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:vd})}),Sd=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=!1,s=!1,g=!1,S=0;if(ze){let t=ze.getStatus();e=t.enabled,s=t.ready,g=t.capable,S=t.embeddedCount}let E=await new FileEmbeddingsBackend(Ve).get(),D=process.env.OK_EMBEDDINGS_API_KEY??null,O=E?`file`:D?`env`:null,k=O!==null,j=E??D,F=j&&j.length>=8?j.slice(-4):null,L=0;for(let[e]of w())!isSystemDoc(e)&&!isConfigDoc(e)&&!isHiddenDocName(e)&&(L+=1);successResponse(t,200,SemanticIndexStatusSchema,{enabled:e,keyPresent:k,keySource:O,keyHint:F,ready:s,capable:g,embedded:S,total:L},{handler:`semantic-status`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`semantic-status`,cause:e})}},{handler:`semantic-status`,method:`GET`,skipBodyParse:!0}),Cd={"/api/config":gd,"/api/asset":Sc,"/api/asset-text":wc,"/api/document":As,"/api/documents":Ns,"/api/backlinks":Ps,"/api/backlink-counts":Is,"/api/forward-links":Rs,"/api/link-graph":$s,"/api/dead-links":nc,"/api/orphans":ec,"/api/hubs":tc,"/api/tags":kl,"/api/pages":Pc,"/api/folder-config":Rl,"/api/template":Wl,"/api/templates":Ul,"/api/skill":cu,"/api/skill-file":Eu,"/api/skills":su,"/api/skills/management":pu,"/api/skill/install":Du,"/api/skill/uninstall":Ou,"/api/skill/restore":Mu,"/api/skill/update":Nu,"/api/skill-targets":ku,"/api/search":ed,"/api/semantic-status":Sd,"/api/suggest-links":Fc,"/api/page-headings":Ac,"/api/create-page":Dc,"/api/create-folder":Oc,"/api/duplicate-path":kc,"/api/rename-path":jc,"/api/delete-path":Mc,"/api/trash/cleanup":Nc,"/api/upload":Ic,"/api/agent-write":Ts,"/api/agent-write-md":Ds,"/api/frontmatter-patch":Os,"/api/agent-patch":rc,"/api/agent-undo":ic,"/api/agent-activity":ac,"/api/agent-burst-diff":oc,"/api/save-version":dc,"/api/history":fc,"/api/rollback":mc,"/api/metrics/reconciliation":hc,"/api/metrics/parse-health":gc,"/api/metrics/agent-presence":yc,"/api/__embed-detect":bc,"/api/server-info":_c,"/api/share/construct-url":sd,"/api/git/branch-info":cd,"/api/git/checkout":ld,"/api/share/publish/owners":dd,"/api/share/publish/name-check":fd,"/api/share/publish":pd,"/api/principal":vc,"/api/rescue":Ec,"/api/workspace":xc,"/api/sync/status":gl,"/api/sync/trigger":_l,"/api/sync/conflicts":vl,"/api/sync/conflict-content":xl,"/api/sync/resolve-conflict":yl,"/api/local-op/clone":Hc,"/api/local-op/ok-init":Kc,"/api/local-op/auth/login":$c,"/api/local-op/auth/status":al,"/api/local-op/auth/repos":ll,"/api/local-op/auth/signout":fl,"/api/local-op/auth/set-identity":hl,"/api/local-op/embeddings/set-key":bd,"/api/local-op/embeddings/clear-key":xd,"/api/installed-agents":Ol,"/api/spawn-cursor":od,"/api/handoff":ad,"/api/install-skill":Dl,"/api/skill/install-state":rd,"/api/seed/plan":Cl,"/api/seed/apply":Tl,"/api/seed/packs":El,"/api/client-logs":md};H&&(Cd[`/api/test-reset`]=cc,Cd[`/api/test-flush-git`]=sc,Cd[`/api/test-rescan-backlinks`]=lc,Cd[`/api/test-rescan-files`]=uc);let wd=new Set(`/api/upload./api/create-page./api/create-folder./api/duplicate-path./api/rename-path./api/delete-path./api/trash/cleanup./api/agent-write./api/agent-write-md./api/frontmatter-patch./api/agent-patch./api/agent-undo./api/save-version./api/rollback./api/sync/trigger./api/sync/resolve-conflict./api/git/checkout./api/test-reset./api/test-flush-git./api/test-rescan-backlinks./api/test-rescan-files./api/install-skill./api/folder-config./api/template./api/skill./api/skill-file./api/skill/install./api/skill/uninstall./api/skill/restore./api/skill/update./api/skills/management./api/skill-targets./api/seed/apply./api/client-logs`.split(`.`)),Td=[`/api/local-op/`];return{priority:100,async onRequest({request:e,response:t}){let s=e.url?.split(`?`)[0];if(!s)return;let g=t=>{let s=e.headers[t];if(s!==void 0)return Array.isArray(s)?s.join(`, `):s};if(recordEmbedProbe({ts:Date.now(),url:s,method:e.method??``,ua:g(`user-agent`),origin:g(`origin`),referer:g(`referer`),host:g(`host`),remote:e.socket?.remoteAddress,secChUa:g(`sec-ch-ua`),secChUaMobile:g(`sec-ch-ua-mobile`),secChUaPlatform:g(`sec-ch-ua-platform`),secFetchSite:g(`sec-fetch-site`),secFetchDest:g(`sec-fetch-dest`),secFetchMode:g(`sec-fetch-mode`),secFetchUser:g(`sec-fetch-user`)}),s.startsWith(`/api/`)){let s=e.headers.origin;if(s!==void 0&&!isAllowedApiOrigin(s)){errorResponse(t,403,`urn:ok:error:invalid-origin`,`Origin not allowed.`,{handler:`api-origin-gate`});return}if(typeof t.setHeader==`function`&&(s!==void 0&&(t.setHeader(`Access-Control-Allow-Origin`,s),t.setHeader(`Vary`,`Origin`)),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, traceparent, tracestate, baggage, ${CLIENT_VERSION_HEADER.protocol}, ${CLIENT_VERSION_HEADER.runtime}, ${CLIENT_VERSION_HEADER.kind}`)),e.method===`OPTIONS`){t.writeHead(204),t.end();return}}if(wd.has(s)||Td.some(e=>s.startsWith(e))){let s=e.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`api-mutating-gate`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`api-mutating-gate`});return}}if(Ue&&s.startsWith(`/api/`)){let s=e.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`api-ephemeral-gate`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`api-ephemeral-gate`});return}}if(!s.startsWith(`/api/`))return;let S=propagation.extract(context.active(),e.headers),w=e.method??`GET`,E=s;s.startsWith(`/api/history/`)?E=`/api/history/:sha`:s.startsWith(`/api/tags/`)?E=`/api/tags/:name`:Cd[s]||(E=`/api/*`);let D=getTracer(),O=Date.now();await context.with(S,()=>D.startActiveSpan(`HTTP ${w} ${E}`,{kind:SpanKind.SERVER,attributes:{[ATTR_HTTP_REQUEST_METHOD]:w,[ATTR_HTTP_ROUTE]:E,[ATTR_URL_PATH]:s,[ATTR_URL_SCHEME]:`http`,[ATTR_USER_AGENT_ORIGINAL]:e.headers[`user-agent`]??``}},async g=>{try{let S=Cd[s],E=!1;if(S)E=!0,await S(e,t);else if(s.startsWith(`/api/history/`)){let g=decodeURIComponent(s.slice(13));g&&(E=!0,await pc(e,t,g))}else if(s.startsWith(`/api/tags/`)){let g=s.slice(10);g&&(E=!0,await jl(e,t,g))}E||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`api-dispatch`,detail:`No handler for ${w} ${s}`});let D=t.statusCode;g.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE,D),D>=500&&g.setStatus({code:SpanStatusCode.ERROR,message:`status ${D}`})}catch(e){throw g.recordException(e),g.setStatus({code:SpanStatusCode.ERROR,message:e instanceof Error?e.message:String(e)}),!t.headersSent&&!t.writableEnded&&!t.destroyed&&errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:E,cause:e}),e}finally{g.end();let e=(Date.now()-O)/1e3;httpDurationHist().record(e,{[ATTR_HTTP_REQUEST_METHOD]:w,[ATTR_HTTP_ROUTE]:E,[ATTR_HTTP_RESPONSE_STATUS_CODE]:t.statusCode})}}))}}}function errnoCode(e){let t=e?.code;return typeof t==`string`?t:void 0}function seedSingleDirBasenameIndex(e){let t;try{t=readdirSync(e.contentDir,{withFileTypes:!0})}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`read-failed`,s,e.contentDir);return}for(let s of t)s.isFile()&&isSupportedAssetFile(s.name,ASSET_EXTENSIONS)&&e.basenameIndex.add(s.name)}async function seedBasenameIndex(e){let t=e.contentDir,s=new Set;async function g(S){let w;try{w=await readdir(S,{withFileTypes:!0})}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`read-failed`,s,S);return}for(let E of w){let w=join(S,E.name),D=toPosix(relative(t,w));if(D.startsWith(`..`)||e.contentFilter?.isDirExcluded(D)&&E.isDirectory())continue;let O;try{O=await lstat(w)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`lstat-failed`,s,w);continue}if(O.isSymbolicLink()){let S;try{S=await realpath(w)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`realpath-failed`,s,w);continue}if(!isWithinDir(S,t)){e.onSkip?.(`symlink-escape`,void 0,w);continue}let E;try{E=await stat$1(S)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`symlink-stat-failed`,s,S);continue}if(s.has(E.ino))continue;s.add(E.ino),E.isDirectory()?await g(S):E.isFile()&&isSupportedAssetFile(w,LINKABLE_ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D);continue}if(O.isDirectory()){if(s.has(O.ino))continue;s.add(O.ino),await g(w);continue}O.isFile()&&isSupportedAssetFile(w,LINKABLE_ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D)}}await g(t)}var AutoStartDisabledError=class extends Error{constructor(e){super(e),this.name=`AutoStartDisabledError`}};const log$5=getLogger(`conflict-storage`);var ConflictStore=class{storePath;projectDir;branch;conflicts=[];constructor(e,t=`main`){this.storePath=join(getLocalDir(e),`conflicts.json`),this.projectDir=e,this.branch=t,this.load()}load(){if(!existsSync(this.storePath)){this.conflicts=[];return}try{let e=readFileSync(this.storePath,`utf-8`),t=JSON.parse(e);if(t.version!==1){log$5.warn({path:this.storePath},`[conflicts] unknown schema version — resetting`),this.conflicts=[];return}this.branch=t.branch??this.branch,this.conflicts=t.conflicts??[]}catch(e){log$5.warn({err:e},`[conflicts] failed to load conflicts.json — starting empty`),this.conflicts=[]}}save(){try{let e=dirname(this.storePath);existsSync(e)||mkdirSync(e,{recursive:!0});let t={version:1,branch:this.branch,conflicts:this.conflicts};writeFileSync(this.storePath,JSON.stringify(t,null,2),`utf-8`)}catch(e){log$5.warn({err:e},`[conflicts] failed to save conflicts.json`)}}addConflict(e){let t=this.conflicts.findIndex(t=>t.file===e.file);t===-1?this.conflicts.push(e):this.conflicts[t]=e,this.save()}removeConflict(e){this.conflicts=this.conflicts.filter(t=>t.file!==e),this.save()}clear(){this.conflicts=[],this.save()}count(){return this.conflicts.length}list(){return[...this.conflicts]}hasConflicts(){return this.conflicts.length>0}setBranch(e){this.branch=e}async resolveConflict(e,t,s,g=[]){if(!this.conflicts.find(t=>t.file===e))throw Error(`[conflicts] no conflict tracked for file: ${e}`);if(t===`content`&&s===void 0)throw Error(`[conflicts] strategy 'content' requires content parameter`);let{createGitInstance:S}=await import(`./git-handle-DdgvPBh6-Dv4DjLoy.mjs`),w=S(this.projectDir,{credentialArgs:g});switch(t){case`mine`:await w.git.raw([`checkout`,`--ours`,`--`,e]),await w.git.raw([`add`,`--`,e]);break;case`theirs`:await w.git.raw([`checkout`,`--theirs`,`--`,e]),await w.git.raw([`add`,`--`,e]);break;case`content`:{if(s===void 0)throw Error(`[conflicts] strategy 'content' requires content parameter`);let t=resolve(this.projectDir),g=resolve(t,e);if(!isWithinDir(g,t))throw Error(`[conflicts] file path escapes project directory: ${e}`);writeFileSync(g,s,`utf-8`),await w.git.raw([`add`,`--`,e]);break}case`delete`:await w.git.raw([`rm`,`--`,e]);break;default:throw Error(`[conflicts] unknown resolve strategy: ${t}`)}if(this.removeConflict(e),!this.hasConflicts())try{await w.git.raw([`commit`,`--no-edit`]),log$5.info({file:e},`[conflicts] all conflicts resolved — merge commit created`)}catch(t){let s=new Date().toISOString(),g=!1;try{let e=(await w.git.raw([`diff`,`--name-only`,`--diff-filter=U`])).split(`
|
|
1940
|
+
`:``)+t;composeAndWriteRawBody(te.dc.document,S,`agent`),recordFrontmatterEditSurface(`mcp-write`),ce=!0}se=!0},te.origin)})}finally{me?.touchMode(O,`idle`)}if(oe){let e;switch(oe.kind){case`invalid_value`:e={[oe.key]:oe.reason};break;case`reserved_key`:e={[oe.key]:`'${oe.key}' is reserved`};break;case`unknown_key`:e={[oe.key]:`'${oe.key}' is not a recognized key`};break;case`duplicate_target`:e={[oe.key]:`'${oe.key}' appears more than once`};break;case`reorder_mismatch`:e={__region__:`frontmatter reorder mismatch (expected: ${oe.expected.join(`, `)}; got: ${oe.got.join(`, `)})`};break;case`region_too_large`:e={__region__:`frontmatter region too large (${oe.bytes} > ${oe.limit} bytes)`};break;case`parse_failed`:e={__region__:`frontmatter region unparseable: ${oe.reason}`};break;case`invalid_path`:e={[oe.path.map(String).join(`.`)||`__path__`]:oe.reason};break;default:e={__region__:`unhandled frontmatter edit error (${String(oe)})`}}errorResponse(w,400,`urn:ok:error:invalid-frontmatter-patch`,`Frontmatter patch rejected: schema validation failed.`,{handler:`frontmatter-patch`,extensions:{fieldErrors:e}});return}if(se&&ue.length>0){if(recordContributor(D,O,k,j,void 0,Xi({clientName:F,clientVersion:L,label:B}),Y),incrementAgentWriteCalls(),_s(ee),ce){let e=await Ht(D);if(e?.kind===`failure`){Ut(w,e.failure,`frontmatter-patch`);return}if(e?.kind===`divergence`){Wt(w,`frontmatter-patch`);return}}Vt(D,`frontmatter-patch`)}fe?.setFocus(O,{agentName:k,currentDoc:D,writeKind:`write`,ts:Date.now()}),ge?.();let de=zt(D),_e=Bt();_e===0&&hintEmittedCounter().add(1,{"shadow.writer":`agent`,"agent.type":resolveAgentType(F)});let ve=Kt(ne);Mr(D,te.dc.document.getText(`source`).toString());let ye=en();ye.add(D);let Ce=computeBrokenOutboundLinks(te.dc.document.getText(`source`).toString(),D,ye,jr);successResponse(w,200,FrontmatterPatchSuccessSchema,{timestamp:ae,subscriberCount:de,systemSubscriberCount:_e,appliedKeys:ue,...J?{summary:J}:{},...ve?{warning:ve,warnings:[ve]}:{},brokenLinks:Ce},{handler:`frontmatter-patch`})}catch(e){if(e instanceof AgentSessionCapacityError){errorResponse(w,503,`urn:ok:error:too-many-agent-sessions`,`Too many agent sessions.`,{handler:`frontmatter-patch`,cause:e,extraHeaders:{"Retry-After":`10`}});return}log$6.error({err:e},`[frontmatter-patch] handler failed`),errorResponse(w,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`frontmatter-patch`,cause:e})}},{handler:`frontmatter-patch`,method:`POST`});function Ns(e){let t=e.getMap(`lifecycle`),s=t.get(`status`);if(typeof s!=`string`||s.length===0)return null;let g=t.get(`reason`);return{status:s,reason:typeof g==`string`?g:``}}let Ps=withValidation(EmptyRequestSchema,async(e,s)=>{try{let S=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`docName`)||`test-doc`;if(!isSafeDocName(S)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`document-read`});return}let w=Rt(S);if(isSystemDoc(w)||isConfigDoc(w)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`'${w}' is a reserved document name.`,{handler:`document-read`});return}let E=t.documents.get(w);if(E){successResponse(s,200,DocumentReadSuccessSchema,{docName:w,content:E.getText(`source`).toString(),lifecycle:Ns(E)},{handler:`document-read`});return}if(!existsSync(resolveContentEntryPath(g,`file`,w))){errorResponse(s,404,`urn:ok:error:doc-not-found`,`Document not found: ${w}.`,{handler:`document-read`});return}let D=await t.openDirectConnection(w);try{let e=D.document;if(!e){errorResponse(s,500,`urn:ok:error:doc-not-available`,`Document is not available.`,{handler:`document-read`});return}successResponse(s,200,DocumentReadSuccessSchema,{docName:w,content:e.getText(`source`).toString(),lifecycle:Ns(e)},{handler:`document-read`})}finally{await D.disconnect()}}catch(e){errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to read document.`,{handler:`document-read`,cause:e})}},{handler:`document-read`,method:`GET`,skipBodyParse:!0}),Is=withValidation(EmptyRequestSchema,async(e,t)=>{try{Me&&await Me.catch(e=>{log$6.warn({err:e,handler:`document-list`},`[api] ready gate rejected — responding with partial index`)});let s=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),S=s.searchParams.get(`dir`),D=s.searchParams.get(`showAll`)===`true`,O=s.searchParams.get(`depth`)===`1`?1:1/0;if(S)try{safeSubdir(g,S)}catch{errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid directory parameter.`,{handler:`document-list`});return}if(D&&Te&&showAllWantsNdjson(e)){let e=new AbortController;t.on(`close`,()=>{t.writableEnded||e.abort()}),t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let s=createStreamingErrorWriter(t,`document-list`),w=async e=>{t.writableEnded||t.destroyed||t.write(e)||await new Promise(e=>{let s=()=>{t.off(`drain`,s),t.off(`close`,s),e()};t.once(`drain`,s),t.once(`close`,s)})};try{let t=getShowAllMaxEntries(),s=streamShowAllEntries({contentDir:g,contentFilter:Te,dirFilter:S,getDocExtension,maxEntries:t,maxDepth:O,signal:e.signal}),E=0,D=await s.next();for(;!D.done;)await w(`${JSON.stringify(D.value)}\n`),E+=1,D=await s.next();let{truncated:k}=D.value;k&&log$6.info({handler:`document-list`,maxEntries:t,count:E},`[document-list][showAll] stream truncated at entry cap`),await w(`${JSON.stringify({type:`complete`,truncated:k,count:E})}\n`)}catch(e){!t.writableEnded&&!t.destroyed?s(500,`urn:ok:error:internal-server-error`,`Failed to list documents (showAll stream).`,{cause:e}):log$6.error({err:e,handler:`document-list`},`[document-list][showAll] stream failed after response ended`)}finally{t.writableEnded||t.end()}return}if(D&&Te){let e=`showAll:${O===1?`d1:`:``}${S??``}`,s=Ge.get(e);if(!s){let t=new AbortController,w=(async()=>{let e=[],s=getShowAllMaxEntries(),{truncated:w}=await walkContentDirForShowAll({contentDir:g,contentFilter:Te,dirFilter:S,documents:e,getDocExtension,maxEntries:s,maxDepth:O,signal:t.signal});return e.sort((e,t)=>{let s=e.kind===`folder`?e.path??``:e.docName??e.path??``,g=t.kind===`folder`?t.path??``:t.docName??t.path??``;return s.localeCompare(g)}),w&&log$6.info({handler:`document-list`,maxEntries:s,count:e.length},`[document-list][showAll] walk truncated at entry cap`),{documents:e,truncated:w}})();s={promise:w,controller:t,waiters:0};let E=s;Ge.set(e,E),w.finally(()=>{Ge.get(e)===E&&Ge.delete(e)})}let w=s;w.waiters+=1;let E=!1,D=()=>{t.writableEnded||E||(E=!0,--w.waiters,w.waiters<=0&&(w.controller.abort(),Ge.get(e)===w&&Ge.delete(e)))};t.on(`close`,D);try{let{documents:e,truncated:s}=await w.promise;if(E)return;successResponse(t,200,DocumentListSuccessSchema,s?{documents:e,truncated:s}:{documents:e},{handler:`document-list`})}catch(e){if(E)return;errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list documents (showAll mode).`,{handler:`document-list`,cause:e})}finally{t.removeListener(`close`,D)}return}let j=w(),F=E(),B=k?.()??new Map,H=[];for(let[e,t]of B)S&&!e.startsWith(`${S}/`)&&e!==S||H.push({kind:`folder`,path:e,size:0,modified:t.modified,docExt:`.md`,isSymlink:!1,canonicalDocName:null,targetPath:null});let q=[];try{let e=st(j);Xe?.signature!==e&&(Xe={signature:e,assets:collectReferencedAssets({contentDir:g,fileIndex:j,readMarkdown:e=>{try{return readFileSync(e,`utf-8`)}catch{return null}},isExcluded:Te?e=>Te.isPathIgnored(e):void 0})}),q=Xe?.assets??[]}catch(e){Xe=null,console.warn(`[document-list] asset collection failed; returning documents only:`,e)}let ee=new Set;for(let e of q)S&&!e.path.startsWith(`${S}/`)&&e.path!==S||(ee.add(e.path),H.push({kind:`asset`,docName:e.path,docExt:e.assetExt,path:e.path,assetExt:e.assetExt,mediaKind:e.mediaKind,referencedBy:e.referencedBy,size:e.size,modified:e.modified,isSymlink:!1,canonicalDocName:null,targetPath:null}));for(let[e,t]of F){if(t.kind===`markdown`){if(S&&!e.startsWith(`${S}/`)&&e!==S)continue;let s=getDocExtension(e);H.push({kind:`document`,docName:e,docExt:s,size:t.size,modified:t.modified,isSymlink:!1,canonicalDocName:null,targetPath:null});for(let w of t.aliases){if(S&&!w.startsWith(`${S}/`)&&w!==S)continue;let E=toPosix(relative(g,t.canonicalPath));H.push({kind:`document`,docName:w,docExt:s,size:t.size,modified:t.modified,isSymlink:!0,canonicalDocName:e,targetPath:E})}continue}if((!S||e===S||e.startsWith(`${S}/`))&&!ee.has(e)){let s=synthesizeShowAllAssetExt(e);H.push({kind:`file`,docName:e,path:e,docExt:`.${s}`,assetExt:s,size:t.size,modified:t.modified,isSymlink:!1,canonicalDocName:null,targetPath:null})}for(let s of t.aliases){if(!(!S||s===S||s.startsWith(`${S}/`))||ee.has(s))continue;let w=toPosix(relative(g,t.canonicalPath)),E=synthesizeShowAllAssetExt(s);H.push({kind:`file`,docName:s,path:s,docExt:`.${E}`,assetExt:E,size:t.size,modified:t.modified,isSymlink:!0,canonicalDocName:e,targetPath:w})}}let J=L?.()??new Map;if(J.size>0){let e=e=>!S||e===S||e.startsWith(`${S}/`),t=new Map;for(let[e,s]of J){let g=t.get(s);g?g.push(e):t.set(s,[e])}for(let[s,S]of t){let t=B.get(s),w=t?toPosix(relative(g,t.canonicalPath)):s;for(let g of S)e(g)&&H.push({kind:`folder`,path:g,size:0,modified:t?.modified??`1970-01-01T00:00:00.000Z`,docExt:`.md`,isSymlink:!0,canonicalDocName:s,targetPath:w})}let s=(s,g)=>{for(let S=s.indexOf(`/`);S!==-1;S=s.indexOf(`/`,S+1)){let w=t.get(s.slice(0,S));if(!w)continue;let E=s.slice(S);for(let t of w){let s=`${t}${E}`;e(s)&&g(s)}}};for(let[e,t]of B)s(e,s=>{H.push({kind:`folder`,path:s,size:0,modified:t.modified,docExt:`.md`,isSymlink:!0,canonicalDocName:e,targetPath:toPosix(relative(g,t.canonicalPath))})});for(let[e,t]of F)s(e,s=>{let S=toPosix(relative(g,t.canonicalPath));if(t.kind===`markdown`)H.push({kind:`document`,docName:s,docExt:getDocExtension(e),size:t.size,modified:t.modified,isSymlink:!0,canonicalDocName:e,targetPath:S});else{let g=synthesizeShowAllAssetExt(s);H.push({kind:`file`,docName:s,path:s,docExt:`.${g}`,assetExt:g,size:t.size,modified:t.modified,isSymlink:!0,canonicalDocName:e,targetPath:S})}})}H.sort((e,t)=>{let s=e.kind===`folder`?e.path??``:e.docName??e.path??``,g=t.kind===`folder`?t.path??``:t.docName??t.path??``;return s.localeCompare(g)}),successResponse(t,200,DocumentListSuccessSchema,{documents:H},{handler:`document-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list documents.`,{handler:`document-list`,cause:e})}},{handler:`document-list`,method:`GET`,skipBodyParse:!0}),Rs=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`backlinks`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!s){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`backlinks`});return}if(!isSafeDocName(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`backlinks`});return}successResponse(t,200,BacklinksSuccessSchema,{docName:s,backlinks:ce.getBacklinks(s).map(e=>({source:e.source,anchor:e.anchor,title:Dt(e.source),snippet:e.snippet}))},{handler:`backlinks`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read backlinks.`,{handler:`backlinks`,cause:e})}},{handler:`backlinks`,method:`GET`,skipBodyParse:!0}),$s=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`backlink-counts`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`docNames`);if(!s){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docNames parameter.`,{handler:`backlink-counts`});return}let g={};for(let e of s.split(`,`)){let t=e.trim();!t||!isSafeDocName(t)||(g[t]=ce.getBacklinkCount(t))}successResponse(t,200,BacklinkCountsSuccessSchema,{counts:g},{handler:`backlink-counts`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read backlink counts.`,{handler:`backlink-counts`,cause:e})}},{handler:`backlink-counts`,method:`GET`,skipBodyParse:!0}),ec=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`forward-links`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!s){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`forward-links`});return}if(!isSafeDocName(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`forward-links`});return}let g=en();successResponse(t,200,ForwardLinksSuccessSchema,{docName:s,forwardLinks:ce.getForwardLinkEntries(s).map(e=>e.kind===`doc`?{kind:`doc`,docName:e.target,anchor:e.anchor,title:jt(e.target,g),snippet:e.snippet}:{kind:`external`,url:e.url,title:e.label??e.url,snippet:e.snippet})},{handler:`forward-links`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read forward links.`,{handler:`forward-links`,cause:e})}},{handler:`forward-links`,method:`GET`,skipBodyParse:!0}),tc=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`link-graph`});return}try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`docName`);if(g&&!isSafeDocName(g)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`link-graph`});return}let S=s.searchParams.get(`degrees`);if(S&&!g){errorResponse(t,400,`urn:ok:error:invalid-request`,`docName is required when degrees is provided.`,{handler:`link-graph`});return}let w,E;if(S&&g){let e=Number.parseInt(S,10);if(!Number.isFinite(e)||e<0){errorResponse(t,400,`urn:ok:error:invalid-request`,`degrees must be a non-negative integer.`,{handler:`link-graph`});return}({nodes:w,links:E}=ce.getLinkGraphNeighborhood(g,e))}else ({nodes:w,links:E}=ce.getLinkGraph());let D=en();successResponse(t,200,LinkGraphSuccessSchema,{nodes:w.map(e=>{if(e.kind===`doc`){let t=It(e.docName,D);return{id:e.id,kind:`doc`,docName:e.docName,anchor:e.anchor??null,label:jt(e.docName,D),cluster:t.cluster??null,category:t.category??null,tags:t.tags??null}}return{id:e.id,kind:`external`,url:e.url,label:e.label??e.url}}),links:E},{handler:`link-graph`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read link graph.`,{handler:`link-graph`,cause:e})}},{handler:`link-graph`,method:`GET`,skipBodyParse:!0}),nc=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`orphans`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`mode`)??`both`;if(!isOrphanMode(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid orphan mode. Allowed values: incoming, outgoing, both.`,{handler:`orphans`});return}successResponse(t,200,OrphansSuccessSchema,{orphans:ce.getOrphans([...w().keys()],s).map(e=>({docName:e,title:Dt(e)}))},{handler:`orphans`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read orphan pages.`,{handler:`orphans`,cause:e})}},{handler:`orphans`,method:`GET`,skipBodyParse:!0}),rc=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`hubs`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`limit`),g=s?Number.parseInt(s,10):20,S=Number.isFinite(g)&&g>0?g:20,w=en();successResponse(t,200,HubsSuccessSchema,{hubs:ce.getHubs(S).map(e=>({docName:e.docName,title:jt(e.docName,w),count:e.count}))},{handler:`hubs`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read hub pages.`,{handler:`hubs`,cause:e})}},{handler:`hubs`,method:`GET`,skipBodyParse:!0}),ic=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`dead-links`});return}try{let s=new URL(e.url??``,`http://localhost`).searchParams.getAll(`sourceDocName`);if(s.some(e=>e.length===0||!isSafeDocName(e))){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid sourceDocName.`,{handler:`dead-links`});return}let g=s.length?[...new Set(s.map(e=>Rt(e)))]:void 0;successResponse(t,200,DeadLinksSuccessSchema,{deadLinks:ce.getDeadLinks(en(),g).map(e=>({target:e.target,sources:e.sources.map(e=>({source:e.source,title:Dt(e.source),snippet:e.snippet}))}))},{handler:`dead-links`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read dead links.`,{handler:`dead-links`,cause:e})}},{handler:`dead-links`,method:`GET`,skipBodyParse:!0}),ac=withValidation(AgentPatchRequestSchema,async(S,w,E)=>{try{let{find:S,replace:D,offset:O}=E,k=requireNonEmptyDocName(E.docName,w,`agent-patch`);if(k===null)return;let j=Rt(k),{agentId:F,agentName:L,colorSeed:B,clientName:H,clientVersion:q,label:ee}=Yi(E);if(findLooksLikeFrontmatter(S)){agentPatchFmTouchCounter().add(1,{result:`rejected`}),errorResponse(w,400,`urn:ok:error:frontmatter-edit-not-supported`,`Frontmatter edits are not supported via a body find/replace. Use edit({ document: { path, frontmatter } }) to change frontmatter, or write({ document: { path, content, position: "replace" } }) to rewrite the whole document including its YAML block.`,{handler:`agent-patch`});return}if(isSystemDoc(j)||isConfigDoc(j)){errorResponse(w,400,`urn:ok:error:reserved-doc-name`,`'${j}' is a reserved document name.`,{handler:`agent-patch`});return}let J=normalizeSummary(E.summary),Y=await s.getSession(j,F,{displayName:L,colorSeed:B,clientName:H}),te=reconcileDiskBeforeAgentWrite(t,j,g,e.resolveEmbed),ne=new Date().toISOString(),ae=!1,oe=!1,se=!1,ce;try{let t=iconFromClientName(H),s=AGENT_ICON_COLORS[t]??colorFromSeed(B??F);if(me?.setPresence(F,{displayName:L,icon:t,color:s,currentDoc:j,mode:`writing`,ts:Date.now()}),captureEffect(Y.dc.document.getText(`source`),F,B,H),Y.dc.document.transact(()=>{let{frontmatter:t,body:s}=stripFrontmatter(Y.dc.document.getText(`source`).toString()),g=prependFrontmatter(t,s),w=O==null?g.indexOf(S):g.slice(O,O+S.length)===S?O:-1;if(w===-1){O==null?ae=!0:oe=!0,console.warn(JSON.stringify({event:`agent-patch-find-mismatch`,"doc.name":j,findLength:S.length,replaceLength:D.length,hadOffset:O!=null})),incrementAgentPatchFindMismatches();return}if(w<t.length){se=!0;return}let{body:E}=stripFrontmatter(g.slice(0,w)+D+g.slice(w+S.length));ce=applyAgentMarkdownWrite(Y.dc.document,E,`patch`,e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:j}:void 0),Y.dc.document.getMap(`agent-flash`).set(F,{agentId:F,timestamp:Date.now(),type:`insert`,description:`Patched (${L}): ${S.slice(0,50)}`})},Y.origin),ce!==void 0&&console.warn(JSON.stringify({event:`agent-write-content-divergence`,"doc.name":j,position:`patch`,intendedBytes:ce.intendedBytes,actualBytes:ce.actualBytes,byteDelta:ce.byteDelta,"agent.id":F,"agent.client_name":H})),!ae&&!oe&&!se){let{stored:e}=Zi(J);recordContributor(j,F,L,B,void 0,Xi({clientName:H,clientVersion:q,label:ee}),e),incrementAgentWriteCalls(),_s(J),recordContentDivergenceGate(`agent-patch`,ce)}}finally{me?.touchMode(F,`idle`)}if(oe){errorResponse(w,409,`urn:ok:error:stale-target`,`Target text no longer matches at the requested offset.`,{handler:`agent-patch`});return}if(ae){errorResponse(w,404,`urn:ok:error:target-not-found`,`Text not found in document.`,{handler:`agent-patch`});return}if(se){agentPatchFmTouchCounter().add(1,{result:`rejected`}),errorResponse(w,400,`urn:ok:error:frontmatter-edit-not-supported`,`Frontmatter edits are not supported via a body find/replace. Use edit({ document: { path, frontmatter } }) to change frontmatter, or write({ document: { path, content, position: "replace" } }) to rewrite the whole document including its YAML block.`,{handler:`agent-patch`});return}let ue=await Ht(j);if(ue?.kind===`failure`){Ut(w,ue.failure,`agent-patch`);return}if(ue?.kind===`divergence`){Wt(w,`agent-patch`);return}Vt(j,`agent-patch`),fe?.setFocus(F,{agentName:L,currentDoc:j,writeKind:`edit`,ts:Date.now()}),ge?.();let de=zt(j),_e=Bt();_e===0&&hintEmittedCounter().add(1,{"shadow.writer":`agent`,"agent.type":resolveAgentType(H)});let{response:ve}=Zi(J),ye=Y.dc.document.getText(`source`).toString();Mr(j,ye);let Ce=await validateMermaidFences(ye,j),we=en();we.add(j);let Te=computeBrokenOutboundLinks(ye,j,we,jr),De=Kt(te),je=ce===void 0?void 0:toContentDivergenceWarning(ce),Me=[...je?[je]:[],...De?[De]:[],...Ce??[]];successResponse(w,200,AgentPatchSuccessSchema,{timestamp:ne,subscriberCount:de,systemSubscriberCount:_e,...ve?{summary:ve}:{},...je?{warning:je}:De?{warning:De}:{},...Me.length>0?{warnings:Me}:{},brokenLinks:Te},{handler:`agent-patch`})}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(w,e,`agent-patch`);return}if(e instanceof FrontmatterMalformedError){respondFrontmatterMalformed(w,e,`agent-patch`);return}if(e instanceof AgentSessionCapacityError){errorResponse(w,503,`urn:ok:error:too-many-agent-sessions`,`Too many agent sessions.`,{handler:`agent-patch`,cause:e,extraHeaders:{"Retry-After":`10`}});return}log$6.error({err:e},`[agent-patch] handler failed`),errorResponse(w,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-patch`,cause:e})}},{handler:`agent-patch`,method:`POST`}),oc=withValidation(AgentUndoRequestSchema,async(t,g,S)=>{try{let t=requireNonEmptyDocName(S.docName,g,`agent-undo`);if(t===null)return;let w=Rt(t),{agentId:E,agentName:D,colorSeed:O,clientName:k,clientVersion:j,label:F}=Yi(S);if(isSystemDoc(w)||isConfigDoc(w)){errorResponse(g,400,`urn:ok:error:reserved-doc-name`,`'${w}' is a reserved document name.`,{handler:`agent-undo`});return}let{connectionId:L}=S,B=S.scope===`session`||S.scope===`file`?`session`:`last`;if(!s.hasSession(w,L)){errorResponse(g,404,`urn:ok:error:no-active-session`,`No active session for this connectionId and docName.`,{handler:`agent-undo`});return}let H=await s.getSession(w,L),q=!1;try{let t=iconFromClientName(k),s=AGENT_ICON_COLORS[t]??colorFromSeed(O??E);me?.setPresence(E,{displayName:D,icon:t,color:s,currentDoc:w,mode:`writing`,ts:Date.now()}),q=applyAgentUndo(H,B,e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:w}:void 0),q&&recordContributor(w,L,D,O,void 0,Xi({clientName:k,clientVersion:j,label:F}))}finally{me?.touchMode(E,`idle`)}if(q){let e=await Ht(w);if(e?.kind===`failure`){Ut(g,e.failure,`agent-undo`);return}if(e?.kind===`divergence`){Wt(g,`agent-undo`);return}Vt(w,`agent-undo`)}fe?.setFocus(L,{agentName:L,currentDoc:w,writeKind:`undo`,ts:Date.now()}),successResponse(g,200,AgentUndoSuccessSchema,{docName:w,scope:B,undone:q},{handler:`agent-undo`})}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(g,e,`agent-undo`);return}log$6.error({err:e},`[agent-undo] handler failed`),errorResponse(g,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-undo`,cause:e})}},{handler:`agent-undo`,method:`POST`}),sc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let g=validateAgentId(new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`agentId`));if(g===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`agentId required (alphanumeric/_/- only).`,{handler:`agent-activity`});return}successResponse(t,200,AgentActivitySuccessSchema,listAgentActivity(s,g),{handler:`agent-activity`})}catch(e){log$6.error({err:e},`[agent-activity] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-activity`,cause:e})}},{handler:`agent-activity`,method:`GET`,skipBodyParse:!0}),cc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let g=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),S=validateAgentId(g.searchParams.get(`agentId`)),w=g.searchParams.get(`docName`),E=g.searchParams.get(`stackIndex`);if(S===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`agentId required (alphanumeric/_/- only).`,{handler:`agent-burst-diff`});return}if(!w||w.trim()===``){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`agent-burst-diff`});return}if(!isSafeDocName(w)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`agent-burst-diff`});return}let D=Rt(w);if(isSystemDoc(D)||isConfigDoc(D)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${D}' is a reserved document name.`,{handler:`agent-burst-diff`});return}if(!E||Number.isNaN(Number(E))){errorResponse(t,400,`urn:ok:error:invalid-request`,`StackIndex must be a number.`,{handler:`agent-burst-diff`});return}let O=Number(E);if(!Number.isInteger(O)||O<0){errorResponse(t,400,`urn:ok:error:invalid-request`,`stackIndex must be a non-negative integer.`,{handler:`agent-burst-diff`});return}let k=s.getLiveSession(D,S);if(!k){errorResponse(t,404,`urn:ok:error:no-active-session`,`No active session for this agentId and docName.`,{handler:`agent-burst-diff`});return}let j=k.um;if(O>=j.undoStack.length){errorResponse(t,404,`urn:ok:error:not-found`,`stackIndex ${O} out of range (stack has ${j.undoStack.length} items).`,{handler:`agent-burst-diff`});return}let F=j.undoStack[O];successResponse(t,200,AgentBurstDiffSuccessSchema,{diff:synthesizeStackItemDiffText(F,k.dc.document.getText(`source`),D),generatedAt:Date.now()},{handler:`agent-burst-diff`})}catch(e){log$6.error({err:e},`[agent-burst-diff] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`agent-burst-diff`,cause:e})}},{handler:`agent-burst-diff`,method:`GET`,skipBodyParse:!0}),lc=withValidation(EmptyRequestSchema,async(e,t)=>{try{await ee?.(),successResponse(t,200,TestFlushGitSuccessSchema,{},{handler:`test-flush-git`})}catch(e){log$6.error({err:e},`[test-flush-git] flush failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`test-flush-git`,cause:e})}},{handler:`test-flush-git`,method:`POST`,skipBodyParse:!0}),uc=withValidation(EmptyRequestSchema,async(e,S)=>{try{let w=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),E=Rt(w.searchParams.get(`docName`)??`test-doc`),D;try{D=safeContentPath(E,g)}catch(e){log$6.error({err:e,docName:E},`[test-reset] safeContentPath rejected docName`),errorResponse(S,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`test-reset`,cause:e});return}await s.closeAll(E),t.closeConnections(E);let O=`onStoreDocument-${E}`;t.debouncer.isDebounced(O)&&await t.debouncer.executeNow(O);let k=t.documents.get(E);if(k&&await(je??t.unloadDocument.bind(t))(k),writeFileSync(D,``,`utf-8`),ce&&(ce.deleteDocument(E),ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist cache after test-reset for ${E}:`,e)}),de?.(`backlinks`),de?.(`graph`)),w.searchParams.get(`reset-okignore`)!==`false`)try{let e=resolve(g,`.okignore`),s=t.documents.get(CONFIG_DOC_NAME_OKIGNORE);if(s){let e=s.getText(`source`);e.length>0&&s.transact(()=>{e.delete(0,e.length)},CONFIG_VALIDATION_REVERT_ORIGIN)}existsSync(e)&&writeFileSync(e,``,`utf-8`),Te&&await Te.rebuildIgnorePatterns()}catch(e){console.warn(`[test-reset] okignore reset partial failure:`,e)}de?.(`files`),successResponse(S,200,TestResetSuccessSchema,{},{handler:`test-reset`})}catch(e){errorResponse(S,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`test-reset`,cause:e})}},{handler:`test-reset`,method:`POST`,skipBodyParse:!0}),dc=withValidation(EmptyRequestSchema,async(e,t)=>{try{if(!ce){errorResponse(t,503,`urn:ok:error:backlink-index-not-configured`,`Backlink index is not configured.`,{handler:`test-rescan-backlinks`});return}await ce.rebuildFromDisk(),await ce.ingestGlobalSkillBundles([resolve(tu,`.ok`,`skills`)]),ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist cache after test-rescan-backlinks:`,e)}),de?.(`backlinks`),de?.(`graph`),successResponse(t,200,TestRescanBacklinksSuccessSchema,{},{handler:`test-rescan-backlinks`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`test-rescan-backlinks`,cause:e})}},{handler:`test-rescan-backlinks`,method:`POST`,skipBodyParse:!0}),fc=withValidation(EmptyRequestSchema,async(e,t)=>{try{if(!B){errorResponse(t,503,`urn:ok:error:file-rescan-not-configured`,`Watcher rescan capability is not configured.`,{handler:`test-rescan-files`});return}await B(),de?.(`files`),successResponse(t,200,TestRescanFilesSuccessSchema,{},{handler:`test-rescan-files`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`test-rescan-files`,cause:e})}},{handler:`test-rescan-files`,method:`POST`,skipBodyParse:!0}),pc=withValidation(SaveVersionRequestSchema,async(e,t,s)=>{try{let{rawAgentId:e,agentId:g,agentName:S,clientName:w}=Yi(s),E=q?.current;if(!E){errorResponse(t,503,`urn:ok:error:shadow-not-configured`,`Shadow repo not configured.`,{handler:`save-version`});return}let D=/^[a-zA-Z0-9_-]+$/,O=[],k=!1;if(Array.isArray(s.writers))try{O=s.writers.map(e=>{let t=e.id??`unknown`;if(!D.test(t))throw Error(`Invalid writer id: ${t}`);return{id:t,name:(e.name??`unknown`).replace(/[\r\n]/g,``),email:(e.email??`noreply@openknowledge.local`).replace(/[\r\n]/g,``)}})}catch(e){errorResponse(t,400,`urn:ok:error:invalid-request`,e instanceof Error?e.message:`Invalid writer id.`,{handler:`save-version`,cause:e});return}let j=ae?.()??`main`;if(O.length===0)if(e!==void 0)O=[{id:g,name:w?`${S} (${w})`:S,email:`${g}@openknowledge.local`}];else{let e=(await enumerateWipChains(E,j)).filter(e=>!e.isPark);O=e.length>0?e.map(e=>({id:e.writerId,name:e.writerId,email:`${e.writerId}@openknowledge.local`})):[SERVICE_WRITER],k=!0}let F=se??`.`,L=normalizeSummary(typeof s.summary==`string`?s.summary:void 0),B=await saveVersion(E,F,O,j,L.kind===`value`?L.value:void 0,k?{includeUpstream:!1}:void 0);getLogger(`history`).info({checkpointRef:B.checkpointRef},`checkpoint`);try{await gcRenameLog(E,getOrLoadRenameLogIndex(E.gitDir))}catch(e){console.warn(`[rename-log] post-saveVersion GC failed:`,e)}successResponse(t,200,SaveVersionSuccessSchema,{checkpointRef:B.checkpointRef},{handler:`save-version`})}catch(e){log$6.error({err:e},`[save-version] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`save-version`,cause:e})}},{handler:`save-version`,method:`POST`}),mc=withValidation(EmptyRequestSchema,async(e,t)=>{let s=q?.current;if(!s){errorResponse(t,503,`urn:ok:error:shadow-not-configured`,`Shadow repo not configured.`,{handler:`history`});return}let g=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),S=g.searchParams.get(`docName`)??``,w=g.searchParams.get(`folder`),E=g.searchParams.get(`branch`)??ae?.()??`main`;if(!S&&w===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`A docName or folder query parameter is required.`,{handler:`history`});return}if(E.includes(`..`)||!/^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/.test(E)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid branch name.`,{handler:`history`});return}if(w!==null&&!S){let e=Fl(w,t,`folder`,`history`);if(!e)return;let S=Number(g.searchParams.get(`limit`)??`50`),D=Math.min(200,Number.isFinite(S)?S:50),O=Number(g.searchParams.get(`offset`)??`0`),k=Math.max(0,Number.isFinite(O)?O:0),j=`folder\0${E}\0${e.folderRel}\0${D}\0${k}`,{promise:F,coalesced:L}=Ke.run(j,()=>getFolderTimeline(s,e.folderRel,se??`.`,{branch:E,limit:D,offset:k}));L&&recordTimelineCoalesced(`folder`),successResponse(t,200,HistorySuccessSchema,{...await F},{handler:`history`});return}let D=se??`.`,O=safeDocPath(S,D);if(`error`in O){errorResponse(t,400,`urn:ok:error:invalid-request`,O.error,{handler:`history`});return}let k=Number(g.searchParams.get(`limit`)??`50`),j=Number(g.searchParams.get(`offset`)??`0`),F=Math.min(200,Number.isFinite(k)?k:50),L=Number.isFinite(j)?j:0,B=g.searchParams.get(`type`)??void 0,H=g.searchParams.get(`author`)??void 0,ee=g.searchParams.get(`excludeAuthor`)??void 0,J=g.searchParams.get(`includeAutoCheckpoints`)===`true`,Y=`doc\0${E}\0${S}\0${F}\0${L}\0${B??``}\0${H??``}\0${ee??``}\0${J?`1`:`0`}`,te=Date.now();try{let{promise:e,coalesced:g}=Ke.run(Y,()=>getDocumentHistory(s,{docName:S,branch:E,limit:F,offset:L,type:B,author:H,excludeAuthor:ee,includeAutoCheckpoints:J},D));g&&recordTimelineCoalesced(`doc`);let w=await e,O=Date.now()-te;getLogger(`timeline`).info({docName:S,entries:w.entries.length,durationMs:O},`query`),successResponse(t,200,HistorySuccessSchema,{...w},{handler:`history`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read history.`,{handler:`history`,cause:e})}},{handler:`history`,method:`GET`,skipBodyParse:!0});async function hc(e,t,s){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`history-version`,extraHeaders:{Allow:`GET`}});return}let g=q?.current;if(!g){errorResponse(t,503,`urn:ok:error:shadow-not-configured`,`Shadow repo not configured.`,{handler:`history-version`});return}let S=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`docName`)??``,w=se??`.`,E=safeDocPath(S,w);if(`error`in E){errorResponse(t,400,`urn:ok:error:invalid-request`,E.error,{handler:`history-version`});return}let D=shadowGit(g),O=ae?.()??`main`;if(!/^[0-9a-f]{40}$/i.test(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid commit SHA.`,{handler:`history-version`});return}try{let e=await resolveDocPathAtCommit(g,S,s,O,getOrLoadRenameLogIndex(g.gitDir),e=>{let t=safeDocPath(e,w);return`error`in t?`${e}.md`:t.path},createAncestorShaSetCache());if(e===null){errorResponse(t,404,`urn:ok:error:doc-not-found`,`Document did not exist at this version.`,{handler:`history-version`});return}let E=await D.raw(`show`,`${s}:${e}`),[k=``,j=``]=(await D.raw(`log`,`-1`,`--format=%aI%x00%an`,s)).trim().split(`\0`);successResponse(t,200,HistoryVersionSuccessSchema,{sha:s,content:E,timestamp:k,author:j},{handler:`history-version`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`history-version`,cause:e})}}let gc=withValidation(RollbackRequestSchema,async(s,g,S)=>{let w=extractActorIdentity(S,Ce);if(w.kind===`invalid-summary`){errorResponse(g,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`rollback`});return}let E=t.documents.get(S.docName);if(E&&isDocInConflict(E)){respondDocInConflict(g,new DocInConflictError({file:`${S.docName}${getDocExtension(S.docName)}`}),`rollback`);return}let D=q?.current;if(!D){errorResponse(g,503,`urn:ok:error:rollback-not-configured`,`Shadow repo not configured.`,{handler:`rollback`});return}let{docName:O,commitSha:k}=S,j=se??`.`,F=safeDocPath(O,j);if(`error`in F){errorResponse(g,400,`urn:ok:error:invalid-request`,F.error,{handler:`rollback`});return}let L=shadowGit(D),B=Date.now();try{let s=getOrLoadRenameLogIndex(D.gitDir),S=createAncestorShaSetCache(),E=await resolveDocPathAtCommit(D,O,k,ae?.()??`main`,s,e=>{let t=safeDocPath(e,j);return`error`in t?`${e}.md`:t.path},S);if(E===null){errorResponse(g,404,`urn:ok:error:doc-not-found`,`Commit ${k.slice(0,7)} does not contain document ${O} at any known historical path.`,{handler:`rollback`});return}let F=await L.raw(`show`,`${k}:${E}`),H=new Date().toISOString();await safetyCheckpoint(D,j,{action:`rollback`,context:{docName:O,targetSha:k}});let q=t.documents.get(O);if(!q){errorResponse(g,409,`urn:ok:error:doc-not-open`,`Document is not currently open — open it in the editor first.`,{handler:`rollback`});return}let ee=e.resolveEmbed?{resolveEmbed:e.resolveEmbed,sourcePath:O}:void 0,J;q.transact(()=>{replaceRawBody(q,F,ee),J=evaluateContentDivergence(q.getText(`source`).toString(),F,`rollback`)},ROLLBACK_ORIGIN),J!==void 0&&console.warn(JSON.stringify({event:`agent-write-content-divergence`,"doc.name":O,position:`rollback`,intendedBytes:J.intendedBytes,actualBytes:J.actualBytes,byteDelta:J.byteDelta,"actor.kind":w.kind,...w.kind===`agent`||w.kind===`principal`?{"actor.writer_id":w.writerId}:{}})),recordContentDivergenceGate(`rollback`,J);let Y;switch(w.kind){case`agent`:{let e=k.slice(0,8),t=w.summary.kind===`value`,s=t?w.summary:normalizeSummary(`Restored to ${e}`),g=Zi(s);Y=t||!g.response?g.response:ka(g.response),recordContributor(O,w.writerId,w.displayName,w.colorSeed,formatRollbackSubject(O,k),w.actor,g.stored),incrementAgentWriteCalls(),_s(s,!t);break}case`principal`:{let e=Zi(w.summary);Y=e.response,recordContributor(O,w.writerId,w.displayName,w.colorSeed,formatRollbackSubject(O,k),w.actor,e.stored),_s(w.summary,!1);break}case`anonymous`:log$6.debug({docName:O,commitSha:k.slice(0,8)},`[rollback] anonymous actor — no contributor recorded (no agentId in body and getPrincipal() returned null)`);break;default:throw Error(`Unhandled actor kind in handleRollback: ${String(w.kind)}`)}renameAttributionCounter().add(1,{kind:`rollback`,attribution_kind:w.kind});let te=await Ht(O);if(te?.kind===`failure`){Ut(g,te.failure,`rollback`);return}if(te?.kind===`divergence`){Wt(g,`rollback`);return}Vt(O,`rollback`);let ne=Date.now()-B;getLogger(`rollback`).info({docName:O,from:k.slice(0,8),durationMs:ne},`rollback`),w.kind===`agent`&&fe?.setFocus(w.writerId,{agentName:w.displayName,currentDoc:O,writeKind:`rollback-apply`,ts:Date.now()});let oe=J===void 0?void 0:toContentDivergenceWarning(J);successResponse(g,200,RollbackSuccessSchema,{restoredFrom:k,timestamp:H,...Y?{summary:Y}:{},...oe?{warning:oe,warnings:[oe]}:{}},{handler:`rollback`})}catch(e){errorResponse(g,500,`urn:ok:error:internal-server-error`,`Failed to roll back.`,{handler:`rollback`,cause:e})}},{handler:`rollback`,method:`POST`}),_c=withValidation(EmptyRequestSchema,async(e,t)=>{try{successResponse(t,200,MetricsReconciliationSuccessSchema,getMetrics(),{handler:`metrics-reconciliation`})}catch(e){log$6.error({err:e},`[metrics-reconciliation] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`metrics-reconciliation`,cause:e})}},{handler:`metrics-reconciliation`,method:`GET`,skipBodyParse:!0}),vc=withValidation(EmptyRequestSchema,async(e,t)=>{try{successResponse(t,200,MetricsParseHealthSuccessSchema,getParseHealth(),{handler:`metrics-parse-health`})}catch(e){log$6.error({err:e},`[metrics-parse-health] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`metrics-parse-health`,cause:e})}},{handler:`metrics-parse-health`,method:`GET`,skipBodyParse:!0}),yc=withValidation(EmptyRequestSchema,async(e,t)=>{try{Me&&await Me.catch(e=>{log$6.warn({err:e,handler:`server-info`},`[api] ready gate rejected — responding with current state`)});let e=getActiveBranch(),s=oe?.();successResponse(t,200,ServerInfoSuccessSchema,{serverInstanceId:S,currentBranch:e,...s===void 0?{}:{currentDiskAckSVs:s}},{handler:`server-info`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`server-info`,cause:e})}},{handler:`server-info`,method:`GET`,skipBodyParse:!0});async function bc(e,t){if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`principal`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`principal`});return}if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`principal`,extraHeaders:{Allow:`GET`}});return}let s=Ce?.()??null;if(!s){errorResponse(t,404,`urn:ok:error:principal-not-available`,`Principal not available.`,{handler:`principal`});return}successResponse(t,200,PrincipalSuccessSchema,s,{handler:`principal`})}async function xc(e,t){if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`metrics-agent-presence`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`metrics-agent-presence`});return}if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`metrics-agent-presence`,extraHeaders:{Allow:`GET`}});return}try{let e=me?.getPresenceMap()??{},s=Date.now(),g={};for(let[t,S]of Object.entries(e))s-S.ts<2e4&&(g[t]=S);successResponse(t,200,MetricsAgentPresenceSuccessSchema,{presence:g},{handler:`metrics-agent-presence`})}catch(e){log$6.error({err:e},`[metrics-agent-presence] handler failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`metrics-agent-presence`,cause:e})}}async function Sc(e,t){if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`embed-detect`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`embed-detect`});return}if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`embed-detect`,extraHeaders:{Allow:`GET`}});return}let s=embedProbeRing.read();successResponse(t,200,EmbedDetectSuccessSchema,{entries:s,count:s.length,detection:deriveDetection(s[0])},{handler:`embed-detect`})}async function Cc(e,t){if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`workspace`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`workspace`});return}if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`workspace`,extraHeaders:{Allow:`GET`}});return}let s=resolve(g),S=s,w=!0;try{S=realpathSync(s)}catch(e){let g=e?.code;if(g===`ENOENT`)console.warn(`[workspace] contentDir does not exist; returning unresolved path`,{path:s}),w=!1;else{console.warn(`[workspace] realpath failed for contentDir`,{path:s,err:e}),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Workspace realpath failed.`,{handler:`workspace`,detail:g??void 0,cause:e});return}}successResponse(t,200,WorkspaceSuccessSchema,{contentDir:S,pathSeparator:sep,symlinkResolved:w},{handler:`workspace`})}let wc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`path`);if(!s||s.includes(`\0`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing asset path.`,{handler:`asset`});return}let S=assetContentTypeForPath(s),w=extname(s).slice(1).toLowerCase();if(!S||!ASSET_EXTENSIONS.has(w)){errorResponse(t,415,`urn:ok:error:unsupported-asset-type`,`Unsupported asset type.`,{handler:`asset`});return}let E=realpathSync(g),D=resolve(E,s),O;try{O=realpathSync(D)}catch{errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset`});return}if(!isWithinContentDir(O,E)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid asset path.`,{handler:`asset`});return}let k;try{k=statSync(O)}catch{errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset`});return}if(!k.isFile()){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset`});return}let j=toContentRelativePath(E,O);if(j!==s.split(`\\`).join(`/`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid asset path.`,{handler:`asset`});return}if(Te?.isPathIgnored(j)){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset`});return}let F=SANDBOXED_HTML_EXTENSIONS.has(w),L={"Content-Type":S,"Content-Length":String(k.size),"X-Content-Type-Options":`nosniff`,"Content-Disposition":INLINE_RENDERABLE_EXTENSIONS.has(w)||F?`inline`:`attachment`,"Cache-Control":`no-store`};w===`svg`?L[`Content-Security-Policy`]=`sandbox; default-src 'none'; style-src 'unsafe-inline'`:F&&(L[`Content-Security-Policy`]=SANDBOXED_HTML_CSP),t.writeHead(200,L);try{await pipeline(createReadStream(O),t)}catch(e){log$6.error({event:`api.asset.pipeline-failed`,handler:`asset`,assetPath:s,err:e},`[asset] pipeline failed mid-stream`),t.destroyed||t.destroy(e instanceof Error?e:void 0)}}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`asset`,cause:e})}},{handler:`asset`,method:`GET`,skipBodyParse:!0}),Tc=1048576,Ec=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`path`);if(!s||s.includes(`\0`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing asset path.`,{handler:`asset-text`});return}let S=realpathSync(g),w=resolve(S,s),E;try{E=realpathSync(w)}catch(e){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset-text`,cause:e});return}if(!isWithinContentDir(E,S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid asset path.`,{handler:`asset-text`});return}let D;try{D=statSync(E)}catch(e){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset-text`,cause:e});return}if(!D.isFile()){errorResponse(t,404,`urn:ok:error:asset-not-found`,`Asset not found.`,{handler:`asset-text`});return}if(toContentRelativePath(S,E)!==s.split(`\\`).join(`/`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid asset path.`,{handler:`asset-text`});return}if(D.size>Tc){errorResponse(t,413,`urn:ok:error:payload-too-large`,`File exceeds the ${Tc}-byte text-viewer cap.`,{handler:`asset-text`});return}let O=(await readFile$1(E)).toString(`utf-8`);t.writeHead(200,{"Content-Type":`text/plain; charset=utf-8`,"X-Content-Type-Options":`nosniff`,"Content-Disposition":`inline`,"Cache-Control":`no-store`}),t.end(O)}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`asset-text`,cause:e})}},{handler:`asset-text`,method:`GET`,skipBodyParse:!0}),Dc=1440*60*1e3,Oc=withValidation(EmptyRequestSchema,async(e,t)=>{try{if(!q?.current){successResponse(t,200,RescueListSuccessSchema,[],{handler:`rescue-list`});return}let e=Date.now(),s=[],g=resolve(q.current.gitDir,`rescue`);if(existsSync(g))try{let t=readdirSync(g).filter(e=>isSupportedDocFile(e));for(let S of t){let t=resolve(g,S),w=statSync(t);if(e-w.mtimeMs>864e5){try{unlinkSync(t)}catch(e){console.debug(`[rescue] cleanup failed (non-critical):`,e)}continue}s.push({docName:stripDocExtension(S),timestamp:w.mtime.toISOString(),size:w.size,source:`flat`})}}catch(e){log$6.error({err:e},`[rescue] Failed to list flat-file rescue buffers`)}try{let e=ae?.()??`main`,t=await listRescueCheckpoints(q.current,e);for(let e of t)s.push({...e,source:`timeline`})}catch(e){log$6.error({err:e},`[rescue] Failed to list timeline-ref rescue checkpoints`)}successResponse(t,200,RescueListSuccessSchema,s,{handler:`rescue-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`rescue-list`,cause:e})}},{handler:`rescue-list`,method:`GET`,skipBodyParse:!0}),kc=withValidation(CreatePageRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`create-page`});return}let S=s.path;if(!isSupportedDocFile(S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must end with .md or .mdx.`,{handler:`create-page`});return}if(S.includes(`..`)||S.startsWith(`/`)||S.includes(`\0`)||S.includes(`\\`)){errorResponse(t,400,`urn:ok:error:path-escape`,`Invalid path.`,{handler:`create-page`,detail:`path must not contain .. or start with /`});return}let w=resolve(g),E=resolve(w,S);if(!isWithinDir(E,w)){errorResponse(t,400,`urn:ok:error:path-escape`,`path must not escape content directory.`,{handler:`create-page`});return}let O=stripDocExtension(S);if(isSystemDoc(O)||isConfigDoc(O)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${O}' is a reserved document name.`,{handler:`create-page`});return}if(S.split(`/`)[0]===`.ok`||isManagedArtifactDocName(O)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${O}' is a reserved document name.`,{handler:`create-page`,detail:`Cannot create a page under .ok/ — skills and templates are authored through their own validating flows.`});return}let k=typeof s.template==`string`?s.template.trim():``,j=``,F;if(k.length>0){if(!/^[A-Za-z0-9_-]+$/.test(k)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Template name must match [A-Za-z0-9_-]+.`,{handler:`create-page`});return}let s=S.includes(`/`)?S.slice(0,S.lastIndexOf(`/`)):``,g=resolveTemplatesAvailable(w,s),E=g.find(e=>e.name===k);if(!E){let e=g.length===0?`(none)`:g.map(e=>`"${e.name}" (${e.scope})`).join(`, `);errorResponse(t,400,`urn:ok:error:invalid-request`,`Template "${k}" does not resolve for folder "${s||`(root)`}". Available: ${e}`,{handler:`create-page`});return}let D=resolve(w,E.path),O;try{O=readFileSync(D,`utf-8`)}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read template at ${E.path}.`,{handler:`create-page`,cause:e});return}let L=instantiateDoc(O),B=e.kind===`agent`||e.kind===`principal`?e.displayName??``:``;j=applySubstitution(L,{date:todayIsoUtc(),user:B}),F=E.scope}mkdirSync(dirname(E),{recursive:!0});try{writeFileSync(E,j,{encoding:`utf-8`,flag:`wx`})}catch(e){if(isAlreadyExistsError(e)){errorResponse(t,409,`urn:ok:error:doc-already-exists`,`File already exists.`,{handler:`create-page`,cause:e});return}throw e}let L=stripDocExtension(S);switch(Pe?.delete(L),Te&&Te.incrementMdDir(dirname(L)),registerWrite(E,contentHash(j)),e.kind){case`agent`:case`principal`:recordContributor(L,e.writerId,e.displayName,e.colorSeed,void 0,e.actor);break;case`anonymous`:break;default:throw Error(`Unhandled actor kind in handleCreatePage: ${String(e.kind)}`)}D?.({kind:`create`,path:E,docName:L,content:j}),ce&&(ce.updateDocumentFromMarkdown(L,j),ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist create-page cache for ${L}:`,e)}),de?.(`backlinks`),de?.(`graph`)),de?.(`files`),F!==void 0&&console.warn(JSON.stringify({event:`template-instantiate`,templateName:k,templateScope:F,docName:L})),successResponse(t,200,CreatePageSuccessSchema,{docName:L},{handler:`create-page`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to create page.`,{handler:`create-page`,cause:e})}},{handler:`create-page`,method:`POST`}),Ac=withValidation(CreateFolderRequestSchema,async(e,t,s)=>{try{if(extractActorIdentity(s,Ce).kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`create-folder`});return}let e=s.path;if(!isValidRelativeContentPath(e)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`create-folder`});return}if(e===`.ok`||e.startsWith(`.ok/`)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'.ok' is a reserved directory.`,{handler:`create-folder`});return}if(Te?.isDirExcluded(e)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Destination folder is excluded by the workspace content config.`,{handler:`create-folder`});return}let S=resolveContentEntryPath(g,`folder`,e);if(existsSync(S)){errorResponse(t,409,`urn:ok:error:doc-already-exists`,`Folder already exists.`,{handler:`create-folder`});return}tracedMkdirSync(S,{recursive:!0}),rt(e),de?.(`files`),successResponse(t,200,CreateFolderSuccessSchema,{path:e},{handler:`create-folder`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to create folder.`,{handler:`create-folder`,cause:e})}},{handler:`create-folder`,method:`POST`}),jc=withValidation(DuplicatePathRequestSchema,async(e,s,S)=>{try{let e=extractActorIdentity(S,Ce);if(e.kind===`invalid-summary`){errorResponse(s,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`duplicate-path`});return}let{kind:w}=S,E=w===`file`?stripDocExtension(S.path):S.path;if(!isValidRelativeContentPath(E)){errorResponse(s,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`duplicate-path`});return}if(E===`.ok`||E.startsWith(`.ok/`)||w===`file`&&(isSystemDoc(E)||isConfigDoc(E))||w===`folder`&&isReservedSyntheticFolderPath(E)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`Reserved paths cannot be duplicated.`,{handler:`duplicate-path`});return}w===`file`&&probeAndRegisterSourceFileExtension(g,E);let O=resolveContentEntryPath(g,w,E);if(!existsSync(O)){if(w===`file`){let e=resolveContentEntryPath(g,`folder`,E);if(existsSync(e)&&statSync(e).isDirectory()){errorResponse(s,400,`urn:ok:error:invalid-request`,`Target path is not a ${w}.`,{handler:`duplicate-path`});return}}errorResponse(s,404,`urn:ok:error:doc-not-found`,`${w} does not exist.`,{handler:`duplicate-path`});return}let k=statSync(O);if(w===`file`&&!k.isFile()||w===`folder`&&!k.isDirectory()){errorResponse(s,400,`urn:ok:error:invalid-request`,`Target path is not a ${w}.`,{handler:`duplicate-path`});return}let j=w===`file`?[E]:ji(resolveContentEntryPath(g,`folder`,E)),F=_e?.(),L=new Set(F?F.getConflicts().map(e=>e.file):[]);for(let e of j){let g=stripDocExtension(e),S=t.documents.get(g),w=`${g}${getDocExtension(g)}`,E=S!==void 0&&isDocInConflict(S),D=L.has(w);if(E||D){respondDocInConflict(s,new DocInConflictError({file:w}),`duplicate-path`);return}}let B,H=[];if(w===`file`){let e=extname(O);if(B=nextAvailableDuplicateDocName(g,E).docName,isSystemDoc(B)||isConfigDoc(B)||Te?.isExcluded(`${B}${e}`)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Duplicated document destination is excluded by the project content config.`,{handler:`duplicate-path`});return}let t=resolveDuplicateDocPath(g,B,e),S=readFileSync(O,`utf-8`),w=dirname(t),k=existsSync(w);try{tracedMkdirSync(w,{recursive:!0}),tracedWriteFileSync(t,S,{encoding:`utf-8`,flag:`wx`})}catch(e){if(isAlreadyExistsError(e)){errorResponse(s,409,`urn:ok:error:doc-already-exists`,`A file at the duplicate destination already exists.`,{handler:`duplicate-path`,cause:e});return}if(!k)try{tracedRmdirSync(w)}catch(e){let t=e.code;t!==`ENOENT`&&t!==`ENOTEMPTY`&&console.warn(`[duplicate-path] failed to clean duplicate parent directory:`,{destinationDir:w,err:e})}throw e}let j=!1;try{registerDocExtension(B,e),Pe?.delete(B),Te&&(Te.incrementMdDir(dirname(B)),j=!0),registerWrite(t,contentHash(S)),D?.({kind:`create`,path:t,docName:B,content:S}),ce?.updateDocumentFromMarkdown(B,S),H=[B]}catch(e){try{tracedRmSync(t,{force:!0})}catch(e){console.warn(`[duplicate-path] failed to clean partial file duplicate:`,{destinationPath:t,err:e})}throw forgetDocExtension(B),Te&&j&&Te.decrementMdDir(dirname(B)),D?.({kind:`delete`,path:t,docName:B}),e}}else{if(B=nextAvailableDuplicateFolderPath(g,E).folderPath,Te?.isDirExcluded(B)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Duplicated folder destination is excluded by the project content config.`,{handler:`duplicate-path`});return}let e=resolveContentEntryPath(g,`folder`,B);try{tracedCpSync(O,e,{recursive:!0,errorOnExist:!0,force:!1})}catch(e){if(isAlreadyExistsError(e)){errorResponse(s,409,`urn:ok:error:doc-already-exists`,`A folder at the duplicate destination already exists.`,{handler:`duplicate-path`,cause:e});return}throw e}try{for(let e of collectFolderPaths(g,B))rt(e);let e=collectMarkdownCopies(g,B);H=e.map(e=>e.docName);for(let t of e){let e=extname(t.fullPath);registerDocExtension(t.docName,e),Pe?.delete(t.docName),Te&&Te.incrementMdDir(dirname(t.docName)),registerWrite(t.fullPath,contentHash(t.content)),D?.({kind:`create`,path:t.fullPath,docName:t.docName,content:t.content}),ce?.updateDocumentFromMarkdown(t.docName,t.content)}}catch(t){try{tracedRmSync(e,{recursive:!0,force:!0})}catch(t){console.warn(`[duplicate-path] failed to clean partial folder duplicate:`,{destinationPath:e,err:t})}throw t}}switch(e.kind){case`agent`:case`principal`:for(let t of H)recordContributor(t,e.writerId,e.displayName,e.colorSeed,void 0,e.actor);break;case`anonymous`:break;default:throw Error(`Unhandled actor kind in handleDuplicatePath: ${String(e.kind)}`)}ce&&H.length>0&&(ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist duplicate-path cache:`,e)}),de?.(`backlinks`),de?.(`graph`)),de?.(`files`),successResponse(s,200,DuplicatePathSuccessSchema,{kind:w,path:B,duplicatedDocNames:H},{handler:`duplicate-path`})}catch(e){if(e instanceof DuplicateNameExhaustedError){errorResponse(s,409,`urn:ok:error:doc-already-exists`,`All available duplicate name slots are occupied for this path.`,{handler:`duplicate-path`,cause:e});return}let t=classifyDuplicatePathFilesystemProblem(e);if(t){errorResponse(s,t.status,t.type,t.title,{handler:`duplicate-path`,cause:e});return}errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to duplicate path.`,{handler:`duplicate-path`,cause:e})}},{handler:`duplicate-path`,method:`POST`}),Mc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!s||s.length===0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docName query parameter.`,{handler:`page-headings`});return}if(!isSafeDocName(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`page-headings`});return}let g=Et(s);if(!g){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`page-headings`});return}if(!existsSync(g)){errorResponse(t,404,`urn:ok:error:doc-not-found`,`Page not found.`,{handler:`page-headings`});return}successResponse(t,200,PageHeadingsSuccessSchema,{docName:s,headings:extractHeadings(readFileSync(g,`utf-8`))},{handler:`page-headings`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read headings.`,{handler:`page-headings`,cause:e})}},{handler:`page-headings`,method:`GET`,skipBodyParse:!0}),Nc=withValidation(RenamePathRequestSchema,async(e,s,S)=>{try{let e=extractActorIdentity(S,Ce);if(e.kind===`invalid-summary`){errorResponse(s,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`rename-path`});return}let{kind:w,fromPath:E,toPath:D}=S;if(!isValidRelativeContentPath(E)||!isValidRelativeContentPath(D)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Paths must be relative content paths.`,{handler:`rename-path`});return}if(w===`file`&&(isSystemDoc(E)||isSystemDoc(D)||isConfigDoc(E)||isConfigDoc(D))){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`Reserved document names cannot be renamed.`,{handler:`rename-path`});return}if(E===`.ok`||E.startsWith(`.ok/`)||D===`.ok`||D.startsWith(`.ok/`)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`.ok is a reserved directory.`,{handler:`rename-path`});return}if(E===D){successResponse(s,200,RenamePathSuccessSchema,{renamed:[],renamedAssets:[],rewrittenDocs:[]},{handler:`rename-path`});return}let O=w===`asset`&&isSupportedDocFile(E)&&isSupportedDocFile(D)?`file`:w;if(O===`asset`){let t;try{t=isSupportedDocFile(E)&&!isSupportedDocFile(D)?await Gi(E,D):await Ui(E,D)}catch(e){if(e instanceof DocInConflictError){respondDocInConflict(s,e,`rename-path`);return}let{status:t,type:g,error:S}=zr(e);errorResponse(s,t,g,S,{handler:`rename-path`,cause:e});return}t.renamedAssets.length>0&&vt();let g;if(t.renamedAssets.length>0&&t.rewrittenDocs.length>0){let s=`Renamed asset ${E} → ${D}`;g=xs(e,s,t.rewrittenDocs.map(({docName:e})=>({docName:e,subject:s})),{context:`handleRenamePath asset branch`,onAnonymous:()=>{log$6.debug({kind:`asset`,fromPath:E,toPath:D,affectedDocs:t.rewrittenDocs.length,affectedAssets:t.renamedAssets.length},`[rename-path] anonymous actor; no contributor recorded (no agentId in body and getPrincipal() returned null)`)}})}if(renameAttributionCounter().add(1,{kind:`rename-asset`,attribution_kind:e.kind}),J)try{await J()}catch(e){console.warn(`[rename-path] flushContributors failed after asset rename (commitSha backfill may be deferred):`,e)}successResponse(s,200,RenamePathSuccessSchema,{renamed:[],renamedAssets:t.renamedAssets,rewrittenDocs:t.rewrittenDocs,...g?{summary:g}:{}},{handler:`rename-path`});return}let k=O===`file`?[stripDocExtension(E)]:ji(resolveContentEntryPath(g,`folder`,E)),j=_e?.(),F=new Set(j?j.getConflicts().map(e=>e.file):[]);for(let e of k){let g=stripDocExtension(e),S=t.documents.get(g),w=O===`file`?E:`${g}${getDocExtension(e)}`,D=S!==void 0&&isDocInConflict(S),k=F.has(w);if(D||k){respondDocInConflict(s,new DocInConflictError({file:w}),`rename-path`);return}}if(O===`file`&&probeAndRegisterSourceFileExtension(g,E),Te&&(O===`file`?Te.isExcluded(isSupportedDocFile(D)?D:`${D}${getDocExtension(E)}`):Te.isDirExcluded(D))){errorResponse(s,400,`urn:ok:error:invalid-request`,`Destination ${O===`file`?`document`:`folder`} is excluded by the project content config.`,{handler:`rename-path`});return}let L=e.kind===`agent`||e.kind===`principal`?{writerId:e.writerId,displayName:e.displayName,colorSeed:e.colorSeed,actorMetadata:e.actor}:void 0,B;try{B=await Ki(E,D,O,L?{actor:L}:{})}catch(e){if(e instanceof ManagedRenameCollisionError){errorResponse(s,409,`urn:ok:error:doc-already-exists`,Lr(e.message),{handler:`rename-path`,extensions:{colliding:e.colliding},cause:e});return}throw e}if(B.renamed.length===0&&B.renamedAssets.length===0){successResponse(s,200,RenamePathSuccessSchema,{renamed:[],renamedAssets:[],rewrittenDocs:[]},{handler:`rename-path`});return}B.renamedAssets.length>0&&vt();let H,q=B.renamed.filter(({fromDocName:e,toDocName:t})=>e!==t);if(q.length>0&&(H=xs(e,`Renamed ${E} → ${D}`,q.map(({fromDocName:e,toDocName:t})=>({docName:t,subject:formatRenameSubject(e,t)})),{context:`handleRenamePath`,onAnonymous:()=>{log$6.debug({kind:w,fromPath:E,toPath:D,affectedDocs:B.renamed.length},`[rename-path] anonymous actor — no contributor recorded (no agentId in body and getPrincipal() returned null)`)}})),renameAttributionCounter().add(1,{kind:`rename-${O}`,attribution_kind:e.kind}),J)try{await J()}catch(e){console.warn(`[rename-path] flushContributors failed (commitSha backfill may be deferred):`,e)}successResponse(s,200,RenamePathSuccessSchema,{renamed:B.renamed,renamedAssets:B.renamedAssets,rewrittenDocs:B.rewrittenDocs,...H?{summary:H}:{}},{handler:`rename-path`})}catch(e){let{status:t,type:g,error:S}=zr(e);errorResponse(s,t,g,S,{handler:`rename-path`,cause:e})}},{handler:`rename-path`,method:`POST`}),Pc=withValidation(DeletePathRequestSchema,async(e,s,S)=>{try{Yi(S);let{kind:e,path:w}=S;if(!isValidRelativeContentPath(w)){errorResponse(s,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`delete-path`});return}let E=e===`asset`?Qr(w):{path:w,ambiguous:!1};if(E.ambiguous){errorResponse(s,400,`urn:ok:error:invalid-request`,`Asset path without an extension matches multiple files.`,{handler:`delete-path`});return}let O=E.path,k=e===`asset`&&isSupportedDocFile(O)?`file`:e;if(k===`file`&&probeAndRegisterSourceFileExtension(g,O),k===`asset`&&isReservedProjectStatePath(O)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`.ok and .git are reserved directories.`,{handler:`delete-path`});return}let j=k===`asset`?resolveContentEntryPath(g,`folder`,O):resolveContentEntryPath(g,k,O);if(!existsSync(j)){errorResponse(s,404,`urn:ok:error:doc-not-found`,`${k} does not exist.`,{handler:`delete-path`});return}let F=statSync(j);if(k===`file`&&!F.isFile()||k===`asset`&&!F.isFile()||k===`folder`&&!F.isDirectory()){errorResponse(s,400,`urn:ok:error:invalid-request`,`Target path is not a ${k}.`,{handler:`delete-path`});return}let L=k===`asset`?[]:k===`file`?[stripDocExtension(O)]:ji(resolveContentEntryPath(g,`folder`,O)),B=_e?.(),H=new Set(B?B.getConflicts().map(e=>e.file):[]);for(let e of L){let g=stripDocExtension(e),S=t.documents.get(g),w=k===`file`&&isSupportedDocFile(O)?O:`${g}${getDocExtension(g)}`,E=S!==void 0&&isDocInConflict(S),D=H.has(w);if(E||D){respondDocInConflict(s,new DocInConflictError({file:w}),`delete-path`);return}}if(await Br(L),Pe)for(let e of L)isSystemDoc(e)||isConfigDoc(e)||(Pe.setDeleted(e),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:e,kind:`deleted`,source:`handleDeletePath`})));k===`file`||k===`asset`?tracedUnlinkSync(j):(tracedRmSync(j,{recursive:!0,force:!1}),it(O)),vt();for(let e of L)D?.({kind:`delete`,path:resolve(g,`${e}${getDocExtension(e)}`),docName:e});de?.(`files`),successResponse(s,200,DeletePathSuccessSchema,{deletedDocNames:L},{handler:`delete-path`})}catch(e){errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to delete path.`,{handler:`delete-path`,cause:e})}},{handler:`delete-path`,method:`POST`}),Fc=withValidation(TrashCleanupRequestSchema,async(e,t,s)=>withSpan(`ok.fs.trash_cleanup`,{attributes:{"ok.cleanup.kind":s.kind,"ok.cleanup.path":normalizeFsPath(s.path),"ok.cleanup.path.role":classifyFsPath(s.path)}},async()=>{try{if(extractActorIdentity(s,Ce).kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`trash-cleanup`});return}let{kind:e,path:S}=s;if(!isValidRelativeContentPath(S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`trash-cleanup`});return}let E=e===`asset`&&isSupportedDocFile(S)?`file`:e,O=stripDocExtension(S);E===`file`&&probeAndRegisterSourceFileExtension(g,S);let k=E===`folder`&&isReservedSyntheticFolderPath(S),j=E===`asset`&&isReservedProjectStatePath(S);if(E===`file`&&(isSystemDoc(O)||isConfigDoc(O))||k||j){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${S}' is a reserved document name.`,{handler:`trash-cleanup`});return}if(E===`asset`){vt(),de?.(`files`),successResponse(t,200,TrashCleanupSuccessSchema,{deletedDocNames:[]},{handler:`trash-cleanup`});return}let F=w(),L=E===`file`?F.has(O)?[O]:[]:listAffectedDocNames(F,E,S);if(vt(),L.length===0){successResponse(t,200,TrashCleanupSuccessSchema,{deletedDocNames:[]},{handler:`trash-cleanup`});return}if(await Br(L),Pe)for(let e of L)isSystemDoc(e)||isConfigDoc(e)||(Pe.setDeleted(e),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:e,kind:`deleted`,source:`handleTrashCleanup`})));for(let e of L)D?.({kind:`delete`,path:resolve(g,`${e}${getDocExtension(e)}`),docName:e});E===`folder`&&it(S),de?.(`files`),successResponse(t,200,TrashCleanupSuccessSchema,{deletedDocNames:L},{handler:`trash-cleanup`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to clean up after trash.`,{handler:`trash-cleanup`,cause:e})}}),{handler:`trash-cleanup`,method:`POST`}),Ic=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=w(),s=[];for(let[t,S]of e){let e=t,w,E=getDocExtension(t);try{let s=readFileSync(resolve(g,`${t}${E}`),`utf-8`);e=extractPageTitle(s,t),w=extractPageIcon(s)}catch(e){console.warn(`[pages] Failed to read title for ${t}:`,e)}s.push({docName:t,title:e,docExt:E,size:S.size,modified:S.modified,icon:w})}s.sort((e,t)=>e.docName.localeCompare(t.docName)),successResponse(t,200,PagesSuccessSchema,{pages:s},{handler:`pages`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list pages.`,{handler:`pages`,cause:e})}},{handler:`pages`,method:`GET`,skipBodyParse:!0}),Lc=withValidation(EmptyRequestSchema,async(e,s)=>{try{let g=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!g){errorResponse(s,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`suggest-links`});return}if(!isSafeDocName(g)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`suggest-links`});return}if(isSystemDoc(g)||isConfigDoc(g)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`'${g}' is a reserved document name.`,{handler:`suggest-links`});return}successResponse(s,200,SuggestLinksSuccessSchema,await suggestLinks({hocuspocus:t,fileIndex:w(),docName:g}),{handler:`suggest-links`})}catch(e){if(e instanceof SuggestLinksTargetNotFoundError){errorResponse(s,404,`urn:ok:error:doc-not-found`,`Page not found.`,{handler:`suggest-links`,cause:e});return}errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to suggest links.`,{handler:`suggest-links`,cause:e})}},{handler:`suggest-links`,method:`GET`,skipBodyParse:!0});async function Rc(e,t){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`upload-asset`,extraHeaders:{Allow:`POST`}});return}let s;try{s=await readUploadBody(e,ye??g)}catch(e){if(e instanceof UploadWriteError){errorResponse(t,uploadStatusFor(e.reason),e.reason,uploadTitleFor(e.reason),{handler:`upload-asset`,cause:e});return}errorResponse(t,400,`urn:ok:error:malformed-upload`,`Failed to parse upload.`,{handler:`upload-asset`,cause:e});return}let{filename:S,tempPath:w,sha:E,byteLength:D,parentDocName:O}=s,k=()=>{if(existsSync(w))try{unlinkSync(w)}catch{}},j=validateBody(UploadRequestSchema,{parentDocName:O},t,{handler:`upload-asset`});if(!j.ok){k();return}let{parentDocName:F}=j.value,{agentId:L,agentName:B}=Yi(Object.fromEntries(new URL(e.url??``,`http://localhost`).searchParams.entries()));if(D===0){k(),errorResponse(t,400,`urn:ok:error:no-file-received`,`No file received.`,{handler:`upload-asset`});return}if(F.includes(`\0`)||F.includes(`..`)||F.startsWith(`/`)){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}let H=resolve(g),q=resolveUploadDestDir(F,`./`,H);if(!isWithinContentDir(q,H)){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}try{assertNoSymlinkEscape(q,H)}catch(e){if(k(),(e instanceof Error?e.message:String(e)).startsWith(`symlink-escape:`)){errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}log$6.error({err:e,destDir:q},`[upload] failed to validate destination directory`),errorResponse(t,500,`urn:ok:error:storage-error`,`Storage error.`,{handler:`upload-asset`,cause:e});return}try{mkdirSync(q,{recursive:!0})}catch(e){if(!isAlreadyExistsError(e)){k();let s=classifyUploadErrno(e);errorResponse(t,uploadStatusFor(s),s,uploadTitleFor(s),{handler:`upload-asset`,cause:e,detail:`failed to create attachment directory`});return}}try{let e=realpathSync(q),s;try{s=realpathSync(H)}catch{s=H}if(!isWithinContentDir(e,s)){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}}catch(e){if(e.code!==`ENOENT`){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`,cause:e});return}}let ee=await fileTypeFromFile(w),J=ee?.mime,Y=ee?.ext;if(!J){let e=readTempFileHead(w,256).toString(`utf-8`).replace(/^/,``).trimStart();(e.startsWith(`<svg`)||e.startsWith(`<?xml`)&&e.includes(`<svg`))&&(J=`image/svg+xml`,Y=`svg`)}{let s=await findDuplicateAsset(q,E,D);if(s){k();let S=toPosix(relative(g,resolve(q,s)));log$6.info({event:`upload`,endpoint:e.url??`/api/upload`,agentId:L,agentName:B,dedup:!0,mime:J??null,size:D,destPath:S,httpStatus:200},`[upload] dedup hit`),successResponse(t,200,UploadAssetSuccessSchema,{src:s,path:S,deduped:!0},{handler:`upload-asset`});return}}let te;if(!S||S===`upload`||GENERIC_PASTE_NAMES.test(S)){let e=new Date().toISOString().replace(/[-:T]/g,``).slice(0,14).replace(/(\d{8})(\d{6})/,`$1-$2`),t=S?extname(S).slice(1):``,s=Y??t??``;te=s===``?`pasted-${e}`:`pasted-${e}.${s}`}else te=sanitizeFilename(S);try{let s=linkTempToFinalWithCollisionRetry(w,q,te),S=toPosix(relative(g,resolve(q,s)));log$6.info({event:`upload`,endpoint:e.url??`/api/upload`,agentId:L,agentName:B,dedup:!1,mime:J??null,size:D,destPath:S,httpStatus:200},`[upload] write ok`),successResponse(t,200,UploadAssetSuccessSchema,{src:s,path:S,deduped:!1},{handler:`upload-asset`})}catch(s){let g=s instanceof UploadWriteError?s.reason:`urn:ok:error:storage-error`;log$6.error({event:`upload`,endpoint:e.url??`/api/upload`,agentId:L,agentName:B,filename:te,size:D,reason:g,httpStatus:uploadStatusFor(g),err:s},`[upload] write failed`),errorResponse(t,uploadStatusFor(g),g,uploadTitleFor(g),{handler:`upload-asset`,cause:s})}}let zc=`/api/local-op/clone`,Bc=`/api/local-op/ok-init`,Vc=600*1e3,Hc=45e3,Uc=`local-op-clone`,Wc=withValidation(LocalOpCloneRequestSchema,Gc,{handler:Uc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Uc})});async function Gc(e,t,s){let{url:g,dir:S,branch:w}=s;if(!isAllowedGitUrl(g)){errorResponse(t,400,`urn:ok:error:url-not-allowed`,`URL protocol is not allowed for clone.`,{handler:Uc,cause:Error(`url=${g}`)});return}if(!isSafeLocalPath(S)){errorResponse(t,400,`urn:ok:error:dir-outside-home`,`Clone destination must be within the user home directory.`,{handler:Uc,cause:Error(`dir=${S}`)});return}if(!We.tryAcquire(zc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A clone operation is already in progress.`,{handler:Uc,extraHeaders:{"Retry-After":`30`}});return}t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let E=createStreamingErrorWriter(t,Uc),D=null,O=runCloneSubprocess({cliArgs:ve,url:g,dir:S,branch:w,timeoutMs:Vc,onEvent:e=>{if(e.type===`complete`){D=e.dir;return}if(e.type===`error`){e.message&&log$6.warn({stderr:redactShareSubprocessStderr(e.message),url:g,dir:S},`[local-op/clone] clone failed`);let t=classifyCloneError(e.message??``);E(500,`urn:ok:error:clone-failed`,t.title,{detail:t.detail||void 0,cause:e.message?Error(redactShareSubprocessStderr(e.message)):void 0});return}if(!t.writableEnded&&!t.destroyed)try{t.write(`${JSON.stringify(e)}\n`)}catch{}}});(async()=>{try{if(await O.done,D&&!t.writableEnded&&!t.destroyed){let e=await Kc(D);!t.writableEnded&&!t.destroyed&&(`port`in e?t.write(`${JSON.stringify({type:`complete`,port:e.port,dir:D})}\n`):E(500,`urn:ok:error:server-start-failed`,`Cloned successfully but failed to start the project server.`,{cause:Error(e.error)}))}}catch(e){!t.writableEnded&&!t.destroyed?E(500,`urn:ok:error:internal-server-error`,`Unexpected error during clone post-processing.`,{cause:e}):log$6.error({err:e,handler:Uc},`clone IIFE rejected after stream ended`)}finally{t.writableEnded||t.end(),We.release(zc)}})(),t.on(`close`,()=>{O.cancel()})}async function Kc(e,t){let s=resolve(expandTilde(e)),g=getLocalDir(s),S=readUiLock(g);if(S&&S.port>0)return{port:S.port};let[w,...E]=ve,D=e=>{let s=t===void 0?[]:e===`ui`?[`--port`,String(t)]:[`--ui-port`,String(t)];return[...E,e,...s]},O=async e=>{let t=spawn(w,D(e),{cwd:s,detached:!0,stdio:[`ignore`,`ignore`,`pipe`],env:{...process.env,OK_LOCK_KIND:`interactive`}}),S=[];t.stderr?.on(`data`,t=>{S.push(t),log$6.warn({cwd:s,cliCmd:e,msg:t.toString(`utf-8`).trim()},`[local-op/clone] child stderr`)});let E=null,O=null,k=null;t.on(`exit`,(e,t)=>{E=e??-1,O=t??null}),t.on(`error`,t=>{k=t.message,E=-1,log$6.error({cwd:s,cliCmd:e,err:t.message},`[local-op/clone] failed to spawn child`)}),t.unref();let j=Date.now()+45e3;for(;Date.now()<j;){await setTimeout$1(500);let t=readUiLock(g);if(t&&t.port>0)return{port:t.port};if(E!==null){let t=Buffer.concat(S).toString(`utf-8`).trim();return{error:`\`ok ${e}\` exited (${k?`spawn failed: ${k}`:O?`killed by ${O}`:`code ${E}`})${t?` — ${t}`:``}`,exited:!0}}}let F=Buffer.concat(S).toString(`utf-8`).trim();return{error:`UI did not start within the expected time${F?` — ${F}`:``}`,exited:!1}},k=readServerLock(g),j=k&&k.port>0?`ui`:`start`,F=await O(j);if(j===`start`&&`error`in F&&F.exited){let e=readServerLock(g);if(e&&e.port>0){let e=await O(`ui`);return`port`in e?e:{error:`${F.error}; connect fallback failed: ${e.error}`}}}return`port`in F?F:{error:F.error}}let qc=`local-op-ok-init`,Jc=withValidation(LocalOpOkInitRequestSchema,async(e,t,s)=>{let{projectPath:g}=s;if(!isAbsolute(g)){errorResponse(t,400,`urn:ok:error:invalid-request`,`projectPath must be an absolute path.`,{handler:qc,cause:Error(`projectPath=${g}`)});return}let S;try{S=realpathSync(g)}catch(e){successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!1,reason:`not-a-git-worktree`,message:`projectPath does not exist or is not accessible: ${e.message}`},{handler:qc});return}if(!isSafeLocalPath(S)){errorResponse(t,400,`urn:ok:error:dir-outside-home`,`projectPath must be within the user home directory.`,{handler:qc,cause:Error(`projectPath=${g}`)});return}let w=resolveGitDirDetailed(S).kind;if(w!==`directory`&&w!==`linked`){console.warn(`[ok-init] action=init project=${basename(S)} result=not-a-git-worktree kind=${w}`),successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!1,reason:`not-a-git-worktree`,message:`projectPath is not a git working tree (.git is ${w}).`},{handler:qc});return}if(isProjectRoot(S)){console.warn(`[ok-init] action=init project=${basename(S)} result=already-initialized`),successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!0,projectPath:S},{handler:qc});return}if(!We.tryAcquire(Bc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An ok-init operation is already in progress.`,{handler:qc,extraHeaders:{"Retry-After":`2`}});return}try{await withParentLock(async()=>{initContent(S)}),console.warn(`[ok-init] action=init project=${basename(S)} result=success`),successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!0,projectPath:S},{handler:qc})}catch(e){let s=e instanceof Error?e.message:String(e);console.warn(`[ok-init] action=init project=${basename(S)} result=failed reason=${s}`),successResponse(t,200,LocalOpOkInitResponseSchema,{ok:!1,reason:`init-failed`,message:s},{handler:qc})}finally{We.release(Bc)}},{handler:qc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:qc})}),Yc=`/api/local-op/auth/login`,Xc=`/api/local-op/auth/status`,Zc=`/api/local-op/auth/repos`,Qc=`/api/local-op/auth/signout`,$c=null,nl=`local-op-auth-login`,il=withValidation(LocalOpAuthHostRequestSchema,al,{handler:nl,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:nl})});async function al(e,t,s){let g=s.host??`github.com`;if(!We.tryAcquire(Yc)){let e=$c;if(!e){console.error(JSON.stringify({event:`ok-local-op:auth-login-slot-no-controller`,channel:`auth`,transport:`http`})),errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth login operation is already in progress.`,{handler:nl,extraHeaders:{"Retry-After":`5`}});return}e.cancel(),$c=null,console.warn(JSON.stringify({event:`ok-local-op:idempotent-start-replaced-stale-slot`,channel:`auth`,transport:`http`}))}t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let S=createStreamingErrorWriter(t,nl),w=runDeviceFlowSubprocess({cliArgs:ve,host:g,timeoutMs:Vc,onEvent:e=>{if(e.type===`error`){S(500,`urn:ok:error:auth-failed`,`Auth subprocess reported an error.`,{cause:e.message?Error(e.message):void 0});return}if(resumeSyncOnAuthEvent(e,_e),!t.writableEnded&&!t.destroyed)try{t.write(`${JSON.stringify(e)}\n`)}catch{}}});$c=w;let E=()=>{w.cancel(),$c===w&&($c=null,We.release(Yc))};t.on(`close`,E),w.done.finally(()=>{if(t.off(`close`,E),!t.writableEnded&&!t.destroyed)try{t.end()}catch{}$c===w&&($c=null,We.release(Yc))})}let cl=`local-op-auth-status`,ll=withValidation(LocalOpAuthHostRequestSchema,async(e,t,s)=>{let g=s.host??`github.com`;if(!We.tryAcquire(Xc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth status operation is already in progress.`,{handler:cl,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...s]=ve,S=[...s,`auth`,`status`,`--json`,`--host`,g],w=(await new Promise((t,s)=>{let g=spawn(e,S,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),w=!1,E=setTimeout(()=>{w=!0,g.kill(`SIGTERM`)},3e4),D=[];g.stdout.on(`data`,e=>D.push(e)),g.on(`close`,()=>{if(clearTimeout(E),w){s(Error(`auth status subprocess timed out after 30s`));return}t(Buffer.concat(D).toString(`utf-8`))}),g.on(`error`,e=>{clearTimeout(E),s(e)})})).split(`
|
|
1941
|
+
`).map(e=>e.trim()).filter(Boolean),E=null;for(let e=w.length-1;e>=0;e--)try{E=JSON.parse(w[e]);break}catch{}E===null?successResponse(t,200,LocalOpAuthStatusSuccessSchema,{authenticated:!1},{handler:cl}):successResponse(t,200,LocalOpAuthStatusSuccessSchema,E,{handler:cl})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth status check failed.`,{handler:cl,cause:e})}finally{We.release(Xc)}},{handler:cl,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:cl})}),ul=`local-op-auth-repos`,dl=withValidation(LocalOpAuthHostRequestSchema,fl,{handler:ul,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:ul})});async function fl(e,t,s){let g=s.host??`github.com`;if(!We.tryAcquire(Zc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth repos operation is already in progress.`,{handler:ul,extraHeaders:{"Retry-After":`5`}});return}t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let S=createStreamingErrorWriter(t,ul),[w,...E]=ve,D=[...E,`auth`,`repos`,`--json`,`--host`,g],O=!1,k=``,j=spawn(w,D,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),F=setTimeout(()=>{j.kill(`SIGTERM`)},Vc);j.stdout.on(`data`,e=>{k+=e.toString(`utf-8`);let s=k.split(`
|
|
1942
|
+
`);k=s.pop()??``;for(let e of s){if(!e.trim())continue;let s=null;try{s=JSON.parse(e)}catch{}if(s&&s.type===`error`){S(500,`urn:ok:error:auth-failed`,`Auth repos subprocess reported an error.`,{detail:typeof s.message==`string`?s.message:void 0});continue}if(!t.writableEnded&&!t.destroyed)try{t.write(`${e}\n`)}catch{}}}),j.stderr.on(`data`,e=>{log$6.debug({msg:e.toString(`utf-8`).trim()},`[local-op/auth/repos] stderr`)}),j.on(`close`,e=>{clearTimeout(F),O||(O=!0,e!==0&&!t.writableEnded&&S(500,`urn:ok:error:auth-failed`,`Auth repos subprocess exited with code ${e}.`),t.end(),We.release(Zc))}),j.on(`error`,e=>{clearTimeout(F),O||(O=!0,t.writableEnded||(S(500,`urn:ok:error:auth-failed`,`Failed to spawn the auth repos subprocess.`,{cause:e}),t.end()),We.release(Zc))}),t.on(`close`,()=>{O||(O=!0,clearTimeout(F),j.kill(`SIGTERM`),We.release(Zc))})}let pl=`local-op-auth-signout`,ml=withValidation(LocalOpAuthHostRequestSchema,async(e,t,s)=>{let g=s.host??`github.com`;if(!We.tryAcquire(Qc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth signout operation is already in progress.`,{handler:pl,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...s]=ve,S=[...s,`auth`,`signout`,`--host`,g];await new Promise((t,s)=>{let g=spawn(e,S,{stdio:`ignore`,env:{...process.env}}),w=setTimeout(()=>{g.kill(`SIGTERM`)},3e4);g.on(`close`,()=>{clearTimeout(w),t()}),g.on(`error`,e=>{clearTimeout(w),s(e)})}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:pl})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth signout failed.`,{handler:pl,cause:e})}finally{We.release(Qc)}},{handler:pl,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:pl})}),hl=`/api/local-op/auth/set-identity`,gl=`local-op-auth-set-identity`,_l=withValidation(LocalOpAuthSetIdentityRequestSchema,async(e,t,s)=>{let g=s.name.trim(),S=s.email.trim();if(!ye){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:gl});return}if(!We.tryAcquire(hl)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A set-identity operation is already in progress.`,{handler:gl,extraHeaders:{"Retry-After":`5`}});return}try{writeGitIdentity(ye,g,S),_e?.()?.refreshIdentity().catch(()=>{}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:gl})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Set-identity failed.`,{handler:gl,cause:e})}finally{We.release(hl)}},{handler:gl,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:gl})});async function vl(e,t){if(checkLocalOpSecurity(e,t,{handler:`sync-status`})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-status`,extraHeaders:{Allow:`GET`}});return}try{let e=_e?.();if(!e){successResponse(t,200,SyncStatusSchema,{state:`dormant`,lastSyncUtc:null,lastFetchUtc:null,lastPushedSha:null,ahead:0,behind:0,consecutiveFailures:0,conflictCount:0,hasRemote:!1,syncEnabled:!1,identityUnresolved:!1,remote:null},{handler:`sync-status`});return}await e.refreshRemote(),successResponse(t,200,SyncStatusSchema,e.getStatus(),{handler:`sync-status`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`sync-status`,cause:e})}}}let yl=withValidation(SyncTriggerRequestSchema,async(e,t,s)=>{let g=_e?.();if(!g){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`});return}let S=s.op??`sync`;successResponse(t,202,SyncTriggerSuccessSchema,{op:S},{handler:`sync-trigger`}),g.trigger(S)},{handler:`sync-trigger`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-trigger`})?_e?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`}),!1):!1});async function xl(e,t){if(checkLocalOpSecurity(e,t,{handler:`sync-conflicts`})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflicts`,extraHeaders:{Allow:`GET`}});return}try{let e=_e?.();successResponse(t,200,SyncConflictsSuccessSchema,{conflicts:e?e.getConflicts():[]},{handler:`sync-conflicts`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`sync-conflicts`,cause:e})}}}let Cl=withValidation(SyncResolveConflictRequestSchema,async(e,t,s)=>{let g=_e?.();if(!g){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`});return}let{file:S,strategy:w,content:E}=s;try{await g.resolveConflict(S,w,E),successResponse(t,200,SyncResolveConflictSuccessSchema,{},{handler:`sync-resolve-conflict`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to resolve conflict.`,{handler:`sync-resolve-conflict`,cause:e,detail:e instanceof Error?e.message:void 0})}},{handler:`sync-resolve-conflict`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-resolve-conflict`})?_e?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`}),!1):!1});async function Tl(e,s){if(!checkLocalOpSecurity(e,s,{handler:`sync-conflict-content`}))return;if(e.method!==`GET`){errorResponse(s,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflict-content`,extraHeaders:{Allow:`GET`}});return}if(!ye){errorResponse(s,503,`urn:ok:error:project-repo-not-configured`,`Project repo not configured.`,{handler:`sync-conflict-content`});return}let g=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),S=g.searchParams.get(`file`);if(!S){errorResponse(s,400,`urn:ok:error:invalid-request`,`Missing required query param: file.`,{handler:`sync-conflict-content`});return}if(S.includes(`..`)||S.startsWith(`/`)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Invalid file path.`,{handler:`sync-conflict-content`});return}let w=stripDocExtension(S),E=t.documents.get(w)?.getMap(`lifecycle`).get(`status`)===`conflict`,D=_e?.(),O=D?D.getConflicts().some(e=>e.file===S):!1;if(!E&&!O){errorResponse(s,404,`urn:ok:error:no-conflict-tracked`,`No conflict is tracked for this path.`,{handler:`sync-conflict-content`,extensions:{file:S}});return}let k=g.searchParams.get(`source`),j=esm_default({baseDir:ye,timeout:{block:15e3}});async function F(e){try{return{present:!0,content:await j.raw([`show`,`:${e}:${S}`])}}catch(t){let s=t instanceof Error?t.message:String(t);if(!/pathspec|did not match|exists on disk, but not in|is in the index, but not at stage/i.test(s))throw console.warn(JSON.stringify({event:`showstage-unexpected-error`,stage:e,file:S,detail:s,handler:`sync-conflict-content`})),t;return{present:!1}}}try{let[e,g,w]=await Promise.all([F(1),F(2),F(3)]),E=e.present?e.content:``,D=w.present?w.content:``,O=g.present&&w.present?`both-modified`:!g.present&&w.present?`delete-modify`:g.present&&!w.present?`modify-delete`:`both-modified`,j=g.present?g.content:``,L=null;if(k===`ytext`){let e=stripDocExtension(S),s=t.documents.get(e);if(s){let t=s.getMap(`lifecycle`).get(`status`);if(L=typeof t==`string`&&t.length>0?t:null,O!==`delete-modify`){let t=Ie?Ie(e):null;t!==null&&!ytextHasConflictMarkers(t)?j=t:t!==null&&console.warn(JSON.stringify({event:`ytext-conflict-marker-detected`,"doc.name":e,handler:`sync-conflict-content`}))}}else console.warn(`[conflict-content] doc ${e} not loaded; lifecycleStatus unavailable`)}successResponse(s,200,SyncConflictContentSuccessSchema,{file:S,base:E,ours:j,theirs:D,kind:O,lifecycleStatus:L},{handler:`sync-conflict-content`})}catch(e){errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to read conflict content.`,{handler:`sync-conflict-content`,cause:e})}}async function El(e,t){if(!checkLocalOpSecurity(e,t,{handler:`seed-plan`}))return;if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`seed-plan`,extraHeaders:{Allow:`GET`}});return}let s=new URL(e.url??`/`,`http://localhost`),S=s.searchParams.get(`rootDir`)??void 0,w=s.searchParams.get(`packId`),E=coercePackId(w);if(w!==null&&w!==``&&E===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-plan`,detail:`Pack id "${w}" is not registered.`});return}try{successResponse(t,200,SeedPlanSuccessSchema,{plan:await planSeed({projectDir:g,rootDir:S,packId:E})},{handler:`seed-plan`})}catch(e){if(e instanceof SeedPrerequisiteError){errorResponse(t,422,`urn:ok:error:seed-prerequisite-missing`,`Seed prerequisite missing.`,{handler:`seed-plan`,cause:e});return}if(e instanceof SeedRootDirError){errorResponse(t,400,`urn:ok:error:seed-invalid-root`,`Invalid seed root directory.`,{handler:`seed-plan`,detail:`The provided root directory is not within the workspace content directory.`,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`seed-plan`,cause:e})}}let Dl=withValidation(SeedApplyRequestSchema,async(e,t,s)=>{let S=s.plan;if(!S||typeof S!=`object`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid plan payload.`,{handler:`seed-apply`});return}let w=S,E=s.packId,D=coercePackId(E);if(typeof E==`string`&&E.length>0&&D===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-apply`,detail:`Pack id "${E}" is not registered.`});return}try{successResponse(t,200,SeedApplySuccessSchema,{result:await applySeed(w,{projectDir:g,packId:D})},{handler:`seed-apply`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to apply seed plan.`,{handler:`seed-apply`,cause:e})}},{handler:`seed-apply`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`seed-apply`})});async function Ol(e,t){if(checkLocalOpSecurity(e,t,{handler:`seed-packs`})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`seed-packs`,extraHeaders:{Allow:`GET`}});return}successResponse(t,200,SeedListPacksSuccessSchema,{packs:listStarterPacks()},{handler:`seed-packs`})}}let kl=withValidation(InstallSkillRequestSchema,async(e,t,s)=>{if(s.out!==void 0&&!isSafeLocalPath(s.out)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Output path must be within home directory.`,{handler:`install-skill`});return}try{successResponse(t,200,InstallSkillSuccessSchema,await buildAndOpenSkill({...s.noOpen===void 0?{}:{noOpen:s.noOpen},...s.out===void 0?{}:{out:s.out}}),{handler:`install-skill`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to install skill.`,{handler:`install-skill`,cause:e})}},{handler:`install-skill`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`install-skill`})});async function jl(e,t){if(checkLocalOpSecurity(e,t,{handler:`installed-agents`}))try{await handleInstalledAgents(e,t,Tt.probeAll)}catch(e){t.headersSent||(log$6.error({err:e},`[installed-agents] route wrapper failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`installed-agents`,cause:e}))}}let Ml=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ue){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-list`});return}try{successResponse(t,200,TagsListSuccessSchema,{tags:ue.getAllTags()},{handler:`tags-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read tags.`,{handler:`tags-list`,cause:e})}},{handler:`tags-list`,method:`GET`,skipBodyParse:!0});async function Pl(e,t,s){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`tags-for-name`,extraHeaders:{Allow:`GET`}});return}if(!ue){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-for-name`});return}let g;try{g=decodeURIComponent(s)}catch{errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid tag name encoding.`,{handler:`tags-for-name`});return}if(!g){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing tag name.`,{handler:`tags-for-name`});return}try{let e=ue.getDocsForTagWithMatches(g).map(({docName:e,matchingTags:t})=>({docName:e,title:Dt(e),matchingTags:t,snippet:null}));successResponse(t,200,TagsForNameSuccessSchema,{name:g,docs:e},{handler:`tags-for-name`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read tag membership.`,{handler:`tags-for-name`,cause:e})}}function Fl(e,t,s=`path`,S=`folder-config`){let w=e.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``);if(w.split(`/`).some(e=>e===`..`)||e.startsWith(`/`))return errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid ${s}: must be project-root-relative.`,{handler:S}),null;let E=resolve(g),D=w===``?E:resolve(E,w);return D!==E&&!D.startsWith(`${E}${sep}`)?(errorResponse(t,400,`urn:ok:error:invalid-request`,`Path escapes content directory.`,{handler:S}),null):{folderRel:w,resolvedContentDir:E}}let Il=/^[A-Za-z0-9_-]+$/;function Ll(e,t,s=`template`){return!e||!Il.test(e)?(errorResponse(t,400,`urn:ok:error:invalid-request`,"Invalid name: must be letters / digits / `_` / `-` only (no `.md` extension).",{handler:s}),!1):!0}function Rl(e,t,s){let g=t===``?[]:t.split(`/`);for(let t=g.length;t>=0;t--){let S=t===0?``:g.slice(0,t).join(`/`),w=S===``?e:resolve(e,S);if(w!==e&&!w.startsWith(`${e}${sep}`))continue;let E=resolve(w,`.ok`,`templates`,`${s}.md`);if(existsSync(E))return{abs:E,folder:S,scope:t===g.length?`local`:`inherited`}}return null}function zl(e){let t={};if(!e||typeof e!=`object`||Array.isArray(e))return t;for(let[s,g]of Object.entries(e))g!==void 0&&(t[s]=g);return t}async function Bl(e,t){if(e.method===`GET`)return Vl(e,t);if(e.method===`PUT`)return Hl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`folder-config`,extraHeaders:{Allow:`GET, PUT`}})}let Vl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=Fl(new URL(e.url??``,`http://localhost`).searchParams.get(`path`)??``,t,`path`,`folder-config-get`);if(!s)return;let g=await enrichDirectory(s.folderRel,{projectDir:s.resolvedContentDir}),S=resolve(resolve(s.resolvedContentDir,s.folderRel,`.ok`),`frontmatter.yml`),w=null;if(existsSync(S))try{let e=(0,import_dist$1.parse)(await readFile$1(S,`utf-8`));w=e&&typeof e==`object`&&!Array.isArray(e)?e:{}}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[folder-config:get] malformed YAML in ${S}: ${t}`),w=null}successResponse(t,200,FolderConfigGetSuccessSchema,{folder:g,frontmatter_local:w},{handler:`folder-config-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read folder config.`,{handler:`folder-config-get`,cause:e})}},{handler:`folder-config-get`,method:`GET`,skipBodyParse:!0}),Hl=withValidation(FolderConfigPutRequestSchema,async(e,t,s)=>{try{if(Ue){errorResponse(t,403,`urn:ok:error:single-file-mode`,`Folder configuration is not available in single-file mode.`,{handler:`folder-config-put`});return}let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`folder-config-put`});return}let g=Fl(s.path,t,`path`,`folder-config-put`);if(!g)return;let S=[];if(s.frontmatter!==void 0){let w=applyFolderFrontmatterPatch({anchorDir:g.resolvedContentDir,folderRel:g.folderRel,patch:s.frontmatter});if(!w.ok){let e=w.error.code===`WRITE_ERROR`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to write folder config.`:w.error.message,{handler:`folder-config-put`,detail:w.error.code,cause:Error(w.error.message)});return}S.push({path:w.path,action:w.action}),w.action!==`noop`&&(Ts(e,Cs(`folder-frontmatter`,g.folderRel),`folder-frontmatter-${w.action===`deleted`?`delete`:`edit`}: ${w.path}`),await Ds(`folder-config-put`))}successResponse(t,200,FolderConfigPutSuccessSchema,{applied:S},{handler:`folder-config-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write folder config.`,{handler:`folder-config-put`,cause:e})}},{handler:`folder-config-put`,method:`PUT`});function Ul(e,s,g,S){if(!s)return!1;let w=e===``?`.ok/templates/${s}`:`${e.replace(/\/$/,``)}/.ok/templates/${s}`,E=t.documents.get(w);return E&&isDocInConflict(E)?(respondDocInConflict(S,new DocInConflictError({file:`${w}.md`}),g),!0):!1}function Wl(e,s,g){let S=t.documents.get(e);return S&&isDocInConflict(S)?(respondDocInConflict(g,new DocInConflictError({file:`${e}.md`}),s),!0):!1}let Gl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=resolveProjectTemplates(resolve(g));successResponse(t,200,TemplatesListSuccessSchema,{templates:e.templates.map(e=>{let{scope:t,...s}=e;return s}),truncated:e.truncated},{handler:`templates-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list templates.`,{handler:`templates-list`,cause:e})}},{handler:`templates-list`,method:`GET`,skipBodyParse:!0});async function Kl(e,t){if(e.method===`GET`)return Jl(e,t);if(e.method===`PUT`)return Yl(e,t);if(e.method===`POST`)return Zl(e,t);if(e.method===`DELETE`)return Xl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`template`,extraHeaders:{Allow:`GET, PUT, POST, DELETE`}})}let ql=e=>{let{frontmatter:t,body:s}=stripFrontmatter(e),g={};if(t!==``)try{let e=(0,import_dist$1.parse)(unwrapFrontmatterFences(t));e&&typeof e==`object`&&!Array.isArray(e)&&(g=e)}catch{}return{frontmatter:g,body:s}},Jl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Ll(g,t,`template-get`))return;let S=Fl(s.searchParams.get(`folder`)??``,t,`folder`,`template-get`);if(!S)return;let{folderRel:w,resolvedContentDir:E}=S,D=Rl(E,w,g);if(!D){errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-get`,detail:`Template "${g}" not found for folder "${w||`.`}". Walked leaf → root.`});return}let{abs:O,folder:k,scope:j}=D,F=parseTemplateFile(await readFile$1(O,`utf-8`)),L=F.identity,B=F.starterContent;successResponse(t,200,TemplateGetSuccessSchema,{template:{name:g,folder:k,scope:j,path:relative(E,O).split(/[\\/]/).filter(Boolean).join(`/`),frontmatter:L,body:B}},{handler:`template-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read template.`,{handler:`template-get`,cause:e})}},{handler:`template-get`,method:`GET`,skipBodyParse:!0}),Yl=withValidation(TemplatePutRequestSchema,async(e,t,g)=>{try{if(Ue){errorResponse(t,403,`urn:ok:error:single-file-mode`,`Templates are not available in single-file mode.`,{handler:`template-put`});return}let e=extractActorIdentity(g,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`template-put`});return}let S=g.name;if(!Ll(S,t,`template-put`))return;let w=Fl(g.folder,t,`folder`,`template-put`);if(!w||Ul(w.folderRel,S,`template-put`,t))return;let E=composeTemplateContent({name:S,body:typeof g.body==`string`?g.body:``,frontmatter:zl(g.frontmatter)});if(!E.ok){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid template request.`,{handler:`template-put`,detail:E.error.code,cause:Error(E.error.message)});return}let D=resolve(w.resolvedContentDir,w.folderRel,`.ok`,`templates`,`${S}.md`),O=!existsSync(D),k=relative(w.resolvedContentDir,D).split(/[\\/]/).filter(Boolean).join(`/`),j=ru(w.folderRel,S),{agentId:F,agentName:L,colorSeed:B,clientName:H}=Yi(g),q=await s.getSession(j,F,{displayName:L,colorSeed:B,clientName:H});q.dc.document.transact(()=>{composeAndWriteRawBody(q.dc.document,E.content,`agent`)},q.origin);let ee=await Ht(j);if(ee?.kind===`failure`){Ut(t,ee.failure,`template-put`);return}if(ee?.kind===`divergence`){Wt(t,`template-put`);return}Ts(e,Cs(`template`,w.folderRel,S),`${O?`template-create`:`template-edit`}: ${k}`),await Ds(`template-put`),successResponse(t,200,TemplatePutSuccessSchema,{path:k,created:O,warnings:E.warnings},{handler:`template-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write template.`,{handler:`template-put`,cause:e})}},{handler:`template-put`,method:`PUT`}),Xl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Ll(g,t,`template-delete`))return;let S=Fl(s.searchParams.get(`folder`)??``,t,`folder`,`template-delete`);if(!S)return;let w=s.searchParams,E=extractActorIdentity({agentId:w.get(`agentId`)??void 0,agentName:w.get(`agentName`)??void 0,colorSeed:w.get(`colorSeed`)??void 0,clientName:w.get(`clientName`)??void 0,clientVersion:w.get(`clientVersion`)??void 0,label:w.get(`label`)??void 0,summary:w.get(`summary`)??void 0},Ce);if(E.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`template-delete`});return}if(Ul(S.folderRel,g,`template-delete`,t))return;await Br([ru(S.folderRel,g)]);let D=applyTemplateDelete({projectDir:S.resolvedContentDir,folder:S.folderRel,name:g});if(!D.ok){let e=D.error.code===`WRITE_ERROR`||D.error.code===`UNLINK_FAILED`||D.error.code===`BAD_PROJECT_DIR`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to delete template.`:`Invalid template request.`,{handler:`template-delete`,detail:D.error.code,cause:Error(D.error.message)});return}D.existed&&(Ts(E,Cs(`template`,S.folderRel,g),`template-delete: ${D.path}`),await Ds(`template-delete`)),successResponse(t,200,TemplateDeleteSuccessSchema,{existed:D.existed,path:D.path},{handler:`template-delete`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to delete template.`,{handler:`template-delete`,cause:e})}},{handler:`template-delete`,method:`DELETE`,skipBodyParse:!0}),Zl=withValidation(TemplateMoveRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`template-move`});return}if(!Ll(s.fromName,t,`template-move`)||!Ll(s.toName,t,`template-move`))return;let g=Fl(s.fromFolder,t,`folder`,`template-move`);if(!g)return;let S=Fl(s.toFolder,t,`folder`,`template-move`);if(!S||Ul(g.folderRel,s.fromName,`template-move`,t))return;await Br([ru(g.folderRel,s.fromName)]);let w=await applyTemplateMove({projectDir:g.resolvedContentDir,fromFolder:g.folderRel,fromName:s.fromName,toFolder:S.folderRel,toName:s.toName,relocate:async(e,t)=>{let s=await renameTrackedPathInGit(ye,e,t);return s||renamePathOnDisk(e,t),s}});if(!w.ok){if(w.error.code===`TEMPLATE_NOT_FOUND`){let e=Rl(g.resolvedContentDir,g.folderRel,s.fromName);if(e?.scope===`inherited`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Template "${s.fromName}" is inherited from "${e.folder||`(root)`}", not local to "${g.folderRel||`(root)`}". Move it from the folder that owns it, or create a local copy here first (then move that).`,{handler:`template-move`,detail:`TEMPLATE_INHERITED`});return}errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-move`,detail:w.error.message});return}if(w.error.code===`TEMPLATE_EXISTS`){errorResponse(t,409,`urn:ok:error:doc-already-exists`,w.error.message,{handler:`template-move`,detail:w.error.code});return}let e=w.error.code===`WRITE_ERROR`||w.error.code===`MOVE_FAILED`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to move template.`:`Invalid template move request.`,{handler:`template-move`,detail:w.error.code,cause:Error(w.error.message)});return}let E=null;if(s.body!==void 0||s.frontmatter!==void 0){let e;if(typeof s.body==`string`)e=s.body;else try{e=instantiateDoc(readFileSync(resolve(S.resolvedContentDir,w.toPath),`utf-8`))}catch{e=null}if(e===null)E={code:`READ_FAILED`,message:`could not read the moved template to apply the metadata change; the move succeeded with the original content intact — retry the edit`};else{let t=applyTemplateWrite({projectDir:S.resolvedContentDir,folder:S.folderRel,name:s.toName,body:e,frontmatter:zl(s.frontmatter)});t.ok||(E=t.error)}}if(Ts(e,Cs(`template`,S.folderRel,s.toName),`template-rename: ${w.fromPath} -> ${w.toPath}`,[{from:w.fromPath,to:w.toPath}]),await Ds(`template-move`),de?.(`files`),E){let e=E.code===`WRITE_ERROR`||E.code===`READ_FAILED`;errorResponse(t,e?500:400,e?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,`Template moved to "${w.toPath}", but updating its content failed.`,{handler:`template-move`,detail:E.code,cause:Error(E.message)});return}successResponse(t,200,TemplateMoveSuccessSchema,{from:w.fromPath,to:w.toPath,committed:w.committed},{handler:`template-move`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to move template.`,{handler:`template-move`,cause:e})}},{handler:`template-move`,method:`POST`}),Ql=500;function $l(e,t,s){return!e||e.length>64||!SKILL_NAME_REGEX.test(e)?(errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill name: lowercase letters, digits, and hyphens only (≤64 chars; no slashes, dots, spaces, or uppercase).`,{handler:s}),!1):!0}function eu(e,t,s){let g=SkillScopeSchema.safeParse(e??`project`);return g.success?g.data:(errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill scope (expected "project" or "global").`,{handler:s}),null)}let tu=we??homedir();function nu(e){return resolve(e===`global`?tu:g,`.ok`,`skills`)}function ru(e,t){return`${MANAGED_ARTIFACT_PREFIX_TEMPLATE}${[...e?e.split(`/`).filter(Boolean).map(encodeURIComponent):[],encodeURIComponent(t)].join(`/`)}`}function iu(e){return e===`navigation`||e===`relevance`?e:void 0}function au(e,t){return relative(t===`global`?tu:g,e).split(/[\\/]/).filter(Boolean).join(`/`)}function ou(e){return e===`global`?tu:ye}async function su(e,t){let s=await removeSkillInstall(e,t);return reverseProjectSkill(t,e,PROJECT_SKILL_EDITOR_IDS),s!==null}function cu(e,t){let s=[];if(!existsSync(e))return{skills:s,truncated:!1};let g;try{g=readdirSync(e,{withFileTypes:!0})}catch(g){return getLogger(`skills`).warn({err:g,skillsRoot:e,scope:t},`failed to read skills root — returning empty skills list`),{skills:s,truncated:!1}}let S=!1;for(let w of g.sort((e,t)=>e.name.localeCompare(t.name))){if(!w.isDirectory()||!SKILL_NAME_REGEX.test(w.name))continue;if(s.length>=500){S=!0;break}let g=resolve(e,w.name,`SKILL.md`);if(!existsSync(g))continue;let E,D;try{let{frontmatter:e}=ql(readFileSync(g,`utf-8`));typeof e.description==`string`&&(E=e.description),typeof e.version==`string`&&e.version.trim()!==``&&(D=e.version)}catch{}s.push({name:w.name,...E===void 0?{}:{description:E},scope:t,path:au(g,t),absolutePath:g,...D===void 0?{}:{installedVersion:D}})}return{skills:s,truncated:S}}let lu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=cu(nu(`project`),`project`),s=cu(nu(`global`),`global`),g=ye?readInstalledSkills(ye).skills:{},S=readInstalledSkills(tu).skills,w=(e,t)=>e.skills.map(e=>{let s=t[e.name]?.hosts??[],g=computePackUpdateStatus(e.name,e.installedVersion);return{...e,installed:s.length>0,hosts:s,...g}});successResponse(t,200,SkillsListSuccessSchema,{skills:[...w(e,g),...w(s,S)],truncated:e.truncated||s.truncated},{handler:`skills-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list skills.`,{handler:`skills-list`,cause:e})}},{handler:`skills-list`,method:`GET`,skipBodyParse:!0});async function uu(e,t){if(e.method===`GET`)return gu(e,t);if(e.method===`PUT`)return _u(e,t);if(e.method===`POST`)return yu(e,t);if(e.method===`DELETE`)return vu(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`skill`,extraHeaders:{Allow:`GET, PUT, POST, DELETE`}})}let du=object$1({managed:boolean().nullable(),importable:number().int().nonnegative()}),fu=()=>({managed:ye?readSkillManagement(ye)?.manageEditorSkills??null:null,importable:ye?countImportableEditorSkills({projectDir:ye,skillsRoot:nu(`project`)}):0}),pu=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ye){errorResponse(t,400,`urn:ok:error:invalid-request`,`No project root resolved.`,{handler:`skills-management-get`,detail:`NO_PROJECT_ROOT`});return}successResponse(t,200,du,fu(),{handler:`skills-management-get`})},{handler:`skills-management-get`,method:`GET`,skipBodyParse:!0}),mu=withValidation(object$1({manageEditorSkills:boolean()}),async(e,t,s)=>{if(!ye){errorResponse(t,400,`urn:ok:error:invalid-request`,`No project root resolved.`,{handler:`skills-management-put`,detail:`NO_PROJECT_ROOT`});return}if(await writeSkillManagement(ye,{manageEditorSkills:s.manageEditorSkills,surface:`ui`}),s.manageEditorSkills){let e=await reconcileSkillInstalls({projectDir:ye,skillsRoot:nu(`project`)});e.adopted.length+e.collided.length>0&&de?.(`files`)}successResponse(t,200,du,fu(),{handler:`skills-management-put`})},{handler:`skills-management-put`,method:`PUT`});async function hu(e,t){if(e.method===`GET`)return pu(e,t);if(e.method===`PUT`)return mu(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`skills-management`,extraHeaders:{Allow:`GET, PUT`}})}let gu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!$l(g,t,`skill-get`))return;let S=eu(s.searchParams.get(`scope`),t,`skill-get`);if(S===null)return;let w=nu(S),E=resolve(w,g,`SKILL.md`);if(!existsSync(E)){errorResponse(t,404,`urn:ok:error:not-found`,`Skill not found.`,{handler:`skill-get`,detail:`Skill "${g}" not found in ${S} scope.`});return}let{frontmatter:D,body:O}=ql(await readFile$1(E,`utf-8`));successResponse(t,200,SkillGetSuccessSchema,{skill:{name:g,scope:S,path:au(E,S),frontmatter:{name:typeof D.name==`string`?D.name:g,description:typeof D.description==`string`?D.description:``},body:O,files:readSkillBundledFiles(resolve(w,g))}},{handler:`skill-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read skill.`,{handler:`skill-get`,cause:e})}},{handler:`skill-get`,method:`GET`,skipBodyParse:!0}),_u=withValidation(SkillPutRequestSchema,async(e,t,g)=>{try{let e=extractActorIdentity(g,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-put`});return}if(!$l(g.name,t,`skill-put`))return;let S=composeSkillContent({name:g.name,body:typeof g.body==`string`?g.body:``,frontmatter:{name:g.frontmatter.name,description:g.frontmatter.description}});if(!S.ok){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill request.`,{handler:`skill-put`,detail:S.error.code,cause:Error(S.error.message)});return}let w=nu(g.scope),E=resolve(w,g.name,`SKILL.md`),D=!existsSync(E),O=relative(w,E).split(/[\\/]/).filter(Boolean).join(`/`),k=skillLiveDocName(g.scope,g.name);if(Wl(k,`skill-put`,t))return;let{agentId:j,agentName:F,colorSeed:L,clientName:B}=Yi(g),H=await s.getSession(k,j,{displayName:F,colorSeed:L,clientName:B});H.dc.document.transact(()=>{composeAndWriteRawBody(H.dc.document,S.content,`agent`)},H.origin);let q=await Ht(k);if(q?.kind===`failure`){Ut(t,q.failure,`skill-put`);return}if(q?.kind===`divergence`){Wt(t,`skill-put`);return}g.scope===`project`&&(Ts(e,Cs(`skill`,``,g.name),`${D?`skill-create`:`skill-edit`}: ${O}`),await Ds(`skill-put`)),de?.(`files`),successResponse(t,200,SkillPutSuccessSchema,{path:O,created:D,warnings:S.warnings},{handler:`skill-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write skill.`,{handler:`skill-put`,cause:e})}},{handler:`skill-put`,method:`PUT`}),vu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!$l(g,t,`skill-delete`))return;let S=eu(s.searchParams.get(`scope`),t,`skill-delete`);if(S===null)return;let w=nu(S),E=s.searchParams,D=extractActorIdentity({agentId:E.get(`agentId`)??void 0,agentName:E.get(`agentName`)??void 0,colorSeed:E.get(`colorSeed`)??void 0,clientName:E.get(`clientName`)??void 0,clientVersion:E.get(`clientVersion`)??void 0,label:E.get(`label`)??void 0,summary:E.get(`summary`)??void 0},Ce);if(D.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-delete`});return}await Br([skillLiveDocName(S,g)]);let O=applySkillDelete({skillsRoot:w,name:g});if(!O.ok){let e=O.error.code===`UNLINK_FAILED`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to delete skill.`:`Invalid skill request.`,{handler:`skill-delete`,detail:O.error.code,cause:Error(O.error.message)});return}O.existed&&(S===`project`&&(Ts(D,Cs(`skill`,``,g),`skill-delete: ${O.path}`),await Ds(`skill-delete`)),de?.(`files`));let k=ou(S);k&&await su(k,g),successResponse(t,200,SkillDeleteSuccessSchema,{existed:O.existed,path:O.path},{handler:`skill-delete`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to delete skill.`,{handler:`skill-delete`,cause:e})}},{handler:`skill-delete`,method:`DELETE`,skipBodyParse:!0}),yu=withValidation(SkillMoveRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-move`});return}if(!$l(s.fromName,t,`skill-move`)||!$l(s.toName,t,`skill-move`))return;let g=nu(s.scope);await Br([skillLiveDocName(s.scope,s.fromName)]);let S=await applySkillMove({skillsRoot:g,fromName:s.fromName,toName:s.toName,relocate:async(e,t)=>{let s=await renameTrackedPathInGit(ye,e,t);return s||renamePathOnDisk(e,t),s}});if(!S.ok){if(S.error.code===`SKILL_NOT_FOUND`){errorResponse(t,404,`urn:ok:error:not-found`,`Skill not found.`,{handler:`skill-move`,detail:S.error.message});return}if(S.error.code===`SKILL_EXISTS`){errorResponse(t,409,`urn:ok:error:doc-already-exists`,S.error.message,{handler:`skill-move`,detail:S.error.code});return}let e=S.error.code===`MOVE_FAILED`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to move skill.`:`Invalid skill move request.`,{handler:`skill-move`,detail:S.error.code,cause:Error(S.error.message)});return}let w=null,E=resolve(g,s.toName,`SKILL.md`),D=``,O=``;try{let e=ql(readFileSync(E,`utf-8`));D=e.body,typeof e.frontmatter.description==`string`&&(O=e.frontmatter.description)}catch{}let k=typeof s.body==`string`?s.body:D,j=s.frontmatter===void 0?O:s.frontmatter.description,F=applySkillWrite({skillsRoot:g,name:s.toName,body:k,frontmatter:{name:s.toName,description:j}});if(F.ok||(w=F.error),s.scope===`project`&&!w)try{wu(g,s.fromName,s.toName)}catch(e){getLogger(`skill-move`).warn({err:e,fromName:s.fromName,toName:s.toName},`reindex of moved project skill docs failed — rename succeeded, deferring to next rescan`)}let L=au(resolve(g,s.fromName),s.scope),B=au(resolve(g,s.toName),s.scope);s.scope===`project`&&(Ts(e,Cs(`skill`,``,s.toName),`skill-rename: ${L} -> ${B}`,[{from:L,to:B}]),await Ds(`skill-move`));let H=ou(s.scope);if(H){let e=await removeSkillInstall(H,s.fromName);if(e){let t=resolvedHosts(e.hosts);reverseProjectSkill(s.fromName,H,t);let S=projectSkill(resolve(g,s.toName),s.toName,H,t);await recordSkillInstall(H,s.toName,{...e,hosts:S})}}if(de?.(`files`),w){let e=w.code===`WRITE_ERROR`;errorResponse(t,e?500:400,e?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,`Skill renamed to "${s.toName}", but updating its SKILL.md failed — its name frontmatter may not match the new directory.`,{handler:`skill-move`,detail:w.code,cause:Error(w.message)});return}successResponse(t,200,SkillMoveSuccessSchema,{from:L,to:B,committed:S.committed},{handler:`skill-move`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to move skill.`,{handler:`skill-move`,cause:e})}},{handler:`skill-move`,method:`POST`});function bu(e){if(e.includes(`\0`))return null;let t=e.replace(/\\/g,`/`).split(`/`).filter(e=>e!==``&&e!==`.`);return t.length<2||t.some(e=>e===`..`)?null:t[0]===`references`?`reference`:t[0]===`scripts`?`script`:null}function xu(e,t,s){return e===`project`&&t===`reference`&&s.toLowerCase().endsWith(`.md`)}function Su(e,t){let s=t.replace(/\.md$/i,``);return`${projectSkillContentDocName(e).replace(/\/SKILL$/,``)}/${s}`}function Cu(e,t){let s=resolve(e,t,`references`);if(!existsSync(s))return[];let g=[],S=(e,t)=>{for(let s of readdirSync(e,{withFileTypes:!0})){let w=t?`${t}/${s.name}`:s.name;s.isDirectory()?S(resolve(e,s.name),w):s.isFile()&&s.name.toLowerCase().endsWith(`.md`)&&g.push(`references/${w}`)}};return S(s,``),g}function wu(e,t,s){if(!ce)return;let g=(e,t,s)=>{let g;try{g=readFileSync(s,`utf-8`)}catch{ce.deleteDocument(e),ue?.deleteDocument(e);return}ce.renameDocument(e,t,g),ue?.renameDocument(e,t,g)};g(projectSkillContentDocName(t),projectSkillContentDocName(s),resolve(e,s,`SKILL.md`));for(let S of Cu(e,s))g(Su(t,S),Su(s,S),resolve(e,s,S));de?.(`backlinks`),de?.(`graph`)}let Tu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!$l(g,t,`skill-file-get`))return;let S=eu(s.searchParams.get(`scope`),t,`skill-file-get`);if(S===null)return;let w=s.searchParams.get(`path`)??``,E=bu(w);if(E===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill file path (must be a file under references/ or scripts/).`,{handler:`skill-file-get`});return}let D=resolve(nu(S),g),O=resolve(D,w);if(O!==D&&!O.startsWith(`${D}${sep}`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Skill file path escapes the skill dir.`,{handler:`skill-file-get`});return}let k=O,j=w;if(!existsSync(k)){let e=w.match(/^(.*)\.(?:md|mdx)$/),s=e?SUPPORTED_DOC_EXTENSIONS.map(t=>`${e[1]}${t}`).find(e=>e!==w&&existsSync(resolve(D,e))):void 0;if(s===void 0){errorResponse(t,404,`urn:ok:error:not-found`,`Skill file not found.`,{handler:`skill-file-get`,detail:`${w} not found in skill "${g}" (${S}).`});return}j=s,k=resolve(D,s)}let F=await readFile$1(k);if(F.includes(0)){errorResponse(t,415,`urn:ok:error:invalid-request`,`Skill file is binary — only text bundle files are readable via MCP.`,{handler:`skill-file-get`});return}successResponse(t,200,SkillFileGetSuccessSchema,{path:j.replace(/\\/g,`/`),kind:E,text:F.toString(`utf-8`)},{handler:`skill-file-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read skill file.`,{handler:`skill-file-get`,cause:e})}},{handler:`skill-file-get`,method:`GET`,skipBodyParse:!0}),Eu=withValidation(SkillFilePutRequestSchema,async(e,t,g)=>{try{let e=extractActorIdentity(g,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-file-put`});return}if(!$l(g.name,t,`skill-file-put`))return;let S=bu(g.path);if(S===null){errorResponse(t,400,`urn:ok:error:invalid-request`,"Invalid skill file path (must be a file under references/ or scripts/, no `..`).",{handler:`skill-file-put`});return}if(Buffer.byteLength(g.content,`utf-8`)>262144){errorResponse(t,400,`urn:ok:error:invalid-request`,`Skill file exceeds the 256 KB per-file cap.`,{handler:`skill-file-put`});return}let w=nu(g.scope);if(!existsSync(resolve(w,g.name,`SKILL.md`))){errorResponse(t,404,`urn:ok:error:not-found`,`Skill not found.`,{handler:`skill-file-put`,detail:`Create skill "${g.name}" before adding bundle files.`});return}let E=g.path.replace(/\\/g,`/`),D=xu(g.scope,S,E),O;if(D){let e=Su(g.name,E);if(Wl(e,`skill-file-put`,t))return;if(O=!existsSync(resolve(w,g.name,E)),O&&countBundleFiles(resolve(w,g.name))>=50){errorResponse(t,400,`urn:ok:error:invalid-request`,`Skill "${g.name}" already holds 50 bundle files (the cap) — delete one before adding another.`,{handler:`skill-file-put`});return}let{agentId:S,agentName:D,colorSeed:k,clientName:j}=Yi(g),F=await s.getSession(e,S,{displayName:D,colorSeed:k,clientName:j});F.dc.document.transact(()=>{composeAndWriteRawBody(F.dc.document,g.content,`agent`)},F.origin);let L=await Ht(e);if(L?.kind===`failure`){Ut(t,L.failure,`skill-file-put`);return}if(L?.kind===`divergence`){Wt(t,`skill-file-put`);return}}else{let e=applySkillBundleFileWrite({skillsRoot:w,name:g.name,relPath:E,content:g.content});if(!e.ok){let s=e.error.code===`WRITE_ERROR`?500:e.error.code===`SKILL_NOT_FOUND`?404:400;errorResponse(t,s,s===500?`urn:ok:error:internal-server-error`:s===404?`urn:ok:error:not-found`:`urn:ok:error:invalid-request`,s===500?`Failed to write skill file.`:`Invalid skill file request.`,{handler:`skill-file-put`,detail:e.error.code,cause:Error(e.error.message)});return}O=e.created}g.scope===`project`&&(Ts(e,Cs(`skill`,``,g.name),`${O?`skill-file-create`:`skill-file-edit`}: .ok/skills/${g.name}/${E}`),await Ds(`skill-file-put`)),de?.(`files`),successResponse(t,200,SkillFilePutSuccessSchema,{path:E,created:O,kind:S,content:D},{handler:`skill-file-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write skill file.`,{handler:`skill-file-put`,cause:e})}},{handler:`skill-file-put`,method:`PUT`}),Du=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`).searchParams,g=s.get(`name`)??``;if(!$l(g,t,`skill-file-delete`))return;let S=eu(s.get(`scope`),t,`skill-file-delete`);if(S===null)return;let w=(s.get(`path`)??``).replace(/\\/g,`/`),E=bu(w);if(E===null){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid skill file path (must be a file under references/ or scripts/).`,{handler:`skill-file-delete`});return}let D=extractActorIdentity({agentId:s.get(`agentId`)??void 0,agentName:s.get(`agentName`)??void 0,colorSeed:s.get(`colorSeed`)??void 0,clientName:s.get(`clientName`)??void 0,clientVersion:s.get(`clientVersion`)??void 0,label:s.get(`label`)??void 0,summary:s.get(`summary`)??void 0},Ce);if(D.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-file-delete`});return}let O=nu(S);xu(S,E,w)&&await Br([Su(g,w)]);let k=applySkillBundleFileDelete({skillsRoot:O,name:g,relPath:w});if(!k.ok){let e=k.error.code===`UNLINK_FAILED`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to delete skill file.`:`Invalid skill file request.`,{handler:`skill-file-delete`,detail:k.error.code,cause:Error(k.error.message)});return}k.existed&&S===`project`&&(Ts(D,Cs(`skill`,``,g),`skill-file-delete: .ok/skills/${g}/${w}`),await Ds(`skill-file-delete`)),k.existed&&de?.(`files`),successResponse(t,200,SkillFileDeleteSuccessSchema,{path:w,existed:k.existed,kind:E},{handler:`skill-file-delete`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to delete skill file.`,{handler:`skill-file-delete`,cause:e})}},{handler:`skill-file-delete`,method:`DELETE`,skipBodyParse:!0});async function Ou(e,t){if(e.method===`GET`)return Tu(e,t);if(e.method===`PUT`)return Eu(e,t);if(e.method===`DELETE`)return Du(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`skill-file`,extraHeaders:{Allow:`GET, PUT, DELETE`}})}let ku=withValidation(SkillInstallRequestSchema,async(e,t,s)=>{try{let e=nu(s.scope);if(!$l(s.name,t,`skill-install`))return;if(s.scope===`project`&&!ye){errorResponse(t,400,`urn:ok:error:invalid-request`,`Cannot install — no project root is resolved for this server. Skills project into editor host dirs at the project root.`,{handler:`skill-install`,detail:`NO_PROJECT_ROOT`});return}let g=ou(s.scope),S=resolve(e,s.name);if(!existsSync(S)){errorResponse(t,404,`urn:ok:error:not-found`,`Skill not found.`,{handler:`skill-install`,detail:`Skill "${s.name}" not found in ${s.scope} scope — create it with write({ skill }) first.`});return}let w=validateSkillForInstall(S,s.name);if(!w.ok){errorResponse(t,400,`urn:ok:error:invalid-request`,`Skill "${s.name}" cannot be installed: ${w.errors.join(` `)}`,{handler:`skill-install`,detail:`INVALID_SKILL_SOURCE`});return}let E=s.scope===`global`?s.targets?PROJECT_SKILL_EDITOR_IDS.filter(e=>s.targets?.some(t=>t===e)):[...PROJECT_SKILL_EDITOR_IDS]:s.targets===void 0?resolveSkillTargets(g,readSkillTargets(g)??void 0):PROJECT_SKILL_EDITOR_IDS.filter(e=>s.targets?.some(t=>t===e)),D=[],O=[];E.length===0&&s.targets===void 0&&(D.push(s.scope===`global`?`No editor skill folders are configured to install into.`:"No project-configured editors detected — nothing was projected. Set up an editor for this project (add .mcp.json / .cursor/mcp.json / .codex/config.toml) or pass explicit `targets`."),O.push(`no-targets`)),w.hasScripts&&(D.push("This skill includes executable `scripts/`. After you install it, the AI agent in your editor (Claude, Cursor, Codex) can run them — Open Knowledge itself never runs anything. Review the scripts before sharing."),O.push(`scripts-present`));let k=resolvedHosts(readInstalledSkills(g).skills[s.name]?.hosts??[]).filter(e=>!E.includes(e));k.length>0&&reverseProjectSkill(s.name,g,k);let j=projectSkill(S,s.name,g,E);j.length===0?await removeSkillInstall(g,s.name):await recordSkillInstall(g,s.name,{hosts:j,scope:s.scope,scripts:w.hasScripts,installedAt:new Date().toISOString()}),de?.(`files`),successResponse(t,200,SkillInstallSuccessSchema,{name:s.name,hosts:j,scripts:w.hasScripts,warnings:D,warningCodes:O},{handler:`skill-install`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to install skill.`,{handler:`skill-install`,cause:e})}},{handler:`skill-install`,method:`POST`}),Au=withValidation(SkillUninstallRequestSchema,async(e,t,s)=>{try{if(!$l(s.name,t,`skill-uninstall`))return;let e=ou(s.scope);if(!e){errorResponse(t,400,`urn:ok:error:invalid-request`,`Cannot uninstall — no project root is resolved for this server.`,{handler:`skill-uninstall`,detail:`NO_PROJECT_ROOT`});return}let g=await su(e,s.name);de?.(`files`),successResponse(t,200,SkillUninstallSuccessSchema,{name:s.name,uninstalled:g},{handler:`skill-uninstall`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to uninstall skill.`,{handler:`skill-uninstall`,cause:e})}},{handler:`skill-uninstall`,method:`POST`});async function ju(e,t){if(e.method===`GET`)return Mu(e,t);if(e.method===`PUT`)return Nu(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`skill-targets`,extraHeaders:{Allow:`GET, PUT`}})}let Mu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=ye?readSkillTargets(ye):null;successResponse(t,200,SkillTargetsGetSuccessSchema,{targets:resolveSkillTargets(ye??``,e??void 0),configured:e!==null},{handler:`skill-targets-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read skill targets.`,{handler:`skill-targets-get`,cause:e})}},{handler:`skill-targets-get`,method:`GET`,skipBodyParse:!0}),Nu=withValidation(SkillTargetsPutRequestSchema,async(e,t,s)=>{try{if(!ye){errorResponse(t,400,`urn:ok:error:invalid-request`,`Cannot set skill targets — no project root is resolved for this server.`,{handler:`skill-targets-put`,detail:`NO_PROJECT_ROOT`});return}let e=s.targets,g=new Set(e),S=resolveSkillTargets(ye,readSkillTargets(ye)??void 0),w=nu(`project`);await writeSkillTargets(ye,e);let{reprojected:E,bundleHosts:D}=await reprojectAllManagedSkills({projectDir:ye,skillsRoot:w,targets:e});de?.(`files`),successResponse(t,200,SkillTargetsPutSuccessSchema,{targets:e,reprojected:E,bundleHosts:D,removedFrom:S.filter(e=>!g.has(e))},{handler:`skill-targets-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to set skill targets.`,{handler:`skill-targets-put`,cause:e})}},{handler:`skill-targets-put`,method:`PUT`}),Pu=withValidation(SkillRestoreRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-restore`});return}if(!$l(s.name,t,`skill-restore`))return;if(s.scope===`global`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Global skills are unversioned — there is no version history to restore from.`,{handler:`skill-restore`,detail:`GLOBAL_SCOPE_UNVERSIONED`});return}let S=q?.current;if(!S){errorResponse(t,409,`urn:ok:error:shadow-not-configured`,`No version history available to restore from.`,{handler:`skill-restore`,detail:`NO_SHADOW_REPO`});return}let w=await restoreSkillVersion({shadow:S,contentDir:g,contentRoot:se??`.`,name:s.name,version:s.version});if(!w.ok){let[e,s]={"no-shadow":[409,`urn:ok:error:shadow-not-configured`],"version-not-found":[404,`urn:ok:error:not-found`],"skill-absent":[404,`urn:ok:error:not-found`],"io-error":[500,`urn:ok:error:storage-error`],"path-escape":[500,`urn:ok:error:path-escape`]}[w.code];errorResponse(t,e,s,w.error,{handler:`skill-restore`,detail:w.code});return}let E=[],D=validateSkillForInstall(resolve(g,`.ok`,`skills`,s.name),s.name);D.ok||E.push(`Restored, but the skill no longer validates: ${D.errors.join(` `)}`),E.push("Run `install` to push the restored version to your editors."),Ts(e,Cs(`skill`,``,s.name),`skill-restore: ${s.name} @ ${s.version.slice(0,8)}`),await Ds(`skill-restore`),de?.(`files`),successResponse(t,200,SkillRestoreSuccessSchema,{name:s.name,version:s.version,restoredFiles:w.restoredFiles,warnings:E},{handler:`skill-restore`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to restore skill.`,{handler:`skill-restore`,cause:e})}},{handler:`skill-restore`,method:`POST`}),Fu=withValidation(SkillUpdateRequestSchema,async(e,t,g)=>{try{let e=extractActorIdentity(g,Ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`skill-update`});return}if(!$l(g.name,t,`skill-update`))return;if(!isPackSkillName(g.name)){errorResponse(t,400,`urn:ok:error:invalid-request`,"Only starter-pack skills (`open-knowledge-pack-*`) can be updated from the bundle.",{handler:`skill-update`,detail:`NOT_A_PACK_SKILL`});return}if(g.scope===`global`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Pack skills are project-scope — there is no global-scope pack to update.`,{handler:`skill-update`,detail:`GLOBAL_SCOPE`});return}let S=readBundledPackSkill(g.name);if(S===null||S.version===void 0){errorResponse(t,404,`urn:ok:error:not-found`,`No bundled version is available for this pack skill.`,{handler:`skill-update`,detail:`NO_BUNDLED_VERSION`});return}let w=resolve(nu(`project`),g.name,`SKILL.md`);if(!existsSync(w)){errorResponse(t,404,`urn:ok:error:not-found`,`Skill is not installed.`,{handler:`skill-update`,detail:`SKILL_ABSENT`});return}let E;try{E=readSkillVersion(readFileSync(w,`utf-8`))}catch{}let D,O=q?.current;if(O)try{let e=ae?.()??`main`;D=(await saveVersion(O,se??`.`,[SERVICE_WRITER],e,`Before updating ${g.name} (${E??`unversioned`} → ${S.version})`)).checkpointRef}catch(e){getLogger(`skills`).warn({err:e,skill:g.name},`pre-update checkpoint failed — proceeding with overwrite`)}let k=skillLiveDocName(`project`,g.name);if(Wl(k,`skill-update`,t))return;let{agentId:j,agentName:F,colorSeed:L,clientName:B}=Yi(g),H=await s.getSession(k,j,{displayName:F,colorSeed:L,clientName:B});H.dc.document.transact(()=>{composeAndWriteRawBody(H.dc.document,S.content,`agent`)},H.origin);let ee=await Ht(k);if(ee?.kind===`failure`){Ut(t,ee.failure,`skill-update`);return}if(ee?.kind===`divergence`){Wt(t,`skill-update`);return}Ts(e,Cs(`skill`,``,g.name),`skill-pack-update: ${g.name} (${E??`unversioned`} → ${S.version})`),await Ds(`skill-update`),de?.(`files`),successResponse(t,200,SkillUpdateSuccessSchema,{name:g.name,version:S.version,...E===void 0?{}:{previousVersion:E},...D===void 0?{}:{checkpointRef:D}},{handler:`skill-update`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to update skill.`,{handler:`skill-update`,cause:e})}},{handler:`skill-update`,method:`POST`});function Iu(e){let t=new Map;for(let s of e){let e=s.path.split(`/`).filter(Boolean);e.pop();for(let g=1;g<=e.length;g++){let S=e.slice(0,g).join(`/`);t.set(S,Math.max(t.get(S)??0,s.modifiedTs))}}return[...t.entries()].map(([e,t])=>createWorkspaceSearchDocument({kind:`folder`,path:e,modifiedTs:t}))}function Lu(e,t){let s=t.trim().toLowerCase();if(!s||!e)return;let g=e.toLowerCase().indexOf(s);if(g<0)return;let S=Math.max(0,g-80),w=Math.min(e.length,g+s.length+120),E=S>0?`…`:``,D=w<e.length?`…`:``;return`${E}${e.slice(S,w).replace(/\s+/g,` `).trim()}${D}`}function Ru(e){return e===`autocomplete`||e===`full_text`||e===`omnibar`?e:`omnibar`}function zu(e){let t=typeof e==`string`?e.split(`,`):Array.isArray(e)?e:void 0;if(!t)return;let s=t.filter(e=>e===`page`||e===`folder`||e===`content`||e===`file`);return s.length>0?s:void 0}function Bu(e){if(typeof e==`boolean`)return e;if(e===`true`)return!0;if(e===`false`)return!1}function Vu(e){return e===`omnibar`||e===`mcp`||e===`http`?e:`http`}async function Hu(e,t,s,g){let S=g.documents.filter(e=>!isHiddenDocName(e.path)),w=S.reduce((e,t)=>e+(t.kind===`page`?1:0),0);if(!ze?.isEnabled()||s!==!0)return{queryEmbedMs:null,pageTotal:w,capable:!1};ze.embedCorpus(S);let E,D=null;if(t===`full_text`&&e.trim().length>=3){let t=performance.now(),s=await ze.queryScores(e,S);if(D=performance.now()-t,s&&s.size>0){let e=Be?.();E=e===void 0?{scores:s}:{scores:s,similarityFloor:e}}}let O=ze.getStatus();return{input:E,status:{capable:O.capable,applied:!1,coverage:{embedded:O.embeddedCount,total:w}},queryEmbedMs:D,pageTotal:w,capable:O.capable}}function Uu(e,t){return{kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?Lu(e.document.content,t):void 0}}async function Wu(e){let t=performance.now();if($u())return{query:e.query,intent:e.intent,results:[],elapsedMs:Math.max(0,performance.now()-t),ready:!1};let{corpus:s,truncated:g}=await ed(),S=await Hu(e.query,e.intent,e.semanticParam,s),w=searchWorkspaceCorpus(s,e.query,{intent:e.intent,ranking:e.ranking,scopes:e.scopes,limit:e.limit,semantic:S.input}).map(t=>Uu(t,e.query)),E;if(S.status){let t=w.reduce((e,t)=>e+(t.signals.vector===void 0?0:1),0),s=t>0;E={...S.status,applied:s},recordSemanticQuery({outcome:S.capable?s?`applied`:S.status.coverage.embedded===0?`warming`:`no_match`:`incapable`,source:e.source,capable:S.capable,embedded:S.status.coverage.embedded,total:S.pageTotal,queryEmbedMs:S.queryEmbedMs,vectorContributors:t})}return{query:e.query,intent:e.intent,results:w,elapsedMs:Math.max(0,performance.now()-t),ready:!0,...E?{semantic:E}:{},...g?{truncated:!0}:{}}}function Gu(){let e=nu(`project`);if(!existsSync(e))return[];let t;try{t=readdirSync(e,{withFileTypes:!0})}catch{return[]}let s=[];for(let g of t.sort((e,t)=>e.name.localeCompare(t.name))){if(!g.isDirectory()||!SKILL_NAME_REGEX.test(g.name))continue;let t=resolve(e,g.name,`SKILL.md`);try{let e=statSync(t);s.push({name:g.name,absolutePath:t,mtimeMs:e.mtimeMs,size:e.size})}catch{}}return s}function Ku(){let e=[];for(let t of Gu()){let s=t.name,g=``;try{let{frontmatter:e,body:S}=ql(readFileSync(t.absolutePath,`utf-8`));typeof e.name==`string`&&e.name&&(s=e.name),g=`${typeof e.description==`string`?e.description:``}\n\n${S}`.trim()}catch{}e.push(createWorkspaceSearchDocument({kind:`page`,path:skillLiveDocName(`project`,t.name),title:s,content:g,modifiedTs:t.mtimeMs}))}return e}function qu(e){return`${e.modified}\0${e.size}\0${e.canonicalPath}\0${e.inode}\0${e.aliases.join(`\0`)}`}let Ju=new Map;async function Yu(){let e=[],t=[],s=new Set;for(let[g,S]of E()){if(isSystemDoc(g)||isConfigDoc(g)||g.startsWith(`.ok/skills/`))continue;if(S.kind===`file`){t.push(createWorkspaceSearchDocument({kind:`file`,path:g,modifiedTs:Date.parse(S.modified),aliases:S.aliases}));continue}s.add(g);let w=qu(S),E=Ju.get(g);if(E&&E.key===w){e.push(E.doc);continue}let D=``,O=g,k=!1;try{D=await readFile$1(S.canonicalPath,`utf-8`)}catch(e){k=!0,console.warn(`[search] Failed to read ${g}:`,e)}if(!k)try{O=extractPageTitle(D,g)}catch(e){console.warn(`[search] Failed to extract title for ${g}:`,e)}let j=createWorkspaceSearchDocument({kind:`page`,path:g,title:O,content:D,modifiedTs:Date.parse(S.modified),aliases:S.aliases});k||Ju.set(g,{key:w,doc:j}),e.push(j)}for(let e of Ju.keys())s.has(e)||Ju.delete(e);let g=getSearchMaxEntries(),S=t,w=!1;return t.length>g&&(w=!0,S=[...t].sort((e,t)=>e.path.split(`/`).length-t.path.split(`/`).length||e.path.localeCompare(t.path)).slice(0,g),getLogger(`search`).warn({dropped:t.length-S.length,retained:S.length,limit:g},`[search] corpus name-only file tier truncated at OK_SEARCH_MAX_ENTRIES`),searchCorpusTruncatedCounter().add(1)),{documents:[...e,...Ku(),...S,...Iu([...e,...S])],truncated:w}}function Xu(){return Gu().map(e=>`${e.name} ${e.mtimeMs} ${e.size}`).join(``)}function Zu(){return O?`gen:${O()}|skills${Xu()}`:`${[...E()].filter(([e])=>!isSystemDoc(e)&&!isConfigDoc(e)).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}\0${qu(t)}`).join(``)}|skills${Xu()}`}let Qu=Me===void 0;Me?.then(()=>{Qu=!0},e=>{Qu=!0,log$6.warn({err:e,handler:`search`},`[api] ready gate rejected — search serves the partial index`)});function $u(){return!Qu}async function ed(){let e=`${g}${ye??``}`,t=Zu(),s=workspaceSearchCaches.get(e);if(s?.fingerprint===t&&s.corpus)return{corpus:s.corpus,truncated:s.truncated??!1};if(s?.fingerprint===t&&s.pending)return s.pending;let S=Yu().then(({documents:e,truncated:t})=>({corpus:createWorkspaceSearchCorpus(e),truncated:t}));workspaceSearchCaches.set(e,{fingerprint:t,pending:S});try{let s=await S;return workspaceSearchCaches.get(e)?.pending===S&&workspaceSearchCaches.set(e,{fingerprint:t,corpus:s.corpus,truncated:s.truncated}),s}catch(t){throw workspaceSearchCaches.get(e)?.pending===S&&workspaceSearchCaches.delete(e),t}}function td(){if(process.env.NODE_ENV!==`test`)for(let e of[0,1e3,3e3])setTimeout(()=>{ed().catch(e=>{console.warn(`[search] Failed to prewarm workspace search cache:`,e)})},e)}td();async function nd(e,t){if(e.method===`GET`)return rd(e,t);if(e.method===`POST`)return ad(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`search`,extraHeaders:{Allow:`GET, POST`}})}let rd=withValidation(EmptyRequestSchema,async(e,t)=>{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`limit`),S=s.searchParams.get(`query`)??``,w=Ru(s.searchParams.get(`intent`)),E=iu(s.searchParams.get(`ranking`)),D=zu(s.searchParams.get(`scope`)??s.searchParams.get(`scopes`)),O=Bu(s.searchParams.get(`semantic`)),k=Vu(s.searchParams.get(`source`)),j=g===null?void 0:Number(g);if(S.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-get`});return}try{successResponse(t,200,SearchSuccessSchema,await Wu({query:S,intent:w,ranking:E,scopes:D,limit:j,semanticParam:O,source:k}),{handler:`search-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to search workspace.`,{handler:`search-get`,cause:e})}},{handler:`search-get`,method:`GET`,skipBodyParse:!0}),ad=withValidation(SearchRequestSchema,async(e,t,s)=>{let g=typeof s.query==`string`?s.query:``,S=Ru(s.intent),w=iu(s.ranking),E=zu(s.scopes??s.scope),D=typeof s.limit==`number`?s.limit:void 0,O=Bu(s.semantic),k=Vu(s.source);if(g.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-post`});return}try{successResponse(t,200,SearchSuccessSchema,await Wu({query:g,intent:S,ranking:w,scopes:E,limit:D,semanticParam:O,source:k}),{handler:`search-post`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to search workspace.`,{handler:`search-post`,cause:e})}},{handler:`search-post`,method:`POST`}),od=withValidation(EmptyRequestSchema,async(e,t)=>{try{successResponse(t,200,SkillInstallStateSuccessSchema,{...await readSkillInstallStateSnapshot(homedir())},{handler:`skill-install-state`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read skill install state.`,{handler:`skill-install-state`,cause:e})}},{handler:`skill-install-state`,method:`GET`,skipBodyParse:!0,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`skill-install-state`})});async function sd(e,t){if(checkLocalOpSecurity(e,t,{handler:`handoff`}))try{await handleHandoffDispatch(e,t,{contentDir:g,platform:process.platform,isSchemeRegistered:Tt.probeWithCache})}catch(e){t.headersSent||(log$6.error({err:e},`[handoff] route wrapper failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`handoff`,cause:e}))}}async function cd(e,t){if(checkLocalOpSecurity(e,t,{handler:`spawn-cursor`}))try{await handleSpawnCursor(e,t,{contentDir:g,platform:process.platform})}catch(e){t.headersSent||(log$6.error({err:e},`[spawn-cursor] route wrapper failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`spawn-cursor`,cause:e}))}}let ld=withValidation(ShareConstructUrlRequestSchema,async(e,t,s)=>{try{if(!ye){emitShareConstructUrlLog(`no-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!isValidSharePath(s.kind===`doc`?s.docPath:s.folderPath,s.kind)){emitShareConstructUrlLog(`invalid-path`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`invalid-path`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let e=readGitHeadBranch(ye);if(e===null){if(readOriginGitHubRepo(ye).kind===`no-remote`){emitShareConstructUrlLog(`no-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}emitShareConstructUrlLog(`detached-head`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`detached-head`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let S=readOriginGitHubRepo(ye);if(S.kind===`no-remote`){emitShareConstructUrlLog(`no-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(S.kind===`non-github`){emitShareConstructUrlLog(`non-github-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`non-github-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!branchExistsOnOrigin(ye,e)){emitShareConstructUrlLog(`branch-not-on-origin`,{branchExists:!1,kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`branch-not-on-origin`,branch:e},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let w=toGitRelativePath(ye,g);if(w===null)throw Error(`content dir is not contained within the project dir`);let E=s.kind===`doc`?s.docPath!==``:s.folderPath!==``;w!==``&&E&&getLogger(`share`).warn({action:`construct-url`,kind:s.kind},`[share] content.dir != "." — non-root share URL omits the content.dir prefix; the github.com link may point at the wrong subtree. In-app receive navigation is content-relative and lands correctly.`);let D;if(s.kind===`doc`)D=buildGitHubBlobUrl(S.owner,S.repo,e,s.docPath);else{let t=s.folderPath===``?w:s.folderPath;D=buildGitHubTreeUrl(S.owner,S.repo,e,t)}let O=`${SHARE_BASE_URL}${encodeShareUrl(D)}`;emitShareConstructUrlLog(`ok`,{branchExists:!0,kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!0,shareUrl:O,sharedUrl:D,branch:e},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG,cause:e})}},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG})}),ud=withValidation(EmptyRequestSchema,async(e,t)=>{try{if(!ye){errorResponse(t,500,`urn:ok:error:internal-server-error`,`projectDir is not configured for this server.`,{handler:BRANCH_INFO_HANDLER_TAG});return}let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`branch`),S=s.searchParams.get(`path`),w=s.searchParams.get(`kind`)===`folder`?`folder`:`doc`;if(!isValidBranchName(g)){errorResponse(t,400,`urn:ok:error:invalid-request`,`branch query param missing or malformed.`,{handler:BRANCH_INFO_HANDLER_TAG});return}if(!isValidBranchInfoPath(S,w)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path query param missing or malformed.`,{handler:BRANCH_INFO_HANDLER_TAG});return}successResponse(t,200,BranchInfoResponseSchema,await computeBranchInfo(ye,g,S,w),{handler:BRANCH_INFO_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:BRANCH_INFO_HANDLER_TAG,cause:e})}},{handler:BRANCH_INFO_HANDLER_TAG,method:`GET`,skipBodyParse:!0}),dd=withValidation(CheckoutRequestSchema,async(e,t,s)=>{if(extractActorIdentity(s,Ce).kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:CHECKOUT_HANDLER_TAG});return}if(!ye){errorResponse(t,500,`urn:ok:error:internal-server-error`,`projectDir is not configured for this server.`,{handler:CHECKOUT_HANDLER_TAG});return}try{successResponse(t,200,CheckoutResponseSchema,await withParentLock(()=>runCheckoutFlow(ye,s.branch)),{handler:CHECKOUT_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:CHECKOUT_HANDLER_TAG,cause:e})}},{handler:CHECKOUT_HANDLER_TAG,method:`POST`});async function fd(e){let[t,...s]=ve,g=[...s,...e];return await new Promise((e,s)=>{let S=spawn(t,g,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),w=!1,E=setTimeout(()=>{w=!0,S.kill(`SIGTERM`)},SHARE_PUBLISH_TIMEOUT_MS),D=[],O=[];S.stdout.on(`data`,e=>D.push(e)),S.stderr.on(`data`,e=>O.push(e)),S.on(`close`,t=>{if(clearTimeout(E),w){s(Error(`share subprocess timed out after ${SHARE_PUBLISH_TIMEOUT_MS}ms`));return}let g=Buffer.concat(D).toString(`utf-8`);if(t!==0){let e=redactShareSubprocessStderr(Buffer.concat(O).toString(`utf-8`)).slice(0,500);console.warn(`[share] subprocess exited code=${t} stderr=${e}`)}e({stdout:g,code:t})}),S.on(`error`,e=>{clearTimeout(E),s(e)})})}let pd=withValidation(EmptyRequestSchema,async(e,t)=>{if(!We.tryAcquire(`/api/share/publish/owners`)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A share owners operation is already in progress.`,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG,extraHeaders:{"Retry-After":`5`}});return}try{let{stdout:e}=await fd([`share`,`owners`,`--json`]),s=parseOwnersEvent(pickTerminalJsonLine(e));emitSharePublishLog(`owners-list`,s.ok?`ok`:s.error,s.ok?{count:s.owners.length}:void 0),successResponse(t,200,SharePublishOwnersResponseSchema,s,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG,cause:e})}finally{We.release(SHARE_PUBLISH_OWNERS_KEY)}},{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG,method:`GET`,skipBodyParse:!0,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG})}),md=withValidation(EmptyRequestSchema,async(e,t)=>{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`owner`)??``,S=s.searchParams.get(`name`)??``;if(!isValidShareOwnerName(g)||!isValidShareRepoName(S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`owner and name query params must be valid GitHub identifiers.`,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG});return}if(!We.tryAcquire(`/api/share/publish/name-check`)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A share name-check operation is already in progress.`,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG,extraHeaders:{"Retry-After":`5`}});return}try{let{stdout:e}=await fd([`share`,`name-check`,`--owner`,g,`--name`,S,`--json`]),s=parseNameCheckEvent(pickTerminalJsonLine(e));emitSharePublishLog(`name-check`,s.ok?`ok`:s.error,s.ok?{available:s.available}:void 0),successResponse(t,200,SharePublishNameCheckResponseSchema,s,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG,cause:e})}finally{We.release(SHARE_PUBLISH_NAME_CHECK_KEY)}},{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG,method:`GET`,skipBodyParse:!0,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG})}),hd=withValidation(SharePublishRequestSchema,async(e,t,s)=>{if(!ye){emitSharePublishLog(`publish-create`,`no-project`),successResponse(t,200,SharePublishResponseSchema,{ok:!1,error:`no-project`},{handler:SHARE_PUBLISH_HANDLER_TAG});return}if(!isValidShareOwnerName(s.owner)||!isValidShareRepoName(s.name)){errorResponse(t,400,`urn:ok:error:invalid-request`,`owner and name must be valid GitHub identifiers.`,{handler:SHARE_PUBLISH_HANDLER_TAG});return}if(!We.tryAcquire(`/api/share/publish`)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A share publish operation is already in progress.`,{handler:SHARE_PUBLISH_HANDLER_TAG,extraHeaders:{"Retry-After":`5`}});return}try{let e=[`share`,`publish`,`--owner`,s.owner,`--name`,s.name,`--visibility`,s.visibility,`--project-dir`,ye,`--json`];s.description!==void 0&&s.description.length>0&&e.push(`--description`,s.description);let{stdout:g}=await fd(e),S=parsePublishEvent(pickTerminalJsonLine(g));emitSharePublishLog(`publish-create`,S.ok?`ok`:S.error),S.ok&&_e?.()?.refreshRemote().catch(()=>{}),successResponse(t,200,SharePublishResponseSchema,S,{handler:SHARE_PUBLISH_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_PUBLISH_HANDLER_TAG,cause:e})}finally{We.release(SHARE_PUBLISH_KEY)}},{handler:SHARE_PUBLISH_HANDLER_TAG,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_HANDLER_TAG})}),gd=withValidation(ClientLogsRequestSchema,async(e,t,s)=>{try{let e=getLogger(`renderer`);for(let t of s.entries)try{e[t.level]({...t.fields,source:`renderer-console`,transport:`web`,...t.sourceId?{sourceId:t.sourceId}:{},...t.lineNumber===void 0?{}:{lineNumber:t.lineNumber},...t.ts===void 0?{}:{clientTs:t.ts}},t.event??t.message)}catch{}successResponse(t,200,ClientLogsSuccessSchema,{accepted:s.entries.length},{handler:`client-logs`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`client-logs`,cause:e})}},{handler:`client-logs`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`client-logs`})}),_d=ye?getLocalDir(ye):null;async function vd(e,t){if(e.method===`DELETE`){let s=e.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`api-config`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`api-config`});return}_d&&clearArmedPaneTarget(_d),t.setHeader(`Cache-Control`,`no-store`),t.statusCode=204,t.end();return}if(e.method===`GET`||e.method===`HEAD`){try{let s=e.headers.host,g={collabUrl:s?`ws://${s}/collab`:null,previewUrl:null,port:_d?readServerLock(_d)?.port??0:0,paneTarget:_d?readArmedPaneTarget(_d):null,singleFile:Ue};if(e.method===`HEAD`){t.setHeader(`Content-Type`,`application/json`),t.setHeader(`Cache-Control`,`no-store`),t.setHeader(`X-Content-Type-Options`,`nosniff`),t.statusCode=200,t.end();return}successResponse(t,200,ApiConfigSuccessSchema,g,{handler:`api-config`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`api-config`,cause:e})}return}errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`api-config`,extraHeaders:{Allow:`GET, HEAD, DELETE`}})}let yd=`local-op-embeddings-set-key`,bd=`local-op-embeddings-clear-key`,xd=`/api/local-op/embeddings`,Sd=withValidation(LocalOpEmbeddingsSetKeyRequestSchema,async(e,t,s)=>{if(!We.tryAcquire(xd)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An embeddings key operation is already in progress.`,{handler:yd,extraHeaders:{"Retry-After":`5`}});return}try{await new FileEmbeddingsBackend(Ve).set(s.key),successResponse(t,200,LocalOpEmbeddingsMutationSuccessSchema,{keyPresent:!0},{handler:yd,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to store the key.`,{handler:yd,cause:e})}finally{We.release(xd)}},{handler:yd,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:yd})}),Cd=withValidation(EmptyRequestSchema,async(e,t)=>{if(!We.tryAcquire(xd)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An embeddings key operation is already in progress.`,{handler:bd,extraHeaders:{"Retry-After":`5`}});return}try{await clearEmbeddingsKeyFromAllBackends(Ve),successResponse(t,200,LocalOpEmbeddingsMutationSuccessSchema,{keyPresent:!1},{handler:bd,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to clear the key.`,{handler:bd,cause:e})}finally{We.release(xd)}},{handler:bd,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:bd})}),wd=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=!1,s=!1,g=!1,S=0;if(ze){let t=ze.getStatus();e=t.enabled,s=t.ready,g=t.capable,S=t.embeddedCount}let E=await new FileEmbeddingsBackend(Ve).get(),D=process.env.OK_EMBEDDINGS_API_KEY??null,O=E?`file`:D?`env`:null,k=O!==null,j=E??D,F=j&&j.length>=8?j.slice(-4):null,L=0;for(let[e]of w())!isSystemDoc(e)&&!isConfigDoc(e)&&!isHiddenDocName(e)&&(L+=1);successResponse(t,200,SemanticIndexStatusSchema,{enabled:e,keyPresent:k,keySource:O,keyHint:F,ready:s,capable:g,embedded:S,total:L},{handler:`semantic-status`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`semantic-status`,cause:e})}},{handler:`semantic-status`,method:`GET`,skipBodyParse:!0}),Td={"/api/config":vd,"/api/asset":wc,"/api/asset-text":Ec,"/api/document":Ps,"/api/documents":Is,"/api/backlinks":Rs,"/api/backlink-counts":$s,"/api/forward-links":ec,"/api/link-graph":tc,"/api/dead-links":ic,"/api/orphans":nc,"/api/hubs":rc,"/api/tags":Ml,"/api/pages":Ic,"/api/folder-config":Bl,"/api/template":Kl,"/api/templates":Gl,"/api/skill":uu,"/api/skill-file":Ou,"/api/skills":lu,"/api/skills/management":hu,"/api/skill/install":ku,"/api/skill/uninstall":Au,"/api/skill/restore":Pu,"/api/skill/update":Fu,"/api/skill-targets":ju,"/api/search":nd,"/api/semantic-status":wd,"/api/suggest-links":Lc,"/api/page-headings":Mc,"/api/create-page":kc,"/api/create-folder":Ac,"/api/duplicate-path":jc,"/api/rename-path":Nc,"/api/delete-path":Pc,"/api/trash/cleanup":Fc,"/api/upload":Rc,"/api/agent-write":Os,"/api/agent-write-md":ks,"/api/frontmatter-patch":As,"/api/agent-patch":ac,"/api/agent-undo":oc,"/api/agent-activity":sc,"/api/agent-burst-diff":cc,"/api/save-version":pc,"/api/history":mc,"/api/rollback":gc,"/api/metrics/reconciliation":_c,"/api/metrics/parse-health":vc,"/api/metrics/agent-presence":xc,"/api/__embed-detect":Sc,"/api/server-info":yc,"/api/share/construct-url":ld,"/api/git/branch-info":ud,"/api/git/checkout":dd,"/api/share/publish/owners":pd,"/api/share/publish/name-check":md,"/api/share/publish":hd,"/api/principal":bc,"/api/rescue":Oc,"/api/workspace":Cc,"/api/sync/status":vl,"/api/sync/trigger":yl,"/api/sync/conflicts":xl,"/api/sync/conflict-content":Tl,"/api/sync/resolve-conflict":Cl,"/api/local-op/clone":Wc,"/api/local-op/ok-init":Jc,"/api/local-op/auth/login":il,"/api/local-op/auth/status":ll,"/api/local-op/auth/repos":dl,"/api/local-op/auth/signout":ml,"/api/local-op/auth/set-identity":_l,"/api/local-op/embeddings/set-key":Sd,"/api/local-op/embeddings/clear-key":Cd,"/api/installed-agents":jl,"/api/spawn-cursor":cd,"/api/handoff":sd,"/api/install-skill":kl,"/api/skill/install-state":od,"/api/seed/plan":El,"/api/seed/apply":Dl,"/api/seed/packs":Ol,"/api/client-logs":gd};H&&(Td[`/api/test-reset`]=uc,Td[`/api/test-flush-git`]=lc,Td[`/api/test-rescan-backlinks`]=dc,Td[`/api/test-rescan-files`]=fc);let Ed=new Set(`/api/upload./api/create-page./api/create-folder./api/duplicate-path./api/rename-path./api/delete-path./api/trash/cleanup./api/agent-write./api/agent-write-md./api/frontmatter-patch./api/agent-patch./api/agent-undo./api/save-version./api/rollback./api/sync/trigger./api/sync/resolve-conflict./api/git/checkout./api/test-reset./api/test-flush-git./api/test-rescan-backlinks./api/test-rescan-files./api/install-skill./api/folder-config./api/template./api/skill./api/skill-file./api/skill/install./api/skill/uninstall./api/skill/restore./api/skill/update./api/skills/management./api/skill-targets./api/seed/apply./api/client-logs`.split(`.`)),Dd=[`/api/local-op/`];return{priority:100,async onRequest({request:e,response:t}){let s=e.url?.split(`?`)[0];if(!s)return;let g=t=>{let s=e.headers[t];if(s!==void 0)return Array.isArray(s)?s.join(`, `):s};if(recordEmbedProbe({ts:Date.now(),url:s,method:e.method??``,ua:g(`user-agent`),origin:g(`origin`),referer:g(`referer`),host:g(`host`),remote:e.socket?.remoteAddress,secChUa:g(`sec-ch-ua`),secChUaMobile:g(`sec-ch-ua-mobile`),secChUaPlatform:g(`sec-ch-ua-platform`),secFetchSite:g(`sec-fetch-site`),secFetchDest:g(`sec-fetch-dest`),secFetchMode:g(`sec-fetch-mode`),secFetchUser:g(`sec-fetch-user`)}),s.startsWith(`/api/`)){let s=e.headers.origin;if(s!==void 0&&!isAllowedApiOrigin(s)){errorResponse(t,403,`urn:ok:error:invalid-origin`,`Origin not allowed.`,{handler:`api-origin-gate`});return}if(typeof t.setHeader==`function`&&(s!==void 0&&(t.setHeader(`Access-Control-Allow-Origin`,s),t.setHeader(`Vary`,`Origin`)),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, traceparent, tracestate, baggage, ${CLIENT_VERSION_HEADER.protocol}, ${CLIENT_VERSION_HEADER.runtime}, ${CLIENT_VERSION_HEADER.kind}`)),e.method===`OPTIONS`){t.writeHead(204),t.end();return}}if(Ed.has(s)||Dd.some(e=>s.startsWith(e))){let s=e.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`api-mutating-gate`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`api-mutating-gate`});return}}if(Ue&&s.startsWith(`/api/`)){let s=e.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`api-ephemeral-gate`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`api-ephemeral-gate`});return}}if(!s.startsWith(`/api/`))return;let S=propagation.extract(context.active(),e.headers),w=e.method??`GET`,E=s;s.startsWith(`/api/history/`)?E=`/api/history/:sha`:s.startsWith(`/api/tags/`)?E=`/api/tags/:name`:Td[s]||(E=`/api/*`);let D=getTracer(),O=Date.now();await context.with(S,()=>D.startActiveSpan(`HTTP ${w} ${E}`,{kind:SpanKind.SERVER,attributes:{[ATTR_HTTP_REQUEST_METHOD]:w,[ATTR_HTTP_ROUTE]:E,[ATTR_URL_PATH]:s,[ATTR_URL_SCHEME]:`http`,[ATTR_USER_AGENT_ORIGINAL]:e.headers[`user-agent`]??``}},async g=>{try{let S=Td[s],E=!1;if(S)E=!0,await S(e,t);else if(s.startsWith(`/api/history/`)){let g=decodeURIComponent(s.slice(13));g&&(E=!0,await hc(e,t,g))}else if(s.startsWith(`/api/tags/`)){let g=s.slice(10);g&&(E=!0,await Pl(e,t,g))}E||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`api-dispatch`,detail:`No handler for ${w} ${s}`});let D=t.statusCode;g.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE,D),D>=500&&g.setStatus({code:SpanStatusCode.ERROR,message:`status ${D}`})}catch(e){throw g.recordException(e),g.setStatus({code:SpanStatusCode.ERROR,message:e instanceof Error?e.message:String(e)}),!t.headersSent&&!t.writableEnded&&!t.destroyed&&errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:E,cause:e}),e}finally{g.end();let e=(Date.now()-O)/1e3;httpDurationHist().record(e,{[ATTR_HTTP_REQUEST_METHOD]:w,[ATTR_HTTP_ROUTE]:E,[ATTR_HTTP_RESPONSE_STATUS_CODE]:t.statusCode})}}))}}}function errnoCode(e){let t=e?.code;return typeof t==`string`?t:void 0}function seedSingleDirBasenameIndex(e){let t;try{t=readdirSync(e.contentDir,{withFileTypes:!0})}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`read-failed`,s,e.contentDir);return}for(let s of t)s.isFile()&&isSupportedAssetFile(s.name,ASSET_EXTENSIONS)&&e.basenameIndex.add(s.name)}async function seedBasenameIndex(e){let t=e.contentDir,s=new Set;async function g(S){let w;try{w=await readdir(S,{withFileTypes:!0})}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`read-failed`,s,S);return}for(let E of w){let w=join(S,E.name),D=toPosix(relative(t,w));if(D.startsWith(`..`)||e.contentFilter?.isDirExcluded(D)&&E.isDirectory())continue;let O;try{O=await lstat(w)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`lstat-failed`,s,w);continue}if(O.isSymbolicLink()){let S;try{S=await realpath(w)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`realpath-failed`,s,w);continue}if(!isWithinDir(S,t)){e.onSkip?.(`symlink-escape`,void 0,w);continue}let E;try{E=await stat$1(S)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`symlink-stat-failed`,s,S);continue}if(s.has(E.ino))continue;s.add(E.ino),E.isDirectory()?await g(S):E.isFile()&&isSupportedAssetFile(w,LINKABLE_ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D);continue}if(O.isDirectory()){if(s.has(O.ino))continue;s.add(O.ino),await g(w);continue}O.isFile()&&isSupportedAssetFile(w,LINKABLE_ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D)}}await g(t)}var AutoStartDisabledError=class extends Error{constructor(e){super(e),this.name=`AutoStartDisabledError`}};const log$5=getLogger(`conflict-storage`);var ConflictStore=class{storePath;projectDir;branch;conflicts=[];constructor(e,t=`main`){this.storePath=join(getLocalDir(e),`conflicts.json`),this.projectDir=e,this.branch=t,this.load()}load(){if(!existsSync(this.storePath)){this.conflicts=[];return}try{let e=readFileSync(this.storePath,`utf-8`),t=JSON.parse(e);if(t.version!==1){log$5.warn({path:this.storePath},`[conflicts] unknown schema version — resetting`),this.conflicts=[];return}this.branch=t.branch??this.branch,this.conflicts=t.conflicts??[]}catch(e){log$5.warn({err:e},`[conflicts] failed to load conflicts.json — starting empty`),this.conflicts=[]}}save(){try{let e=dirname(this.storePath);existsSync(e)||mkdirSync(e,{recursive:!0});let t={version:1,branch:this.branch,conflicts:this.conflicts};writeFileSync(this.storePath,JSON.stringify(t,null,2),`utf-8`)}catch(e){log$5.warn({err:e},`[conflicts] failed to save conflicts.json`)}}addConflict(e){let t=this.conflicts.findIndex(t=>t.file===e.file);t===-1?this.conflicts.push(e):this.conflicts[t]=e,this.save()}removeConflict(e){this.conflicts=this.conflicts.filter(t=>t.file!==e),this.save()}clear(){this.conflicts=[],this.save()}count(){return this.conflicts.length}list(){return[...this.conflicts]}hasConflicts(){return this.conflicts.length>0}setBranch(e){this.branch=e}async resolveConflict(e,t,s,g=[]){if(!this.conflicts.find(t=>t.file===e))throw Error(`[conflicts] no conflict tracked for file: ${e}`);if(t===`content`&&s===void 0)throw Error(`[conflicts] strategy 'content' requires content parameter`);let{createGitInstance:S}=await import(`./git-handle-DdgvPBh6-Dv4DjLoy.mjs`),w=S(this.projectDir,{credentialArgs:g});switch(t){case`mine`:await w.git.raw([`checkout`,`--ours`,`--`,e]),await w.git.raw([`add`,`--`,e]);break;case`theirs`:await w.git.raw([`checkout`,`--theirs`,`--`,e]),await w.git.raw([`add`,`--`,e]);break;case`content`:{if(s===void 0)throw Error(`[conflicts] strategy 'content' requires content parameter`);let t=resolve(this.projectDir),g=resolve(t,e);if(!isWithinDir(g,t))throw Error(`[conflicts] file path escapes project directory: ${e}`);writeFileSync(g,s,`utf-8`),await w.git.raw([`add`,`--`,e]);break}case`delete`:await w.git.raw([`rm`,`--`,e]);break;default:throw Error(`[conflicts] unknown resolve strategy: ${t}`)}if(this.removeConflict(e),!this.hasConflicts())try{await w.git.raw([`commit`,`--no-edit`]),log$5.info({file:e},`[conflicts] all conflicts resolved — merge commit created`)}catch(t){let s=new Date().toISOString(),g=!1;try{let e=(await w.git.raw([`diff`,`--name-only`,`--diff-filter=U`])).split(`
|
|
1943
1943
|
`).map(e=>e.trim()).filter(Boolean);for(let t of e)this.addConflict({file:t,detectedAt:s});g=e.length>0}catch(e){log$5.warn({err:e},`[conflicts] commit failed and re-scan of unmerged files failed — falling back to single-file re-add`)}g||this.addConflict({file:e,detectedAt:s}),log$5.warn({err:t},`[conflicts] failed to commit merge after all conflicts resolved — unmerged files re-added`);let S=t instanceof Error?t.message:String(t);throw Error(`Merge commit failed after resolving ${e}; ${g?`unmerged files re-added`:`original file re-added`} — ${S}`,{cause:t})}}};const DEFAULT_WARN_BEFORE_MS=300*1e3;function attachIdleShutdown(e){let t=e.scheduler??defaultScheduler,s=e.warnBeforeMs??DEFAULT_WARN_BEFORE_MS,g=0,S=null,w=null,E=!1,D=!1;function O(){S!==null&&(t.clearTimeout(S),S=null),w!==null&&(t.clearTimeout(w),w=null)}function k(){O(),!(D||E)&&g===0&&(s>0&&s<e.thresholdMs&&(w=t.setTimeout(()=>{w=null,g===0&&!E&&e.log?.warn({msUntilShutdown:s,webSocketClientCount:0},`idle shutdown pending: no WebSocket clients`)},e.thresholdMs-s)),S=t.setTimeout(()=>{if(S=null,!(D||E)&&g===0){E=!0,e.log?.info({webSocketClientCount:0},`idle shutdown firing`);try{let t=e.onShutdown();t&&typeof t.then==`function`&&t.catch(t=>{e.log?.error({err:t},`idle shutdown handler rejected`)})}catch(t){e.log?.error({err:t},`idle shutdown handler threw`)}}},e.thresholdMs))}let j=(e,t)=>{e.url?.startsWith(`/collab`)&&(g++,O(),t.once(`close`,()=>{g--,g<0&&(g=0),g===0&&k()}))};return e.httpServer.on(`upgrade`,j),k(),{detach:()=>{D||(D=!0,e.httpServer.off(`upgrade`,j),O())}}}function isObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function readRawSinkBlock(e){if(!existsSync(e))return{};let t;try{t=(0,import_dist$1.parse)(readFileSync(e,`utf-8`))}catch(t){return console.warn(`[telemetry.localSink] failed to parse ${e}; falling back to schema defaults — any explicit telemetry.localSink fields in this file are being ignored. Reason: ${t instanceof Error?t.message:String(t)}`),{}}if(!isObject(t))return{};let s=t.telemetry;if(!isObject(s))return{};let g=s.localSink;return isObject(g)?g:{}}function readBoolean(e){return typeof e==`boolean`?e:void 0}function readPositiveNumber(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?e:void 0}function readStringArray(e){if(Array.isArray(e)&&e.every(e=>typeof e==`string`))return e}function readMaxBytes(e){if(isObject(e))return readPositiveNumber(e.maxBytes)}function resolveLocalSinkConfig(e){if(process.env.OK_DISABLE_LOCAL_SINK===`1`||process.env.OK_DISABLE_LOCAL_SINK===`true`)return null;let t=readRawSinkBlock(resolveConfigPath(`project`,e.projectDir)),s=readRawSinkBlock(resolveConfigPath(`project-local`,e.projectDir));if((readBoolean(s.enabled)??readBoolean(t.enabled)??!0)===!1)return null;let g=readMaxBytes(s.spans)??readMaxBytes(t.spans)??52428800,S=readMaxBytes(s.logs)??readMaxBytes(t.logs)??26214400,w=readStringArray(s.attributeDenylist)??readStringArray(t.attributeDenylist)??DEFAULT_TELEMETRY_ATTRIBUTE_DENYLIST;return{telemetry:{projectDir:e.projectDir,spansMaxBytes:g,attributeDenylist:w},logs:{projectDir:e.projectDir,maxBytes:S}}}const MCP_CONNECTION_ID_HEADER=`x-ok-connection-id`;function sanitizeClientName(e,t){let s=Array.from(e??``).map(e=>{let t=e.charCodeAt(0);return t<=31||t===127?` `:e}).join(``).replace(/\s+/g,` `).trim();return s?s.slice(0,128):t}function installPrettyZodErrors(e){let t=e;if(t.__prettyZodErrorsInstalled===!0)return;let s=t.validateToolInput;if(typeof s!=`function`){console.warn(`[pretty-zod-errors] McpServer.validateToolInput not found — SDK internals may have changed. Falling back to default error formatting.`);return}t.validateToolInput=async function(e,t,g){if(!e.inputSchema||!isZodSchema(e.inputSchema))return s.call(this,e,t,g);let S=await e.inputSchema.safeParseAsync(t);if(S.success)return S.data;let w=prettifyError(S.error);throw new McpError(ErrorCode.InvalidParams,`Input validation error: Invalid arguments for tool ${g}:\n${w}`)},t.__prettyZodErrorsInstalled=!0}function isZodSchema(e){return typeof e!=`object`||!e?!1:typeof e.safeParseAsync==`function`}const SPAWN_TIMEOUT_MS=2e3,LOCK_SCAN_MAX_DEPTH=3,LOCK_SCAN_MAX_ENTRIES=2e3,OK_LOCK_DIR_ARG_PREFIX=`--ok-lock-dir-b64=`,OK_PROJECT_PATH_ARG_PREFIX=`--ok-project-path=`,OK_PROCESS_PGREP_QUERY=`cli\\.mjs|open-knowledge|Open ?Knowledge(\\.app| Helper)|--ok-lock-dir-b64=|--ok-project-path=|(^|[ /])ok[ ]+(start|mcp|ui)([ ]|$)|packages/(cli|app)|hocuspocus|vite`,OK_PROCESS_PATTERNS=[/cli\.mjs/,/(^|[\s/])(open-knowledge|ok)\s+(start|mcp|ui)(\s|$)/,/Open ?Knowledge(?:\.app| Helper)/,/(^|[\s/])bun([\s/]).*?(run dev|packages\/app|vite|hocuspocus)/,/(^|[\s/])node([\s/]).*?(packages\/(cli|app)|vite|hocuspocus)/,/(^|\s)--ok-lock-dir-b64=/,/(^|\s)--ok-project-path=/];function isOkProcess(e){return OK_PROCESS_PATTERNS.some(t=>t.test(e))}function extractMarkedLockDir(e){let t=e.trim().split(/\s+/).find(e=>e.startsWith(OK_LOCK_DIR_ARG_PREFIX));if(t==null)return null;let s=t.slice(18);if(!s)return null;try{let e=Buffer.from(s,`base64url`).toString(`utf8`);return isAbsolute(e)?e:null}catch{return null}}function extractProjectPathArg(e){let t=e.indexOf(OK_PROJECT_PATH_ARG_PREFIX);if(t===-1)return null;let s=t+18,g=e.slice(s),S=g.search(/\s--/),w=(S===-1?g:g.slice(0,S)).trim();return w&&isAbsolute(w)?w:null}function parsePgrepOutput(e){let t=[];for(let s of e.split(`
|
|
1944
1944
|
`)){let e=s.trim();if(!e)continue;let g=e.indexOf(` `);if(g===-1)continue;let S=e.slice(0,g),w=e.slice(g+1),E=Number.parseInt(S,10);!Number.isNaN(E)&&isOkProcess(w)&&t.push({pid:E,command:w})}return t}function parsePsOutput(e){let t=[],s=e.split(`
|
|
1945
1945
|
`);for(let e=1;e<s.length;e++){let g=s[e]?.trim();if(!g)continue;let S=g.indexOf(` `);if(S===-1)continue;let w=g.slice(0,S),E=g.slice(S+1).trim(),D=Number.parseInt(w,10);!Number.isNaN(D)&&isOkProcess(E)&&t.push({pid:D,command:E})}return t}async function findOkProcessEntries(){let e=spawnSync(`pgrep`,[`-a`,`-f`,OK_PROCESS_PGREP_QUERY],{encoding:`utf-8`,timeout:SPAWN_TIMEOUT_MS});if(!(e.error!=null&&e.error.code===`ENOENT`)){let t=e.stdout??``,s=parsePgrepOutput(t);if(s.length>0||t.trim()===``)return s}let t=spawnSync(`ps`,[`-axo`,`pid,command`],{encoding:`utf-8`,timeout:SPAWN_TIMEOUT_MS});return t.error!=null||!t.stdout?[]:parsePsOutput(t.stdout)}function extractOkBinaryPath(e){let t=e.trim().split(/\s+/).filter(Boolean);for(let e of t){if(e.startsWith(`@`))continue;let t=basename(e);if(t===`open-knowledge`||t===`ok`||e.endsWith(`/packages/cli/src/cli.ts`)||e.endsWith(`/packages/cli/dist/cli.mjs`)||t===`cli.mjs`||t===`cli.ts`)return e}return null}function processCommand(e){let t=spawnSync(`ps`,[`-p`,String(e),`-o`,`command=`],{encoding:`utf-8`,timeout:SPAWN_TIMEOUT_MS});return t.error!=null||!t.stdout?null:t.stdout.trim()||null}function processUsage(e){let t=spawnSync(`ps`,[`-p`,String(e),`-o`,`%cpu=,%mem=`],{encoding:`utf-8`,timeout:SPAWN_TIMEOUT_MS});if(t.error!=null||!t.stdout)return null;let[s,g]=t.stdout.trim().split(/\s+/),S=Number.parseFloat(s??``),w=Number.parseFloat(g??``);return Number.isNaN(S)||Number.isNaN(w)?null:{cpuPercent:S,memPercent:w}}async function pidCwd(e){let t=spawnSync(`lsof`,[`-p`,String(e),`-a`,`-d`,`cwd`,`-Fn`],{encoding:`utf-8`,timeout:SPAWN_TIMEOUT_MS});if(t.error!=null)return null;let s=t.stdout??``;for(let e of s.split(`
|
|
@@ -3251,4 +3251,4 @@ Incremental by default — don't re-read the whole repo.
|
|
|
3251
3251
|
`))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`)}setBatchInProgress(!1),await ye.flushDeferredStores(`discard-stale`),Te?.emitBranchSwitched(g)}if(e.headMoved&&e.newHead&&_e.current&&s>0){let t=L??`.`;try{let s=await commitUpstreamImport(_e.current,t,e.oldHead,e.newHead,g);incrementUpstreamImport(),Y.info({oldHead:e.oldHead?.slice(0,8)??`null`,newHead:e.newHead.slice(0,8),sha:s.slice(0,8)},`[history] upstream-import from ${e.oldHead?.slice(0,8)??`null`}..${e.newHead.slice(0,8)} → ${s.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`),Fr.push(`head-watcher`)}function D(e){for(let g of e)try{let e=toPosix(relative(t,join(s,g)));if(e.startsWith(`..`))continue;let S=stripDocExtension(e),w=Ce.documents.get(S);if(!w)continue;let E=jt(S);E===null?Y.warn({docName:S,file:g},`[sync] content conflict: serializeDoc returned null; reconciledBase snapshot skipped`):setReconciledBase(S,E);let D=w.getMap(`lifecycle`);D.set(`status`,`conflict`),D.set(`reason`,`sync-merge-conflict`),Y.info({docName:S,file:g},`[sync] marked loaded content conflict`)}catch(e){Y.warn({err:e,file:g},`[sync] failed to mark loaded content conflict`)}}let O=buildSyncCredentialArgs(H);try{$t=new SyncEngine({projectDir:s,contentDir:t,contentFilter:fe,contentRoot:L,syncEnabled:te(),credentialArgs:O,cc1Broadcaster:Te,detectGh:e.detectGh,tokenStore:e.tokenStore,checkPushPermissionFn:e.checkPushPermissionFn,setBatchInProgress:e=>{setBatchInProgress(e),e||ye.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:D,onAutoDisable:async e=>{Y.warn({reason:e},`[sync] auto-disabled — persisting to project-local config`);let t=await writeConfigPatch({cwd:s,scope:`project-local`,patch:{autoSync:{enabled:!1}}});t.ok||Y.error({result:t,reason:e,humanError:humanFormat(t.error),configPath:resolveConfigPath(`project-local`,s)},`[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 $t.start()}catch(e){Y.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),$t=null}Ke(`files`),Ke(`backlinks`),Ke(`graph`),Ke(`tags`)}return Ir().then(Ue,We),{hocuspocus:Ce,sessionManager:we,cc1Broadcaster:Te,agentFocusBroadcaster:De,agentPresenceBroadcaster:je,maintenanceCoordinator:ve,contentFilter:fe,basenameIndex:ce,serverInstanceId:oe,destroy:Mr,ready:Ge,degraded:Fr,lockDir:se,get syncEngine(){return $t}}}const SERVER_MEMORY_SCHEMA_VERSION=1,BYTES_PER_MB=1024*1024;function toMb(e){return e/BYTES_PER_MB}function captureServerMemorySnapshot(){let e=process.memoryUsage();return{schemaVersion:SERVER_MEMORY_SCHEMA_VERSION,capturedAt:new Date().toISOString(),snapshot:{rssMb:toMb(e.rss),heapTotalMb:toMb(e.heapTotal),heapUsedMb:toMb(e.heapUsed),externalMb:toMb(e.external),arrayBuffersMb:toMb(e.arrayBuffers)}}}let cachedGauge=null;onTelemetryShutdown(()=>{cachedGauge=null});function installServerMemoryGauge(){if(cachedGauge)return;let e=getMeter().createObservableGauge(`ok.server.memory.usage_megabytes`,{description:`Server process memory by section. Bounded labels: section ∈ {heap_used, heap_total, rss}.`,unit:`MB`});e.addCallback(e=>{let{snapshot:t}=captureServerMemorySnapshot();e.observe(t.heapUsedMb,{section:`heap_used`}),e.observe(t.heapTotalMb,{section:`heap_total`}),e.observe(t.rssMb,{section:`rss`})}),cachedGauge=e}const TELEMETRY_FILENAME=`tolerance-telemetry.jsonl`,TELEMETRY_PREV_FILENAME=`tolerance-telemetry.prev.jsonl`,TELEMETRY_MAX_BYTES=8*1024*1024;let appender=null,appendFailureWarned=!1;function isToleranceTelemetryEnabled(e=process.env){return e.OK_BRIDGE_TOLERANCE_TELEMETRY===`1`}function initToleranceTelemetryWriter(e){if(!isToleranceTelemetryEnabled())return;let t=getLocalDir(e);appender=new RotatingAppender({currentPath:resolve(t,TELEMETRY_FILENAME),previousPath:resolve(t,TELEMETRY_PREV_FILENAME),maxBytes:TELEMETRY_MAX_BYTES}),setToleranceTelemetryHook(e=>{let t={event:`bridge-tolerance-fire`,timestamp:e.timestamp,class:e.className,document:e.documentName??null,codeUnitPosition:e.codeUnitPosition,severity:e.severity};appender?.append(`${JSON.stringify(t)}\n`).catch(e=>{appendFailureWarned||(appendFailureWarned=!0,console.warn(`[tolerance-telemetry] append failed; further failures are silent:`,e instanceof Error?e.message:String(e)))})})}async function teardownToleranceTelemetryWriter(){setToleranceTelemetryHook(null),await appender?.drain(),appender=null,appendFailureWarned=!1}const LEGACY_RUNTIME_FILENAMES=[`server.lock`,`ui.lock`,`state.json`,`principal.json`,`sync-state.json`,`conflicts.json`,`last-spawn-error.log`],LEGACY_RUNTIME_DIRNAMES=[`cache`,`tmp`];function findLegacyRuntimeFiles(e){let t=resolve(e,LOCAL_DIR);if(!(()=>{if(!existsSync(t))return!0;try{return readdirSync(t).length===0}catch{return!0}})())return[];let s=[];for(let t of LEGACY_RUNTIME_FILENAMES)existsSync(resolve(e,t))&&s.push(t);for(let t of LEGACY_RUNTIME_DIRNAMES){let g=resolve(e,t);try{existsSync(g)&&statSync(g).isDirectory()&&s.push(`${t}/`)}catch{}}return s}function computeWorktreeAttributes(e){let t=resolveGitDirDetailed(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 DEFAULT_IDLE_THRESHOLD_MS=1800*1e3,DESTROY_STEP_TIMEOUT_MS=5e3,PINO_REDACT_MAX_DEPTH=5;async function bootServer(e){let t=e.projectDir??e.contentDir,s=resolveLocalSinkConfig({projectDir:t});if(s){let e=s.telemetry.attributeDenylist,t=[];for(let s of e){t.push(s);for(let e=1;e<=PINO_REDACT_MAX_DEPTH;e++)t.push(`${`*.`.repeat(e)}${s}`)}loggerFactory.configure({pinoConfig:{fileSink:s.logs,redactPaths:t}})}initTelemetry({localSink:s?.telemetry}),initToleranceTelemetryWriter(t),installServerMemoryGauge();let{kind:g,gitdir:S}=computeWorktreeAttributes(e.projectDir??e.contentDir),w={"ok.worktree.kind":g};return S!==null&&(w[`ok.worktree.gitdir`]=normalizeFsPath(S)),withSpan(`ok.boot`,{attributes:w},async()=>bootServerInner(e))}async function bootServerInner(e){let t=e.skipAutoInit??!1,s=e.attachUiSibling??!0,g=e.idleShutdownMs,S=e.log??getLogger(`boot`),w=process.env.OK_LOCK_KIND===`mcp-spawned`||process.env.OK_LOCK_KIND===`interactive`?process.env.OK_LOCK_KIND:void 0,E=e.lockKind??w??`interactive`,{createServer:D}=await import(`node:http`),{updateServerLockPort:O}=await import(`./server-lock-8Lv6A-Xa-C35kJqNB.mjs`),k=!1;if(!t&&e.autoInitFn)try{k=!!await e.autoInitFn()}catch(e){S.warn({err:e},`autoInitFn failed`)}let j=e.projectDir??e.contentDir,F=resolve(j,`.ok`);if(!existsSync(resolve(F,`config.yml`)))throw new MissingOkConfigError(existsSync(F)?`config`:`okdir`,j);existsSync(resolve(F,`.gitignore`))||console.warn("[boot] 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 L=e.gitPreflight??assertGitAvailable;try{e.gitEnabled!==!1&&L()}catch(e){if(e instanceof GitNotAvailableError||e instanceof GitTooOldError){let t=e instanceof GitTooOldError?e.detected:``,s=e instanceof GitTooOldError?`too_old`:`not_available`;emitPreflightFailureSpan(e),S.warn({event:`git_preflight_fail`,platform:e.platform,reason:s,detectedVersion:t},s===`not_available`?`git binary not found`:`git binary too old`),process.stderr.write(`${e.message}\n`)}throw await shutdownTelemetry(),await Promise.race([teardownToleranceTelemetryWriter(),new Promise(e=>setTimeout(e,DESTROY_STEP_TIMEOUT_MS))]),e}let B=findLegacyRuntimeFiles(F);B.length>0&&console.warn(`[boot] Found legacy runtime files at .ok/${B.join(`, `)}. Delete .ok/ and re-init — these files moved to .ok/${LOCAL_DIR}/.`);let H=createServer$1({contentDir:e.contentDir,projectDir:e.projectDir,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,onAgentWrite:e.onAgentWrite,lockKind:E,skipStateManifestCheck:e.skipStateManifestCheck,detectGh:e.detectGh,tokenStore:e.tokenStore,embeddingsKeyStore:e.embeddingsKeyStore,singleDocRelPath:e.singleDocRelPath,ephemeral:e.ephemeral}),{hocuspocus:q,destroy:ee,ready:J,degraded:Y,lockDir:te,sessionManager:ne,agentFocusBroadcaster:ae,agentPresenceBroadcaster:oe,maintenanceCoordinator:se}=H,ce=(()=>{let t=e.host??`localhost`;return t===`0.0.0.0`||t===`::`?`localhost`:t.includes(`:`)&&!t.startsWith(`[`)?`[${t}]`:t})(),ue=e.port??0,de=e.ephemeral?void 0:createMcpHttpHandler({contentDir:e.contentDir,projectDir:e.projectDir??e.contentDir,config:e.config,getServerUrl:()=>`http://${ce}:${ue}`,log:S}),fe=D();fe.headersTimeout=3e4,fe.requestTimeout=6e4;let me=e.serveContentAssets?createAssetServeMiddleware({contentFilter:H.contentFilter,contentSirv:build_default(e.contentDir,{dev:!0,dotfiles:!1}),inlineExtensions:INLINE_RENDERABLE_EXTENSIONS,assetExtensions:ASSET_EXTENSIONS,blocklistExtensions:EXECUTABLE_BLOCKLIST_EXTENSIONS}):void 0,ge=!1;if(e.reactShellDistDir)try{acquireUiLock(te,{port:0,worktreeRoot:e.projectDir??e.contentDir}),ge=!0}catch(e){if(e instanceof UiLockCollisionError)S.info({event:`ui-lock-yielded-to-live-holder`,pid:process.pid,existingPid:e.existing.pid,existingPort:e.existing.port,lockDir:te},`ui.lock already held by a live process — yielding (advertisement is fulfilled)`);else throw await ee().catch(()=>{}),e}let _e=e.reactShellDistDir?build_default(e.reactShellDistDir,{single:!0,gzip:!0,immutable:!0}):void 0,ve=mountMcpAndApi({httpServer:fe,hocuspocus:q,mcpHttpHandler:de,log:S,sessionManager:ne,agentFocusBroadcaster:ae,agentPresenceBroadcaster:oe,maintenanceCoordinator:se,keepaliveGraceMs:e.keepaliveGraceMs,contentAssetMiddleware:me,reactShellMiddleware:_e,ephemeral:e.ephemeral}),ye=async()=>{throw Error(`bootServer: destroy() invoked before initialization — boot did not complete`)},Ce=null;g!==null&&(Ce=attachIdleShutdown({httpServer:fe,thresholdMs:g??DEFAULT_IDLE_THRESHOLD_MS,log:S,onShutdown:(e.idleShutdownHandler??(e=>async()=>{await e()}))(async()=>{await ye()})})),await restoreLifecycleFromConflictsJson({hocuspocus:q,projectDir:e.projectDir??e.contentDir,log:S});try{await new Promise((t,s)=>{let g=e=>s(e);fe.once(`error`,g),fe.listen(e.port,e.host,()=>{fe.removeListener(`error`,g),t()})})}catch(e){if(ge)try{releaseUiLock(te)}catch(e){S.warn({err:e},`releaseUiLock failed during listen-error cleanup`)}throw await ee().catch(()=>{}),e}let we=fe.address(),Te=typeof we==`object`&&we?we.port:e.port??0;if(ue=Te,O(te,Te),ge&&updateUiLockPort(te,Te),s&&e.spawnUiSiblingFn)try{await e.spawnUiSiblingFn({lockDir:te,log:S})}catch(e){S.warn({err:e},`spawnUiSiblingFn failed`)}let De=!1,je=async(e,t)=>{let s;try{await Promise.race([t(),new Promise((t,g)=>{s=setTimeout(()=>{g(Error(`${e} timed out after ${DESTROY_STEP_TIMEOUT_MS}ms`))},DESTROY_STEP_TIMEOUT_MS),s.unref?.()})])}finally{s!==void 0&&clearTimeout(s)}};ye=async()=>{if(De)return;De=!0;let e=[],t=async(t,s)=>{try{await je(t,s)}catch(s){e.push(s),S.warn({err:s,step:t},`bootServer destroy step failed`)}};try{Ce?.detach()}catch(t){e.push(t),S.warn({err:t,step:`idleHandle.detach`},`bootServer destroy step failed`)}if(await t(`mount.shutdown`,()=>ve.shutdown()),de!==void 0&&await t(`mcpHttpHandler.close`,()=>de.close()),await t(`mount.wss.close`,()=>new Promise((e,t)=>{ve.wss.close(s=>s?t(s):e())})),await t(`httpServer.closeAllConnections`,async()=>{fe.closeAllConnections?.()}),await t(`httpServer.close`,()=>new Promise((e,t)=>{fe.close(s=>s&&s.code!==`ERR_SERVER_NOT_RUNNING`?t(s):e())})),await t(`destroyHocuspocus`,()=>ee()),ge&&await t(`releaseUiLock`,async()=>releaseUiLock(te)),await t(`shutdownTelemetry`,()=>shutdownTelemetry()),await t(`teardownToleranceTelemetry`,()=>teardownToleranceTelemetryWriter()),await t(`flushLogFileSinks`,()=>loggerFactory.flushAllFileSinks()),e.length>0)throw AggregateError(e,`bootServer destroy completed with errors`)};try{let t=await reconcileSkillInstalls({projectDir:j,skillsRoot:resolve(e.contentDir,`.ok`,`skills`)}),s=t.healed.length+t.adopted.length+t.replaced.length+t.collided.length+t.orphansRemoved.length;s>0&&S.info?.({event:`installed-skills-reconciled`,healed:t.healed.length,adopted:t.adopted.length,replaced:t.replaced.length,collided:t.collided.length,orphansRemoved:t.orphansRemoved.length},`Reconciled ${s} editor skill entr${s===1?`y`:`ies`} to the symlink model.`)}catch(e){S.warn?.({event:`installed-skills-reconcile-failed`,error:String(e)},`Installed-skills reconcile failed (non-fatal).`)}return{httpServer:fe,destroy:ye,lockDir:te,contentDir:e.contentDir,port:Te,ready:J,degraded:Y,didAutoInit:k,serverInstance:H}}async function restoreLifecycleFromConflictsJson(e){let{hocuspocus:t,projectDir:s,log:g}=e,S,w;try{S=new ConflictStore(s),w=S.list()}catch(e){g.warn({err:e,projectDir:s},`[boot] lifecycle restore: failed to read conflicts.json — skipping`);return}if(w.length===0)return;let E=null;try{let e=resolveGitDir(s),t=e?join(e,`MERGE_HEAD`):null;if(!t||!existsSync(t)){S.clear(),console.warn(JSON.stringify({event:`lifecycle-restore-cleared-stale-conflicts`,reason:`no-merge-head`,count:w.length}));return}let g=(await simpleGit({baseDir:s,timeout:{block:5e3}}).raw([`diff`,`--name-only`,`--diff-filter=U`])).trim();E=new Set(g?g.split(`
|
|
3252
3252
|
`).map(e=>e.trim()).filter(Boolean):[])}catch(e){g.warn({err:e,projectDir:s},`[boot] lifecycle restore: git unmerged probe failed — restoring all entries`)}if(E!==null){let e=0;for(let t of w)E.has(t.file)||(S.removeConflict(t.file),e++);if(e>0&&console.warn(JSON.stringify({event:`lifecycle-restore-pruned-resolved-entries`,pruned:e,remaining:w.length-e})),w=w.filter(e=>E?.has(e.file)),w.length===0)return}for(let e of w){let s=stripDocExtension(e.file),S=null,w=!1;try{S=await t.openDirectConnection(s);let e=S.document;if(!e)continue;let g=e.getMap(`lifecycle`);g.set(`status`,`conflict`),g.set(`reason`,`conflict-markers`),w=!0,console.warn(JSON.stringify({event:`lifecycle-restored-from-conflicts-json`,"doc.name":s}))}catch(e){g.warn({err:e,docName:s},`[boot] lifecycle restore: failed to set lifecycle for doc — skipping`)}finally{if(S)try{await S.disconnect()}catch(e){g.warn({err:e,docName:s,restored:w},`[boot] lifecycle restore: disconnect failed after lifecycle write`)}}}}const ConfigSchema=ConfigSchema$1;function detectClaudeDesktopPresence(e={}){let t=e.home??homedir(),s=e.platformName??process.platform,g=e.env??process.env;return s===`darwin`?existsSync(join(t,`Library`,`Application Support`,`Claude`)):s===`win32`?existsSync(join(g.APPDATA??join(t,`AppData`,`Roaming`),`Claude`)):!1}const OK_LOGS_DIR=join(homedir(),`.ok`,`logs`),MAX_ROTATED_FILES=2,MAX_AGE_DAYS=7,MAX_DIR_SIZE_BYTES=45*1024*1024,REDACT_PATHS=[`authorization`,`password`,`token`,`apiKey`,`secret`,`*.authorization`,`*.password`,`*.token`,`*.apiKey`,`*.secret`];function resolveLogLevel(){let e=process.env.OK_LOG_LEVEL??process.env.LOG_LEVEL;if(e){let t=[`fatal`,`error`,`warn`,`info`,`debug`],s=e.toLowerCase();if(t.includes(s))return s}return process.env.NODE_ENV===`test`?`silent`:`info`}function ensureDir(e){mkdirSync(e,{recursive:!0})}function todayDateString(){return new Date().toISOString().slice(0,10)}function rotateIfNeeded(e){try{if(statSync(e).size<5242880)return}catch{return}for(let t=MAX_ROTATED_FILES;t>=1;t--){let s=t===1?e:`${e}.${t-1}`,g=`${e}.${t}`;try{renameSync(s,g)}catch{}}try{unlinkSync(`${e}.${MAX_ROTATED_FILES+1}`)}catch{}}function pruneLogsDir(e){try{let t=Date.now(),s=MAX_AGE_DAYS*24*60*60*1e3,g=readdirSync(e).filter(e=>e.endsWith(`.log`)||/\.log\.\d+$/.test(e)).map(t=>{try{let s=statSync(join(e,t));return{name:t,mtime:s.mtimeMs,size:s.size}}catch{return null}}).filter(Boolean);for(let S of g)if(t-S.mtime>s)try{unlinkSync(join(e,S.name))}catch{}let S=g.filter(e=>t-e.mtime<=s).sort((e,t)=>e.mtime-t.mtime),w=S.reduce((e,t)=>e+t.size,0);for(let t of S){if(w<=MAX_DIR_SIZE_BYTES)break;try{unlinkSync(join(e,t.name)),w-=t.size}catch{}}}catch{}}function createFileLogger(e){ensureDir(OK_LOGS_DIR);let t=todayDateString(),s=e.filePath??join(OK_LOGS_DIR,`${e.name}.${t}.log`);rotateIfNeeded(s),(e._setTimeout??setTimeout)(()=>pruneLogsDir(OK_LOGS_DIR),5e3).unref();let g=import_pino.default.destination({dest:s,append:!0,sync:!0});return(0,import_pino.default)({level:resolveLogLevel(),name:e.name,redact:{paths:REDACT_PATHS,censor:`[REDACTED]`},base:{pid:process.pid,hostname:void 0,runtime:`cli`,project:e.project??`<no-project>`},timestamp:import_pino.default.stdTimeFunctions.isoTime,...e.additionalOptions},g)}function flushFileLogger(e,t=250){return new Promise(s=>{if(!e){s();return}let g=e[import_pino.default.symbols.streamSym],S=!1,w=()=>{S||(S=!0,s())};if(!g||typeof g.flushSync!=`function`){w();return}let E=()=>{try{g.flushSync?.()}catch{}w()},D=setTimeout(w,t);typeof D.unref==`function`&&D.unref(),typeof g.fd==`number`&&g.fd>=0?(clearTimeout(D),E()):typeof g.once==`function`?g.once(`ready`,()=>{clearTimeout(D),E()}):(clearTimeout(D),E())})}function getLogFilePath(e){return join(OK_LOGS_DIR,`${e}.${todayDateString()}.log`)}function getLogsDir(){return OK_LOGS_DIR}const ANCESTOR_WALK_DEPTH_LIMIT=30,GIT_MARKER=`.git`;function findEnclosingGitRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT;){let e=!1;try{e=existsSync(resolve(t,GIT_MARKER))}catch{e=!1}if(e)return{gitRoot:t,distance:s};let g=dirname(t);if(g===t)return null;t=g,s+=1}return null}const execFileAsync=promisify(execFile),log=getLogger(`project-git`);var ProjectGitInitError=class extends Error{stderr;constructor(e,t=``,s){super(e,s),this.name=`ProjectGitInitError`,this.stderr=t}};async function isInsideExistingWorkTree(e,t){try{let{stdout:s}=await execFileAsync(e,[`rev-parse`,`--is-inside-work-tree`],{cwd:t});return s.trim()===`true`}catch{return!1}}async function ensureProjectGit(e){let t=resolve(e),s=resolve(t,`.git`),g=resolve(s,`HEAD`),S=!1;if(existsSync(s)){if(!statSync(s).isDirectory()||existsSync(g))return{didInit:!1};log.info({},`detected partial .git/ — running git init to repair`),S=!0}let w;try{w=assertGitAvailable()}catch(e){throw e instanceof GitNotAvailableError||e instanceof GitTooOldError?(emitPreflightFailureSpan(e),log.warn({event:`git_preflight_fail`,platform:e.platform,reason:e instanceof GitTooOldError?`too_old`:`not_available`,detectedVersion:e instanceof GitTooOldError?e.detected:``},e instanceof GitTooOldError?`git binary too old`:`git binary not found`)):log.warn({event:`git_preflight_unexpected_error`,message:e instanceof Error?e.message:String(e)},`unexpected error during git preflight`),e}let E=w.resolvedPath;if(!S&&await isInsideExistingWorkTree(E,t))return{didInit:!1};let D=``;try{D=(await execFileAsync(E,[`init`,`--initial-branch=main`,t])).stderr??``}catch(e){let s=typeof e==`object`&&e&&`stderr`in e?String(e.stderr??``):``;throw new ProjectGitInitError(`git init failed at ${t}: ${e instanceof Error?e.message:String(e)}`,s,{cause:e})}if(!existsSync(g))throw new ProjectGitInitError(`git init reported success but ${s}/HEAD is missing (partial init detected)`,D);return S?(log.info({path:t},`backfilled missing .git/HEAD`),{didInit:!0,repaired:!0}):(log.info({path:t,branch:`main`},`initialized .git/`),{didInit:!0})}async function resolvePackageVersion(e,t){let s;try{s=createRequire(t).resolve(e)}catch(e){if(e?.code===`MODULE_NOT_FOUND`)return;throw e}for(let t=dirname(s),g=0;g<32;g+=1){let s=join(t,`package.json`);if(existsSync(s))try{let t=JSON.parse(await readFile$1(s,`utf-8`));if(t.name===e&&typeof t.version==`string`)return t.version}catch{}let g=dirname(t);if(g===t)return;t=g}}const MAX_CAUSE_DEPTH=5,HOME_PATH_PATTERNS=[{regex:/\/Users\/[^/]+\//g,replacement:`~/`},{regex:/\/home\/[^/]+\//g,replacement:`~/`},{regex:/C:\\\\Users\\\\[^\\\\]+\\\\/g,replacement:`~\\`},{regex:/C:\\Users\\[^\\]+\\/g,replacement:`~\\`}];function scrubPaths(e){if(e===void 0)return;let t=e;for(let{regex:e,replacement:s}of HOME_PATH_PATTERNS)t=t.replace(e,s);return t}function serializeError(e,t=0,s=new WeakSet){if(t>=MAX_CAUSE_DEPTH)return{name:`SerializedError.CauseDepthExceeded`,message:`cause chain depth > ${MAX_CAUSE_DEPTH}; truncated`};if(typeof e==`object`&&e){if(s.has(e))return{name:`SerializedError.CauseCycle`,message:`cyclic cause; truncated`};s.add(e)}if(e instanceof Error)return{name:e.name,message:scrubPaths(e.message)??``,stack:scrubPaths(e.stack),code:e.code,cause:e.cause===void 0?void 0:serializeError(e.cause,t+1,s)};if(e==null)return{name:`UnknownError`,message:String(e)};if(typeof e==`string`)return{name:`StringError`,message:scrubPaths(e)??e};if(typeof e==`object`){let g=e;return{name:String(g.name??`ObjectError`),message:scrubPaths(String(g.message??``))??``,stack:scrubPaths(g.stack),code:g.code,cause:g.cause===void 0?void 0:serializeError(g.cause,t+1,s)}}return{name:`UnknownError`,message:String(e)}}var SingleFileNotFoundError=class extends Error{constructor(e){super(`File not found: ${e}`),this.filePath=e,this.name=`SingleFileNotFoundError`}},SingleFileNotAFileError=class extends Error{constructor(e){super(`Not a file: ${e}. \`ok <file>\` opens a single markdown file.`),this.filePath=e,this.name=`SingleFileNotAFileError`}},SingleFileNotMarkdownError=class extends Error{constructor(e){super(`OpenKnowledge edits markdown files (.md / .mdx): ${e}`),this.filePath=e,this.name=`SingleFileNotMarkdownError`}};function prepareSingleFileOpen(e){if(!isSupportedDocFile(e))throw new SingleFileNotMarkdownError(e);let t;try{t=realpathSync(resolve(e))}catch(t){throw t.code===`ENOENT`?new SingleFileNotFoundError(e):t}if(!statSync(t).isFile())throw new SingleFileNotAFileError(e);let s=dirname(t),g=findEnclosingProjectRoot(s);if(g){let e=g.rootPath;return{mode:`project`,projectRoot:e,docName:stripDocExtension(relative(resolveProjectContentDir(e),t).split(sep).join(`/`)),canonicalFilePath:t}}let S=basename(t);return{mode:`ephemeral`,canonicalFilePath:t,contentDir:s,singleDocRelPath:S,docName:stripDocExtension(S)}}function resolveProjectContentDir(e){return resolve(e,readConfigSafely({absPath:resolveConfigPath(`project`,e),sideline:!1,warn:()=>{}}).value.content?.dir??`.`)}function createEphemeralProjectDir(e){let t=mkdtempSync(resolve(tmpdir(),`ok-ephemeral-`)),s=resolve(t,`.ok`);return mkdirSync(s,{recursive:!0}),writeFileSync(resolve(s,`config.yml`),`# Ephemeral single-file session (\`ok <file>\`). Throwaway — safe to delete.\ncontent:\n dir: ${JSON.stringify(e)}\n`,`utf-8`),writeFileSync(resolve(s,`.gitignore`),`local/
|
|
3253
3253
|
`,`utf-8`),t}export{STARTER_PACKS as $,withSpan as $i,isAllowedWorkspaceHostHeader as $n,resolveBundledSkillDir as $r,createExternalChangeHandler as $t,HocuspocusAuthRejection as A,spawnDetached as Ai,formatPackRationale as An,planSeed as Ar,bundleSkillMdPath as At,McpLogger as B,tracedMkdirSync as Bi,handleCollabSocketError as Bn,readSkillManagement as Br,compareSemver as Bt,FILE_WATCHER_ORIGIN as C,serializeError as Ci,fallbackPaths as Cn,normalizeFsPath as Cr,bootServer as Ct,GitNotAvailableError as D,skillManagementPath as Di,formatAuthRejectionWire as Dn,parseHocuspocusAuthToken as Dr,buildSkillZip as Dt,GIT_UPSTREAM_WRITER as E,shutdownTelemetry as Ei,flushFileLogger as En,parseGitVersion as Er,buildExecResult as Et,MANAGED_RENAME_ORIGIN as F,teardownToleranceTelemetryWriter as Fi,getLogger as Fn,readArmedPaneTarget as Fr,clearEmbeddingsKeyFromAllBackends as Ft,PinoLogger as G,tracedUnlinkSync as Gi,initContent as Gn,reconcile as Gr,countStaleAgentWipRefs as Gt,OBSERVER_SYNC_ORIGIN as H,tracedRenameSync as Hi,hasGcLogLatch as Hn,readTargetRecordedAt as Hr,contentHash as Ht,MAX_AGENT_SESSIONS as I,toBroadcasterKey as Ii,getLogsDir as In,readBranchFromHead as Ir,coercePackId as It,ROOT_GITIGNORE_TEMPLATE as J,updateLastKnownHash as Ji,initToleranceTelemetryWriter as Jn,registerAllTools as Jr,createAssetServeMiddleware as Jt,ProjectGitInitError as K,tracedWriteFile as Ki,initShadowRepo as Kn,recordContributor as Kr,countWipRefs as Kt,MCP_CONNECTION_ID_HEADER as L,tracedAppendFileSync as Li,getMeter as Ln,readProjectLocalSemanticConfig as Lr,commitUpstreamImport as Lt,INSTALLED_AGENTS_SCHEMES as M,startWatcher as Mi,getCurrentMcpLogger as Mn,processCommand as Mr,classifyFsPath as Mt,LIVE_DERIVED_INDEX_DEBOUNCE_MS as N,streamingProblemEvent as Ni,getLocalDir as Nn,processUsage as Nr,clearArmedPaneTarget as Nt,GitTooOldError as O,spansCurrentPath as Oi,formatContributors as On,parseKeepaliveConnectionId as Or,buildStarterFolderFrontmatterYaml as Ot,LOG_MD_TEMPLATE as P,swapContributors as Pi,getLogFilePath as Pn,readAllTargets as Pr,clearContributors as Pt,STARTER_FOLDER_FRONTMATTER_FILENAME as Q,validateSkillZip as Qi,isAllowedApiOrigin as Qn,resetMetrics as Qr,createEphemeralProjectDir as Qt,MIN_GIT_VERSION as R,tracedLinkSync as Ri,getMetrics as Rn,readServerPackageVersion as Rr,commitWip as Rt,FILE_SYSTEM_WRITER as S,seedBasenameIndex as Si,extractWikiLinksFromMarkdown as Sn,mountMcpAndApi as Sr,attachIdleShutdown as St,GIT_PREFLIGHT_FAIL_SPAN_NAME as T,shadowGit as Ti,findEnclosingProjectRoot as Tn,parseAuthRejectionWire as Tr,buildConfigYmlContent as Tt,OK_OKIGNORE_TEMPLATE as U,tracedRmSync as Ui,incrementCollabSocketFilteredError as Un,readTargetVersion as Ur,contributorCount as Ut,MissingOkConfigError as V,tracedRename as Vi,handleSpawnCursor as Vn,readStateManifest as Vr,containsConflictMarkers as Vt,PANE_TARGET_TTL_MS as W,tracedRmdirSync as Wi,incrementServerObserverFire as Wn,readUiLock as Wr,countShadowObjects as Wt,SKILL_INSTALL_EVENTS_FILE_REL as X,validateAgentId as Xi,installTestLoggers as Xn,releaseUiLock as Xr,createContentFilterAsync as Xt,SERVICE_WRITER as Y,updateUiLockPort as Yi,installPrettyZodErrors as Yn,registerWrite as Yr,createContentFilter as Yt,STARTER_FOLDERS as Z,validateCloneInputs as Zi,installUserSkill as Zn,removeLastKnownHash as Zr,createEmbeddingsSecretStore as Zt,ConfigSchema as _,GitDirAccessError as _a,safeSubdir as _i,encodeSkillRoute as _n,loadPrincipal as _r,applySeed as _t,AgentPresenceBroadcaster as a,writeTracker as aa,resolvePackageVersion as ai,createServer$1 as an,isManagedArtifactDoc as ar,SingleFileNotAFileError as at,DEFAULT_PACK_ID as b,resolveGitDirDetailed as ba,saveInMemoryCheckpoint as bi,evictStaleTrackerEntries as bn,logsPreviousPath as br,assertGitAvailable as bt,AutoStartDisabledError as c,LATEST_PROTOCOL_VERSION as ca,restoreLifecycleFromConflictsJson as ci,createTestLogger as cn,isProjectRoot as cr,StateManifestError as ct,BUNDLE_SKILL_NAME as d,isJSONRPCResultResponse as da,runAuthReposSubprocess as di,detectGit as dn,isSelfWrite as dr,UiLockCollisionError as dt,withSpanSync as ea,resolveContentDir as ei,createFileLogger as en,isConfigDoc as er,STARTER_PACK_IDS as et,BacklinkIndex as f,atomicWriteFileSync as fa,runAuthStatusSubprocess as fi,detectProjectShape as fn,isSystemDoc as fr,__getShowAllWalkStatsForTesting as ft,CURSOR_BUNDLE_PATHS_BY_PLATFORM as g,writeConfigPatch as ga,safeContentPath as gi,encodeFolderRoute as gn,listStarterPacks as gr,applyExternalChange as gt,CONFLICT_MARKER_RE as h,withFileLockSync as ha,runWithMcpLogger as hi,encodeDocName as hn,listRescueCheckpoints as hr,applyAgentMarkdownWrite as ht,AgentFocusBroadcaster as i,writeTargetVersion as ia,resolvePack as ii,createPersistenceExtension as in,isLoopbackAddress as ir,SeedRootDirError as it,HocuspocusAuthTokenSchema as j,splitMarkdownBlocks as ji,gcCheckpointRefs as jn,prepareSingleFileOpen as jr,classifyEvents as jt,HOCUSPOCUS_AUTH_REJECTION_REASONS as k,spansPreviousPath as ki,formatContributorsFrom as kn,pathToDocName as kr,buildWipTree as kt,BUNDLE_IDS as l,isInitializedNotification as la,rewriteMarkdownLinksForDocumentRename as li,describeStoredEmbeddingsKey as ln,isProjectSkillManaged as lr,TagIndex as lt,CONFIG_FILENAME as m,resolveConfigPath as ma,runDeviceFlowSubprocess as mi,emitPreflightFailureSpan as mn,lastKnownHash as mr,acquireUiLock as mt,AGENT_ID_RE as n,writeSkillManagement as na,resolveCursorSpawnInvocation as ni,createMcpHttpHandler as nn,isKnownPackId as nr,STATE_MANIFEST_FILENAME as nt,AgentSessionCapacityError as o,McpServer as oa,resolveUiInfo as oi,createServerObserverExtension as on,isPairedWriteOrigin as or,SingleFileNotFoundError as ot,CC1Broadcaster as p,readConfigSafely as pa,runCloneSubprocess as pi,discoverLockDirs as pn,isToleranceTelemetryEnabled as pr,__resetShowAllWalkStatsForTesting as pt,ROLLBACK_ORIGIN as q,tracedWriteFileSync as qi,initTelemetry as qn,recordSkillInstallEvent as qr,createApiExtension as qt,AGENT_WRITE_ORIGIN as r,writeStateManifest as ra,resolveLockDir as ri,createOsProbe as rn,isLinkIndexExcludedDoc as rr,SeedPrerequisiteError as rt,AgentSessionManager as s,JSONRPCMessageSchema as sa,restoreContributors as si,createStreamingErrorWriter as sn,isPathWithinDir as sr,SingleFileNotMarkdownError as st,AGENT_ID_MAX_LEN as t,writeRootGitignoreForNewRepo as ta,resolveCursorBinaryDefault as ti,createLiveDerivedIndexExtension as tn,isHocuspocusAuthRejectionReason as tr,STARTER_TEMPLATES as tt,BUNDLE_SCOPE as u,isJSONRPCRequest as ua,rewriteWikiLinksForDocumentRename as ui,detectClaudeDesktopPresence as un,isReservedForUserTree as ur,USER_GLOBAL_BUNDLE_IDS as ut,DEFAULT_CHECKPOINT_RETENTION as v,MalformedGitPointerError as va,safetyCheckpoint as vi,ensureProjectGit as vn,loggerFactory as vr,armPaneTarget as vt,FileEmbeddingsBackend as w,setActiveSpanAttributes as wi,findEnclosingGitRoot as wn,packageVersionMajorMinor as wr,buildAndOpenSkill as wt,EMBEDDINGS_API_KEY_ENV as x,resolveShadowDir as xa,saveVersion as xi,extractOkBinaryPath as xn,makeLazyEmbeddingsKeyStore as xr,assertNeverDiskEvent as xt,DEFAULT_EMBEDDINGS_DIMENSIONS as y,parseCheckpoint as ya,sanitizeClientName as yi,errorResponse as yn,logsCurrentPath as yr,assertCompatibleStateManifest as yt,MISSING_OK_CONFIG_MESSAGE as z,tracedMkdir as zi,getTracer as zn,readSkillInstallStateSnapshot as zr,commitWipFromTree as zt};
|
|
3254
|
-
//# sourceMappingURL=dist-
|
|
3254
|
+
//# sourceMappingURL=dist-nP_B5M33.mjs.map
|