@inkeep/open-knowledge 0.6.0-beta.0 → 0.6.0-beta.2
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 +90 -0
- package/dist/assets/skills/{open-knowledge → project}/SKILL.md +128 -211
- package/dist/cli.mjs +21 -21
- package/dist/constants-xZa5P4wL.mjs +2 -0
- package/dist/dist-7_PKsuCz.mjs +1 -0
- package/dist/{dist-B_Nlx5d6.mjs → dist-soQLoIV1.mjs} +91 -110
- package/dist/index.mjs +1 -1
- package/dist/init-CFkaUfzc.mjs +1 -0
- package/dist/{init-pu_7zCAy.mjs → init-DjF_or_S.mjs} +10 -10
- package/dist/loader-Bmw95q2S.mjs +1 -0
- package/dist/{loader-DwgxIIbN.mjs → loader-D39G1Qj8.mjs} +3 -3
- package/dist/{preview-Bep4xj-R.mjs → preview-BrADtCN4.mjs} +2 -2
- package/dist/preview-COcwGoDu.mjs +1 -0
- package/dist/public/assets/{index-Izdfgq4i.js → index-zU1ANKhn.js} +2 -2
- package/dist/public/index.html +1 -1
- package/dist/{repair-launch-json-ByfyoscN.mjs → repair-launch-json-BbKHWVwS.mjs} +2 -2
- package/dist/{repair-mcp-configs-D6LjdRhL.mjs → repair-mcp-configs-DwbKFYJm.mjs} +2 -2
- package/dist/{src-DOCgFp9P.mjs → src-C9SFj148.mjs} +2 -2
- package/dist/start-BYnDVYJN.mjs +1 -0
- package/dist/{start-CojePtz9.mjs → start-DZJdwuup.mjs} +2 -2
- package/package.json +2 -2
- package/dist/constants-JUZqR_Yu.mjs +0 -2
- package/dist/dist-Bq1Nm7Hl.mjs +0 -1
- package/dist/init-DD_r2nwd.mjs +0 -1
- package/dist/loader-CTWe5z9-.mjs +0 -1
- package/dist/preview-DtrIs0gZ.mjs +0 -1
- package/dist/start-PJUtb0rl.mjs +0 -1
|
@@ -362,7 +362,7 @@ $2`).split(`
|
|
|
362
362
|
`;return F.join(H)},table(e,t,S,w){let E=` `,D=S.enter(`table`),O=[],k=[],j=e.children??[];for(let e of j){let t=e.children??[],E=[],D=[];for(let e of t){let t=S.enter(`tableCell`),O=S.enter(`phrasing`),k=S.containerPhrasing(e,{...w,before:` `,after:` `});O(),t(),E.push(k);let j=e.data?.sourcePadding;D.push(j&&typeof j.left==`number`&&typeof j.right==`number`?{left:j.left,right:j.right}:null)}O.push(E),k.push(D)}D();let F=e.align??[],L=e.data?.sourceDashCounts,B=O[0]?.length??0,H=O.slice(1).reduce((e,t)=>Math.max(e,t.length),0),q=Math.max(B,H,F.length),J=[];for(let e=0;e<q;e++){let t=F[e],S=``,w=``;t===`center`?(S=`:`,w=`:`):t===`left`?S=`:`:t===`right`&&(w=`:`);let E=L?.[e],D=typeof E==`number`&&E>=1?E:1;J.push(S+`-`.repeat(D)+w)}let Y=(e,t)=>{let S=[];for(let w=0;w<q;w++){let E=e[w]??``,D=t[w]??{left:1,right:1};S.push(` `.repeat(D.left)+E+` `.repeat(D.right))}return`|${S.join(`|`)}|`},ee=Array.from({length:q},()=>null);if(O.length===0)return Y(J,ee);let te=[];te.push(Y(O[0],k[0]??[])),te.push(Y(J,ee));for(let e=1;e<O.length;e++)te.push(Y(O[e],k[e]??[]));return te.join(`
|
|
363
363
|
`)},mdxJsxFlowElement(e,t,S,w){let E=e,D=E.data?.sourceRaw;if(typeof D==`string`)return D;let O=E.data?.htmlBoundary;if(O&&typeof O.opener==`string`&&typeof O.closer==`string`){let e=S.containerFlow({type:`root`,children:E.children??[]},w);return`${O.opener}\n\n${e}\n\n${O.closer}`}let k=E.name??``,j=serializeMdxJsxAttrs(E.attributes??[]);if(!E.children||E.children.length===0)return k?j?`<${k} ${j} />`:`<${k} />`:``;let F=j?`<${k} ${j}>`:`<${k}>`,L=`</${k}>`;return`${F}\n\n${S.containerFlow({type:`root`,children:E.children},w)}\n\n${L}`},mark(e,t,S,w){let E=S.createTracker(w),D=S.enter(`mark`),O=E.move(`==`);return O+=S.containerPhrasing(e,{before:O,after:`==`,...E.current()}),O+=E.move(`==`),D(),O},comment(e,t,S,w){let E=e.data?.sourceForm,D=E===`html`?`<!-- `:`%%`,O=E===`html`?` -->`:`%%`,k=S.createTracker(w),j=S.enter(`comment`),F=k.move(D);return F+=S.containerPhrasing(e,{before:F,after:O,...k.current()}),F+=k.move(O),j(),F},commentBlock(e,t,S,w){let E=S.createTracker(w),D=S.enter(`commentBlock`),O=e.children??[],k=e.data?.sourceForm,j=e.data?.sourceLayout,F=O.length===1&&O[0]?.type===`paragraph`;if(k===`html`&&F){let e=O[0],t=S.containerPhrasing(e,{before:`<!-- `,after:` -->`,...E.current()});return D(),`<!-- ${t} -->`}if(j===`inline`&&F){let e=O[0],t=S.containerPhrasing(e,{before:`%% `,after:` %%`,...E.current()});return D(),`%% ${t} %%`}let L=S.containerFlow(e,E.current());return D(),`%%\n\n${L}\n\n%%`},mdxJsxTextElement(e){let t=e.data?.sourceRaw;if(typeof t==`string`)return t;let S=e.name??``,w=serializeMdxJsxAttrs(e.attributes??[]);return w?`<${S} ${w} />`:`<${S}/>`},rawMdxFallback(e){return e.value??``},blockquote(e,t,S,w){let E=S.enter(`blockquote`),D=S.createTracker(w);D.move(`> `),D.shift(2);let O=S.containerFlow(e,D.current());E();let k=e.data?.sourceMarkerSpacings,j=0;return S.indentLines(O,(e,t,S)=>S?`>`:k?.[j++]===`none`?`>${e}`:`> ${e}`)}};function serializeMdxJsxAttrs(e){let t=[];for(let S of e){if(S.type===`mdxJsxExpressionAttribute`){t.push(`{${S.value}}`);continue}let e=S.name;if(S.value===null||S.value===void 0){t.push(e);continue}if(typeof S.value==`string`){if(S.value.includes(`"`)){let w=S.value.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`);t.push(`${e}={"${w}"}`)}else t.push(`${e}="${S.value}"`);continue}t.push(`${e}={${S.value.value}}`)}return t.join(` `)}function emitLinkTitle(e,t,S=` `){return t===`single`?`${S}'${e.replace(/'/g,`\\'`)}'`:t===`paren`?`${S}(${e.replace(/[()]/g,`\\$&`)})`:`${S}"${e.replace(/"/g,`\\"`)}"`}function formatLinkUrl(e){if(!e)return``;let t=0,S=!0;for(let w of e)w===`(`?t++:w===`)`&&(t--,t<0&&(S=!1));return t!==0&&(S=!1),S?e:e.replace(/[\\()]/g,`\\$&`)}function escapeEntityAmpersands(e){return e.replace(/(?<!\\)&(?=[A-Za-z][A-Za-z0-9]*;|#[0-9]+;|#[xX][0-9A-Fa-f]+;)/g,`\\&`)}function safeText(e,t,S){let w=e.unsafe;e.unsafe=w.filter(e=>!(e.character===`&`&&e.after===`[#A-Za-z]`||e.character===`<`||e.character===`[`||e.character===`(`||e.character==="`"));let E;try{E=e.safe(t,S)}finally{e.unsafe=w}return escapeEntityAmpersands(E)}function formatFileSize(e){if(!Number.isFinite(e)||e<0)return``;if(e<1024)return`${e} B`;let t=[`KiB`,`MiB`,`GiB`,`TiB`],S=e/1024,w=0;for(;S>=1024&&w<t.length-1;)S/=1024,w+=1;return`${S.toFixed(1).replace(/\.0$/,``)} ${t[w]}`}var MarkdownManager=class{schema;handlers;pmNodeHandlers;pmMarkHandlers;parseProcessor;serializeProcessor;parseCtx={current:{}};constructor(e){this.schema=getSchema(e.extensions),this.handlers=buildMdastToPmHandlers(this.schema,this.parseCtx);let{nodeHandlers:t,markHandlers:S}=buildPmToMdastHandlers(this.schema);this.pmNodeHandlers=t,this.pmMarkHandlers=S,this.parseProcessor=createParseProcessor({schema:this.schema,handlers:this.handlers,pmNodeHandlers:this.pmNodeHandlers,pmMarkHandlers:this.pmMarkHandlers}),this.serializeProcessor=createSerializeProcessor({schema:this.schema,handlers:this.handlers,pmNodeHandlers:this.pmNodeHandlers,pmMarkHandlers:this.pmMarkHandlers,toMarkdownHandlers})}parse(e,t){if(!e.trim())return{type:`doc`,content:[{type:`paragraph`,content:[]}]};this.parseCtx.current=t??{};try{return parseMd(e,this.parseProcessor).toJSON()}finally{this.parseCtx.current={}}}parseToMdast(e){return e.trim()?parseMdToMdast(e,this.parseProcessor):{type:`root`,children:[]}}parseWithFallback(e,t){return e.trim()?parseWithFallback(e,{parse:e=>this.parse(e,t)}):{type:`doc`,content:[{type:`paragraph`,content:[]}]}}serialize(e){let t;try{t=this.schema.nodeFromJSON(e)}catch(t){let S=`MarkdownManager.serialize() failed: schema rejected JSONContent (type=${e.type}, childCount=${e.content?.length??0})`;throw Error(S,{cause:t})}return serializeMd(t,this.serializeProcessor,{schema:this.schema,pmNodeHandlers:this.pmNodeHandlers,pmMarkHandlers:this.pmMarkHandlers})}};const registry=createRegistry();function destructureAttrs(e,t){let S=new Map;for(let e of t)S.set(e.name,e);let w={};for(let t of e){if(t.type===`mdxJsxExpressionAttribute`)continue;let e=t.name,E=S.get(e);if(t.value===null||t.value===void 0){w[e]=!0;continue}if(typeof t.value==`string`){if(E?.type===`number`){let S=Number(t.value);w[e]=Number.isNaN(S)?t.value:S}else E?.type===`boolean`?w[e]=t.value===`true`:w[e]=t.value;continue}let D=t.value.value;try{w[e]=JSON.parse(D)}catch{w[e]=D}}return w}function hasDirtyDescendant(e){let t=!1;return e.descendants(e=>t||e.type.name===`jsxInline`?!1:e.type.name===`jsxComponent`&&e.attrs.sourceDirty?(t=!0,!1):!0),t}function effectiveDirty(e){return e.attrs.sourceDirty||hasDirtyDescendant(e)}function isEmptyMdastParagraph(e){if(e.type!==`paragraph`)return!1;let t=e.children??[];return t.length===0?!0:t.every(e=>e.type===`text`&&e.value===``)}function withInlineCodeData(e,t){if(!t)return e;let S={};return t.sourceFenceChar&&(S.sourceFenceChar=t.sourceFenceChar),typeof t.sourceFenceLength==`number`&&(S.sourceFenceLength=t.sourceFenceLength),Object.keys(S).length===0?e:{...e,data:S}}function wrapAsInlineCode(e,t){if(e.length===0)return withInlineCodeData({type:`inlineCode`,value:``},t);if(e.every(e=>e.type===`text`))return withInlineCodeData({type:`inlineCode`,value:e.map(e=>e.value).join(``)},t);if(e.length===1&&`children`in e[0]){let S=e[0];return{...S,children:[wrapAsInlineCode(S.children,t)]}}return withInlineCodeData({type:`inlineCode`,value:extractTextFromMdastNodes(e)},t)}function extractTextFromMdastNodes(e){let t=``;for(let S of e)S.type===`text`?t+=S.value:`children`in S&&Array.isArray(S.children)?t+=extractTextFromMdastNodes(S.children):`value`in S&&typeof S.value==`string`&&(t+=S.value);return t}const WIKI_EMBED_IMAGE_EXTS=IMAGE_EXTENSIONS;function buildMdastToPmHandlers(e,t){let S=e.nodes,w=e.marks,E={};S.paragraph&&(E.paragraph=(e,t,w)=>{let E=w.all(e).flat(),D=E.some(e=>e?.isBlock&&!e?.isInline),O=E.some(e=>e?.isInline||e?.isText||e?.isTextblock);if(D&&!O)return E.length===1?E[0]:E;if(D&&O){let e=E.filter(e=>!e?.isBlock||e?.isInline),t=E.filter(e=>e?.isBlock&&!e?.isInline),w=[],D=S.paragraph.createAndFill(null,e.length>0?e:null);return D&&w.push(D),w.push(...t),w.length===1?w[0]:w}return S.paragraph.createAndFill(null,E.length>0?E:null)}),S.blockquote&&(E.blockquote=toPmNode(S.blockquote,e=>({sourceMarkerSpacings:e.data?.sourceMarkerSpacings??null}))),S.tableCell&&(E.tableCell=(e=>(t,w,E)=>{let D=E.all(t).flat();if(D.length>0&&S.paragraph){let t=S.paragraph.create(null,D);return e.createAndFill(null,[t])}return e.createAndFill(null,null)})(S.tableCell)),S.tableRow&&(E.tableRow=toPmNode(S.tableRow)),S.table&&S.tableRow&&S.tableCell&&(E.table=(e,t,w)=>{let E=e.align??[],D=e.children??[],O=[];for(let e=0;e<D.length;e++){let t=D[e];if(t.type!==`tableRow`)continue;let k=t.children??[],j=[];for(let t=0;t<k.length;t++){let D=k[t];if(D.type!==`tableCell`)continue;let O=w.all(D).flat(),F=O.length>0&&S.paragraph?[S.paragraph.create(null,O)]:null,L=E[t]??null,B=e===0&&S.tableHeader?S.tableHeader:S.tableCell,H=D.data?.sourcePadding??null,q=B.createAndFill({align:L,sourcePadding:H},F);q&&j.push(q)}let F=S.tableRow.createAndFill(null,j.length>0?j:null);F&&O.push(F)}let k=e.data?.sourceDashCounts??null;return S.table.createAndFill({sourceDashCounts:k},O.length>0?O:null)}),S.image&&(E.image=e=>{let w=e.url??``,E=normalizeDocRelativeAssetUrl(w,t.current.sourcePath);return S.image.createAndFill({src:E,alt:e.alt??null,title:e.title??null,sourceUrl:E===w?null:w})},S.imageReference?E.imageReference=e=>S.imageReference.createAndFill({alt:e.alt??``,label:e.label??e.identifier??``,identifier:e.identifier??``,referenceType:e.referenceType??`shortcut`}):E.imageReference=e=>S.image.createAndFill({src:``,alt:e.alt??null,title:null})),w.escapeMark&&(E.text=t=>{let S=t.value??``,E=typeof t.data?.sourceRaw==`string`?t.data.sourceRaw:null;if(!S&&!E)return null;if(E){let t=S.replaceAll(`\xA0`,` `);return w.sourceLiteral?e.text(t,[w.sourceLiteral.create({sourceRaw:E})]):e.text(t)}let D=t.data?.escapedChars,O=t.data?.entityRefSpans;if(!D?.length&&!O?.length)return e.text(S.replaceAll(`\xA0`,` `));let k=[...(D??[]).map(e=>({kind:`escape`,offset:e.offset,length:1})),...(O??[]).map(e=>({kind:`entity`,offset:e.offset,length:e.length,raw:e.raw}))];k.sort((e,t)=>e.offset-t.offset);let j=[],F=0;for(let t of k){if(t.offset>F){let w=S.slice(F,t.offset).replaceAll(`\xA0`,` `);w&&j.push(e.text(w))}if(t.offset<S.length){let E=S.slice(t.offset,t.offset+t.length).replaceAll(`\xA0`,` `);E&&(t.kind===`escape`?j.push(e.text(E,[w.escapeMark.create()])):w.sourceLiteral?j.push(e.text(E,[w.sourceLiteral.create({sourceRaw:t.raw})])):j.push(e.text(E))),F=t.offset+t.length}}if(F<S.length){let t=S.slice(F).replaceAll(`\xA0`,` `);t&&j.push(e.text(t))}return j.length===1?j[0]:j}),w.code&&(E.inlineCode=t=>e.text(t.value,[w.code.create({sourceFenceChar:t.data?.sourceFenceChar??"`",sourceFenceLength:typeof t.data?.sourceFenceLength==`number`?t.data.sourceFenceLength:1})]));let D=w.strike??w.delete;if(D&&(E.delete=toPmMark(D)),w.highlight&&(E.mark=toPmMark(w.highlight)),w.comment&&(E.comment=toPmMark(w.comment,e=>({sourceForm:e.data?.sourceForm??`percent`}))),S.commentBlock&&(E.commentBlock=toPmNode(S.commentBlock,e=>({sourceForm:e.data?.sourceForm??`percent`,sourceLayout:e.data?.sourceLayout??`block`}))),w.emphasis&&(E.emphasis=toPmMark(w.emphasis,e=>({sourceDelimiter:e.data?.sourceDelimiter??`*`}))),w.strong&&(E.strong=toPmMark(w.strong,e=>({sourceDelimiter:e.data?.sourceDelimiter??`**`}))),S.heading&&(E.heading=toPmNode(S.heading,e=>({level:e.depth,headingStyle:e.data?.sourceStyle??`atx`,sourceTrailingHashes:e.data?.sourceTrailingHashes??null,sourceUnderlineLength:e.data?.sourceUnderlineLength??null,sourceContiguousNext:e.data?.sourceContiguousNext??!1}))),S.codeBlock&&(E.code=t=>{let w=t.value?[e.text(t.value)]:[];return S.codeBlock.createAndFill({language:t.lang??null,meta:t.meta??null,fenceDelimiter:t.data?.sourceFenceChar??"`",fenceLength:t.data?.sourceFenceLength??3,sourceStyle:t.data?.sourceStyle??`fenced`},w)}),S.thematicBreak&&(E.thematicBreak=e=>S.thematicBreak.createAndFill({sourceRaw:e.data?.sourceRaw??`---`})),S.hardBreak&&(E.break=e=>S.hardBreak.createAndFill({hardBreakStyle:e.data?.sourceStyle??`spaces`})),S.list&&(E.list=toPmNode(S.list,e=>({ordered:!!e.ordered,start:e.start??1,spread:!!e.spread,bulletMarker:e.data?.bulletMarker??null,listMarkerDelimiter:e.data?.listMarkerDelimiter??null}))),S.listItem&&(E.listItem=toPmNode(S.listItem,e=>({checked:e.checked??null,spread:!!e.spread}))),w.link){let t=w.sourceLiteral;E.link=(S,E,D)=>{if((S.children??[]).length===0){let w=typeof S.data?.sourceRaw==`string`?S.data.sourceRaw:`[](${S.url??``})`;return w?t?e.text(w,[t.create({sourceRaw:w})]):e.text(w):null}let O=D.all(S).flat(),k=w.link.create({href:S.url??``,title:S.title??null,linkStyle:S.data?.sourceStyle??`inline`,refLabel:null,sourceUrlForm:S.data?.sourceUrlForm??null,sourceTitleMarker:S.data?.sourceTitleMarker??null});return O.map(e=>e.mark(k.addToSet(e.marks)))},E.linkReference=(S,E,D)=>{if((S.children??[]).length===0){let w=typeof S.data?.sourceRaw==`string`?S.data.sourceRaw:`[${S.label??``}][${S.identifier??``}]`;return w?t?e.text(w,[t.create({sourceRaw:w})]):e.text(w):null}let O=D.all(S).flat(),k=w.link.create({href:``,title:null,linkStyle:S.referenceType??`shortcut`,refLabel:S.label??S.identifier??null});return O.map(e=>e.mark(k.addToSet(e.marks)))}}S.htmlBlock&&(E.html=e=>S.htmlBlock.createAndFill({content:e.value??``}));let O=S.linkDefinition??S.linkRefDef;if(O){let e=!!O.spec.attrs?.url,t=!!O.spec.attrs?.href,S=!!O.spec.attrs?.identifier,w=!!O.spec.attrs?.sourceLayout,D=!!O.spec.attrs?.sourceTitleMarker;E.definition=E=>{let k={title:E.title??null};return S&&(k.identifier=E.identifier??``),k.label=E.label??E.identifier??``,e?k.url=E.url??``:t&&(k.href=E.url??``),w&&(k.sourceLayout=E.data?.sourceLayout??null),D&&(k.sourceTitleMarker=E.data?.sourceTitleMarker??null),O.createAndFill(k)}}if(S.jsxComponent){let w=e=>{if(e&&typeof e==`object`&&`sourceRaw`in e){let t=e.sourceRaw;if(typeof t==`string`)return t}};E.mdxJsxFlowElement=(e,E,D)=>{let O=e.name??``,k=registry.getOrWildcard(O),j=destructureAttrs(e.attributes,k.props);if(O===`CommonMarkImage`&&typeof j.src==`string`){let e=j.src,S=normalizeDocRelativeAssetUrl(e,t.current.sourcePath);S!==e&&(j.src=S,j.sourceUrl=e)}let F=D.all(e).flat();return S.jsxComponent.createAndFill({componentName:O,kind:`element`,attributes:e.attributes,sourceRaw:w(e.data)??``,sourceDirty:!1,props:j},F.length?F:void 0)};let D=(e,t)=>{let S=e.attributes?.find(e=>e.type===`mdxJsxAttribute`&&e.name===t);return S&&typeof S.value==`string`?S.value:null};E.mdxJsxTextElement=t=>{if(t.name===`InlineMath`&&S.mathInline){let e=D(t,`formula`)??``,w=D(t,`id`);return S.mathInline.create({formula:e,id:w??null})}if(t.name===`Tag`&&S.tag){let e=D(t,`value`)??``;return S.tag.create({value:e})}if(S.jsxInline){let E=w(t.data)??``;return S.jsxInline.createAndFill({},E?[e.text(E)]:null)}return S.jsxComponent.createAndFill({sourceRaw:w(t.data)??``})},E.mdxFlowExpression=e=>{let t=w(e.data)??`{${e.value??``}}`;return S.jsxComponent.createAndFill({kind:`expression`,sourceRaw:t,sourceDirty:!1})},E.mdxTextExpression=t=>{let S=w(t.data)??`{${t.value??``}}`;return e.text(S)}}return S.wikiLink&&(E.wikiLink=e=>S.wikiLink.createAndFill({target:e.data?.target??``,alias:e.data?.alias??null,anchor:e.data?.anchor??null})),S.tag&&(E.tag=e=>S.tag.createAndFill({value:e.value})),S.wikiLinkEmbed&&(E.wikiLinkEmbed=(E,D)=>{let O=E.data?.target??``,k=E.data?.alias??null,j=E.data?.anchor??null,F=extensionOf(O),{resolveEmbed:L,sourcePath:B}=t.current,H=L&&B?L(O,B)??null:null,q=H?`/${H}`:O,J=D?.type===`paragraph`&&Array.isArray(D.children)&&D.children.length===1;if(J&&WIKI_EMBED_IMAGE_EXTS.has(F)&&S.jsxComponent&®istry.has(`WikiEmbedImage`))return S.jsxComponent.createAndFill({componentName:`WikiEmbedImage`,kind:`element`,attributes:[],sourceRaw:``,sourceDirty:!1,props:{src:q,alt:k??O,target:O,anchor:j,alias:k}});if(J&&VIDEO_EXTENSIONS.has(F)&&S.jsxComponent&®istry.has(`WikiEmbedVideo`))return S.jsxComponent.createAndFill({componentName:`WikiEmbedVideo`,kind:`element`,attributes:[],sourceRaw:``,sourceDirty:!1,props:{src:q,title:k??O,target:O,anchor:j,alias:k}});if(J&&AUDIO_EXTENSIONS.has(F)&&S.jsxComponent&®istry.has(`WikiEmbedAudio`))return S.jsxComponent.createAndFill({componentName:`WikiEmbedAudio`,kind:`element`,attributes:[],sourceRaw:``,sourceDirty:!1,props:{src:q,title:k??O,target:O,anchor:j,alias:k}});if(J&&FILE_ATTACHMENT_EXTENSIONS.has(F)&&S.jsxComponent&®istry.has(`WikiEmbedFile`)){let{resolveSize:e}=t.current,w=e&&B?e(O,B)??null:null,E=w===null?null:formatFileSize(w);return S.jsxComponent.createAndFill({componentName:`WikiEmbedFile`,kind:`element`,attributes:[],sourceRaw:``,sourceDirty:!1,props:{src:q,target:O,anchor:j,alias:k,size:E}})}let Y=k||(j?`${O}#${j}`:O);if(WIKI_EMBED_EXTENSIONS.has(F)&&w.link){let t=w.link.create({href:q,title:null,linkStyle:`inline`,refLabel:null,sourceForm:`wikiembed`,target:O,anchor:j,alias:k});return e.text(Y,[t])}if(w.link){let t=w.link.create({href:O,title:null,linkStyle:`inline`,refLabel:null});return e.text(Y,[t])}throw Error("[wikiLinkEmbed handler] schema lacks `link` mark — cannot dispatch without violating the STOP rule against emitting PM wikiLinkEmbed server-side")}),S.mathInline&&(E.inlineMath=e=>S.mathInline.create({formula:e.value??``})),E.math||=t=>{let w=t.value==null?`«unknown:${t.type}»`:t.value;return S.rawMdxFallback?(console.warn(JSON.stringify({event:`unknown-mdast-type`,type:t.type,reason:`Unhandled block mdast: ${t.type}`})),S.rawMdxFallback.createAndFill({reason:`Unhandled block mdast: ${t.type}`},w?[e.text(w)]:null)):null},E.inlineMath||=t=>(console.warn(JSON.stringify({event:`unknown-mdast-type`,type:t.type,reason:`Unhandled inline mdast: ${t.type}`})),t.value==null?e.text(`«unknown:${t.type}»`):e.text(t.value)),S.footnoteReference?E.footnoteReference=e=>S.footnoteReference.create({identifier:e.identifier,label:e.label??e.identifier}):E.footnoteReference||=t=>(console.warn(JSON.stringify({event:`unknown-mdast-type`,type:`footnoteReference`,reason:`FootnoteReference extension missing — recovering [^id] source`})),e.text(`[^${t.label??t.identifier}]`)),S.footnoteDefinition?E.footnoteDefinition=toPmNode(S.footnoteDefinition,e=>{let t=e;return{identifier:t.identifier,label:t.label??t.identifier}}):E.footnoteDefinition||=t=>{console.warn(JSON.stringify({event:`unknown-mdast-type`,type:`footnoteDefinition`,reason:`FootnoteDefinition extension missing — recovering [^id]: marker`}));let w=`[^${t.label??t.identifier}]: `;return S.paragraph?S.paragraph.create(null,e.text(w)):null},E.rawMdxFallbackMdast=t=>{if(!S.rawMdxFallback)return null;let w=t.position?{start:t.position.start?.offset??0,end:t.position.end?.offset??0}:{start:0,end:0};return console.warn(JSON.stringify({event:`unknown-mdast-type`,type:t.originalType,reason:`Unhandled mdast: ${t.originalType}`})),S.rawMdxFallback.createAndFill({reason:`Unhandled mdast: ${t.originalType}`,originalSpan:w},t.value?[e.text(t.value)]:null)},E}function buildPmToMdastHandlers(e){let t={},S={},w=e.nodes,E=e.marks;w.paragraph&&(t.paragraph=fromPmNode(`paragraph`)),w.blockquote&&(t.blockquote=fromPmNode(`blockquote`,e=>{let t=e.attrs.sourceMarkerSpacings,S={};return Array.isArray(t)&&t.length>0&&(S.sourceMarkerSpacings=t),Object.keys(S).length>0?{data:S}:{}})),w.heading&&(t.heading=fromPmNode(`heading`,e=>({depth:e.attrs.level,data:{sourceStyle:e.attrs.headingStyle,sourceTrailingHashes:e.attrs.sourceTrailingHashes??void 0,sourceUnderlineLength:e.attrs.sourceUnderlineLength??void 0,sourceContiguousNext:e.attrs.sourceContiguousNext===!0?!0:void 0}}))),w.codeBlock&&(t.codeBlock=e=>{let t=e.attrs.sourceStyle===`indented`?`indented`:`fenced`;return{type:`code`,lang:t===`indented`?null:e.attrs.language??null,meta:t===`indented`?null:e.attrs.meta??null,value:e.textContent??``,data:{sourceFenceChar:e.attrs.fenceDelimiter,sourceFenceLength:e.attrs.fenceLength,sourceStyle:t}}}),w.thematicBreak&&(t.thematicBreak=e=>({type:`thematicBreak`,data:{sourceRaw:e.attrs.sourceRaw}})),w.hardBreak&&(t.hardBreak=e=>({type:`break`,data:{sourceStyle:e.attrs.hardBreakStyle}})),w.list&&(t.list=fromPmNode(`list`,e=>({ordered:e.attrs.ordered??!1,start:e.attrs.ordered?e.attrs.start??1:null,spread:e.attrs.spread??!1,data:{bulletMarker:e.attrs.bulletMarker,listMarkerDelimiter:e.attrs.listMarkerDelimiter}}))),w.listItem&&(t.listItem=(e,t,S)=>{let w=S.all(e),E=w.length>1&&isEmptyMdastParagraph(w[0])?w.slice(1):w;return{type:`listItem`,checked:e.attrs.checked??null,spread:e.attrs.spread??!1,children:E}}),w.table&&(t.table=(e,t,S)=>{let w=S.all(e),E=[],D=e.firstChild;D&&D.forEach(e=>{let t=e.attrs.align;E.push(t===`left`||t===`right`||t===`center`?t:null)});let O=w.filter(e=>e.type===`tableRow`),k=e.attrs.sourceDashCounts,j=Array.isArray(k)&&k.length>0?{sourceDashCounts:k}:void 0,F={type:`table`,align:E,children:O};return j&&(F.data=j),F}),w.tableRow&&(t.tableRow=fromPmNode(`tableRow`));let D=e=>{let t=e.attrs.sourcePadding,S={};return typeof t==`object`&&t&&typeof t.left==`number`&&typeof t.right==`number`&&(S.sourcePadding=t),Object.keys(S).length>0?{data:S}:{}};if(w.tableCell&&(t.tableCell=fromPmNode(`tableCell`,D)),w.tableHeader&&(t.tableHeader=fromPmNode(`tableCell`,D)),w.image&&(t.image=e=>({type:`image`,url:e.attrs.sourceUrl??e.attrs.src,alt:e.attrs.alt,title:e.attrs.title})),w.imageReference&&(t.imageReference=e=>{let t=e.attrs.label??``,S=e.attrs.identifier??t;return{type:`imageReference`,alt:e.attrs.alt??``,identifier:S,label:t||S,referenceType:e.attrs.referenceType??`shortcut`}}),w.htmlBlock&&(t.htmlBlock=e=>({type:`html`,value:e.attrs.content})),w.linkDefinition??w.linkRefDef){let e=w.linkDefinition?`linkDefinition`:`linkRefDef`;t[e]=e=>{let t={},S=e.attrs.sourceLayout;(S===`multiline`||S===`inline`)&&(t.sourceLayout=S);let w=e.attrs.sourceTitleMarker;(w===`single`||w===`double`||w===`paren`)&&(t.sourceTitleMarker=w);let E={type:`definition`,identifier:e.attrs.identifier??e.attrs.label??``,label:e.attrs.label??e.attrs.identifier??``,url:e.attrs.url??e.attrs.href??``,title:e.attrs.title};return Object.keys(t).length>0&&(E.data=t),E}}if(w.jsxComponent&&(t.jsxComponent=(e,t,S)=>{if(e.attrs.kind===`expression`)return{type:`html`,value:e.attrs.sourceRaw??``};let w=e.attrs.componentName||null,E=Array.isArray(e.attrs.attributes)?e.attrs.attributes:[];return!effectiveDirty(e)&&e.attrs.sourceRaw?{type:`mdxJsxFlowElement`,name:w,attributes:E,children:[],data:{sourceRaw:String(e.attrs.sourceRaw)}}:registry.getOrWildcard(w??`*`).serialize(e,{all:e=>S.all(e),registry,serializeChildren:()=>{throw Error(`SerializeContext.serializeChildren is not available in the PM→mdast handler. Compat descriptors that need markdown-byte body rendering must emit a marker mdast node and let the to-markdown handler render the body via state.containerFlow.`)}})}),w.rawMdxFallback&&(t.rawMdxFallback=e=>{let t=e.textContent??``,S=typeof e.attrs.reason==`string`?e.attrs.reason:``,w=e.attrs.originalSpan;return{type:`rawMdxFallback`,value:t,data:{reason:S,originalSpan:w&&typeof w==`object`&&`start`in w&&`end`in w?{start:Number(w.start)||0,end:Number(w.end)||0}:{start:0,end:0}}}}),w.jsxInline&&(t.jsxInline=e=>{let t=e.attrs.sourceRaw||e.textContent||``;return{type:`mdxJsxTextElement`,name:null,attributes:[],children:[],data:{sourceRaw:String(t)}}}),w.mathInline&&(t.mathInline=e=>{let t=e.attrs.formula??``,S=e.attrs.id;return typeof S==`string`&&S.length>0?{type:`mdxJsxTextElement`,name:`InlineMath`,attributes:[{type:`mdxJsxAttribute`,name:`formula`,value:t},{type:`mdxJsxAttribute`,name:`id`,value:S}],children:[]}:{type:`inlineMath`,value:t}}),w.wikiLink&&(t.wikiLink=e=>{let t=e.attrs.target??``,S=e.attrs.anchor??null,w=e.attrs.alias??null,E=w||(S?`${t}#${S}`:t);return{type:`wikiLink`,value:E,data:{target:t,anchor:S,alias:w},children:[{type:`text`,value:E}]}}),w.tag&&(t.tag=e=>({type:`tag`,value:String(e.attrs.value??``)})),w.wikiLinkEmbed&&(t.wikiLinkEmbed=e=>{let t=e.attrs.target??``,S=e.attrs.anchor??null,w=e.attrs.alias??null,E=w||(S?`${t}#${S}`:t);return{type:`wikiLinkEmbed`,value:E,data:{target:t,anchor:S,alias:w},children:[{type:`text`,value:E}]}}),E.emphasis&&(S.emphasis=fromPmMark(`emphasis`,e=>({data:{sourceDelimiter:e.attrs.sourceDelimiter}}))),E.strong&&(S.strong=fromPmMark(`strong`,e=>({data:{sourceDelimiter:e.attrs.sourceDelimiter}}))),E.code&&(S.code=(e,t,S)=>{let w=e.attrs.sourceFenceChar,E=e.attrs.sourceFenceLength;return wrapAsInlineCode(S,{sourceFenceChar:w,sourceFenceLength:E})}),E.strike??E.delete){let e=E.strike?`strike`:`delete`;S[e]=fromPmMark(`delete`)}return E.highlight&&(S.highlight=fromPmMark(`mark`)),E.comment&&(S.comment=fromPmMark(`comment`,e=>({data:{sourceForm:e.attrs.sourceForm===`html`?`html`:`percent`}}))),w.commentBlock&&(t.commentBlock=fromPmNode(`commentBlock`,e=>({data:{sourceForm:e.attrs.sourceForm===`html`?`html`:`percent`,sourceLayout:e.attrs.sourceLayout===`inline`?`inline`:`block`}}))),w.footnoteReference&&(t.footnoteReference=e=>{let t=String(e.attrs.identifier??``);return{type:`footnoteReference`,identifier:t,label:e.attrs.label?String(e.attrs.label):t}}),w.footnoteDefinition&&(t.footnoteDefinition=fromPmNode(`footnoteDefinition`,e=>({identifier:String(e.attrs.identifier??``),label:e.attrs.label?String(e.attrs.label):String(e.attrs.identifier??``)}))),E.link&&(S.link=(e,t,S)=>{if(e.attrs.sourceForm===`wikiembed`){let t=typeof e.attrs.target==`string`&&e.attrs.target.length>0?e.attrs.target:e.attrs.href??``,S=typeof e.attrs.anchor==`string`&&e.attrs.anchor.length>0?e.attrs.anchor:null,w=typeof e.attrs.alias==`string`&&e.attrs.alias.length>0?e.attrs.alias:null,E=w||(S?`${t}#${S}`:t);return{type:`wikiLinkEmbed`,value:E,data:{target:t,anchor:S,alias:w},children:[{type:`text`,value:E}]}}let w=e.attrs.linkStyle;if(w===`autolink`)return{type:`link`,url:e.attrs.href??``,title:null,children:S,data:{sourceStyle:`autolink`}};if(w===`gfm-autolink`)return{type:`link`,url:e.attrs.href??``,title:null,children:S,data:{sourceStyle:`gfm-autolink`}};if(w===`inline`||!w){let t={};e.attrs.sourceUrlForm===`angle-bracketed`&&(t.sourceUrlForm=`angle-bracketed`);let w=e.attrs.sourceTitleMarker;return(w===`single`||w===`double`||w===`paren`)&&(t.sourceTitleMarker=w),{type:`link`,url:e.attrs.href??``,title:e.attrs.title??null,children:S,...Object.keys(t).length>0?{data:t}:{}}}return{type:`linkReference`,identifier:(e.attrs.refLabel??``).toLowerCase(),label:e.attrs.refLabel,referenceType:w,children:S}}),E.escapeMark&&(S.escapeMark=(e,t,S)=>{for(let e of S)if(e.type===`text`&&e.value){let t=e;t.data=t.data??{},t.data.escapedChars=t.data.escapedChars??[];for(let e=0;e<t.value.length;e++)t.data.escapedChars.push({offset:e,char:t.value[e]})}return S.length===1?S[0]:S}),E.sourceLiteral&&(S.sourceLiteral=(e,t,S)=>{let w=typeof e.attrs.sourceRaw==`string`?e.attrs.sourceRaw:``;if(S.length===1&&S[0]?.type===`text`){let e=S[0],t=w||e.value;return isValidSourceLiteralRaw(t,e.value)&&(e.data=e.data??{},e.data.sourceRaw=t),e}return{type:`text`,value:S.filter(e=>e.type===`text`).map(e=>e.value??``).join(``)||w}}),{nodeHandlers:t,markHandlers:S}}const COMBINING_MARK_RE=/\p{M}+/gu,NON_LETTER_OR_NUMBER_RE=/[^\p{L}\p{N}]+/gu,EDGE_HYPHENS_RE=/^-+|-+$/g;function toWikiLinkSlug(e){return e.trim().normalize(`NFKD`).replace(COMBINING_MARK_RE,``).toLowerCase().replace(NON_LETTER_OR_NUMBER_RE,`-`).replace(EDGE_HYPHENS_RE,``)}function disambiguateSlug(e,t){let S=t.get(e)??0;return t.set(e,S+1),S===0?e:`${e}-${S}`}function getHeadingSlug(e,t){let S=toWikiLinkSlug(e);return S?disambiguateSlug(S,t):``}const MICROMARK_MDX_EXT=mdx(),FROM_MARKDOWN_MDX_EXT=mdxFromMarkdown(),TO_MARKDOWN_MDX_EXT=mdxToMarkdown(),PLACEHOLDER_BODY=`Body content here.`,PLACEHOLDER_MERMAID_FENCE_BODY=`graph LR
|
|
364
364
|
A --> B`;function getCanonicalDescriptors(){return builtInComponents.filter(e=>e.surface===`canonical`&&e.name!==`*`)}function getAgentCanonicalDescriptors(){return getCanonicalDescriptors().filter(e=>resolveKind(e)!==`fence`)}function resolveKind(e){return e.name===`MermaidFence`?`fence`:e.hasChildren?`jsx-block`:`jsx-void`}function projectLite(e){return{id:e.name,displayName:e.displayName??e.name,description:e.description??``,kind:resolveKind(e)}}function exampleValueFor(e){if(e.hidden!==!0&&e.type!==`reactnode`){if(`defaultValue`in e&&e.defaultValue!==void 0)return e.defaultValue;if(e.type===`enum`)return e.enumValues[0];if(e.type===`string`)return``;if(e.type===`number`)return 0;if(e.type===`boolean`)return!1}}function shouldEmitProp(e,t){return!(e.omitOnDefault===!0&&`defaultValue`in e&&Object.is(e.defaultValue,t)||e.type===`string`&&e.required===!1&&e.defaultValue===void 0&&t===``)}function buildAttributes(e){let t=[];for(let S of e.props){let e=exampleValueFor(S);e!==void 0&&shouldEmitProp(S,e)&&t.push(propToMdxJsxAttribute(S.name,e))}return t}function buildBodyChildren(e){return fromMarkdown(e.exampleBody&&e.exampleBody.trim().length>0?e.exampleBody:PLACEHOLDER_BODY,{extensions:[MICROMARK_MDX_EXT],mdastExtensions:[FROM_MARKDOWN_MDX_EXT]}).children}function synthesizeExample(e){let t=resolveKind(e),S;if(t===`fence`)S={type:`code`,lang:`mermaid`,meta:null,value:e.exampleBody&&e.exampleBody.trim().length>0?e.exampleBody:PLACEHOLDER_MERMAID_FENCE_BODY};else{let w=buildAttributes(e),E=t===`jsx-block`?buildBodyChildren(e):[];S={type:`mdxJsxFlowElement`,name:e.name,attributes:w,children:E}}return toMarkdown({type:`root`,children:[S]},{extensions:[TO_MARKDOWN_MDX_EXT]}).trimEnd()}function projectParams(e){let t=[];for(let S of e.props){if(S.hidden===!0)continue;let e={name:S.name,type:S.type,required:S.required};S.description!==void 0&&(e.description=S.description),S.advanced===!0&&(e.advanced=!0),S.omitOnDefault===!0&&(e.omitOnDefault=!0),S.type===`enum`&&(e.values=S.enumValues,S.defaultValue!==void 0&&(e.defaultValue=S.defaultValue)),S.type===`string`&&(S.defaultValue!==void 0&&(e.defaultValue=S.defaultValue),S.language!==void 0&&(e.language=S.language),S.accept!==void 0&&(e.accept=S.accept)),S.type===`boolean`&&S.defaultValue!==void 0&&(e.defaultValue=S.defaultValue),S.type===`number`&&S.defaultValue!==void 0&&(e.defaultValue=S.defaultValue),t.push(e)}return t}function projectFull(e){return{...projectLite(e),example:synthesizeExample(e),params:projectParams(e)}}function renderInventoryFooter(){return[``,"**Custom canonical components.** OK `.md` / `.mdx` supports the JSX components below — use whichever is semantically useful in any part of the doc. For full source syntax + parameter schemas, call `get_components({ ids })` with the ids you want to use. Fenced code blocks render naturally and don't need a fetch — including ` ```mermaid ` for diagrams and ` ```html preview ` for interactive HTML/JS/CSS pages (the fence info-string `preview` token renders the block as a live iframe; works for `html` / `htm` / `xml`; optional `h=` / `w=` tokens set size, e.g. ` ```html preview h=400px `). Use ` ```html preview ` whenever you want anything interactive or JS-powered (charts, demos, calculators, animations) — just author the standalone HTML page in the fence. Arbitrary `<TagName>` JSX falls through as raw MDX when no canonical fits.",``,...getAgentCanonicalDescriptors().map(projectLite).map(e=>`- \`${e.id}\` (${e.kind}) — ${e.description}`)].join(`
|
|
365
|
-
`)}const AgentWriteRequestSchema=object$1({docName:safeDocNameField,summary:summaryField,content:string$2().optional(),...agentIdentityFields}).loose(),AgentWriteMdRequestSchema=object$1({docName:safeDocNameField,summary:summaryField,markdown:string$2().min(1),position:_enum([`append`,`prepend`,`replace`]).optional(),...agentIdentityFields}).loose(),AgentPatchRequestSchema=object$1({docName:safeDocNameField,summary:summaryField,find:string$2().min(1),replace:string$2(),offset:number$1().int().nonnegative().optional(),...agentIdentityFields}).loose(),AgentUndoRequestSchema=object$1({docName:safeDocNameField,connectionId:string$2().min(1),scope:_enum([`last`,`session`,`file`]).optional(),...agentIdentityFields}).loose(),SummaryResponseFieldSchema=object$1({value:string$2(),truncatedFrom:number$1().int().nonnegative().optional(),hint:string$2().optional()}).loose(),OrphanHintSchema=object$1({type:literal(`orphan`),parentCandidates:array(string$2()),message:string$2()}).loose(),AgentWriteSuccessSchema=object$1({timestamp:string$2().min(1),summary:SummaryResponseFieldSchema.optional()}).loose(),AgentWriteMdSuccessSchema=object$1({timestamp:string$2().min(1),subscriberCount:number$1().int().nonnegative(),systemSubscriberCount:number$1().int().nonnegative(),hints:array(OrphanHintSchema).optional(),summary:SummaryResponseFieldSchema.optional()}).loose(),AgentPatchSuccessSchema=object$1({timestamp:string$2().min(1),subscriberCount:number$1().int().nonnegative(),systemSubscriberCount:number$1().int().nonnegative(),summary:SummaryResponseFieldSchema.optional()}).loose(),AgentUndoSuccessSchema=object$1({docName:string$2().min(1),scope:_enum([`last`,`session`]),undone:boolean$1()}).loose(),FrontmatterPatchRequestSchema=object$1({docName:safeDocNameField,patch:record(string$2(),union([FrontmatterValueSchema,_null()])),types:record(string$2(),_enum(FRONTMATTER_TYPES)).optional(),summary:summaryField,...agentIdentityFields}).loose(),FrontmatterPatchSuccessSchema=object$1({timestamp:string$2().min(1),subscriberCount:number$1().int().nonnegative(),systemSubscriberCount:number$1().int().nonnegative(),appliedKeys:array(string$2()),summary:SummaryResponseFieldSchema.optional()}).loose(),DocumentReadSuccessSchema=object$1({docName:string$2().min(1),content:string$2()}).loose(),DocumentListEntrySchema=object$1({kind:_enum([`document`,`asset`,`folder`]).default(`document`),docName:string$2().min(1).optional(),docExt:string$2().min(1).default(`.md`),size:number$1().int().nonnegative(),modified:string$2().min(1),isSymlink:boolean$1().default(!1),canonicalDocName:string$2().nullable().default(null),targetPath:string$2().nullable().default(null),path:string$2().min(1).optional(),assetExt:string$2().min(1).optional(),mediaKind:_enum([`image`,`video`,`audio`,`pdf`,`text`]).nullable().optional(),referencedBy:array(string$2().min(1)).optional()}).loose().refine(e=>e.kind===`document`?e.docName!==void 0&&e.path===void 0&&e.assetExt===void 0&&e.mediaKind===void 0&&e.referencedBy===void 0:e.kind===`folder`?e.docName===void 0&&e.path!==void 0&&e.assetExt===void 0&&e.mediaKind===void 0&&e.referencedBy===void 0:e.path!==void 0&&e.assetExt!==void 0&&e.referencedBy!==void 0,{message:`document/asset/folder kind must match its required fields (document → docName; asset → path+assetExt+referencedBy; folder → path only, no docName)`}),DocumentListSuccessSchema=object$1({documents:array(DocumentListEntrySchema)}).loose(),BacklinkEntrySchema=object$1({source:string$2().min(1),anchor:string$2().nullable(),title:string$2(),snippet:string$2().nullable()}).loose(),BacklinksSuccessSchema=object$1({docName:string$2().min(1),backlinks:array(BacklinkEntrySchema)}).loose(),BacklinkCountsSuccessSchema=object$1({counts:record(string$2().min(1),number$1().int().nonnegative())}).loose(),ForwardLinkDocEntrySchema=object$1({kind:literal(`doc`),docName:string$2().min(1),anchor:string$2().nullable(),title:string$2(),snippet:string$2().nullable()}).loose(),ForwardLinkExternalEntrySchema=object$1({kind:literal(`external`),url:string$2().min(1),title:string$2(),snippet:string$2().nullable()}).loose(),ForwardLinkEntrySchema=discriminatedUnion(`kind`,[ForwardLinkDocEntrySchema,ForwardLinkExternalEntrySchema]),ForwardLinksSuccessSchema=object$1({docName:string$2().min(1),forwardLinks:array(ForwardLinkEntrySchema)}).loose(),LinkGraphDocNodeSchema=object$1({id:string$2().min(1),kind:literal(`doc`),docName:string$2().min(1),anchor:string$2().nullable(),label:string$2(),cluster:string$2().nullable(),category:string$2().nullable(),tags:array(string$2()).nullable()}).loose(),LinkGraphExternalNodeSchema=object$1({id:string$2().min(1),kind:literal(`external`),url:string$2().min(1),label:string$2()}).loose(),LinkGraphNodeSchema=discriminatedUnion(`kind`,[LinkGraphDocNodeSchema,LinkGraphExternalNodeSchema]),LinkGraphEdgeSchema=object$1({source:string$2().min(1),target:string$2().min(1)}).loose(),LinkGraphSuccessSchema=object$1({nodes:array(LinkGraphNodeSchema),links:array(LinkGraphEdgeSchema)}).loose(),SaveVersionWriterSchema=object$1({id:string$2().min(1),name:string$2().optional(),email:string$2().optional()}).loose(),SaveVersionRequestSchema=object$1({writers:array(SaveVersionWriterSchema).optional(),...agentIdentityFields}).loose(),SaveVersionSuccessSchema=object$1({checkpointRef:string$2().min(1)}).loose(),HistoryShadowContributorSchema=object$1({v:number$1().int().optional(),id:string$2().min(1),name:string$2().min(1),colorSeed:string$2().optional(),docs:array(string$2()),summaries:array(string$2()).optional()}).loose(),HistoryEntrySchema=object$1({sha:string$2().min(1),timestamp:string$2().min(1),author:string$2(),authorEmail:string$2(),type:_enum([`checkpoint`,`wip`,`upstream`,`park`]),message:string$2(),contributors:array(HistoryShadowContributorSchema),checkpoint:unknown$2().nullable()}).loose(),HistorySuccessSchema=object$1({entries:array(HistoryEntrySchema),total:number$1().int().nonnegative().optional(),truncated:boolean$1().optional()}).loose(),HistoryVersionSuccessSchema=object$1({sha:string$2().regex(/^[0-9a-f]{40}$/i),content:string$2(),timestamp:string$2(),author:string$2()}).loose(),DiffLineSchema=object$1({type:_enum([`added`,`removed`,`unchanged`]),text:string$2()}).loose(),DiffSuccessSchema=object$1({lines:array(DiffLineSchema),additions:number$1().int().nonnegative(),deletions:number$1().int().nonnegative()}).loose(),WorkspaceSuccessSchema=object$1({contentDir:string$2().min(1),pathSeparator:_enum([`/`,`\\`]),symlinkResolved:boolean$1()}).loose(),RescueEntryFlatSchema=object$1({docName:string$2().min(1),timestamp:string$2().min(1),size:number$1().int().nonnegative(),source:literal(`flat`)}).loose(),RescueEntryTimelineSchema=object$1({docName:string$2().min(1),timestamp:string$2().min(1),source:literal(`timeline`),sha:string$2().min(1)}).loose(),RescueListSuccessSchema=array(discriminatedUnion(`source`,[RescueEntryFlatSchema,RescueEntryTimelineSchema])).meta({description:"Flat array of rescue buffer entries; discriminated via `source`."}),OrphanEntrySchema=object$1({docName:string$2().min(1),title:string$2()}).loose(),OrphansSuccessSchema=object$1({orphans:array(OrphanEntrySchema)}).loose(),HubEntrySchema=object$1({docName:string$2().min(1),title:string$2(),count:number$1().int().nonnegative()}).loose(),HubsSuccessSchema=object$1({hubs:array(HubEntrySchema)}).loose(),DeadLinkSourceSchema=object$1({source:string$2().min(1),title:string$2(),snippet:string$2().nullable()}).loose(),DeadLinkEntrySchema=object$1({target:string$2().min(1),sources:array(DeadLinkSourceSchema)}).loose(),DeadLinksSuccessSchema=object$1({deadLinks:array(DeadLinkEntrySchema)}).loose(),SuggestLinksTargetSchema=object$1({docName:string$2().min(1),title:string$2(),aliases:array(string$2())}).loose(),SuggestLinksMentionSchema=object$1({source:string$2().min(1),excerpt:string$2(),offset:number$1().int().nonnegative()}).loose(),SuggestLinksSuccessSchema=object$1({target:SuggestLinksTargetSchema,mentions:array(SuggestLinksMentionSchema),truncated:boolean$1()}).loose(),LocalOpOpenRequestSchema=object$1({dir:string$2().min(1)}).loose(),LocalOpOpenSuccessSchema=object$1({port:number$1().int().positive()}).loose(),LocalOpAuthHostRequestSchema=object$1({host:string$2().min(1).optional()}).loose(),LocalOpAuthPatRequestSchema=object$1({pat:string$2().min(1),host:string$2().min(1).optional()}).loose(),LocalOpAuthSetIdentityRequestSchema=object$1({name:string$2().refine(e=>e.trim().length>0,{message:`name must be non-empty`}),email:string$2().refine(e=>e.trim().length>0,{message:`email must be non-empty`})}).loose(),LocalOpAuthIdentitySchema=object$1({name:string$2().min(1),email:string$2().min(1)}).loose().nullable(),LocalOpAuthIdentitySuccessSchema=object$1({identity:LocalOpAuthIdentitySchema}).loose(),LocalOpAuthStatusSuccessSchema=object$1({authenticated:boolean$1()}).loose(),LocalOpAuthPatSuccessSchema=object$1({type:literal(`complete`).optional(),login:string$2().min(1).optional()}).loose(),LocalOpAuthEmptySuccessSchema=object$1({}).loose(),ActivityBurstSchema=object$1({stackIndex:number$1().int().min(0),ts:number$1().int().min(0),additions:number$1().int().min(0),deletions:number$1().int().min(0)}).loose(),ActivityFileSchema=object$1({docName:string$2().min(1),additionsTotal:number$1().int().min(0),deletionsTotal:number$1().int().min(0),lastTs:number$1().int().min(0),bursts:array(ActivityBurstSchema)}).loose(),ActivityAgentHeaderSchema=object$1({displayName:string$2().min(1),color:string$2().min(1),icon:string$2().optional(),connectionId:string$2().min(1)}).loose(),AgentActivitySuccessSchema=object$1({sessionAlive:boolean$1(),agent:ActivityAgentHeaderSchema.nullable(),files:array(ActivityFileSchema)}).loose(),AgentBurstDiffSuccessSchema=object$1({diff:string$2(),generatedAt:number$1().int().min(0)}).loose(),TestResetSuccessSchema=object$1({}).loose(),TestRescanBacklinksSuccessSchema=object$1({}).loose(),TestRescanFilesSuccessSchema=object$1({}).loose(),MetricsReconciliationSuccessSchema=object$1({}).loose(),MetricsParseHealthSuccessSchema=object$1({}).loose(),AgentPresenceEntrySchema=object$1({displayName:string$2().min(1),icon:string$2(),color:string$2().min(1),currentDoc:string$2().nullable(),mode:_enum([`idle`,`writing`]),ts:number$1().int().min(0)}).loose(),MetricsAgentPresenceSuccessSchema=object$1({presence:record(string$2().min(1),AgentPresenceEntrySchema)}).loose(),InstalledAgentsSuccessSchema=record(string$2().min(1),boolean$1()).meta({description:`Flat boolean record keyed by agent-scheme name (claude / codex / cursor). True = installed.`}),SpawnCursorRequestSchema=object$1({path:string$2().min(1,`path must be non-empty`)}).loose(),SpawnCursorSuccessSchema=object$1({}).loose(),RenamedDocMappingSchema=object$1({fromDocName:string$2().min(1),toDocName:string$2().min(1)}).loose(),EmptyRequestSchema=object$1({}).loose(),CreatePageRequestSchema=object$1({path:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),CreatePageSuccessSchema=object$1({docName:string$2().min(1)}).loose(),CreateFolderRequestSchema=object$1({path:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),CreateFolderSuccessSchema=object$1({path:string$2().min(1)}).loose(),DuplicatePathRequestSchema=object$1({kind:_enum([`file`,`folder`]),path:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),DuplicatePathSuccessSchema=object$1({kind:_enum([`file`,`folder`]),path:string$2().min(1),duplicatedDocNames:array(string$2().min(1))}).loose(),PageEntrySchema=object$1({docName:string$2().min(1),title:string$2(),docExt:string$2().min(1),size:number$1().int().nonnegative(),modified:string$2().min(1)}).loose(),PagesSuccessSchema=object$1({pages:array(PageEntrySchema)}).loose(),HeadingEntrySchema=object$1({level:number$1().int().min(1).max(6),text:string$2(),slug:string$2()}).loose(),PageHeadingsSuccessSchema=object$1({docName:string$2().min(1),headings:array(HeadingEntrySchema)}).loose(),RenameRequestSchema=object$1({docName:string$2().min(1),newDocName:string$2().min(1),summary:summaryField,...agentIdentityFields}).loose(),RenameRewrittenDocSchema=object$1({docName:string$2().min(1),rewrites:number$1().int().nonnegative()}).loose(),RenameSuccessSchema=object$1({renamed:array(RenamedDocMappingSchema),rewrittenDocs:array(RenameRewrittenDocSchema),summary:SummaryResponseFieldSchema.optional()}).loose(),RenamePathRequestSchema=object$1({kind:_enum([`file`,`folder`]),fromPath:string$2().min(1),toPath:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),RenamePathSuccessSchema=object$1({renamed:array(RenamedDocMappingSchema),rewrittenDocs:array(RenameRewrittenDocSchema).optional(),summary:SummaryResponseFieldSchema.optional()}).loose(),DeletePathRequestSchema=object$1({kind:_enum([`file`,`folder`]),path:string$2().min(1),...agentIdentityFields}).loose(),DeletePathSuccessSchema=object$1({deletedDocNames:array(string$2().min(1))}).loose(),TrashCleanupRequestSchema=object$1({kind:_enum([`file`,`folder`]),path:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),TrashCleanupSuccessSchema=object$1({deletedDocNames:array(string$2().min(1))}).loose(),RollbackRequestSchema=object$1({docName:string$2().min(1),commitSha:string$2().regex(/^[0-9a-f]{40}$/i,{message:`commitSha must be a 40-char git SHA`}),summary:summaryField,...agentIdentityFields}).loose(),RollbackSuccessSchema=object$1({restoredFrom:string$2().min(1),timestamp:string$2().min(1),summary:SummaryResponseFieldSchema.optional()}).loose(),ShareConstructUrlRequestSchema=object$1({docPath:string$2().min(1)}).loose(),ShareConstructUrlErrorCodeSchema=_enum([`no-remote`,`detached-head`,`branch-not-on-origin`,`non-github-remote`,`invalid-path`]),ShareConstructUrlResponseSchema=discriminatedUnion(`ok`,[object$1({ok:literal(!0),shareUrl:string$2().min(1),blobUrl:string$2().min(1),branch:string$2().min(1)}).loose(),object$1({ok:literal(!1),error:ShareConstructUrlErrorCodeSchema,branch:string$2().min(1).optional()}).loose()]),SharePublishOwnerKindSchema=_enum([`user`,`org`]),SharePublishOwnerSchema=object$1({login:string$2().min(1),kind:SharePublishOwnerKindSchema,avatarUrl:string$2().optional()}).loose(),SharePublishOwnersErrorCodeSchema=_enum([`auth-required`,`network`]),SharePublishOwnersResponseSchema=discriminatedUnion(`ok`,[object$1({ok:literal(!0),owners:array(SharePublishOwnerSchema)}).loose(),object$1({ok:literal(!1),error:SharePublishOwnersErrorCodeSchema}).loose()]),SharePublishNameCheckResponseSchema=discriminatedUnion(`ok`,[object$1({ok:literal(!0),available:boolean$1()}).loose(),object$1({ok:literal(!1),error:SharePublishOwnersErrorCodeSchema}).loose()]),SharePublishVisibilitySchema=_enum([`public`,`private`]),SharePublishRequestSchema=object$1({owner:string$2().min(1),name:string$2().min(1),visibility:SharePublishVisibilitySchema,description:string$2().optional()}).loose(),SharePublishErrorCodeSchema=_enum([`name-conflict`,`saml-sso`,`auth-required`,`push-failed`,`init-failed`,`network`,`no-project`]),SharePublishResponseSchema=discriminatedUnion(`ok`,[object$1({ok:literal(!0),ownerLogin:string$2().min(1),repoName:string$2().min(1),cloneUrl:string$2().min(1),defaultBranch:string$2().min(1)}).loose(),object$1({ok:literal(!1),error:SharePublishErrorCodeSchema}).loose()]),SyncStateSchema=_enum([`dormant`,`idle`,`fetching`,`pulling`,`pushing`,`conflict`,`offline`,`auth-error`,`disabled`]),SyncStatusSchema=object$1({state:SyncStateSchema,lastSyncUtc:string$2().nullable(),lastFetchUtc:string$2().nullable(),lastPushedSha:string$2().nullable(),ahead:number$1().int().min(0),behind:number$1().int().min(0),consecutiveFailures:number$1().int().min(0),conflictCount:number$1().int().min(0),hasRemote:boolean$1(),syncEnabled:boolean$1(),identityUnresolved:boolean$1(),error:string$2().optional(),pausedReason:string$2().optional()}).loose(),SyncTriggerRequestSchema=object$1({op:_enum([`sync`,`push`,`pull`]).optional()}).loose(),SyncTriggerSuccessSchema=object$1({op:_enum([`sync`,`push`,`pull`])}).loose(),ConflictEntrySchema=object$1({file:string$2().min(1),detectedAt:string$2().min(1),oursSha:string$2().optional(),theirsSha:string$2().optional(),baseSha:string$2().optional()}).loose(),SyncConflictsSuccessSchema=object$1({conflicts:array(ConflictEntrySchema)}).loose(),SyncResolveConflictRequestSchema=object$1({file:string$2().min(1),strategy:_enum([`mine`,`theirs`,`content`]),content:string$2().optional()}).loose().refine(e=>e.strategy!==`content`||e.content!==void 0,{message:`content is required when strategy is 'content'`,path:[`content`]}),SyncResolveConflictSuccessSchema=object$1({}).loose(),SyncConflictContentSuccessSchema=object$1({file:string$2().min(1),base:string$2(),ours:string$2(),theirs:string$2()}).loose(),SyncAbortMergeSuccessSchema=object$1({}).loose(),SeedPlanSuccessSchema=object$1({plan:custom(e=>e!==void 0,{message:`plan is required`})}).loose(),SeedApplyRequestSchema=object$1({plan:custom(e=>e!==void 0,{message:`plan is required`})}).loose(),SeedApplySuccessSchema=object$1({result:custom(e=>e!==void 0,{message:`result is required`})}).loose(),SeedPackFolderInfoSchema=object$1({path:string$2().min(1),summary:string$2().min(1)}).loose(),SeedPackEntryCountsSchema=object$1({files:number$1().int().nonnegative(),folders:number$1().int().nonnegative()}).loose(),SeedPackInfoSchema=object$1({id:string$2().min(1),name:string$2().min(1),description:string$2().min(1),defaultSubfolder:string$2().optional(),folders:array(SeedPackFolderInfoSchema),entryCounts:SeedPackEntryCountsSchema}).loose(),SeedListPacksSuccessSchema=object$1({packs:array(SeedPackInfoSchema)}).loose(),InstallSkillRequestSchema=object$1({noOpen:boolean$1().optional(),out:string$2().min(1).optional()}).loose(),InstallSkillHandoffErrorSchema=object$1({reason:_enum([`unsupported-platform`,`spawn-error`]),message:string$2()}).loose(),InstallSkillSuccessSchema=discriminatedUnion(`status`,[object$1({status:literal(`installed`),outputPath:string$2(),size:number$1().int().nonnegative(),sha256:string$2(),skillVersion:string$2()}).loose(),object$1({status:literal(`built`),outputPath:string$2(),size:number$1().int().nonnegative(),sha256:string$2(),skillVersion:string$2(),handoffError:InstallSkillHandoffErrorSchema.optional()}).loose(),object$1({status:literal(`failed`),buildError:string$2()}).loose(),object$1({status:literal(`skip-current`),skillVersion:string$2(),recordedAt:string$2().optional()}).loose()]),TagSummaryEntrySchema=object$1({name:string$2().min(1),count:number$1().int().nonnegative(),isLeaf:boolean$1()}).loose(),TagsListSuccessSchema=object$1({tags:array(TagSummaryEntrySchema)}).loose(),TagsDocEntrySchema=object$1({docName:string$2().min(1),title:string$2(),matchingTags:array(string$2().min(1)),snippet:string$2().nullable()}).loose(),TagsForNameSuccessSchema=object$1({name:string$2().min(1),docs:array(TagsDocEntrySchema)}).loose(),FolderConfigGetSuccessSchema=object$1({folder:unknown$2(),frontmatter_local:record(string$2(),unknown$2()).nullable()}).loose(),FolderConfigPutRequestSchema=object$1({path:string$2(),frontmatter:record(string$2(),unknown$2()).optional()}).loose(),FolderConfigPutSuccessSchema=object$1({applied:unknown$2()}).loose(),TemplateFrontmatterSchema=record(string$2(),unknown$2()).meta({description:`Free-form frontmatter map embedded in template payloads.`}),TemplatePayloadSchema=object$1({name:string$2().min(1),folder:string$2(),scope:_enum([`local`,`inherited`]),path:string$2().min(1),frontmatter:TemplateFrontmatterSchema,body:string$2()}).strict(),TemplateGetSuccessSchema=object$1({template:TemplatePayloadSchema}).strict(),TemplatePutRequestSchema=object$1({folder:string$2(),name:string$2(),body:string$2().optional(),frontmatter:TemplateFrontmatterSchema.optional()}).strict(),TemplatePutSuccessSchema=object$1({path:string$2().min(1),created:boolean$1(),warnings:array(string$2())}).strict(),TemplateDeleteSuccessSchema=object$1({existed:boolean$1(),path:string$2().min(1)}).strict(),SearchRequestSchema=object$1({query:string$2().optional(),intent:_enum([`autocomplete`,`full_text`,`omnibar`]).optional(),scopes:array(_enum([`page`,`folder`,`content`])).optional(),scope:string$2().optional(),limit:number$1().int().nonnegative().optional()}).loose(),SearchResultEntrySchema=object$1({kind:_enum([`page`,`folder`,`content`]),path:string$2().min(1),title:string$2(),score:number$1(),signals:record(string$2(),unknown$2()),snippet:string$2().optional()}).loose(),SearchSuccessSchema=object$1({query:string$2(),intent:_enum([`autocomplete`,`full_text`,`omnibar`]),results:array(SearchResultEntrySchema),elapsedMs:number$1().nonnegative()}).loose(),SkillInstallTargetStateSchema=object$1({version:string$2().min(1),recordedAt:string$2().min(1)}).loose(),SkillInstallStateSuccessSchema=object$1({currentVersion:string$2().min(1),targets:record(string$2(),SkillInstallTargetStateSchema.nullable())}).loose(),CC1_CHANNEL_SERVER_INFO=`server-info`,CC1_CHANNEL_BRANCH_SWITCHED=`branch-switched`,CC1_CHANNEL_DISK_ACK=`disk-ack`,CC1_CHANNEL_CONFIG_VALIDATION_REJECTED=`config-validation-rejected`,CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR=`config-ignore-nested-error`,DerivedViewChannelSchema=_enum([`files`,`backlinks`,`graph`,`sync-status`,`session-activity`,`tags`]),CC1ServerInfoPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_SERVER_INFO),seq:number$1(),serverInstanceId:string$2().min(1),currentBranch:string$2().min(1).optional()}).loose(),CC1BranchSwitchedPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_BRANCH_SWITCHED),seq:number$1(),branch:string$2().min(1)}).loose(),CC1DerivedViewPayloadSchema=object$1({v:literal(1),ch:DerivedViewChannelSchema,seq:number$1()}).loose(),CC1DiskAckPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_DISK_ACK),seq:number$1(),docName:string$2().min(1),sv:string$2().min(1)}).loose(),CC1ConfigValidationRejectedPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_CONFIG_VALIDATION_REJECTED),seq:number$1(),docName:string$2().min(1),error:ConfigValidationErrorSchema}).loose(),CC1ConfigIgnoreNestedErrorPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR),seq:number$1(),path:string$2().min(1),error:string$2().min(1)}).loose(),WORKSPACE_SEARCH_SCHEMA={id:`string`,kind:`enum`,path:`string`,title:`string`,name:`string`,pathSegments:`string`,content:`string`,modifiedTs:`number`},workspaceSearchIndexes=new WeakMap;function clampLimit(e){return e===void 0||!Number.isFinite(e)?20:Math.max(1,Math.min(100,Math.trunc(e)))}function normalize$2(e){return e.trim().toLowerCase()}function workspaceSearchBasename(e){let t=e.split(`/`).filter(Boolean);return t[t.length-1]??e}function workspaceSearchPathSegments(e){return e.split(`/`).filter(Boolean).join(` `)}function createWorkspaceSearchDocument(e){let t=workspaceSearchBasename(e.path),S=e.title?.trim()||t,w=e.modifiedTs??0;return{id:`${e.kind}:${e.path}`,kind:e.kind,path:e.path,title:S,name:t,pathSegments:workspaceSearchPathSegments(e.path),content:e.content??``,modifiedTs:Number.isFinite(w)?w:0}}function createWorkspaceSearchIndex(e){let t=create$9({schema:WORKSPACE_SEARCH_SCHEMA});return e.length>0&&insertMultiple(t,e),t}function createWorkspaceSearchCorpus(e){let t={documents:e};return workspaceSearchIndexes.set(t,createWorkspaceSearchIndex(e)),t}function getWorkspaceSearchIndex(e){let t=workspaceSearchIndexes.get(e);if(t)return t;let S=createWorkspaceSearchIndex(e.documents);return workspaceSearchIndexes.set(e,S),S}function defaultScopes(e){return e===`autocomplete`?[`page`]:e===`full_text`?[`page`,`content`]:[`page`,`folder`]}function scopeAllows(e,t){return t.has(e.kind)?!0:e.kind===`page`&&t.has(`content`)}function lexicalScore(e,t){let S=normalize$2(t);if(!S)return 0;let w=normalize$2(e.title),E=normalize$2(e.name),D=normalize$2(e.path),O=D.split(`/`);return w===S||E===S?700:D===S?650:w.startsWith(S)||E.startsWith(S)?600:O.some(e=>e.startsWith(S))?550:w.includes(S)||E.includes(S)?500:D.includes(S)?450:-1}function recencyScores(e){let t=e.map(e=>e.modifiedTs).filter(e=>Number.isFinite(e)&&e>0);if(t.length===0)return new Map;let S=1/0,w=-1/0;for(let e of t)e<S&&(S=e),e>w&&(w=e);let E=Math.max(1,w-S);return new Map(e.map(e=>[e.id,e.modifiedTs>0?(e.modifiedTs-S)/E*50:0]))}function searchProperties(e){return e===`full_text`?[`title`,`name`,`path`,`pathSegments`,`content`]:[`title`,`name`,`path`,`pathSegments`]}function searchBoost(e){return e===`full_text`?{title:8,name:7,path:5,pathSegments:4,content:1}:e===`autocomplete`?{title:10,name:9,path:5,pathSegments:4}:{title:8,name:7,path:5,pathSegments:4}}function toleranceFor(e,t){return normalize$2(t).length<4?0:e===`full_text`?1:0}function searchWorkspaceCorpus(e,t,S={}){let w=S.intent??`omnibar`,E=clampLimit(S.limit),D=new Set(S.scopes??defaultScopes(w)),O=e.documents.filter(e=>scopeAllows(e,D)),k=normalize$2(t);if(!k)return O.slice().sort((e,t)=>e.path.localeCompare(t.path)).slice(0,E).map(e=>({document:e,score:0,signals:{lexical:0,fullText:0,recency:0}}));let j=search(getWorkspaceSearchIndex(e),{term:k,properties:searchProperties(w),boost:searchBoost(w),tolerance:toleranceFor(w,k),limit:Math.max(E*4,40)}),F=new Map(j.hits.filter(e=>scopeAllows(e.document,D)).map(e=>[e.document.id,e.score])),L=recencyScores(O),B=new Map;for(let e of O)lexicalScore(e,k)>=0&&B.set(e.id,e);for(let e of j.hits)scopeAllows(e.document,D)&&B.set(e.document.id,e.document);return[...B.values()].map(e=>{let t=Math.max(0,lexicalScore(e,k)),S=F.get(e.id)??0,w=L.get(e.id)??0;return{document:e,score:t+S*20+w,signals:{lexical:t,fullText:S,recency:w}}}).sort((e,t)=>e.score===t.score?e.document.path.localeCompare(t.document.path):t.score-e.score).slice(0,E)}const SHARE_URL_VERSION_V1=1;function encodeShareUrl(e){let t=new TextEncoder().encode(e),S=new Uint8Array(1+t.length);return S[0]=SHARE_URL_VERSION_V1,S.set(t,1),uint8ArrayToBase64Url(S)}function uint8ArrayToBase64Url(e){let t=``;for(let S=0;S<e.length;S++)t+=String.fromCharCode(e[S]);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}const SINGLETON_KEY=Symbol.for(`@inkeep/open-knowledge/skill-state-field-registry`),g=globalThis;g[SINGLETON_KEY]===void 0&&(g[SINGLETON_KEY]=registry$1());const skillStateFieldRegistry=g[SINGLETON_KEY],SKILL_STATE_FILENAME=`skill-state.yml`,SKILL_STATE_REL=[`.ok`,SKILL_STATE_FILENAME],SKILL_STATE_TARGETS=[`claude-cowork`,`cli-hosts`],SKILL_STATE_SURFACES=[`server-build-and-open`,`electron-build-and-open`,`cli-npx-skills-add`,`desktop-direct`],SKILL_STATE_VERSION_RE=/^\d+\.\d+\.\d+(?:[-+][\w.-]+)?$/,TargetEntrySchema=looseObject({version:string$2().regex(SKILL_STATE_VERSION_RE,`version must match /^\\d+\\.\\d+\\.\\d+(?:[-+][\\w.-]+)?$/`).register(skillStateFieldRegistry,{description:`Recorded skill version for this target.`}),recordedAt:datetime().register(skillStateFieldRegistry,{description:`ISO 8601 timestamp of the most recent successful write. Updated on every write, including reinstalls of the same version.`}),surface:_enum(SKILL_STATE_SURFACES).register(skillStateFieldRegistry,{description:`Install-source surface that recorded this entry.`}).optional()}),SkillStateSchema=looseObject({schema:literal(1).register(skillStateFieldRegistry,{description:`Schema major version. Bumped only on breaking shape changes.`}),targets:looseObject({"claude-cowork":TargetEntrySchema.optional(),"cli-hosts":TargetEntrySchema.optional()}).register(skillStateFieldRegistry,{description:`Per-target install-state entries. Absent target = no recorded install.`}).default({})});function emptySkillState(){return{schema:1,targets:{}}}function createCodeFenceTracker(){let e=!1,t=``,S=0;return w=>{let E=parseCodeFenceLine(w);return e?(E&&E.char===t&&E.len>=S&&!E.hasInfo&&(e=!1,t=``,S=0),!0):E?(e=!0,t=E.char,S=E.len,!0):!1}}function parseCodeFenceLine(e){let t=(e.endsWith(`\r`)?e.slice(0,-1):e).match(/^ {0,3}([`~])(\1{2,})(.*)$/);return t?{char:t[1],len:1+t[2].length,hasInfo:t[3].trim()!==``}:null}const AGENT_COLORS=[`#D97757`,`#1B1912`,`#F9F3E9`,`#7A9DFF`,`#8534F3`,`#9663F0`,`#727CF3`],AGENT_ICON_COLORS={claude:`#D97757`,cursor:`#1B1912`,windsurf:`#0B100F`,openai:`#7A9DFF`,github:`#8534F3`,cline:`#9663F0`,bot:`#727CF3`};function colorFromSeed(e,t=AGENT_COLORS){let S=0;for(let t of e)S=(S<<5)-S+t.charCodeAt(0)|0;return t[Math.abs(S)%t.length]}const ICON_MAP={"claude-code":`claude`,"claude-ai":`claude`,cursor:`cursor`,"cursor-vscode":`cursor`,cascade:`windsurf`,codex:`openai`,"codex-mcp-client":`openai`,copilot:`github`,cline:`cline`};function iconFromClientName(e){return e?ICON_MAP[e]??`bot`:`bot`}function resolveInternalHref(e,t){let S=e.trim();if(!S||/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(S)||S.startsWith(`//`)||S.startsWith(`/`)||S.startsWith(`#`))return null;let w=S.indexOf(`#`),E=w>=0?S.slice(0,w):S,D=w>=0?S.slice(w+1):null,O=(E.split(`?`)[0]??``).trim();if(!O)return null;let k=(O.split(`/`).pop()??``).match(/\.([a-z0-9]+)$/i);if(k){let e=(k[1]??``).toLowerCase();if(e!==`md`&&e!==`mdx`)return null}let j=O.toLowerCase(),F=j.endsWith(`.mdx`)?O.slice(0,-4):j.endsWith(`.md`)?O.slice(0,-3):O,L=t.includes(`/`)?t.split(`/`).slice(0,-1):[];for(let e of F.split(`/`))if(e===`..`){if(L.length===0)return null;L.pop()}else e!==`.`&&e!==``&&L.push(e);return L.length===0?null:{docName:L.join(`/`),anchor:D||null}}const URI_SCHEME_RE=/^[a-zA-Z][a-zA-Z\d+\-.]*:/;function extractAssetExtension(e){let t=(e.split(/[?#]/)[0]??e).match(/\.([a-z0-9]+)$/i);return t?(t[1]??``).toLowerCase():null}function isExternalHref(e){let t=e.trim();return URI_SCHEME_RE.test(t)||t.startsWith(`//`)}function classifyMarkdownHref(e,t){let S=e.trim();if(!S)return null;if(S.startsWith(`#`)){let e=S.slice(1).trim();return e?{kind:`anchor`,anchor:e}:null}let w=resolveInternalHref(S,t);if(w)return{kind:`doc`,docName:w.docName,anchor:w.anchor};if(isExternalHref(S)||S.startsWith(`/`))return{kind:`external`,url:S};let E=extractAssetExtension(S);return E&&E!==`md`&&E!==`mdx`?{kind:`asset`,url:S,ext:E}:null}function classifyWikiLinkTarget(e,t){let S=e.trim();if(!S)return null;if(isExternalHref(S))return{kind:`external`,url:t?`${S}#${t}`:S};let w=extractAssetExtension(S);return w&&w!==`md`&&w!==`mdx`?{kind:`asset`,url:S,ext:w}:{kind:`doc`,docName:S,anchor:t?.trim()||null}}function resolveAssetProjectPath(e,t){let S=e.trim();if(!S||URI_SCHEME_RE.test(S)||S.startsWith(`//`)||S.startsWith(`#`))return null;let w=S.indexOf(`#`),E=((w>=0?S.slice(0,w):S).split(`?`)[0]??``).trim();if(!E)return null;let D=E.startsWith(`/`),O=D?E.slice(1):E,k=D?[]:t.includes(`/`)?t.split(`/`).slice(0,-1):[];for(let e of O.split(`/`))if(e===`..`){if(k.length===0)return null;k.pop()}else e!==`.`&&e!==``&&k.push(e);return k.length===0?null:k.join(`/`)}function normalizePath(e){let t=e;return t.startsWith(`./`)&&(t=t.slice(2)),t.startsWith(`/`)&&(t=t.slice(1)),t}function basenameOf(e){let t=e.lastIndexOf(`/`);return t===-1?e:e.slice(t+1)}function dirnameOf(e){let t=e.lastIndexOf(`/`);return t===-1?``:e.slice(0,t)}function splitSegments(e){return e.split(`/`).filter(e=>e!==``)}function isInSubtree(e,t){let S=dirnameOf(t);return e===``||S===e?!0:S.startsWith(`${e}/`)}function depthInSubtree(e,t){let S=dirnameOf(t);if(e===S)return 0;let w=e===``?S:S.slice(e.length+1);return w===``?0:splitSegments(w).length}function relativeHops(e,t){let S=splitSegments(e),w=splitSegments(t),E=0;for(;E<S.length&&E<w.length&&S[E]===w[E];)E++;return S.length-E+(w.length-E)}function createBasenameIndex(){let e=new Map;function t(t){let S=normalizePath(t);if(S===``)return;let w=basenameOf(S);if(w===``)return;let E=w.toLowerCase(),D=e.get(E);if(!D){e.set(E,[S]);return}D.includes(S)||D.push(S)}function S(t){let S=normalizePath(t),w=basenameOf(S).toLowerCase(),E=e.get(w);if(!E)return;let D=E.indexOf(S);D!==-1&&(E.splice(D,1),E.length===0&&e.delete(w))}function w(e,w){S(e),t(w)}function E(t,S){let w=t.toLowerCase(),E=e.get(w);if(!E||E.length===0)return null;if(E.length===1)return E[0];let D=dirnameOf(normalizePath(S)),O=[],k=[];for(let e of E)isInSubtree(D,e)?O.push(e):k.push(e);return O.length>0?(e=>{let t=e[0],S=depthInSubtree(D,t);for(let w=1;w<e.length;w++){let E=e[w],O=depthInSubtree(D,E);(O<S||O===S&&E<t)&&(t=E,S=O)}return t})(O):(e=>{let t=e[0],S=relativeHops(D,dirnameOf(t));for(let w=1;w<e.length;w++){let E=e[w],O=relativeHops(D,dirnameOf(E));(O<S||O===S&&E<t)&&(t=E,S=O)}return t})(k)}function D(){let t=new Map;for(let[S,w]of e)t.set(S,[...w]);return t}function O(){e.clear()}return{add:t,remove:S,rename:w,resolveEmbed:E,clear:O,snapshot:D,size:()=>e.size}}const TAG_HIERARCHY_SEPARATOR=`/`;function expandTagToHierarchy(e){if(!e)return[];let t=e.split(TAG_HIERARCHY_SEPARATOR),S=[],w=``;for(let e of t)w=w?`${w}${TAG_HIERARCHY_SEPARATOR}${e}`:e,S.push(w);return S}function tagsMatchingPrefix(e,t){if(e.size===0)return new Set;if(t===``)return new Set(e);let S=new Set,w=`${t}${TAG_HIERARCHY_SEPARATOR}`;for(let E of e)(E===t||E.startsWith(w))&&S.add(E);return S}const WRITER_ID_RE=/^(agent-[^/]+|principal-[^/]+|file-system|git-upstream|openknowledge-service)$/;function classifyGitEntry(e,t,S){let w;try{w=statSync(e)}catch(t){let S=t.code;return S===`ENOENT`||S===`ENOTDIR`?{kind:`absent`}:{kind:`inaccessible`,gitPath:e,cause:t}}let E=computeProjectSubPath(t,S);if(w.isDirectory())return{kind:`directory`,path:e,projectSubPath:E};if(w.isFile()){let S;try{S=readFileSync(e,`utf-8`).trim()}catch(t){return{kind:`malformed-pointer`,gitPath:e,target:``,cause:t}}let w=S.match(/^gitdir:\s*(.+)$/);return w?{kind:`linked`,path:resolve(t,w[1]),gitPath:e,projectSubPath:E}:{kind:`malformed-pointer`,gitPath:e,target:``}}return{kind:`absent`}}function computeProjectSubPath(e,t){let S=relative(e,t);return S===``||S===`.`||S.startsWith(`..`)||isAbsolute(S)?``:S}function findAncestorGitEntry(e){let t=homedir(),S=resolve(e),w=64;for(let e=0;e<64;e++){if(S===t)return null;let e=dirname(S);if(e===S||e===t)return null;let w=resolve(e,`.git`);try{let t=statSync(w);if(t.isDirectory()||t.isFile())return{gitPath:w,workTreeRoot:e}}catch(e){let t=e.code;t!==`ENOENT`&&t!==`ENOTDIR`&&console.warn(`[shadow-repo-layout] Cannot stat ${w} (${t??`unknown`}); skipping ancestor`)}S=e}return null}function resolveGitDirDetailed(e){let t=resolve(e),S=classifyGitEntry(resolve(t,`.git`),t,t);if(S.kind!==`absent`)return S;let w=findAncestorGitEntry(t);return w===null?{kind:`absent`}:classifyGitEntry(w.gitPath,w.workTreeRoot,t)}function resolveGitDir(e){let t=resolveGitDirDetailed(e);return t.kind===`directory`||t.kind===`linked`?t.path:null}function resolveShadowDir(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return resolve(t.path,shadowSubdirName(t.projectSubPath));case`linked`:if(!existsSync(t.path))throw new MalformedGitPointerError(t.gitPath,t.path);return resolve(t.path,shadowSubdirName(t.projectSubPath));case`malformed-pointer`:throw new MalformedGitPointerError(t.gitPath,t.target,{cause:t.cause});case`inaccessible`:throw new GitDirAccessError(t.gitPath,{cause:t.cause});case`absent`:return resolve(e,`.git/ok`)}}function shadowSubdirName(e){return e===``?`ok`:`ok-${slugifyShadowSubPath(e)}`}function slugifyShadowSubPath(e){let t=e.split(sep).join(`-`).replace(/\/+/g,`-`).replace(/[^A-Za-z0-9._-]/g,`_`).replace(/^\.+/,`_`),S=64;if(t.length<=64)return t||`sub`;let w=djb2(e).toString(16).padStart(8,`0`);return`${t.slice(0,55)}-${w}`}function djb2(e){let t=5381;for(let S=0;S<e.length;S++)t=t*33+e.charCodeAt(S)>>>0;return t}var MalformedGitPointerError=class extends Error{gitPointerPath;resolvedTarget;constructor(e,t,S){let w=t?`references a missing or unreadable gitdir at ${t}`:`is unreadable or has no valid gitdir: pointer`;super(`\`.git\` pointer at ${e} ${w}. Run \`git worktree prune\` from the source repo and try again.`,S),this.name=`MalformedGitPointerError`,this.gitPointerPath=e,this.resolvedTarget=t}},GitDirAccessError=class extends Error{gitPath;constructor(e,t){let S=t?.cause!==void 0&&t.cause!==null&&typeof t.cause==`object`&&`code`in t.cause&&typeof t.cause.code==`string`?` (${t.cause.code})`:``;super(`Cannot access \`.git\` at ${e}${S}. Check filesystem permissions and that the volume is mounted.`,t),this.name=`GitDirAccessError`,this.gitPath=e}};function getShadowRepoPath(e){let t;try{t=resolveShadowDir(e)}catch(e){if(e instanceof MalformedGitPointerError||e instanceof GitDirAccessError)return null;throw e}return existsSync(resolve(t,`HEAD`))?t:null}function getWipRefPattern(e){return`refs/wip/${e}/`}const OK_CONTRIBUTORS_PREFIX=`ok-contributors: `;function parseContributors(e){if(!e)return[];let t=[];for(let S of e.split(`
|
|
365
|
+
`)}const AgentWriteRequestSchema=object$1({docName:safeDocNameField,summary:summaryField,content:string$2().optional(),...agentIdentityFields}).loose(),AgentWriteMdRequestSchema=object$1({docName:safeDocNameField,summary:summaryField,markdown:string$2().min(1),position:_enum([`append`,`prepend`,`replace`]).optional(),...agentIdentityFields}).loose(),AgentPatchRequestSchema=object$1({docName:safeDocNameField,summary:summaryField,find:string$2().min(1),replace:string$2(),offset:number$1().int().nonnegative().optional(),...agentIdentityFields}).loose(),AgentUndoRequestSchema=object$1({docName:safeDocNameField,connectionId:string$2().min(1),scope:_enum([`last`,`session`,`file`]).optional(),...agentIdentityFields}).loose(),SummaryResponseFieldSchema=object$1({value:string$2(),truncatedFrom:number$1().int().nonnegative().optional(),hint:string$2().optional()}).loose(),OrphanHintSchema=object$1({type:literal(`orphan`),parentCandidates:array(string$2()),message:string$2()}).loose(),AgentWriteSuccessSchema=object$1({timestamp:string$2().min(1),summary:SummaryResponseFieldSchema.optional()}).loose(),AgentWriteMdSuccessSchema=object$1({timestamp:string$2().min(1),subscriberCount:number$1().int().nonnegative(),systemSubscriberCount:number$1().int().nonnegative(),hints:array(OrphanHintSchema).optional(),summary:SummaryResponseFieldSchema.optional()}).loose(),AgentPatchSuccessSchema=object$1({timestamp:string$2().min(1),subscriberCount:number$1().int().nonnegative(),systemSubscriberCount:number$1().int().nonnegative(),summary:SummaryResponseFieldSchema.optional()}).loose(),AgentUndoSuccessSchema=object$1({docName:string$2().min(1),scope:_enum([`last`,`session`]),undone:boolean$1()}).loose(),FrontmatterPatchRequestSchema=object$1({docName:safeDocNameField,patch:record(string$2(),union([FrontmatterValueSchema,_null()])),types:record(string$2(),_enum(FRONTMATTER_TYPES)).optional(),summary:summaryField,...agentIdentityFields}).loose(),FrontmatterPatchSuccessSchema=object$1({timestamp:string$2().min(1),subscriberCount:number$1().int().nonnegative(),systemSubscriberCount:number$1().int().nonnegative(),appliedKeys:array(string$2()),summary:SummaryResponseFieldSchema.optional()}).loose(),DocumentReadSuccessSchema=object$1({docName:string$2().min(1),content:string$2()}).loose(),DocumentListEntrySchema=object$1({kind:_enum([`document`,`asset`,`folder`]).default(`document`),docName:string$2().min(1).optional(),docExt:string$2().min(1).default(`.md`),size:number$1().int().nonnegative(),modified:string$2().min(1),isSymlink:boolean$1().default(!1),canonicalDocName:string$2().nullable().default(null),targetPath:string$2().nullable().default(null),path:string$2().min(1).optional(),assetExt:string$2().min(1).optional(),mediaKind:_enum([`image`,`video`,`audio`,`pdf`,`text`]).nullable().optional(),referencedBy:array(string$2().min(1)).optional()}).loose().refine(e=>e.kind===`document`?e.docName!==void 0&&e.path===void 0&&e.assetExt===void 0&&e.mediaKind===void 0&&e.referencedBy===void 0:e.kind===`folder`?e.docName===void 0&&e.path!==void 0&&e.assetExt===void 0&&e.mediaKind===void 0&&e.referencedBy===void 0:e.path!==void 0&&e.assetExt!==void 0&&e.referencedBy!==void 0,{message:`document/asset/folder kind must match its required fields (document → docName; asset → path+assetExt+referencedBy; folder → path only, no docName)`}),DocumentListSuccessSchema=object$1({documents:array(DocumentListEntrySchema)}).loose(),BacklinkEntrySchema=object$1({source:string$2().min(1),anchor:string$2().nullable(),title:string$2(),snippet:string$2().nullable()}).loose(),BacklinksSuccessSchema=object$1({docName:string$2().min(1),backlinks:array(BacklinkEntrySchema)}).loose(),BacklinkCountsSuccessSchema=object$1({counts:record(string$2().min(1),number$1().int().nonnegative())}).loose(),ForwardLinkDocEntrySchema=object$1({kind:literal(`doc`),docName:string$2().min(1),anchor:string$2().nullable(),title:string$2(),snippet:string$2().nullable()}).loose(),ForwardLinkExternalEntrySchema=object$1({kind:literal(`external`),url:string$2().min(1),title:string$2(),snippet:string$2().nullable()}).loose(),ForwardLinkEntrySchema=discriminatedUnion(`kind`,[ForwardLinkDocEntrySchema,ForwardLinkExternalEntrySchema]),ForwardLinksSuccessSchema=object$1({docName:string$2().min(1),forwardLinks:array(ForwardLinkEntrySchema)}).loose(),LinkGraphDocNodeSchema=object$1({id:string$2().min(1),kind:literal(`doc`),docName:string$2().min(1),anchor:string$2().nullable(),label:string$2(),cluster:string$2().nullable(),category:string$2().nullable(),tags:array(string$2()).nullable()}).loose(),LinkGraphExternalNodeSchema=object$1({id:string$2().min(1),kind:literal(`external`),url:string$2().min(1),label:string$2()}).loose(),LinkGraphNodeSchema=discriminatedUnion(`kind`,[LinkGraphDocNodeSchema,LinkGraphExternalNodeSchema]),LinkGraphEdgeSchema=object$1({source:string$2().min(1),target:string$2().min(1)}).loose(),LinkGraphSuccessSchema=object$1({nodes:array(LinkGraphNodeSchema),links:array(LinkGraphEdgeSchema)}).loose(),SaveVersionWriterSchema=object$1({id:string$2().min(1),name:string$2().optional(),email:string$2().optional()}).loose(),SaveVersionRequestSchema=object$1({writers:array(SaveVersionWriterSchema).optional(),...agentIdentityFields}).loose(),SaveVersionSuccessSchema=object$1({checkpointRef:string$2().min(1)}).loose(),HistoryShadowContributorSchema=object$1({v:number$1().int().optional(),id:string$2().min(1),name:string$2().min(1),colorSeed:string$2().optional(),docs:array(string$2()),summaries:array(string$2()).optional()}).loose(),HistoryEntrySchema=object$1({sha:string$2().min(1),timestamp:string$2().min(1),author:string$2(),authorEmail:string$2(),type:_enum([`checkpoint`,`wip`,`upstream`,`park`]),message:string$2(),contributors:array(HistoryShadowContributorSchema),checkpoint:unknown$2().nullable()}).loose(),HistorySuccessSchema=object$1({entries:array(HistoryEntrySchema),total:number$1().int().nonnegative().optional(),truncated:boolean$1().optional()}).loose(),HistoryVersionSuccessSchema=object$1({sha:string$2().regex(/^[0-9a-f]{40}$/i),content:string$2(),timestamp:string$2(),author:string$2()}).loose(),DiffLineSchema=object$1({type:_enum([`added`,`removed`,`unchanged`]),text:string$2()}).loose(),DiffSuccessSchema=object$1({lines:array(DiffLineSchema),additions:number$1().int().nonnegative(),deletions:number$1().int().nonnegative()}).loose(),WorkspaceSuccessSchema=object$1({contentDir:string$2().min(1),pathSeparator:_enum([`/`,`\\`]),symlinkResolved:boolean$1()}).loose(),RescueEntryFlatSchema=object$1({docName:string$2().min(1),timestamp:string$2().min(1),size:number$1().int().nonnegative(),source:literal(`flat`)}).loose(),RescueEntryTimelineSchema=object$1({docName:string$2().min(1),timestamp:string$2().min(1),source:literal(`timeline`),sha:string$2().min(1)}).loose(),RescueListSuccessSchema=array(discriminatedUnion(`source`,[RescueEntryFlatSchema,RescueEntryTimelineSchema])).meta({description:"Flat array of rescue buffer entries; discriminated via `source`."}),OrphanEntrySchema=object$1({docName:string$2().min(1),title:string$2()}).loose(),OrphansSuccessSchema=object$1({orphans:array(OrphanEntrySchema)}).loose(),HubEntrySchema=object$1({docName:string$2().min(1),title:string$2(),count:number$1().int().nonnegative()}).loose(),HubsSuccessSchema=object$1({hubs:array(HubEntrySchema)}).loose(),DeadLinkSourceSchema=object$1({source:string$2().min(1),title:string$2(),snippet:string$2().nullable()}).loose(),DeadLinkEntrySchema=object$1({target:string$2().min(1),sources:array(DeadLinkSourceSchema)}).loose(),DeadLinksSuccessSchema=object$1({deadLinks:array(DeadLinkEntrySchema)}).loose(),SuggestLinksTargetSchema=object$1({docName:string$2().min(1),title:string$2(),aliases:array(string$2())}).loose(),SuggestLinksMentionSchema=object$1({source:string$2().min(1),excerpt:string$2(),offset:number$1().int().nonnegative()}).loose(),SuggestLinksSuccessSchema=object$1({target:SuggestLinksTargetSchema,mentions:array(SuggestLinksMentionSchema),truncated:boolean$1()}).loose(),LocalOpOpenRequestSchema=object$1({dir:string$2().min(1)}).loose(),LocalOpOpenSuccessSchema=object$1({port:number$1().int().positive()}).loose(),LocalOpAuthHostRequestSchema=object$1({host:string$2().min(1).optional()}).loose(),LocalOpAuthPatRequestSchema=object$1({pat:string$2().min(1),host:string$2().min(1).optional()}).loose(),LocalOpAuthSetIdentityRequestSchema=object$1({name:string$2().refine(e=>e.trim().length>0,{message:`name must be non-empty`}),email:string$2().refine(e=>e.trim().length>0,{message:`email must be non-empty`})}).loose(),LocalOpAuthIdentitySchema=object$1({name:string$2().min(1),email:string$2().min(1)}).loose().nullable(),LocalOpAuthIdentitySuccessSchema=object$1({identity:LocalOpAuthIdentitySchema}).loose(),LocalOpAuthStatusSuccessSchema=object$1({authenticated:boolean$1()}).loose(),LocalOpAuthPatSuccessSchema=object$1({type:literal(`complete`).optional(),login:string$2().min(1).optional()}).loose(),LocalOpAuthEmptySuccessSchema=object$1({}).loose(),ActivityBurstSchema=object$1({stackIndex:number$1().int().min(0),ts:number$1().int().min(0),additions:number$1().int().min(0),deletions:number$1().int().min(0)}).loose(),ActivityFileSchema=object$1({docName:string$2().min(1),additionsTotal:number$1().int().min(0),deletionsTotal:number$1().int().min(0),lastTs:number$1().int().min(0),bursts:array(ActivityBurstSchema)}).loose(),ActivityAgentHeaderSchema=object$1({displayName:string$2().min(1),color:string$2().min(1),icon:string$2().optional(),connectionId:string$2().min(1)}).loose(),AgentActivitySuccessSchema=object$1({sessionAlive:boolean$1(),agent:ActivityAgentHeaderSchema.nullable(),files:array(ActivityFileSchema)}).loose(),AgentBurstDiffSuccessSchema=object$1({diff:string$2(),generatedAt:number$1().int().min(0)}).loose(),TestResetSuccessSchema=object$1({}).loose(),TestRescanBacklinksSuccessSchema=object$1({}).loose(),TestRescanFilesSuccessSchema=object$1({}).loose(),MetricsReconciliationSuccessSchema=object$1({}).loose(),MetricsParseHealthSuccessSchema=object$1({}).loose(),AgentPresenceEntrySchema=object$1({displayName:string$2().min(1),icon:string$2(),color:string$2().min(1),currentDoc:string$2().nullable(),mode:_enum([`idle`,`writing`]),ts:number$1().int().min(0)}).loose(),MetricsAgentPresenceSuccessSchema=object$1({presence:record(string$2().min(1),AgentPresenceEntrySchema)}).loose(),InstalledAgentsSuccessSchema=record(string$2().min(1),boolean$1()).meta({description:`Flat boolean record keyed by agent-scheme name (claude / codex / cursor). True = installed.`}),SpawnCursorRequestSchema=object$1({path:string$2().min(1,`path must be non-empty`)}).loose(),SpawnCursorSuccessSchema=object$1({}).loose(),RenamedDocMappingSchema=object$1({fromDocName:string$2().min(1),toDocName:string$2().min(1)}).loose(),EmptyRequestSchema=object$1({}).loose(),CreatePageRequestSchema=object$1({path:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),CreatePageSuccessSchema=object$1({docName:string$2().min(1)}).loose(),CreateFolderRequestSchema=object$1({path:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),CreateFolderSuccessSchema=object$1({path:string$2().min(1)}).loose(),DuplicatePathRequestSchema=object$1({kind:_enum([`file`,`folder`]),path:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),DuplicatePathSuccessSchema=object$1({kind:_enum([`file`,`folder`]),path:string$2().min(1),duplicatedDocNames:array(string$2().min(1))}).loose(),PageEntrySchema=object$1({docName:string$2().min(1),title:string$2(),docExt:string$2().min(1),size:number$1().int().nonnegative(),modified:string$2().min(1)}).loose(),PagesSuccessSchema=object$1({pages:array(PageEntrySchema)}).loose(),HeadingEntrySchema=object$1({level:number$1().int().min(1).max(6),text:string$2(),slug:string$2()}).loose(),PageHeadingsSuccessSchema=object$1({docName:string$2().min(1),headings:array(HeadingEntrySchema)}).loose(),RenameRequestSchema=object$1({docName:string$2().min(1),newDocName:string$2().min(1),summary:summaryField,...agentIdentityFields}).loose(),RenameRewrittenDocSchema=object$1({docName:string$2().min(1),rewrites:number$1().int().nonnegative()}).loose(),RenameSuccessSchema=object$1({renamed:array(RenamedDocMappingSchema),rewrittenDocs:array(RenameRewrittenDocSchema),summary:SummaryResponseFieldSchema.optional()}).loose(),RenamePathRequestSchema=object$1({kind:_enum([`file`,`folder`]),fromPath:string$2().min(1),toPath:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),RenamePathSuccessSchema=object$1({renamed:array(RenamedDocMappingSchema),rewrittenDocs:array(RenameRewrittenDocSchema).optional(),summary:SummaryResponseFieldSchema.optional()}).loose(),DeletePathRequestSchema=object$1({kind:_enum([`file`,`folder`]),path:string$2().min(1),...agentIdentityFields}).loose(),DeletePathSuccessSchema=object$1({deletedDocNames:array(string$2().min(1))}).loose(),TrashCleanupRequestSchema=object$1({kind:_enum([`file`,`folder`]),path:string$2().min(1),...agentIdentityFields,summary:summaryField}).loose(),TrashCleanupSuccessSchema=object$1({deletedDocNames:array(string$2().min(1))}).loose(),RollbackRequestSchema=object$1({docName:string$2().min(1),commitSha:string$2().regex(/^[0-9a-f]{40}$/i,{message:`commitSha must be a 40-char git SHA`}),summary:summaryField,...agentIdentityFields}).loose(),RollbackSuccessSchema=object$1({restoredFrom:string$2().min(1),timestamp:string$2().min(1),summary:SummaryResponseFieldSchema.optional()}).loose(),ShareConstructUrlRequestSchema=object$1({docPath:string$2().min(1)}).loose(),ShareConstructUrlErrorCodeSchema=_enum([`no-remote`,`detached-head`,`branch-not-on-origin`,`non-github-remote`,`invalid-path`]),ShareConstructUrlResponseSchema=discriminatedUnion(`ok`,[object$1({ok:literal(!0),shareUrl:string$2().min(1),blobUrl:string$2().min(1),branch:string$2().min(1)}).loose(),object$1({ok:literal(!1),error:ShareConstructUrlErrorCodeSchema,branch:string$2().min(1).optional()}).loose()]),SharePublishOwnerKindSchema=_enum([`user`,`org`]),SharePublishOwnerSchema=object$1({login:string$2().min(1),kind:SharePublishOwnerKindSchema,avatarUrl:string$2().optional()}).loose(),SharePublishOwnersErrorCodeSchema=_enum([`auth-required`,`network`]),SharePublishOwnersResponseSchema=discriminatedUnion(`ok`,[object$1({ok:literal(!0),owners:array(SharePublishOwnerSchema)}).loose(),object$1({ok:literal(!1),error:SharePublishOwnersErrorCodeSchema}).loose()]),SharePublishNameCheckResponseSchema=discriminatedUnion(`ok`,[object$1({ok:literal(!0),available:boolean$1()}).loose(),object$1({ok:literal(!1),error:SharePublishOwnersErrorCodeSchema}).loose()]),SharePublishVisibilitySchema=_enum([`public`,`private`]),SharePublishRequestSchema=object$1({owner:string$2().min(1),name:string$2().min(1),visibility:SharePublishVisibilitySchema,description:string$2().optional()}).loose(),SharePublishErrorCodeSchema=_enum([`name-conflict`,`saml-sso`,`auth-required`,`push-failed`,`init-failed`,`network`,`no-project`]),SharePublishResponseSchema=discriminatedUnion(`ok`,[object$1({ok:literal(!0),ownerLogin:string$2().min(1),repoName:string$2().min(1),cloneUrl:string$2().min(1),defaultBranch:string$2().min(1)}).loose(),object$1({ok:literal(!1),error:SharePublishErrorCodeSchema}).loose()]),SyncStateSchema=_enum([`dormant`,`idle`,`fetching`,`pulling`,`pushing`,`conflict`,`offline`,`auth-error`,`disabled`]),SyncStatusSchema=object$1({state:SyncStateSchema,lastSyncUtc:string$2().nullable(),lastFetchUtc:string$2().nullable(),lastPushedSha:string$2().nullable(),ahead:number$1().int().min(0),behind:number$1().int().min(0),consecutiveFailures:number$1().int().min(0),conflictCount:number$1().int().min(0),hasRemote:boolean$1(),syncEnabled:boolean$1(),identityUnresolved:boolean$1(),error:string$2().optional(),pausedReason:string$2().optional()}).loose(),SyncTriggerRequestSchema=object$1({op:_enum([`sync`,`push`,`pull`]).optional()}).loose(),SyncTriggerSuccessSchema=object$1({op:_enum([`sync`,`push`,`pull`])}).loose(),ConflictEntrySchema=object$1({file:string$2().min(1),detectedAt:string$2().min(1),oursSha:string$2().optional(),theirsSha:string$2().optional(),baseSha:string$2().optional()}).loose(),SyncConflictsSuccessSchema=object$1({conflicts:array(ConflictEntrySchema)}).loose(),SyncResolveConflictRequestSchema=object$1({file:string$2().min(1),strategy:_enum([`mine`,`theirs`,`content`]),content:string$2().optional()}).loose().refine(e=>e.strategy!==`content`||e.content!==void 0,{message:`content is required when strategy is 'content'`,path:[`content`]}),SyncResolveConflictSuccessSchema=object$1({}).loose(),SyncConflictContentSuccessSchema=object$1({file:string$2().min(1),base:string$2(),ours:string$2(),theirs:string$2()}).loose(),SyncAbortMergeSuccessSchema=object$1({}).loose(),SeedPlanSuccessSchema=object$1({plan:custom(e=>e!==void 0,{message:`plan is required`})}).loose(),SeedApplyRequestSchema=object$1({plan:custom(e=>e!==void 0,{message:`plan is required`})}).loose(),SeedApplySuccessSchema=object$1({result:custom(e=>e!==void 0,{message:`result is required`})}).loose(),SeedPackFolderInfoSchema=object$1({path:string$2().min(1),summary:string$2().min(1)}).loose(),SeedPackEntryCountsSchema=object$1({files:number$1().int().nonnegative(),folders:number$1().int().nonnegative()}).loose(),SeedPackInfoSchema=object$1({id:string$2().min(1),name:string$2().min(1),description:string$2().min(1),defaultSubfolder:string$2().optional(),folders:array(SeedPackFolderInfoSchema),entryCounts:SeedPackEntryCountsSchema}).loose(),SeedListPacksSuccessSchema=object$1({packs:array(SeedPackInfoSchema)}).loose(),InstallSkillRequestSchema=object$1({noOpen:boolean$1().optional(),out:string$2().min(1).optional()}).loose(),InstallSkillHandoffErrorSchema=object$1({reason:_enum([`unsupported-platform`,`spawn-error`]),message:string$2()}).loose(),InstallSkillSuccessSchema=discriminatedUnion(`status`,[object$1({status:literal(`installed`),outputPath:string$2(),size:number$1().int().nonnegative(),sha256:string$2(),skillVersion:string$2()}).loose(),object$1({status:literal(`built`),outputPath:string$2(),size:number$1().int().nonnegative(),sha256:string$2(),skillVersion:string$2(),handoffError:InstallSkillHandoffErrorSchema.optional()}).loose(),object$1({status:literal(`failed`),buildError:string$2()}).loose(),object$1({status:literal(`skip-current`),skillVersion:string$2(),recordedAt:string$2().optional()}).loose()]),TagSummaryEntrySchema=object$1({name:string$2().min(1),count:number$1().int().nonnegative(),isLeaf:boolean$1()}).loose(),TagsListSuccessSchema=object$1({tags:array(TagSummaryEntrySchema)}).loose(),TagsDocEntrySchema=object$1({docName:string$2().min(1),title:string$2(),matchingTags:array(string$2().min(1)),snippet:string$2().nullable()}).loose(),TagsForNameSuccessSchema=object$1({name:string$2().min(1),docs:array(TagsDocEntrySchema)}).loose(),FolderConfigGetSuccessSchema=object$1({folder:unknown$2(),frontmatter_local:record(string$2(),unknown$2()).nullable()}).loose(),FolderConfigPutRequestSchema=object$1({path:string$2(),frontmatter:record(string$2(),unknown$2()).optional()}).loose(),FolderConfigPutSuccessSchema=object$1({applied:unknown$2()}).loose(),TemplateFrontmatterSchema$1=record(string$2(),unknown$2()).meta({description:`Free-form frontmatter map embedded in template payloads.`}),TemplatePayloadSchema=object$1({name:string$2().min(1),folder:string$2(),scope:_enum([`local`,`inherited`]),path:string$2().min(1),frontmatter:TemplateFrontmatterSchema$1,body:string$2()}).strict(),TemplateGetSuccessSchema=object$1({template:TemplatePayloadSchema}).strict(),TemplatePutRequestSchema=object$1({folder:string$2(),name:string$2(),body:string$2().optional(),frontmatter:TemplateFrontmatterSchema$1.optional()}).strict(),TemplatePutSuccessSchema=object$1({path:string$2().min(1),created:boolean$1(),warnings:array(string$2())}).strict(),TemplateDeleteSuccessSchema=object$1({existed:boolean$1(),path:string$2().min(1)}).strict(),SearchRequestSchema=object$1({query:string$2().optional(),intent:_enum([`autocomplete`,`full_text`,`omnibar`]).optional(),scopes:array(_enum([`page`,`folder`,`content`])).optional(),scope:string$2().optional(),limit:number$1().int().nonnegative().optional()}).loose(),SearchResultEntrySchema=object$1({kind:_enum([`page`,`folder`,`content`]),path:string$2().min(1),title:string$2(),score:number$1(),signals:record(string$2(),unknown$2()),snippet:string$2().optional()}).loose(),SearchSuccessSchema=object$1({query:string$2(),intent:_enum([`autocomplete`,`full_text`,`omnibar`]),results:array(SearchResultEntrySchema),elapsedMs:number$1().nonnegative()}).loose(),SkillInstallTargetStateSchema=object$1({version:string$2().min(1),recordedAt:string$2().min(1)}).loose(),SkillInstallStateSuccessSchema=object$1({currentVersion:string$2().min(1),targets:record(string$2(),SkillInstallTargetStateSchema.nullable())}).loose(),CC1_CHANNEL_SERVER_INFO=`server-info`,CC1_CHANNEL_BRANCH_SWITCHED=`branch-switched`,CC1_CHANNEL_DISK_ACK=`disk-ack`,CC1_CHANNEL_CONFIG_VALIDATION_REJECTED=`config-validation-rejected`,CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR=`config-ignore-nested-error`,DerivedViewChannelSchema=_enum([`files`,`backlinks`,`graph`,`sync-status`,`session-activity`,`tags`]),CC1ServerInfoPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_SERVER_INFO),seq:number$1(),serverInstanceId:string$2().min(1),currentBranch:string$2().min(1).optional()}).loose(),CC1BranchSwitchedPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_BRANCH_SWITCHED),seq:number$1(),branch:string$2().min(1)}).loose(),CC1DerivedViewPayloadSchema=object$1({v:literal(1),ch:DerivedViewChannelSchema,seq:number$1()}).loose(),CC1DiskAckPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_DISK_ACK),seq:number$1(),docName:string$2().min(1),sv:string$2().min(1)}).loose(),CC1ConfigValidationRejectedPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_CONFIG_VALIDATION_REJECTED),seq:number$1(),docName:string$2().min(1),error:ConfigValidationErrorSchema}).loose(),CC1ConfigIgnoreNestedErrorPayloadSchema=object$1({v:literal(1),ch:literal(CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR),seq:number$1(),path:string$2().min(1),error:string$2().min(1)}).loose(),WORKSPACE_SEARCH_SCHEMA={id:`string`,kind:`enum`,path:`string`,title:`string`,name:`string`,pathSegments:`string`,content:`string`,modifiedTs:`number`},workspaceSearchIndexes=new WeakMap;function clampLimit(e){return e===void 0||!Number.isFinite(e)?20:Math.max(1,Math.min(100,Math.trunc(e)))}function normalize$2(e){return e.trim().toLowerCase()}function workspaceSearchBasename(e){let t=e.split(`/`).filter(Boolean);return t[t.length-1]??e}function workspaceSearchPathSegments(e){return e.split(`/`).filter(Boolean).join(` `)}function createWorkspaceSearchDocument(e){let t=workspaceSearchBasename(e.path),S=e.title?.trim()||t,w=e.modifiedTs??0;return{id:`${e.kind}:${e.path}`,kind:e.kind,path:e.path,title:S,name:t,pathSegments:workspaceSearchPathSegments(e.path),content:e.content??``,modifiedTs:Number.isFinite(w)?w:0}}function createWorkspaceSearchIndex(e){let t=create$9({schema:WORKSPACE_SEARCH_SCHEMA});return e.length>0&&insertMultiple(t,e),t}function createWorkspaceSearchCorpus(e){let t={documents:e};return workspaceSearchIndexes.set(t,createWorkspaceSearchIndex(e)),t}function getWorkspaceSearchIndex(e){let t=workspaceSearchIndexes.get(e);if(t)return t;let S=createWorkspaceSearchIndex(e.documents);return workspaceSearchIndexes.set(e,S),S}function defaultScopes(e){return e===`autocomplete`?[`page`]:e===`full_text`?[`page`,`content`]:[`page`,`folder`]}function scopeAllows(e,t){return t.has(e.kind)?!0:e.kind===`page`&&t.has(`content`)}function lexicalScore(e,t){let S=normalize$2(t);if(!S)return 0;let w=normalize$2(e.title),E=normalize$2(e.name),D=normalize$2(e.path),O=D.split(`/`);return w===S||E===S?700:D===S?650:w.startsWith(S)||E.startsWith(S)?600:O.some(e=>e.startsWith(S))?550:w.includes(S)||E.includes(S)?500:D.includes(S)?450:-1}function recencyScores(e){let t=e.map(e=>e.modifiedTs).filter(e=>Number.isFinite(e)&&e>0);if(t.length===0)return new Map;let S=1/0,w=-1/0;for(let e of t)e<S&&(S=e),e>w&&(w=e);let E=Math.max(1,w-S);return new Map(e.map(e=>[e.id,e.modifiedTs>0?(e.modifiedTs-S)/E*50:0]))}function searchProperties(e){return e===`full_text`?[`title`,`name`,`path`,`pathSegments`,`content`]:[`title`,`name`,`path`,`pathSegments`]}function searchBoost(e){return e===`full_text`?{title:8,name:7,path:5,pathSegments:4,content:1}:e===`autocomplete`?{title:10,name:9,path:5,pathSegments:4}:{title:8,name:7,path:5,pathSegments:4}}function toleranceFor(e,t){return normalize$2(t).length<4?0:e===`full_text`?1:0}function searchWorkspaceCorpus(e,t,S={}){let w=S.intent??`omnibar`,E=clampLimit(S.limit),D=new Set(S.scopes??defaultScopes(w)),O=e.documents.filter(e=>scopeAllows(e,D)),k=normalize$2(t);if(!k)return O.slice().sort((e,t)=>e.path.localeCompare(t.path)).slice(0,E).map(e=>({document:e,score:0,signals:{lexical:0,fullText:0,recency:0}}));let j=search(getWorkspaceSearchIndex(e),{term:k,properties:searchProperties(w),boost:searchBoost(w),tolerance:toleranceFor(w,k),limit:Math.max(E*4,40)}),F=new Map(j.hits.filter(e=>scopeAllows(e.document,D)).map(e=>[e.document.id,e.score])),L=recencyScores(O),B=new Map;for(let e of O)lexicalScore(e,k)>=0&&B.set(e.id,e);for(let e of j.hits)scopeAllows(e.document,D)&&B.set(e.document.id,e.document);return[...B.values()].map(e=>{let t=Math.max(0,lexicalScore(e,k)),S=F.get(e.id)??0,w=L.get(e.id)??0;return{document:e,score:t+S*20+w,signals:{lexical:t,fullText:S,recency:w}}}).sort((e,t)=>e.score===t.score?e.document.path.localeCompare(t.document.path):t.score-e.score).slice(0,E)}const SHARE_URL_VERSION_V1=1;function encodeShareUrl(e){let t=new TextEncoder().encode(e),S=new Uint8Array(1+t.length);return S[0]=SHARE_URL_VERSION_V1,S.set(t,1),uint8ArrayToBase64Url(S)}function uint8ArrayToBase64Url(e){let t=``;for(let S=0;S<e.length;S++)t+=String.fromCharCode(e[S]);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}const SINGLETON_KEY=Symbol.for(`@inkeep/open-knowledge/skill-state-field-registry`),g=globalThis;g[SINGLETON_KEY]===void 0&&(g[SINGLETON_KEY]=registry$1());const skillStateFieldRegistry=g[SINGLETON_KEY],SKILL_STATE_FILENAME=`skill-state.yml`,SKILL_STATE_REL=[`.ok`,SKILL_STATE_FILENAME],SKILL_STATE_TARGETS=[`claude-cowork`,`cli-hosts`],SKILL_STATE_SURFACES=[`server-build-and-open`,`electron-build-and-open`,`cli-npx-skills-add`,`desktop-direct`],SKILL_STATE_VERSION_RE=/^\d+\.\d+\.\d+(?:[-+][\w.-]+)?$/,TargetEntrySchema=looseObject({version:string$2().regex(SKILL_STATE_VERSION_RE,`version must match /^\\d+\\.\\d+\\.\\d+(?:[-+][\\w.-]+)?$/`).register(skillStateFieldRegistry,{description:`Recorded skill version for this target.`}),recordedAt:datetime().register(skillStateFieldRegistry,{description:`ISO 8601 timestamp of the most recent successful write. Updated on every write, including reinstalls of the same version.`}),surface:_enum(SKILL_STATE_SURFACES).register(skillStateFieldRegistry,{description:`Install-source surface that recorded this entry.`}).optional()}),SkillStateSchema=looseObject({schema:literal(1).register(skillStateFieldRegistry,{description:`Schema major version. Bumped only on breaking shape changes.`}),targets:looseObject({"claude-cowork":TargetEntrySchema.optional(),"cli-hosts":TargetEntrySchema.optional()}).register(skillStateFieldRegistry,{description:`Per-target install-state entries. Absent target = no recorded install.`}).default({})});function emptySkillState(){return{schema:1,targets:{}}}function createCodeFenceTracker(){let e=!1,t=``,S=0;return w=>{let E=parseCodeFenceLine(w);return e?(E&&E.char===t&&E.len>=S&&!E.hasInfo&&(e=!1,t=``,S=0),!0):E?(e=!0,t=E.char,S=E.len,!0):!1}}function parseCodeFenceLine(e){let t=(e.endsWith(`\r`)?e.slice(0,-1):e).match(/^ {0,3}([`~])(\1{2,})(.*)$/);return t?{char:t[1],len:1+t[2].length,hasInfo:t[3].trim()!==``}:null}const AGENT_COLORS=[`#D97757`,`#1B1912`,`#F9F3E9`,`#7A9DFF`,`#8534F3`,`#9663F0`,`#727CF3`],AGENT_ICON_COLORS={claude:`#D97757`,cursor:`#1B1912`,windsurf:`#0B100F`,openai:`#7A9DFF`,github:`#8534F3`,cline:`#9663F0`,bot:`#727CF3`};function colorFromSeed(e,t=AGENT_COLORS){let S=0;for(let t of e)S=(S<<5)-S+t.charCodeAt(0)|0;return t[Math.abs(S)%t.length]}const ICON_MAP={"claude-code":`claude`,"claude-ai":`claude`,cursor:`cursor`,"cursor-vscode":`cursor`,cascade:`windsurf`,codex:`openai`,"codex-mcp-client":`openai`,copilot:`github`,cline:`cline`};function iconFromClientName(e){return e?ICON_MAP[e]??`bot`:`bot`}function resolveInternalHref(e,t){let S=e.trim();if(!S||/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(S)||S.startsWith(`//`)||S.startsWith(`/`)||S.startsWith(`#`))return null;let w=S.indexOf(`#`),E=w>=0?S.slice(0,w):S,D=w>=0?S.slice(w+1):null,O=(E.split(`?`)[0]??``).trim();if(!O)return null;let k=(O.split(`/`).pop()??``).match(/\.([a-z0-9]+)$/i);if(k){let e=(k[1]??``).toLowerCase();if(e!==`md`&&e!==`mdx`)return null}let j=O.toLowerCase(),F=j.endsWith(`.mdx`)?O.slice(0,-4):j.endsWith(`.md`)?O.slice(0,-3):O,L=t.includes(`/`)?t.split(`/`).slice(0,-1):[];for(let e of F.split(`/`))if(e===`..`){if(L.length===0)return null;L.pop()}else e!==`.`&&e!==``&&L.push(e);return L.length===0?null:{docName:L.join(`/`),anchor:D||null}}const URI_SCHEME_RE=/^[a-zA-Z][a-zA-Z\d+\-.]*:/;function extractAssetExtension(e){let t=(e.split(/[?#]/)[0]??e).match(/\.([a-z0-9]+)$/i);return t?(t[1]??``).toLowerCase():null}function isExternalHref(e){let t=e.trim();return URI_SCHEME_RE.test(t)||t.startsWith(`//`)}function classifyMarkdownHref(e,t){let S=e.trim();if(!S)return null;if(S.startsWith(`#`)){let e=S.slice(1).trim();return e?{kind:`anchor`,anchor:e}:null}let w=resolveInternalHref(S,t);if(w)return{kind:`doc`,docName:w.docName,anchor:w.anchor};if(isExternalHref(S)||S.startsWith(`/`))return{kind:`external`,url:S};let E=extractAssetExtension(S);return E&&E!==`md`&&E!==`mdx`?{kind:`asset`,url:S,ext:E}:null}function classifyWikiLinkTarget(e,t){let S=e.trim();if(!S)return null;if(isExternalHref(S))return{kind:`external`,url:t?`${S}#${t}`:S};let w=extractAssetExtension(S);return w&&w!==`md`&&w!==`mdx`?{kind:`asset`,url:S,ext:w}:{kind:`doc`,docName:S,anchor:t?.trim()||null}}function resolveAssetProjectPath(e,t){let S=e.trim();if(!S||URI_SCHEME_RE.test(S)||S.startsWith(`//`)||S.startsWith(`#`))return null;let w=S.indexOf(`#`),E=((w>=0?S.slice(0,w):S).split(`?`)[0]??``).trim();if(!E)return null;let D=E.startsWith(`/`),O=D?E.slice(1):E,k=D?[]:t.includes(`/`)?t.split(`/`).slice(0,-1):[];for(let e of O.split(`/`))if(e===`..`){if(k.length===0)return null;k.pop()}else e!==`.`&&e!==``&&k.push(e);return k.length===0?null:k.join(`/`)}function normalizePath(e){let t=e;return t.startsWith(`./`)&&(t=t.slice(2)),t.startsWith(`/`)&&(t=t.slice(1)),t}function basenameOf(e){let t=e.lastIndexOf(`/`);return t===-1?e:e.slice(t+1)}function dirnameOf(e){let t=e.lastIndexOf(`/`);return t===-1?``:e.slice(0,t)}function splitSegments(e){return e.split(`/`).filter(e=>e!==``)}function isInSubtree(e,t){let S=dirnameOf(t);return e===``||S===e?!0:S.startsWith(`${e}/`)}function depthInSubtree(e,t){let S=dirnameOf(t);if(e===S)return 0;let w=e===``?S:S.slice(e.length+1);return w===``?0:splitSegments(w).length}function relativeHops(e,t){let S=splitSegments(e),w=splitSegments(t),E=0;for(;E<S.length&&E<w.length&&S[E]===w[E];)E++;return S.length-E+(w.length-E)}function createBasenameIndex(){let e=new Map;function t(t){let S=normalizePath(t);if(S===``)return;let w=basenameOf(S);if(w===``)return;let E=w.toLowerCase(),D=e.get(E);if(!D){e.set(E,[S]);return}D.includes(S)||D.push(S)}function S(t){let S=normalizePath(t),w=basenameOf(S).toLowerCase(),E=e.get(w);if(!E)return;let D=E.indexOf(S);D!==-1&&(E.splice(D,1),E.length===0&&e.delete(w))}function w(e,w){S(e),t(w)}function E(t,S){let w=t.toLowerCase(),E=e.get(w);if(!E||E.length===0)return null;if(E.length===1)return E[0];let D=dirnameOf(normalizePath(S)),O=[],k=[];for(let e of E)isInSubtree(D,e)?O.push(e):k.push(e);return O.length>0?(e=>{let t=e[0],S=depthInSubtree(D,t);for(let w=1;w<e.length;w++){let E=e[w],O=depthInSubtree(D,E);(O<S||O===S&&E<t)&&(t=E,S=O)}return t})(O):(e=>{let t=e[0],S=relativeHops(D,dirnameOf(t));for(let w=1;w<e.length;w++){let E=e[w],O=relativeHops(D,dirnameOf(E));(O<S||O===S&&E<t)&&(t=E,S=O)}return t})(k)}function D(){let t=new Map;for(let[S,w]of e)t.set(S,[...w]);return t}function O(){e.clear()}return{add:t,remove:S,rename:w,resolveEmbed:E,clear:O,snapshot:D,size:()=>e.size}}const TAG_HIERARCHY_SEPARATOR=`/`;function expandTagToHierarchy(e){if(!e)return[];let t=e.split(TAG_HIERARCHY_SEPARATOR),S=[],w=``;for(let e of t)w=w?`${w}${TAG_HIERARCHY_SEPARATOR}${e}`:e,S.push(w);return S}function tagsMatchingPrefix(e,t){if(e.size===0)return new Set;if(t===``)return new Set(e);let S=new Set,w=`${t}${TAG_HIERARCHY_SEPARATOR}`;for(let E of e)(E===t||E.startsWith(w))&&S.add(E);return S}const WRITER_ID_RE=/^(agent-[^/]+|principal-[^/]+|file-system|git-upstream|openknowledge-service)$/;function classifyGitEntry(e,t,S){let w;try{w=statSync(e)}catch(t){let S=t.code;return S===`ENOENT`||S===`ENOTDIR`?{kind:`absent`}:{kind:`inaccessible`,gitPath:e,cause:t}}let E=computeProjectSubPath(t,S);if(w.isDirectory())return{kind:`directory`,path:e,projectSubPath:E};if(w.isFile()){let S;try{S=readFileSync(e,`utf-8`).trim()}catch(t){return{kind:`malformed-pointer`,gitPath:e,target:``,cause:t}}let w=S.match(/^gitdir:\s*(.+)$/);return w?{kind:`linked`,path:resolve(t,w[1]),gitPath:e,projectSubPath:E}:{kind:`malformed-pointer`,gitPath:e,target:``}}return{kind:`absent`}}function computeProjectSubPath(e,t){let S=relative(e,t);return S===``||S===`.`||S.startsWith(`..`)||isAbsolute(S)?``:S}function findAncestorGitEntry(e){let t=homedir(),S=resolve(e),w=64;for(let e=0;e<64;e++){if(S===t)return null;let e=dirname(S);if(e===S||e===t)return null;let w=resolve(e,`.git`);try{let t=statSync(w);if(t.isDirectory()||t.isFile())return{gitPath:w,workTreeRoot:e}}catch(e){let t=e.code;t!==`ENOENT`&&t!==`ENOTDIR`&&console.warn(`[shadow-repo-layout] Cannot stat ${w} (${t??`unknown`}); skipping ancestor`)}S=e}return null}function resolveGitDirDetailed(e){let t=resolve(e),S=classifyGitEntry(resolve(t,`.git`),t,t);if(S.kind!==`absent`)return S;let w=findAncestorGitEntry(t);return w===null?{kind:`absent`}:classifyGitEntry(w.gitPath,w.workTreeRoot,t)}function resolveGitDir(e){let t=resolveGitDirDetailed(e);return t.kind===`directory`||t.kind===`linked`?t.path:null}function resolveShadowDir(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return resolve(t.path,shadowSubdirName(t.projectSubPath));case`linked`:if(!existsSync(t.path))throw new MalformedGitPointerError(t.gitPath,t.path);return resolve(t.path,shadowSubdirName(t.projectSubPath));case`malformed-pointer`:throw new MalformedGitPointerError(t.gitPath,t.target,{cause:t.cause});case`inaccessible`:throw new GitDirAccessError(t.gitPath,{cause:t.cause});case`absent`:return resolve(e,`.git/ok`)}}function shadowSubdirName(e){return e===``?`ok`:`ok-${slugifyShadowSubPath(e)}`}function slugifyShadowSubPath(e){let t=e.split(sep).join(`-`).replace(/\/+/g,`-`).replace(/[^A-Za-z0-9._-]/g,`_`).replace(/^\.+/,`_`),S=64;if(t.length<=64)return t||`sub`;let w=djb2(e).toString(16).padStart(8,`0`);return`${t.slice(0,55)}-${w}`}function djb2(e){let t=5381;for(let S=0;S<e.length;S++)t=t*33+e.charCodeAt(S)>>>0;return t}var MalformedGitPointerError=class extends Error{gitPointerPath;resolvedTarget;constructor(e,t,S){let w=t?`references a missing or unreadable gitdir at ${t}`:`is unreadable or has no valid gitdir: pointer`;super(`\`.git\` pointer at ${e} ${w}. Run \`git worktree prune\` from the source repo and try again.`,S),this.name=`MalformedGitPointerError`,this.gitPointerPath=e,this.resolvedTarget=t}},GitDirAccessError=class extends Error{gitPath;constructor(e,t){let S=t?.cause!==void 0&&t.cause!==null&&typeof t.cause==`object`&&`code`in t.cause&&typeof t.cause.code==`string`?` (${t.cause.code})`:``;super(`Cannot access \`.git\` at ${e}${S}. Check filesystem permissions and that the volume is mounted.`,t),this.name=`GitDirAccessError`,this.gitPath=e}};function getShadowRepoPath(e){let t;try{t=resolveShadowDir(e)}catch(e){if(e instanceof MalformedGitPointerError||e instanceof GitDirAccessError)return null;throw e}return existsSync(resolve(t,`HEAD`))?t:null}function getWipRefPattern(e){return`refs/wip/${e}/`}const OK_CONTRIBUTORS_PREFIX=`ok-contributors: `;function parseContributors(e){if(!e)return[];let t=[];for(let S of e.split(`
|
|
366
366
|
`)){let e=S.trim();if(e.startsWith(OK_CONTRIBUTORS_PREFIX))try{let S=JSON.parse(e.slice(17));if(typeof S==`object`&&S&&`id`in S&&typeof S.id==`string`&&`name`in S&&typeof S.name==`string`&&`docs`in S&&Array.isArray(S.docs)&&S.docs.every(e=>typeof e==`string`)&&(!(`colorSeed`in S)||typeof S.colorSeed==`string`)){let e=S;if(`summaries`in e){let t=e.summaries;(!Array.isArray(t)||!t.every(e=>typeof e==`string`))&&delete e.summaries}t.push(S)}}catch{}}return t}const OK_CHECKPOINT_PREFIX=`ok-checkpoint-v1: `;function parseCheckpoint(e){if(!e)return null;for(let t of e.split(`
|
|
367
367
|
`)){let e=t.trim();if(!e.startsWith(OK_CHECKPOINT_PREFIX))continue;let S;try{S=JSON.parse(e.slice(18))}catch{return null}if(typeof S!=`object`||!S)return null;let w=S,E=w.kind,D=w.metadata;if(typeof D!=`object`||!D)return null;let O=typeof w.docName==`string`?w.docName:null,k=typeof w.size==`number`&&Number.isFinite(w.size)?w.size:null;if(E===`bridge-merge-loss`){let e=D;return Array.isArray(e.lostSubstrings)&&e.lostSubstrings.every(e=>typeof e==`string`)?{kind:`bridge-merge-loss`,docName:O,size:k,metadata:{lostSubstrings:e.lostSubstrings}}:null}if(E===`external-change-rescue`){let e=D;return typeof e.incomingDiskSha==`string`?{kind:`external-change-rescue`,docName:O,size:k,metadata:{incomingDiskSha:e.incomingDiskSha}}:null}return null}return null}function formatCheckpointBodyLine(e){let t={kind:e.kind,metadata:e.metadata};return e.docName!==null&&(t.docName=e.docName),e.size!==null&&(t.size=e.size),`${OK_CHECKPOINT_PREFIX}${JSON.stringify(t)}`}const OK_ACTOR_PREFIX=`ok-actor: `;function formatOkActor(e){let{summaries:t,previous_paths:S,...w}=e,E={...w};return t&&t.length>0&&(E.summaries=t),S&&S.length>0&&(E.previous_paths=S),`${OK_ACTOR_PREFIX}${JSON.stringify(E)}`}function parseOkActorObject(e){if(e.v!==1||!(`display_name`in e)||typeof e.display_name!=`string`||!(`docs`in e)||!Array.isArray(e.docs))return null;let t=typeof e.principal==`string`?e.principal:null,S=typeof e.agent_session==`string`?e.agent_session:null,w;if(typeof e.writer_id==`string`&&e.writer_id.length>0)w=e.writer_id;else if(S)w=`agent-${S}`;else if(t)w=t;else switch(e.display_name){case`File System`:w=`file-system`;break;case`Git (upstream)`:w=`git-upstream`;break;default:w=`openknowledge-service`}let E=`summaries`in e&&Array.isArray(e.summaries)&&e.summaries.every(e=>typeof e==`string`)?e.summaries:void 0,D=parsePreviousPaths(e);return{v:1,writer_id:w,principal:t,agent_session:S,agent_type:typeof e.agent_type==`string`?e.agent_type:null,client_name:typeof e.client_name==`string`?e.client_name:null,client_version:typeof e.client_version==`string`?e.client_version:null,label:typeof e.label==`string`?e.label:null,display_name:e.display_name,color_seed:typeof e.color_seed==`string`?e.color_seed:`unknown`,docs:e.docs.filter(e=>typeof e==`string`),...E&&E.length>0?{summaries:E}:{},...D&&D.length>0?{previous_paths:D}:{}}}function parsePreviousPaths(e){if(!(`previous_paths`in e)||!Array.isArray(e.previous_paths))return;let t=[];for(let S of e.previous_paths){if(typeof S!=`object`||!S)continue;let e=S;typeof e.from!=`string`||typeof e.to!=`string`||t.push({from:e.from,to:e.to})}return t}function parseOkActors(e){if(!e)return[];let t=[];for(let S of e.split(`
|
|
368
368
|
`)){let e=S.trim();if(!e.startsWith(OK_ACTOR_PREFIX))continue;let w;try{w=JSON.parse(e.slice(10))}catch{continue}if(typeof w!=`object`||!w)continue;let E=parseOkActorObject(w);E&&t.push(E)}return t}function okActorToShadowContributor(e){let t={v:1,id:e.writer_id,name:e.display_name,colorSeed:e.color_seed,docs:e.docs};return e.summaries&&e.summaries.length>0&&(t.summaries=e.summaries),t}function readContributors(e){let t=parseOkActors(e);return t.length>0?t.map(okActorToShadowContributor):parseContributors(e)}function formatWipSubject(e){return e.length===0?`wip: auto-save`:e.length===1?`wip: ${e[0]}`:`wip: ${e.length} docs`}function formatReconcileSubject(e){return`reconcile: ${e}`}function formatRollbackSubject(e,t){return`rollback: ${e} to ${t.slice(0,7)}`}function formatParkSubject(e,t){return`park: ${e} -> ${t}`}function formatRenameSubject(e,t){return`rename: ${e} -> ${t}`}function formatCheckpointSubject(e){return`checkpoint: ${e}`}function formatImportSubject(e,t){return e?`import: from ${e.slice(0,8)}..${t.slice(0,8)}`:`import: initial at ${t.slice(0,8)}`}const SUBJECT_LINE_BREAK_RE=RegExp(`[\\r\\n\\v\\f\\u0085\\u2028\\u2029]`,`g`);function stripLineBreaks(e){return e.replace(SUBJECT_LINE_BREAK_RE,` `)}function composeCommitSubject(e,t){let S=stripLineBreaks(e);if(t.length===0)return S;if(t.length>=2)return`${S} (${t.length} edits)`;let[w]=t;if(w===void 0)return S;let E=stripLineBreaks(w),D=`${S} — ${E}`;if(D.length<=72)return D;let O=`${S} — `,k=72-O.length-1;return k<=0?D.slice(0,72):`${O}${E.slice(0,k)}…`}function parseWriterId(e){return WRITER_ID_RE.test(e)?e.startsWith(`agent-`)?{id:e,classification:`agent`,isAgent:!0}:e.startsWith(`principal-`)?{id:e,classification:`principal`,isAgent:!1}:e===`file-system`?{id:e,classification:`classified-file-system`,isAgent:null}:e===`git-upstream`?{id:e,classification:`classified-git-upstream`,isAgent:null}:e===`openknowledge-service`?{id:e,classification:`classified-openknowledge-service`,isAgent:null}:{id:e,classification:`unknown`,isAgent:null}:{id:e,classification:`unknown`,isAgent:null}}var require_err_helpers=__commonJSMin$1(((e,t)=>{let S=e=>e&&typeof e.message==`string`,w=e=>{if(!e)return;let t=e.cause;if(typeof t==`function`){let t=e.cause();return S(t)?t:void 0}else return S(t)?t:void 0},E=(e,t)=>{if(!S(e))return``;let D=e.stack||``;if(t.has(e))return D+`
|
|
@@ -1123,7 +1123,7 @@ ${e.terminator}`}function Qa(e){return`(${Ee(e.body)})${ke(e.redirections)}`}fun
|
|
|
1123
1123
|
`,exitCode:2,env:n(this.state.env,t?.env)});if(e instanceof RangeError)return this.logResult({stdout:``,stderr:`bash: ${n$1(e.message)}
|
|
1124
1124
|
`,exitCode:1,env:n(this.state.env,t?.env)});throw e}finally{F?.deactivate()}}async readFile(e){return this.fs.readFile(this.fs.resolvePath(this.state.cwd,e))}async writeFile(e,t){return this.fs.writeFile(this.fs.resolvePath(this.state.cwd,e),t)}getCwd(){return this.state.cwd}getEnv(){return r(this.state.env)}registerTransformPlugin(e){this.transformPlugins.push(e)}transform(e){let t=di$1(Vi(e),{maxHeredocSize:this.limits.maxHeredocSize}),S=Object.create(null);for(let e of this.transformPlugins){let w=e.transform({ast:t,metadata:S});t=w.ast,w.metadata&&(S=c$3(S,w.metadata))}return{script:Ot(t),ast:t,metadata:S}}};function Vi(e){let t=e.split(`
|
|
1125
1125
|
`),S=[],w=[];for(let e=0;e<t.length;e++){let E=t[e];if(w.length>0){let e=w[w.length-1];if((e.stripTabs?E.replace(/^\t+/,``):E)===e.delimiter){S.push(E.trimStart()),w.pop();continue}S.push(E);continue}let D=E.trimStart();S.push(D);for(let e of D.matchAll(/<<(-?)\s*(['"]?)([\w-]+)\2/g)){let t=e[1]===`-`,S=e[3];w.push({delimiter:S,stripTabs:t})}}return S.join(`
|
|
1126
|
-
`)}var rl=new TextDecoder(`utf-8`,{fatal:!0});function Bi(e){if(!e)return e;let t=!1;for(let S=0;S<e.length;S++){let w=e.charCodeAt(S);if(w>255)return e;w>127&&(t=!0)}if(!t)return e;let S=new Uint8Array(e.length);for(let t=0;t<e.length;t++)S[t]=e.charCodeAt(t);try{return rl.decode(S)}catch{return e}}var ol=[`EACCES`,`escaping sandbox`,`EFBIG`],Ss=class{root;canonicalRoot;maxFileReadSize;allowSymlinks;constructor(e){this.root=U.resolve(e.root),this.maxFileReadSize=e.maxFileReadSize??10485760,this.allowSymlinks=e.allowSymlinks??!1,$$3(this.root,`ReadWriteFs`),this.canonicalRoot=I.realpathSync(this.root)}resolveAndValidate(e,t){let S=this.allowSymlinks?f$1(e,this.canonicalRoot):P$1(e,this.root,this.canonicalRoot);if(S===null)throw Error(`EACCES: permission denied, '${t}' resolves outside sandbox`);return S}validateParent(e,t){let S=U.dirname(e),w=this.resolveAndValidate(S,t);return U.join(w,U.basename(e))}toRealPath(e){let t=c$2(e),S=U.join(this.root,t);return U.resolve(S)}async readFile(e,t){return h$4(await this.readFileBuffer(e),l$1(t))}async readFileBuffer(e){h$3(e,`open`);let t=this.toRealPath(e),S=this.resolveAndValidate(t,e);try{let t=this.allowSymlinks?I.constants.O_RDONLY:I.constants.O_RDONLY|I.constants.O_NOFOLLOW,w=await I.promises.open(S,t);try{if(this.maxFileReadSize>0){let t=await w.stat();if(t.size>this.maxFileReadSize)throw Error(`EFBIG: file too large, read '${e}' (${t.size} bytes, max ${this.maxFileReadSize})`)}let t=await w.readFile();return new Uint8Array(t)}finally{await w.close()}}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, open '${e}'`);if(S.code===`EISDIR`)throw Error(`EISDIR: illegal operation on a directory, read '${e}'`);if(S.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`open`)}}async writeFile(e,t,S){h$3(e,`write`);let w=this.toRealPath(e),E=this.resolveAndValidate(w,e),D=o(t,l$1(S)),O=U.dirname(E);try{await I.promises.mkdir(O,{recursive:!0}),E=this.resolveAndValidate(w,e);let t=this.allowSymlinks?0:I.constants.O_NOFOLLOW,S=I.constants.O_WRONLY|I.constants.O_CREAT|I.constants.O_TRUNC|t,k=await I.promises.open(E,S,438);try{await k.writeFile(D)}finally{await k.close()}}catch(t){if(t.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`write`)}}async appendFile(e,t,S){h$3(e,`append`);let w=this.toRealPath(e),E=this.resolveAndValidate(w,e),D=o(t,l$1(S)),O=U.dirname(E);try{await I.promises.mkdir(O,{recursive:!0}),E=this.resolveAndValidate(w,e);let t=this.allowSymlinks?0:I.constants.O_NOFOLLOW,S=I.constants.O_WRONLY|I.constants.O_CREAT|I.constants.O_APPEND|t,k=await I.promises.open(E,S,438);try{await k.writeFile(D)}finally{await k.close()}}catch(t){if(t.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`append`)}}async exists(e){if(e.includes(`\0`))return!1;let t=this.toRealPath(e);try{let S=this.resolveAndValidate(t,e);return await I.promises.access(S),!0}catch{return!1}}async stat(e){h$3(e,`stat`);let t=this.toRealPath(e),S=this.resolveAndValidate(t,e);try{let t=await I.promises.lstat(S);if(!this.allowSymlinks&&t.isSymbolicLink())throw Error(`EACCES: permission denied, '${e}' is a symlink`);return{isFile:t.isFile(),isDirectory:t.isDirectory(),isSymbolicLink:t.isSymbolicLink(),mode:t.mode,size:t.size,mtime:t.mtime}}catch(t){if(t.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, stat '${e}'`);this.sanitizeError(t,e,`stat`)}}async lstat(e){h$3(e,`lstat`);let t=this.toRealPath(e),S=this.validateParent(t,e);try{let e=await I.promises.lstat(S);return{isFile:e.isFile(),isDirectory:e.isDirectory(),isSymbolicLink:e.isSymbolicLink(),mode:e.mode,size:e.size,mtime:e.mtime}}catch(t){if(t.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, lstat '${e}'`);this.sanitizeError(t,e,`lstat`)}}async mkdir(e,t){h$3(e,`mkdir`);let S=this.toRealPath(e),w=this.resolveAndValidate(S,e);try{await I.promises.mkdir(w,{recursive:t?.recursive})}catch(t){let S=t;if(S.code===`EEXIST`)throw Error(`EEXIST: file already exists, mkdir '${e}'`);if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, mkdir '${e}'`);this.sanitizeError(t,e,`mkdir`)}}async readdir(e){return(await this.readdirWithFileTypes(e)).map(e=>e.name)}async readdirWithFileTypes(e){h$3(e,`scandir`);let t=this.toRealPath(e),S=this.resolveAndValidate(t,e);try{if(!this.allowSymlinks&&(await I.promises.lstat(S)).isSymbolicLink())throw Error(`EACCES: permission denied, '${e}' is a symlink`);return(await I.promises.readdir(S,{withFileTypes:!0})).map(e=>({name:e.name,isFile:e.isFile(),isDirectory:e.isDirectory(),isSymbolicLink:e.isSymbolicLink()})).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:0)}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, scandir '${e}'`);if(S.code===`ENOTDIR`)throw Error(`ENOTDIR: not a directory, scandir '${e}'`);this.sanitizeError(t,e,`scandir`)}}async rm(e,t){h$3(e,`rm`);let S=this.toRealPath(e),w=this.resolveAndValidate(S,e);try{await I.promises.rm(w,{recursive:t?.recursive??!1,force:t?.force??!1})}catch(S){let w=S;if(w.code===`ENOENT`&&!t?.force)throw Error(`ENOENT: no such file or directory, rm '${e}'`);if(w.code===`ENOTEMPTY`)throw Error(`ENOTEMPTY: directory not empty, rm '${e}'`);this.sanitizeError(S,e,`rm`)}}async cp(e,t,S){h$3(e,`cp`),h$3(t,`cp`);let w=this.toRealPath(e),E=this.toRealPath(t),D=this.resolveAndValidate(w,e),O=this.resolveAndValidate(E,t);try{await I.promises.cp(D,O,{recursive:S?.recursive??!1,filter:async e=>{try{if(I.lstatSync(e).isSymbolicLink()){let t=await I.promises.realpath(e).catch(()=>null);return t===null?!1:d$1(t,this.canonicalRoot)}return!0}catch(e){return e.code===`ENOENT`}}})}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, cp '${e}'`);if(S.code===`EISDIR`)throw Error(`EISDIR: is a directory, cp '${e}'`);this.sanitizeError(t,e,`cp`)}}async mv(e,t){h$3(e,`mv`),h$3(t,`mv`);let S=this.toRealPath(e),w=this.toRealPath(t),E=this.validateParent(S,e),D=this.validateParent(w,t);try{if((await I.promises.lstat(E)).isSymbolicLink()){let S=await I.promises.readlink(E),w=U.resolve(U.dirname(D),S);if(!d$1(await I.promises.realpath(w).catch(()=>w),this.canonicalRoot))throw Error(`EACCES: permission denied, mv '${e}' -> '${t}' would create symlink escaping sandbox`)}}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, mv '${e}'`);if(S.message?.includes(`EACCES`)||S.message?.includes(`escaping sandbox`))throw t}let O=U.dirname(D);try{await I.promises.mkdir(O,{recursive:!0})}catch(e){this.sanitizeError(e,t,`mv`)}try{await I.promises.rename(E,D)}catch(S){let w=S;if(w.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, mv '${e}'`);if(w.code===`EXDEV`){await this.cp(e,t,{recursive:!0}),await this.rm(e,{recursive:!0});return}this.sanitizeError(S,e,`mv`)}try{if(I.lstatSync(D).isDirectory()&&this.findEscapingSymlinks(D).length>0)throw await I.promises.rename(D,E),Error(`EACCES: permission denied, mv '${e}' -> '${t}' would create symlinks escaping sandbox`)}catch(e){if(e.message?.includes(`EACCES`)||e.message?.includes(`escaping sandbox`))throw e}}resolvePath(e,t){return y(e,t)}getAllPaths(){let e=[];return this.scanDir(`/`,e),e}sanitizeError(e,t,S){N(e,t,S,ol)}findEscapingSymlinks(e){let t=[];try{let S=I.readdirSync(e);for(let w of S){let S=U.join(e,w);try{let w=I.lstatSync(S);if(w.isSymbolicLink()){let w=I.readlinkSync(S),E=U.resolve(e,w),D;try{D=I.realpathSync(E)}catch{D=E}d$1(D,this.canonicalRoot)||t.push(S)}else w.isDirectory()&&t.push(...this.findEscapingSymlinks(S))}catch{}}}catch{}return t}scanDir(e,t){let S=this.toRealPath(e),w;try{w=this.resolveAndValidate(S,e)}catch{return}try{let S=I.readdirSync(w);for(let E of S){let S=e===`/`?`/${E}`:`${e}/${E}`;t.push(S);let D=U.join(w,E);I.lstatSync(D).isDirectory()&&this.scanDir(S,t)}}catch{}}async chmod(e,t){h$3(e,`chmod`);let S=this.toRealPath(e),w=this.resolveAndValidate(S,e);try{let e=this.allowSymlinks?I.constants.O_RDONLY:I.constants.O_RDONLY|I.constants.O_NOFOLLOW,S=await I.promises.open(w,e);try{await S.chmod(t)}finally{await S.close()}}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, chmod '${e}'`);if(S.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`chmod`)}}async symlink(e,t){if(!this.allowSymlinks)throw Error(`EPERM: operation not permitted, symlink '${t}'`);h$3(t,`symlink`);let S=this.toRealPath(t),w=this.validateParent(S,t),E=c$2(t),D=c$2(U.dirname(E)),O=e.startsWith(`/`)?c$2(e):c$2(D===`/`?`/${e}`:`${D}/${e}`),k=U.join(this.canonicalRoot,O),j=U.dirname(w),F=e.startsWith(`/`)?k:U.relative(j,k)||`.`;try{await I.promises.symlink(F,w)}catch(e){if(e.code===`EEXIST`)throw Error(`EEXIST: file already exists, symlink '${t}'`);this.sanitizeError(e,t,`symlink`)}}async link(e,t){h$3(e,`link`),h$3(t,`link`);let S=this.toRealPath(e),w=this.toRealPath(t),E=this.resolveAndValidate(S,e),D=this.resolveAndValidate(w,t);try{await I.promises.link(E,D)}catch(S){let w=S;if(w.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, link '${e}'`);if(w.code===`EEXIST`)throw Error(`EEXIST: file already exists, link '${t}'`);if(w.code===`EPERM`)throw Error(`EPERM: operation not permitted, link '${e}'`);this.sanitizeError(S,e,`link`)}}async readlink(e){h$3(e,`readlink`);let t=this.toRealPath(e),S=this.validateParent(t,e);try{let t=await I.promises.readlink(S),w=c$2(e),E=U.dirname(w),D=U.isAbsolute(t)?t:U.resolve(U.dirname(S),t),O=await I.promises.realpath(D).catch(()=>D);if(d$1(O,this.canonicalRoot)){let e=O.slice(this.canonicalRoot.length)||`/`;return E===`/`?e.startsWith(`/`)?e.slice(1)||`.`:e:U.relative(E,e)}return U.basename(t)}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, readlink '${e}'`);if(S.code===`EINVAL`)throw Error(`EINVAL: invalid argument, readlink '${e}'`);this.sanitizeError(t,e,`readlink`)}}async realpath(e){h$3(e,`realpath`);let t=this.toRealPath(e);try{this.resolveAndValidate(t,e)}catch{throw Error(`ENOENT: no such file or directory, realpath '${e}'`)}let S;try{S=await I.promises.realpath(t)}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, realpath '${e}'`);if(S.code===`ELOOP`)throw Error(`ELOOP: too many levels of symbolic links, realpath '${e}'`);this.sanitizeError(t,e,`realpath`)}if(d$1(S,this.canonicalRoot))return S.slice(this.canonicalRoot.length)||`/`;throw Error(`ENOENT: no such file or directory, realpath '${e}'`)}async utimes(e,t,S){h$3(e,`utimes`);let w=this.toRealPath(e),E=this.resolveAndValidate(w,e);try{let e=this.allowSymlinks?I.constants.O_RDONLY:I.constants.O_RDONLY|I.constants.O_NOFOLLOW,w=await I.promises.open(E,e);try{await w.utimes(t,S)}finally{await w.close()}}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, utimes '${e}'`);if(S.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`utimes`)}}},require_quote=__commonJSMin$1(((e,t)=>{t.exports=function(e){return e.map(function(e){return e===``?`''`:e&&typeof e==`object`?e.op.replace(/(.)/g,`\\$1`):/["\s\\]/.test(e)&&!/'/.test(e)?`'`+e.replace(/(['])/g,`\\$1`)+`'`:/["'\s]/.test(e)?`"`+e.replace(/(["\\$`!])/g,`\\$1`)+`"`:String(e).replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g,`$1\\$2`)}).join(` `)}})),require_parse=__commonJSMin$1(((e,t)=>{for(var S=`(?:`+[`\\|\\|`,`\\&\\&`,`;;`,`\\|\\&`,`\\<\\(`,`\\<\\<\\<`,`>>`,`>\\&`,`<\\&`,`[&;()|<>]`].join(`|`)+`)`,w=RegExp(`^`+S+`$`),E=`|&;()<> \\t`,D=`"((\\\\"|[^"])*?)"`,O=`'((\\\\'|[^'])*?)'`,k=/^#$/,j=`'`,F=`"`,L=`$`,B=``,H=4294967296,q=0;q<4;q++)B+=(H*Math.random()).toString(16);var J=RegExp(`^`+B);function Y(e,t){for(var S=t.lastIndex,w=[],E;E=t.exec(e);)w.push(E),t.lastIndex===E.index&&(t.lastIndex+=1);return t.lastIndex=S,w}function ee(e,t,S){var w=typeof e==`function`?e(S):e[S];return w===void 0&&S!=``?w=``:w===void 0&&(w=`$`),typeof w==`object`?t+B+JSON.stringify(w)+B:t+w}function te(e,t,B){B||={};var H=B.escape||`\\`,q=`(\\`+H+`['"`+E+`]|[^\\s'"`+E+`])+`,J=Y(e,new RegExp([`(`+S+`)`,`(`+q+`|`+D+`|`+O+`)+`].join(`|`),`g`));if(J.length===0)return[];t||={};var te=!1;return J.map(function(S){var E=S[0];if(!E||te)return;if(w.test(E))return{op:E};var D=!1,O=!1,B=``,q=!1,J;function Y(){J+=1;var e,S,w=E.charAt(J);if(w===`{`){if(J+=1,E.charAt(J)===`}`)throw Error(`Bad substitution: `+E.slice(J-2,J+1));if(e=E.indexOf(`}`,J),e<0)throw Error(`Bad substitution: `+E.slice(J));S=E.slice(J,e),J=e}else if(/[*@#?$!_-]/.test(w))S=w,J+=1;else{var D=E.slice(J);e=D.match(/[^\w\d_]/),e?(S=D.slice(0,e.index),J+=e.index-1):(S=D,J=E.length)}return ee(t,``,S)}for(J=0;J<E.length;J++){var ne=E.charAt(J);if(q||=!D&&(ne===`*`||ne===`?`),O)B+=ne,O=!1;else if(D)ne===D?D=!1:D==j?B+=ne:ne===H?(J+=1,ne=E.charAt(J),ne===F||ne===H||ne===L?B+=ne:B+=H+ne):ne===L?B+=Y():B+=ne;else if(ne===F||ne===j)D=ne;else if(w.test(ne))return{op:E};else if(k.test(ne)){te=!0;var ae={comment:e.slice(S.index+J+1)};return B.length?[B,ae]:[ae]}else ne===H?O=!0:ne===L?B+=Y():B+=ne}return q?{op:`glob`,pattern:B}:B}).reduce(function(e,t){return t===void 0?e:e.concat(t)},[])}t.exports=function(e,t,S){var w=te(e,t,S);return typeof t==`function`?w.reduce(function(e,t){if(typeof t==`object`)return e.concat(t);var S=t.split(RegExp(`(`+B+`.*?`+B+`)`,`g`));return S.length===1?e.concat(S[0]):e.concat(S.filter(Boolean).map(function(e){return J.test(e)?JSON.parse(e.split(B)[1]):e}))},[]):w}})),require_shell_quote=__commonJSMin$1((e=>{e.quote=require_quote(),e.parse=require_parse()})),require_ignore=__commonJSMin$1(((e,t)=>{function S(e){return Array.isArray(e)?e:[e]}let w=``,E=` `,D=`\\`,O=/^\s+$/,k=/(?:[^\\]|^)\\$/,j=/^\\!/,F=/^\\#/,L=/\r?\n/g,B=/^\.*\/|^\.+$/,H=`/`,q=`node-ignore`;typeof Symbol<`u`&&(q=Symbol.for(`node-ignore`));let J=q,Y=(e,t,S)=>Object.defineProperty(e,t,{value:S}),ee=/([0-z])-([0-z])/g,te=()=>!1,ne=e=>e.replace(ee,(e,t,S)=>t.charCodeAt(0)<=S.charCodeAt(0)?e:``),ae=e=>{let{length:t}=e;return e.slice(0,t-t%2)},oe=[[/^\uFEFF/,()=>``],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,S)=>t+(S.indexOf(`\\`)===0?` `:``)],[/(\\+?)\s/g,(e,t)=>{let{length:S}=t;return t.slice(0,S-S%2)+` `}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>`[^/]`],[/^\//,()=>`^`],[/\//g,()=>`\\/`],[/^\^*\\\*\\\*\\\//,()=>`^(?:.*\\/)?`],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?`^`:`(?:^|\\/)`}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,S)=>t+6<S.length?`(?:\\/[^\\/]+)*`:`\\/.+`],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,S)=>t+S.replace(/\\\*/g,`[^\\/]*`)],[/\\\\\\(?=[$.|*+(){^])/g,()=>`\\`],[/\\\\/g,()=>`\\`],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,S,w,E)=>t===`\\`?`\\[${S}${ae(w)}${E}`:E===`]`&&w.length%2==0?`[${ne(S)}${w}]`:`[]`],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(e,t)=>`${t?`${t}[^/]+`:`[^/]*`}(?=$|\\/$)`]],se=Object.create(null),ce=(e,t)=>{let S=se[e];return S||(S=oe.reduce((t,[S,w])=>t.replace(S,w.bind(e)),e),se[e]=S),t?new RegExp(S,`i`):new RegExp(S)},ue=e=>typeof e==`string`,de=e=>e&&ue(e)&&!O.test(e)&&!k.test(e)&&e.indexOf(`#`)!==0,fe=e=>e.split(L);var me=class{constructor(e,t,S,w){this.origin=e,this.pattern=t,this.negative=S,this.regex=w}};let ge=(e,t)=>{let S=e,w=!1;e.indexOf(`!`)===0&&(w=!0,e=e.substr(1)),e=e.replace(j,`!`).replace(F,`#`);let E=ce(e,t);return new me(S,e,w,E)},_e=(e,t)=>{throw new t(e)},ve=(e,t,S)=>ue(e)?e?ve.isNotRelative(e)?S(`path should be a \`path.relative()\`d string, but got "${t}"`,RangeError):!0:S(`path must not be empty`,TypeError):S(`path must be a string, but got \`${t}\``,TypeError),ye=e=>B.test(e);ve.isNotRelative=ye,ve.convert=e=>e;var Ce=class{constructor({ignorecase:e=!0,ignoreCase:t=e,allowRelativePaths:S=!1}={}){Y(this,J,!0),this._rules=[],this._ignoreCase=t,this._allowRelativePaths=S,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(e){if(e&&e[J]){this._rules=this._rules.concat(e._rules),this._added=!0;return}if(de(e)){let t=ge(e,this._ignoreCase);this._added=!0,this._rules.push(t)}}add(e){return this._added=!1,S(ue(e)?fe(e):e).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(e){return this.add(e)}_testOne(e,t){let S=!1,w=!1;return this._rules.forEach(E=>{let{negative:D}=E;w===D&&S!==w||D&&!S&&!w&&!t||E.regex.test(e)&&(S=!D,w=D)}),{ignored:S,unignored:w}}_test(e,t,S,w){let E=e&&ve.convert(e);return ve(E,e,this._allowRelativePaths?te:_e),this._t(E,t,S,w)}_t(e,t,S,w){if(e in t)return t[e];if(w||=e.split(`/`),w.pop(),!w.length)return t[e]=this._testOne(e,S);let E=this._t(w.join(`/`)+`/`,t,S,w);return t[e]=E.ignored?E:this._testOne(e,S)}ignores(e){return this._test(e,this._ignoreCache,!1).ignored}createFilter(){return e=>!this.ignores(e)}filter(e){return S(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}};let we=e=>new Ce(e);if(we.isPathValid=e=>ve(e&&ve.convert(e),e,te),we.default=we,t.exports=we,typeof process<`u`&&(process.env&&process.env.IGNORE_TEST_WIN32||process.platform===`win32`)){ve.convert=e=>/^\\\\\?\\/.test(e)||/["<>|\u0000-\u001F]+/u.test(e)?e:e.replace(/\\/g,`/`);let e=/^[a-z]:\//i;ve.isNotRelative=t=>e.test(t)||ye(t)}})),require_constants$1=__commonJSMin$1(((e,t)=>{let S=[`nodebuffer`,`arraybuffer`,`fragments`],w=typeof Blob<`u`;w&&S.push(`blob`),t.exports={BINARY_TYPES:S,CLOSE_TIMEOUT:3e4,EMPTY_BUFFER:Buffer.alloc(0),GUID:`258EAFA5-E914-47DA-95CA-C5AB0DC85B11`,hasBlob:w,kForOnEventAttribute:Symbol(`kIsForOnEventAttribute`),kListener:Symbol(`kListener`),kStatusCode:Symbol(`status-code`),kWebSocket:Symbol(`websocket`),NOOP:()=>{}}})),require_buffer_util$1=__commonJSMin$1(((e,t)=>{let{EMPTY_BUFFER:S}=require_constants$1(),w=Buffer[Symbol.species];function E(e,t){if(e.length===0)return S;if(e.length===1)return e[0];let E=Buffer.allocUnsafe(t),D=0;for(let t=0;t<e.length;t++){let S=e[t];E.set(S,D),D+=S.length}return D<t?new w(E.buffer,E.byteOffset,D):E}function D(e,t,S,w,E){for(let D=0;D<E;D++)S[w+D]=e[D]^t[D&3]}function O(e,t){for(let S=0;S<e.length;S++)e[S]^=t[S&3]}function k(e){return e.length===e.buffer.byteLength?e.buffer:e.buffer.slice(e.byteOffset,e.byteOffset+e.length)}function j(e){if(j.readOnly=!0,Buffer.isBuffer(e))return e;let t;return e instanceof ArrayBuffer?t=new w(e):ArrayBuffer.isView(e)?t=new w(e.buffer,e.byteOffset,e.byteLength):(t=Buffer.from(e),j.readOnly=!1),t}if(t.exports={concat:E,mask:D,toArrayBuffer:k,toBuffer:j,unmask:O},!process.env.WS_NO_BUFFER_UTIL)try{let e=__require$1(`bufferutil`);t.exports.mask=function(t,S,w,E,O){O<48?D(t,S,w,E,O):e.mask(t,S,w,E,O)},t.exports.unmask=function(t,S){t.length<32?O(t,S):e.unmask(t,S)}}catch{}})),require_limiter$1=__commonJSMin$1(((e,t)=>{let S=Symbol(`kDone`),w=Symbol(`kRun`);t.exports=class{constructor(e){this[S]=()=>{this.pending--,this[w]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[w]()}[w](){if(this.pending!==this.concurrency&&this.jobs.length){let e=this.jobs.shift();this.pending++,e(this[S])}}}})),require_permessage_deflate$1=__commonJSMin$1(((e,t)=>{let S=__require$1(`zlib`),w=require_buffer_util$1(),E=require_limiter$1(),{kStatusCode:D}=require_constants$1(),O=Buffer[Symbol.species],k=Buffer.from([0,0,255,255]),j=Symbol(`permessage-deflate`),F=Symbol(`total-length`),L=Symbol(`callback`),B=Symbol(`buffers`),H=Symbol(`error`),q;t.exports=class{constructor(e){this._options=e||{},this._threshold=this._options.threshold===void 0?1024:this._options.threshold,this._maxPayload=this._options.maxPayload|0,this._isServer=!!this._options.isServer,this._deflate=null,this._inflate=null,this.params=null,q||=new E(this._options.concurrencyLimit===void 0?10:this._options.concurrencyLimit)}static get extensionName(){return`permessage-deflate`}offer(){let e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits??(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&=(this._inflate.close(),null),this._deflate){let e=this._deflate[L];this._deflate.close(),this._deflate=null,e&&e(Error(`The deflate stream was closed while data was being processed`))}}acceptAsServer(e){let t=this._options,S=e.find(e=>!(t.serverNoContextTakeover===!1&&e.server_no_context_takeover||e.server_max_window_bits&&(t.serverMaxWindowBits===!1||typeof t.serverMaxWindowBits==`number`&&t.serverMaxWindowBits>e.server_max_window_bits)||typeof t.clientMaxWindowBits==`number`&&!e.client_max_window_bits));if(!S)throw Error(`None of the extension offers can be accepted`);return t.serverNoContextTakeover&&(S.server_no_context_takeover=!0),t.clientNoContextTakeover&&(S.client_no_context_takeover=!0),typeof t.serverMaxWindowBits==`number`&&(S.server_max_window_bits=t.serverMaxWindowBits),typeof t.clientMaxWindowBits==`number`?S.client_max_window_bits=t.clientMaxWindowBits:(S.client_max_window_bits===!0||t.clientMaxWindowBits===!1)&&delete S.client_max_window_bits,S}acceptAsClient(e){let t=e[0];if(this._options.clientNoContextTakeover===!1&&t.client_no_context_takeover)throw Error(`Unexpected parameter "client_no_context_takeover"`);if(!t.client_max_window_bits)typeof this._options.clientMaxWindowBits==`number`&&(t.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits==`number`&&t.client_max_window_bits>this._options.clientMaxWindowBits)throw Error(`Unexpected or invalid parameter "client_max_window_bits"`);return t}normalizeParams(e){return e.forEach(e=>{Object.keys(e).forEach(t=>{let S=e[t];if(S.length>1)throw Error(`Parameter "${t}" must have only a single value`);if(S=S[0],t===`client_max_window_bits`){if(S!==!0){let e=+S;if(!Number.isInteger(e)||e<8||e>15)throw TypeError(`Invalid value for parameter "${t}": ${S}`);S=e}else if(!this._isServer)throw TypeError(`Invalid value for parameter "${t}": ${S}`)}else if(t===`server_max_window_bits`){let e=+S;if(!Number.isInteger(e)||e<8||e>15)throw TypeError(`Invalid value for parameter "${t}": ${S}`);S=e}else if(t===`client_no_context_takeover`||t===`server_no_context_takeover`){if(S!==!0)throw TypeError(`Invalid value for parameter "${t}": ${S}`)}else throw Error(`Unknown parameter "${t}"`);e[t]=S})}),e}decompress(e,t,S){q.add(w=>{this._decompress(e,t,(e,t)=>{w(),S(e,t)})})}compress(e,t,S){q.add(w=>{this._compress(e,t,(e,t)=>{w(),S(e,t)})})}_decompress(e,t,E){let D=this._isServer?`client`:`server`;if(!this._inflate){let e=`${D}_max_window_bits`,t=typeof this.params[e]==`number`?this.params[e]:S.Z_DEFAULT_WINDOWBITS;this._inflate=S.createInflateRaw({...this._options.zlibInflateOptions,windowBits:t}),this._inflate[j]=this,this._inflate[F]=0,this._inflate[B]=[],this._inflate.on(`error`,ee),this._inflate.on(`data`,Y)}this._inflate[L]=E,this._inflate.write(e),t&&this._inflate.write(k),this._inflate.flush(()=>{let e=this._inflate[H];if(e){this._inflate.close(),this._inflate=null,E(e);return}let S=w.concat(this._inflate[B],this._inflate[F]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[F]=0,this._inflate[B]=[],t&&this.params[`${D}_no_context_takeover`]&&this._inflate.reset()),E(null,S)})}_compress(e,t,E){let D=this._isServer?`server`:`client`;if(!this._deflate){let e=`${D}_max_window_bits`,t=typeof this.params[e]==`number`?this.params[e]:S.Z_DEFAULT_WINDOWBITS;this._deflate=S.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:t}),this._deflate[F]=0,this._deflate[B]=[],this._deflate.on(`data`,J)}this._deflate[L]=E,this._deflate.write(e),this._deflate.flush(S.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let e=w.concat(this._deflate[B],this._deflate[F]);t&&(e=new O(e.buffer,e.byteOffset,e.length-4)),this._deflate[L]=null,this._deflate[F]=0,this._deflate[B]=[],t&&this.params[`${D}_no_context_takeover`]&&this._deflate.reset(),E(null,e)})}};function J(e){this[B].push(e),this[F]+=e.length}function Y(e){if(this[F]+=e.length,this[j]._maxPayload<1||this[F]<=this[j]._maxPayload){this[B].push(e);return}this[H]=RangeError(`Max payload size exceeded`),this[H].code=`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`,this[H][D]=1009,this.removeListener(`data`,Y),this.reset()}function ee(e){if(this[j]._inflate=null,this[H]){this[L](this[H]);return}e[D]=1007,this[L](e)}})),require_validation$1=__commonJSMin$1(((e,t)=>{let{isUtf8:S}=__require$1(`buffer`),{hasBlob:w}=require_constants$1(),E=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function D(e){return e>=1e3&&e<=1014&&e!==1004&&e!==1005&&e!==1006||e>=3e3&&e<=4999}function O(e){let t=e.length,S=0;for(;S<t;)if(!(e[S]&128))S++;else if((e[S]&224)==192){if(S+1===t||(e[S+1]&192)!=128||(e[S]&254)==192)return!1;S+=2}else if((e[S]&240)==224){if(S+2>=t||(e[S+1]&192)!=128||(e[S+2]&192)!=128||e[S]===224&&(e[S+1]&224)==128||e[S]===237&&(e[S+1]&224)==160)return!1;S+=3}else if((e[S]&248)==240){if(S+3>=t||(e[S+1]&192)!=128||(e[S+2]&192)!=128||(e[S+3]&192)!=128||e[S]===240&&(e[S+1]&240)==128||e[S]===244&&e[S+1]>143||e[S]>244)return!1;S+=4}else return!1;return!0}function k(e){return w&&typeof e==`object`&&typeof e.arrayBuffer==`function`&&typeof e.type==`string`&&typeof e.stream==`function`&&(e[Symbol.toStringTag]===`Blob`||e[Symbol.toStringTag]===`File`)}if(t.exports={isBlob:k,isValidStatusCode:D,isValidUTF8:O,tokenChars:E},S)t.exports.isValidUTF8=function(e){return e.length<24?O(e):S(e)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{let e=__require$1(`utf-8-validate`);t.exports.isValidUTF8=function(t){return t.length<32?O(t):e(t)}}catch{}})),require_receiver$1=__commonJSMin$1(((e,t)=>{let{Writable:S}=__require$1(`stream`),w=require_permessage_deflate$1(),{BINARY_TYPES:E,EMPTY_BUFFER:D,kStatusCode:O,kWebSocket:k}=require_constants$1(),{concat:j,toArrayBuffer:F,unmask:L}=require_buffer_util$1(),{isValidStatusCode:B,isValidUTF8:H}=require_validation$1(),q=Buffer[Symbol.species],J=0,Y=1,ee=2,te=3,ne=4,ae=5,oe=6;t.exports=class extends S{constructor(e={}){super(),this._allowSynchronousEvents=e.allowSynchronousEvents===void 0?!0:e.allowSynchronousEvents,this._binaryType=e.binaryType||E[0],this._extensions=e.extensions||{},this._isServer=!!e.isServer,this._maxPayload=e.maxPayload|0,this._skipUTF8Validation=!!e.skipUTF8Validation,this[k]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._errored=!1,this._loop=!1,this._state=0}_write(e,t,S){if(this._opcode===8&&this._state==0)return S();this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(S)}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e<this._buffers[0].length){let t=this._buffers[0];return this._buffers[0]=new q(t.buffer,t.byteOffset+e,t.length-e),new q(t.buffer,t.byteOffset,e)}let t=Buffer.allocUnsafe(e);do{let S=this._buffers[0],w=t.length-e;e>=S.length?t.set(this._buffers.shift(),w):(t.set(new Uint8Array(S.buffer,S.byteOffset,e),w),this._buffers[0]=new q(S.buffer,S.byteOffset+e,S.length-e)),e-=S.length}while(e>0);return t}startLoop(e){this._loop=!0;do switch(this._state){case 0:this.getInfo(e);break;case 1:this.getPayloadLength16(e);break;case 2:this.getPayloadLength64(e);break;case 3:this.getMask();break;case 4:this.getData(e);break;case 5:case 6:this._loop=!1;return}while(this._loop);this._errored||e()}getInfo(e){if(this._bufferedBytes<2){this._loop=!1;return}let t=this.consume(2);if(t[0]&48){e(this.createError(RangeError,`RSV2 and RSV3 must be clear`,!0,1002,`WS_ERR_UNEXPECTED_RSV_2_3`));return}let S=(t[0]&64)==64;if(S&&!this._extensions[w.extensionName]){e(this.createError(RangeError,`RSV1 must be clear`,!0,1002,`WS_ERR_UNEXPECTED_RSV_1`));return}if(this._fin=(t[0]&128)==128,this._opcode=t[0]&15,this._payloadLength=t[1]&127,this._opcode===0){if(S){e(this.createError(RangeError,`RSV1 must be clear`,!0,1002,`WS_ERR_UNEXPECTED_RSV_1`));return}if(!this._fragmented){e(this.createError(RangeError,`invalid opcode 0`,!0,1002,`WS_ERR_INVALID_OPCODE`));return}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){e(this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,`WS_ERR_INVALID_OPCODE`));return}this._compressed=S}else if(this._opcode>7&&this._opcode<11){if(!this._fin){e(this.createError(RangeError,`FIN must be set`,!0,1002,`WS_ERR_EXPECTED_FIN`));return}if(S){e(this.createError(RangeError,`RSV1 must be clear`,!0,1002,`WS_ERR_UNEXPECTED_RSV_1`));return}if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1){e(this.createError(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,`WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH`));return}}else{e(this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,`WS_ERR_INVALID_OPCODE`));return}if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(t[1]&128)==128,this._isServer){if(!this._masked){e(this.createError(RangeError,`MASK must be set`,!0,1002,`WS_ERR_EXPECTED_MASK`));return}}else if(this._masked){e(this.createError(RangeError,`MASK must be clear`,!0,1002,`WS_ERR_UNEXPECTED_MASK`));return}this._payloadLength===126?this._state=1:this._payloadLength===127?this._state=2:this.haveLength(e)}getPayloadLength16(e){if(this._bufferedBytes<2){this._loop=!1;return}this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength(e)}getPayloadLength64(e){if(this._bufferedBytes<8){this._loop=!1;return}let t=this.consume(8),S=t.readUInt32BE(0);if(S>2**21-1){e(this.createError(RangeError,`Unsupported WebSocket frame: payload length > 2^53 - 1`,!1,1009,`WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH`));return}this._payloadLength=S*2**32+t.readUInt32BE(4),this.haveLength(e)}haveLength(e){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0)){e(this.createError(RangeError,`Max payload size exceeded`,!1,1009,`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`));return}this._masked?this._state=3:this._state=4}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=4}getData(e){let t=D;if(this._payloadLength){if(this._bufferedBytes<this._payloadLength){this._loop=!1;return}t=this.consume(this._payloadLength),this._masked&&(this._mask[0]|this._mask[1]|this._mask[2]|this._mask[3])!==0&&L(t,this._mask)}if(this._opcode>7){this.controlMessage(t,e);return}if(this._compressed){this._state=5,this.decompress(t,e);return}t.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(t)),this.dataMessage(e)}decompress(e,t){this._extensions[w.extensionName].decompress(e,this._fin,(e,S)=>{if(e)return t(e);if(S.length){if(this._messageLength+=S.length,this._messageLength>this._maxPayload&&this._maxPayload>0){t(this.createError(RangeError,`Max payload size exceeded`,!1,1009,`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`));return}this._fragments.push(S)}this.dataMessage(t),this._state===0&&this.startLoop(t)})}dataMessage(e){if(!this._fin){this._state=0;return}let t=this._messageLength,S=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let w;w=this._binaryType===`nodebuffer`?j(S,t):this._binaryType===`arraybuffer`?F(j(S,t)):this._binaryType===`blob`?new Blob(S):S,this._allowSynchronousEvents?(this.emit(`message`,w,!0),this._state=0):(this._state=6,setImmediate(()=>{this.emit(`message`,w,!0),this._state=0,this.startLoop(e)}))}else{let w=j(S,t);if(!this._skipUTF8Validation&&!H(w)){e(this.createError(Error,`invalid UTF-8 sequence`,!0,1007,`WS_ERR_INVALID_UTF8`));return}this._state===5||this._allowSynchronousEvents?(this.emit(`message`,w,!1),this._state=0):(this._state=6,setImmediate(()=>{this.emit(`message`,w,!1),this._state=0,this.startLoop(e)}))}}controlMessage(e,t){if(this._opcode===8){if(e.length===0)this._loop=!1,this.emit(`conclude`,1005,D),this.end();else{let S=e.readUInt16BE(0);if(!B(S)){t(this.createError(RangeError,`invalid status code ${S}`,!0,1002,`WS_ERR_INVALID_CLOSE_CODE`));return}let w=new q(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!H(w)){t(this.createError(Error,`invalid UTF-8 sequence`,!0,1007,`WS_ERR_INVALID_UTF8`));return}this._loop=!1,this.emit(`conclude`,S,w),this.end()}this._state=0;return}this._allowSynchronousEvents?(this.emit(this._opcode===9?`ping`:`pong`,e),this._state=0):(this._state=6,setImmediate(()=>{this.emit(this._opcode===9?`ping`:`pong`,e),this._state=0,this.startLoop(t)}))}createError(e,t,S,w,E){this._loop=!1,this._errored=!0;let D=new e(S?`Invalid WebSocket frame: ${t}`:t);return Error.captureStackTrace(D,this.createError),D.code=E,D[O]=w,D}}})),require_sender$1=__commonJSMin$1(((e,t)=>{let{Duplex:S}=__require$1(`stream`),{randomFillSync:w}=__require$1(`crypto`),E=require_permessage_deflate$1(),{EMPTY_BUFFER:D,kWebSocket:O,NOOP:k}=require_constants$1(),{isBlob:j,isValidStatusCode:F}=require_validation$1(),{mask:L,toBuffer:B}=require_buffer_util$1(),H=Symbol(`kByteLength`),q=Buffer.alloc(4),J=8*1024,Y,ee=J,te=0,ne=1,ae=2;t.exports=class e{constructor(e,t,S){this._extensions=t||{},S&&(this._generateMask=S,this._maskBuffer=Buffer.alloc(4)),this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._queue=[],this._state=0,this.onerror=k,this[O]=void 0}static frame(e,t){let S,E=!1,D=2,O=!1;t.mask&&(S=t.maskBuffer||q,t.generateMask?t.generateMask(S):(ee===J&&(Y===void 0&&(Y=Buffer.alloc(J)),w(Y,0,J),ee=0),S[0]=Y[ee++],S[1]=Y[ee++],S[2]=Y[ee++],S[3]=Y[ee++]),O=(S[0]|S[1]|S[2]|S[3])===0,D=6);let k;typeof e==`string`?(!t.mask||O)&&t[H]!==void 0?k=t[H]:(e=Buffer.from(e),k=e.length):(k=e.length,E=t.mask&&t.readOnly&&!O);let j=k;k>=65536?(D+=8,j=127):k>125&&(D+=2,j=126);let F=Buffer.allocUnsafe(E?k+D:D);return F[0]=t.fin?t.opcode|128:t.opcode,t.rsv1&&(F[0]|=64),F[1]=j,j===126?F.writeUInt16BE(k,2):j===127&&(F[2]=F[3]=0,F.writeUIntBE(k,4,6)),!t.mask||(F[1]|=128,F[D-4]=S[0],F[D-3]=S[1],F[D-2]=S[2],F[D-1]=S[3],O)?[F,e]:E?(L(e,S,F,D,k),[F]):(L(e,S,e,0,k),[F,e])}close(t,S,w,E){let O;if(t===void 0)O=D;else if(typeof t!=`number`||!F(t))throw TypeError(`First argument must be a valid error code number`);else if(S===void 0||!S.length)O=Buffer.allocUnsafe(2),O.writeUInt16BE(t,0);else{let e=Buffer.byteLength(S);if(e>123)throw RangeError(`The message must not be greater than 123 bytes`);O=Buffer.allocUnsafe(2+e),O.writeUInt16BE(t,0),typeof S==`string`?O.write(S,2):O.set(S,2)}let k={[H]:O.length,fin:!0,generateMask:this._generateMask,mask:w,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._state===0?this.sendFrame(e.frame(O,k),E):this.enqueue([this.dispatch,O,!1,k,E])}ping(t,S,w){let E,D;if(typeof t==`string`?(E=Buffer.byteLength(t),D=!1):j(t)?(E=t.size,D=!1):(t=B(t),E=t.length,D=B.readOnly),E>125)throw RangeError(`The data size must not be greater than 125 bytes`);let O={[H]:E,fin:!0,generateMask:this._generateMask,mask:S,maskBuffer:this._maskBuffer,opcode:9,readOnly:D,rsv1:!1};j(t)?this._state===0?this.getBlobData(t,!1,O,w):this.enqueue([this.getBlobData,t,!1,O,w]):this._state===0?this.sendFrame(e.frame(t,O),w):this.enqueue([this.dispatch,t,!1,O,w])}pong(t,S,w){let E,D;if(typeof t==`string`?(E=Buffer.byteLength(t),D=!1):j(t)?(E=t.size,D=!1):(t=B(t),E=t.length,D=B.readOnly),E>125)throw RangeError(`The data size must not be greater than 125 bytes`);let O={[H]:E,fin:!0,generateMask:this._generateMask,mask:S,maskBuffer:this._maskBuffer,opcode:10,readOnly:D,rsv1:!1};j(t)?this._state===0?this.getBlobData(t,!1,O,w):this.enqueue([this.getBlobData,t,!1,O,w]):this._state===0?this.sendFrame(e.frame(t,O),w):this.enqueue([this.dispatch,t,!1,O,w])}send(e,t,S){let w=this._extensions[E.extensionName],D=t.binary?2:1,O=t.compress,k,F;typeof e==`string`?(k=Buffer.byteLength(e),F=!1):j(e)?(k=e.size,F=!1):(e=B(e),k=e.length,F=B.readOnly),this._firstFragment?(this._firstFragment=!1,O&&w&&w.params[w._isServer?`server_no_context_takeover`:`client_no_context_takeover`]&&(O=k>=w._threshold),this._compress=O):(O=!1,D=0),t.fin&&(this._firstFragment=!0);let L={[H]:k,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:D,readOnly:F,rsv1:O};j(e)?this._state===0?this.getBlobData(e,this._compress,L,S):this.enqueue([this.getBlobData,e,this._compress,L,S]):this._state===0?this.dispatch(e,this._compress,L,S):this.enqueue([this.dispatch,e,this._compress,L,S])}getBlobData(t,S,w,E){this._bufferedBytes+=w[H],this._state=2,t.arrayBuffer().then(t=>{if(this._socket.destroyed){let e=Error(`The socket was closed while the blob was being read`);process.nextTick(oe,this,e,E);return}this._bufferedBytes-=w[H];let D=B(t);S?this.dispatch(D,S,w,E):(this._state=0,this.sendFrame(e.frame(D,w),E),this.dequeue())}).catch(e=>{process.nextTick(se,this,e,E)})}dispatch(t,S,w,D){if(!S){this.sendFrame(e.frame(t,w),D);return}let O=this._extensions[E.extensionName];this._bufferedBytes+=w[H],this._state=1,O.compress(t,w.fin,(t,S)=>{if(this._socket.destroyed){oe(this,Error(`The socket was closed while data was being compressed`),D);return}this._bufferedBytes-=w[H],this._state=0,w.readOnly=!1,this.sendFrame(e.frame(S,w),D),this.dequeue()})}dequeue(){for(;this._state===0&&this._queue.length;){let e=this._queue.shift();this._bufferedBytes-=e[3][H],Reflect.apply(e[0],this,e.slice(1))}}enqueue(e){this._bufferedBytes+=e[3][H],this._queue.push(e)}sendFrame(e,t){e.length===2?(this._socket.cork(),this._socket.write(e[0]),this._socket.write(e[1],t),this._socket.uncork()):this._socket.write(e[0],t)}};function oe(e,t,S){typeof S==`function`&&S(t);for(let S=0;S<e._queue.length;S++){let w=e._queue[S],E=w[w.length-1];typeof E==`function`&&E(t)}}function se(e,t,S){oe(e,t,S),e.onerror(t)}})),require_event_target$1=__commonJSMin$1(((e,t)=>{let{kForOnEventAttribute:S,kListener:w}=require_constants$1(),E=Symbol(`kCode`),D=Symbol(`kData`),O=Symbol(`kError`),k=Symbol(`kMessage`),j=Symbol(`kReason`),F=Symbol(`kTarget`),L=Symbol(`kType`),B=Symbol(`kWasClean`);var H=class{constructor(e){this[F]=null,this[L]=e}get target(){return this[F]}get type(){return this[L]}};Object.defineProperty(H.prototype,`target`,{enumerable:!0}),Object.defineProperty(H.prototype,`type`,{enumerable:!0});var q=class extends H{constructor(e,t={}){super(e),this[E]=t.code===void 0?0:t.code,this[j]=t.reason===void 0?``:t.reason,this[B]=t.wasClean===void 0?!1:t.wasClean}get code(){return this[E]}get reason(){return this[j]}get wasClean(){return this[B]}};Object.defineProperty(q.prototype,`code`,{enumerable:!0}),Object.defineProperty(q.prototype,`reason`,{enumerable:!0}),Object.defineProperty(q.prototype,`wasClean`,{enumerable:!0});var J=class extends H{constructor(e,t={}){super(e),this[O]=t.error===void 0?null:t.error,this[k]=t.message===void 0?``:t.message}get error(){return this[O]}get message(){return this[k]}};Object.defineProperty(J.prototype,`error`,{enumerable:!0}),Object.defineProperty(J.prototype,`message`,{enumerable:!0});var Y=class extends H{constructor(e,t={}){super(e),this[D]=t.data===void 0?null:t.data}get data(){return this[D]}};Object.defineProperty(Y.prototype,`data`,{enumerable:!0}),t.exports={CloseEvent:q,ErrorEvent:J,Event:H,EventTarget:{addEventListener(e,t,E={}){for(let D of this.listeners(e))if(!E[S]&&D[w]===t&&!D[S])return;let D;if(e===`message`)D=function(e,S){let w=new Y(`message`,{data:S?e:e.toString()});w[F]=this,ee(t,this,w)};else if(e===`close`)D=function(e,S){let w=new q(`close`,{code:e,reason:S.toString(),wasClean:this._closeFrameReceived&&this._closeFrameSent});w[F]=this,ee(t,this,w)};else if(e===`error`)D=function(e){let S=new J(`error`,{error:e,message:e.message});S[F]=this,ee(t,this,S)};else if(e===`open`)D=function(){let e=new H(`open`);e[F]=this,ee(t,this,e)};else return;D[S]=!!E[S],D[w]=t,E.once?this.once(e,D):this.on(e,D)},removeEventListener(e,t){for(let E of this.listeners(e))if(E[w]===t&&!E[S]){this.removeListener(e,E);break}}},MessageEvent:Y};function ee(e,t,S){typeof e==`object`&&e.handleEvent?e.handleEvent.call(e,S):e.call(t,S)}})),require_extension$1=__commonJSMin$1(((e,t)=>{let{tokenChars:S}=require_validation$1();function w(e,t,S){e[t]===void 0?e[t]=[S]:e[t].push(S)}function E(e){let t=Object.create(null),E=Object.create(null),D=!1,O=!1,k=!1,j,F,L=-1,B=-1,H=-1,q=0;for(;q<e.length;q++)if(B=e.charCodeAt(q),j===void 0)if(H===-1&&S[B]===1)L===-1&&(L=q);else if(q!==0&&(B===32||B===9))H===-1&&L!==-1&&(H=q);else if(B===59||B===44){if(L===-1)throw SyntaxError(`Unexpected character at index ${q}`);H===-1&&(H=q);let S=e.slice(L,H);B===44?(w(t,S,E),E=Object.create(null)):j=S,L=H=-1}else throw SyntaxError(`Unexpected character at index ${q}`);else if(F===void 0)if(H===-1&&S[B]===1)L===-1&&(L=q);else if(B===32||B===9)H===-1&&L!==-1&&(H=q);else if(B===59||B===44){if(L===-1)throw SyntaxError(`Unexpected character at index ${q}`);H===-1&&(H=q),w(E,e.slice(L,H),!0),B===44&&(w(t,j,E),E=Object.create(null),j=void 0),L=H=-1}else if(B===61&&L!==-1&&H===-1)F=e.slice(L,q),L=H=-1;else throw SyntaxError(`Unexpected character at index ${q}`);else if(O){if(S[B]!==1)throw SyntaxError(`Unexpected character at index ${q}`);L===-1?L=q:D||=!0,O=!1}else if(k)if(S[B]===1)L===-1&&(L=q);else if(B===34&&L!==-1)k=!1,H=q;else if(B===92)O=!0;else throw SyntaxError(`Unexpected character at index ${q}`);else if(B===34&&e.charCodeAt(q-1)===61)k=!0;else if(H===-1&&S[B]===1)L===-1&&(L=q);else if(L!==-1&&(B===32||B===9))H===-1&&(H=q);else if(B===59||B===44){if(L===-1)throw SyntaxError(`Unexpected character at index ${q}`);H===-1&&(H=q);let S=e.slice(L,H);D&&=(S=S.replace(/\\/g,``),!1),w(E,F,S),B===44&&(w(t,j,E),E=Object.create(null),j=void 0),F=void 0,L=H=-1}else throw SyntaxError(`Unexpected character at index ${q}`);if(L===-1||k||B===32||B===9)throw SyntaxError(`Unexpected end of input`);H===-1&&(H=q);let J=e.slice(L,H);return j===void 0?w(t,J,E):(F===void 0?w(E,J,!0):D?w(E,F,J.replace(/\\/g,``)):w(E,F,J),w(t,j,E)),t}function D(e){return Object.keys(e).map(t=>{let S=e[t];return Array.isArray(S)||(S=[S]),S.map(e=>[t].concat(Object.keys(e).map(t=>{let S=e[t];return Array.isArray(S)||(S=[S]),S.map(e=>e===!0?t:`${t}=${e}`).join(`; `)})).join(`; `)).join(`, `)}).join(`, `)}t.exports={format:D,parse:E}})),require_websocket$1=__commonJSMin$1(((e,t)=>{let S=__require$1(`events`),w=__require$1(`https`),E=__require$1(`http`),D=__require$1(`net`),O=__require$1(`tls`),{randomBytes:k,createHash:j}=__require$1(`crypto`),{Duplex:F,Readable:L}=__require$1(`stream`),{URL:B}=__require$1(`url`),H=require_permessage_deflate$1(),q=require_receiver$1(),J=require_sender$1(),{isBlob:Y}=require_validation$1(),{BINARY_TYPES:ee,CLOSE_TIMEOUT:te,EMPTY_BUFFER:ne,GUID:ae,kForOnEventAttribute:oe,kListener:se,kStatusCode:ce,kWebSocket:ue,NOOP:de}=require_constants$1(),{EventTarget:{addEventListener:fe,removeEventListener:me}}=require_event_target$1(),{format:ge,parse:_e}=require_extension$1(),{toBuffer:ve}=require_buffer_util$1(),ye=Symbol(`kAborted`),Ce=[8,13],we=[`CONNECTING`,`OPEN`,`CLOSING`,`CLOSED`],Te=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;var De=class e extends S{constructor(t,S,w){super(),this._binaryType=ee[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=ne,this._closeTimer=null,this._errorEmitted=!1,this._extensions={},this._paused=!1,this._protocol=``,this._readyState=e.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,t===null?(this._autoPong=w.autoPong,this._closeTimeout=w.closeTimeout,this._isServer=!0):(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,S===void 0?S=[]:Array.isArray(S)||(typeof S==`object`&&S?(w=S,S=[]):S=[S]),je(this,t,S,w))}get binaryType(){return this._binaryType}set binaryType(e){ee.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(t,S,w){let E=new q({allowSynchronousEvents:w.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxPayload:w.maxPayload,skipUTF8Validation:w.skipUTF8Validation}),D=new J(t,this._extensions,w.generateMask);this._receiver=E,this._sender=D,this._socket=t,E[ue]=this,D[ue]=this,t[ue]=this,E.on(`conclude`,Be),E.on(`drain`,Ve),E.on(`error`,Ue),E.on(`message`,Ge),E.on(`ping`,Ke),E.on(`pong`,Xe),D.onerror=nt,t.setTimeout&&t.setTimeout(0),t.setNoDelay&&t.setNoDelay(),S.length>0&&t.unshift(S),t.on(`close`,it),t.on(`data`,at),t.on(`end`,st),t.on(`error`,vt),this._readyState=e.OPEN,this.emit(`open`)}emitClose(){if(!this._socket){this._readyState=e.CLOSED,this.emit(`close`,this._closeCode,this._closeMessage);return}this._extensions[H.extensionName]&&this._extensions[H.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=e.CLOSED,this.emit(`close`,this._closeCode,this._closeMessage)}close(t,S){if(this.readyState!==e.CLOSED){if(this.readyState===e.CONNECTING){Re(this,this._req,`WebSocket was closed before the connection was established`);return}if(this.readyState===e.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=e.CLOSING,this._sender.close(t,S,!this._isServer,e=>{e||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),rt(this)}}pause(){this.readyState===e.CONNECTING||this.readyState===e.CLOSED||(this._paused=!0,this._socket.pause())}ping(t,S,w){if(this.readyState===e.CONNECTING)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(typeof t==`function`?(w=t,t=S=void 0):typeof S==`function`&&(w=S,S=void 0),typeof t==`number`&&(t=t.toString()),this.readyState!==e.OPEN){ze(this,t,w);return}S===void 0&&(S=!this._isServer),this._sender.ping(t||ne,S,w)}pong(t,S,w){if(this.readyState===e.CONNECTING)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(typeof t==`function`?(w=t,t=S=void 0):typeof S==`function`&&(w=S,S=void 0),typeof t==`number`&&(t=t.toString()),this.readyState!==e.OPEN){ze(this,t,w);return}S===void 0&&(S=!this._isServer),this._sender.pong(t||ne,S,w)}resume(){this.readyState===e.CONNECTING||this.readyState===e.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(t,S,w){if(this.readyState===e.CONNECTING)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(typeof S==`function`&&(w=S,S={}),typeof t==`number`&&(t=t.toString()),this.readyState!==e.OPEN){ze(this,t,w);return}let E={binary:typeof t!=`string`,mask:!this._isServer,compress:!0,fin:!0,...S};this._extensions[H.extensionName]||(E.compress=!1),this._sender.send(t||ne,E,w)}terminate(){if(this.readyState!==e.CLOSED){if(this.readyState===e.CONNECTING){Re(this,this._req,`WebSocket was closed before the connection was established`);return}this._socket&&(this._readyState=e.CLOSING,this._socket.destroy())}}};Object.defineProperty(De,`CONNECTING`,{enumerable:!0,value:we.indexOf(`CONNECTING`)}),Object.defineProperty(De.prototype,`CONNECTING`,{enumerable:!0,value:we.indexOf(`CONNECTING`)}),Object.defineProperty(De,`OPEN`,{enumerable:!0,value:we.indexOf(`OPEN`)}),Object.defineProperty(De.prototype,`OPEN`,{enumerable:!0,value:we.indexOf(`OPEN`)}),Object.defineProperty(De,`CLOSING`,{enumerable:!0,value:we.indexOf(`CLOSING`)}),Object.defineProperty(De.prototype,`CLOSING`,{enumerable:!0,value:we.indexOf(`CLOSING`)}),Object.defineProperty(De,`CLOSED`,{enumerable:!0,value:we.indexOf(`CLOSED`)}),Object.defineProperty(De.prototype,`CLOSED`,{enumerable:!0,value:we.indexOf(`CLOSED`)}),[`binaryType`,`bufferedAmount`,`extensions`,`isPaused`,`protocol`,`readyState`,`url`].forEach(e=>{Object.defineProperty(De.prototype,e,{enumerable:!0})}),[`open`,`error`,`close`,`message`].forEach(e=>{Object.defineProperty(De.prototype,`on${e}`,{enumerable:!0,get(){for(let t of this.listeners(e))if(t[oe])return t[se];return null},set(t){for(let t of this.listeners(e))if(t[oe]){this.removeListener(e,t);break}typeof t==`function`&&this.addEventListener(e,t,{[oe]:!0})}})}),De.prototype.addEventListener=fe,De.prototype.removeEventListener=me,t.exports=De;function je(e,t,S,D){let O={allowSynchronousEvents:!0,autoPong:!0,closeTimeout:te,protocolVersion:Ce[1],maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...D,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:`GET`,host:void 0,path:void 0,port:void 0};if(e._autoPong=O.autoPong,e._closeTimeout=O.closeTimeout,!Ce.includes(O.protocolVersion))throw RangeError(`Unsupported protocol version: ${O.protocolVersion} (supported versions: ${Ce.join(`, `)})`);let F;if(t instanceof B)F=t;else try{F=new B(t)}catch{throw SyntaxError(`Invalid URL: ${t}`)}F.protocol===`http:`?F.protocol=`ws:`:F.protocol===`https:`&&(F.protocol=`wss:`),e._url=F.href;let L=F.protocol===`wss:`,q=F.protocol===`ws+unix:`,J;if(F.protocol!==`ws:`&&!L&&!q?J=`The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"`:q&&!F.pathname?J=`The URL's pathname is empty`:F.hash&&(J=`The URL contains a fragment identifier`),J){let t=SyntaxError(J);if(e._redirects===0)throw t;Me(e,t);return}let Y=L?443:80,ee=k(16).toString(`base64`),ne=L?w.request:E.request,oe=new Set,se;if(O.createConnection=O.createConnection||(L?Ie:Pe),O.defaultPort=O.defaultPort||Y,O.port=F.port||Y,O.host=F.hostname.startsWith(`[`)?F.hostname.slice(1,-1):F.hostname,O.headers={...O.headers,"Sec-WebSocket-Version":O.protocolVersion,"Sec-WebSocket-Key":ee,Connection:`Upgrade`,Upgrade:`websocket`},O.path=F.pathname+F.search,O.timeout=O.handshakeTimeout,O.perMessageDeflate&&(se=new H({...O.perMessageDeflate,isServer:!1,maxPayload:O.maxPayload}),O.headers[`Sec-WebSocket-Extensions`]=ge({[H.extensionName]:se.offer()})),S.length){for(let e of S){if(typeof e!=`string`||!Te.test(e)||oe.has(e))throw SyntaxError(`An invalid or duplicated subprotocol was specified`);oe.add(e)}O.headers[`Sec-WebSocket-Protocol`]=S.join(`,`)}if(O.origin&&(O.protocolVersion<13?O.headers[`Sec-WebSocket-Origin`]=O.origin:O.headers.Origin=O.origin),(F.username||F.password)&&(O.auth=`${F.username}:${F.password}`),q){let e=O.path.split(`:`);O.socketPath=e[0],O.path=e[1]}let ce;if(O.followRedirects){if(e._redirects===0){e._originalIpc=q,e._originalSecure=L,e._originalHostOrSocketPath=q?O.socketPath:F.host;let t=D&&D.headers;if(D={...D,headers:{}},t)for(let[e,S]of Object.entries(t))D.headers[e.toLowerCase()]=S}else if(e.listenerCount(`redirect`)===0){let t=q?e._originalIpc?O.socketPath===e._originalHostOrSocketPath:!1:e._originalIpc?!1:F.host===e._originalHostOrSocketPath;(!t||e._originalSecure&&!L)&&(delete O.headers.authorization,delete O.headers.cookie,t||delete O.headers.host,O.auth=void 0)}O.auth&&!D.headers.authorization&&(D.headers.authorization=`Basic `+Buffer.from(O.auth).toString(`base64`)),ce=e._req=ne(O),e._redirects&&e.emit(`redirect`,e.url,ce)}else ce=e._req=ne(O);O.timeout&&ce.on(`timeout`,()=>{Re(e,ce,`Opening handshake has timed out`)}),ce.on(`error`,t=>{ce===null||ce[ye]||(ce=e._req=null,Me(e,t))}),ce.on(`response`,w=>{let E=w.headers.location,k=w.statusCode;if(E&&O.followRedirects&&k>=300&&k<400){if(++e._redirects>O.maxRedirects){Re(e,ce,`Maximum redirects exceeded`);return}ce.abort();let w;try{w=new B(E,t)}catch{Me(e,SyntaxError(`Invalid URL: ${E}`));return}je(e,w,S,D)}else e.emit(`unexpected-response`,ce,w)||Re(e,ce,`Unexpected server response: ${w.statusCode}`)}),ce.on(`upgrade`,(t,S,w)=>{if(e.emit(`upgrade`,t),e.readyState!==De.CONNECTING)return;ce=e._req=null;let E=t.headers.upgrade;if(E===void 0||E.toLowerCase()!==`websocket`){Re(e,S,`Invalid Upgrade header`);return}let D=j(`sha1`).update(ee+ae).digest(`base64`);if(t.headers[`sec-websocket-accept`]!==D){Re(e,S,`Invalid Sec-WebSocket-Accept header`);return}let k=t.headers[`sec-websocket-protocol`],F;if(k===void 0?oe.size&&(F=`Server sent no subprotocol`):oe.size?oe.has(k)||(F=`Server sent an invalid subprotocol`):F=`Server sent a subprotocol but none was requested`,F){Re(e,S,F);return}k&&(e._protocol=k);let L=t.headers[`sec-websocket-extensions`];if(L!==void 0){if(!se){Re(e,S,`Server sent a Sec-WebSocket-Extensions header but no extension was requested`);return}let t;try{t=_e(L)}catch{Re(e,S,`Invalid Sec-WebSocket-Extensions header`);return}let w=Object.keys(t);if(w.length!==1||w[0]!==H.extensionName){Re(e,S,`Server indicated an extension that was not requested`);return}try{se.accept(t[H.extensionName])}catch{Re(e,S,`Invalid Sec-WebSocket-Extensions header`);return}e._extensions[H.extensionName]=se}e.setSocket(S,w,{allowSynchronousEvents:O.allowSynchronousEvents,generateMask:O.generateMask,maxPayload:O.maxPayload,skipUTF8Validation:O.skipUTF8Validation})}),O.finishRequest?O.finishRequest(ce,e):ce.end()}function Me(e,t){e._readyState=De.CLOSING,e._errorEmitted=!0,e.emit(`error`,t),e.emitClose()}function Pe(e){return e.path=e.socketPath,D.connect(e)}function Ie(e){return e.path=void 0,!e.servername&&e.servername!==``&&(e.servername=D.isIP(e.host)?``:e.host),O.connect(e)}function Re(e,t,S){e._readyState=De.CLOSING;let w=Error(S);Error.captureStackTrace(w,Re),t.setHeader?(t[ye]=!0,t.abort(),t.socket&&!t.socket.destroyed&&t.socket.destroy(),process.nextTick(Me,e,w)):(t.destroy(w),t.once(`error`,e.emit.bind(e,`error`)),t.once(`close`,e.emitClose.bind(e)))}function ze(e,t,S){if(t){let S=Y(t)?t.size:ve(t).length;e._socket?e._sender._bufferedBytes+=S:e._bufferedAmount+=S}if(S){let t=Error(`WebSocket is not open: readyState ${e.readyState} (${we[e.readyState]})`);process.nextTick(S,t)}}function Be(e,t){let S=this[ue];S._closeFrameReceived=!0,S._closeMessage=t,S._closeCode=e,S._socket[ue]!==void 0&&(S._socket.removeListener(`data`,at),process.nextTick($e,S._socket),e===1005?S.close():S.close(e,t))}function Ve(){let e=this[ue];e.isPaused||e._socket.resume()}function Ue(e){let t=this[ue];t._socket[ue]!==void 0&&(t._socket.removeListener(`data`,at),process.nextTick($e,t._socket),t.close(e[ce])),t._errorEmitted||(t._errorEmitted=!0,t.emit(`error`,e))}function We(){this[ue].emitClose()}function Ge(e,t){this[ue].emit(`message`,e,t)}function Ke(e){let t=this[ue];t._autoPong&&t.pong(e,!this._isServer,de),t.emit(`ping`,e)}function Xe(e){this[ue].emit(`pong`,e)}function $e(e){e.resume()}function nt(e){let t=this[ue];t.readyState!==De.CLOSED&&(t.readyState===De.OPEN&&(t._readyState=De.CLOSING,rt(t)),this._socket.end(),t._errorEmitted||(t._errorEmitted=!0,t.emit(`error`,e)))}function rt(e){e._closeTimer=setTimeout(e._socket.destroy.bind(e._socket),e._closeTimeout)}function it(){let e=this[ue];if(this.removeListener(`close`,it),this.removeListener(`data`,at),this.removeListener(`end`,st),e._readyState=De.CLOSING,!this._readableState.endEmitted&&!e._closeFrameReceived&&!e._receiver._writableState.errorEmitted&&this._readableState.length!==0){let t=this.read(this._readableState.length);e._receiver.write(t)}e._receiver.end(),this[ue]=void 0,clearTimeout(e._closeTimer),e._receiver._writableState.finished||e._receiver._writableState.errorEmitted?e.emitClose():(e._receiver.on(`error`,We),e._receiver.on(`finish`,We))}function at(e){this[ue]._receiver.write(e)||this.pause()}function st(){let e=this[ue];e._readyState=De.CLOSING,e._receiver.end(),this.end()}function vt(){let e=this[ue];this.removeListener(`error`,vt),this.on(`error`,de),e&&(e._readyState=De.CLOSING,this.destroy())}})),require_stream$1=__commonJSMin$1(((e,t)=>{require_websocket$1();let{Duplex:S}=__require$1(`stream`);function w(e){e.emit(`close`)}function E(){!this.destroyed&&this._writableState.finished&&this.destroy()}function D(e){this.removeListener(`error`,D),this.destroy(),this.listenerCount(`error`)===0&&this.emit(`error`,e)}function O(e,t){let O=!0,k=new S({...t,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return e.on(`message`,function(t,S){let w=!S&&k._readableState.objectMode?t.toString():t;k.push(w)||e.pause()}),e.once(`error`,function(e){k.destroyed||(O=!1,k.destroy(e))}),e.once(`close`,function(){k.destroyed||k.push(null)}),k._destroy=function(t,S){if(e.readyState===e.CLOSED){S(t),process.nextTick(w,k);return}let E=!1;e.once(`error`,function(e){E=!0,S(e)}),e.once(`close`,function(){E||S(t),process.nextTick(w,k)}),O&&e.terminate()},k._final=function(t){if(e.readyState===e.CONNECTING){e.once(`open`,function(){k._final(t)});return}e._socket!==null&&(e._socket._writableState.finished?(t(),k._readableState.endEmitted&&k.destroy()):(e._socket.once(`finish`,function(){t()}),e.close()))},k._read=function(){e.isPaused&&e.resume()},k._write=function(t,S,w){if(e.readyState===e.CONNECTING){e.once(`open`,function(){k._write(t,S,w)});return}e.send(t,w)},k.on(`end`,E),k.on(`error`,D),k}t.exports=O})),require_subprotocol$1=__commonJSMin$1(((e,t)=>{let{tokenChars:S}=require_validation$1();function w(e){let t=new Set,w=-1,E=-1,D=0;for(;D<e.length;D++){let O=e.charCodeAt(D);if(E===-1&&S[O]===1)w===-1&&(w=D);else if(D!==0&&(O===32||O===9))E===-1&&w!==-1&&(E=D);else if(O===44){if(w===-1)throw SyntaxError(`Unexpected character at index ${D}`);E===-1&&(E=D);let S=e.slice(w,E);if(t.has(S))throw SyntaxError(`The "${S}" subprotocol is duplicated`);t.add(S),w=E=-1}else throw SyntaxError(`Unexpected character at index ${D}`)}if(w===-1||E!==-1)throw SyntaxError(`Unexpected end of input`);let O=e.slice(w,D);if(t.has(O))throw SyntaxError(`The "${O}" subprotocol is duplicated`);return t.add(O),t}t.exports={parse:w}})),require_websocket_server$1=__commonJSMin$1(((e,t)=>{let S=__require$1(`events`),w=__require$1(`http`),{Duplex:E}=__require$1(`stream`),{createHash:D}=__require$1(`crypto`),O=require_extension$1(),k=require_permessage_deflate$1(),j=require_subprotocol$1(),F=require_websocket$1(),{CLOSE_TIMEOUT:L,GUID:B,kWebSocket:H}=require_constants$1(),q=/^[+/0-9A-Za-z]{22}==$/,J=0,Y=1,ee=2;t.exports=class extends S{constructor(e,t){if(super(),e={allowSynchronousEvents:!0,autoPong:!0,maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,closeTimeout:L,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,WebSocket:F,...e},e.port==null&&!e.server&&!e.noServer||e.port!=null&&(e.server||e.noServer)||e.server&&e.noServer)throw TypeError(`One and only one of the "port", "server", or "noServer" options must be specified`);if(e.port==null?e.server&&(this._server=e.server):(this._server=w.createServer((e,t)=>{let S=w.STATUS_CODES[426];t.writeHead(426,{"Content-Length":S.length,"Content-Type":`text/plain`}),t.end(S)}),this._server.listen(e.port,e.host,e.backlog,t)),this._server){let e=this.emit.bind(this,`connection`);this._removeListeners=te(this._server,{listening:this.emit.bind(this,`listening`),error:this.emit.bind(this,`error`),upgrade:(t,S,w)=>{this.handleUpgrade(t,S,w,e)}})}e.perMessageDeflate===!0&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=e,this._state=0}address(){if(this.options.noServer)throw Error(`The server is operating in "noServer" mode`);return this._server?this._server.address():null}close(e){if(this._state===2){e&&this.once(`close`,()=>{e(Error(`The server is not running`))}),process.nextTick(ne,this);return}if(e&&this.once(`close`,e),this._state!==1)if(this._state=1,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients&&this.clients.size?this._shouldEmitClose=!0:process.nextTick(ne,this);else{let e=this._server;this._removeListeners(),this._removeListeners=this._server=null,e.close(()=>{ne(this)})}}shouldHandle(e){if(this.options.path){let t=e.url.indexOf(`?`);if((t===-1?e.url:e.url.slice(0,t))!==this.options.path)return!1}return!0}handleUpgrade(e,t,S,w){t.on(`error`,ae);let E=e.headers[`sec-websocket-key`],D=e.headers.upgrade,F=+e.headers[`sec-websocket-version`];if(e.method!==`GET`){se(this,e,t,405,`Invalid HTTP method`);return}if(D===void 0||D.toLowerCase()!==`websocket`){se(this,e,t,400,`Invalid Upgrade header`);return}if(E===void 0||!q.test(E)){se(this,e,t,400,`Missing or invalid Sec-WebSocket-Key header`);return}if(F!==13&&F!==8){se(this,e,t,400,`Missing or invalid Sec-WebSocket-Version header`,{"Sec-WebSocket-Version":`13, 8`});return}if(!this.shouldHandle(e)){oe(t,400);return}let L=e.headers[`sec-websocket-protocol`],B=new Set;if(L!==void 0)try{B=j.parse(L)}catch{se(this,e,t,400,`Invalid Sec-WebSocket-Protocol header`);return}let H=e.headers[`sec-websocket-extensions`],J={};if(this.options.perMessageDeflate&&H!==void 0){let S=new k({...this.options.perMessageDeflate,isServer:!0,maxPayload:this.options.maxPayload});try{let e=O.parse(H);e[k.extensionName]&&(S.accept(e[k.extensionName]),J[k.extensionName]=S)}catch{se(this,e,t,400,`Invalid or unacceptable Sec-WebSocket-Extensions header`);return}}if(this.options.verifyClient){let D={origin:e.headers[`${F===8?`sec-websocket-origin`:`origin`}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(D,(D,O,k,j)=>{if(!D)return oe(t,O||401,k,j);this.completeUpgrade(J,E,B,e,t,S,w)});return}if(!this.options.verifyClient(D))return oe(t,401)}this.completeUpgrade(J,E,B,e,t,S,w)}completeUpgrade(e,t,S,w,E,j,F){if(!E.readable||!E.writable)return E.destroy();if(E[H])throw Error(`server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration`);if(this._state>0)return oe(E,503);let L=[`HTTP/1.1 101 Switching Protocols`,`Upgrade: websocket`,`Connection: Upgrade`,`Sec-WebSocket-Accept: ${D(`sha1`).update(t+B).digest(`base64`)}`],q=new this.options.WebSocket(null,void 0,this.options);if(S.size){let e=this.options.handleProtocols?this.options.handleProtocols(S,w):S.values().next().value;e&&(L.push(`Sec-WebSocket-Protocol: ${e}`),q._protocol=e)}if(e[k.extensionName]){let t=e[k.extensionName].params,S=O.format({[k.extensionName]:[t]});L.push(`Sec-WebSocket-Extensions: ${S}`),q._extensions=e}this.emit(`headers`,L,w),E.write(L.concat(`\r
|
|
1126
|
+
`)}var rl=new TextDecoder(`utf-8`,{fatal:!0});function Bi(e){if(!e)return e;let t=!1;for(let S=0;S<e.length;S++){let w=e.charCodeAt(S);if(w>255)return e;w>127&&(t=!0)}if(!t)return e;let S=new Uint8Array(e.length);for(let t=0;t<e.length;t++)S[t]=e.charCodeAt(t);try{return rl.decode(S)}catch{return e}}var ol=[`EACCES`,`escaping sandbox`,`EFBIG`],Ss=class{root;canonicalRoot;maxFileReadSize;allowSymlinks;constructor(e){this.root=U.resolve(e.root),this.maxFileReadSize=e.maxFileReadSize??10485760,this.allowSymlinks=e.allowSymlinks??!1,$$3(this.root,`ReadWriteFs`),this.canonicalRoot=I.realpathSync(this.root)}resolveAndValidate(e,t){let S=this.allowSymlinks?f$1(e,this.canonicalRoot):P$1(e,this.root,this.canonicalRoot);if(S===null)throw Error(`EACCES: permission denied, '${t}' resolves outside sandbox`);return S}validateParent(e,t){let S=U.dirname(e),w=this.resolveAndValidate(S,t);return U.join(w,U.basename(e))}toRealPath(e){let t=c$2(e),S=U.join(this.root,t);return U.resolve(S)}async readFile(e,t){return h$4(await this.readFileBuffer(e),l$1(t))}async readFileBuffer(e){h$3(e,`open`);let t=this.toRealPath(e),S=this.resolveAndValidate(t,e);try{let t=this.allowSymlinks?I.constants.O_RDONLY:I.constants.O_RDONLY|I.constants.O_NOFOLLOW,w=await I.promises.open(S,t);try{if(this.maxFileReadSize>0){let t=await w.stat();if(t.size>this.maxFileReadSize)throw Error(`EFBIG: file too large, read '${e}' (${t.size} bytes, max ${this.maxFileReadSize})`)}let t=await w.readFile();return new Uint8Array(t)}finally{await w.close()}}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, open '${e}'`);if(S.code===`EISDIR`)throw Error(`EISDIR: illegal operation on a directory, read '${e}'`);if(S.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`open`)}}async writeFile(e,t,S){h$3(e,`write`);let w=this.toRealPath(e),E=this.resolveAndValidate(w,e),D=o(t,l$1(S)),O=U.dirname(E);try{await I.promises.mkdir(O,{recursive:!0}),E=this.resolveAndValidate(w,e);let t=this.allowSymlinks?0:I.constants.O_NOFOLLOW,S=I.constants.O_WRONLY|I.constants.O_CREAT|I.constants.O_TRUNC|t,k=await I.promises.open(E,S,438);try{await k.writeFile(D)}finally{await k.close()}}catch(t){if(t.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`write`)}}async appendFile(e,t,S){h$3(e,`append`);let w=this.toRealPath(e),E=this.resolveAndValidate(w,e),D=o(t,l$1(S)),O=U.dirname(E);try{await I.promises.mkdir(O,{recursive:!0}),E=this.resolveAndValidate(w,e);let t=this.allowSymlinks?0:I.constants.O_NOFOLLOW,S=I.constants.O_WRONLY|I.constants.O_CREAT|I.constants.O_APPEND|t,k=await I.promises.open(E,S,438);try{await k.writeFile(D)}finally{await k.close()}}catch(t){if(t.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`append`)}}async exists(e){if(e.includes(`\0`))return!1;let t=this.toRealPath(e);try{let S=this.resolveAndValidate(t,e);return await I.promises.access(S),!0}catch{return!1}}async stat(e){h$3(e,`stat`);let t=this.toRealPath(e),S=this.resolveAndValidate(t,e);try{let t=await I.promises.lstat(S);if(!this.allowSymlinks&&t.isSymbolicLink())throw Error(`EACCES: permission denied, '${e}' is a symlink`);return{isFile:t.isFile(),isDirectory:t.isDirectory(),isSymbolicLink:t.isSymbolicLink(),mode:t.mode,size:t.size,mtime:t.mtime}}catch(t){if(t.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, stat '${e}'`);this.sanitizeError(t,e,`stat`)}}async lstat(e){h$3(e,`lstat`);let t=this.toRealPath(e),S=this.validateParent(t,e);try{let e=await I.promises.lstat(S);return{isFile:e.isFile(),isDirectory:e.isDirectory(),isSymbolicLink:e.isSymbolicLink(),mode:e.mode,size:e.size,mtime:e.mtime}}catch(t){if(t.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, lstat '${e}'`);this.sanitizeError(t,e,`lstat`)}}async mkdir(e,t){h$3(e,`mkdir`);let S=this.toRealPath(e),w=this.resolveAndValidate(S,e);try{await I.promises.mkdir(w,{recursive:t?.recursive})}catch(t){let S=t;if(S.code===`EEXIST`)throw Error(`EEXIST: file already exists, mkdir '${e}'`);if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, mkdir '${e}'`);this.sanitizeError(t,e,`mkdir`)}}async readdir(e){return(await this.readdirWithFileTypes(e)).map(e=>e.name)}async readdirWithFileTypes(e){h$3(e,`scandir`);let t=this.toRealPath(e),S=this.resolveAndValidate(t,e);try{if(!this.allowSymlinks&&(await I.promises.lstat(S)).isSymbolicLink())throw Error(`EACCES: permission denied, '${e}' is a symlink`);return(await I.promises.readdir(S,{withFileTypes:!0})).map(e=>({name:e.name,isFile:e.isFile(),isDirectory:e.isDirectory(),isSymbolicLink:e.isSymbolicLink()})).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:0)}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, scandir '${e}'`);if(S.code===`ENOTDIR`)throw Error(`ENOTDIR: not a directory, scandir '${e}'`);this.sanitizeError(t,e,`scandir`)}}async rm(e,t){h$3(e,`rm`);let S=this.toRealPath(e),w=this.resolveAndValidate(S,e);try{await I.promises.rm(w,{recursive:t?.recursive??!1,force:t?.force??!1})}catch(S){let w=S;if(w.code===`ENOENT`&&!t?.force)throw Error(`ENOENT: no such file or directory, rm '${e}'`);if(w.code===`ENOTEMPTY`)throw Error(`ENOTEMPTY: directory not empty, rm '${e}'`);this.sanitizeError(S,e,`rm`)}}async cp(e,t,S){h$3(e,`cp`),h$3(t,`cp`);let w=this.toRealPath(e),E=this.toRealPath(t),D=this.resolveAndValidate(w,e),O=this.resolveAndValidate(E,t);try{await I.promises.cp(D,O,{recursive:S?.recursive??!1,filter:async e=>{try{if(I.lstatSync(e).isSymbolicLink()){let t=await I.promises.realpath(e).catch(()=>null);return t===null?!1:d$1(t,this.canonicalRoot)}return!0}catch(e){return e.code===`ENOENT`}}})}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, cp '${e}'`);if(S.code===`EISDIR`)throw Error(`EISDIR: is a directory, cp '${e}'`);this.sanitizeError(t,e,`cp`)}}async mv(e,t){h$3(e,`mv`),h$3(t,`mv`);let S=this.toRealPath(e),w=this.toRealPath(t),E=this.validateParent(S,e),D=this.validateParent(w,t);try{if((await I.promises.lstat(E)).isSymbolicLink()){let S=await I.promises.readlink(E),w=U.resolve(U.dirname(D),S);if(!d$1(await I.promises.realpath(w).catch(()=>w),this.canonicalRoot))throw Error(`EACCES: permission denied, mv '${e}' -> '${t}' would create symlink escaping sandbox`)}}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, mv '${e}'`);if(S.message?.includes(`EACCES`)||S.message?.includes(`escaping sandbox`))throw t}let O=U.dirname(D);try{await I.promises.mkdir(O,{recursive:!0})}catch(e){this.sanitizeError(e,t,`mv`)}try{await I.promises.rename(E,D)}catch(S){let w=S;if(w.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, mv '${e}'`);if(w.code===`EXDEV`){await this.cp(e,t,{recursive:!0}),await this.rm(e,{recursive:!0});return}this.sanitizeError(S,e,`mv`)}try{if(I.lstatSync(D).isDirectory()&&this.findEscapingSymlinks(D).length>0)throw await I.promises.rename(D,E),Error(`EACCES: permission denied, mv '${e}' -> '${t}' would create symlinks escaping sandbox`)}catch(e){if(e.message?.includes(`EACCES`)||e.message?.includes(`escaping sandbox`))throw e}}resolvePath(e,t){return y(e,t)}getAllPaths(){let e=[];return this.scanDir(`/`,e),e}sanitizeError(e,t,S){N(e,t,S,ol)}findEscapingSymlinks(e){let t=[];try{let S=I.readdirSync(e);for(let w of S){let S=U.join(e,w);try{let w=I.lstatSync(S);if(w.isSymbolicLink()){let w=I.readlinkSync(S),E=U.resolve(e,w),D;try{D=I.realpathSync(E)}catch{D=E}d$1(D,this.canonicalRoot)||t.push(S)}else w.isDirectory()&&t.push(...this.findEscapingSymlinks(S))}catch{}}}catch{}return t}scanDir(e,t){let S=this.toRealPath(e),w;try{w=this.resolveAndValidate(S,e)}catch{return}try{let S=I.readdirSync(w);for(let E of S){let S=e===`/`?`/${E}`:`${e}/${E}`;t.push(S);let D=U.join(w,E);I.lstatSync(D).isDirectory()&&this.scanDir(S,t)}}catch{}}async chmod(e,t){h$3(e,`chmod`);let S=this.toRealPath(e),w=this.resolveAndValidate(S,e);try{let e=this.allowSymlinks?I.constants.O_RDONLY:I.constants.O_RDONLY|I.constants.O_NOFOLLOW,S=await I.promises.open(w,e);try{await S.chmod(t)}finally{await S.close()}}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, chmod '${e}'`);if(S.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`chmod`)}}async symlink(e,t){if(!this.allowSymlinks)throw Error(`EPERM: operation not permitted, symlink '${t}'`);h$3(t,`symlink`);let S=this.toRealPath(t),w=this.validateParent(S,t),E=c$2(t),D=c$2(U.dirname(E)),O=e.startsWith(`/`)?c$2(e):c$2(D===`/`?`/${e}`:`${D}/${e}`),k=U.join(this.canonicalRoot,O),j=U.dirname(w),F=e.startsWith(`/`)?k:U.relative(j,k)||`.`;try{await I.promises.symlink(F,w)}catch(e){if(e.code===`EEXIST`)throw Error(`EEXIST: file already exists, symlink '${t}'`);this.sanitizeError(e,t,`symlink`)}}async link(e,t){h$3(e,`link`),h$3(t,`link`);let S=this.toRealPath(e),w=this.toRealPath(t),E=this.resolveAndValidate(S,e),D=this.resolveAndValidate(w,t);try{await I.promises.link(E,D)}catch(S){let w=S;if(w.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, link '${e}'`);if(w.code===`EEXIST`)throw Error(`EEXIST: file already exists, link '${t}'`);if(w.code===`EPERM`)throw Error(`EPERM: operation not permitted, link '${e}'`);this.sanitizeError(S,e,`link`)}}async readlink(e){h$3(e,`readlink`);let t=this.toRealPath(e),S=this.validateParent(t,e);try{let t=await I.promises.readlink(S),w=c$2(e),E=U.dirname(w),D=U.isAbsolute(t)?t:U.resolve(U.dirname(S),t),O=await I.promises.realpath(D).catch(()=>D);if(d$1(O,this.canonicalRoot)){let e=O.slice(this.canonicalRoot.length)||`/`;return E===`/`?e.startsWith(`/`)?e.slice(1)||`.`:e:U.relative(E,e)}return U.basename(t)}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, readlink '${e}'`);if(S.code===`EINVAL`)throw Error(`EINVAL: invalid argument, readlink '${e}'`);this.sanitizeError(t,e,`readlink`)}}async realpath(e){h$3(e,`realpath`);let t=this.toRealPath(e);try{this.resolveAndValidate(t,e)}catch{throw Error(`ENOENT: no such file or directory, realpath '${e}'`)}let S;try{S=await I.promises.realpath(t)}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, realpath '${e}'`);if(S.code===`ELOOP`)throw Error(`ELOOP: too many levels of symbolic links, realpath '${e}'`);this.sanitizeError(t,e,`realpath`)}if(d$1(S,this.canonicalRoot))return S.slice(this.canonicalRoot.length)||`/`;throw Error(`ENOENT: no such file or directory, realpath '${e}'`)}async utimes(e,t,S){h$3(e,`utimes`);let w=this.toRealPath(e),E=this.resolveAndValidate(w,e);try{let e=this.allowSymlinks?I.constants.O_RDONLY:I.constants.O_RDONLY|I.constants.O_NOFOLLOW,w=await I.promises.open(E,e);try{await w.utimes(t,S)}finally{await w.close()}}catch(t){let S=t;if(S.code===`ENOENT`)throw Error(`ENOENT: no such file or directory, utimes '${e}'`);if(S.code===`ELOOP`)throw Error(`EACCES: permission denied, '${e}' is a symlink`);this.sanitizeError(t,e,`utimes`)}}},require_quote=__commonJSMin$1(((e,t)=>{t.exports=function(e){return e.map(function(e){return e===``?`''`:e&&typeof e==`object`?e.op.replace(/(.)/g,`\\$1`):/["\s\\]/.test(e)&&!/'/.test(e)?`'`+e.replace(/(['])/g,`\\$1`)+`'`:/["'\s]/.test(e)?`"`+e.replace(/(["\\$`!])/g,`\\$1`)+`"`:String(e).replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g,`$1\\$2`)}).join(` `)}})),require_parse=__commonJSMin$1(((e,t)=>{for(var S=`(?:`+[`\\|\\|`,`\\&\\&`,`;;`,`\\|\\&`,`\\<\\(`,`\\<\\<\\<`,`>>`,`>\\&`,`<\\&`,`[&;()|<>]`].join(`|`)+`)`,w=RegExp(`^`+S+`$`),E=`|&;()<> \\t`,D=`"((\\\\"|[^"])*?)"`,O=`'((\\\\'|[^'])*?)'`,k=/^#$/,j=`'`,F=`"`,L=`$`,B=``,H=4294967296,q=0;q<4;q++)B+=(H*Math.random()).toString(16);var J=RegExp(`^`+B);function Y(e,t){for(var S=t.lastIndex,w=[],E;E=t.exec(e);)w.push(E),t.lastIndex===E.index&&(t.lastIndex+=1);return t.lastIndex=S,w}function ee(e,t,S){var w=typeof e==`function`?e(S):e[S];return w===void 0&&S!=``?w=``:w===void 0&&(w=`$`),typeof w==`object`?t+B+JSON.stringify(w)+B:t+w}function te(e,t,B){B||={};var H=B.escape||`\\`,q=`(\\`+H+`['"`+E+`]|[^\\s'"`+E+`])+`,J=Y(e,new RegExp([`(`+S+`)`,`(`+q+`|`+D+`|`+O+`)+`].join(`|`),`g`));if(J.length===0)return[];t||={};var te=!1;return J.map(function(S){var E=S[0];if(!E||te)return;if(w.test(E))return{op:E};var D=!1,O=!1,B=``,q=!1,J;function Y(){J+=1;var e,S,w=E.charAt(J);if(w===`{`){if(J+=1,E.charAt(J)===`}`)throw Error(`Bad substitution: `+E.slice(J-2,J+1));if(e=E.indexOf(`}`,J),e<0)throw Error(`Bad substitution: `+E.slice(J));S=E.slice(J,e),J=e}else if(/[*@#?$!_-]/.test(w))S=w,J+=1;else{var D=E.slice(J);e=D.match(/[^\w\d_]/),e?(S=D.slice(0,e.index),J+=e.index-1):(S=D,J=E.length)}return ee(t,``,S)}for(J=0;J<E.length;J++){var ne=E.charAt(J);if(q||=!D&&(ne===`*`||ne===`?`),O)B+=ne,O=!1;else if(D)ne===D?D=!1:D==j?B+=ne:ne===H?(J+=1,ne=E.charAt(J),ne===F||ne===H||ne===L?B+=ne:B+=H+ne):ne===L?B+=Y():B+=ne;else if(ne===F||ne===j)D=ne;else if(w.test(ne))return{op:E};else if(k.test(ne)){te=!0;var ae={comment:e.slice(S.index+J+1)};return B.length?[B,ae]:[ae]}else ne===H?O=!0:ne===L?B+=Y():B+=ne}return q?{op:`glob`,pattern:B}:B}).reduce(function(e,t){return t===void 0?e:e.concat(t)},[])}t.exports=function(e,t,S){var w=te(e,t,S);return typeof t==`function`?w.reduce(function(e,t){if(typeof t==`object`)return e.concat(t);var S=t.split(RegExp(`(`+B+`.*?`+B+`)`,`g`));return S.length===1?e.concat(S[0]):e.concat(S.filter(Boolean).map(function(e){return J.test(e)?JSON.parse(e.split(B)[1]):e}))},[]):w}})),require_shell_quote=__commonJSMin$1((e=>{e.quote=require_quote(),e.parse=require_parse()})),require_constants$1=__commonJSMin$1(((e,t)=>{let S=[`nodebuffer`,`arraybuffer`,`fragments`],w=typeof Blob<`u`;w&&S.push(`blob`),t.exports={BINARY_TYPES:S,CLOSE_TIMEOUT:3e4,EMPTY_BUFFER:Buffer.alloc(0),GUID:`258EAFA5-E914-47DA-95CA-C5AB0DC85B11`,hasBlob:w,kForOnEventAttribute:Symbol(`kIsForOnEventAttribute`),kListener:Symbol(`kListener`),kStatusCode:Symbol(`status-code`),kWebSocket:Symbol(`websocket`),NOOP:()=>{}}})),require_buffer_util$1=__commonJSMin$1(((e,t)=>{let{EMPTY_BUFFER:S}=require_constants$1(),w=Buffer[Symbol.species];function E(e,t){if(e.length===0)return S;if(e.length===1)return e[0];let E=Buffer.allocUnsafe(t),D=0;for(let t=0;t<e.length;t++){let S=e[t];E.set(S,D),D+=S.length}return D<t?new w(E.buffer,E.byteOffset,D):E}function D(e,t,S,w,E){for(let D=0;D<E;D++)S[w+D]=e[D]^t[D&3]}function O(e,t){for(let S=0;S<e.length;S++)e[S]^=t[S&3]}function k(e){return e.length===e.buffer.byteLength?e.buffer:e.buffer.slice(e.byteOffset,e.byteOffset+e.length)}function j(e){if(j.readOnly=!0,Buffer.isBuffer(e))return e;let t;return e instanceof ArrayBuffer?t=new w(e):ArrayBuffer.isView(e)?t=new w(e.buffer,e.byteOffset,e.byteLength):(t=Buffer.from(e),j.readOnly=!1),t}if(t.exports={concat:E,mask:D,toArrayBuffer:k,toBuffer:j,unmask:O},!process.env.WS_NO_BUFFER_UTIL)try{let e=__require$1(`bufferutil`);t.exports.mask=function(t,S,w,E,O){O<48?D(t,S,w,E,O):e.mask(t,S,w,E,O)},t.exports.unmask=function(t,S){t.length<32?O(t,S):e.unmask(t,S)}}catch{}})),require_limiter$1=__commonJSMin$1(((e,t)=>{let S=Symbol(`kDone`),w=Symbol(`kRun`);t.exports=class{constructor(e){this[S]=()=>{this.pending--,this[w]()},this.concurrency=e||1/0,this.jobs=[],this.pending=0}add(e){this.jobs.push(e),this[w]()}[w](){if(this.pending!==this.concurrency&&this.jobs.length){let e=this.jobs.shift();this.pending++,e(this[S])}}}})),require_permessage_deflate$1=__commonJSMin$1(((e,t)=>{let S=__require$1(`zlib`),w=require_buffer_util$1(),E=require_limiter$1(),{kStatusCode:D}=require_constants$1(),O=Buffer[Symbol.species],k=Buffer.from([0,0,255,255]),j=Symbol(`permessage-deflate`),F=Symbol(`total-length`),L=Symbol(`callback`),B=Symbol(`buffers`),H=Symbol(`error`),q;t.exports=class{constructor(e){this._options=e||{},this._threshold=this._options.threshold===void 0?1024:this._options.threshold,this._maxPayload=this._options.maxPayload|0,this._isServer=!!this._options.isServer,this._deflate=null,this._inflate=null,this.params=null,q||=new E(this._options.concurrencyLimit===void 0?10:this._options.concurrencyLimit)}static get extensionName(){return`permessage-deflate`}offer(){let e={};return this._options.serverNoContextTakeover&&(e.server_no_context_takeover=!0),this._options.clientNoContextTakeover&&(e.client_no_context_takeover=!0),this._options.serverMaxWindowBits&&(e.server_max_window_bits=this._options.serverMaxWindowBits),this._options.clientMaxWindowBits?e.client_max_window_bits=this._options.clientMaxWindowBits:this._options.clientMaxWindowBits??(e.client_max_window_bits=!0),e}accept(e){return e=this.normalizeParams(e),this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e),this.params}cleanup(){if(this._inflate&&=(this._inflate.close(),null),this._deflate){let e=this._deflate[L];this._deflate.close(),this._deflate=null,e&&e(Error(`The deflate stream was closed while data was being processed`))}}acceptAsServer(e){let t=this._options,S=e.find(e=>!(t.serverNoContextTakeover===!1&&e.server_no_context_takeover||e.server_max_window_bits&&(t.serverMaxWindowBits===!1||typeof t.serverMaxWindowBits==`number`&&t.serverMaxWindowBits>e.server_max_window_bits)||typeof t.clientMaxWindowBits==`number`&&!e.client_max_window_bits));if(!S)throw Error(`None of the extension offers can be accepted`);return t.serverNoContextTakeover&&(S.server_no_context_takeover=!0),t.clientNoContextTakeover&&(S.client_no_context_takeover=!0),typeof t.serverMaxWindowBits==`number`&&(S.server_max_window_bits=t.serverMaxWindowBits),typeof t.clientMaxWindowBits==`number`?S.client_max_window_bits=t.clientMaxWindowBits:(S.client_max_window_bits===!0||t.clientMaxWindowBits===!1)&&delete S.client_max_window_bits,S}acceptAsClient(e){let t=e[0];if(this._options.clientNoContextTakeover===!1&&t.client_no_context_takeover)throw Error(`Unexpected parameter "client_no_context_takeover"`);if(!t.client_max_window_bits)typeof this._options.clientMaxWindowBits==`number`&&(t.client_max_window_bits=this._options.clientMaxWindowBits);else if(this._options.clientMaxWindowBits===!1||typeof this._options.clientMaxWindowBits==`number`&&t.client_max_window_bits>this._options.clientMaxWindowBits)throw Error(`Unexpected or invalid parameter "client_max_window_bits"`);return t}normalizeParams(e){return e.forEach(e=>{Object.keys(e).forEach(t=>{let S=e[t];if(S.length>1)throw Error(`Parameter "${t}" must have only a single value`);if(S=S[0],t===`client_max_window_bits`){if(S!==!0){let e=+S;if(!Number.isInteger(e)||e<8||e>15)throw TypeError(`Invalid value for parameter "${t}": ${S}`);S=e}else if(!this._isServer)throw TypeError(`Invalid value for parameter "${t}": ${S}`)}else if(t===`server_max_window_bits`){let e=+S;if(!Number.isInteger(e)||e<8||e>15)throw TypeError(`Invalid value for parameter "${t}": ${S}`);S=e}else if(t===`client_no_context_takeover`||t===`server_no_context_takeover`){if(S!==!0)throw TypeError(`Invalid value for parameter "${t}": ${S}`)}else throw Error(`Unknown parameter "${t}"`);e[t]=S})}),e}decompress(e,t,S){q.add(w=>{this._decompress(e,t,(e,t)=>{w(),S(e,t)})})}compress(e,t,S){q.add(w=>{this._compress(e,t,(e,t)=>{w(),S(e,t)})})}_decompress(e,t,E){let D=this._isServer?`client`:`server`;if(!this._inflate){let e=`${D}_max_window_bits`,t=typeof this.params[e]==`number`?this.params[e]:S.Z_DEFAULT_WINDOWBITS;this._inflate=S.createInflateRaw({...this._options.zlibInflateOptions,windowBits:t}),this._inflate[j]=this,this._inflate[F]=0,this._inflate[B]=[],this._inflate.on(`error`,ee),this._inflate.on(`data`,Y)}this._inflate[L]=E,this._inflate.write(e),t&&this._inflate.write(k),this._inflate.flush(()=>{let e=this._inflate[H];if(e){this._inflate.close(),this._inflate=null,E(e);return}let S=w.concat(this._inflate[B],this._inflate[F]);this._inflate._readableState.endEmitted?(this._inflate.close(),this._inflate=null):(this._inflate[F]=0,this._inflate[B]=[],t&&this.params[`${D}_no_context_takeover`]&&this._inflate.reset()),E(null,S)})}_compress(e,t,E){let D=this._isServer?`server`:`client`;if(!this._deflate){let e=`${D}_max_window_bits`,t=typeof this.params[e]==`number`?this.params[e]:S.Z_DEFAULT_WINDOWBITS;this._deflate=S.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:t}),this._deflate[F]=0,this._deflate[B]=[],this._deflate.on(`data`,J)}this._deflate[L]=E,this._deflate.write(e),this._deflate.flush(S.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let e=w.concat(this._deflate[B],this._deflate[F]);t&&(e=new O(e.buffer,e.byteOffset,e.length-4)),this._deflate[L]=null,this._deflate[F]=0,this._deflate[B]=[],t&&this.params[`${D}_no_context_takeover`]&&this._deflate.reset(),E(null,e)})}};function J(e){this[B].push(e),this[F]+=e.length}function Y(e){if(this[F]+=e.length,this[j]._maxPayload<1||this[F]<=this[j]._maxPayload){this[B].push(e);return}this[H]=RangeError(`Max payload size exceeded`),this[H].code=`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`,this[H][D]=1009,this.removeListener(`data`,Y),this.reset()}function ee(e){if(this[j]._inflate=null,this[H]){this[L](this[H]);return}e[D]=1007,this[L](e)}})),require_validation$1=__commonJSMin$1(((e,t)=>{let{isUtf8:S}=__require$1(`buffer`),{hasBlob:w}=require_constants$1(),E=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function D(e){return e>=1e3&&e<=1014&&e!==1004&&e!==1005&&e!==1006||e>=3e3&&e<=4999}function O(e){let t=e.length,S=0;for(;S<t;)if(!(e[S]&128))S++;else if((e[S]&224)==192){if(S+1===t||(e[S+1]&192)!=128||(e[S]&254)==192)return!1;S+=2}else if((e[S]&240)==224){if(S+2>=t||(e[S+1]&192)!=128||(e[S+2]&192)!=128||e[S]===224&&(e[S+1]&224)==128||e[S]===237&&(e[S+1]&224)==160)return!1;S+=3}else if((e[S]&248)==240){if(S+3>=t||(e[S+1]&192)!=128||(e[S+2]&192)!=128||(e[S+3]&192)!=128||e[S]===240&&(e[S+1]&240)==128||e[S]===244&&e[S+1]>143||e[S]>244)return!1;S+=4}else return!1;return!0}function k(e){return w&&typeof e==`object`&&typeof e.arrayBuffer==`function`&&typeof e.type==`string`&&typeof e.stream==`function`&&(e[Symbol.toStringTag]===`Blob`||e[Symbol.toStringTag]===`File`)}if(t.exports={isBlob:k,isValidStatusCode:D,isValidUTF8:O,tokenChars:E},S)t.exports.isValidUTF8=function(e){return e.length<24?O(e):S(e)};else if(!process.env.WS_NO_UTF_8_VALIDATE)try{let e=__require$1(`utf-8-validate`);t.exports.isValidUTF8=function(t){return t.length<32?O(t):e(t)}}catch{}})),require_receiver$1=__commonJSMin$1(((e,t)=>{let{Writable:S}=__require$1(`stream`),w=require_permessage_deflate$1(),{BINARY_TYPES:E,EMPTY_BUFFER:D,kStatusCode:O,kWebSocket:k}=require_constants$1(),{concat:j,toArrayBuffer:F,unmask:L}=require_buffer_util$1(),{isValidStatusCode:B,isValidUTF8:H}=require_validation$1(),q=Buffer[Symbol.species],J=0,Y=1,ee=2,te=3,ne=4,ae=5,oe=6;t.exports=class extends S{constructor(e={}){super(),this._allowSynchronousEvents=e.allowSynchronousEvents===void 0?!0:e.allowSynchronousEvents,this._binaryType=e.binaryType||E[0],this._extensions=e.extensions||{},this._isServer=!!e.isServer,this._maxPayload=e.maxPayload|0,this._skipUTF8Validation=!!e.skipUTF8Validation,this[k]=void 0,this._bufferedBytes=0,this._buffers=[],this._compressed=!1,this._payloadLength=0,this._mask=void 0,this._fragmented=0,this._masked=!1,this._fin=!1,this._opcode=0,this._totalPayloadLength=0,this._messageLength=0,this._fragments=[],this._errored=!1,this._loop=!1,this._state=0}_write(e,t,S){if(this._opcode===8&&this._state==0)return S();this._bufferedBytes+=e.length,this._buffers.push(e),this.startLoop(S)}consume(e){if(this._bufferedBytes-=e,e===this._buffers[0].length)return this._buffers.shift();if(e<this._buffers[0].length){let t=this._buffers[0];return this._buffers[0]=new q(t.buffer,t.byteOffset+e,t.length-e),new q(t.buffer,t.byteOffset,e)}let t=Buffer.allocUnsafe(e);do{let S=this._buffers[0],w=t.length-e;e>=S.length?t.set(this._buffers.shift(),w):(t.set(new Uint8Array(S.buffer,S.byteOffset,e),w),this._buffers[0]=new q(S.buffer,S.byteOffset+e,S.length-e)),e-=S.length}while(e>0);return t}startLoop(e){this._loop=!0;do switch(this._state){case 0:this.getInfo(e);break;case 1:this.getPayloadLength16(e);break;case 2:this.getPayloadLength64(e);break;case 3:this.getMask();break;case 4:this.getData(e);break;case 5:case 6:this._loop=!1;return}while(this._loop);this._errored||e()}getInfo(e){if(this._bufferedBytes<2){this._loop=!1;return}let t=this.consume(2);if(t[0]&48){e(this.createError(RangeError,`RSV2 and RSV3 must be clear`,!0,1002,`WS_ERR_UNEXPECTED_RSV_2_3`));return}let S=(t[0]&64)==64;if(S&&!this._extensions[w.extensionName]){e(this.createError(RangeError,`RSV1 must be clear`,!0,1002,`WS_ERR_UNEXPECTED_RSV_1`));return}if(this._fin=(t[0]&128)==128,this._opcode=t[0]&15,this._payloadLength=t[1]&127,this._opcode===0){if(S){e(this.createError(RangeError,`RSV1 must be clear`,!0,1002,`WS_ERR_UNEXPECTED_RSV_1`));return}if(!this._fragmented){e(this.createError(RangeError,`invalid opcode 0`,!0,1002,`WS_ERR_INVALID_OPCODE`));return}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){e(this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,`WS_ERR_INVALID_OPCODE`));return}this._compressed=S}else if(this._opcode>7&&this._opcode<11){if(!this._fin){e(this.createError(RangeError,`FIN must be set`,!0,1002,`WS_ERR_EXPECTED_FIN`));return}if(S){e(this.createError(RangeError,`RSV1 must be clear`,!0,1002,`WS_ERR_UNEXPECTED_RSV_1`));return}if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1){e(this.createError(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002,`WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH`));return}}else{e(this.createError(RangeError,`invalid opcode ${this._opcode}`,!0,1002,`WS_ERR_INVALID_OPCODE`));return}if(!this._fin&&!this._fragmented&&(this._fragmented=this._opcode),this._masked=(t[1]&128)==128,this._isServer){if(!this._masked){e(this.createError(RangeError,`MASK must be set`,!0,1002,`WS_ERR_EXPECTED_MASK`));return}}else if(this._masked){e(this.createError(RangeError,`MASK must be clear`,!0,1002,`WS_ERR_UNEXPECTED_MASK`));return}this._payloadLength===126?this._state=1:this._payloadLength===127?this._state=2:this.haveLength(e)}getPayloadLength16(e){if(this._bufferedBytes<2){this._loop=!1;return}this._payloadLength=this.consume(2).readUInt16BE(0),this.haveLength(e)}getPayloadLength64(e){if(this._bufferedBytes<8){this._loop=!1;return}let t=this.consume(8),S=t.readUInt32BE(0);if(S>2**21-1){e(this.createError(RangeError,`Unsupported WebSocket frame: payload length > 2^53 - 1`,!1,1009,`WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH`));return}this._payloadLength=S*2**32+t.readUInt32BE(4),this.haveLength(e)}haveLength(e){if(this._payloadLength&&this._opcode<8&&(this._totalPayloadLength+=this._payloadLength,this._totalPayloadLength>this._maxPayload&&this._maxPayload>0)){e(this.createError(RangeError,`Max payload size exceeded`,!1,1009,`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`));return}this._masked?this._state=3:this._state=4}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=4}getData(e){let t=D;if(this._payloadLength){if(this._bufferedBytes<this._payloadLength){this._loop=!1;return}t=this.consume(this._payloadLength),this._masked&&(this._mask[0]|this._mask[1]|this._mask[2]|this._mask[3])!==0&&L(t,this._mask)}if(this._opcode>7){this.controlMessage(t,e);return}if(this._compressed){this._state=5,this.decompress(t,e);return}t.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(t)),this.dataMessage(e)}decompress(e,t){this._extensions[w.extensionName].decompress(e,this._fin,(e,S)=>{if(e)return t(e);if(S.length){if(this._messageLength+=S.length,this._messageLength>this._maxPayload&&this._maxPayload>0){t(this.createError(RangeError,`Max payload size exceeded`,!1,1009,`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`));return}this._fragments.push(S)}this.dataMessage(t),this._state===0&&this.startLoop(t)})}dataMessage(e){if(!this._fin){this._state=0;return}let t=this._messageLength,S=this._fragments;if(this._totalPayloadLength=0,this._messageLength=0,this._fragmented=0,this._fragments=[],this._opcode===2){let w;w=this._binaryType===`nodebuffer`?j(S,t):this._binaryType===`arraybuffer`?F(j(S,t)):this._binaryType===`blob`?new Blob(S):S,this._allowSynchronousEvents?(this.emit(`message`,w,!0),this._state=0):(this._state=6,setImmediate(()=>{this.emit(`message`,w,!0),this._state=0,this.startLoop(e)}))}else{let w=j(S,t);if(!this._skipUTF8Validation&&!H(w)){e(this.createError(Error,`invalid UTF-8 sequence`,!0,1007,`WS_ERR_INVALID_UTF8`));return}this._state===5||this._allowSynchronousEvents?(this.emit(`message`,w,!1),this._state=0):(this._state=6,setImmediate(()=>{this.emit(`message`,w,!1),this._state=0,this.startLoop(e)}))}}controlMessage(e,t){if(this._opcode===8){if(e.length===0)this._loop=!1,this.emit(`conclude`,1005,D),this.end();else{let S=e.readUInt16BE(0);if(!B(S)){t(this.createError(RangeError,`invalid status code ${S}`,!0,1002,`WS_ERR_INVALID_CLOSE_CODE`));return}let w=new q(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!H(w)){t(this.createError(Error,`invalid UTF-8 sequence`,!0,1007,`WS_ERR_INVALID_UTF8`));return}this._loop=!1,this.emit(`conclude`,S,w),this.end()}this._state=0;return}this._allowSynchronousEvents?(this.emit(this._opcode===9?`ping`:`pong`,e),this._state=0):(this._state=6,setImmediate(()=>{this.emit(this._opcode===9?`ping`:`pong`,e),this._state=0,this.startLoop(t)}))}createError(e,t,S,w,E){this._loop=!1,this._errored=!0;let D=new e(S?`Invalid WebSocket frame: ${t}`:t);return Error.captureStackTrace(D,this.createError),D.code=E,D[O]=w,D}}})),require_sender$1=__commonJSMin$1(((e,t)=>{let{Duplex:S}=__require$1(`stream`),{randomFillSync:w}=__require$1(`crypto`),E=require_permessage_deflate$1(),{EMPTY_BUFFER:D,kWebSocket:O,NOOP:k}=require_constants$1(),{isBlob:j,isValidStatusCode:F}=require_validation$1(),{mask:L,toBuffer:B}=require_buffer_util$1(),H=Symbol(`kByteLength`),q=Buffer.alloc(4),J=8*1024,Y,ee=J,te=0,ne=1,ae=2;t.exports=class e{constructor(e,t,S){this._extensions=t||{},S&&(this._generateMask=S,this._maskBuffer=Buffer.alloc(4)),this._socket=e,this._firstFragment=!0,this._compress=!1,this._bufferedBytes=0,this._queue=[],this._state=0,this.onerror=k,this[O]=void 0}static frame(e,t){let S,E=!1,D=2,O=!1;t.mask&&(S=t.maskBuffer||q,t.generateMask?t.generateMask(S):(ee===J&&(Y===void 0&&(Y=Buffer.alloc(J)),w(Y,0,J),ee=0),S[0]=Y[ee++],S[1]=Y[ee++],S[2]=Y[ee++],S[3]=Y[ee++]),O=(S[0]|S[1]|S[2]|S[3])===0,D=6);let k;typeof e==`string`?(!t.mask||O)&&t[H]!==void 0?k=t[H]:(e=Buffer.from(e),k=e.length):(k=e.length,E=t.mask&&t.readOnly&&!O);let j=k;k>=65536?(D+=8,j=127):k>125&&(D+=2,j=126);let F=Buffer.allocUnsafe(E?k+D:D);return F[0]=t.fin?t.opcode|128:t.opcode,t.rsv1&&(F[0]|=64),F[1]=j,j===126?F.writeUInt16BE(k,2):j===127&&(F[2]=F[3]=0,F.writeUIntBE(k,4,6)),!t.mask||(F[1]|=128,F[D-4]=S[0],F[D-3]=S[1],F[D-2]=S[2],F[D-1]=S[3],O)?[F,e]:E?(L(e,S,F,D,k),[F]):(L(e,S,e,0,k),[F,e])}close(t,S,w,E){let O;if(t===void 0)O=D;else if(typeof t!=`number`||!F(t))throw TypeError(`First argument must be a valid error code number`);else if(S===void 0||!S.length)O=Buffer.allocUnsafe(2),O.writeUInt16BE(t,0);else{let e=Buffer.byteLength(S);if(e>123)throw RangeError(`The message must not be greater than 123 bytes`);O=Buffer.allocUnsafe(2+e),O.writeUInt16BE(t,0),typeof S==`string`?O.write(S,2):O.set(S,2)}let k={[H]:O.length,fin:!0,generateMask:this._generateMask,mask:w,maskBuffer:this._maskBuffer,opcode:8,readOnly:!1,rsv1:!1};this._state===0?this.sendFrame(e.frame(O,k),E):this.enqueue([this.dispatch,O,!1,k,E])}ping(t,S,w){let E,D;if(typeof t==`string`?(E=Buffer.byteLength(t),D=!1):j(t)?(E=t.size,D=!1):(t=B(t),E=t.length,D=B.readOnly),E>125)throw RangeError(`The data size must not be greater than 125 bytes`);let O={[H]:E,fin:!0,generateMask:this._generateMask,mask:S,maskBuffer:this._maskBuffer,opcode:9,readOnly:D,rsv1:!1};j(t)?this._state===0?this.getBlobData(t,!1,O,w):this.enqueue([this.getBlobData,t,!1,O,w]):this._state===0?this.sendFrame(e.frame(t,O),w):this.enqueue([this.dispatch,t,!1,O,w])}pong(t,S,w){let E,D;if(typeof t==`string`?(E=Buffer.byteLength(t),D=!1):j(t)?(E=t.size,D=!1):(t=B(t),E=t.length,D=B.readOnly),E>125)throw RangeError(`The data size must not be greater than 125 bytes`);let O={[H]:E,fin:!0,generateMask:this._generateMask,mask:S,maskBuffer:this._maskBuffer,opcode:10,readOnly:D,rsv1:!1};j(t)?this._state===0?this.getBlobData(t,!1,O,w):this.enqueue([this.getBlobData,t,!1,O,w]):this._state===0?this.sendFrame(e.frame(t,O),w):this.enqueue([this.dispatch,t,!1,O,w])}send(e,t,S){let w=this._extensions[E.extensionName],D=t.binary?2:1,O=t.compress,k,F;typeof e==`string`?(k=Buffer.byteLength(e),F=!1):j(e)?(k=e.size,F=!1):(e=B(e),k=e.length,F=B.readOnly),this._firstFragment?(this._firstFragment=!1,O&&w&&w.params[w._isServer?`server_no_context_takeover`:`client_no_context_takeover`]&&(O=k>=w._threshold),this._compress=O):(O=!1,D=0),t.fin&&(this._firstFragment=!0);let L={[H]:k,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:D,readOnly:F,rsv1:O};j(e)?this._state===0?this.getBlobData(e,this._compress,L,S):this.enqueue([this.getBlobData,e,this._compress,L,S]):this._state===0?this.dispatch(e,this._compress,L,S):this.enqueue([this.dispatch,e,this._compress,L,S])}getBlobData(t,S,w,E){this._bufferedBytes+=w[H],this._state=2,t.arrayBuffer().then(t=>{if(this._socket.destroyed){let e=Error(`The socket was closed while the blob was being read`);process.nextTick(oe,this,e,E);return}this._bufferedBytes-=w[H];let D=B(t);S?this.dispatch(D,S,w,E):(this._state=0,this.sendFrame(e.frame(D,w),E),this.dequeue())}).catch(e=>{process.nextTick(se,this,e,E)})}dispatch(t,S,w,D){if(!S){this.sendFrame(e.frame(t,w),D);return}let O=this._extensions[E.extensionName];this._bufferedBytes+=w[H],this._state=1,O.compress(t,w.fin,(t,S)=>{if(this._socket.destroyed){oe(this,Error(`The socket was closed while data was being compressed`),D);return}this._bufferedBytes-=w[H],this._state=0,w.readOnly=!1,this.sendFrame(e.frame(S,w),D),this.dequeue()})}dequeue(){for(;this._state===0&&this._queue.length;){let e=this._queue.shift();this._bufferedBytes-=e[3][H],Reflect.apply(e[0],this,e.slice(1))}}enqueue(e){this._bufferedBytes+=e[3][H],this._queue.push(e)}sendFrame(e,t){e.length===2?(this._socket.cork(),this._socket.write(e[0]),this._socket.write(e[1],t),this._socket.uncork()):this._socket.write(e[0],t)}};function oe(e,t,S){typeof S==`function`&&S(t);for(let S=0;S<e._queue.length;S++){let w=e._queue[S],E=w[w.length-1];typeof E==`function`&&E(t)}}function se(e,t,S){oe(e,t,S),e.onerror(t)}})),require_event_target$1=__commonJSMin$1(((e,t)=>{let{kForOnEventAttribute:S,kListener:w}=require_constants$1(),E=Symbol(`kCode`),D=Symbol(`kData`),O=Symbol(`kError`),k=Symbol(`kMessage`),j=Symbol(`kReason`),F=Symbol(`kTarget`),L=Symbol(`kType`),B=Symbol(`kWasClean`);var H=class{constructor(e){this[F]=null,this[L]=e}get target(){return this[F]}get type(){return this[L]}};Object.defineProperty(H.prototype,`target`,{enumerable:!0}),Object.defineProperty(H.prototype,`type`,{enumerable:!0});var q=class extends H{constructor(e,t={}){super(e),this[E]=t.code===void 0?0:t.code,this[j]=t.reason===void 0?``:t.reason,this[B]=t.wasClean===void 0?!1:t.wasClean}get code(){return this[E]}get reason(){return this[j]}get wasClean(){return this[B]}};Object.defineProperty(q.prototype,`code`,{enumerable:!0}),Object.defineProperty(q.prototype,`reason`,{enumerable:!0}),Object.defineProperty(q.prototype,`wasClean`,{enumerable:!0});var J=class extends H{constructor(e,t={}){super(e),this[O]=t.error===void 0?null:t.error,this[k]=t.message===void 0?``:t.message}get error(){return this[O]}get message(){return this[k]}};Object.defineProperty(J.prototype,`error`,{enumerable:!0}),Object.defineProperty(J.prototype,`message`,{enumerable:!0});var Y=class extends H{constructor(e,t={}){super(e),this[D]=t.data===void 0?null:t.data}get data(){return this[D]}};Object.defineProperty(Y.prototype,`data`,{enumerable:!0}),t.exports={CloseEvent:q,ErrorEvent:J,Event:H,EventTarget:{addEventListener(e,t,E={}){for(let D of this.listeners(e))if(!E[S]&&D[w]===t&&!D[S])return;let D;if(e===`message`)D=function(e,S){let w=new Y(`message`,{data:S?e:e.toString()});w[F]=this,ee(t,this,w)};else if(e===`close`)D=function(e,S){let w=new q(`close`,{code:e,reason:S.toString(),wasClean:this._closeFrameReceived&&this._closeFrameSent});w[F]=this,ee(t,this,w)};else if(e===`error`)D=function(e){let S=new J(`error`,{error:e,message:e.message});S[F]=this,ee(t,this,S)};else if(e===`open`)D=function(){let e=new H(`open`);e[F]=this,ee(t,this,e)};else return;D[S]=!!E[S],D[w]=t,E.once?this.once(e,D):this.on(e,D)},removeEventListener(e,t){for(let E of this.listeners(e))if(E[w]===t&&!E[S]){this.removeListener(e,E);break}}},MessageEvent:Y};function ee(e,t,S){typeof e==`object`&&e.handleEvent?e.handleEvent.call(e,S):e.call(t,S)}})),require_extension$1=__commonJSMin$1(((e,t)=>{let{tokenChars:S}=require_validation$1();function w(e,t,S){e[t]===void 0?e[t]=[S]:e[t].push(S)}function E(e){let t=Object.create(null),E=Object.create(null),D=!1,O=!1,k=!1,j,F,L=-1,B=-1,H=-1,q=0;for(;q<e.length;q++)if(B=e.charCodeAt(q),j===void 0)if(H===-1&&S[B]===1)L===-1&&(L=q);else if(q!==0&&(B===32||B===9))H===-1&&L!==-1&&(H=q);else if(B===59||B===44){if(L===-1)throw SyntaxError(`Unexpected character at index ${q}`);H===-1&&(H=q);let S=e.slice(L,H);B===44?(w(t,S,E),E=Object.create(null)):j=S,L=H=-1}else throw SyntaxError(`Unexpected character at index ${q}`);else if(F===void 0)if(H===-1&&S[B]===1)L===-1&&(L=q);else if(B===32||B===9)H===-1&&L!==-1&&(H=q);else if(B===59||B===44){if(L===-1)throw SyntaxError(`Unexpected character at index ${q}`);H===-1&&(H=q),w(E,e.slice(L,H),!0),B===44&&(w(t,j,E),E=Object.create(null),j=void 0),L=H=-1}else if(B===61&&L!==-1&&H===-1)F=e.slice(L,q),L=H=-1;else throw SyntaxError(`Unexpected character at index ${q}`);else if(O){if(S[B]!==1)throw SyntaxError(`Unexpected character at index ${q}`);L===-1?L=q:D||=!0,O=!1}else if(k)if(S[B]===1)L===-1&&(L=q);else if(B===34&&L!==-1)k=!1,H=q;else if(B===92)O=!0;else throw SyntaxError(`Unexpected character at index ${q}`);else if(B===34&&e.charCodeAt(q-1)===61)k=!0;else if(H===-1&&S[B]===1)L===-1&&(L=q);else if(L!==-1&&(B===32||B===9))H===-1&&(H=q);else if(B===59||B===44){if(L===-1)throw SyntaxError(`Unexpected character at index ${q}`);H===-1&&(H=q);let S=e.slice(L,H);D&&=(S=S.replace(/\\/g,``),!1),w(E,F,S),B===44&&(w(t,j,E),E=Object.create(null),j=void 0),F=void 0,L=H=-1}else throw SyntaxError(`Unexpected character at index ${q}`);if(L===-1||k||B===32||B===9)throw SyntaxError(`Unexpected end of input`);H===-1&&(H=q);let J=e.slice(L,H);return j===void 0?w(t,J,E):(F===void 0?w(E,J,!0):D?w(E,F,J.replace(/\\/g,``)):w(E,F,J),w(t,j,E)),t}function D(e){return Object.keys(e).map(t=>{let S=e[t];return Array.isArray(S)||(S=[S]),S.map(e=>[t].concat(Object.keys(e).map(t=>{let S=e[t];return Array.isArray(S)||(S=[S]),S.map(e=>e===!0?t:`${t}=${e}`).join(`; `)})).join(`; `)).join(`, `)}).join(`, `)}t.exports={format:D,parse:E}})),require_websocket$1=__commonJSMin$1(((e,t)=>{let S=__require$1(`events`),w=__require$1(`https`),E=__require$1(`http`),D=__require$1(`net`),O=__require$1(`tls`),{randomBytes:k,createHash:j}=__require$1(`crypto`),{Duplex:F,Readable:L}=__require$1(`stream`),{URL:B}=__require$1(`url`),H=require_permessage_deflate$1(),q=require_receiver$1(),J=require_sender$1(),{isBlob:Y}=require_validation$1(),{BINARY_TYPES:ee,CLOSE_TIMEOUT:te,EMPTY_BUFFER:ne,GUID:ae,kForOnEventAttribute:oe,kListener:se,kStatusCode:ce,kWebSocket:ue,NOOP:de}=require_constants$1(),{EventTarget:{addEventListener:fe,removeEventListener:me}}=require_event_target$1(),{format:ge,parse:_e}=require_extension$1(),{toBuffer:ve}=require_buffer_util$1(),ye=Symbol(`kAborted`),Ce=[8,13],we=[`CONNECTING`,`OPEN`,`CLOSING`,`CLOSED`],Te=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;var De=class e extends S{constructor(t,S,w){super(),this._binaryType=ee[0],this._closeCode=1006,this._closeFrameReceived=!1,this._closeFrameSent=!1,this._closeMessage=ne,this._closeTimer=null,this._errorEmitted=!1,this._extensions={},this._paused=!1,this._protocol=``,this._readyState=e.CONNECTING,this._receiver=null,this._sender=null,this._socket=null,t===null?(this._autoPong=w.autoPong,this._closeTimeout=w.closeTimeout,this._isServer=!0):(this._bufferedAmount=0,this._isServer=!1,this._redirects=0,S===void 0?S=[]:Array.isArray(S)||(typeof S==`object`&&S?(w=S,S=[]):S=[S]),je(this,t,S,w))}get binaryType(){return this._binaryType}set binaryType(e){ee.includes(e)&&(this._binaryType=e,this._receiver&&(this._receiver._binaryType=e))}get bufferedAmount(){return this._socket?this._socket._writableState.length+this._sender._bufferedBytes:this._bufferedAmount}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(t,S,w){let E=new q({allowSynchronousEvents:w.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxPayload:w.maxPayload,skipUTF8Validation:w.skipUTF8Validation}),D=new J(t,this._extensions,w.generateMask);this._receiver=E,this._sender=D,this._socket=t,E[ue]=this,D[ue]=this,t[ue]=this,E.on(`conclude`,Be),E.on(`drain`,Ve),E.on(`error`,Ue),E.on(`message`,Ge),E.on(`ping`,Ke),E.on(`pong`,Xe),D.onerror=nt,t.setTimeout&&t.setTimeout(0),t.setNoDelay&&t.setNoDelay(),S.length>0&&t.unshift(S),t.on(`close`,it),t.on(`data`,at),t.on(`end`,st),t.on(`error`,vt),this._readyState=e.OPEN,this.emit(`open`)}emitClose(){if(!this._socket){this._readyState=e.CLOSED,this.emit(`close`,this._closeCode,this._closeMessage);return}this._extensions[H.extensionName]&&this._extensions[H.extensionName].cleanup(),this._receiver.removeAllListeners(),this._readyState=e.CLOSED,this.emit(`close`,this._closeCode,this._closeMessage)}close(t,S){if(this.readyState!==e.CLOSED){if(this.readyState===e.CONNECTING){Re(this,this._req,`WebSocket was closed before the connection was established`);return}if(this.readyState===e.CLOSING){this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end();return}this._readyState=e.CLOSING,this._sender.close(t,S,!this._isServer,e=>{e||(this._closeFrameSent=!0,(this._closeFrameReceived||this._receiver._writableState.errorEmitted)&&this._socket.end())}),rt(this)}}pause(){this.readyState===e.CONNECTING||this.readyState===e.CLOSED||(this._paused=!0,this._socket.pause())}ping(t,S,w){if(this.readyState===e.CONNECTING)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(typeof t==`function`?(w=t,t=S=void 0):typeof S==`function`&&(w=S,S=void 0),typeof t==`number`&&(t=t.toString()),this.readyState!==e.OPEN){ze(this,t,w);return}S===void 0&&(S=!this._isServer),this._sender.ping(t||ne,S,w)}pong(t,S,w){if(this.readyState===e.CONNECTING)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(typeof t==`function`?(w=t,t=S=void 0):typeof S==`function`&&(w=S,S=void 0),typeof t==`number`&&(t=t.toString()),this.readyState!==e.OPEN){ze(this,t,w);return}S===void 0&&(S=!this._isServer),this._sender.pong(t||ne,S,w)}resume(){this.readyState===e.CONNECTING||this.readyState===e.CLOSED||(this._paused=!1,this._receiver._writableState.needDrain||this._socket.resume())}send(t,S,w){if(this.readyState===e.CONNECTING)throw Error(`WebSocket is not open: readyState 0 (CONNECTING)`);if(typeof S==`function`&&(w=S,S={}),typeof t==`number`&&(t=t.toString()),this.readyState!==e.OPEN){ze(this,t,w);return}let E={binary:typeof t!=`string`,mask:!this._isServer,compress:!0,fin:!0,...S};this._extensions[H.extensionName]||(E.compress=!1),this._sender.send(t||ne,E,w)}terminate(){if(this.readyState!==e.CLOSED){if(this.readyState===e.CONNECTING){Re(this,this._req,`WebSocket was closed before the connection was established`);return}this._socket&&(this._readyState=e.CLOSING,this._socket.destroy())}}};Object.defineProperty(De,`CONNECTING`,{enumerable:!0,value:we.indexOf(`CONNECTING`)}),Object.defineProperty(De.prototype,`CONNECTING`,{enumerable:!0,value:we.indexOf(`CONNECTING`)}),Object.defineProperty(De,`OPEN`,{enumerable:!0,value:we.indexOf(`OPEN`)}),Object.defineProperty(De.prototype,`OPEN`,{enumerable:!0,value:we.indexOf(`OPEN`)}),Object.defineProperty(De,`CLOSING`,{enumerable:!0,value:we.indexOf(`CLOSING`)}),Object.defineProperty(De.prototype,`CLOSING`,{enumerable:!0,value:we.indexOf(`CLOSING`)}),Object.defineProperty(De,`CLOSED`,{enumerable:!0,value:we.indexOf(`CLOSED`)}),Object.defineProperty(De.prototype,`CLOSED`,{enumerable:!0,value:we.indexOf(`CLOSED`)}),[`binaryType`,`bufferedAmount`,`extensions`,`isPaused`,`protocol`,`readyState`,`url`].forEach(e=>{Object.defineProperty(De.prototype,e,{enumerable:!0})}),[`open`,`error`,`close`,`message`].forEach(e=>{Object.defineProperty(De.prototype,`on${e}`,{enumerable:!0,get(){for(let t of this.listeners(e))if(t[oe])return t[se];return null},set(t){for(let t of this.listeners(e))if(t[oe]){this.removeListener(e,t);break}typeof t==`function`&&this.addEventListener(e,t,{[oe]:!0})}})}),De.prototype.addEventListener=fe,De.prototype.removeEventListener=me,t.exports=De;function je(e,t,S,D){let O={allowSynchronousEvents:!0,autoPong:!0,closeTimeout:te,protocolVersion:Ce[1],maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!0,followRedirects:!1,maxRedirects:10,...D,socketPath:void 0,hostname:void 0,protocol:void 0,timeout:void 0,method:`GET`,host:void 0,path:void 0,port:void 0};if(e._autoPong=O.autoPong,e._closeTimeout=O.closeTimeout,!Ce.includes(O.protocolVersion))throw RangeError(`Unsupported protocol version: ${O.protocolVersion} (supported versions: ${Ce.join(`, `)})`);let F;if(t instanceof B)F=t;else try{F=new B(t)}catch{throw SyntaxError(`Invalid URL: ${t}`)}F.protocol===`http:`?F.protocol=`ws:`:F.protocol===`https:`&&(F.protocol=`wss:`),e._url=F.href;let L=F.protocol===`wss:`,q=F.protocol===`ws+unix:`,J;if(F.protocol!==`ws:`&&!L&&!q?J=`The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"`:q&&!F.pathname?J=`The URL's pathname is empty`:F.hash&&(J=`The URL contains a fragment identifier`),J){let t=SyntaxError(J);if(e._redirects===0)throw t;Me(e,t);return}let Y=L?443:80,ee=k(16).toString(`base64`),ne=L?w.request:E.request,oe=new Set,se;if(O.createConnection=O.createConnection||(L?Ie:Pe),O.defaultPort=O.defaultPort||Y,O.port=F.port||Y,O.host=F.hostname.startsWith(`[`)?F.hostname.slice(1,-1):F.hostname,O.headers={...O.headers,"Sec-WebSocket-Version":O.protocolVersion,"Sec-WebSocket-Key":ee,Connection:`Upgrade`,Upgrade:`websocket`},O.path=F.pathname+F.search,O.timeout=O.handshakeTimeout,O.perMessageDeflate&&(se=new H({...O.perMessageDeflate,isServer:!1,maxPayload:O.maxPayload}),O.headers[`Sec-WebSocket-Extensions`]=ge({[H.extensionName]:se.offer()})),S.length){for(let e of S){if(typeof e!=`string`||!Te.test(e)||oe.has(e))throw SyntaxError(`An invalid or duplicated subprotocol was specified`);oe.add(e)}O.headers[`Sec-WebSocket-Protocol`]=S.join(`,`)}if(O.origin&&(O.protocolVersion<13?O.headers[`Sec-WebSocket-Origin`]=O.origin:O.headers.Origin=O.origin),(F.username||F.password)&&(O.auth=`${F.username}:${F.password}`),q){let e=O.path.split(`:`);O.socketPath=e[0],O.path=e[1]}let ce;if(O.followRedirects){if(e._redirects===0){e._originalIpc=q,e._originalSecure=L,e._originalHostOrSocketPath=q?O.socketPath:F.host;let t=D&&D.headers;if(D={...D,headers:{}},t)for(let[e,S]of Object.entries(t))D.headers[e.toLowerCase()]=S}else if(e.listenerCount(`redirect`)===0){let t=q?e._originalIpc?O.socketPath===e._originalHostOrSocketPath:!1:e._originalIpc?!1:F.host===e._originalHostOrSocketPath;(!t||e._originalSecure&&!L)&&(delete O.headers.authorization,delete O.headers.cookie,t||delete O.headers.host,O.auth=void 0)}O.auth&&!D.headers.authorization&&(D.headers.authorization=`Basic `+Buffer.from(O.auth).toString(`base64`)),ce=e._req=ne(O),e._redirects&&e.emit(`redirect`,e.url,ce)}else ce=e._req=ne(O);O.timeout&&ce.on(`timeout`,()=>{Re(e,ce,`Opening handshake has timed out`)}),ce.on(`error`,t=>{ce===null||ce[ye]||(ce=e._req=null,Me(e,t))}),ce.on(`response`,w=>{let E=w.headers.location,k=w.statusCode;if(E&&O.followRedirects&&k>=300&&k<400){if(++e._redirects>O.maxRedirects){Re(e,ce,`Maximum redirects exceeded`);return}ce.abort();let w;try{w=new B(E,t)}catch{Me(e,SyntaxError(`Invalid URL: ${E}`));return}je(e,w,S,D)}else e.emit(`unexpected-response`,ce,w)||Re(e,ce,`Unexpected server response: ${w.statusCode}`)}),ce.on(`upgrade`,(t,S,w)=>{if(e.emit(`upgrade`,t),e.readyState!==De.CONNECTING)return;ce=e._req=null;let E=t.headers.upgrade;if(E===void 0||E.toLowerCase()!==`websocket`){Re(e,S,`Invalid Upgrade header`);return}let D=j(`sha1`).update(ee+ae).digest(`base64`);if(t.headers[`sec-websocket-accept`]!==D){Re(e,S,`Invalid Sec-WebSocket-Accept header`);return}let k=t.headers[`sec-websocket-protocol`],F;if(k===void 0?oe.size&&(F=`Server sent no subprotocol`):oe.size?oe.has(k)||(F=`Server sent an invalid subprotocol`):F=`Server sent a subprotocol but none was requested`,F){Re(e,S,F);return}k&&(e._protocol=k);let L=t.headers[`sec-websocket-extensions`];if(L!==void 0){if(!se){Re(e,S,`Server sent a Sec-WebSocket-Extensions header but no extension was requested`);return}let t;try{t=_e(L)}catch{Re(e,S,`Invalid Sec-WebSocket-Extensions header`);return}let w=Object.keys(t);if(w.length!==1||w[0]!==H.extensionName){Re(e,S,`Server indicated an extension that was not requested`);return}try{se.accept(t[H.extensionName])}catch{Re(e,S,`Invalid Sec-WebSocket-Extensions header`);return}e._extensions[H.extensionName]=se}e.setSocket(S,w,{allowSynchronousEvents:O.allowSynchronousEvents,generateMask:O.generateMask,maxPayload:O.maxPayload,skipUTF8Validation:O.skipUTF8Validation})}),O.finishRequest?O.finishRequest(ce,e):ce.end()}function Me(e,t){e._readyState=De.CLOSING,e._errorEmitted=!0,e.emit(`error`,t),e.emitClose()}function Pe(e){return e.path=e.socketPath,D.connect(e)}function Ie(e){return e.path=void 0,!e.servername&&e.servername!==``&&(e.servername=D.isIP(e.host)?``:e.host),O.connect(e)}function Re(e,t,S){e._readyState=De.CLOSING;let w=Error(S);Error.captureStackTrace(w,Re),t.setHeader?(t[ye]=!0,t.abort(),t.socket&&!t.socket.destroyed&&t.socket.destroy(),process.nextTick(Me,e,w)):(t.destroy(w),t.once(`error`,e.emit.bind(e,`error`)),t.once(`close`,e.emitClose.bind(e)))}function ze(e,t,S){if(t){let S=Y(t)?t.size:ve(t).length;e._socket?e._sender._bufferedBytes+=S:e._bufferedAmount+=S}if(S){let t=Error(`WebSocket is not open: readyState ${e.readyState} (${we[e.readyState]})`);process.nextTick(S,t)}}function Be(e,t){let S=this[ue];S._closeFrameReceived=!0,S._closeMessage=t,S._closeCode=e,S._socket[ue]!==void 0&&(S._socket.removeListener(`data`,at),process.nextTick($e,S._socket),e===1005?S.close():S.close(e,t))}function Ve(){let e=this[ue];e.isPaused||e._socket.resume()}function Ue(e){let t=this[ue];t._socket[ue]!==void 0&&(t._socket.removeListener(`data`,at),process.nextTick($e,t._socket),t.close(e[ce])),t._errorEmitted||(t._errorEmitted=!0,t.emit(`error`,e))}function We(){this[ue].emitClose()}function Ge(e,t){this[ue].emit(`message`,e,t)}function Ke(e){let t=this[ue];t._autoPong&&t.pong(e,!this._isServer,de),t.emit(`ping`,e)}function Xe(e){this[ue].emit(`pong`,e)}function $e(e){e.resume()}function nt(e){let t=this[ue];t.readyState!==De.CLOSED&&(t.readyState===De.OPEN&&(t._readyState=De.CLOSING,rt(t)),this._socket.end(),t._errorEmitted||(t._errorEmitted=!0,t.emit(`error`,e)))}function rt(e){e._closeTimer=setTimeout(e._socket.destroy.bind(e._socket),e._closeTimeout)}function it(){let e=this[ue];if(this.removeListener(`close`,it),this.removeListener(`data`,at),this.removeListener(`end`,st),e._readyState=De.CLOSING,!this._readableState.endEmitted&&!e._closeFrameReceived&&!e._receiver._writableState.errorEmitted&&this._readableState.length!==0){let t=this.read(this._readableState.length);e._receiver.write(t)}e._receiver.end(),this[ue]=void 0,clearTimeout(e._closeTimer),e._receiver._writableState.finished||e._receiver._writableState.errorEmitted?e.emitClose():(e._receiver.on(`error`,We),e._receiver.on(`finish`,We))}function at(e){this[ue]._receiver.write(e)||this.pause()}function st(){let e=this[ue];e._readyState=De.CLOSING,e._receiver.end(),this.end()}function vt(){let e=this[ue];this.removeListener(`error`,vt),this.on(`error`,de),e&&(e._readyState=De.CLOSING,this.destroy())}})),require_stream$1=__commonJSMin$1(((e,t)=>{require_websocket$1();let{Duplex:S}=__require$1(`stream`);function w(e){e.emit(`close`)}function E(){!this.destroyed&&this._writableState.finished&&this.destroy()}function D(e){this.removeListener(`error`,D),this.destroy(),this.listenerCount(`error`)===0&&this.emit(`error`,e)}function O(e,t){let O=!0,k=new S({...t,autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1});return e.on(`message`,function(t,S){let w=!S&&k._readableState.objectMode?t.toString():t;k.push(w)||e.pause()}),e.once(`error`,function(e){k.destroyed||(O=!1,k.destroy(e))}),e.once(`close`,function(){k.destroyed||k.push(null)}),k._destroy=function(t,S){if(e.readyState===e.CLOSED){S(t),process.nextTick(w,k);return}let E=!1;e.once(`error`,function(e){E=!0,S(e)}),e.once(`close`,function(){E||S(t),process.nextTick(w,k)}),O&&e.terminate()},k._final=function(t){if(e.readyState===e.CONNECTING){e.once(`open`,function(){k._final(t)});return}e._socket!==null&&(e._socket._writableState.finished?(t(),k._readableState.endEmitted&&k.destroy()):(e._socket.once(`finish`,function(){t()}),e.close()))},k._read=function(){e.isPaused&&e.resume()},k._write=function(t,S,w){if(e.readyState===e.CONNECTING){e.once(`open`,function(){k._write(t,S,w)});return}e.send(t,w)},k.on(`end`,E),k.on(`error`,D),k}t.exports=O})),require_subprotocol$1=__commonJSMin$1(((e,t)=>{let{tokenChars:S}=require_validation$1();function w(e){let t=new Set,w=-1,E=-1,D=0;for(;D<e.length;D++){let O=e.charCodeAt(D);if(E===-1&&S[O]===1)w===-1&&(w=D);else if(D!==0&&(O===32||O===9))E===-1&&w!==-1&&(E=D);else if(O===44){if(w===-1)throw SyntaxError(`Unexpected character at index ${D}`);E===-1&&(E=D);let S=e.slice(w,E);if(t.has(S))throw SyntaxError(`The "${S}" subprotocol is duplicated`);t.add(S),w=E=-1}else throw SyntaxError(`Unexpected character at index ${D}`)}if(w===-1||E!==-1)throw SyntaxError(`Unexpected end of input`);let O=e.slice(w,D);if(t.has(O))throw SyntaxError(`The "${O}" subprotocol is duplicated`);return t.add(O),t}t.exports={parse:w}})),require_websocket_server$1=__commonJSMin$1(((e,t)=>{let S=__require$1(`events`),w=__require$1(`http`),{Duplex:E}=__require$1(`stream`),{createHash:D}=__require$1(`crypto`),O=require_extension$1(),k=require_permessage_deflate$1(),j=require_subprotocol$1(),F=require_websocket$1(),{CLOSE_TIMEOUT:L,GUID:B,kWebSocket:H}=require_constants$1(),q=/^[+/0-9A-Za-z]{22}==$/,J=0,Y=1,ee=2;t.exports=class extends S{constructor(e,t){if(super(),e={allowSynchronousEvents:!0,autoPong:!0,maxPayload:100*1024*1024,skipUTF8Validation:!1,perMessageDeflate:!1,handleProtocols:null,clientTracking:!0,closeTimeout:L,verifyClient:null,noServer:!1,backlog:null,server:null,host:null,path:null,port:null,WebSocket:F,...e},e.port==null&&!e.server&&!e.noServer||e.port!=null&&(e.server||e.noServer)||e.server&&e.noServer)throw TypeError(`One and only one of the "port", "server", or "noServer" options must be specified`);if(e.port==null?e.server&&(this._server=e.server):(this._server=w.createServer((e,t)=>{let S=w.STATUS_CODES[426];t.writeHead(426,{"Content-Length":S.length,"Content-Type":`text/plain`}),t.end(S)}),this._server.listen(e.port,e.host,e.backlog,t)),this._server){let e=this.emit.bind(this,`connection`);this._removeListeners=te(this._server,{listening:this.emit.bind(this,`listening`),error:this.emit.bind(this,`error`),upgrade:(t,S,w)=>{this.handleUpgrade(t,S,w,e)}})}e.perMessageDeflate===!0&&(e.perMessageDeflate={}),e.clientTracking&&(this.clients=new Set,this._shouldEmitClose=!1),this.options=e,this._state=0}address(){if(this.options.noServer)throw Error(`The server is operating in "noServer" mode`);return this._server?this._server.address():null}close(e){if(this._state===2){e&&this.once(`close`,()=>{e(Error(`The server is not running`))}),process.nextTick(ne,this);return}if(e&&this.once(`close`,e),this._state!==1)if(this._state=1,this.options.noServer||this.options.server)this._server&&(this._removeListeners(),this._removeListeners=this._server=null),this.clients&&this.clients.size?this._shouldEmitClose=!0:process.nextTick(ne,this);else{let e=this._server;this._removeListeners(),this._removeListeners=this._server=null,e.close(()=>{ne(this)})}}shouldHandle(e){if(this.options.path){let t=e.url.indexOf(`?`);if((t===-1?e.url:e.url.slice(0,t))!==this.options.path)return!1}return!0}handleUpgrade(e,t,S,w){t.on(`error`,ae);let E=e.headers[`sec-websocket-key`],D=e.headers.upgrade,F=+e.headers[`sec-websocket-version`];if(e.method!==`GET`){se(this,e,t,405,`Invalid HTTP method`);return}if(D===void 0||D.toLowerCase()!==`websocket`){se(this,e,t,400,`Invalid Upgrade header`);return}if(E===void 0||!q.test(E)){se(this,e,t,400,`Missing or invalid Sec-WebSocket-Key header`);return}if(F!==13&&F!==8){se(this,e,t,400,`Missing or invalid Sec-WebSocket-Version header`,{"Sec-WebSocket-Version":`13, 8`});return}if(!this.shouldHandle(e)){oe(t,400);return}let L=e.headers[`sec-websocket-protocol`],B=new Set;if(L!==void 0)try{B=j.parse(L)}catch{se(this,e,t,400,`Invalid Sec-WebSocket-Protocol header`);return}let H=e.headers[`sec-websocket-extensions`],J={};if(this.options.perMessageDeflate&&H!==void 0){let S=new k({...this.options.perMessageDeflate,isServer:!0,maxPayload:this.options.maxPayload});try{let e=O.parse(H);e[k.extensionName]&&(S.accept(e[k.extensionName]),J[k.extensionName]=S)}catch{se(this,e,t,400,`Invalid or unacceptable Sec-WebSocket-Extensions header`);return}}if(this.options.verifyClient){let D={origin:e.headers[`${F===8?`sec-websocket-origin`:`origin`}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(D,(D,O,k,j)=>{if(!D)return oe(t,O||401,k,j);this.completeUpgrade(J,E,B,e,t,S,w)});return}if(!this.options.verifyClient(D))return oe(t,401)}this.completeUpgrade(J,E,B,e,t,S,w)}completeUpgrade(e,t,S,w,E,j,F){if(!E.readable||!E.writable)return E.destroy();if(E[H])throw Error(`server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration`);if(this._state>0)return oe(E,503);let L=[`HTTP/1.1 101 Switching Protocols`,`Upgrade: websocket`,`Connection: Upgrade`,`Sec-WebSocket-Accept: ${D(`sha1`).update(t+B).digest(`base64`)}`],q=new this.options.WebSocket(null,void 0,this.options);if(S.size){let e=this.options.handleProtocols?this.options.handleProtocols(S,w):S.values().next().value;e&&(L.push(`Sec-WebSocket-Protocol: ${e}`),q._protocol=e)}if(e[k.extensionName]){let t=e[k.extensionName].params,S=O.format({[k.extensionName]:[t]});L.push(`Sec-WebSocket-Extensions: ${S}`),q._extensions=e}this.emit(`headers`,L,w),E.write(L.concat(`\r
|
|
1127
1127
|
`).join(`\r
|
|
1128
1128
|
`)),E.removeListener(`error`,ae),q.setSocket(E,j,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(q),q.on(`close`,()=>{this.clients.delete(q),this._shouldEmitClose&&!this.clients.size&&process.nextTick(ne,this)})),F(q,w)}};function te(e,t){for(let S of Object.keys(t))e.on(S,t[S]);return function(){for(let S of Object.keys(t))e.removeListener(S,t[S])}}function ne(e){e._state=2,e.emit(`close`)}function ae(){this.destroy()}function oe(e,t,S,E){S||=w.STATUS_CODES[t],E={Connection:`close`,"Content-Type":`text/html`,"Content-Length":Buffer.byteLength(S),...E},e.once(`finish`,e.destroy),e.end(`HTTP/1.1 ${t} ${w.STATUS_CODES[t]}\r\n`+Object.keys(E).map(e=>`${e}: ${E[e]}`).join(`\r
|
|
1129
1129
|
`)+`\r
|
|
@@ -1133,7 +1133,7 @@ ${e.terminator}`}function Qa(e){return`(${Ee(e.body)})${ke(e.redirections)}`}fun
|
|
|
1133
1133
|
`)),E.removeListener(`error`,ae),q.setSocket(E,j,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation}),this.clients&&(this.clients.add(q),q.on(`close`,()=>{this.clients.delete(q),this._shouldEmitClose&&!this.clients.size&&process.nextTick(ne,this)})),F(q,w)}};function te(e,t){for(let S of Object.keys(t))e.on(S,t[S]);return function(){for(let S of Object.keys(t))e.removeListener(S,t[S])}}function ne(e){e._state=2,e.emit(`close`)}function ae(){this.destroy()}function oe(e,t,S,E){S||=w.STATUS_CODES[t],E={Connection:`close`,"Content-Type":`text/html`,"Content-Length":Buffer.byteLength(S),...E},e.once(`finish`,e.destroy),e.end(`HTTP/1.1 ${t} ${w.STATUS_CODES[t]}\r\n`+Object.keys(E).map(e=>`${e}: ${E[e]}`).join(`\r
|
|
1134
1134
|
`)+`\r
|
|
1135
1135
|
\r
|
|
1136
|
-
`+S)}function se(e,t,S,w,E,D){if(e.listenerCount(`wsClientError`)){let w=Error(E);Error.captureStackTrace(w,se),e.emit(`wsClientError`,w,S,t)}else oe(S,w,E,D)}}));require_stream(),require_receiver(),require_sender(),require_websocket();var import_websocket_server=__toESM(require_websocket_server(),1);init_esm$2();var import_pino=__toESM$1(require_pino(),1),import_pino_pretty=__toESM$1(require_pino_pretty(),1),import_src=require_src$14(),import_src$1=require_src$13(),import_src$2=require_src$4(),import_src$3=require_src$3(),import_src$4=require_src$2(),import_src$5=require_src$1(),import_src$6=require_src();init_esm$1();var import_lib=__toESM$1(require_lib(),1),import_yazl=__toESM$1(require_yazl(),1),import_shell_quote=__toESM$1(require_shell_quote(),1),import_ignore=__toESM$1(require_ignore(),1);const MAX_LEN=128;function sanitizeGitIdentity(e){return e.replace(/[<>\r\n]/g,``).trim().slice(0,MAX_LEN)}const AGENT_ID_RE=/^[a-zA-Z0-9_-]+$/,AGENT_ID_MAX_LEN=64;function validateAgentId(e){return typeof e!=`string`||e.length===0||e.length>64||!AGENT_ID_RE.test(e)?null:e}function toBroadcasterKey(e){return e.startsWith(`agent-`)?e:`agent-${e}`}function isPresenceEligibleAgentId(e){return!e.startsWith(`principal-`)}function resolveAgentType(e){if(!e)return`bot`;let t=e.toLowerCase();return t.includes(`claude`)?`claude`:t.includes(`cursor`)?`cursor`:t.includes(`codex`)?`codex`:t.includes(`cline`)?`cline`:t.includes(`windsurf`)?`windsurf`:`bot`}function parseAgentBodyFields(e){let t=validateAgentId(typeof e.agentId==`string`?e.agentId:null)??void 0;return{rawAgentId:t,writerId:t===void 0?void 0:toBroadcasterKey(t),displayName:typeof e.agentName==`string`?sanitizeGitIdentity(e.agentName):`Claude`,clientName:typeof e.clientName==`string`?sanitizeGitIdentity(e.clientName):void 0,clientVersion:typeof e.clientVersion==`string`?sanitizeGitIdentity(e.clientVersion):void 0,label:typeof e.label==`string`?sanitizeGitIdentity(e.label):void 0,colorSeed:typeof e.colorSeed==`string`&&e.colorSeed.length>0?e.colorSeed.slice(0,128):void 0}}function otelMixin(){let e=trace.getSpan(context.active());if(!e)return{};let t=e.spanContext();return{trace_id:t.traceId,span_id:t.spanId,trace_flags:t.traceFlags}}function shouldColorize(){return process.env.NO_COLOR&&process.env.NO_COLOR!==``?!1:process.stdout.isTTY??!1}var PinoLogger=class{name;transportConfigs=[];pinoInstance;options;constructor(e,t={}){this.name=e,this.options={name:this.name,level:process.env.LOG_LEVEL||(process.env.NODE_ENV===`test`?`silent`:`info`),serializers:{err:import_pino.default.stdSerializers.err,error:import_pino.default.stdSerializers.err},mixin:otelMixin,...t.options},t.transportConfigs&&(this.transportConfigs=t.transportConfigs),this.pinoInstance=this.buildInstance()}buildInstance(){if(this.transportConfigs.length>0)return(0,import_pino.default)(this.options,import_pino.default.transport({targets:this.transportConfigs}));try{let e=(0,import_pino_pretty.default)({colorize:shouldColorize(),translateTime:`HH:MM:ss`,ignore:`pid,hostname`});return(0,import_pino.default)(this.options,e)}catch(e){return console.warn(`[PinoLogger] pino-pretty failed, falling back to JSON:`,e),(0,import_pino.default)(this.options)}}recreateInstance(){typeof this.pinoInstance.flush==`function`&&this.pinoInstance.flush(),this.pinoInstance=this.buildInstance()}addTransport(e){this.transportConfigs.push(e),this.recreateInstance()}removeTransport(e){e>=0&&e<this.transportConfigs.length&&(this.transportConfigs.splice(e,1),this.recreateInstance())}getTransports(){return[...this.transportConfigs]}updateOptions(e){this.options={...this.options,...e},this.recreateInstance()}getPinoInstance(){return this.pinoInstance}error(e,t){this.pinoInstance.error(e,t)}warn(e,t){this.pinoInstance.warn(e,t)}info(e,t){this.pinoInstance.info(e,t)}debug(e,t){this.pinoInstance.debug(e,t)}},LoggerFactory=class{config={};loggers=new Map;configure(e){this.config=e,this.loggers.clear()}getLogger(e){let t=this.loggers.get(e);if(t)return t;let S;return S=this.config.loggerFactory?this.config.loggerFactory(e):this.config.defaultLogger?this.config.defaultLogger:new PinoLogger(e,this.config.pinoConfig),this.loggers.set(e,S),S}reset(){this.config={},this.loggers.clear()}};const loggerFactory=new LoggerFactory;function getLogger(e){return loggerFactory.getLogger(e)}function createTestLogger(e=`test`){return new PinoLogger(e,{options:{level:`silent`}})}function installTestLoggers(){loggerFactory.configure({pinoConfig:{options:{level:`silent`}}})}var AgentFocusBroadcaster=class{hocuspocus;log=getLogger(`agent-focus`);warnedMissing=!1;constructor(e){this.hocuspocus=e}setFocus(e,t){isPresenceEligibleAgentId(e)&&this.mutateAgentFocus(S=>({...S,[e]:t}))}clearFocus(e){isPresenceEligibleAgentId(e)&&this.mutateAgentFocus(t=>{if(!(e in t))return t;let{[e]:S,...w}=t;return w})}getFocusMap(){let e=this.resolveAwareness();return e?e.getLocalState()?.agentFocus??{}:{}}mutateAgentFocus(e){let t=this.resolveAwareness();if(t)try{let S=t.getLocalState()??{},w=e(S.agentFocus??{});t.setLocalState({...S,agentFocus:w})}catch(e){this.log.error({err:e},`[agent-focus] awareness mutation failed`)}}resolveAwareness(){let e=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);return e?(this.warnedMissing&&=(this.log.info({},`[agent-focus] __system__ document now available — resuming focus updates`),!1),getAwareness$1(e)):(this.warnedMissing||=(this.log.warn({},`[agent-focus] __system__ document not found — focus updates will be dropped until it is materialized`),!0),null)}};function getAwareness$1(e){return e?.awareness??null}const counters$1={reconcileCount:0,conflictCount:0,batchCount:0,upstreamImportCount:0,rescueBufferCount:0,branchSwitchCount:0,parkCount:0,gitAutoSaveFailureCount:0,gitWriterCommitFailureCount:0,cc1BroadcastCount:0,cc1BroadcastDropCount:0,cc1SubscriberCount:0,cc1LastSeq:{},serverObserverFiresA:0,serverObserverFiresB:0,serverObserverErrorsA:0,serverObserverErrorsB:0,persistenceDiskWrites:0,bridgeMergeContentLoss:0,bridgeMergeCheckpointCreated:0,bridgeInvariantViolations:0,bridgeInvariantViolationsSuppressed:0,persistenceSkipNonQuiescent:0,persistenceForceFlushDuringBurst:0,collabSocketEpipeCount:0,collabSocketEconnresetCount:0,collabMessageTooLargeCount:0,shadowMigrationLegacyRefsDeleted:0,effectDiffCaptureFailures:0,agentPresenceMutationErrors:0,agentWriteCalls:0,summariesProvided:0,summariesTruncated:0,agentPatchFindMismatches:0,bridgeToleranceApplied:{},observerAPathBFires:0,observerAPathBFiresSuppressed:0,persistenceReconciliationFailures:0,externalChangeHandlerErrors:0,persistenceSanityCheckSerializeFailures:0,deferredStoreFailures:0,authRenameRedirectCount:0,authDocDeletedCount:0,recentlyRemovedDocsEvictions:0,recentlyRemovedDocsSize:0,authRemovalGuardErrors:0,removalRedirectChainCycles:0};function incrementReconcile(){counters$1.reconcileCount++}function incrementConflict(){counters$1.conflictCount++}function incrementBatch(){counters$1.batchCount++}function incrementUpstreamImport(){counters$1.upstreamImportCount++}function incrementRescueBuffer(){counters$1.rescueBufferCount++}function incrementBranchSwitch(){counters$1.branchSwitchCount++}function incrementPark(){counters$1.parkCount++}function incrementGitAutoSaveFailure(){counters$1.gitAutoSaveFailureCount++}function incrementGitWriterCommitFailure(){counters$1.gitWriterCommitFailureCount++}function incrementCC1Broadcast(){counters$1.cc1BroadcastCount++}function incrementCC1BroadcastDrop(){counters$1.cc1BroadcastDropCount++}function setCC1SubscriberCount(e){counters$1.cc1SubscriberCount=e}function incrementServerObserverFire(e){e===`a`?counters$1.serverObserverFiresA++:counters$1.serverObserverFiresB++}function incrementPersistenceDiskWrite(){counters$1.persistenceDiskWrites++}function incrementServerObserverError(e){e===`a`?counters$1.serverObserverErrorsA++:counters$1.serverObserverErrorsB++}function incrementBridgeMergeContentLoss(){counters$1.bridgeMergeContentLoss++}function incrementAgentWriteCalls(){counters$1.agentWriteCalls++}function incrementSummariesProvided(){counters$1.summariesProvided++}function incrementSummariesTruncated(){counters$1.summariesTruncated++}function incrementBridgeMergeCheckpointCreated(){counters$1.bridgeMergeCheckpointCreated++}function incrementBridgeInvariantViolations(){counters$1.bridgeInvariantViolations++}function incrementBridgeInvariantViolationsSuppressed(){counters$1.bridgeInvariantViolationsSuppressed++}function incrementPersistenceSkipNonQuiescent(){counters$1.persistenceSkipNonQuiescent++}function incrementPersistenceForceFlushDuringBurst(){counters$1.persistenceForceFlushDuringBurst++}function incrementAgentPatchFindMismatches(){counters$1.agentPatchFindMismatches++}function incrementBridgeToleranceApplied(e){counters$1.bridgeToleranceApplied[e]=(counters$1.bridgeToleranceApplied[e]??0)+1}function incrementObserverAPathBFires(){counters$1.observerAPathBFires++}function incrementObserverAPathBFiresSuppressed(){counters$1.observerAPathBFiresSuppressed++}function incrementPersistenceReconciliationFailures(){counters$1.persistenceReconciliationFailures++}function incrementExternalChangeHandlerErrors(){counters$1.externalChangeHandlerErrors++}function incrementPersistenceSanityCheckSerializeFailures(){counters$1.persistenceSanityCheckSerializeFailures++}function incrementDeferredStoreFailures(){counters$1.deferredStoreFailures++}function incrementAuthRenameRedirect(){counters$1.authRenameRedirectCount++}function incrementAuthDocDeleted(){counters$1.authDocDeletedCount++}function incrementRecentlyRemovedDocsEviction(){counters$1.recentlyRemovedDocsEvictions++}function setRecentlyRemovedDocsSize(e){counters$1.recentlyRemovedDocsSize=e}function incrementAuthRemovalGuardError(){counters$1.authRemovalGuardErrors++}function incrementRemovalRedirectChainCycle(){counters$1.removalRedirectChainCycles++}function incrementCollabSocketFilteredError(e){e===`EPIPE`?counters$1.collabSocketEpipeCount++:counters$1.collabSocketEconnresetCount++}function incrementCollabMessageTooLarge(){counters$1.collabMessageTooLargeCount++}function incrementShadowMigrationLegacyRefsDeleted(e){counters$1.shadowMigrationLegacyRefsDeleted+=e}function incrementEffectDiffCaptureFailures(){counters$1.effectDiffCaptureFailures++}function incrementAgentPresenceMutationError(){counters$1.agentPresenceMutationErrors++}function handleCollabSocketError(e){return e.code===`EPIPE`||e.code===`ECONNRESET`?(incrementCollabSocketFilteredError(e.code),!0):!1}function setCC1LastSeq(e,t){counters$1.cc1LastSeq[e]=t}function getMetrics(){return{...counters$1,cc1LastSeq:{...counters$1.cc1LastSeq},bridgeToleranceApplied:{...counters$1.bridgeToleranceApplied}}}function resetMetrics(){counters$1.reconcileCount=0,counters$1.conflictCount=0,counters$1.batchCount=0,counters$1.upstreamImportCount=0,counters$1.rescueBufferCount=0,counters$1.branchSwitchCount=0,counters$1.parkCount=0,counters$1.gitAutoSaveFailureCount=0,counters$1.gitWriterCommitFailureCount=0,counters$1.cc1BroadcastCount=0,counters$1.cc1BroadcastDropCount=0,counters$1.cc1SubscriberCount=0,counters$1.cc1LastSeq={},counters$1.serverObserverFiresA=0,counters$1.serverObserverFiresB=0,counters$1.serverObserverErrorsA=0,counters$1.serverObserverErrorsB=0,counters$1.persistenceDiskWrites=0,counters$1.bridgeMergeContentLoss=0,counters$1.bridgeMergeCheckpointCreated=0,counters$1.bridgeInvariantViolations=0,counters$1.bridgeInvariantViolationsSuppressed=0,counters$1.persistenceSkipNonQuiescent=0,counters$1.persistenceForceFlushDuringBurst=0,counters$1.collabSocketEpipeCount=0,counters$1.collabSocketEconnresetCount=0,counters$1.collabMessageTooLargeCount=0,counters$1.shadowMigrationLegacyRefsDeleted=0,counters$1.effectDiffCaptureFailures=0,counters$1.agentPresenceMutationErrors=0,counters$1.agentWriteCalls=0,counters$1.summariesProvided=0,counters$1.summariesTruncated=0,counters$1.agentPatchFindMismatches=0,counters$1.bridgeToleranceApplied={},counters$1.observerAPathBFires=0,counters$1.observerAPathBFiresSuppressed=0,counters$1.persistenceReconciliationFailures=0,counters$1.externalChangeHandlerErrors=0,counters$1.persistenceSanityCheckSerializeFailures=0,counters$1.deferredStoreFailures=0,counters$1.authRenameRedirectCount=0,counters$1.authDocDeletedCount=0,counters$1.recentlyRemovedDocsEvictions=0,counters$1.recentlyRemovedDocsSize=0,counters$1.authRemovalGuardErrors=0,counters$1.removalRedirectChainCycles=0}const BROADCASTER_EVICTION_MS=5e3*4;var AgentPresenceBroadcaster=class{hocuspocus;log=getLogger(`agent-presence`);warnedMissing=!1;destroyed=!1;constructor(e){this.hocuspocus=e}setPresence(e,t){if(!isPresenceEligibleAgentId(e))return;let S=0;this.mutateAgentPresence(w=>{let E=Date.now(),D={};for(let[t,O]of Object.entries(w)){if(E-O.ts>=2e4&&t!==e){S++;continue}D[t]=O}return D[e]=t,D})&&(this.log.debug({agentId:e,action:`set`,currentDoc:t.currentDoc,ts:t.ts},`[agent-presence] set`),S>0&&this.log.info({evictedCount:S,thresholdMs:BROADCASTER_EVICTION_MS},`[agent-presence] evicted stale entries`))}clearPresence(e){if(!isPresenceEligibleAgentId(e))return;let t=!1;this.mutateAgentPresence(S=>{if(!S[e])return S;t=!0;let{[e]:w,...E}=S;return E})&&t&&this.log.info({agentId:e,action:`clear`,currentDoc:null,ts:Date.now()},`[agent-presence] clear`)}touchMode(e,t){if(!isPresenceEligibleAgentId(e))return;let S=[],w=!1,E=this.mutateAgentPresence(E=>{let D=E[e];if(!D)return E;w=!0;let O=Date.now();return S.push({currentDoc:D.currentDoc,ts:O}),{...E,[e]:{...D,mode:t,ts:O}}}),D=S[0];E&&D?this.log.debug({agentId:e,action:`touchMode`,currentDoc:D.currentDoc,ts:D.ts,mode:t},`[agent-presence] touchMode`):w||this.log.debug({agentId:e,action:`touchMode`,mode:t,reason:`entry-missing`},`[agent-presence] touchMode skipped — no entry for agentId`)}bumpPresenceTs(e){if(!isPresenceEligibleAgentId(e))return;let t=null;this.mutateAgentPresence(S=>{let w=S[e];if(!w)return S;let E=Date.now();return t=E,{...S,[e]:{...w,ts:E}}}),t!==null&&this.log.debug({agentId:e,action:`bumpTs`,ts:t},`[agent-presence] bumpTs`)}getPresenceMap(){let e=this.resolveAwareness();return e?e.getLocalState()?.agentPresence??{}:{}}destroy(){this.destroyed=!0}mutateAgentPresence(e){if(this.destroyed)return!1;let t=this.resolveAwareness();if(!t)return!1;try{let S=t.getLocalState()??{},w=e(S.agentPresence??{});return t.setLocalState({...S,agentPresence:w}),!0}catch(e){return incrementAgentPresenceMutationError(),this.log.error({err:e},`[agent-presence] awareness mutation failed`),!1}}resolveAwareness(){let e=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);return e?(this.warnedMissing&&=(this.log.info({},`[agent-presence] __system__ document now available — resuming presence updates`),!1),getAwareness(e)):(this.warnedMissing||=(this.log.warn({},`[agent-presence] __system__ document not found — presence updates will be dropped until it is materialized`),!0),null)}};function getAwareness(e){return e?.awareness??null}const mdManager=new MarkdownManager({extensions:sharedExtensions}),schema=getSchema(sharedExtensions),TRACER_NAME=`open-knowledge-server`;let tracerProvider=null,meterProvider=null;function noopResult(){return{tracer:trace.getTracer(TRACER_NAME),meter:metrics$1.getMeter(TRACER_NAME)}}function initTelemetry(){if(process.env.OTEL_SDK_DISABLED!==`false`||tracerProvider)return noopResult();try{let e=(0,import_src$4.resourceFromAttributes)({[ATTR_SERVICE_NAME]:process.env.OTEL_SERVICE_NAME||`open-knowledge-server`,[ATTR_SERVICE_VERSION]:process.env.OTEL_SERVICE_VERSION||`0.2.0`}),t=new import_src.AsyncLocalStorageContextManager;context.setGlobalContextManager(t);let S=new import_src$6.BasicTracerProvider({resource:e,spanProcessors:[new import_src$6.BatchSpanProcessor(new import_src$3.OTLPTraceExporter)]});trace.setGlobalTracerProvider(S),propagation.setGlobalPropagator(new import_src$1.W3CTraceContextPropagator);let w=new import_src$5.MeterProvider({resource:e,readers:[new import_src$5.PeriodicExportingMetricReader({exporter:new import_src$2.OTLPMetricExporter})]});metrics$1.setGlobalMeterProvider(w),tracerProvider=S,meterProvider=w,getLogger(`telemetry`).info({otlp_endpoint:process.env.OTEL_EXPORTER_OTLP_ENDPOINT||`http://localhost:4318`,service_name:e.attributes[ATTR_SERVICE_NAME]},`OpenTelemetry initialized — traces + metrics exporting via OTLP/HTTP`)}catch(e){getLogger(`telemetry`).error({err:e},`failed to initialize OpenTelemetry — falling back to no-op`),tracerProvider=null,meterProvider=null}return noopResult()}const SHUTDOWN_TIMEOUT_MS=5e3;async function shutdownTelemetry(){if(!tracerProvider&&!meterProvider)return;let e=getLogger(`telemetry`),t=Promise.all([tracerProvider?.shutdown().catch(t=>{e.warn({err:t},`tracer provider shutdown failed`)}),meterProvider?.shutdown().catch(t=>{e.warn({err:t},`meter provider shutdown failed`)})]);await Promise.race([t.then(()=>!1),new Promise(e=>setTimeout(()=>e(!0),SHUTDOWN_TIMEOUT_MS))])&&e.warn({},`telemetry shutdown timed out after ${SHUTDOWN_TIMEOUT_MS}ms — data may be lost`),tracerProvider=null,meterProvider=null,trace.disable(),metrics$1.disable(),context.disable()}function getTracer(){return trace.getTracer(TRACER_NAME)}function getMeter(){return metrics$1.getMeter(TRACER_NAME)}async function withSpan(e,t,S){return getTracer().startActiveSpan(e,t??{},async e=>{try{let t=await S(e);return e.isRecording(),t}catch(t){throw e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t instanceof Error?t.message:String(t)}),t}finally{e.end()}})}function withSpanSync(e,t,S){return getTracer().startActiveSpan(e,t??{},e=>{try{return S(e)}catch(t){throw e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t instanceof Error?t.message:String(t)}),t}finally{e.end()}})}function setActiveSpanAttributes(e){let t=trace.getSpan(context.active());t&&t.setAttributes(e)}function buildParseOpts(e){return e?{resolveEmbed:e.resolveEmbed,resolveSize:e.resolveSize,sourcePath:e.sourcePath}:void 0}function composeAndWriteRawBody(e,t,S,w){withSpanSync(`bridge.composeAndWriteRawBody`,{attributes:{surface:S,"body.bytes":t.length,"doc.name":e.guid}},()=>{let S=e.getXmlFragment(`default`),E=e.getText(`source`),D=E.toString(),{body:O}=stripFrontmatter(t),k=withSpanSync(`md.parseWithFallback`,{attributes:{"body.bytes":O.length,"doc.name":e.guid}},()=>mdManager.parseWithFallback(O,buildParseOpts(w))),j=schema.nodeFromJSON(k);D!==t&&applyFastDiff(E,D,t),updateYFragment(e,S,j,{mapping:new Map,isOMark:new Map})})}function replaceRawBody(e,t,S){let w=e.getXmlFragment(`default`),E=e.getText(`source`),{body:D}=stripFrontmatter(t),O=mdManager.parseWithFallback(D,buildParseOpts(S)),k=schema.nodeFromJSON(O),j=E.toString();j!==t&&(E.delete(0,j.length),E.insert(0,t)),updateYFragment(e,w,k,{mapping:new Map,isOMark:new Map})}function deriveFragmentFromYtext(e,t){let S=e.getXmlFragment(`default`),{body:w}=stripFrontmatter(e.getText(`source`).toString()),E=mdManager.parseWithFallback(w,buildParseOpts(t));updateYFragment(e,S,schema.nodeFromJSON(E),{mapping:new Map,isOMark:new Map})}const DEBOUNCE_MS=100,MAX_DISK_ACK_SVS=1e3;function isSystemDoc(e){return e===SYSTEM_DOC_NAME}const CONFIG_DOC_NAME_SET=new Set(CONFIG_DOC_NAMES);function isConfigDoc(e){return CONFIG_DOC_NAME_SET.has(e)}var CC1Broadcaster=class{hocuspocus;seqs=new Map;timers=new Map;log=getLogger(`cc1`);warnedMissing=!1;latestDiskAckSVs=new Map;constructor(e){this.hocuspocus=e}signal(e){let t=this.timers.get(e);t!==void 0&&clearTimeout(t),this.timers.set(e,setTimeout(()=>{this.timers.delete(e),this.broadcast(e)},DEBOUNCE_MS))}broadcast(e){try{let t=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!t){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found — broadcasts will be dropped until it is materialized`),!0),incrementCC1BroadcastDrop();return}let S=(this.seqs.get(e)??0)+1;this.seqs.set(e,S);let w=CC1DerivedViewPayloadSchema.parse({v:1,ch:e,seq:S});t.broadcastStateless(JSON.stringify(w)),incrementCC1Broadcast(),setCC1LastSeq(e,S),setCC1SubscriberCount(t.getConnectionsCount())}catch(t){this.log.error({err:t,channel:e},`[cc1] broadcast failed`)}}emitServerInfo(e,t){try{let S=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!S){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitServerInfo — dropped`),!0),incrementCC1BroadcastDrop();return}let w=CC1ServerInfoPayloadSchema.parse({v:1,ch:CC1_CHANNEL_SERVER_INFO,seq:0,serverInstanceId:e,...t===void 0?{}:{currentBranch:t}});S.broadcastStateless(JSON.stringify(w)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_SERVER_INFO,0)}catch(e){this.log.error({err:e},`[cc1] emitServerInfo failed`)}}emitBranchSwitched(e){try{let t=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!t){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitBranchSwitched — dropped`),!0),incrementCC1BroadcastDrop();return}let S=(this.seqs.get(`branch-switched`)??0)+1;this.seqs.set(CC1_CHANNEL_BRANCH_SWITCHED,S);let w=CC1BranchSwitchedPayloadSchema.parse({v:1,ch:CC1_CHANNEL_BRANCH_SWITCHED,seq:S,branch:e});t.broadcastStateless(JSON.stringify(w)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_BRANCH_SWITCHED,S)}catch(e){this.log.error({err:e},`[cc1] emitBranchSwitched failed`)}}emitDiskAck(e,t){if(this.latestDiskAckSVs.delete(e),this.latestDiskAckSVs.set(e,t),this.latestDiskAckSVs.size>MAX_DISK_ACK_SVS){let e=this.latestDiskAckSVs.keys().next().value;e!==void 0&&this.latestDiskAckSVs.delete(e)}try{let S=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!S){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitDiskAck — dropped`),!0),incrementCC1BroadcastDrop();return}let w=(this.seqs.get(`disk-ack`)??0)+1;this.seqs.set(CC1_CHANNEL_DISK_ACK,w);let E=CC1DiskAckPayloadSchema.parse({v:1,ch:CC1_CHANNEL_DISK_ACK,seq:w,docName:e,sv:Buffer.from(t).toString(`base64`)});S.broadcastStateless(JSON.stringify(E)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_DISK_ACK,w)}catch(t){this.log.error({err:t,docName:e},`[cc1] emitDiskAck failed`)}}getLatestDiskAckSVsAsBase64(){let e={};for(let[t,S]of this.latestDiskAckSVs)e[t]=Buffer.from(S).toString(`base64`);return e}emitConfigValidationRejected(e,t){try{let S=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!S){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitConfigValidationRejected — dropped`),!0),incrementCC1BroadcastDrop();return}let w=(this.seqs.get(`config-validation-rejected`)??0)+1;this.seqs.set(CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,w);let E=CC1ConfigValidationRejectedPayloadSchema.parse({v:1,ch:CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,seq:w,docName:e,error:t});S.broadcastStateless(JSON.stringify(E)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,w)}catch(t){this.log.error({err:t,docName:e},`[cc1] emitConfigValidationRejected failed`)}}emitConfigIgnoreNestedError(e,t){try{let S=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!S){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitConfigIgnoreNestedError — dropped`),!0),incrementCC1BroadcastDrop();return}let w=(this.seqs.get(`config-ignore-nested-error`)??0)+1;this.seqs.set(CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,w);let E=CC1ConfigIgnoreNestedErrorPayloadSchema.parse({v:1,ch:CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,seq:w,path:e,error:t});S.broadcastStateless(JSON.stringify(E)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,w)}catch(t){this.log.error({err:t,path:e},`[cc1] emitConfigIgnoreNestedError failed`)}}get subscriberCount(){let e=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);return e?e.getConnectionsCount():0}destroy(){for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}};let _editSurfaceCounter=null;function editSurfaceCounter(){return _editSurfaceCounter||=getMeter().createCounter(`ok.frontmatter.edit_surface_total`,{description:`Count of frontmatter edits by surface. Bounded label: source ∈ {source-mode, mcp-write, file-watcher}.`}),_editSurfaceCounter}function recordFrontmatterEditSurface(e){editSurfaceCounter().add(1,{source:e})}const log$8=getLogger(`agent-sessions`),AGENT_WRITE_ORIGIN={source:`local`,skipStoreHooks:!1,context:{origin:`agent-write`,paired:!0}};function applyAgentMarkdownWrite(e,t,S,w){withSpanSync(`agent.applyAgentMarkdownWrite`,{attributes:{"doc.name":e.name,"agent.write_position":S,"agent.markdown.bytes":t.length}},()=>applyAgentMarkdownWriteInner(e,t,S,w))}function applyAgentMarkdownWriteInner(e,t,S,w){try{let{frontmatter:E,body:D}=stripFrontmatter(e.getText(`source`).toString()),{frontmatter:O,body:k}=stripFrontmatter(t),j,F;switch(S){case`replace`:j=O||E,F=k;break;case`prepend`:j=E,F=D.length>0?`${k}\n\n${D}`:k;break;case`append`:j=E,F=D.length>0?`${D}\n\n${k}`:k;break}j!==E&&recordFrontmatterEditSurface(`mcp-write`),composeAndWriteRawBody(e,prependFrontmatter(j,F),`agent`,w)}catch(w){throw log$8.error({err:w,docName:e.name,position:S,markdownLen:t.length},`[applyAgentMarkdownWrite] failed for '${e.name}'`),w}}function applyAgentUndo(e,t,S){return withSpanSync(`agent.applyAgentUndo`,{attributes:{"doc.name":e.dc.document.name,"agent.undo_scope":t}},()=>{let w=applyAgentUndoInner(e,t,S);return setActiveSpanAttributes({"agent.undo_effective":w}),w})}function applyAgentUndoInner(e,t,S){let{dc:w,um:E,undoOrigin:D}=e,O=w.document,k=!1;return O.transact(()=>{if(t===`last`){if(E.undoStack.length===0)return;E.undo(),k=!0}else for(;E.undoStack.length>0;)E.undo(),k=!0;deriveFragmentFromYtext(O,S)},D),k}function createSessionOrigin(e,t,S,w,E){let D={origin:`agent-write`,paired:!0,session_id:e};t!==void 0&&(D.agent_type=t),S!==void 0&&(D.principal=S),w!==void 0&&(D.display_name=w),E!==void 0&&(D.color_seed=E),Object.freeze(D);let O={source:`local`,skipStoreHooks:!1,context:D};return Object.freeze(O),O}function createUndoOrigin(e,t){let S={origin:`agent-undo`,paired:!0,session_id:e};t!==void 0&&(S.agent_type=t),Object.freeze(S);let w={source:`local`,skipStoreHooks:!1,context:S};return Object.freeze(w),w}const MAX_AGENT_SESSIONS=256;var AgentSessionCapacityError=class extends Error{limit;constructor(e){super(`Maximum agent session count reached (${e})`),this.name=`AgentSessionCapacityError`,this.limit=e}},AgentSessionManager=class{sessions=new Map;pendingSessions=new Map;hocuspocus;maxSessions;constructor(e,t={}){this.hocuspocus=e,this.maxSessions=t.maxSessions??256}sessionKey(e,t){return`${e}\0${t}`}*sessionsForConnection(e){let t=`\0${e}`;for(let[e,S]of this.sessions)e.endsWith(t)&&(yield S)}getLiveSession(e,t){return this.sessions.get(this.sessionKey(e,t))}async getSession(e,t=`claude-1`,S){if(isSystemDoc(e)||isConfigDoc(e))throw Error(`Cannot create agent session for reserved doc: ${e}`);let w=this.sessionKey(e,t),E=this.sessions.get(w);if(E)return E;let D=this.pendingSessions.get(w);if(D)return D;if(this.sessions.size+this.pendingSessions.size>=this.maxSessions)throw new AgentSessionCapacityError(this.maxSessions);let O=this._createSession(e,t,S);this.pendingSessions.set(w,O);try{let e=await O;return this.sessions.set(w,e),e}finally{this.pendingSessions.delete(w)}}async _createSession(e,t,S){let w=S?.clientName,E=t.startsWith(`agent-`)?t.slice(6):t,D=createSessionOrigin(E,w,S?.principalId,S?.displayName,S?.colorSeed),O=createUndoOrigin(E,w),k={session_id:E,...w===void 0?{}:{agent_type:w},...S?.clientName===void 0?{}:{client_name:S.clientName},...S?.principalId===void 0?{}:{principalId:S.principalId}},j=await this.hocuspocus.openDirectConnection(e,k),F=new UndoManager([j.document.getText(`source`),j.document.getMap(`agent-flash`)],{trackedOrigins:new Set([D]),captureTimeout:500,captureTransaction:e=>e.origin!==O,ignoreRemoteMapChanges:!0}),L=({stackItem:e})=>{e.meta.set(`time`,Date.now())};return F.on(`stack-item-added`,L),F.on(`stack-item-updated`,L),log$8.info({docName:e,agentId:t},`[agent-session] Created session for: ${e} / ${t}`),{dc:j,origin:D,undoOrigin:O,um:F,agentId:t,docName:e}}hasSession(e,t=`claude-1`){return this.sessions.has(this.sessionKey(e,t))}async cleanupSession(e,t,S){try{try{t.um.destroy()}catch(e){log$8.error({err:e,...S},`[agent-session] um.destroy() failed`)}try{await t.dc.disconnect()}catch(e){log$8.error({err:e,...S},`[agent-session] dc.disconnect() failed`)}}finally{this.sessions.delete(e)}}async closeSession(e,t=`claude-1`){let S=this.sessionKey(e,t),w=this.sessions.get(S);w&&(await this.cleanupSession(S,w,{docName:e,agentId:t}),log$8.info({docName:e,agentId:t},`[agent-session] Closed session for: ${e} / ${t}`))}async closeAllForAgent(e){let t=`\0${e}`,S=[...this.pendingSessions.keys()].filter(e=>e.endsWith(t));S.length>0&&await Promise.allSettled(S.map(e=>this.pendingSessions.get(e)));let w=[...this.sessions.keys()].filter(e=>e.endsWith(t));for(let t of w){let S=this.sessions.get(t);S&&await this.cleanupSession(t,S,{agentId:e,key:t})}}async closeAllForDoc(e){let t=`${e}\0`,S=[...this.sessions.keys()].filter(e=>e.startsWith(t));for(let t of S){let S=this.sessions.get(t);S&&await this.cleanupSession(t,S,{docName:e,key:t})}}async closeAll(e){if(e){await this.closeAllForDoc(e);return}let t=[...this.sessions.keys()];for(let e of t){let t=this.sessions.get(e);t&&await this.cleanupSession(e,t,{key:e})}}};const RING_BUFFER_LIMIT=50;let _effectCounter=0;const EFFECT_CAPTURE_ORIGIN=Object.freeze({source:`local`,skipStoreHooks:!0,context:Object.freeze({origin:`effect-capture`,paired:!1})});function captureEffect(e,t,S,w){let E=e.doc;if(!E)return;let D=++_effectCounter,O=E.getMap(`agent-effects`),k=F=>{e.unobserve(k),E.off(`destroy`,j);let L=`${t}:${D}`,B={sessionId:t,timestamp:Date.now(),delta:F.delta,agent_type:w??`agent`,color_seed:S??t};try{E.transact(()=>{if(O.set(L,B),O.size>RING_BUFFER_LIMIT){let e=[...O.entries()].sort((e,t)=>e[1].timestamp-t[1].timestamp);for(let[t]of e.slice(0,O.size-RING_BUFFER_LIMIT))O.delete(t)}},EFFECT_CAPTURE_ORIGIN)}catch(e){let S=e instanceof Error?e.message:String(e);if(console.warn(JSON.stringify({event:`effect-diff-capture-failed`,sessionId:t,reason:S})),incrementEffectDiffCaptureFailures(),process.env.NODE_ENV!==`production`)throw e}},j=()=>{e.unobserve(k)};e.observe(k),E.once(`destroy`,j)}function collectItemsInDeleteSet(e,t,S){iterateDeletedStructs(e,t,e=>{e instanceof Item&&S.add(e)})}function*walkYTextItems(e){let t=e._start;for(;t!==null;)yield t,t=t.right}function synthesizeStackItemDiff(e,t){let S=[],w=[],E=t.doc,D=new Set,O=new Set;E&&E.transact(t=>{collectItemsInDeleteSet(t,e.insertions,D),collectItemsInDeleteSet(t,e.deletions,O)});let k=``,j=``,F=0,L=0;for(let e of walkYTextItems(t)){if(!(e.content instanceof ContentString))continue;let t=e.content.str,E=t.length,B=D.has(e),H=O.has(e);e.deleted?H&&(w.push({position:F,content:t,length:E}),k+=t,F+=E):(j+=t,B?S.push({position:L,content:t,length:E}):(k+=t,F+=E),L+=E)}return{insertions:S,deletions:w,before:k,after:j}}function synthesizeStackItemDiffText(e,t,S){let{before:w,after:E}=synthesizeStackItemDiff(e,t);return w===E?``:createPatch(S,w,E,void 0,void 0,{context:3})}function getBurstTs(e){let t=e.meta.get(`time`);return typeof t==`number`?t:Date.now()}function countStackItemChanges(e,t){let S=t.doc,w=new Set,E=new Set;S&&S.transact(t=>{collectItemsInDeleteSet(t,e.insertions,w),collectItemsInDeleteSet(t,e.deletions,E)});let D=0,O=0;for(let e of walkYTextItems(t)){if(!(e.content instanceof ContentString))continue;let t=e.content.str.length;!e.deleted&&w.has(e)&&(D+=t),E.has(e)&&(O+=t)}return{additions:D,deletions:O}}function listAgentActivity(e,t){let S=[],w=null,E=!1;for(let D of e.sessionsForConnection(t)){if(E=!0,!w){let e=D.origin.context,S=typeof e?.agent_type==`string`?e.agent_type:void 0,E=typeof e?.color_seed==`string`?e.color_seed:t,O=iconFromClientName(S),k=AGENT_ICON_COLORS[O]??colorFromSeed(E);w={displayName:e?.display_name||(typeof e?.agent_type==`string`?e.agent_type:void 0)||t,color:k,icon:O,connectionId:t}}let e=D.docName,O=D.um,k=D.dc.document.getText(`source`),j=[];for(let e=0;e<O.undoStack.length;e++){let t=O.undoStack[e],S=getBurstTs(t),{additions:w,deletions:E}=countStackItemChanges(t,k);j.push({stackIndex:e,ts:S,additions:w,deletions:E})}if(j.length===0)continue;j.sort((e,t)=>t.stackIndex-e.stackIndex);let F=j.reduce((e,t)=>e+t.additions,0),L=j.reduce((e,t)=>e+t.deletions,0),B=Math.max(...j.map(e=>e.ts));S.push({docName:e,additionsTotal:F,deletionsTotal:L,lastTs:B,bursts:j})}return E?(S.sort((e,t)=>t.lastTs-e.lastTs),{sessionAlive:!0,agent:w,files:S}):{sessionAlive:!1,agent:null,files:[]}}const ELLIPSIS=`…`,LINE_TERMINATOR_RE=RegExp(`[\\r\\n\\v\\f\\u0085\\u2028\\u2029]`,`g`);function normalizeSummary(e){if(e===void 0)return{kind:`absent`};if(typeof e!=`string`)return{kind:`invalid`};if(e.length===0||e.trim().length===0)return{kind:`absent`};let t=e.replace(LINE_TERMINATOR_RE,` `);return t.length<=80?{kind:`value`,value:t}:{kind:`value`,value:t.slice(0,79)+ELLIPSIS,truncatedFrom:e.length}}function isAllowedApiOrigin(e){if(e===`null`)return!0;try{let{hostname:t}=new URL(e);return t===`localhost`||t===`::1`||t===`[::1]`||/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(t)}catch{return!1}}const counters=new WeakMap;let globalCounter=0;function getCounters(e){let t=counters.get(e);return t||(t={lastUserTxGen:0,settledGen:0,lastUserTxAtMs:null},counters.set(e,t)),t}function isObserverSelfOrigin(e){if(!e||typeof e!=`object`)return!1;let t=e.context;return t!=null&&t.origin===`observer-sync`}function attachQuiescenceTracker(e){let t=t=>{if(isObserverSelfOrigin(t.origin))return;let S=getCounters(e);S.lastUserTxGen=++globalCounter,S.lastUserTxAtMs=Date.now()},S=()=>{getCounters(e).settledGen=++globalCounter};return e.on(`afterTransaction`,t),e.on(`afterAllTransactions`,S),()=>{e.off(`afterTransaction`,t),e.off(`afterAllTransactions`,S)}}const overrides=new WeakMap;function isDocQuiescent(e){let t=overrides.get(e);if(t!==void 0)return t;let S=counters.get(e);return S?S.settledGen>S.lastUserTxGen:!0}function getMsSinceLastUserTx(e,t=Date.now()){let S=counters.get(e);return!S||S.lastUserTxAtMs===null?null:Math.max(0,t-S.lastUserTxAtMs)}const DEFAULT_DEBOUNCE_S=60,lastEmitMs=new Map,MAX_VIOLATION_RATE_TUPLES=1024,lastToleranceEmitMs=new Map,lastPathBEmitMs=new Map;function toleranceRateKey(e,t){return`${e}::${t}`}function readDebounceMs(){let e=process.env.OK_BRIDGE_VIOLATION_DEBOUNCE_S;if(e===void 0)return DEFAULT_DEBOUNCE_S*1e3;let t=Number.parseInt(e,10);return!Number.isFinite(t)||t<=0?DEFAULT_DEBOUNCE_S*1e3:t*1e3}function rateKey(e,t){return`${e}::${t??`__nodoc__`}`}function shouldEmitBridgeInvariantViolation(e,t,S=Date.now()){let w=rateKey(e,t),E=lastEmitMs.get(w),D=readDebounceMs();if(E!==void 0&&S-E<D)return!1;if(lastEmitMs.size>=MAX_VIOLATION_RATE_TUPLES)for(let[e,t]of lastEmitMs)S-t>=D&&lastEmitMs.delete(e);return lastEmitMs.set(w,S),!0}function shouldEmitBridgeToleranceApplied(e,t,S=Date.now()){let w=toleranceRateKey(e,t),E=lastToleranceEmitMs.get(w),D=readDebounceMs();return E!==void 0&&S-E<D?!1:(lastToleranceEmitMs.set(w,S),!0)}function shouldEmitObserverAPathBFired(e,t=Date.now()){let S=e??`__nodoc__`,w=lastPathBEmitMs.get(S),E=readDebounceMs();if(w!==void 0&&t-w<E)return!1;if(lastPathBEmitMs.size>=MAX_VIOLATION_RATE_TUPLES)for(let[e,S]of lastPathBEmitMs)t-S>=E&&lastPathBEmitMs.delete(e);return lastPathBEmitMs.set(S,t),!0}function emitObserverAPathBFired(e,t){let S=shouldEmitObserverAPathBFired(e,t);return S||incrementObserverAPathBFiresSuppressed(),S}function shouldThrowOnBridgeInvariantViolation(e=process.env){return e.NODE_ENV===`test`||e.OK_BRIDGE_THROW_ON_VIOLATION===`1`}function assertBridgeInvariant(e,t,S){let w=normalizeBridge(e),E=normalizeBridge(t);if(w===E){if(e!==t){let w=detectAppliedToleranceClasses(e,t);for(let e of w)shouldEmitBridgeToleranceApplied(S.site,e,S.nowMs)&&(incrementBridgeToleranceApplied(e),console.warn(JSON.stringify({event:`bridge-tolerance-applied`,site:S.site,class:e})))}return!0}let D={site:S.site,origin:S.origin,docName:S.docName,ytextSnapshot:e,fragmentMdSnapshot:t,unifiedDiff:` ytext: ${w.slice(0,300)}\n frag: ${E.slice(0,300)}`,stack:Error().stack};if(shouldThrowOnBridgeInvariantViolation()&&!S.suppressDevThrow)throw new BridgeInvariantViolationError(D);if(!shouldEmitBridgeInvariantViolation(S.site,S.docName,S.nowMs))return incrementBridgeInvariantViolationsSuppressed(),!1;incrementBridgeInvariantViolations();let O=process.env.OK_TELEMETRY_VERBOSE===`1`;return console.warn(JSON.stringify(toBridgeInvariantLog(D,{verbose:O}))),!1}const CONFIG_VALIDATION_REVERT_ORIGIN={source:`local`,skipStoreHooks:!0,context:{origin:`config-validation-revert`}},CONFIG_FILE_WATCHER_ORIGIN={source:`local`,skipStoreHooks:!0,context:{origin:`config-file-watcher`}};function normalizeFsPath(e){let t=e.split(sep).filter(Boolean);return t.length<=2?e:`...${sep}${t.slice(-2).join(sep)}`}function classifyFsPath(e){return e.includes(`${sep}.git${sep}ok${sep}`)||e.includes(`shadow-repo`)?`shadow-repo`:e.includes(`${sep}.git${sep}`)?`git`:basename(e).endsWith(`.lock`)||basename(e)===`lock`?`lock`:basename(e)===`principal.json`?`principal`:e.includes(`${sep}.ok${sep}`)&&(basename(e)===`conflicts.json`||e.includes(`${sep}conflicts${sep}`))?`conflict`:e.includes(`${sep}.ok${sep}`)?`ok-internal`:e.endsWith(`.md`)||e.endsWith(`.mdx`)?`content-md`:`other`}function buildAttrs(e,t,S){let w={"fs.operation":e,"fs.path":normalizeFsPath(t),"fs.path.role":classifyFsPath(t)};return S&&Object.assign(w,S),w}function byteLength(e){return typeof e==`string`?Buffer.byteLength(e,`utf-8`):e instanceof Uint8Array?e.byteLength:e.byteLength??0}async function tracedWriteFile(e,t,S){return withSpan(`fs.writeFile`,{attributes:buildAttrs(`writeFile`,e,{"fs.bytes":byteLength(t)})},async()=>{await writeFile(e,t,S)})}async function tracedRename(e,t){return withSpan(`fs.rename`,{attributes:buildAttrs(`rename`,t,{"fs.source_path":normalizeFsPath(e)})},async()=>{await rename(e,t)})}async function tracedMkdir(e,t){return withSpan(`fs.mkdir`,{attributes:buildAttrs(`mkdir`,e)},async()=>mkdir(e,t))}function tracedWriteFileSync(e,t,S){withSpanSync(`fs.writeFileSync`,{attributes:buildAttrs(`writeFileSync`,e,{"fs.bytes":byteLength(t)})},()=>{writeFileSync(e,t,S)})}function tracedAppendFileSync(e,t,S){withSpanSync(`fs.appendFileSync`,{attributes:buildAttrs(`appendFileSync`,e,{"fs.bytes":byteLength(t)})},()=>{appendFileSync(e,t,S)})}function tracedMkdirSync(e,t){return withSpanSync(`fs.mkdirSync`,{attributes:buildAttrs(`mkdirSync`,e)},()=>mkdirSync(e,t))}function tracedRenameSync(e,t){withSpanSync(`fs.renameSync`,{attributes:buildAttrs(`renameSync`,t,{"fs.source_path":normalizeFsPath(e)})},()=>{renameSync(e,t)})}function tracedCpSync(e,t,S){withSpanSync(`fs.cpSync`,{attributes:buildAttrs(`cpSync`,t,{"fs.source_path":normalizeFsPath(e)})},()=>{cpSync(e,t,S)})}function tracedUnlinkSync(e){withSpanSync(`fs.unlinkSync`,{attributes:buildAttrs(`unlinkSync`,e)},()=>{unlinkSync(e)})}function tracedLinkSync(e,t){withSpanSync(`fs.linkSync`,{attributes:buildAttrs(`linkSync`,t,{"fs.source_path":normalizeFsPath(e)})},()=>{linkSync(e,t)})}function tracedRmSync(e,t){withSpanSync(`fs.rmSync`,{attributes:buildAttrs(`rmSync`,e)},()=>{rmSync(e,t)})}function tracedRmdirSync(e){withSpanSync(`fs.rmdirSync`,{attributes:buildAttrs(`rmdirSync`,e)},()=>{rmdirSync(e)})}function configScopeAttr(e){if(e===`__config__/project`)return`project`;if(e===`__local__/project`)return`project-local`;if(e===`__user__/config.yml`)return`user`;if(e===`__config__/okignore`)return`project`}let _okignoreRejectionCounter=null;function okignoreRejectionCounter(){return _okignoreRejectionCounter||=getMeter().createCounter(`ok.config.ignore.rejection_total`,{description:`Count of okignore L3 rejections by error code.`}),_okignoreRejectionCounter}function emitSchemaInvalidIssueEvents(e){if(isKnownConfigError(e)&&e.code===`SCHEMA_INVALID`)for(let t of e.issues)addConfigSpanEvent(`config.validation.issue`,{"issue.path":t.path.map(e=>String(e)).join(`.`),"issue.message":t.message})}function configDocAbsPath(e,t){if(e===`__config__/project`)return resolveConfigPath(`project`,t.projectDir,t.homedirOverride);if(e===`__local__/project`)return resolveConfigPath(`project-local`,t.projectDir,t.homedirOverride);if(e===`__user__/config.yml`)return resolveConfigPath(`user`,t.projectDir,t.homedirOverride);if(e===`__config__/okignore`)return resolve(t.contentDir??t.projectDir,`.okignore`);throw Error(`configDocAbsPath: not a config doc name: ${e}`)}let cachedDefaultsYaml=null;function serializedDefaults(){return cachedDefaultsYaml===null&&(cachedDefaultsYaml=(0,import_dist$1.stringify)(ConfigSchema$1.parse({}))),cachedDefaultsYaml}function validateOkignore(e){if(e.length===0)return{ok:!0};let t=e.split(`
|
|
1136
|
+
`+S)}function se(e,t,S,w,E,D){if(e.listenerCount(`wsClientError`)){let w=Error(E);Error.captureStackTrace(w,se),e.emit(`wsClientError`,w,S,t)}else oe(S,w,E,D)}}));require_stream(),require_receiver(),require_sender(),require_websocket();var import_websocket_server=__toESM(require_websocket_server(),1),require_ignore=__commonJSMin$1(((e,t)=>{function S(e){return Array.isArray(e)?e:[e]}let w=``,E=` `,D=`\\`,O=/^\s+$/,k=/(?:[^\\]|^)\\$/,j=/^\\!/,F=/^\\#/,L=/\r?\n/g,B=/^\.*\/|^\.+$/,H=`/`,q=`node-ignore`;typeof Symbol<`u`&&(q=Symbol.for(`node-ignore`));let J=q,Y=(e,t,S)=>Object.defineProperty(e,t,{value:S}),ee=/([0-z])-([0-z])/g,te=()=>!1,ne=e=>e.replace(ee,(e,t,S)=>t.charCodeAt(0)<=S.charCodeAt(0)?e:``),ae=e=>{let{length:t}=e;return e.slice(0,t-t%2)},oe=[[/^\uFEFF/,()=>``],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,S)=>t+(S.indexOf(`\\`)===0?` `:``)],[/(\\+?)\s/g,(e,t)=>{let{length:S}=t;return t.slice(0,S-S%2)+` `}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>`[^/]`],[/^\//,()=>`^`],[/\//g,()=>`\\/`],[/^\^*\\\*\\\*\\\//,()=>`^(?:.*\\/)?`],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?`^`:`(?:^|\\/)`}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,S)=>t+6<S.length?`(?:\\/[^\\/]+)*`:`\\/.+`],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,S)=>t+S.replace(/\\\*/g,`[^\\/]*`)],[/\\\\\\(?=[$.|*+(){^])/g,()=>`\\`],[/\\\\/g,()=>`\\`],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,S,w,E)=>t===`\\`?`\\[${S}${ae(w)}${E}`:E===`]`&&w.length%2==0?`[${ne(S)}${w}]`:`[]`],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(e,t)=>`${t?`${t}[^/]+`:`[^/]*`}(?=$|\\/$)`]],se=Object.create(null),ce=(e,t)=>{let S=se[e];return S||(S=oe.reduce((t,[S,w])=>t.replace(S,w.bind(e)),e),se[e]=S),t?new RegExp(S,`i`):new RegExp(S)},ue=e=>typeof e==`string`,de=e=>e&&ue(e)&&!O.test(e)&&!k.test(e)&&e.indexOf(`#`)!==0,fe=e=>e.split(L);var me=class{constructor(e,t,S,w){this.origin=e,this.pattern=t,this.negative=S,this.regex=w}};let ge=(e,t)=>{let S=e,w=!1;e.indexOf(`!`)===0&&(w=!0,e=e.substr(1)),e=e.replace(j,`!`).replace(F,`#`);let E=ce(e,t);return new me(S,e,w,E)},_e=(e,t)=>{throw new t(e)},ve=(e,t,S)=>ue(e)?e?ve.isNotRelative(e)?S(`path should be a \`path.relative()\`d string, but got "${t}"`,RangeError):!0:S(`path must not be empty`,TypeError):S(`path must be a string, but got \`${t}\``,TypeError),ye=e=>B.test(e);ve.isNotRelative=ye,ve.convert=e=>e;var Ce=class{constructor({ignorecase:e=!0,ignoreCase:t=e,allowRelativePaths:S=!1}={}){Y(this,J,!0),this._rules=[],this._ignoreCase=t,this._allowRelativePaths=S,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(e){if(e&&e[J]){this._rules=this._rules.concat(e._rules),this._added=!0;return}if(de(e)){let t=ge(e,this._ignoreCase);this._added=!0,this._rules.push(t)}}add(e){return this._added=!1,S(ue(e)?fe(e):e).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(e){return this.add(e)}_testOne(e,t){let S=!1,w=!1;return this._rules.forEach(E=>{let{negative:D}=E;w===D&&S!==w||D&&!S&&!w&&!t||E.regex.test(e)&&(S=!D,w=D)}),{ignored:S,unignored:w}}_test(e,t,S,w){let E=e&&ve.convert(e);return ve(E,e,this._allowRelativePaths?te:_e),this._t(E,t,S,w)}_t(e,t,S,w){if(e in t)return t[e];if(w||=e.split(`/`),w.pop(),!w.length)return t[e]=this._testOne(e,S);let E=this._t(w.join(`/`)+`/`,t,S,w);return t[e]=E.ignored?E:this._testOne(e,S)}ignores(e){return this._test(e,this._ignoreCache,!1).ignored}createFilter(){return e=>!this.ignores(e)}filter(e){return S(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}};let we=e=>new Ce(e);if(we.isPathValid=e=>ve(e&&ve.convert(e),e,te),we.default=we,t.exports=we,typeof process<`u`&&(process.env&&process.env.IGNORE_TEST_WIN32||process.platform===`win32`)){ve.convert=e=>/^\\\\\?\\/.test(e)||/["<>|\u0000-\u001F]+/u.test(e)?e:e.replace(/\\/g,`/`);let e=/^[a-z]:\//i;ve.isNotRelative=t=>e.test(t)||ye(t)}}));init_esm$2();var import_pino=__toESM$1(require_pino(),1),import_pino_pretty=__toESM$1(require_pino_pretty(),1),import_src=require_src$14(),import_src$1=require_src$13(),import_src$2=require_src$4(),import_src$3=require_src$3(),import_src$4=require_src$2(),import_src$5=require_src$1(),import_src$6=require_src();init_esm$1();var import_lib=__toESM$1(require_lib(),1),import_yazl=__toESM$1(require_yazl(),1),import_shell_quote=__toESM$1(require_shell_quote(),1),import_ignore=__toESM$1(require_ignore(),1);const MAX_LEN=128;function sanitizeGitIdentity(e){return e.replace(/[<>\r\n]/g,``).trim().slice(0,MAX_LEN)}const AGENT_ID_RE=/^[a-zA-Z0-9_-]+$/,AGENT_ID_MAX_LEN=64;function validateAgentId(e){return typeof e!=`string`||e.length===0||e.length>64||!AGENT_ID_RE.test(e)?null:e}function toBroadcasterKey(e){return e.startsWith(`agent-`)?e:`agent-${e}`}function isPresenceEligibleAgentId(e){return!e.startsWith(`principal-`)}function resolveAgentType(e){if(!e)return`bot`;let t=e.toLowerCase();return t.includes(`claude`)?`claude`:t.includes(`cursor`)?`cursor`:t.includes(`codex`)?`codex`:t.includes(`cline`)?`cline`:t.includes(`windsurf`)?`windsurf`:`bot`}function parseAgentBodyFields(e){let t=validateAgentId(typeof e.agentId==`string`?e.agentId:null)??void 0;return{rawAgentId:t,writerId:t===void 0?void 0:toBroadcasterKey(t),displayName:typeof e.agentName==`string`?sanitizeGitIdentity(e.agentName):`Claude`,clientName:typeof e.clientName==`string`?sanitizeGitIdentity(e.clientName):void 0,clientVersion:typeof e.clientVersion==`string`?sanitizeGitIdentity(e.clientVersion):void 0,label:typeof e.label==`string`?sanitizeGitIdentity(e.label):void 0,colorSeed:typeof e.colorSeed==`string`&&e.colorSeed.length>0?e.colorSeed.slice(0,128):void 0}}function otelMixin(){let e=trace.getSpan(context.active());if(!e)return{};let t=e.spanContext();return{trace_id:t.traceId,span_id:t.spanId,trace_flags:t.traceFlags}}function shouldColorize(){return process.env.NO_COLOR&&process.env.NO_COLOR!==``?!1:process.stdout.isTTY??!1}var PinoLogger=class{name;transportConfigs=[];pinoInstance;options;constructor(e,t={}){this.name=e,this.options={name:this.name,level:process.env.LOG_LEVEL||(process.env.NODE_ENV===`test`?`silent`:`info`),serializers:{err:import_pino.default.stdSerializers.err,error:import_pino.default.stdSerializers.err},mixin:otelMixin,...t.options},t.transportConfigs&&(this.transportConfigs=t.transportConfigs),this.pinoInstance=this.buildInstance()}buildInstance(){if(this.transportConfigs.length>0)return(0,import_pino.default)(this.options,import_pino.default.transport({targets:this.transportConfigs}));try{let e=(0,import_pino_pretty.default)({colorize:shouldColorize(),translateTime:`HH:MM:ss`,ignore:`pid,hostname`});return(0,import_pino.default)(this.options,e)}catch(e){return console.warn(`[PinoLogger] pino-pretty failed, falling back to JSON:`,e),(0,import_pino.default)(this.options)}}recreateInstance(){typeof this.pinoInstance.flush==`function`&&this.pinoInstance.flush(),this.pinoInstance=this.buildInstance()}addTransport(e){this.transportConfigs.push(e),this.recreateInstance()}removeTransport(e){e>=0&&e<this.transportConfigs.length&&(this.transportConfigs.splice(e,1),this.recreateInstance())}getTransports(){return[...this.transportConfigs]}updateOptions(e){this.options={...this.options,...e},this.recreateInstance()}getPinoInstance(){return this.pinoInstance}error(e,t){this.pinoInstance.error(e,t)}warn(e,t){this.pinoInstance.warn(e,t)}info(e,t){this.pinoInstance.info(e,t)}debug(e,t){this.pinoInstance.debug(e,t)}},LoggerFactory=class{config={};loggers=new Map;configure(e){this.config=e,this.loggers.clear()}getLogger(e){let t=this.loggers.get(e);if(t)return t;let S;return S=this.config.loggerFactory?this.config.loggerFactory(e):this.config.defaultLogger?this.config.defaultLogger:new PinoLogger(e,this.config.pinoConfig),this.loggers.set(e,S),S}reset(){this.config={},this.loggers.clear()}};const loggerFactory=new LoggerFactory;function getLogger(e){return loggerFactory.getLogger(e)}function createTestLogger(e=`test`){return new PinoLogger(e,{options:{level:`silent`}})}function installTestLoggers(){loggerFactory.configure({pinoConfig:{options:{level:`silent`}}})}var AgentFocusBroadcaster=class{hocuspocus;log=getLogger(`agent-focus`);warnedMissing=!1;constructor(e){this.hocuspocus=e}setFocus(e,t){isPresenceEligibleAgentId(e)&&this.mutateAgentFocus(S=>({...S,[e]:t}))}clearFocus(e){isPresenceEligibleAgentId(e)&&this.mutateAgentFocus(t=>{if(!(e in t))return t;let{[e]:S,...w}=t;return w})}getFocusMap(){let e=this.resolveAwareness();return e?e.getLocalState()?.agentFocus??{}:{}}mutateAgentFocus(e){let t=this.resolveAwareness();if(t)try{let S=t.getLocalState()??{},w=e(S.agentFocus??{});t.setLocalState({...S,agentFocus:w})}catch(e){this.log.error({err:e},`[agent-focus] awareness mutation failed`)}}resolveAwareness(){let e=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);return e?(this.warnedMissing&&=(this.log.info({},`[agent-focus] __system__ document now available — resuming focus updates`),!1),getAwareness$1(e)):(this.warnedMissing||=(this.log.warn({},`[agent-focus] __system__ document not found — focus updates will be dropped until it is materialized`),!0),null)}};function getAwareness$1(e){return e?.awareness??null}const counters$1={reconcileCount:0,conflictCount:0,batchCount:0,upstreamImportCount:0,rescueBufferCount:0,branchSwitchCount:0,parkCount:0,gitAutoSaveFailureCount:0,gitWriterCommitFailureCount:0,cc1BroadcastCount:0,cc1BroadcastDropCount:0,cc1SubscriberCount:0,cc1LastSeq:{},serverObserverFiresA:0,serverObserverFiresB:0,serverObserverErrorsA:0,serverObserverErrorsB:0,persistenceDiskWrites:0,bridgeMergeContentLoss:0,bridgeMergeCheckpointCreated:0,bridgeInvariantViolations:0,bridgeInvariantViolationsSuppressed:0,persistenceSkipNonQuiescent:0,persistenceForceFlushDuringBurst:0,collabSocketEpipeCount:0,collabSocketEconnresetCount:0,collabMessageTooLargeCount:0,shadowMigrationLegacyRefsDeleted:0,effectDiffCaptureFailures:0,agentPresenceMutationErrors:0,agentWriteCalls:0,summariesProvided:0,summariesTruncated:0,agentPatchFindMismatches:0,bridgeToleranceApplied:{},observerAPathBFires:0,observerAPathBFiresSuppressed:0,persistenceReconciliationFailures:0,externalChangeHandlerErrors:0,persistenceSanityCheckSerializeFailures:0,deferredStoreFailures:0,authRenameRedirectCount:0,authDocDeletedCount:0,recentlyRemovedDocsEvictions:0,recentlyRemovedDocsSize:0,authRemovalGuardErrors:0,removalRedirectChainCycles:0};function incrementReconcile(){counters$1.reconcileCount++}function incrementConflict(){counters$1.conflictCount++}function incrementBatch(){counters$1.batchCount++}function incrementUpstreamImport(){counters$1.upstreamImportCount++}function incrementRescueBuffer(){counters$1.rescueBufferCount++}function incrementBranchSwitch(){counters$1.branchSwitchCount++}function incrementPark(){counters$1.parkCount++}function incrementGitAutoSaveFailure(){counters$1.gitAutoSaveFailureCount++}function incrementGitWriterCommitFailure(){counters$1.gitWriterCommitFailureCount++}function incrementCC1Broadcast(){counters$1.cc1BroadcastCount++}function incrementCC1BroadcastDrop(){counters$1.cc1BroadcastDropCount++}function setCC1SubscriberCount(e){counters$1.cc1SubscriberCount=e}function incrementServerObserverFire(e){e===`a`?counters$1.serverObserverFiresA++:counters$1.serverObserverFiresB++}function incrementPersistenceDiskWrite(){counters$1.persistenceDiskWrites++}function incrementServerObserverError(e){e===`a`?counters$1.serverObserverErrorsA++:counters$1.serverObserverErrorsB++}function incrementBridgeMergeContentLoss(){counters$1.bridgeMergeContentLoss++}function incrementAgentWriteCalls(){counters$1.agentWriteCalls++}function incrementSummariesProvided(){counters$1.summariesProvided++}function incrementSummariesTruncated(){counters$1.summariesTruncated++}function incrementBridgeMergeCheckpointCreated(){counters$1.bridgeMergeCheckpointCreated++}function incrementBridgeInvariantViolations(){counters$1.bridgeInvariantViolations++}function incrementBridgeInvariantViolationsSuppressed(){counters$1.bridgeInvariantViolationsSuppressed++}function incrementPersistenceSkipNonQuiescent(){counters$1.persistenceSkipNonQuiescent++}function incrementPersistenceForceFlushDuringBurst(){counters$1.persistenceForceFlushDuringBurst++}function incrementAgentPatchFindMismatches(){counters$1.agentPatchFindMismatches++}function incrementBridgeToleranceApplied(e){counters$1.bridgeToleranceApplied[e]=(counters$1.bridgeToleranceApplied[e]??0)+1}function incrementObserverAPathBFires(){counters$1.observerAPathBFires++}function incrementObserverAPathBFiresSuppressed(){counters$1.observerAPathBFiresSuppressed++}function incrementPersistenceReconciliationFailures(){counters$1.persistenceReconciliationFailures++}function incrementExternalChangeHandlerErrors(){counters$1.externalChangeHandlerErrors++}function incrementPersistenceSanityCheckSerializeFailures(){counters$1.persistenceSanityCheckSerializeFailures++}function incrementDeferredStoreFailures(){counters$1.deferredStoreFailures++}function incrementAuthRenameRedirect(){counters$1.authRenameRedirectCount++}function incrementAuthDocDeleted(){counters$1.authDocDeletedCount++}function incrementRecentlyRemovedDocsEviction(){counters$1.recentlyRemovedDocsEvictions++}function setRecentlyRemovedDocsSize(e){counters$1.recentlyRemovedDocsSize=e}function incrementAuthRemovalGuardError(){counters$1.authRemovalGuardErrors++}function incrementRemovalRedirectChainCycle(){counters$1.removalRedirectChainCycles++}function incrementCollabSocketFilteredError(e){e===`EPIPE`?counters$1.collabSocketEpipeCount++:counters$1.collabSocketEconnresetCount++}function incrementCollabMessageTooLarge(){counters$1.collabMessageTooLargeCount++}function incrementShadowMigrationLegacyRefsDeleted(e){counters$1.shadowMigrationLegacyRefsDeleted+=e}function incrementEffectDiffCaptureFailures(){counters$1.effectDiffCaptureFailures++}function incrementAgentPresenceMutationError(){counters$1.agentPresenceMutationErrors++}function handleCollabSocketError(e){return e.code===`EPIPE`||e.code===`ECONNRESET`?(incrementCollabSocketFilteredError(e.code),!0):!1}function setCC1LastSeq(e,t){counters$1.cc1LastSeq[e]=t}function getMetrics(){return{...counters$1,cc1LastSeq:{...counters$1.cc1LastSeq},bridgeToleranceApplied:{...counters$1.bridgeToleranceApplied}}}function resetMetrics(){counters$1.reconcileCount=0,counters$1.conflictCount=0,counters$1.batchCount=0,counters$1.upstreamImportCount=0,counters$1.rescueBufferCount=0,counters$1.branchSwitchCount=0,counters$1.parkCount=0,counters$1.gitAutoSaveFailureCount=0,counters$1.gitWriterCommitFailureCount=0,counters$1.cc1BroadcastCount=0,counters$1.cc1BroadcastDropCount=0,counters$1.cc1SubscriberCount=0,counters$1.cc1LastSeq={},counters$1.serverObserverFiresA=0,counters$1.serverObserverFiresB=0,counters$1.serverObserverErrorsA=0,counters$1.serverObserverErrorsB=0,counters$1.persistenceDiskWrites=0,counters$1.bridgeMergeContentLoss=0,counters$1.bridgeMergeCheckpointCreated=0,counters$1.bridgeInvariantViolations=0,counters$1.bridgeInvariantViolationsSuppressed=0,counters$1.persistenceSkipNonQuiescent=0,counters$1.persistenceForceFlushDuringBurst=0,counters$1.collabSocketEpipeCount=0,counters$1.collabSocketEconnresetCount=0,counters$1.collabMessageTooLargeCount=0,counters$1.shadowMigrationLegacyRefsDeleted=0,counters$1.effectDiffCaptureFailures=0,counters$1.agentPresenceMutationErrors=0,counters$1.agentWriteCalls=0,counters$1.summariesProvided=0,counters$1.summariesTruncated=0,counters$1.agentPatchFindMismatches=0,counters$1.bridgeToleranceApplied={},counters$1.observerAPathBFires=0,counters$1.observerAPathBFiresSuppressed=0,counters$1.persistenceReconciliationFailures=0,counters$1.externalChangeHandlerErrors=0,counters$1.persistenceSanityCheckSerializeFailures=0,counters$1.deferredStoreFailures=0,counters$1.authRenameRedirectCount=0,counters$1.authDocDeletedCount=0,counters$1.recentlyRemovedDocsEvictions=0,counters$1.recentlyRemovedDocsSize=0,counters$1.authRemovalGuardErrors=0,counters$1.removalRedirectChainCycles=0}const BROADCASTER_EVICTION_MS=5e3*4;var AgentPresenceBroadcaster=class{hocuspocus;log=getLogger(`agent-presence`);warnedMissing=!1;destroyed=!1;constructor(e){this.hocuspocus=e}setPresence(e,t){if(!isPresenceEligibleAgentId(e))return;let S=0;this.mutateAgentPresence(w=>{let E=Date.now(),D={};for(let[t,O]of Object.entries(w)){if(E-O.ts>=2e4&&t!==e){S++;continue}D[t]=O}return D[e]=t,D})&&(this.log.debug({agentId:e,action:`set`,currentDoc:t.currentDoc,ts:t.ts},`[agent-presence] set`),S>0&&this.log.info({evictedCount:S,thresholdMs:BROADCASTER_EVICTION_MS},`[agent-presence] evicted stale entries`))}clearPresence(e){if(!isPresenceEligibleAgentId(e))return;let t=!1;this.mutateAgentPresence(S=>{if(!S[e])return S;t=!0;let{[e]:w,...E}=S;return E})&&t&&this.log.info({agentId:e,action:`clear`,currentDoc:null,ts:Date.now()},`[agent-presence] clear`)}touchMode(e,t){if(!isPresenceEligibleAgentId(e))return;let S=[],w=!1,E=this.mutateAgentPresence(E=>{let D=E[e];if(!D)return E;w=!0;let O=Date.now();return S.push({currentDoc:D.currentDoc,ts:O}),{...E,[e]:{...D,mode:t,ts:O}}}),D=S[0];E&&D?this.log.debug({agentId:e,action:`touchMode`,currentDoc:D.currentDoc,ts:D.ts,mode:t},`[agent-presence] touchMode`):w||this.log.debug({agentId:e,action:`touchMode`,mode:t,reason:`entry-missing`},`[agent-presence] touchMode skipped — no entry for agentId`)}bumpPresenceTs(e){if(!isPresenceEligibleAgentId(e))return;let t=null;this.mutateAgentPresence(S=>{let w=S[e];if(!w)return S;let E=Date.now();return t=E,{...S,[e]:{...w,ts:E}}}),t!==null&&this.log.debug({agentId:e,action:`bumpTs`,ts:t},`[agent-presence] bumpTs`)}getPresenceMap(){let e=this.resolveAwareness();return e?e.getLocalState()?.agentPresence??{}:{}}destroy(){this.destroyed=!0}mutateAgentPresence(e){if(this.destroyed)return!1;let t=this.resolveAwareness();if(!t)return!1;try{let S=t.getLocalState()??{},w=e(S.agentPresence??{});return t.setLocalState({...S,agentPresence:w}),!0}catch(e){return incrementAgentPresenceMutationError(),this.log.error({err:e},`[agent-presence] awareness mutation failed`),!1}}resolveAwareness(){let e=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);return e?(this.warnedMissing&&=(this.log.info({},`[agent-presence] __system__ document now available — resuming presence updates`),!1),getAwareness(e)):(this.warnedMissing||=(this.log.warn({},`[agent-presence] __system__ document not found — presence updates will be dropped until it is materialized`),!0),null)}};function getAwareness(e){return e?.awareness??null}const mdManager=new MarkdownManager({extensions:sharedExtensions}),schema=getSchema(sharedExtensions),TRACER_NAME=`open-knowledge-server`;let tracerProvider=null,meterProvider=null;function noopResult(){return{tracer:trace.getTracer(TRACER_NAME),meter:metrics$1.getMeter(TRACER_NAME)}}function initTelemetry(){if(process.env.OTEL_SDK_DISABLED!==`false`||tracerProvider)return noopResult();try{let e=(0,import_src$4.resourceFromAttributes)({[ATTR_SERVICE_NAME]:process.env.OTEL_SERVICE_NAME||`open-knowledge-server`,[ATTR_SERVICE_VERSION]:process.env.OTEL_SERVICE_VERSION||`0.2.0`}),t=new import_src.AsyncLocalStorageContextManager;context.setGlobalContextManager(t);let S=new import_src$6.BasicTracerProvider({resource:e,spanProcessors:[new import_src$6.BatchSpanProcessor(new import_src$3.OTLPTraceExporter)]});trace.setGlobalTracerProvider(S),propagation.setGlobalPropagator(new import_src$1.W3CTraceContextPropagator);let w=new import_src$5.MeterProvider({resource:e,readers:[new import_src$5.PeriodicExportingMetricReader({exporter:new import_src$2.OTLPMetricExporter})]});metrics$1.setGlobalMeterProvider(w),tracerProvider=S,meterProvider=w,getLogger(`telemetry`).info({otlp_endpoint:process.env.OTEL_EXPORTER_OTLP_ENDPOINT||`http://localhost:4318`,service_name:e.attributes[ATTR_SERVICE_NAME]},`OpenTelemetry initialized — traces + metrics exporting via OTLP/HTTP`)}catch(e){getLogger(`telemetry`).error({err:e},`failed to initialize OpenTelemetry — falling back to no-op`),tracerProvider=null,meterProvider=null}return noopResult()}const SHUTDOWN_TIMEOUT_MS=5e3;async function shutdownTelemetry(){if(!tracerProvider&&!meterProvider)return;let e=getLogger(`telemetry`),t=Promise.all([tracerProvider?.shutdown().catch(t=>{e.warn({err:t},`tracer provider shutdown failed`)}),meterProvider?.shutdown().catch(t=>{e.warn({err:t},`meter provider shutdown failed`)})]);await Promise.race([t.then(()=>!1),new Promise(e=>setTimeout(()=>e(!0),SHUTDOWN_TIMEOUT_MS))])&&e.warn({},`telemetry shutdown timed out after ${SHUTDOWN_TIMEOUT_MS}ms — data may be lost`),tracerProvider=null,meterProvider=null,trace.disable(),metrics$1.disable(),context.disable()}function getTracer(){return trace.getTracer(TRACER_NAME)}function getMeter(){return metrics$1.getMeter(TRACER_NAME)}async function withSpan(e,t,S){return getTracer().startActiveSpan(e,t??{},async e=>{try{let t=await S(e);return e.isRecording(),t}catch(t){throw e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t instanceof Error?t.message:String(t)}),t}finally{e.end()}})}function withSpanSync(e,t,S){return getTracer().startActiveSpan(e,t??{},e=>{try{return S(e)}catch(t){throw e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t instanceof Error?t.message:String(t)}),t}finally{e.end()}})}function setActiveSpanAttributes(e){let t=trace.getSpan(context.active());t&&t.setAttributes(e)}function buildParseOpts(e){return e?{resolveEmbed:e.resolveEmbed,resolveSize:e.resolveSize,sourcePath:e.sourcePath}:void 0}function composeAndWriteRawBody(e,t,S,w){withSpanSync(`bridge.composeAndWriteRawBody`,{attributes:{surface:S,"body.bytes":t.length,"doc.name":e.guid}},()=>{let S=e.getXmlFragment(`default`),E=e.getText(`source`),D=E.toString(),{body:O}=stripFrontmatter(t),k=withSpanSync(`md.parseWithFallback`,{attributes:{"body.bytes":O.length,"doc.name":e.guid}},()=>mdManager.parseWithFallback(O,buildParseOpts(w))),j=schema.nodeFromJSON(k);D!==t&&applyFastDiff(E,D,t),updateYFragment(e,S,j,{mapping:new Map,isOMark:new Map})})}function replaceRawBody(e,t,S){let w=e.getXmlFragment(`default`),E=e.getText(`source`),{body:D}=stripFrontmatter(t),O=mdManager.parseWithFallback(D,buildParseOpts(S)),k=schema.nodeFromJSON(O),j=E.toString();j!==t&&(E.delete(0,j.length),E.insert(0,t)),updateYFragment(e,w,k,{mapping:new Map,isOMark:new Map})}function deriveFragmentFromYtext(e,t){let S=e.getXmlFragment(`default`),{body:w}=stripFrontmatter(e.getText(`source`).toString()),E=mdManager.parseWithFallback(w,buildParseOpts(t));updateYFragment(e,S,schema.nodeFromJSON(E),{mapping:new Map,isOMark:new Map})}const DEBOUNCE_MS=100,MAX_DISK_ACK_SVS=1e3;function isSystemDoc(e){return e===SYSTEM_DOC_NAME}const CONFIG_DOC_NAME_SET=new Set(CONFIG_DOC_NAMES);function isConfigDoc(e){return CONFIG_DOC_NAME_SET.has(e)}var CC1Broadcaster=class{hocuspocus;seqs=new Map;timers=new Map;log=getLogger(`cc1`);warnedMissing=!1;latestDiskAckSVs=new Map;constructor(e){this.hocuspocus=e}signal(e){let t=this.timers.get(e);t!==void 0&&clearTimeout(t),this.timers.set(e,setTimeout(()=>{this.timers.delete(e),this.broadcast(e)},DEBOUNCE_MS))}broadcast(e){try{let t=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!t){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found — broadcasts will be dropped until it is materialized`),!0),incrementCC1BroadcastDrop();return}let S=(this.seqs.get(e)??0)+1;this.seqs.set(e,S);let w=CC1DerivedViewPayloadSchema.parse({v:1,ch:e,seq:S});t.broadcastStateless(JSON.stringify(w)),incrementCC1Broadcast(),setCC1LastSeq(e,S),setCC1SubscriberCount(t.getConnectionsCount())}catch(t){this.log.error({err:t,channel:e},`[cc1] broadcast failed`)}}emitServerInfo(e,t){try{let S=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!S){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitServerInfo — dropped`),!0),incrementCC1BroadcastDrop();return}let w=CC1ServerInfoPayloadSchema.parse({v:1,ch:CC1_CHANNEL_SERVER_INFO,seq:0,serverInstanceId:e,...t===void 0?{}:{currentBranch:t}});S.broadcastStateless(JSON.stringify(w)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_SERVER_INFO,0)}catch(e){this.log.error({err:e},`[cc1] emitServerInfo failed`)}}emitBranchSwitched(e){try{let t=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!t){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitBranchSwitched — dropped`),!0),incrementCC1BroadcastDrop();return}let S=(this.seqs.get(`branch-switched`)??0)+1;this.seqs.set(CC1_CHANNEL_BRANCH_SWITCHED,S);let w=CC1BranchSwitchedPayloadSchema.parse({v:1,ch:CC1_CHANNEL_BRANCH_SWITCHED,seq:S,branch:e});t.broadcastStateless(JSON.stringify(w)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_BRANCH_SWITCHED,S)}catch(e){this.log.error({err:e},`[cc1] emitBranchSwitched failed`)}}emitDiskAck(e,t){if(this.latestDiskAckSVs.delete(e),this.latestDiskAckSVs.set(e,t),this.latestDiskAckSVs.size>MAX_DISK_ACK_SVS){let e=this.latestDiskAckSVs.keys().next().value;e!==void 0&&this.latestDiskAckSVs.delete(e)}try{let S=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!S){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitDiskAck — dropped`),!0),incrementCC1BroadcastDrop();return}let w=(this.seqs.get(`disk-ack`)??0)+1;this.seqs.set(CC1_CHANNEL_DISK_ACK,w);let E=CC1DiskAckPayloadSchema.parse({v:1,ch:CC1_CHANNEL_DISK_ACK,seq:w,docName:e,sv:Buffer.from(t).toString(`base64`)});S.broadcastStateless(JSON.stringify(E)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_DISK_ACK,w)}catch(t){this.log.error({err:t,docName:e},`[cc1] emitDiskAck failed`)}}getLatestDiskAckSVsAsBase64(){let e={};for(let[t,S]of this.latestDiskAckSVs)e[t]=Buffer.from(S).toString(`base64`);return e}emitConfigValidationRejected(e,t){try{let S=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!S){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitConfigValidationRejected — dropped`),!0),incrementCC1BroadcastDrop();return}let w=(this.seqs.get(`config-validation-rejected`)??0)+1;this.seqs.set(CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,w);let E=CC1ConfigValidationRejectedPayloadSchema.parse({v:1,ch:CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,seq:w,docName:e,error:t});S.broadcastStateless(JSON.stringify(E)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,w)}catch(t){this.log.error({err:t,docName:e},`[cc1] emitConfigValidationRejected failed`)}}emitConfigIgnoreNestedError(e,t){try{let S=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);if(!S){this.warnedMissing||=(this.log.warn({},`[cc1] __system__ document not found at emitConfigIgnoreNestedError — dropped`),!0),incrementCC1BroadcastDrop();return}let w=(this.seqs.get(`config-ignore-nested-error`)??0)+1;this.seqs.set(CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,w);let E=CC1ConfigIgnoreNestedErrorPayloadSchema.parse({v:1,ch:CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,seq:w,path:e,error:t});S.broadcastStateless(JSON.stringify(E)),incrementCC1Broadcast(),setCC1LastSeq(CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,w)}catch(t){this.log.error({err:t,path:e},`[cc1] emitConfigIgnoreNestedError failed`)}}get subscriberCount(){let e=this.hocuspocus.documents.get(SYSTEM_DOC_NAME);return e?e.getConnectionsCount():0}destroy(){for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}};let _editSurfaceCounter=null;function editSurfaceCounter(){return _editSurfaceCounter||=getMeter().createCounter(`ok.frontmatter.edit_surface_total`,{description:`Count of frontmatter edits by surface. Bounded label: source ∈ {source-mode, mcp-write, file-watcher}.`}),_editSurfaceCounter}function recordFrontmatterEditSurface(e){editSurfaceCounter().add(1,{source:e})}const log$8=getLogger(`agent-sessions`),AGENT_WRITE_ORIGIN={source:`local`,skipStoreHooks:!1,context:{origin:`agent-write`,paired:!0}};function applyAgentMarkdownWrite(e,t,S,w){withSpanSync(`agent.applyAgentMarkdownWrite`,{attributes:{"doc.name":e.name,"agent.write_position":S,"agent.markdown.bytes":t.length}},()=>applyAgentMarkdownWriteInner(e,t,S,w))}function applyAgentMarkdownWriteInner(e,t,S,w){try{let{frontmatter:E,body:D}=stripFrontmatter(e.getText(`source`).toString()),{frontmatter:O,body:k}=stripFrontmatter(t),j,F;switch(S){case`replace`:j=O||E,F=k;break;case`prepend`:j=E,F=D.length>0?`${k}\n\n${D}`:k;break;case`append`:j=E,F=D.length>0?`${D}\n\n${k}`:k;break}j!==E&&recordFrontmatterEditSurface(`mcp-write`),composeAndWriteRawBody(e,prependFrontmatter(j,F),`agent`,w)}catch(w){throw log$8.error({err:w,docName:e.name,position:S,markdownLen:t.length},`[applyAgentMarkdownWrite] failed for '${e.name}'`),w}}function applyAgentUndo(e,t,S){return withSpanSync(`agent.applyAgentUndo`,{attributes:{"doc.name":e.dc.document.name,"agent.undo_scope":t}},()=>{let w=applyAgentUndoInner(e,t,S);return setActiveSpanAttributes({"agent.undo_effective":w}),w})}function applyAgentUndoInner(e,t,S){let{dc:w,um:E,undoOrigin:D}=e,O=w.document,k=!1;return O.transact(()=>{if(t===`last`){if(E.undoStack.length===0)return;E.undo(),k=!0}else for(;E.undoStack.length>0;)E.undo(),k=!0;deriveFragmentFromYtext(O,S)},D),k}function createSessionOrigin(e,t,S,w,E){let D={origin:`agent-write`,paired:!0,session_id:e};t!==void 0&&(D.agent_type=t),S!==void 0&&(D.principal=S),w!==void 0&&(D.display_name=w),E!==void 0&&(D.color_seed=E),Object.freeze(D);let O={source:`local`,skipStoreHooks:!1,context:D};return Object.freeze(O),O}function createUndoOrigin(e,t){let S={origin:`agent-undo`,paired:!0,session_id:e};t!==void 0&&(S.agent_type=t),Object.freeze(S);let w={source:`local`,skipStoreHooks:!1,context:S};return Object.freeze(w),w}const MAX_AGENT_SESSIONS=256;var AgentSessionCapacityError=class extends Error{limit;constructor(e){super(`Maximum agent session count reached (${e})`),this.name=`AgentSessionCapacityError`,this.limit=e}},AgentSessionManager=class{sessions=new Map;pendingSessions=new Map;hocuspocus;maxSessions;constructor(e,t={}){this.hocuspocus=e,this.maxSessions=t.maxSessions??256}sessionKey(e,t){return`${e}\0${t}`}*sessionsForConnection(e){let t=`\0${e}`;for(let[e,S]of this.sessions)e.endsWith(t)&&(yield S)}getLiveSession(e,t){return this.sessions.get(this.sessionKey(e,t))}async getSession(e,t=`claude-1`,S){if(isSystemDoc(e)||isConfigDoc(e))throw Error(`Cannot create agent session for reserved doc: ${e}`);let w=this.sessionKey(e,t),E=this.sessions.get(w);if(E)return E;let D=this.pendingSessions.get(w);if(D)return D;if(this.sessions.size+this.pendingSessions.size>=this.maxSessions)throw new AgentSessionCapacityError(this.maxSessions);let O=this._createSession(e,t,S);this.pendingSessions.set(w,O);try{let e=await O;return this.sessions.set(w,e),e}finally{this.pendingSessions.delete(w)}}async _createSession(e,t,S){let w=S?.clientName,E=t.startsWith(`agent-`)?t.slice(6):t,D=createSessionOrigin(E,w,S?.principalId,S?.displayName,S?.colorSeed),O=createUndoOrigin(E,w),k={session_id:E,...w===void 0?{}:{agent_type:w},...S?.clientName===void 0?{}:{client_name:S.clientName},...S?.principalId===void 0?{}:{principalId:S.principalId}},j=await this.hocuspocus.openDirectConnection(e,k),F=new UndoManager([j.document.getText(`source`),j.document.getMap(`agent-flash`)],{trackedOrigins:new Set([D]),captureTimeout:500,captureTransaction:e=>e.origin!==O,ignoreRemoteMapChanges:!0}),L=({stackItem:e})=>{e.meta.set(`time`,Date.now())};return F.on(`stack-item-added`,L),F.on(`stack-item-updated`,L),log$8.info({docName:e,agentId:t},`[agent-session] Created session for: ${e} / ${t}`),{dc:j,origin:D,undoOrigin:O,um:F,agentId:t,docName:e}}hasSession(e,t=`claude-1`){return this.sessions.has(this.sessionKey(e,t))}async cleanupSession(e,t,S){try{try{t.um.destroy()}catch(e){log$8.error({err:e,...S},`[agent-session] um.destroy() failed`)}try{await t.dc.disconnect()}catch(e){log$8.error({err:e,...S},`[agent-session] dc.disconnect() failed`)}}finally{this.sessions.delete(e)}}async closeSession(e,t=`claude-1`){let S=this.sessionKey(e,t),w=this.sessions.get(S);w&&(await this.cleanupSession(S,w,{docName:e,agentId:t}),log$8.info({docName:e,agentId:t},`[agent-session] Closed session for: ${e} / ${t}`))}async closeAllForAgent(e){let t=`\0${e}`,S=[...this.pendingSessions.keys()].filter(e=>e.endsWith(t));S.length>0&&await Promise.allSettled(S.map(e=>this.pendingSessions.get(e)));let w=[...this.sessions.keys()].filter(e=>e.endsWith(t));for(let t of w){let S=this.sessions.get(t);S&&await this.cleanupSession(t,S,{agentId:e,key:t})}}async closeAllForDoc(e){let t=`${e}\0`,S=[...this.sessions.keys()].filter(e=>e.startsWith(t));for(let t of S){let S=this.sessions.get(t);S&&await this.cleanupSession(t,S,{docName:e,key:t})}}async closeAll(e){if(e){await this.closeAllForDoc(e);return}let t=[...this.sessions.keys()];for(let e of t){let t=this.sessions.get(e);t&&await this.cleanupSession(e,t,{key:e})}}};const RING_BUFFER_LIMIT=50;let _effectCounter=0;const EFFECT_CAPTURE_ORIGIN=Object.freeze({source:`local`,skipStoreHooks:!0,context:Object.freeze({origin:`effect-capture`,paired:!1})});function captureEffect(e,t,S,w){let E=e.doc;if(!E)return;let D=++_effectCounter,O=E.getMap(`agent-effects`),k=F=>{e.unobserve(k),E.off(`destroy`,j);let L=`${t}:${D}`,B={sessionId:t,timestamp:Date.now(),delta:F.delta,agent_type:w??`agent`,color_seed:S??t};try{E.transact(()=>{if(O.set(L,B),O.size>RING_BUFFER_LIMIT){let e=[...O.entries()].sort((e,t)=>e[1].timestamp-t[1].timestamp);for(let[t]of e.slice(0,O.size-RING_BUFFER_LIMIT))O.delete(t)}},EFFECT_CAPTURE_ORIGIN)}catch(e){let S=e instanceof Error?e.message:String(e);if(console.warn(JSON.stringify({event:`effect-diff-capture-failed`,sessionId:t,reason:S})),incrementEffectDiffCaptureFailures(),process.env.NODE_ENV!==`production`)throw e}},j=()=>{e.unobserve(k)};e.observe(k),E.once(`destroy`,j)}function collectItemsInDeleteSet(e,t,S){iterateDeletedStructs(e,t,e=>{e instanceof Item&&S.add(e)})}function*walkYTextItems(e){let t=e._start;for(;t!==null;)yield t,t=t.right}function synthesizeStackItemDiff(e,t){let S=[],w=[],E=t.doc,D=new Set,O=new Set;E&&E.transact(t=>{collectItemsInDeleteSet(t,e.insertions,D),collectItemsInDeleteSet(t,e.deletions,O)});let k=``,j=``,F=0,L=0;for(let e of walkYTextItems(t)){if(!(e.content instanceof ContentString))continue;let t=e.content.str,E=t.length,B=D.has(e),H=O.has(e);e.deleted?H&&(w.push({position:F,content:t,length:E}),k+=t,F+=E):(j+=t,B?S.push({position:L,content:t,length:E}):(k+=t,F+=E),L+=E)}return{insertions:S,deletions:w,before:k,after:j}}function synthesizeStackItemDiffText(e,t,S){let{before:w,after:E}=synthesizeStackItemDiff(e,t);return w===E?``:createPatch(S,w,E,void 0,void 0,{context:3})}function getBurstTs(e){let t=e.meta.get(`time`);return typeof t==`number`?t:Date.now()}function countStackItemChanges(e,t){let S=t.doc,w=new Set,E=new Set;S&&S.transact(t=>{collectItemsInDeleteSet(t,e.insertions,w),collectItemsInDeleteSet(t,e.deletions,E)});let D=0,O=0;for(let e of walkYTextItems(t)){if(!(e.content instanceof ContentString))continue;let t=e.content.str.length;!e.deleted&&w.has(e)&&(D+=t),E.has(e)&&(O+=t)}return{additions:D,deletions:O}}function listAgentActivity(e,t){let S=[],w=null,E=!1;for(let D of e.sessionsForConnection(t)){if(E=!0,!w){let e=D.origin.context,S=typeof e?.agent_type==`string`?e.agent_type:void 0,E=typeof e?.color_seed==`string`?e.color_seed:t,O=iconFromClientName(S),k=AGENT_ICON_COLORS[O]??colorFromSeed(E);w={displayName:e?.display_name||(typeof e?.agent_type==`string`?e.agent_type:void 0)||t,color:k,icon:O,connectionId:t}}let e=D.docName,O=D.um,k=D.dc.document.getText(`source`),j=[];for(let e=0;e<O.undoStack.length;e++){let t=O.undoStack[e],S=getBurstTs(t),{additions:w,deletions:E}=countStackItemChanges(t,k);j.push({stackIndex:e,ts:S,additions:w,deletions:E})}if(j.length===0)continue;j.sort((e,t)=>t.stackIndex-e.stackIndex);let F=j.reduce((e,t)=>e+t.additions,0),L=j.reduce((e,t)=>e+t.deletions,0),B=Math.max(...j.map(e=>e.ts));S.push({docName:e,additionsTotal:F,deletionsTotal:L,lastTs:B,bursts:j})}return E?(S.sort((e,t)=>t.lastTs-e.lastTs),{sessionAlive:!0,agent:w,files:S}):{sessionAlive:!1,agent:null,files:[]}}const ELLIPSIS=`…`,LINE_TERMINATOR_RE=RegExp(`[\\r\\n\\v\\f\\u0085\\u2028\\u2029]`,`g`);function normalizeSummary(e){if(e===void 0)return{kind:`absent`};if(typeof e!=`string`)return{kind:`invalid`};if(e.length===0||e.trim().length===0)return{kind:`absent`};let t=e.replace(LINE_TERMINATOR_RE,` `);return t.length<=80?{kind:`value`,value:t}:{kind:`value`,value:t.slice(0,79)+ELLIPSIS,truncatedFrom:e.length}}function isAllowedApiOrigin(e){if(e===`null`)return!0;try{let{hostname:t}=new URL(e);return t===`localhost`||t===`::1`||t===`[::1]`||/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(t)}catch{return!1}}const counters=new WeakMap;let globalCounter=0;function getCounters(e){let t=counters.get(e);return t||(t={lastUserTxGen:0,settledGen:0,lastUserTxAtMs:null},counters.set(e,t)),t}function isObserverSelfOrigin(e){if(!e||typeof e!=`object`)return!1;let t=e.context;return t!=null&&t.origin===`observer-sync`}function attachQuiescenceTracker(e){let t=t=>{if(isObserverSelfOrigin(t.origin))return;let S=getCounters(e);S.lastUserTxGen=++globalCounter,S.lastUserTxAtMs=Date.now()},S=()=>{getCounters(e).settledGen=++globalCounter};return e.on(`afterTransaction`,t),e.on(`afterAllTransactions`,S),()=>{e.off(`afterTransaction`,t),e.off(`afterAllTransactions`,S)}}const overrides=new WeakMap;function isDocQuiescent(e){let t=overrides.get(e);if(t!==void 0)return t;let S=counters.get(e);return S?S.settledGen>S.lastUserTxGen:!0}function getMsSinceLastUserTx(e,t=Date.now()){let S=counters.get(e);return!S||S.lastUserTxAtMs===null?null:Math.max(0,t-S.lastUserTxAtMs)}const DEFAULT_DEBOUNCE_S=60,lastEmitMs=new Map,MAX_VIOLATION_RATE_TUPLES=1024,lastToleranceEmitMs=new Map,lastPathBEmitMs=new Map;function toleranceRateKey(e,t){return`${e}::${t}`}function readDebounceMs(){let e=process.env.OK_BRIDGE_VIOLATION_DEBOUNCE_S;if(e===void 0)return DEFAULT_DEBOUNCE_S*1e3;let t=Number.parseInt(e,10);return!Number.isFinite(t)||t<=0?DEFAULT_DEBOUNCE_S*1e3:t*1e3}function rateKey(e,t){return`${e}::${t??`__nodoc__`}`}function shouldEmitBridgeInvariantViolation(e,t,S=Date.now()){let w=rateKey(e,t),E=lastEmitMs.get(w),D=readDebounceMs();if(E!==void 0&&S-E<D)return!1;if(lastEmitMs.size>=MAX_VIOLATION_RATE_TUPLES)for(let[e,t]of lastEmitMs)S-t>=D&&lastEmitMs.delete(e);return lastEmitMs.set(w,S),!0}function shouldEmitBridgeToleranceApplied(e,t,S=Date.now()){let w=toleranceRateKey(e,t),E=lastToleranceEmitMs.get(w),D=readDebounceMs();return E!==void 0&&S-E<D?!1:(lastToleranceEmitMs.set(w,S),!0)}function shouldEmitObserverAPathBFired(e,t=Date.now()){let S=e??`__nodoc__`,w=lastPathBEmitMs.get(S),E=readDebounceMs();if(w!==void 0&&t-w<E)return!1;if(lastPathBEmitMs.size>=MAX_VIOLATION_RATE_TUPLES)for(let[e,S]of lastPathBEmitMs)t-S>=E&&lastPathBEmitMs.delete(e);return lastPathBEmitMs.set(S,t),!0}function emitObserverAPathBFired(e,t){let S=shouldEmitObserverAPathBFired(e,t);return S||incrementObserverAPathBFiresSuppressed(),S}function shouldThrowOnBridgeInvariantViolation(e=process.env){return e.NODE_ENV===`test`||e.OK_BRIDGE_THROW_ON_VIOLATION===`1`}function assertBridgeInvariant(e,t,S){let w=normalizeBridge(e),E=normalizeBridge(t);if(w===E){if(e!==t){let w=detectAppliedToleranceClasses(e,t);for(let e of w)shouldEmitBridgeToleranceApplied(S.site,e,S.nowMs)&&(incrementBridgeToleranceApplied(e),console.warn(JSON.stringify({event:`bridge-tolerance-applied`,site:S.site,class:e})))}return!0}let D={site:S.site,origin:S.origin,docName:S.docName,ytextSnapshot:e,fragmentMdSnapshot:t,unifiedDiff:` ytext: ${w.slice(0,300)}\n frag: ${E.slice(0,300)}`,stack:Error().stack};if(shouldThrowOnBridgeInvariantViolation()&&!S.suppressDevThrow)throw new BridgeInvariantViolationError(D);if(!shouldEmitBridgeInvariantViolation(S.site,S.docName,S.nowMs))return incrementBridgeInvariantViolationsSuppressed(),!1;incrementBridgeInvariantViolations();let O=process.env.OK_TELEMETRY_VERBOSE===`1`;return console.warn(JSON.stringify(toBridgeInvariantLog(D,{verbose:O}))),!1}const CONFIG_VALIDATION_REVERT_ORIGIN={source:`local`,skipStoreHooks:!0,context:{origin:`config-validation-revert`}},CONFIG_FILE_WATCHER_ORIGIN={source:`local`,skipStoreHooks:!0,context:{origin:`config-file-watcher`}};function normalizeFsPath(e){let t=e.split(sep).filter(Boolean);return t.length<=2?e:`...${sep}${t.slice(-2).join(sep)}`}function classifyFsPath(e){return e.includes(`${sep}.git${sep}ok${sep}`)||e.includes(`shadow-repo`)?`shadow-repo`:e.includes(`${sep}.git${sep}`)?`git`:basename(e).endsWith(`.lock`)||basename(e)===`lock`?`lock`:basename(e)===`principal.json`?`principal`:e.includes(`${sep}.ok${sep}`)&&(basename(e)===`conflicts.json`||e.includes(`${sep}conflicts${sep}`))?`conflict`:e.includes(`${sep}.ok${sep}`)?`ok-internal`:e.endsWith(`.md`)||e.endsWith(`.mdx`)?`content-md`:`other`}function buildAttrs(e,t,S){let w={"fs.operation":e,"fs.path":normalizeFsPath(t),"fs.path.role":classifyFsPath(t)};return S&&Object.assign(w,S),w}function byteLength(e){return typeof e==`string`?Buffer.byteLength(e,`utf-8`):e instanceof Uint8Array?e.byteLength:e.byteLength??0}async function tracedWriteFile(e,t,S){return withSpan(`fs.writeFile`,{attributes:buildAttrs(`writeFile`,e,{"fs.bytes":byteLength(t)})},async()=>{await writeFile(e,t,S)})}async function tracedRename(e,t){return withSpan(`fs.rename`,{attributes:buildAttrs(`rename`,t,{"fs.source_path":normalizeFsPath(e)})},async()=>{await rename(e,t)})}async function tracedMkdir(e,t){return withSpan(`fs.mkdir`,{attributes:buildAttrs(`mkdir`,e)},async()=>mkdir(e,t))}function tracedWriteFileSync(e,t,S){withSpanSync(`fs.writeFileSync`,{attributes:buildAttrs(`writeFileSync`,e,{"fs.bytes":byteLength(t)})},()=>{writeFileSync(e,t,S)})}function tracedAppendFileSync(e,t,S){withSpanSync(`fs.appendFileSync`,{attributes:buildAttrs(`appendFileSync`,e,{"fs.bytes":byteLength(t)})},()=>{appendFileSync(e,t,S)})}function tracedMkdirSync(e,t){return withSpanSync(`fs.mkdirSync`,{attributes:buildAttrs(`mkdirSync`,e)},()=>mkdirSync(e,t))}function tracedRenameSync(e,t){withSpanSync(`fs.renameSync`,{attributes:buildAttrs(`renameSync`,t,{"fs.source_path":normalizeFsPath(e)})},()=>{renameSync(e,t)})}function tracedCpSync(e,t,S){withSpanSync(`fs.cpSync`,{attributes:buildAttrs(`cpSync`,t,{"fs.source_path":normalizeFsPath(e)})},()=>{cpSync(e,t,S)})}function tracedUnlinkSync(e){withSpanSync(`fs.unlinkSync`,{attributes:buildAttrs(`unlinkSync`,e)},()=>{unlinkSync(e)})}function tracedLinkSync(e,t){withSpanSync(`fs.linkSync`,{attributes:buildAttrs(`linkSync`,t,{"fs.source_path":normalizeFsPath(e)})},()=>{linkSync(e,t)})}function tracedRmSync(e,t){withSpanSync(`fs.rmSync`,{attributes:buildAttrs(`rmSync`,e)},()=>{rmSync(e,t)})}function tracedRmdirSync(e){withSpanSync(`fs.rmdirSync`,{attributes:buildAttrs(`rmdirSync`,e)},()=>{rmdirSync(e)})}function configScopeAttr(e){if(e===`__config__/project`)return`project`;if(e===`__local__/project`)return`project-local`;if(e===`__user__/config.yml`)return`user`;if(e===`__config__/okignore`)return`project`}let _okignoreRejectionCounter=null;function okignoreRejectionCounter(){return _okignoreRejectionCounter||=getMeter().createCounter(`ok.config.ignore.rejection_total`,{description:`Count of okignore L3 rejections by error code.`}),_okignoreRejectionCounter}function emitSchemaInvalidIssueEvents(e){if(isKnownConfigError(e)&&e.code===`SCHEMA_INVALID`)for(let t of e.issues)addConfigSpanEvent(`config.validation.issue`,{"issue.path":t.path.map(e=>String(e)).join(`.`),"issue.message":t.message})}function configDocAbsPath(e,t){if(e===`__config__/project`)return resolveConfigPath(`project`,t.projectDir,t.homedirOverride);if(e===`__local__/project`)return resolveConfigPath(`project-local`,t.projectDir,t.homedirOverride);if(e===`__user__/config.yml`)return resolveConfigPath(`user`,t.projectDir,t.homedirOverride);if(e===`__config__/okignore`)return resolve(t.contentDir??t.projectDir,`.okignore`);throw Error(`configDocAbsPath: not a config doc name: ${e}`)}let cachedDefaultsYaml=null;function serializedDefaults(){return cachedDefaultsYaml===null&&(cachedDefaultsYaml=(0,import_dist$1.stringify)(ConfigSchema$1.parse({}))),cachedDefaultsYaml}function validateOkignore(e){if(e.length===0)return{ok:!0};let t=e.split(`
|
|
1137
1137
|
`);for(let e=0;e<t.length;e++){let S=t[e]??``;if(S.length!==0&&/^\s+$/.test(S))return{ok:!1,error:{code:`OKIGNORE_INVALID`,detail:`Whitespace-only pattern is not allowed.`,lineNumber:e+1}}}return{ok:!0}}function validateConfigContent(e,t){return e===`__config__/okignore`?validateOkignore(t):validateConfigYaml(t)}function defaultLkgFor(e){return e===`__config__/okignore`?``:serializedDefaults()}function validateConfigYaml(e){let t=(0,import_dist$1.parseDocument)(e);if(t.errors.length>0)return{ok:!1,error:{code:`YAML_PARSE`,detail:t.errors.map(e=>e.message).join(`; `)}};let S=t.toJSON()??{},w=ConfigSchema$1.safeParse(S);return w.success?{ok:!0}:{ok:!1,error:{code:`SCHEMA_INVALID`,issues:w.error.issues.map(e=>({path:e.path.map(e=>typeof e==`symbol`?String(e):e),message:e.message,issueCode:e.code}))}}}function loadConfigDoc(e,t,S){let w=e.getText(`source`);if(w.length>0)return;let E=configDocAbsPath(t,S),D=``;if(existsSync(E))try{D=readFileSync(E,`utf-8`)}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[config] Could not read ${E}: ${t}. Seeding with empty content.`),D=``}let O=validateConfigContent(t,D);!O.ok&&D.length>0&&getLogger(`config-persistence`).warn({docName:t,path:E},`[config-persistence] loadConfigDoc seeding invalid content for ${t} into Y.Text — first mutation will revert to LKG`),e.transact(()=>{D.length>0&&w.insert(0,D)},CONFIG_VALIDATION_REVERT_ORIGIN),O.ok&&D.length>0?S.lkgCache.set(t,D):S.lkgCache.set(t,defaultLkgFor(t))}async function atomicWriteConfig(e,t){await tracedMkdir(dirname(e),{recursive:!0});let S=`${e}.tmp.${crypto.randomUUID()}`;try{await tracedWriteFile(S,t,`utf-8`),await tracedRename(S,e)}catch(e){try{tracedUnlinkSync(S)}catch{}throw e}}async function storeConfigDoc(e,t,S,w){return withConfigSpan(`config.persist`,{"config.scope":configScopeAttr(t),"config.transport":`fs`},async E=>{let D=await storeConfigDocInner(e,t,S,w);return E.setAttribute(`config.outcome`,persistOutcomeAttr(D)),D})}function persistOutcomeAttr(e){return e===`reverted`?`reverted`:e===`write-failed`?`rejected`:`success`}async function storeConfigDocInner(e,t,S,w){if(S===CONFIG_VALIDATION_REVERT_ORIGIN)return`no-op`;let E=e.getText(`source`),D=E.toString();if(D.length===0)return`no-op`;let O=w.lkgCache.get(t);if(O!==void 0&&D===O)return`no-op`;let k=configScopeAttr(t),j=withConfigSpanSync(`config.validate`,{"config.scope":k,"config.validation.layer":`L3`},e=>{let S=validateConfigContent(t,D);return e.setAttribute(`config.outcome`,S.ok?`success`:`rejected`),S.ok||emitSchemaInvalidIssueEvents(S.error),S});if(!j.ok)return await withConfigSpan(`config.revert`,{"config.scope":k,"config.outcome":`reverted`},async()=>{let S=O??defaultLkgFor(t);e.transact(()=>{E.length>0&&E.delete(0,E.length),E.insert(0,S)},CONFIG_VALIDATION_REVERT_ORIGIN),O===void 0&&w.lkgCache.set(t,S),t===`__config__/okignore`&&isKnownConfigError(j.error)&&okignoreRejectionCounter().add(1,{"error.code":j.error.code}),w.onConfigRejected?.(t,j.error)}),`reverted`;let F=configDocAbsPath(t,w);try{await tracedMkdir(dirname(F),{recursive:!0})}catch(e){let S=e instanceof Error?e.message:String(e);return getLogger(`config-persistence`).warn({docName:t,path:F,err:e},`[config-persistence] could not create parent dir for ${F}: ${S}`),w.onConfigRejected?.(t,{code:`WRITE_ERROR`,detail:`Could not create parent directory for ${F}: ${S}`}),`write-failed`}try{return await withFileLock(`${F}.lock`,async()=>{let S=null;try{S=readFileSync(F,`utf-8`)}catch(e){if(e.code!==`ENOENT`){let S=e instanceof Error?e.message:String(e);return getLogger(`config-persistence`).warn({docName:t,path:F,err:e},`[config-persistence] could not read config for reconciliation: ${S}`),w.onConfigRejected?.(t,{code:`WRITE_ERROR`,detail:`Could not read config for reconciliation at ${F}: ${S}`}),`write-failed`}}if(S!==null&&O!==void 0&&S!==O){if(validateConfigContent(t,S).ok)return e.transact(()=>{E.length>0&&E.delete(0,E.length),E.insert(0,S)},CONFIG_FILE_WATCHER_ORIGIN),w.lkgCache.set(t,S),getLogger(`config-persistence`).info({docName:t,path:F},`[config-persistence] reconciled: external writer landed; imported disk into Y.Text`),`reconciled`;getLogger(`config-persistence`).warn({docName:t,path:F},`[config-persistence] disk diverged from LKG but contains invalid content; proceeding with local write`)}try{await atomicWriteConfig(F,D)}catch(e){let S=e instanceof Error?e.message:String(e);return getLogger(`config-persistence`).warn({docName:t,path:F,err:e},`[config-persistence] write-failed at ${F}: ${S}`),w.onConfigRejected?.(t,{code:`WRITE_ERROR`,detail:`Failed to persist config at ${F}: ${S}`}),`write-failed`}return w.lkgCache.set(t,D),`persisted`},{onWarn:(e,t)=>{getLogger(`config-persistence`).warn(t,`[config-persistence] ${e}`)}})}catch(e){if(e instanceof FileLockTimeoutError)return getLogger(`config-persistence`).warn({docName:t,path:F,err:e},`[config-persistence] lock timeout at ${F}: ${e.message}`),w.onConfigRejected?.(t,{code:`WRITE_ERROR`,detail:e.message}),`write-failed`;throw e}}function applyExternalConfigChange(e,t,S,w){if(!e)return`no-op`;let E=w.lkgCache.get(t);if(E!==void 0&&E===S)return`no-op`;let D=configScopeAttr(t),O=withConfigSpanSync(`config.validate`,{"config.scope":D,"config.validation.layer":`L3`},e=>{let w=validateConfigContent(t,S);return e.setAttribute(`config.outcome`,w.ok?`success`:`rejected`),w.ok||emitSchemaInvalidIssueEvents(w.error),w});if(!O.ok)return t===`__config__/okignore`&&isKnownConfigError(O.error)&&okignoreRejectionCounter().add(1,{"error.code":O.error.code}),w.onConfigRejected?.(t,O.error),`rejected`;let k=e.getText(`source`);return e.transact(()=>{k.length>0&&k.delete(0,k.length),k.insert(0,S)},CONFIG_FILE_WATCHER_ORIGIN),w.lkgCache.set(t,S),`applied`}let pendingContributors=new Map;function recordContributor(e,t,S,w,E,D,O,k){let j=pendingContributors.get(t);if(j||(j={writerId:t,displayName:S,colorSeed:w??S,docs:new Set,subjectOverride:E,actor:D,summaries:[],previousPaths:[]},pendingContributors.set(t,j)),j.docs.add(e),E!==void 0&&(j.subjectOverride=E),D!==void 0){let e=j.actor??{};D.principalId!==void 0&&(e.principalId=D.principalId),D.agentType!==void 0&&(e.agentType=D.agentType),D.clientName!==void 0&&(e.clientName=D.clientName),D.clientVersion!==void 0&&(e.clientVersion=D.clientVersion),D.label!==void 0&&(e.label=D.label),j.actor=e}if(typeof O==`string`&&O.length>0&&j.summaries.push(O),k&&k.length>0)for(let e of k)j.previousPaths.push(e)}function swapContributors(){let e=pendingContributors;return pendingContributors=new Map,e}function restoreContributors(e){for(let[t,S]of e){let e=pendingContributors.get(t);e||(e={writerId:t,displayName:S.displayName,colorSeed:S.colorSeed,docs:new Set,actor:S.actor,summaries:[],previousPaths:[]},pendingContributors.set(t,e));for(let t of S.docs)e.docs.add(t);S.summaries.length>0&&(e.summaries=[...S.summaries,...e.summaries]),S.previousPaths.length>0&&(e.previousPaths=[...S.previousPaths,...e.previousPaths])}}function formatContributorsFrom(e){if(e.size===0)return``;let t=[``];for(let S of e.values()){let e={v:1,id:S.writerId,name:S.displayName,colorSeed:S.colorSeed,docs:[...S.docs]};S.summaries.length>0&&(e.summaries=[...S.summaries]),t.push(`ok-contributors: ${JSON.stringify(e)}`)}return t.join(`
|
|
1138
1138
|
`)}function formatContributors(){return formatContributorsFrom(pendingContributors)}function restoreContributorEntry(e,t){let S=pendingContributors.get(e);S||(S={writerId:e,displayName:t.displayName,colorSeed:t.colorSeed,docs:new Set,actor:t.actor,summaries:[],previousPaths:[]},pendingContributors.set(e,S));for(let e of t.docs)S.docs.add(e);t.summaries.length>0&&(S.summaries=[...t.summaries,...S.summaries]),t.previousPaths.length>0&&(S.previousPaths=[...t.previousPaths,...S.previousPaths])}function clearContributors(){pendingContributors.clear()}function contributorCount(){return pendingContributors.size}function hasContributor(e){return pendingContributors.has(e)}const SUPPORTED_DOC_EXTENSIONS=[`.mdx`,`.md`],DEFAULT_EXTENSION=`.md`;function isSupportedDocFile(e){let t=extname(e).toLowerCase();return SUPPORTED_DOC_EXTENSIONS.includes(t)}function isSupportedAssetFile(e,t){let S=extname(e).slice(1).toLowerCase();return S.length>0&&t.has(S)}function stripDocExtension(e){let t=e.toLowerCase();for(let S of SUPPORTED_DOC_EXTENSIONS)if(t.endsWith(S))return e.slice(0,-S.length);return e}function canonicalize(e){let t=e.toLowerCase();return t===`.mdx`?`.mdx`:t===`.md`?`.md`:null}function rank(e){return SUPPORTED_DOC_EXTENSIONS.indexOf(e)}const docExtensionByName=new Map;function registerDocExtension(e,t){let S=canonicalize(t);if(!S)throw Error(`registerDocExtension: unsupported extension "${t}"`);let w=docExtensionByName.get(e);if(!w)return docExtensionByName.set(e,t),{effective:t,changed:!0,shadowed:null};let E=canonicalize(w);return E?E===S?{effective:w,changed:!1,shadowed:null}:rank(S)<rank(E)?(docExtensionByName.set(e,t),{effective:t,changed:!0,shadowed:w}):{effective:w,changed:!1,shadowed:t}:(docExtensionByName.set(e,t),{effective:t,changed:!0,shadowed:w})}function getDocExtension(e){return docExtensionByName.get(e)??DEFAULT_EXTENSION}function forgetDocExtension(e){docExtensionByName.delete(e)}function acquireLock(e,t){let S=resolve(e,`lock`);if(existsSync(S)){let t=null;try{t=JSON.parse(readFileSync(S,`utf-8`))}catch{console.warn(`[shadow-lock] Corrupt lock file at ${S} — replacing`)}if(t&&!isValidLockPid(t.pid)&&(console.warn(`[shadow-lock] Invalid lock pid (${String(t.pid)}) at ${S} — replacing`),t=null),t){let S=t.hostname===hostname();if(!(S&&t.pid===process.pid)){if(S&&isProcessAlive(t.pid))throw Error(`Shadow repo at ${e} is locked by another writer (pid=${t.pid}, worktree=${t.worktreeRoot}, started=${t.startedAt}). Only one active writer instance may mutate a given shadow root at a time.`);console.warn(`[shadow-lock] Stale lock detected (pid=${t.pid}, host=${t.hostname}) — replacing`)}}}let w={pid:process.pid,hostname:hostname(),startedAt:new Date().toISOString(),worktreeRoot:t};return writeFileSync(S,JSON.stringify(w,null,2),`utf-8`),S}function releaseLock(e){let t=resolve(e,`lock`);try{unlinkSync(t)}catch{}}const GIT_TIMEOUT_MS$3=(()=>{let e=process.env.OK_GIT_TIMEOUT_MS;if(!e)return 3e4;let t=Number.parseInt(e,10);return Number.isFinite(t)&&t>0?t:3e4})();function shadowGit(e){return esm_default({baseDir:e.workTree,timeout:{block:GIT_TIMEOUT_MS$3}}).env({GIT_DIR:e.gitDir,GIT_WORK_TREE:e.workTree})}async function initShadowRepo(e){let t=resolveShadowDir(e),S=resolve(e,`.git/openknowledge`),w=existsSync(S),E=existsSync(t);if(w&&!E?tracedRenameSync(S,t):w&&E&&console.warn(`[shadow-repo] unexpected legacy + new shadow both present — no rename performed`),!existsSync(resolve(t,`HEAD`))){tracedMkdirSync(t,{recursive:!0}),await esm_default({baseDir:e,timeout:{block:GIT_TIMEOUT_MS$3}}).raw(`init`,`--bare`,t);let S=esm_default({timeout:{block:GIT_TIMEOUT_MS$3}}).env({GIT_DIR:t});await S.raw(`config`,`--unset`,`core.bare`),await S.raw(`config`,`core.worktree`,e),await S.raw(`config`,`user.name`,`openknowledge`),await S.raw(`config`,`user.email`,`noreply@openknowledge.local`)}let D={gitDir:t,workTree:e};return await sweepLegacyShadowRefs(D),sweepOrphanedTmpIndexFiles(D),acquireLock(t,e),D}function destroyShadowRepo(e){releaseLock(e.gitDir)}async function sweepLegacyShadowRefs(e){let t=shadowGit(e),S;try{S=(await t.raw(`for-each-ref`,`--format=%(refname)`,`refs/wip`)).trim().split(`
|
|
1139
1139
|
`).filter(e=>e.length>0)}catch{return 0}let w=[],E={server:0,"human-":0,upstream:0};for(let e of S){let t=e.split(`/`);if(t.length<4)continue;let S=t.slice(3).join(`/`);parseWriterId(S).classification===`unknown`&&(S===`server`?(w.push(e),E.server++):S.startsWith(`human-`)?(w.push(e),E[`human-`]++):S===`upstream`&&(w.push(e),E.upstream++))}if(w.length===0)return 0;for(let e of w)try{await t.raw(`update-ref`,`-d`,e)}catch(t){console.warn(`[shadow-migration] failed to delete legacy ref ${e}:`,t)}let D=w.length;return incrementShadowMigrationLegacyRefsDeleted(D),console.warn(`[shadow-migration] deleted ${D} legacy refs: server=${E.server} human-=${E[`human-`]} upstream=${E.upstream}`),D}async function commitWip(e,t,S,w,E=`main`){return withSpan(`shadow.commitWip`,{attributes:{"shadow.writer":t.id,"shadow.branch":E}},async()=>commitWipInner(e,t,S,w,E))}async function commitWipInner(e,t,S,w,E=`main`){let D=resolve(e.gitDir,`index-wip-${t.id}`),O=`refs/wip/${E}/${t.id}`,k=shadowGit(e),j=S||`.`;try{try{let t=(await k.raw(`rev-parse`,`${O}^{tree}`)).trim();await k.env({GIT_DIR:e.gitDir,GIT_INDEX_FILE:D}).raw(`read-tree`,t)}catch(e){let t=e instanceof Error?e.message:String(e);if(!(t.includes(`unknown revision`)||t.includes(`bad revision`)))throw console.error(`[shadow-repo] Unexpected error seeding index for ${O}:`,e),e}await k.env({GIT_DIR:e.gitDir,GIT_WORK_TREE:e.workTree,GIT_INDEX_FILE:D}).raw(`add`,j);let S=(await k.env({GIT_DIR:e.gitDir,GIT_INDEX_FILE:D}).raw(`write-tree`)).trim(),E=null;try{E=(await k.raw(`rev-parse`,O)).trim()}catch(e){let t=e instanceof Error?e.message:String(e);if(!t.includes(`unknown revision`)&&!t.includes(`bad revision`))throw console.error(`[shadow-repo] Unexpected error resolving ${O}:`,e),e}let F=[`commit-tree`,S,`-m`,w];E&&F.push(`-p`,E);let L=(await k.env({GIT_DIR:e.gitDir,GIT_AUTHOR_NAME:t.name,GIT_AUTHOR_EMAIL:t.email,GIT_COMMITTER_NAME:`openknowledge`,GIT_COMMITTER_EMAIL:`noreply@openknowledge.local`}).raw(...F)).trim();return await k.raw(`update-ref`,O,L),L}finally{try{rmSync(D)}catch{}}}function sweepOrphanedTmpIndexFiles(e){let t=0;try{for(let S of readdirSync(e.gitDir))if(S.startsWith(`index-wip-fanout-`))try{rmSync(resolve(e.gitDir,S)),t++}catch{}}catch{}return t}async function buildWipTree(e,t){let S=resolve(e.gitDir,`index-wip-fanout-${randomUUID()}`),w=shadowGit(e),E=t||`.`;try{return await w.env({GIT_DIR:e.gitDir,GIT_WORK_TREE:e.workTree,GIT_INDEX_FILE:S}).raw(`add`,E),(await w.env({GIT_DIR:e.gitDir,GIT_INDEX_FILE:S}).raw(`write-tree`)).trim()}finally{try{rmSync(S)}catch{}}}async function commitWipFromTree(e,t,S,w,E=`main`){return withSpan(`shadow.commitWipFromTree`,{attributes:{"shadow.writer":t.id,"shadow.branch":E,"shadow.tree":S.slice(0,8)}},async()=>commitWipFromTreeInner(e,t,S,w,E))}async function commitWipFromTreeInner(e,t,S,w,E=`main`){let D=`refs/wip/${E}/${t.id}`,O=shadowGit(e),k=null;try{k=(await O.raw(`rev-parse`,D)).trim()}catch(e){let t=e instanceof Error?e.message:String(e);if(!t.includes(`unknown revision`)&&!t.includes(`bad revision`))throw console.error(`[shadow-repo] Unexpected error resolving ${D}:`,e),e}let j=[`commit-tree`,S,`-m`,w];k&&j.push(`-p`,k);let F=(await O.env({GIT_DIR:e.gitDir,GIT_AUTHOR_NAME:t.name,GIT_AUTHOR_EMAIL:t.email,GIT_COMMITTER_NAME:`openknowledge`,GIT_COMMITTER_EMAIL:`noreply@openknowledge.local`}).raw(...j)).trim();return await O.raw(`update-ref`,D,F),F}const FILE_SYSTEM_WRITER={id:`file-system`,name:`File System`,email:`file-system@openknowledge.local`},GIT_UPSTREAM_WRITER={id:`git-upstream`,name:`Git (upstream)`,email:`git@openknowledge.local`},SERVICE_WRITER={id:`openknowledge-service`,name:`Open Knowledge (service)`,email:`service@openknowledge.local`},UPSTREAM_WRITER=GIT_UPSTREAM_WRITER;async function commitUpstreamImport(e,t,S,w,E=`main`){return withSpan(`shadow.commitUpstreamImport`,{attributes:{"shadow.branch":E,"shadow.new_head":w.slice(0,8)}},async()=>commitUpstreamImportInner(e,t,S,w,E))}async function commitUpstreamImportInner(e,t,S,w,E=`main`){return commitWip(e,UPSTREAM_WRITER,t,`${formatImportSubject(S,w)}\n\n${formatOkActor({v:1,writer_id:UPSTREAM_WRITER.id,principal:null,agent_session:null,agent_type:null,client_name:null,client_version:null,label:null,display_name:UPSTREAM_WRITER.name,color_seed:UPSTREAM_WRITER.id,docs:[]})}`,E)}const SAFETY_WRITER=SERVICE_WRITER;async function safetyCheckpoint(e,t,S,w=`main`){return commitWip(e,SAFETY_WRITER,t,`${formatCheckpointSubject(`pre-${S.action}`)}\n\n${formatOkActor({v:1,writer_id:SAFETY_WRITER.id,principal:null,agent_session:null,agent_type:null,client_name:null,client_version:null,label:null,display_name:SAFETY_WRITER.name,color_seed:SAFETY_WRITER.id,docs:[]})}`,w)}async function saveInMemoryCheckpoint(e,t,S){let w=S.branch??`main`,E=shadowGit(e),D=randomUUID(),O=resolve(e.gitDir,`index-checkpoint-${D}`),k=resolve(e.gitDir,`tmp-checkpoint-blob-${D}`),j=t?`${t.replace(/\/$/,``)}/${S.docName}`:S.docName,F=Buffer.byteLength(S.contents,`utf-8`),L=formatCheckpointBodyLine(S.kind===`bridge-merge-loss`?{kind:`bridge-merge-loss`,docName:S.docName,size:F,metadata:S.metadata}:{kind:`external-change-rescue`,docName:S.docName,size:F,metadata:S.metadata}),B=`checkpoint: ${S.label}\n\n${L}`;try{tracedWriteFileSync(k,S.contents,`utf-8`);let t=(await E.env({GIT_DIR:e.gitDir,GIT_INDEX_FILE:O}).raw(`hash-object`,`-w`,k)).trim();await E.env({GIT_DIR:e.gitDir,GIT_INDEX_FILE:O}).raw(`update-index`,`--add`,`--cacheinfo`,`100644,${t},${j}`);let D=(await E.env({GIT_DIR:e.gitDir,GIT_INDEX_FILE:O}).raw(`write-tree`)).trim(),F=(await E.env({GIT_DIR:e.gitDir,GIT_AUTHOR_NAME:`openknowledge`,GIT_AUTHOR_EMAIL:`noreply@openknowledge.local`,GIT_COMMITTER_NAME:`openknowledge`,GIT_COMMITTER_EMAIL:`noreply@openknowledge.local`}).raw(`commit-tree`,D,`-m`,B)).trim();return await E.raw(`update-ref`,`refs/checkpoints/${w}/${F}`,F),F}finally{try{rmSync(O)}catch{}try{rmSync(k)}catch{}}}async function listRescueCheckpoints(e,t=`main`){let S=shadowGit(e),w;try{w=await S.raw(`for-each-ref`,`--format=%(objectname)`,`refs/checkpoints/${t}/`)}catch{return[]}let E=w.trim().split(`
|
|
@@ -1182,11 +1182,11 @@ Karpathy's insight: "The tedious part of maintaining a knowledge base is not the
|
|
|
1182
1182
|
|
|
1183
1183
|
`}function buildWorkflowHandler(e,t,S,w){return async E=>{let D=typeof E.cwd==`string`?E.cwd:void 0,O=await resolveProjectConfigContext(t.resolveCwd,t.config,D);if(!O.ok)return textResult(`Error: ${O.error}`,!0);let k=E[S],j=typeof k==`string`?k:``;return textPlusStructured(`${buildWorkflowFrame(e)}${w(j,O.config.content.dir)}`,{previewUrl:null})}}async function resolveServerUrl(e,t){return typeof e==`function`?await e(t):e}async function resolveConfig(e,t){return typeof e==`function`?await e(t):e}async function resolveProjectConfigContext(e,t,S){let w;try{w=await e(S)}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}try{let e=await resolveConfig(t,w);return{ok:!0,cwd:w,config:e}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async function resolveProjectServerContext(e,t,S,w){let E=await resolveProjectConfigContext(e,t,w);if(!E.ok)return E;let{cwd:D,config:O}=E;try{return{ok:!0,cwd:D,config:O,url:await resolveServerUrl(S,D)}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}function normalizeDocName(e){let t=e.toLowerCase();return t.endsWith(`.md`)?{ok:!0,docName:e.slice(0,-3)}:t.endsWith(`.mdx`)?{ok:!0,docName:e.slice(0,-4)}:t.endsWith(`.markdown`)?{ok:!1,error:`Error: docName "${e}" ends in ".markdown", which is not a supported extension. Use ".md" or ".mdx", or strip the extension to let the server auto-detect.`}:{ok:!0,docName:e}}function normalizeResponse(e,t){if(e.ok){if(typeof t!=`object`||!t||Array.isArray(t))return{ok:!0,data:t};let{ok:e,...S}=t;return{ok:!0,...S}}if(typeof t!=`object`||!t||Array.isArray(t))return{ok:!1,error:`Server returned HTTP ${e.status} with non-object body`};let S=t;if(typeof S.type==`string`&&typeof S.title==`string`){let{type:e,title:t,status:w,instance:E,detail:D,...O}=S;return{...O,ok:!1,error:t,type:e,...typeof w==`number`?{status:w}:{},...typeof E==`string`?{instance:E}:{},...typeof D==`string`?{detail:D}:{}}}let{ok:w,error:E,...D}=S,O=typeof E==`string`?E:typeof S.message==`string`?S.message:`Server returned HTTP ${e.status}`;return{...D,ok:!1,error:O}}async function httpGet(e,t){let S;try{S=await fetch(`${e}${t}`,{signal:AbortSignal.timeout(3e4)})}catch(e){return{ok:!1,error:`Server unreachable: ${e instanceof Error?e.message:e}`}}let w;try{w=await S.json()}catch(e){let t=e instanceof Error?e.message:String(e);return S.ok?{ok:!1,error:`Server returned 2xx response with non-JSON body: ${t}`}:{ok:!1,error:`Server returned HTTP ${S.status} with non-JSON body: ${t}`}}return normalizeResponse(S,w)}async function httpPost(e,t,S){let w;if(S!==void 0)try{w=JSON.stringify(S)}catch(e){return{ok:!1,error:`Request body is not JSON-serializable: ${e instanceof Error?e.message:String(e)}`}}let E;try{E=await fetch(`${e}${t}`,{method:`POST`,headers:{"Content-Type":`application/json`},body:w,signal:AbortSignal.timeout(3e4)})}catch(e){return{ok:!1,error:`Server unreachable: ${e instanceof Error?e.message:e}`}}let D;try{D=await E.json()}catch(e){let t=e instanceof Error?e.message:String(e);return E.ok?{ok:!1,error:`Server returned 2xx response with non-JSON body: ${t}`}:{ok:!1,error:`Server returned HTTP ${E.status} with non-JSON body: ${t}`}}return normalizeResponse(E,D)}function parseRenameCollidingPairs(e){return Array.isArray(e)?e.flatMap(e=>{if(!e||typeof e!=`object`)return[];let{existing:t,incoming:S,to:w}=e;return typeof t==`string`&&typeof S==`string`&&typeof w==`string`?[{existing:t,incoming:S,to:w}]:[]}):[]}function mergeCascade(e,t){let S={...e},w=new Map;for(let[e,E]of Object.entries(t))if(E!==void 0)if(Array.isArray(E)){let t=Array.isArray(S[e])?[...S[e]]:[],D=w.get(e)??new Set(t.map(toDedupKey));w.set(e,D);for(let e of E){let S=toDedupKey(e);D.has(S)||(D.add(S),t.push(e))}S[e]=t}else S[e]=E;return S}function mergePatch(e,t){let S={...e};for(let[e,w]of Object.entries(t))if(w!==void 0){if(isEmpty$1(w)){delete S[e];continue}S[e]=w}return S}function isEmpty$1(e){return!!(e===null||typeof e==`string`&&e===``||Array.isArray(e)&&e.length===0)}function toDedupKey(e){return typeof e==`string`?`s:${e}`:typeof e==`number`?`n:${e}`:typeof e==`boolean`?`b:${e}`:e===null?`null`:e===void 0?`undefined`:`j:${JSON.stringify(e)}`}function resolveNestedFrontmatter(e,t){return resolveNestedFrontmatterWithSources(e,t).merged}function resolveNestedFrontmatterWithSources(e,t){let S=t.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``),w=S===``||S===`.`?[]:S.split(`/`).filter(e=>e.length>0),E={},D={},O=!1;for(let t=0;t<=w.length;t++){let S=t===0?``:w.slice(0,t).join(`/`),k=t===0?resolve(e,`.ok`,`frontmatter.yml`):resolve(e,S,`.ok`,`frontmatter.yml`);if(!existsSync(k))continue;let j=readFrontmatterYaml(k);if(j!=null){E=mergeCascade(E,j);for(let e of Object.keys(j))j[e]!==void 0&&(D[e]=S);O=!0}}return O?{merged:coerceWellKnown(E),sources:D}:{merged:{},sources:{}}}function coerceWellKnown(e){let t={};for(let[S,w]of Object.entries(e))t[S]=w;return typeof e.title==`string`?t.title=e.title:delete t.title,typeof e.description==`string`?t.description=e.description:delete t.description,Array.isArray(e.tags)?t.tags=e.tags.filter(e=>typeof e==`string`):delete t.tags,t}const warnedPaths=new Set;function readFrontmatterYaml(e){let t;try{t=readFileSync(e,`utf-8`)}catch{return null}let S;try{S=(0,import_dist$1.parse)(t)}catch(t){if(!warnedPaths.has(e)){warnedPaths.add(e);let S=t instanceof Error?t.message:String(t);console.warn(`[ok-folder-frontmatter] malformed YAML at ${e} — folder defaults skipped. Fix the file or delete it. Reason: ${S}`)}return null}return typeof S!=`object`||!S||Array.isArray(S)?null:S}function parentFolderOf(e){let t=e.lastIndexOf(`/`);return t===-1?``:e.slice(0,t)}const GIT_TIMEOUT_MS$2=5e3;function projectHasGitDir(e){try{return statSync(resolve(e,`.git`)).isDirectory()}catch{return!1}}function openProjectGit(e){return esm_default({baseDir:resolve(e),timeout:{block:GIT_TIMEOUT_MS$2}})}async function readProjectGitLog(e,t,S=5){if(!projectHasGitDir(e))return{commits:[],source:`git-absent`};let w=openProjectGit(e),E=``;try{E=await w.raw(`log`,`-${Math.max(1,S)}`,`--format=%H|%aI|%an|%s`,`--follow`,`--`,t)}catch{return{commits:[],source:`git`}}let D=[];for(let e of E.split(`
|
|
1184
1184
|
`)){if(!e)continue;let t=e.indexOf(`|`);if(t<0)continue;let S=e.indexOf(`|`,t+1);if(S<0)continue;let w=e.indexOf(`|`,S+1);w<0||D.push({hash:e.slice(0,t),date:e.slice(t+1,S),authorName:e.slice(S+1,w),subject:e.slice(w+1)})}return{commits:D,source:`git`}}const GIT_TIMEOUT_MS$1=5e3;async function currentProjectBranch(e){try{let t=(await esm_default({baseDir:e,timeout:{block:GIT_TIMEOUT_MS$1}}).revparse([`--abbrev-ref`,`HEAD`])).trim();return t&&t!==`HEAD`?t:null}catch{return null}}function openShadowGit(e,t){return esm_default({baseDir:t,timeout:{block:GIT_TIMEOUT_MS$1}}).env({GIT_DIR:e,GIT_WORK_TREE:t})}function writerIdFromRef(e,t){let S=getWipRefPattern(t);return e.startsWith(S)?e.slice(S.length):e}async function logOnRef(e,t,S,w,E){let D=``;try{D=await e.raw(`log`,t,`-${Math.max(1,E*2)}`,`--format=%H%x00%aI%x00%an%x00%s%x00%B%x1e`,`--`,S)}catch{return[]}let O=writerIdFromRef(t,w),k=parseWriterId(O),j=[];for(let e of D.split(``)){let t=e.trimStart();if(!t)continue;let[S=``,E=``,D=``,F=``,L=``]=t.split(`\0`),B=S.trim();B.length===40&&j.push({hash:B,date:E,writerName:D,message:F,contributors:readContributors(L),writerId:O,isAgent:k.isAgent,writerClassification:k.classification,branch:w})}return j}async function readShadowLog(e,t,S=5){let w=getShadowRepoPath(e);if(!w)return{commits:[],source:`shadow-repo-absent`};let E=await currentProjectBranch(e);if(!E)return{commits:[],source:`shadow-repo`};let D=openShadowGit(w,resolve(e)),O=``;try{O=await D.raw(`for-each-ref`,getWipRefPattern(E),`--format=%(refname)`)}catch{return{commits:[],source:`shadow-repo`}}let k=O.split(`
|
|
1185
|
-
`).map(e=>e.trim()).filter(Boolean);return k.length===0?{commits:[],source:`shadow-repo`}:{commits:(await Promise.all(k.map(e=>logOnRef(D,e,t,E,S)))).flat().sort((e,t)=>t.date.localeCompare(e.date)).slice(0,S),source:`shadow-repo`}}function resolveTemplatesAvailable(e,t,S={}){let w=normalizeFolderPath(t),E=w===``?[]:w.split(`/`),D=new Set,O=[];collectFromFolder(e,w,`local`,D,O);for(let t=E.length-1;t>=1;t--)collectFromFolder(e,E.slice(0,t).join(`/`),`inherited`,D,O);return E.length>0&&collectFromFolder(e,``,`inherited`,D,O),O}function collectFromFolder(e,t,S,w,E){let D=t?join(e,t,`.ok`,`templates`):join(e,`.ok`,`templates`);if(!existsSync(D))return;let O;try{O=readdirSync(D)}catch{return}for(let e of O){if(!e.endsWith(`.md`))continue;let O=e.slice(0,-3);if(w.has(O))continue;let k=join(D,e),j;try{j=statSync(k)}catch{continue}if(!j.isFile())continue;let F=readTemplateMeta(k),L={name:O,path:t?posix.join(t,`.ok`,`templates`,e):posix.join(`.ok`,`templates`,e),source_folder:t,scope:S};F.title!==void 0&&(L.title=F.title),F.description!==void 0&&(L.description=F.description),w.add(O),E.push(L)}}function normalizeFolderPath(e){return e.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``).replace(/^\.$/,``)}const templateMetaWarnedPaths=new Set;function readTemplateMeta(e){let t;try{t=readFileSync(e,`utf-8`)}catch(t){if(t?.code!==`ENOENT`&&!templateMetaWarnedPaths.has(e)){templateMetaWarnedPaths.add(e);let S=t instanceof Error?t.message:String(t);console.warn(`[ok-templates] failed to read template at ${e} — metadata skipped. Reason: ${S}`)}return{}}let S=extractFrontmatterYaml(t);if(S===null)return{};let w;try{w=(0,import_dist$1.parse)(S)}catch(t){if(!templateMetaWarnedPaths.has(e)){templateMetaWarnedPaths.add(e);let S=t instanceof Error?t.message:String(t);console.warn(`[ok-templates] malformed YAML frontmatter at ${e} — title/description unavailable. Reason: ${S}`)}return{}}if(typeof w!=`object`||!w)return{};let E=w,D={};return typeof E.title==`string`&&(D.title=E.title),typeof E.description==`string`&&(D.description=E.description),D}function extractFrontmatterYaml(e){let t=e.replace(/^/,``),S=/^[ \t]*---\r?\n([\s\S]*?)\r?\n[ \t]*---(\r?\n|$)/.exec(t);return S?S[1]??null:null}const FRONTMATTER_RE=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;function parseFrontmatterRaw(e){let t=e.match(FRONTMATTER_RE);if(!t)return null;try{let e=(0,import_dist$1.parse)(t[1]);if(typeof e==`object`&&e&&!Array.isArray(e))return e}catch{}return null}const DIRECTORY_SCAN_CAP=1e3,DIR_SKIP=new Set([`.git`,`.ok`,`node_modules`,`.changeset`,`.claude`,`.agents`,`dist`,`build`]),WIKI_EXT_RE=/\.(md|mdx)$/i;function pathToDocName$1(e){return e.replace(/\.md$/,``).replace(/\.mdx$/,``)}const fmReadWarnedPaths=new Set;async function readFrontmatter(e){try{return parseFrontmatterRaw(await readFile$1(e,`utf-8`))??{}}catch(t){if(t?.code!==`ENOENT`&&!fmReadWarnedPaths.has(e)){fmReadWarnedPaths.add(e);let S=t instanceof Error?t.message:String(t);console.warn(`[ok-enrich] failed to read frontmatter at ${e} — enrichment degraded for this file. Reason: ${S}`)}return null}}async function fetchBacklinks(e,t){if(!e)return null;let S=await httpGet(e,`/api/backlinks?docName=${encodeURIComponent(t)}`);if(!S.ok)return null;let w=S.backlinks??S.results??S.links;if(!Array.isArray(w))return[];let E=[];for(let e of w){if(typeof e!=`object`||!e)continue;let t=e,S=typeof t.docName==`string`?t.docName:typeof t.source==`string`?t.source:typeof t.page==`string`?t.page:void 0;S&&E.push({source:S,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null})}return E}const BACKLINK_COUNT_CHUNK=100;async function fetchBacklinkCountsBatch(e,t){if(!e||t.length===0)return null;let S=[...new Set(t)],w=[];for(let e=0;e<S.length;e+=BACKLINK_COUNT_CHUNK)w.push(S.slice(e,e+BACKLINK_COUNT_CHUNK));let E=await Promise.all(w.map(async t=>{let S=await httpGet(e,`/api/backlink-counts?docNames=${encodeURIComponent(t.join(`,`))}`);return S.ok?S.counts??{}:null})),D=new Map,O=!1;for(let e of E)if(e){O=!0;for(let[t,S]of Object.entries(e))typeof S==`number`&&Number.isFinite(S)&&D.set(t,S)}return O?D:null}async function fetchForwardLinks(e,t){if(!e)return null;let S=await httpGet(e,`/api/forward-links?docName=${encodeURIComponent(t)}`);if(!S.ok)return null;let w=S.forwardLinks??S.links??S.results;if(!Array.isArray(w))return[];let E=[];for(let e of w){if(typeof e!=`object`||!e)continue;let t=e;if(t.kind===`external`&&typeof t.url==`string`){E.push({kind:`external`,url:t.url,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null});continue}let S=typeof t.docName==`string`?t.docName:void 0;S&&E.push({kind:`doc`,docName:S,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null})}return E}function mergeFileAndFolder(e,t,S){let w=mergeCascade(S?resolveNestedFrontmatter(S,parentFolderOf(t)):{},e??{});return{title:typeof w.title==`string`?w.title:void 0,description:typeof w.description==`string`?w.description:void 0,tags:Array.isArray(w.tags)?w.tags.filter(e=>typeof e==`string`):[],frontmatter:w}}async function enrichPath(e,t,S={}){let w=resolveWithinRoot(t.projectDir,e);if(!w.ok)throw Error(`enrichPath: ${w.reason}`);let E=w.rel,D=w.abs,O=t.historyDepth??5,k=S.includeRichFields===!0,j=readFrontmatter(D);if(!k){let e=mergeFileAndFolder(await j,E,t.projectDir);return{path:E,title:e.title,description:e.description,tags:e.tags,frontmatter:e.frontmatter,backlinkCount:null,backlinks:null,forwardLinkCount:null,forwardLinks:null,history:null,historySource:null,projectHistory:null,projectHistorySource:null}}let[F,L,B,H,q]=await Promise.all([j,fetchBacklinks(t.serverUrl,pathToDocName$1(E)).catch(()=>null),fetchForwardLinks(t.serverUrl,pathToDocName$1(E)).catch(()=>null),readShadowLog(t.projectDir,E,O).catch(()=>({commits:[],source:`shadow-repo`})),readProjectGitLog(t.projectDir,E,O).catch(()=>({commits:[],source:`git`}))]),J=mergeFileAndFolder(F,E,t.projectDir);return{path:E,title:J.title,description:J.description,tags:J.tags,frontmatter:J.frontmatter,backlinkCount:L?.length??null,backlinks:L,forwardLinkCount:B?.length??null,forwardLinks:B,history:H.commits,historySource:H.source,projectHistory:q.commits,projectHistorySource:q.source}}async function scanDirectory(e,t){let S={directMdCount:0,recursiveMdCount:0,childDirCount:0,mostRecent:null,truncated:!1},w=0,E=[{path:e,depth:0}];for(;E.length>0;){let e=E.shift();if(!e)break;if(w>=DIRECTORY_SCAN_CAP){S.truncated=!0;break}let D;try{D=await readdir(e.path,{withFileTypes:!0})}catch{continue}for(let O of D){if(w>=DIRECTORY_SCAN_CAP){S.truncated=!0;break}w++;let D=O.name;if(O.isDirectory()){if(DIR_SKIP.has(D)||D.startsWith(`.`))continue;e.depth===0&&S.childDirCount++,E.push({path:`${e.path}/${D}`,depth:e.depth+1})}else if(O.isFile()&&WIKI_EXT_RE.test(D)){S.recursiveMdCount++,e.depth===0&&S.directMdCount++;let w=`${e.path}/${D}`;try{let e=await stat$1(w);(!S.mostRecent||e.mtimeMs>S.mostRecent.mtimeMs)&&(S.mostRecent={absPath:w,relPath:relative(t,w).split(/[\\/]/).filter(Boolean).join(`/`),mtimeMs:e.mtimeMs})}catch{}}}}return S}async function enrichDirectory(e,t){let S=resolveWithinRoot(t.projectDir,e);if(!S.ok)throw Error(`enrichDirectory: ${S.reason}`);let w=S.rel,E=S.abs,D=await scanDirectory(E,t.projectDir),O;if(D.mostRecent){let e=await readFrontmatter(D.mostRecent.absPath),t=typeof e?.title==`string`?e.title:void 0;O={path:D.mostRecent.relPath,title:t??basename(D.mostRecent.relPath),updatedAt:new Date(D.mostRecent.mtimeMs).toISOString()}}let k={path:w,type:`directory`,directMdCount:D.directMdCount,recursiveMdCount:D.recursiveMdCount,childDirCount:D.childDirCount,mostRecentMd:O,truncated:D.truncated},j=resolveNestedFrontmatter(t.projectDir,w),F=j.title,L=j.description,B=j.tags??[];F!==void 0&&(k.title=F),L!==void 0&&(k.description=L),B.length>0&&(k.tags=B),Object.keys(j).length>0&&(k.frontmatter_defaults=j);let H=resolveTemplatesAvailable(t.projectDir,w);return H.length>0&&(k.templates_available=H),k}async function enrichDirectoryRecursive(e,t,S){let w=await enrichDirectory(e,S);if(t<=1)return w;let E=w.path,D=resolve(S.projectDir,E),O;try{O=await readdir(D,{withFileTypes:!0})}catch{return w}let k=[];for(let e of O){if(!e.isDirectory()||RECURSIVE_LISTING_SKIP_DIRS.has(e.name)||e.name.startsWith(`.`))continue;let w=await enrichDirectoryRecursive(E?`${E}/${e.name}`:e.name,t-1,S);k.push(w)}return k.length>0&&(w.subfolders=k),w}const RECURSIVE_LISTING_SKIP_DIRS=new Set([`.git`,`.ok`,`node_modules`,`.venv`,`venv`,`env`,`__pycache__`,`vendor`,`dist`,`build`,`out`,`output`,`.next`,`.nuxt`,`.svelte-kit`,`.astro`,`.turbo`,`.cache`,`.parcel-cache`,`coverage`]);function applyNestedFolderRulesUpsert(e){if(!isAbsolute(e.projectDir))return{ok:!1,error:{code:`BAD_PROJECT_DIR`,message:`projectDir must be absolute`}};let t=[];for(let S of e.rules){let w=resolveTargetFolderFromMatch(S.new_match??S.match);if(!w.ok)return{ok:!1,error:{code:`MULTI_FOLDER_GLOB`,message:w.message,rule:S.match}};let E=w.folder?resolve(e.projectDir,w.folder):e.projectDir,D=resolve(e.projectDir);if(!E.startsWith(D+sep)&&E!==D)return{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved target folder escapes projectDir: ${E}`,rule:S.match}};let O=null,k=null;if(S.new_match!==void 0&&S.new_match!==S.match){let t=resolveTargetFolderFromMatch(S.match);if(!t.ok)return{ok:!1,error:{code:`MULTI_FOLDER_GLOB`,message:t.message,rule:S.match}};if(O=t.folder,k=t.folder?resolve(e.projectDir,t.folder):e.projectDir,!k.startsWith(D+sep)&&k!==D)return{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved source folder escapes projectDir: ${k}`,rule:S.match}}}t.push({targetFolder:w.folder,targetAbs:E,sourceFolder:O,sourceAbs:k,rule:S})}let S=[];for(let w of t)try{if(w.sourceAbs&&w.sourceAbs!==w.targetAbs){let t=join(w.sourceAbs,`.ok`,`frontmatter.yml`);existsSync(t)&&(unlinkSync(t),autoCleanOkDir(join(w.sourceAbs,`.ok`)),S.push({match:w.rule.match,path:relPathOf$1(e.projectDir,t),action:`deleted`}))}let t=join(w.targetAbs,`.ok`),E=join(t,`frontmatter.yml`),D=readExistingFrontmatter(E),O=Object.keys(w.rule.frontmatter).length===0?{}:mergePatch(D,w.rule.frontmatter);if(Object.keys(O).length===0){existsSync(E)&&(unlinkSync(E),autoCleanOkDir(t),S.push({match:w.rule.new_match??w.rule.match,path:relPathOf$1(e.projectDir,E),action:`deleted`}));continue}mkdirSync(t,{recursive:!0});let k=(0,import_dist$1.stringify)(O),j=`${E}.tmp.${process.pid}.${Date.now()}`;writeFileSync(j,k,`utf-8`),renameSync(j,E),S.push({match:w.rule.new_match??w.rule.match,path:relPathOf$1(e.projectDir,E),action:`written`})}catch(e){return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to write nested frontmatter for ${w.rule.match}: ${e.message}`,rule:w.rule.match},...S.length>0?{partiallyApplied:S}:{}}}return{ok:!0,applied:S}}function resolveTargetFolderFromMatch(e){let t=e.split(`/`).filter(e=>e.length>0),S=[],w=!1;for(let E of t){let t=/[*?[\]{}]/.test(E);if(w&&!t)return{ok:!1,message:`Glob "${e}" matches multiple folders (literal segment "${E}" appears after a glob). Split it into one rule per folder, e.g. set_folder_rule({ rules: [{ match: "specs/foo/${E}/**", ... }, ...] }).`};if(t){if(w=!0,E!==`**`&&E!==`*`)return{ok:!1,message:`Glob "${e}" uses an unsupported pattern segment "${E}". Only "*" and "**" are supported in nested folder rules.`};continue}S.push(E)}return{ok:!0,folder:S.join(`/`)}}function readExistingFrontmatter(e){if(!existsSync(e))return{};let t=(0,import_dist$1.parse)(readFileSync(e,`utf-8`));return typeof t!=`object`||!t||Array.isArray(t)?{}:{...t}}function autoCleanOkDir(e){if(!existsSync(e))return;let t;try{t=readdirSync(e)}catch{return}if(t.length===0)try{rmdirSync(e)}catch{}}function relPathOf$1(e,t){let S=resolve(e);return t.startsWith(S+sep)?t.slice(S.length+1).split(sep).join(`/`):t}const SUBSTITUTION_ALLOWLIST=[`date`,`user`],TOKEN_PATTERN=/\{\{([^{}\n]+?)\}\}/g;function validateSubstitution(e){let t=[];for(let S of e.matchAll(TOKEN_PATTERN)){let e=(S[1]??``).trim();isAllowedToken(e)||t.push({token:e,offset:S.index??0})}return t}function applySubstitution(e,t){return e.replace(TOKEN_PATTERN,(e,S)=>{let w=S.trim();return isAllowedToken(w)?t[w]:e})}function isAllowedToken(e){return SUBSTITUTION_ALLOWLIST.includes(e)}function todayIsoUtc(e=new Date){return`${e.getUTCFullYear().toString().padStart(4,`0`)}-${(e.getUTCMonth()+1).toString().padStart(2,`0`)}-${e.getUTCDate().toString().padStart(2,`0`)}`}const NAME_RE=/^[A-Za-z0-9_-]+$/;function applyTemplateWrite(e){let t=validateInputs(e.projectDir,e.folder,e.name);if(!t.ok)return{ok:!1,error:t.error};let S=validateTitle(e.frontmatter.title);if(!S.ok)return{ok:!1,error:S.error};let w=validateSubstitutionAllowlist(e.body);if(!w.ok)return{ok:!1,error:w.error};let{templatesDir:E,filePath:D}=templatePaths(e.projectDir,t.folderRel,e.name),O=serializeFrontmatter(e.frontmatter),k=O?`---\n${O}---\n${e.body}`:e.body;try{mkdirSync(E,{recursive:!0})}catch(t){return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to create template directory at ${relPathOf(e.projectDir,E)}: ${t.message}`}}}let j=!existsSync(D),F=`${D}.tmp.${process.pid}.${Date.now()}`;try{writeFileSync(F,k,`utf-8`),renameSync(F,D)}catch(t){try{unlinkSync(F)}catch{}return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to write template at ${relPathOf(e.projectDir,D)}: ${t.message}`}}}let L=[];return(e.frontmatter.description===void 0||typeof e.frontmatter.description!=`string`||e.frontmatter.description.length===0)&&L.push("Template frontmatter.description is missing — `description` disambiguates between similarly-named templates in the menu. Recommended but not required."),{ok:!0,path:relPathOf(e.projectDir,D),created:j,warnings:L}}function applyTemplateDelete(e){let t=validateInputs(e.projectDir,e.folder,e.name);if(!t.ok)return{ok:!1,error:t.error};let{templatesDir:S,okDir:w,filePath:E}=templatePaths(e.projectDir,t.folderRel,e.name),D=existsSync(E);if(D)try{unlinkSync(E)}catch(t){return{ok:!1,error:{code:`UNLINK_FAILED`,message:`Failed to delete template at ${relPathOf(e.projectDir,E)}: ${t.message}`}}}let O=!1,k=!1;if(existsSync(S)&&isEmpty(S))try{rmdirSync(S),O=!0}catch{}if(existsSync(w)&&isEmpty(w))try{rmdirSync(w),k=!0}catch{}return{ok:!0,path:relPathOf(e.projectDir,E),existed:D,cleanedEmpty:{templatesDir:O,okDir:k}}}function validateInputs(e,t,S){if(!isAbsolute(e))return{ok:!1,error:{code:`BAD_PROJECT_DIR`,message:`projectDir must be absolute`}};if(!NAME_RE.test(S))return{ok:!1,error:{code:`BAD_NAME`,message:`Template name must match /^[A-Za-z0-9_-]+$/ (got: ${JSON.stringify(S)}). Use letters, digits, underscores, or hyphens — no slashes, dots, or spaces.`}};let w=t.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``).replace(/^\.$/,``);if(w.includes(`..`))return{ok:!1,error:{code:`PATH_TRAVERSAL`,message:`Folder path may not contain "..": ${JSON.stringify(t)}`}};let E=w?resolve(e,w):e,D=resolve(e);return!E.startsWith(D+sep)&&E!==D?{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved folder path escapes projectDir: ${E}`}}:{ok:!0,folderRel:w}}function validateTitle(e){return typeof e!=`string`||e.length===0?{ok:!1,error:{code:`TEMPLATE_TITLE_REQUIRED`,message:"Template frontmatter.title is required. `title` is the menu surface — agents pick templates by name+title; a title-less template is effectively invisible. Set a non-empty `title` and retry."}}:{ok:!0}}function validateSubstitutionAllowlist(e){let t=validateSubstitution(e);return t.length===0?{ok:!0}:{ok:!1,error:{code:`TEMPLATE_UNKNOWN_VARIABLE`,message:`Template body contains unknown substitution token(s): ${t.map(e=>`\`{{${e.token}}}\` at offset ${e.offset}`).join(`, `)}. v1 allowlist: \`{{date}}\`, \`{{user}}\`. Remove or rename the offending tokens and retry.`}}}function templatePaths(e,t,S){let w=t?join(e,t,`.ok`):join(e,`.ok`),E=join(w,`templates`);return{okDir:w,templatesDir:E,filePath:join(E,`${S}.md`)}}function relPathOf(e,t){return normalize(t.startsWith(e+sep)?t.slice(e.length+1):t).split(sep).join(`/`)}function serializeFrontmatter(e){let t={};return e.title!==void 0&&(t.title=e.title),e.description!==void 0&&(t.description=e.description),Array.isArray(e.tags)&&e.tags.length>0&&(t.tags=e.tags),Object.keys(t).length===0?``:(0,import_dist$1.stringify)(t)}function isEmpty(e){try{return readdirSync(e).length===0}catch{return!1}}const log$6=()=>getLogger(`http`);let _apiErrorCounter=null;function apiErrorCounter(){return _apiErrorCounter||=getMeter().createCounter(`ok.api.error.count`,{description:`API error responses by problem type and handler`,unit:`1`}),_apiErrorCounter}function errorResponse(e,t,S,w,E={}){let D=E.instance??`urn:uuid:${randomUUID()}`;if(e.headersSent||e.writableEnded||e.destroyed){log$6().error({event:`api.error.double-write`,instance:D,type:S,status:t,handler:E.handler},`errorResponse called after headers already sent — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...E.handler?{handler:E.handler}:{}});return}let O={type:S,title:w,status:t,instance:D,detail:E.detail??void 0},k=ProblemDetailsSchema.safeParse(O);if(!k.success){log$6().error({event:`api.error.malformed-envelope`,issues:k.error.issues,body:O,handler:E.handler,originalStatus:t},`errorResponse produced an invalid ProblemDetails body — emitting fallback`);let S=500;apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...E.handler?{handler:E.handler}:{}}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:D}));return}let j=E.extensions?{...E.extensions,...O}:O;apiErrorCounter().add(1,{type:S,...E.handler?{handler:E.handler}:{}});let F=t>=500?`error`:`warn`;log$6()[F]({event:`api.error`,instance:D,type:S,status:t,handler:E.handler,detail:E.detail,err:E.cause},w);let L;try{L=JSON.stringify(j)}catch(S){log$6().error({event:`api.error.unserializable-body`,bodyKeys:Object.keys(j),handler:E.handler,originalStatus:t,instance:D,err:S},`errorResponse wireBody is not JSON-serializable — emitting hardcoded fallback`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...E.handler?{handler:E.handler}:{}}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:D}));return}e.writeHead(t,{...E.extraHeaders,"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(L)}function streamingProblemEvent(e,t,S,w={}){let E=w.instance??`urn:uuid:${randomUUID()}`,D={type:`error`,problem:{type:t,title:S,status:e,instance:E,detail:w.detail??void 0}},O=StreamingProblemEventSchema.safeParse(D);if(!O.success){log$6().error({event:`api.streaming.malformed-envelope`,issues:O.error.issues,body:D,handler:w.handler,originalStatus:e},`streamingProblemEvent produced an invalid StreamingProblemEvent — returning fallback`);let t=500;return apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...w.handler?{handler:w.handler}:{}}),{type:`error`,problem:{type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:E}}}apiErrorCounter().add(1,{type:t,...w.handler?{handler:w.handler}:{}});let k=e>=500?`error`:`warn`;return log$6()[k]({event:`api.streaming.error`,instance:E,type:t,status:e,handler:w.handler,detail:w.detail,err:w.cause},S),D}function createStreamingErrorWriter(e,t){return(S,w,E,D={})=>{if(e.writableEnded||e.destroyed){log$6().error({event:`api.streaming.error.suppressed`,type:w,status:S,handler:t,detail:D.detail,err:D.cause},`createStreamingErrorWriter called after writableEnded/destroyed — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...t?{handler:t}:{}});return}let O=streamingProblemEvent(S,w,E,{handler:t,...D});try{e.write(`${JSON.stringify(O)}\n`)}catch(e){log$6().error({event:`api.streaming.error.write-failed`,type:w,status:S,handler:t,err:D.cause,writeErr:e},`createStreamingErrorWriter: res.write threw — original error preserved in log`)}}}const log$5=()=>getLogger(`http`);function successResponse(e,t,S,w,E={}){if(e.headersSent||e.writableEnded||e.destroyed){log$5().error({event:`api.success.double-write`,status:t,handler:E.handler},`successResponse called after headers already sent — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...E.handler?{handler:E.handler}:{}});return}let D=S.safeParse(w);if(!D.success){log$5().error({event:`api.success.malformed-body`,issues:D.error.issues,bodyKeys:typeof w==`object`&&w?Object.keys(w):null,handler:E.handler,originalStatus:t},`successResponse produced an invalid body for the supplied schema — emitting fallback`),errorResponse(e,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:E.handler});return}let O;try{O=JSON.stringify(D.data)}catch(S){log$5().error({event:`api.success.unserializable-body`,bodyKeys:typeof D.data==`object`&&D.data!==null?Object.keys(D.data):null,handler:E.handler,originalStatus:t,err:S},`successResponse parsed body is not JSON-serializable — emitting fallback`),errorResponse(e,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:E.handler});return}e.writeHead(t,{...E.extraHeaders,"Content-Type":`application/json`,"X-Content-Type-Options":`nosniff`}),e.end(O)}const INSTALLED_AGENTS_SCHEMES=[`claude`,`codex`,`cursor`],INSTALLED_AGENTS_PROBE_TIMEOUT_MS=2e3,MACOS_APP_NAMES={claude:[`Claude`],codex:[`Codex`,`OpenAI Codex`],cursor:[`Cursor`]};function createInstalledAgentsProbe(e){let t=new Map,S=e.now??Date.now,w=e.ttlMs??6e4;async function E(E){let D=t.get(E);if(D?.status===`resolved`&&D.expiresAt>S())return D.installed;if(D?.status===`inflight`)return D.promise;let O=(async()=>{try{let D=await e.probe(E);return t.set(E,{status:`resolved`,installed:D,expiresAt:S()+w}),D}catch{return t.set(E,{status:`resolved`,installed:!1,expiresAt:S()+w}),!1}})();return t.set(E,{status:`inflight`,promise:O}),O}async function D(){let e=await Promise.all(INSTALLED_AGENTS_SCHEMES.map(async e=>[e,await E(e)]));return Object.fromEntries(e)}return{probeAll:D,probeWithCache:E}}function isLocalWebHost(e){let t=e.headers.host;if(typeof t==`string`&&t.length>0)try{let{hostname:e}=new URL(`http://${t}/`);return isLoopbackHostname(e)}catch{}let S=e.headers.origin;if(typeof S==`string`&&S.length>0)try{return isLoopbackHostname(new URL(S).hostname)}catch{return!1}return!0}function isLoopbackHostname(e){return e===`localhost`||e===`127.0.0.1`||e===`[::1]`||e===`::1`}async function handleInstalledAgents(e,t,S){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`installed-agents`,extraHeaders:{Allow:`GET`}});return}try{successResponse(t,200,InstalledAgentsSuccessSchema,isLocalWebHost(e)?await S():Object.fromEntries(INSTALLED_AGENTS_SCHEMES.map(e=>[e,!0])),{handler:`installed-agents`})}catch(e){console.error(`[installed-agents]`,e),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`installed-agents`,cause:e})}}function createOsProbe(e,t=execFile){return S=>e===`darwin`?probeMacOs(S,t):e===`win32`?probeWindows(S,t):probeLinux(S,t)}function probeMacOs(e,t){let S=MACOS_APP_NAMES[e];function w(e){return new Promise(S=>{t(`osascript`,[`-e`,`id of app "${e}"`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},(e,t)=>{if(e){S(!1);return}S(t.trim().length>0)})})}return(async()=>{for(let e of S)if(await w(e))return!0;return!1})()}function probeWindows(e,t){return new Promise(S=>{t(`reg`,[`query`,`HKCR\\${e}`,`/ve`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},e=>{S(!e)})})}function probeLinux(e,t){return new Promise(S=>{t(`xdg-mime`,[`query`,`default`,`x-scheme-handler/${e}`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},(e,t)=>{if(e){S(!1);return}S(t.trim().length>0)})})}const MAX_BODY_BYTES=1048576,REQUEST_BODY_TIMEOUT_MS=3e4;function readRequestBody(e){return readBoundedJsonBody(e,{maxBytes:MAX_BODY_BYTES,timeoutMs:REQUEST_BODY_TIMEOUT_MS})}async function readBoundedJsonBody(e,t){let S=[],w=0,E=AbortSignal.timeout(t.timeoutMs),D=()=>e.destroy(new RequestBodyTimeoutError(t.timeoutMs));E.addEventListener(`abort`,D,{once:!0});try{for await(let E of e){if(w+=E.length,w>t.maxBytes)throw new PayloadTooLargeError(t.maxBytes);S.push(E)}return Buffer.concat(S)}finally{E.removeEventListener(`abort`,D)}}var PayloadTooLargeError=class extends Error{maxBytes;constructor(e){super(e===void 0?`Request body exceeded cap`:`Request body exceeded ${formatBytes(e)} cap`),this.name=`PayloadTooLargeError`,this.maxBytes=e}},RequestBodyTimeoutError=class extends Error{timeoutMs;constructor(e){super(e===void 0?`Request body read exceeded timeout`:`Request body read exceeded ${e}ms timeout`),this.name=`RequestBodyTimeoutError`,this.timeoutMs=e}};function formatBytes(e){return e>=1048576?`${(e/1048576).toFixed(0)} MB`:e>=1024?`${(e/1024).toFixed(0)} KB`:`${e} B`}function validateBody(e,t,S,w={}){let E=e.safeParse(t);if(E.success)return{ok:!0,value:E.data};let D=E.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `);return errorResponse(S,400,`urn:ok:error:invalid-request`,`Request body is invalid.`,{handler:w.handler,detail:D}),{ok:!1}}function withValidation(e,t,S={}){return async(w,E)=>{if(S.method!==void 0&&w.method!==S.method){errorResponse(E,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:S.handler,extraHeaders:{Allow:S.method}});return}if(S.preBodyGate!==void 0&&!S.preBodyGate(w,E)){!E.headersSent&&!E.writableEnded&&!E.destroyed&&errorResponse(E,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:S.handler,cause:Error(`preBodyGate returned false without writing a response`)});return}if(S.skipBodyParse){let D=validateBody(e,{},E,S);if(!D.ok)return;await t(w,E,D.value);return}let D;try{D=await readRequestBody(w)}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(E,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:S.handler,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(E,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:S.handler,cause:e});return}errorResponse(E,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:S.handler,cause:e});return}let O;try{O=D.length===0?{}:JSON.parse(D.toString(`utf8`))}catch(e){errorResponse(E,400,`urn:ok:error:invalid-request`,`Request body is not valid JSON.`,{handler:S.handler,cause:e});return}let k=validateBody(e,O,E,S);k.ok&&await t(w,E,k.value)}}function classifySpawnError(e){let t=e instanceof Error?e.message:String(e);return/ENOENT|EACCES|EPERM/.test(t)?{ok:!1,reason:`not-installed`}:{ok:!1,reason:`spawn-error`}}function spawnDetached(e,t,S){return new Promise(w=>{let E=!1,D=e=>{E||(E=!0,w(e))},O=setTimeout(()=>D({ok:!1,reason:`timeout`}),S);try{let S=spawn(e,[...t],{detached:!0,stdio:`ignore`,shell:!1});S.once(`error`,e=>{clearTimeout(O),D(classifySpawnError(e))}),S.once(`spawn`,()=>{if(!E){try{S.unref()}catch{}clearTimeout(O),D({ok:!0})}})}catch(e){console.warn(`[spawn-detached] synchronous spawn throw:`,e),clearTimeout(O),D(classifySpawnError(e))}})}const SPAWN_CURSOR_WHICH_TIMEOUT_MS=500,SPAWN_CURSOR_SPAWN_TIMEOUT_MS=2e3,SPAWN_CURSOR_MAX_BODY_BYTES=4*1024,SPAWN_CURSOR_BODY_READ_TIMEOUT_MS=5e3,HANDLER$1=`spawn-cursor`;function assertNeverSpawnReason(e){throw Error(`Unhandled spawn-cursor outcome.reason: ${String(e)}`)}async function handleSpawnCursor(e,t,S){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:HANDLER$1,extraHeaders:{Allow:`POST`}});return}let w;try{w=await readBoundedJsonBody(e,{maxBytes:SPAWN_CURSOR_MAX_BODY_BYTES,timeoutMs:SPAWN_CURSOR_BODY_READ_TIMEOUT_MS})}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(t,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:HANDLER$1,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(t,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:HANDLER$1,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:HANDLER$1,cause:e});return}let E;try{E=JSON.parse(w.toString(`utf-8`))}catch(e){errorResponse(t,400,`urn:ok:error:invalid-request`,`Malformed JSON body.`,{handler:HANDLER$1,cause:e});return}let D=typeof E.path==`string`?E.path:``;if(!D){errorResponse(t,400,`urn:ok:error:invalid-request`,"Missing or empty `path` field.",{handler:HANDLER$1});return}if(!isPathWithinDir(D,S.contentDir,S.platform)){errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER$1});return}let O=await(S.resolveCursorBinary??resolveCursorBinaryDefault)(SPAWN_CURSOR_WHICH_TIMEOUT_MS);if(!O){errorResponse(t,422,`urn:ok:error:cursor-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER$1});return}let k=resolveCursorSpawnInvocation(O,D,S.platform),j=await(S.spawnDetached??spawnDetached)(k.exec,k.args,SPAWN_CURSOR_SPAWN_TIMEOUT_MS);if(j.ok){successResponse(t,200,SpawnCursorSuccessSchema,{},{handler:HANDLER$1});return}switch(j.reason){case`not-installed`:errorResponse(t,422,`urn:ok:error:cursor-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER$1});return;case`timeout`:errorResponse(t,504,`urn:ok:error:cursor-spawn-timeout`,`Cursor spawn exceeded the deadline.`,{handler:HANDLER$1});return;case`spawn-error`:errorResponse(t,502,`urn:ok:error:cursor-spawn-failed`,`Cursor spawn failed.`,{handler:HANDLER$1});return;case`invalid-path`:errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER$1});return;default:return assertNeverSpawnReason(j.reason)}}const CURSOR_BUNDLE_PATHS_BY_PLATFORM={darwin:[()=>`/Applications/Cursor.app/Contents/Resources/app/bin/cursor`,e=>`${e}/Applications/Cursor.app/Contents/Resources/app/bin/cursor`],win32:[e=>`${e}\\AppData\\Local\\Programs\\cursor\\resources\\app\\bin\\cursor.cmd`,()=>`C:\\Program Files\\Cursor\\resources\\app\\bin\\cursor.cmd`]};async function resolveCursorBinaryDefault(e){let t=CURSOR_BUNDLE_PATHS_BY_PLATFORM[process.platform];if(t&&t.length>0){let e=homedir();for(let S of t){let t=S(e);try{return await access(t,constants.X_OK),t}catch(e){let S=e?.code;S!==`ENOENT`&&S!==`EACCES`&&S!==`EPERM`&&console.warn(`[spawn-cursor] unexpected fs.access error on bundle probe:`,S,t)}}}return new Promise(t=>{execFile(process.platform===`win32`?`where`:`which`,[`cursor`],{timeout:e,encoding:`utf-8`},(e,S)=>{if(e){t(null);return}let w=S.split(/\r?\n/)[0]?.trim();t(w&&w.length>0?w:null)})})}function resolveCursorSpawnInvocation(e,t,S){return S===`darwin`&&/\.app\/?$/.test(e)?{exec:`/usr/bin/open`,args:[`-a`,e.replace(/\/$/,``),t]}:{exec:e,args:[t]}}function isPathWithinDir(e,t,S){if(!e||typeof e!=`string`||e.includes(`\0`)||!t||typeof t!=`string`)return!1;if(S===`win32`){if(!/^([a-zA-Z]:[\\/]|\\\\)/.test(e)||!/^([a-zA-Z]:[\\/]|\\\\)/.test(t))return!1}else if(!e.startsWith(`/`)||!t.startsWith(`/`))return!1;let w=S===`win32`?win32:posix;try{let E=w.resolve(e),D=w.resolve(t);if(S===`win32`){let e=w.parse(E).root.toLowerCase(),t=w.parse(D).root.toLowerCase();if(!e||!t||e!==t)return!1}if(E===D)return!0;let O=w.relative(D,E);return O===``||O===`.`?!0:!(O===`..`||O.startsWith(`..${w.sep}`)||S===`win32`&&(/^[a-zA-Z]:[\\/]/.test(O)||O.startsWith(`\\\\`))||S!==`win32`&&O.startsWith(`/`))}catch(e){return console.warn(`[spawn-cursor] unexpected path-resolution error:`,e),!1}}const HANDLER=`handoff`,HANDOFF_MAX_BODY_BYTES=4*1024,HANDOFF_BODY_READ_TIMEOUT_MS=5e3,SPAWN_TIMEOUT_MS=2e3,WHICH_TIMEOUT_MS=500,QUIT_SETTLE_MS=3e3,APP_BUNDLE_SETTLE_MS=5e3,CURSOR_SETTLE_MS=1500,RECIPES={"claude-cowork":{type:`app-bundle`,appName:`Claude`,urlScheme:`claude:`,quitFirst:!1},"claude-code":{type:`app-bundle`,appName:`Claude`,urlScheme:`claude:`,quitFirst:!1},codex:{type:`app-bundle`,appName:`Codex`,urlScheme:`codex:`,quitFirst:!0},cursor:{type:`cli-binary`,binaryName:`cursor`,urlScheme:`cursor:`}},TARGET_VALUES=Object.keys(RECIPES),HandoffRequestSchema=object$1({target:_enum(TARGET_VALUES),url:string$2().min(1).max(4096),workspacePath:string$2().optional()}),HandoffSuccessSchema=object$1({}).loose();function defaultSleep(e){return new Promise(t=>setTimeout(t,e))}async function handleHandoffDispatch(e,t,S){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:HANDLER,extraHeaders:{Allow:`POST`}});return}if(S.platform!==`darwin`){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Handoff is currently macOS-only.`,{handler:HANDLER});return}let w;try{w=await readBoundedJsonBody(e,{maxBytes:HANDOFF_MAX_BODY_BYTES,timeoutMs:HANDOFF_BODY_READ_TIMEOUT_MS})}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(t,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:HANDLER,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(t,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:HANDLER,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:HANDLER,cause:e});return}let E;try{E=JSON.parse(w.toString(`utf-8`))}catch(e){errorResponse(t,400,`urn:ok:error:invalid-request`,`Malformed JSON body.`,{handler:HANDLER,cause:e});return}let D=HandoffRequestSchema.safeParse(E);if(!D.success){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid request body.`,{handler:HANDLER});return}let{target:O,url:k,workspacePath:j}=D.data,F=RECIPES[O];if(!k.startsWith(F.urlScheme)){errorResponse(t,400,`urn:ok:error:invalid-request`,`URL scheme must be ${F.urlScheme} for target ${O}.`,{handler:HANDLER});return}let L=S.sleep??defaultSleep,B=S.spawnDetached??spawnDetached;if(F.type===`app-bundle`){F.quitFirst&&(await B(`/usr/bin/osascript`,[`-e`,`tell application "${F.appName}" to quit`],SPAWN_TIMEOUT_MS).catch(()=>void 0),await L(QUIT_SETTLE_MS));let e=await B(`/usr/bin/open`,[`-a`,F.appName],SPAWN_TIMEOUT_MS);if(!e.ok){emitSpawnFailure(t,O,e.reason);return}await L(APP_BUNDLE_SETTLE_MS);let S=await B(`/usr/bin/open`,[k],SPAWN_TIMEOUT_MS);if(!S.ok){emitSpawnFailure(t,O,S.reason);return}successResponse(t,200,HandoffSuccessSchema,{},{handler:HANDLER});return}if(!j){errorResponse(t,400,`urn:ok:error:invalid-request`,`workspacePath is required for cursor handoff.`,{handler:HANDLER});return}if(!isPathWithinDir(j,S.contentDir,S.platform)){errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER});return}let H=await(S.resolveCursorBinary??resolveCursorBinaryDefault)(WHICH_TIMEOUT_MS);if(!H){errorResponse(t,422,`urn:ok:error:handoff-target-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER,extensions:{target:`cursor`}});return}let q=resolveCursorSpawnInvocation(H,j,S.platform),J=await B(q.exec,q.args,SPAWN_TIMEOUT_MS);if(!J.ok){emitSpawnFailure(t,O,J.reason);return}await L(CURSOR_SETTLE_MS);let Y=await B(`/usr/bin/open`,[k],SPAWN_TIMEOUT_MS);if(!Y.ok){emitSpawnFailure(t,O,Y.reason);return}successResponse(t,200,HandoffSuccessSchema,{},{handler:HANDLER})}function emitSpawnFailure(e,t,S){switch(S){case`not-installed`:errorResponse(e,422,`urn:ok:error:handoff-target-not-installed`,`Required binary or application not found.`,{handler:HANDLER,extensions:{target:t}});return;case`timeout`:errorResponse(e,504,`urn:ok:error:handoff-spawn-timeout`,`Handoff spawn exceeded the deadline.`,{handler:HANDLER,extensions:{target:t}});return;case`spawn-error`:errorResponse(e,502,`urn:ok:error:handoff-spawn-failed`,`Handoff spawn failed.`,{handler:HANDLER,extensions:{target:t}});return;default:assertNeverReason(S)}}function assertNeverReason(e){throw Error(`Unhandled spawn reason: ${String(e)}`)}const FIXED_HUB_BASENAMES=[`INDEX`,`README`,`REPORT`,`SPEC`],MAX_CANDIDATES=3;function findHubCandidates(e,t){let S=[],w=new Set,E=t=>{!t||w.has(t)||t!==e&&(w.add(t),S.push(t))},D=buildLowerDocNameIndex(t),O=parentFolder(e);for(;;){for(let e of FIXED_HUB_BASENAMES)if(E(lookup$1(t,D,joinDocName(O,e))),S.length>=MAX_CANDIDATES)return S;let e=O===``?null:basename$1(O);if(e&&(E(lookup$1(t,D,joinDocName(O,e))),S.length>=MAX_CANDIDATES))return S;if(O===``)break;O=parentFolder(O)}return S}function lookup$1(e,t,S){return e.has(S)?S:t.get(S.toLowerCase())??null}function buildLowerDocNameIndex(e){let t=new Map;for(let S of e.keys()){let e=S.toLowerCase();t.has(e)||t.set(e,S)}return t}function parentFolder(e){let t=e.lastIndexOf(`/`);return t<0?``:e.slice(0,t)}function basename$1(e){let t=e.lastIndexOf(`/`);return t<0?e:e.slice(t+1)}function joinDocName(e,t){return e===``?t:`${e}/${t}`}function splitFrontmatterLines(e){return e?e.replace(/^---\r?\n/,``).replace(/\r?\n---(?:\r?\n)?$/,``).split(/\r?\n/):[]}function normalizeFrontmatterScalar(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).trim():t}function extractFrontmatterScalar(e,t){let S=`${t}:`;for(let t of splitFrontmatterLines(e))if(t.startsWith(S))return normalizeFrontmatterScalar(t.slice(S.length))||null;return null}function parseInlineAliases(e){let t=[],S=``,w=null;for(let E of e){if(w){S+=E,E===w&&(w=null);continue}if(E===`"`||E===`'`){w=E,S+=E;continue}if(E===`,`){let e=normalizeFrontmatterScalar(S);e&&t.push(e),S=``;continue}S+=E}let E=normalizeFrontmatterScalar(S);return E&&t.push(E),t}function dedupeExact(e){let t=[],S=new Set;for(let w of e)!w||S.has(w)||(S.add(w),t.push(w));return t}function extractPageAliases(e){let{frontmatter:t}=stripFrontmatter(e);if(!t)return[];let S=splitFrontmatterLines(t);for(let e=0;e<S.length;e+=1){let t=S[e]?.match(/^aliases:\s*(.*)$/);if(!t)continue;let w=t[1]?.trim()??``;if(w){if(w.startsWith(`[`)&&w.endsWith(`]`))return dedupeExact(parseInlineAliases(w.slice(1,-1)));let e=normalizeFrontmatterScalar(w);return e?[e]:[]}let E=[];for(let t=e+1;t<S.length;t+=1){let e=S[t];if(e?.trim()){if(/^\s*-\s+/.test(e)){let t=normalizeFrontmatterScalar(e.replace(/^\s*-\s+/,``));t&&E.push(t);continue}if(/^[^\s][^:]*:\s*/.test(e))break;break}}return dedupeExact(E)}return[]}function extractPageTitle(e,t){let{frontmatter:S,body:w}=stripFrontmatter(e),E=extractFrontmatterScalar(S,`title`);if(E)return E;let D=w.match(/^# (.+)$/m);return D?D[1].trim():t}function parseFrontmatterMetadata(e){return e?.trim()?{cluster:extractFrontmatterScalar(e,`cluster`)??void 0,category:extractFrontmatterScalar(e,`category`)??void 0,tags:extractFrontmatterArray(e,`tags`)}:{cluster:void 0,category:void 0,tags:void 0}}function extractFrontmatterArray(e,t){let S=`${t}:`,w=splitFrontmatterLines(e);for(let e=0;e<w.length;e+=1){let t=w[e];if(!t?.startsWith(S))continue;let E=t.slice(S.length).trim();if(E){if(E.startsWith(`[`)&&E.endsWith(`]`)){let e=parseInlineAliases(E.slice(1,-1));return e.length>0?e:void 0}let e=normalizeFrontmatterScalar(E);return e?[e]:void 0}let D=[];for(let t=e+1;t<w.length;t+=1){let e=w[t];if(e?.trim()){if(/^\s*-\s+/.test(e)){let t=normalizeFrontmatterScalar(e.replace(/^\s*-\s+/,``));t&&D.push(t);continue}if(/^[^\s][^:]*:\s*/.test(e))break;break}}return D.length>0?D:void 0}}function extractPageIdentity(e,t){let S=extractPageTitle(e,t),w=extractPageAliases(e),E=dedupeExact([S,...w]),D=[],O=new Set;for(let e of E){let t=toWikiLinkSlug(e);!t||O.has(t)||(O.add(t),D.push(t))}return{docName:t,title:S,aliases:w,matchLabels:E,normalizedMatchLabels:D}}const SHARE_BASE_URL=`https://openknowledge.ai/d/`,SHARE_CONSTRUCT_URL_HANDLER_TAG=`share-construct-url`;function isValidShareDocPath(e){if(e.length===0||e.startsWith(`/`)||e.startsWith(`\\`))return!1;for(let t of e.split(/[/\\]/))if(t===`..`||t===`.git`||t.length===0)return!1;return!0}function buildGitHubBlobUrl(e,t,S,w){return`https://github.com/${e}/${t}/blob/${S.split(`/`).map(encodeURIComponent).join(`/`)}/${w.split(`/`).map(encodeURIComponent).join(`/`)}`}function emitShareConstructUrlLog(e,t){let S=t===void 0?``:` branch_exists=${t}`;console.log(`[share] action=construct-url result=${e}${S}`)}function resolveGitDir$1(e){let t=resolve(e,`.git`);if(!existsSync(t))return null;let S;try{S=statSync(t)}catch{return null}if(S.isDirectory())return t;if(S.isFile()){let S;try{S=readFileSync(t,`utf-8`)}catch{return null}let w=/^gitdir:\s*(.+)$/m.exec(S.trim());if(!w)return null;let E=w[1].trim(),D=isAbsolute(E)?E:resolve(e,E);return existsSync(D)?D:null}return null}function readGitHeadBranch(e){let t=resolveGitDir$1(e);if(!t)return null;let S=join(t,`HEAD`);if(!existsSync(S))return null;let w;try{w=readFileSync(S,`utf-8`)}catch{return null}let E=/^ref:\s*refs\/heads\/(.+)$/.exec(w.trim());return E?E[1]:null}function stripCommentAndTrim(e){let t=e.indexOf(`#`),S=e.indexOf(`;`),w=-1;return t>=0&&S>=0?w=Math.min(t,S):t>=0?w=t:S>=0&&(w=S),(w===-1?e:e.slice(0,w)).trim()}function extractOriginUrl(e){let t=!1;for(let S of e.split(/\r?\n/)){let e=stripCommentAndTrim(S);if(e.length===0)continue;if(e.startsWith(`[`)){t=/^\[\s*remote\s+["']origin["']\s*\]$/.test(e);continue}if(!t)continue;let w=/^url\s*=\s*(.+)$/.exec(e);if(!w)continue;let E=w[1].trim();if((E.startsWith(`"`)&&E.endsWith(`"`)||E.startsWith(`'`)&&E.endsWith(`'`))&&(E=E.slice(1,-1)),E.length>0)return E}return null}function parseGitHubOriginUrl(e){let t=e.trim();if(!t)return null;let S=/^https?:\/\/(?:www\.)?github\.com\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t);return S||(S=/^ssh:\/\/(?:[\w.-]+@)?github\.com(?::\d+)?\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t),S)||(S=/^[\w.-]+@github\.com:([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?$/.exec(t),S)||(S=/^git:\/\/github\.com\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t),S)?{owner:S[1],repo:S[2]}:null}function readOriginGitHubRepo(e){let t=resolveGitDir$1(e);if(!t)return{kind:`no-remote`};let S=join(t,`config`);if(!existsSync(S))return{kind:`no-remote`};let w;try{w=readFileSync(S,`utf-8`)}catch{return{kind:`no-remote`}}let E=extractOriginUrl(w);if(!E)return{kind:`no-remote`};let D=parseGitHubOriginUrl(E);return D?{kind:`ok`,owner:D.owner,repo:D.repo}:{kind:`non-github`}}function branchExistsOnOrigin(e,t){let S=resolveGitDir$1(e);if(!S)return!1;if(existsSync(join(S,`refs`,`remotes`,`origin`,t)))return!0;let w=join(S,`packed-refs`);if(!existsSync(w))return!1;let E;try{E=readFileSync(w,`utf-8`)}catch{return!1}let D=`refs/remotes/origin/${t}`;for(let e of E.split(/\r?\n/)){let t=e.trim();if(t.length===0||t.startsWith(`#`)||t.startsWith(`^`))continue;let S=t.split(/\s+/);if(S.length===2&&S[1]===D)return!0}return!1}const SHARE_PUBLISH_OWNERS_HANDLER_TAG=`share-publish-owners`,SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG=`share-publish-name-check`,SHARE_PUBLISH_HANDLER_TAG=`share-publish`,SHARE_PUBLISH_OWNERS_KEY=`/api/share/publish/owners`,SHARE_PUBLISH_NAME_CHECK_KEY=`/api/share/publish/name-check`,SHARE_PUBLISH_KEY=`/api/share/publish`,SHARE_PUBLISH_TIMEOUT_MS=3e4;function isValidShareRepoName(e){return e.length===0||e.length>100||e.startsWith(`.`)||e.startsWith(`-`)||/^-+$/.test(e)?!1:/^[A-Za-z0-9._-]+$/.test(e)}function isValidShareOwnerName(e){return e.length===0||e.length>39||e.startsWith(`-`)||e.endsWith(`-`)?!1:/^[A-Za-z0-9-]+$/.test(e)}function pickTerminalJsonLine(e){let t=e.split(`
|
|
1186
|
-
`).map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;e--)try{let S=JSON.parse(t[e]);if(S&&typeof S==`object`&&!Array.isArray(S))return S}catch{}return null}function parseOwnersEvent(e){if(e===null)return{ok:!1,error:`network`};if(e.type===`owners`&&Array.isArray(e.owners)){let t=[];for(let S of e.owners){if(!S||typeof S!=`object`)continue;let e=S,w=typeof e.login==`string`?e.login:null,E=e.kind===`user`||e.kind===`org`?e.kind:null;if(w===null||E===null)continue;let D=typeof e.avatarUrl==`string`?e.avatarUrl:void 0;t.push({login:w,kind:E,...D?{avatarUrl:D}:{}})}return{ok:!0,owners:t}}return e.type===`error`?{ok:!1,error:isOwnersErrorCode(e.code)?e.code:`network`}:{ok:!1,error:`network`}}function isOwnersErrorCode(e){return e===`auth-required`||e===`network`}function parseNameCheckEvent(e){return e===null?{ok:!1,error:`network`}:e.type===`name-check`&&typeof e.available==`boolean`?{ok:!0,available:e.available}:e.type===`error`?{ok:!1,error:isOwnersErrorCode(e.code)?e.code:`network`}:{ok:!1,error:`network`}}const PUBLISH_ERROR_CODES=new Set([`name-conflict`,`saml-sso`,`auth-required`,`push-failed`,`init-failed`,`network`,`no-project`]);function isPublishErrorCode(e){return typeof e==`string`&&PUBLISH_ERROR_CODES.has(e)}function parsePublishEvent(e){if(e===null)return{ok:!1,error:`network`};if(e.type===`publish`){let t=typeof e.ownerLogin==`string`?e.ownerLogin:null,S=typeof e.repoName==`string`?e.repoName:null,w=typeof e.cloneUrl==`string`?e.cloneUrl:null,E=typeof e.defaultBranch==`string`?e.defaultBranch:null;return t!==null&&S!==null&&w!==null&&E!==null?{ok:!0,ownerLogin:t,repoName:S,cloneUrl:w,defaultBranch:E}:{ok:!1,error:`network`}}return e.type===`error`?{ok:!1,error:isPublishErrorCode(e.code)?e.code:`network`}:{ok:!1,error:`network`}}function emitSharePublishLog(e,t,S){let w=[`action=${e}`,`result=${t}`];S?.count!==void 0&&w.push(`count=${S.count}`),S?.available!==void 0&&w.push(`available=${S.available}`),console.log(`[share] ${w.join(` `)}`)}function redactShareSubprocessStderr(e){return e.replace(/(https?:\/\/)([^:@\s/]+):([^@\s/]+)@/g,`$1$2:***@`)}const MAX_ZIP_BYTES=102400
|
|
1185
|
+
`).map(e=>e.trim()).filter(Boolean);return k.length===0?{commits:[],source:`shadow-repo`}:{commits:(await Promise.all(k.map(e=>logOnRef(D,e,t,E,S)))).flat().sort((e,t)=>t.date.localeCompare(e.date)).slice(0,S),source:`shadow-repo`}}function resolveTemplatesAvailable(e,t,S={}){let w=normalizeFolderPath(t),E=w===``?[]:w.split(`/`),D=new Set,O=[];collectFromFolder(e,w,`local`,D,O);for(let t=E.length-1;t>=1;t--)collectFromFolder(e,E.slice(0,t).join(`/`),`inherited`,D,O);return E.length>0&&collectFromFolder(e,``,`inherited`,D,O),O}function collectFromFolder(e,t,S,w,E){let D=t?join(e,t,`.ok`,`templates`):join(e,`.ok`,`templates`);if(!existsSync(D))return;let O;try{O=readdirSync(D)}catch{return}for(let e of O){if(!e.endsWith(`.md`))continue;let O=e.slice(0,-3);if(w.has(O))continue;let k=join(D,e),j;try{j=statSync(k)}catch{continue}if(!j.isFile())continue;let F=readTemplateMeta(k),L={name:O,path:t?posix.join(t,`.ok`,`templates`,e):posix.join(`.ok`,`templates`,e),source_folder:t,scope:S};F.title!==void 0&&(L.title=F.title),F.description!==void 0&&(L.description=F.description),w.add(O),E.push(L)}}function normalizeFolderPath(e){return e.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``).replace(/^\.$/,``)}const templateMetaWarnedPaths=new Set;function readTemplateMeta(e){let t;try{t=readFileSync(e,`utf-8`)}catch(t){if(t?.code!==`ENOENT`&&!templateMetaWarnedPaths.has(e)){templateMetaWarnedPaths.add(e);let S=t instanceof Error?t.message:String(t);console.warn(`[ok-templates] failed to read template at ${e} — metadata skipped. Reason: ${S}`)}return{}}let S=extractFrontmatterYaml(t);if(S===null)return{};let w;try{w=(0,import_dist$1.parse)(S)}catch(t){if(!templateMetaWarnedPaths.has(e)){templateMetaWarnedPaths.add(e);let S=t instanceof Error?t.message:String(t);console.warn(`[ok-templates] malformed YAML frontmatter at ${e} — title/description unavailable. Reason: ${S}`)}return{}}if(typeof w!=`object`||!w)return{};let E=w,D={};return typeof E.title==`string`&&(D.title=E.title),typeof E.description==`string`&&(D.description=E.description),D}function extractFrontmatterYaml(e){let t=e.replace(/^/,``),S=/^[ \t]*---\r?\n([\s\S]*?)\r?\n[ \t]*---(\r?\n|$)/.exec(t);return S?S[1]??null:null}const FRONTMATTER_RE=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;function parseFrontmatterRaw(e){let t=e.match(FRONTMATTER_RE);if(!t)return null;try{let e=(0,import_dist$1.parse)(t[1]);if(typeof e==`object`&&e&&!Array.isArray(e))return e}catch{}return null}const DIRECTORY_SCAN_CAP=1e3,DIR_SKIP=new Set([`.git`,`.ok`,`node_modules`,`.changeset`,`.claude`,`.agents`,`dist`,`build`]),WIKI_EXT_RE=/\.(md|mdx)$/i;function pathToDocName$1(e){return e.replace(/\.md$/,``).replace(/\.mdx$/,``)}const fmReadWarnedPaths=new Set;async function readFrontmatter(e){try{return parseFrontmatterRaw(await readFile$1(e,`utf-8`))??{}}catch(t){if(t?.code!==`ENOENT`&&!fmReadWarnedPaths.has(e)){fmReadWarnedPaths.add(e);let S=t instanceof Error?t.message:String(t);console.warn(`[ok-enrich] failed to read frontmatter at ${e} — enrichment degraded for this file. Reason: ${S}`)}return null}}async function fetchBacklinks(e,t){if(!e)return null;let S=await httpGet(e,`/api/backlinks?docName=${encodeURIComponent(t)}`);if(!S.ok)return null;let w=S.backlinks??S.results??S.links;if(!Array.isArray(w))return[];let E=[];for(let e of w){if(typeof e!=`object`||!e)continue;let t=e,S=typeof t.docName==`string`?t.docName:typeof t.source==`string`?t.source:typeof t.page==`string`?t.page:void 0;S&&E.push({source:S,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null})}return E}const BACKLINK_COUNT_CHUNK=100;async function fetchBacklinkCountsBatch(e,t){if(!e||t.length===0)return null;let S=[...new Set(t)],w=[];for(let e=0;e<S.length;e+=BACKLINK_COUNT_CHUNK)w.push(S.slice(e,e+BACKLINK_COUNT_CHUNK));let E=await Promise.all(w.map(async t=>{let S=await httpGet(e,`/api/backlink-counts?docNames=${encodeURIComponent(t.join(`,`))}`);return S.ok?S.counts??{}:null})),D=new Map,O=!1;for(let e of E)if(e){O=!0;for(let[t,S]of Object.entries(e))typeof S==`number`&&Number.isFinite(S)&&D.set(t,S)}return O?D:null}async function fetchForwardLinks(e,t){if(!e)return null;let S=await httpGet(e,`/api/forward-links?docName=${encodeURIComponent(t)}`);if(!S.ok)return null;let w=S.forwardLinks??S.links??S.results;if(!Array.isArray(w))return[];let E=[];for(let e of w){if(typeof e!=`object`||!e)continue;let t=e;if(t.kind===`external`&&typeof t.url==`string`){E.push({kind:`external`,url:t.url,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null});continue}let S=typeof t.docName==`string`?t.docName:void 0;S&&E.push({kind:`doc`,docName:S,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null})}return E}function mergeFileAndFolder(e,t,S){let w=mergeCascade(S?resolveNestedFrontmatter(S,parentFolderOf(t)):{},e??{});return{title:typeof w.title==`string`?w.title:void 0,description:typeof w.description==`string`?w.description:void 0,tags:Array.isArray(w.tags)?w.tags.filter(e=>typeof e==`string`):[],frontmatter:w}}async function enrichPath(e,t,S={}){let w=resolveWithinRoot(t.projectDir,e);if(!w.ok)throw Error(`enrichPath: ${w.reason}`);let E=w.rel,D=w.abs,O=t.historyDepth??5,k=S.includeRichFields===!0,j=readFrontmatter(D);if(!k){let e=mergeFileAndFolder(await j,E,t.projectDir);return{path:E,title:e.title,description:e.description,tags:e.tags,frontmatter:e.frontmatter,backlinkCount:null,backlinks:null,forwardLinkCount:null,forwardLinks:null,history:null,historySource:null,projectHistory:null,projectHistorySource:null}}let[F,L,B,H,q]=await Promise.all([j,fetchBacklinks(t.serverUrl,pathToDocName$1(E)).catch(()=>null),fetchForwardLinks(t.serverUrl,pathToDocName$1(E)).catch(()=>null),readShadowLog(t.projectDir,E,O).catch(()=>({commits:[],source:`shadow-repo`})),readProjectGitLog(t.projectDir,E,O).catch(()=>({commits:[],source:`git`}))]),J=mergeFileAndFolder(F,E,t.projectDir);return{path:E,title:J.title,description:J.description,tags:J.tags,frontmatter:J.frontmatter,backlinkCount:L?.length??null,backlinks:L,forwardLinkCount:B?.length??null,forwardLinks:B,history:H.commits,historySource:H.source,projectHistory:q.commits,projectHistorySource:q.source}}async function scanDirectory(e,t){let S={directMdCount:0,recursiveMdCount:0,childDirCount:0,mostRecent:null,truncated:!1},w=0,E=[{path:e,depth:0}];for(;E.length>0;){let e=E.shift();if(!e)break;if(w>=DIRECTORY_SCAN_CAP){S.truncated=!0;break}let D;try{D=await readdir(e.path,{withFileTypes:!0})}catch{continue}for(let O of D){if(w>=DIRECTORY_SCAN_CAP){S.truncated=!0;break}w++;let D=O.name;if(O.isDirectory()){if(DIR_SKIP.has(D)||D.startsWith(`.`))continue;e.depth===0&&S.childDirCount++,E.push({path:`${e.path}/${D}`,depth:e.depth+1})}else if(O.isFile()&&WIKI_EXT_RE.test(D)){S.recursiveMdCount++,e.depth===0&&S.directMdCount++;let w=`${e.path}/${D}`;try{let e=await stat$1(w);(!S.mostRecent||e.mtimeMs>S.mostRecent.mtimeMs)&&(S.mostRecent={absPath:w,relPath:relative(t,w).split(/[\\/]/).filter(Boolean).join(`/`),mtimeMs:e.mtimeMs})}catch{}}}}return S}async function enrichDirectory(e,t){let S=resolveWithinRoot(t.projectDir,e);if(!S.ok)throw Error(`enrichDirectory: ${S.reason}`);let w=S.rel,E=S.abs,D=await scanDirectory(E,t.projectDir),O;if(D.mostRecent){let e=await readFrontmatter(D.mostRecent.absPath),t=typeof e?.title==`string`?e.title:void 0;O={path:D.mostRecent.relPath,title:t??basename(D.mostRecent.relPath),updatedAt:new Date(D.mostRecent.mtimeMs).toISOString()}}let k={path:w,type:`directory`,directMdCount:D.directMdCount,recursiveMdCount:D.recursiveMdCount,childDirCount:D.childDirCount,mostRecentMd:O,truncated:D.truncated},j=resolveNestedFrontmatter(t.projectDir,w),F=j.title,L=j.description,B=j.tags??[];F!==void 0&&(k.title=F),L!==void 0&&(k.description=L),B.length>0&&(k.tags=B),Object.keys(j).length>0&&(k.frontmatter_defaults=j);let H=resolveTemplatesAvailable(t.projectDir,w);return H.length>0&&(k.templates_available=H),k}async function enrichDirectoryRecursive(e,t,S){let w=await enrichDirectory(e,S);if(t<=1)return w;let E=w.path,D=resolve(S.projectDir,E),O;try{O=await readdir(D,{withFileTypes:!0})}catch{return w}let k=[];for(let e of O){if(!e.isDirectory()||RECURSIVE_LISTING_SKIP_DIRS.has(e.name)||e.name.startsWith(`.`))continue;let w=await enrichDirectoryRecursive(E?`${E}/${e.name}`:e.name,t-1,S);k.push(w)}return k.length>0&&(w.subfolders=k),w}const RECURSIVE_LISTING_SKIP_DIRS=new Set([`.git`,`.ok`,`node_modules`,`.venv`,`venv`,`env`,`__pycache__`,`vendor`,`dist`,`build`,`out`,`output`,`.next`,`.nuxt`,`.svelte-kit`,`.astro`,`.turbo`,`.cache`,`.parcel-cache`,`coverage`]);function applyNestedFolderRulesUpsert(e){if(!isAbsolute(e.projectDir))return{ok:!1,error:{code:`BAD_PROJECT_DIR`,message:`projectDir must be absolute`}};let t=[];for(let S of e.rules){let w=resolveTargetFolderFromMatch(S.new_match??S.match);if(!w.ok)return{ok:!1,error:{code:`MULTI_FOLDER_GLOB`,message:w.message,rule:S.match}};let E=w.folder?resolve(e.projectDir,w.folder):e.projectDir,D=resolve(e.projectDir);if(!E.startsWith(D+sep)&&E!==D)return{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved target folder escapes projectDir: ${E}`,rule:S.match}};let O=null,k=null;if(S.new_match!==void 0&&S.new_match!==S.match){let t=resolveTargetFolderFromMatch(S.match);if(!t.ok)return{ok:!1,error:{code:`MULTI_FOLDER_GLOB`,message:t.message,rule:S.match}};if(O=t.folder,k=t.folder?resolve(e.projectDir,t.folder):e.projectDir,!k.startsWith(D+sep)&&k!==D)return{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved source folder escapes projectDir: ${k}`,rule:S.match}}}t.push({targetFolder:w.folder,targetAbs:E,sourceFolder:O,sourceAbs:k,rule:S})}let S=[];for(let w of t)try{if(w.sourceAbs&&w.sourceAbs!==w.targetAbs){let t=join(w.sourceAbs,`.ok`,`frontmatter.yml`);existsSync(t)&&(unlinkSync(t),autoCleanOkDir(join(w.sourceAbs,`.ok`)),S.push({match:w.rule.match,path:relPathOf$1(e.projectDir,t),action:`deleted`}))}let t=join(w.targetAbs,`.ok`),E=join(t,`frontmatter.yml`),D=readExistingFrontmatter(E),O=Object.keys(w.rule.frontmatter).length===0?{}:mergePatch(D,w.rule.frontmatter);if(Object.keys(O).length===0){existsSync(E)&&(unlinkSync(E),autoCleanOkDir(t),S.push({match:w.rule.new_match??w.rule.match,path:relPathOf$1(e.projectDir,E),action:`deleted`}));continue}mkdirSync(t,{recursive:!0});let k=(0,import_dist$1.stringify)(O),j=`${E}.tmp.${process.pid}.${Date.now()}`;writeFileSync(j,k,`utf-8`),renameSync(j,E),S.push({match:w.rule.new_match??w.rule.match,path:relPathOf$1(e.projectDir,E),action:`written`})}catch(e){return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to write nested frontmatter for ${w.rule.match}: ${e.message}`,rule:w.rule.match},...S.length>0?{partiallyApplied:S}:{}}}return{ok:!0,applied:S}}function resolveTargetFolderFromMatch(e){let t=e.split(`/`).filter(e=>e.length>0),S=[],w=!1;for(let E of t){let t=/[*?[\]{}]/.test(E);if(w&&!t)return{ok:!1,message:`Glob "${e}" matches multiple folders (literal segment "${E}" appears after a glob). Split it into one rule per folder, e.g. folder_config({ action: "set-rule", rules: [{ match: "specs/foo/${E}/**", ... }, ...] }).`};if(t){if(w=!0,E!==`**`&&E!==`*`)return{ok:!1,message:`Glob "${e}" uses an unsupported pattern segment "${E}". Only "*" and "**" are supported in nested folder rules.`};continue}S.push(E)}return{ok:!0,folder:S.join(`/`)}}function readExistingFrontmatter(e){if(!existsSync(e))return{};let t=(0,import_dist$1.parse)(readFileSync(e,`utf-8`));return typeof t!=`object`||!t||Array.isArray(t)?{}:{...t}}function autoCleanOkDir(e){if(!existsSync(e))return;let t;try{t=readdirSync(e)}catch{return}if(t.length===0)try{rmdirSync(e)}catch{}}function relPathOf$1(e,t){let S=resolve(e);return t.startsWith(S+sep)?t.slice(S.length+1).split(sep).join(`/`):t}const SUBSTITUTION_ALLOWLIST=[`date`,`user`],TOKEN_PATTERN=/\{\{([^{}\n]+?)\}\}/g;function validateSubstitution(e){let t=[];for(let S of e.matchAll(TOKEN_PATTERN)){let e=(S[1]??``).trim();isAllowedToken(e)||t.push({token:e,offset:S.index??0})}return t}function applySubstitution(e,t){return e.replace(TOKEN_PATTERN,(e,S)=>{let w=S.trim();return isAllowedToken(w)?t[w]:e})}function isAllowedToken(e){return SUBSTITUTION_ALLOWLIST.includes(e)}function todayIsoUtc(e=new Date){return`${e.getUTCFullYear().toString().padStart(4,`0`)}-${(e.getUTCMonth()+1).toString().padStart(2,`0`)}-${e.getUTCDate().toString().padStart(2,`0`)}`}const NAME_RE=/^[A-Za-z0-9_-]+$/;function applyTemplateWrite(e){let t=validateInputs(e.projectDir,e.folder,e.name);if(!t.ok)return{ok:!1,error:t.error};let S=validateTitle(e.frontmatter.title);if(!S.ok)return{ok:!1,error:S.error};let w=validateSubstitutionAllowlist(e.body);if(!w.ok)return{ok:!1,error:w.error};let{templatesDir:E,filePath:D}=templatePaths(e.projectDir,t.folderRel,e.name),O=serializeFrontmatter(e.frontmatter),k=O?`---\n${O}---\n${e.body}`:e.body;try{mkdirSync(E,{recursive:!0})}catch(t){return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to create template directory at ${relPathOf(e.projectDir,E)}: ${t.message}`}}}let j=!existsSync(D),F=`${D}.tmp.${process.pid}.${Date.now()}`;try{writeFileSync(F,k,`utf-8`),renameSync(F,D)}catch(t){try{unlinkSync(F)}catch{}return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to write template at ${relPathOf(e.projectDir,D)}: ${t.message}`}}}let L=[];return(e.frontmatter.description===void 0||typeof e.frontmatter.description!=`string`||e.frontmatter.description.length===0)&&L.push("Template frontmatter.description is missing — `description` disambiguates between similarly-named templates in the menu. Recommended but not required."),{ok:!0,path:relPathOf(e.projectDir,D),created:j,warnings:L}}function applyTemplateDelete(e){let t=validateInputs(e.projectDir,e.folder,e.name);if(!t.ok)return{ok:!1,error:t.error};let{templatesDir:S,okDir:w,filePath:E}=templatePaths(e.projectDir,t.folderRel,e.name),D=existsSync(E);if(D)try{unlinkSync(E)}catch(t){return{ok:!1,error:{code:`UNLINK_FAILED`,message:`Failed to delete template at ${relPathOf(e.projectDir,E)}: ${t.message}`}}}let O=!1,k=!1;if(existsSync(S)&&isEmpty(S))try{rmdirSync(S),O=!0}catch{}if(existsSync(w)&&isEmpty(w))try{rmdirSync(w),k=!0}catch{}return{ok:!0,path:relPathOf(e.projectDir,E),existed:D,cleanedEmpty:{templatesDir:O,okDir:k}}}function validateInputs(e,t,S){if(!isAbsolute(e))return{ok:!1,error:{code:`BAD_PROJECT_DIR`,message:`projectDir must be absolute`}};if(!NAME_RE.test(S))return{ok:!1,error:{code:`BAD_NAME`,message:`Template name must match /^[A-Za-z0-9_-]+$/ (got: ${JSON.stringify(S)}). Use letters, digits, underscores, or hyphens — no slashes, dots, or spaces.`}};let w=t.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``).replace(/^\.$/,``);if(w.includes(`..`))return{ok:!1,error:{code:`PATH_TRAVERSAL`,message:`Folder path may not contain "..": ${JSON.stringify(t)}`}};let E=w?resolve(e,w):e,D=resolve(e);return!E.startsWith(D+sep)&&E!==D?{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved folder path escapes projectDir: ${E}`}}:{ok:!0,folderRel:w}}function validateTitle(e){return typeof e!=`string`||e.length===0?{ok:!1,error:{code:`TEMPLATE_TITLE_REQUIRED`,message:"Template frontmatter.title is required. `title` is the menu surface — agents pick templates by name+title; a title-less template is effectively invisible. Set a non-empty `title` and retry."}}:{ok:!0}}function validateSubstitutionAllowlist(e){let t=validateSubstitution(e);return t.length===0?{ok:!0}:{ok:!1,error:{code:`TEMPLATE_UNKNOWN_VARIABLE`,message:`Template body contains unknown substitution token(s): ${t.map(e=>`\`{{${e.token}}}\` at offset ${e.offset}`).join(`, `)}. v1 allowlist: \`{{date}}\`, \`{{user}}\`. Remove or rename the offending tokens and retry.`}}}function templatePaths(e,t,S){let w=t?join(e,t,`.ok`):join(e,`.ok`),E=join(w,`templates`);return{okDir:w,templatesDir:E,filePath:join(E,`${S}.md`)}}function relPathOf(e,t){return normalize(t.startsWith(e+sep)?t.slice(e.length+1):t).split(sep).join(`/`)}function serializeFrontmatter(e){let t={};return e.title!==void 0&&(t.title=e.title),e.description!==void 0&&(t.description=e.description),Array.isArray(e.tags)&&e.tags.length>0&&(t.tags=e.tags),Object.keys(t).length===0?``:(0,import_dist$1.stringify)(t)}function isEmpty(e){try{return readdirSync(e).length===0}catch{return!1}}const log$6=()=>getLogger(`http`);let _apiErrorCounter=null;function apiErrorCounter(){return _apiErrorCounter||=getMeter().createCounter(`ok.api.error.count`,{description:`API error responses by problem type and handler`,unit:`1`}),_apiErrorCounter}function errorResponse(e,t,S,w,E={}){let D=E.instance??`urn:uuid:${randomUUID()}`;if(e.headersSent||e.writableEnded||e.destroyed){log$6().error({event:`api.error.double-write`,instance:D,type:S,status:t,handler:E.handler},`errorResponse called after headers already sent — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...E.handler?{handler:E.handler}:{}});return}let O={type:S,title:w,status:t,instance:D,detail:E.detail??void 0},k=ProblemDetailsSchema.safeParse(O);if(!k.success){log$6().error({event:`api.error.malformed-envelope`,issues:k.error.issues,body:O,handler:E.handler,originalStatus:t},`errorResponse produced an invalid ProblemDetails body — emitting fallback`);let S=500;apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...E.handler?{handler:E.handler}:{}}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:D}));return}let j=E.extensions?{...E.extensions,...O}:O;apiErrorCounter().add(1,{type:S,...E.handler?{handler:E.handler}:{}});let F=t>=500?`error`:`warn`;log$6()[F]({event:`api.error`,instance:D,type:S,status:t,handler:E.handler,detail:E.detail,err:E.cause},w);let L;try{L=JSON.stringify(j)}catch(S){log$6().error({event:`api.error.unserializable-body`,bodyKeys:Object.keys(j),handler:E.handler,originalStatus:t,instance:D,err:S},`errorResponse wireBody is not JSON-serializable — emitting hardcoded fallback`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...E.handler?{handler:E.handler}:{}}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:D}));return}e.writeHead(t,{...E.extraHeaders,"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(L)}function streamingProblemEvent(e,t,S,w={}){let E=w.instance??`urn:uuid:${randomUUID()}`,D={type:`error`,problem:{type:t,title:S,status:e,instance:E,detail:w.detail??void 0}},O=StreamingProblemEventSchema.safeParse(D);if(!O.success){log$6().error({event:`api.streaming.malformed-envelope`,issues:O.error.issues,body:D,handler:w.handler,originalStatus:e},`streamingProblemEvent produced an invalid StreamingProblemEvent — returning fallback`);let t=500;return apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...w.handler?{handler:w.handler}:{}}),{type:`error`,problem:{type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:E}}}apiErrorCounter().add(1,{type:t,...w.handler?{handler:w.handler}:{}});let k=e>=500?`error`:`warn`;return log$6()[k]({event:`api.streaming.error`,instance:E,type:t,status:e,handler:w.handler,detail:w.detail,err:w.cause},S),D}function createStreamingErrorWriter(e,t){return(S,w,E,D={})=>{if(e.writableEnded||e.destroyed){log$6().error({event:`api.streaming.error.suppressed`,type:w,status:S,handler:t,detail:D.detail,err:D.cause},`createStreamingErrorWriter called after writableEnded/destroyed — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...t?{handler:t}:{}});return}let O=streamingProblemEvent(S,w,E,{handler:t,...D});try{e.write(`${JSON.stringify(O)}\n`)}catch(e){log$6().error({event:`api.streaming.error.write-failed`,type:w,status:S,handler:t,err:D.cause,writeErr:e},`createStreamingErrorWriter: res.write threw — original error preserved in log`)}}}const log$5=()=>getLogger(`http`);function successResponse(e,t,S,w,E={}){if(e.headersSent||e.writableEnded||e.destroyed){log$5().error({event:`api.success.double-write`,status:t,handler:E.handler},`successResponse called after headers already sent — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...E.handler?{handler:E.handler}:{}});return}let D=S.safeParse(w);if(!D.success){log$5().error({event:`api.success.malformed-body`,issues:D.error.issues,bodyKeys:typeof w==`object`&&w?Object.keys(w):null,handler:E.handler,originalStatus:t},`successResponse produced an invalid body for the supplied schema — emitting fallback`),errorResponse(e,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:E.handler});return}let O;try{O=JSON.stringify(D.data)}catch(S){log$5().error({event:`api.success.unserializable-body`,bodyKeys:typeof D.data==`object`&&D.data!==null?Object.keys(D.data):null,handler:E.handler,originalStatus:t,err:S},`successResponse parsed body is not JSON-serializable — emitting fallback`),errorResponse(e,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:E.handler});return}e.writeHead(t,{...E.extraHeaders,"Content-Type":`application/json`,"X-Content-Type-Options":`nosniff`}),e.end(O)}const INSTALLED_AGENTS_SCHEMES=[`claude`,`codex`,`cursor`],INSTALLED_AGENTS_PROBE_TIMEOUT_MS=2e3,MACOS_APP_NAMES={claude:[`Claude`],codex:[`Codex`,`OpenAI Codex`],cursor:[`Cursor`]};function createInstalledAgentsProbe(e){let t=new Map,S=e.now??Date.now,w=e.ttlMs??6e4;async function E(E){let D=t.get(E);if(D?.status===`resolved`&&D.expiresAt>S())return D.installed;if(D?.status===`inflight`)return D.promise;let O=(async()=>{try{let D=await e.probe(E);return t.set(E,{status:`resolved`,installed:D,expiresAt:S()+w}),D}catch{return t.set(E,{status:`resolved`,installed:!1,expiresAt:S()+w}),!1}})();return t.set(E,{status:`inflight`,promise:O}),O}async function D(){let e=await Promise.all(INSTALLED_AGENTS_SCHEMES.map(async e=>[e,await E(e)]));return Object.fromEntries(e)}return{probeAll:D,probeWithCache:E}}function isLocalWebHost(e){let t=e.headers.host;if(typeof t==`string`&&t.length>0)try{let{hostname:e}=new URL(`http://${t}/`);return isLoopbackHostname(e)}catch{}let S=e.headers.origin;if(typeof S==`string`&&S.length>0)try{return isLoopbackHostname(new URL(S).hostname)}catch{return!1}return!0}function isLoopbackHostname(e){return e===`localhost`||e===`127.0.0.1`||e===`[::1]`||e===`::1`}async function handleInstalledAgents(e,t,S){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`installed-agents`,extraHeaders:{Allow:`GET`}});return}try{successResponse(t,200,InstalledAgentsSuccessSchema,isLocalWebHost(e)?await S():Object.fromEntries(INSTALLED_AGENTS_SCHEMES.map(e=>[e,!0])),{handler:`installed-agents`})}catch(e){console.error(`[installed-agents]`,e),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`installed-agents`,cause:e})}}function createOsProbe(e,t=execFile){return S=>e===`darwin`?probeMacOs(S,t):e===`win32`?probeWindows(S,t):probeLinux(S,t)}function probeMacOs(e,t){let S=MACOS_APP_NAMES[e];function w(e){return new Promise(S=>{t(`osascript`,[`-e`,`id of app "${e}"`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},(e,t)=>{if(e){S(!1);return}S(t.trim().length>0)})})}return(async()=>{for(let e of S)if(await w(e))return!0;return!1})()}function probeWindows(e,t){return new Promise(S=>{t(`reg`,[`query`,`HKCR\\${e}`,`/ve`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},e=>{S(!e)})})}function probeLinux(e,t){return new Promise(S=>{t(`xdg-mime`,[`query`,`default`,`x-scheme-handler/${e}`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},(e,t)=>{if(e){S(!1);return}S(t.trim().length>0)})})}const MAX_BODY_BYTES=1048576,REQUEST_BODY_TIMEOUT_MS=3e4;function readRequestBody(e){return readBoundedJsonBody(e,{maxBytes:MAX_BODY_BYTES,timeoutMs:REQUEST_BODY_TIMEOUT_MS})}async function readBoundedJsonBody(e,t){let S=[],w=0,E=AbortSignal.timeout(t.timeoutMs),D=()=>e.destroy(new RequestBodyTimeoutError(t.timeoutMs));E.addEventListener(`abort`,D,{once:!0});try{for await(let E of e){if(w+=E.length,w>t.maxBytes)throw new PayloadTooLargeError(t.maxBytes);S.push(E)}return Buffer.concat(S)}finally{E.removeEventListener(`abort`,D)}}var PayloadTooLargeError=class extends Error{maxBytes;constructor(e){super(e===void 0?`Request body exceeded cap`:`Request body exceeded ${formatBytes(e)} cap`),this.name=`PayloadTooLargeError`,this.maxBytes=e}},RequestBodyTimeoutError=class extends Error{timeoutMs;constructor(e){super(e===void 0?`Request body read exceeded timeout`:`Request body read exceeded ${e}ms timeout`),this.name=`RequestBodyTimeoutError`,this.timeoutMs=e}};function formatBytes(e){return e>=1048576?`${(e/1048576).toFixed(0)} MB`:e>=1024?`${(e/1024).toFixed(0)} KB`:`${e} B`}function validateBody(e,t,S,w={}){let E=e.safeParse(t);if(E.success)return{ok:!0,value:E.data};let D=E.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `);return errorResponse(S,400,`urn:ok:error:invalid-request`,`Request body is invalid.`,{handler:w.handler,detail:D}),{ok:!1}}function withValidation(e,t,S={}){return async(w,E)=>{if(S.method!==void 0&&w.method!==S.method){errorResponse(E,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:S.handler,extraHeaders:{Allow:S.method}});return}if(S.preBodyGate!==void 0&&!S.preBodyGate(w,E)){!E.headersSent&&!E.writableEnded&&!E.destroyed&&errorResponse(E,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:S.handler,cause:Error(`preBodyGate returned false without writing a response`)});return}if(S.skipBodyParse){let D=validateBody(e,{},E,S);if(!D.ok)return;await t(w,E,D.value);return}let D;try{D=await readRequestBody(w)}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(E,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:S.handler,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(E,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:S.handler,cause:e});return}errorResponse(E,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:S.handler,cause:e});return}let O;try{O=D.length===0?{}:JSON.parse(D.toString(`utf8`))}catch(e){errorResponse(E,400,`urn:ok:error:invalid-request`,`Request body is not valid JSON.`,{handler:S.handler,cause:e});return}let k=validateBody(e,O,E,S);k.ok&&await t(w,E,k.value)}}function classifySpawnError(e){let t=e instanceof Error?e.message:String(e);return/ENOENT|EACCES|EPERM/.test(t)?{ok:!1,reason:`not-installed`}:{ok:!1,reason:`spawn-error`}}function spawnDetached(e,t,S){return new Promise(w=>{let E=!1,D=e=>{E||(E=!0,w(e))},O=setTimeout(()=>D({ok:!1,reason:`timeout`}),S);try{let S=spawn(e,[...t],{detached:!0,stdio:`ignore`,shell:!1});S.once(`error`,e=>{clearTimeout(O),D(classifySpawnError(e))}),S.once(`spawn`,()=>{if(!E){try{S.unref()}catch{}clearTimeout(O),D({ok:!0})}})}catch(e){console.warn(`[spawn-detached] synchronous spawn throw:`,e),clearTimeout(O),D(classifySpawnError(e))}})}const SPAWN_CURSOR_WHICH_TIMEOUT_MS=500,SPAWN_CURSOR_SPAWN_TIMEOUT_MS=2e3,SPAWN_CURSOR_MAX_BODY_BYTES=4*1024,SPAWN_CURSOR_BODY_READ_TIMEOUT_MS=5e3,HANDLER$1=`spawn-cursor`;function assertNeverSpawnReason(e){throw Error(`Unhandled spawn-cursor outcome.reason: ${String(e)}`)}async function handleSpawnCursor(e,t,S){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:HANDLER$1,extraHeaders:{Allow:`POST`}});return}let w;try{w=await readBoundedJsonBody(e,{maxBytes:SPAWN_CURSOR_MAX_BODY_BYTES,timeoutMs:SPAWN_CURSOR_BODY_READ_TIMEOUT_MS})}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(t,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:HANDLER$1,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(t,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:HANDLER$1,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:HANDLER$1,cause:e});return}let E;try{E=JSON.parse(w.toString(`utf-8`))}catch(e){errorResponse(t,400,`urn:ok:error:invalid-request`,`Malformed JSON body.`,{handler:HANDLER$1,cause:e});return}let D=typeof E.path==`string`?E.path:``;if(!D){errorResponse(t,400,`urn:ok:error:invalid-request`,"Missing or empty `path` field.",{handler:HANDLER$1});return}if(!isPathWithinDir(D,S.contentDir,S.platform)){errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER$1});return}let O=await(S.resolveCursorBinary??resolveCursorBinaryDefault)(SPAWN_CURSOR_WHICH_TIMEOUT_MS);if(!O){errorResponse(t,422,`urn:ok:error:cursor-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER$1});return}let k=resolveCursorSpawnInvocation(O,D,S.platform),j=await(S.spawnDetached??spawnDetached)(k.exec,k.args,SPAWN_CURSOR_SPAWN_TIMEOUT_MS);if(j.ok){successResponse(t,200,SpawnCursorSuccessSchema,{},{handler:HANDLER$1});return}switch(j.reason){case`not-installed`:errorResponse(t,422,`urn:ok:error:cursor-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER$1});return;case`timeout`:errorResponse(t,504,`urn:ok:error:cursor-spawn-timeout`,`Cursor spawn exceeded the deadline.`,{handler:HANDLER$1});return;case`spawn-error`:errorResponse(t,502,`urn:ok:error:cursor-spawn-failed`,`Cursor spawn failed.`,{handler:HANDLER$1});return;case`invalid-path`:errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER$1});return;default:return assertNeverSpawnReason(j.reason)}}const CURSOR_BUNDLE_PATHS_BY_PLATFORM={darwin:[()=>`/Applications/Cursor.app/Contents/Resources/app/bin/cursor`,e=>`${e}/Applications/Cursor.app/Contents/Resources/app/bin/cursor`],win32:[e=>`${e}\\AppData\\Local\\Programs\\cursor\\resources\\app\\bin\\cursor.cmd`,()=>`C:\\Program Files\\Cursor\\resources\\app\\bin\\cursor.cmd`]};async function resolveCursorBinaryDefault(e){let t=CURSOR_BUNDLE_PATHS_BY_PLATFORM[process.platform];if(t&&t.length>0){let e=homedir();for(let S of t){let t=S(e);try{return await access(t,constants.X_OK),t}catch(e){let S=e?.code;S!==`ENOENT`&&S!==`EACCES`&&S!==`EPERM`&&console.warn(`[spawn-cursor] unexpected fs.access error on bundle probe:`,S,t)}}}return new Promise(t=>{execFile(process.platform===`win32`?`where`:`which`,[`cursor`],{timeout:e,encoding:`utf-8`},(e,S)=>{if(e){t(null);return}let w=S.split(/\r?\n/)[0]?.trim();t(w&&w.length>0?w:null)})})}function resolveCursorSpawnInvocation(e,t,S){return S===`darwin`&&/\.app\/?$/.test(e)?{exec:`/usr/bin/open`,args:[`-a`,e.replace(/\/$/,``),t]}:{exec:e,args:[t]}}function isPathWithinDir(e,t,S){if(!e||typeof e!=`string`||e.includes(`\0`)||!t||typeof t!=`string`)return!1;if(S===`win32`){if(!/^([a-zA-Z]:[\\/]|\\\\)/.test(e)||!/^([a-zA-Z]:[\\/]|\\\\)/.test(t))return!1}else if(!e.startsWith(`/`)||!t.startsWith(`/`))return!1;let w=S===`win32`?win32:posix;try{let E=w.resolve(e),D=w.resolve(t);if(S===`win32`){let e=w.parse(E).root.toLowerCase(),t=w.parse(D).root.toLowerCase();if(!e||!t||e!==t)return!1}if(E===D)return!0;let O=w.relative(D,E);return O===``||O===`.`?!0:!(O===`..`||O.startsWith(`..${w.sep}`)||S===`win32`&&(/^[a-zA-Z]:[\\/]/.test(O)||O.startsWith(`\\\\`))||S!==`win32`&&O.startsWith(`/`))}catch(e){return console.warn(`[spawn-cursor] unexpected path-resolution error:`,e),!1}}const HANDLER=`handoff`,HANDOFF_MAX_BODY_BYTES=4*1024,HANDOFF_BODY_READ_TIMEOUT_MS=5e3,SPAWN_TIMEOUT_MS=2e3,WHICH_TIMEOUT_MS=500,QUIT_SETTLE_MS=3e3,APP_BUNDLE_SETTLE_MS=5e3,CURSOR_SETTLE_MS=1500,RECIPES={"claude-cowork":{type:`app-bundle`,appName:`Claude`,urlScheme:`claude:`,quitFirst:!1},"claude-code":{type:`app-bundle`,appName:`Claude`,urlScheme:`claude:`,quitFirst:!1},codex:{type:`app-bundle`,appName:`Codex`,urlScheme:`codex:`,quitFirst:!0},cursor:{type:`cli-binary`,binaryName:`cursor`,urlScheme:`cursor:`}},TARGET_VALUES=Object.keys(RECIPES),HandoffRequestSchema=object$1({target:_enum(TARGET_VALUES),url:string$2().min(1).max(4096),workspacePath:string$2().optional()}),HandoffSuccessSchema=object$1({}).loose();function defaultSleep(e){return new Promise(t=>setTimeout(t,e))}async function handleHandoffDispatch(e,t,S){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:HANDLER,extraHeaders:{Allow:`POST`}});return}if(S.platform!==`darwin`){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Handoff is currently macOS-only.`,{handler:HANDLER});return}let w;try{w=await readBoundedJsonBody(e,{maxBytes:HANDOFF_MAX_BODY_BYTES,timeoutMs:HANDOFF_BODY_READ_TIMEOUT_MS})}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(t,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:HANDLER,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(t,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:HANDLER,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:HANDLER,cause:e});return}let E;try{E=JSON.parse(w.toString(`utf-8`))}catch(e){errorResponse(t,400,`urn:ok:error:invalid-request`,`Malformed JSON body.`,{handler:HANDLER,cause:e});return}let D=HandoffRequestSchema.safeParse(E);if(!D.success){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid request body.`,{handler:HANDLER});return}let{target:O,url:k,workspacePath:j}=D.data,F=RECIPES[O];if(!k.startsWith(F.urlScheme)){errorResponse(t,400,`urn:ok:error:invalid-request`,`URL scheme must be ${F.urlScheme} for target ${O}.`,{handler:HANDLER});return}let L=S.sleep??defaultSleep,B=S.spawnDetached??spawnDetached;if(F.type===`app-bundle`){F.quitFirst&&(await B(`/usr/bin/osascript`,[`-e`,`tell application "${F.appName}" to quit`],SPAWN_TIMEOUT_MS).catch(()=>void 0),await L(QUIT_SETTLE_MS));let e=await B(`/usr/bin/open`,[`-a`,F.appName],SPAWN_TIMEOUT_MS);if(!e.ok){emitSpawnFailure(t,O,e.reason);return}await L(APP_BUNDLE_SETTLE_MS);let S=await B(`/usr/bin/open`,[k],SPAWN_TIMEOUT_MS);if(!S.ok){emitSpawnFailure(t,O,S.reason);return}successResponse(t,200,HandoffSuccessSchema,{},{handler:HANDLER});return}if(!j){errorResponse(t,400,`urn:ok:error:invalid-request`,`workspacePath is required for cursor handoff.`,{handler:HANDLER});return}if(!isPathWithinDir(j,S.contentDir,S.platform)){errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER});return}let H=await(S.resolveCursorBinary??resolveCursorBinaryDefault)(WHICH_TIMEOUT_MS);if(!H){errorResponse(t,422,`urn:ok:error:handoff-target-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER,extensions:{target:`cursor`}});return}let q=resolveCursorSpawnInvocation(H,j,S.platform),J=await B(q.exec,q.args,SPAWN_TIMEOUT_MS);if(!J.ok){emitSpawnFailure(t,O,J.reason);return}await L(CURSOR_SETTLE_MS);let Y=await B(`/usr/bin/open`,[k],SPAWN_TIMEOUT_MS);if(!Y.ok){emitSpawnFailure(t,O,Y.reason);return}successResponse(t,200,HandoffSuccessSchema,{},{handler:HANDLER})}function emitSpawnFailure(e,t,S){switch(S){case`not-installed`:errorResponse(e,422,`urn:ok:error:handoff-target-not-installed`,`Required binary or application not found.`,{handler:HANDLER,extensions:{target:t}});return;case`timeout`:errorResponse(e,504,`urn:ok:error:handoff-spawn-timeout`,`Handoff spawn exceeded the deadline.`,{handler:HANDLER,extensions:{target:t}});return;case`spawn-error`:errorResponse(e,502,`urn:ok:error:handoff-spawn-failed`,`Handoff spawn failed.`,{handler:HANDLER,extensions:{target:t}});return;default:assertNeverReason(S)}}function assertNeverReason(e){throw Error(`Unhandled spawn reason: ${String(e)}`)}const FIXED_HUB_BASENAMES=[`INDEX`,`README`,`REPORT`,`SPEC`],MAX_CANDIDATES=3;function findHubCandidates(e,t){let S=[],w=new Set,E=t=>{!t||w.has(t)||t!==e&&(w.add(t),S.push(t))},D=buildLowerDocNameIndex(t),O=parentFolder(e);for(;;){for(let e of FIXED_HUB_BASENAMES)if(E(lookup$1(t,D,joinDocName(O,e))),S.length>=MAX_CANDIDATES)return S;let e=O===``?null:basename$1(O);if(e&&(E(lookup$1(t,D,joinDocName(O,e))),S.length>=MAX_CANDIDATES))return S;if(O===``)break;O=parentFolder(O)}return S}function lookup$1(e,t,S){return e.has(S)?S:t.get(S.toLowerCase())??null}function buildLowerDocNameIndex(e){let t=new Map;for(let S of e.keys()){let e=S.toLowerCase();t.has(e)||t.set(e,S)}return t}function parentFolder(e){let t=e.lastIndexOf(`/`);return t<0?``:e.slice(0,t)}function basename$1(e){let t=e.lastIndexOf(`/`);return t<0?e:e.slice(t+1)}function joinDocName(e,t){return e===``?t:`${e}/${t}`}function splitFrontmatterLines(e){return e?e.replace(/^---\r?\n/,``).replace(/\r?\n---(?:\r?\n)?$/,``).split(/\r?\n/):[]}function normalizeFrontmatterScalar(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).trim():t}function extractFrontmatterScalar(e,t){let S=`${t}:`;for(let t of splitFrontmatterLines(e))if(t.startsWith(S))return normalizeFrontmatterScalar(t.slice(S.length))||null;return null}function parseInlineAliases(e){let t=[],S=``,w=null;for(let E of e){if(w){S+=E,E===w&&(w=null);continue}if(E===`"`||E===`'`){w=E,S+=E;continue}if(E===`,`){let e=normalizeFrontmatterScalar(S);e&&t.push(e),S=``;continue}S+=E}let E=normalizeFrontmatterScalar(S);return E&&t.push(E),t}function dedupeExact(e){let t=[],S=new Set;for(let w of e)!w||S.has(w)||(S.add(w),t.push(w));return t}function extractPageAliases(e){let{frontmatter:t}=stripFrontmatter(e);if(!t)return[];let S=splitFrontmatterLines(t);for(let e=0;e<S.length;e+=1){let t=S[e]?.match(/^aliases:\s*(.*)$/);if(!t)continue;let w=t[1]?.trim()??``;if(w){if(w.startsWith(`[`)&&w.endsWith(`]`))return dedupeExact(parseInlineAliases(w.slice(1,-1)));let e=normalizeFrontmatterScalar(w);return e?[e]:[]}let E=[];for(let t=e+1;t<S.length;t+=1){let e=S[t];if(e?.trim()){if(/^\s*-\s+/.test(e)){let t=normalizeFrontmatterScalar(e.replace(/^\s*-\s+/,``));t&&E.push(t);continue}if(/^[^\s][^:]*:\s*/.test(e))break;break}}return dedupeExact(E)}return[]}function extractPageTitle(e,t){let{frontmatter:S,body:w}=stripFrontmatter(e),E=extractFrontmatterScalar(S,`title`);if(E)return E;let D=w.match(/^# (.+)$/m);return D?D[1].trim():t}function parseFrontmatterMetadata(e){return e?.trim()?{cluster:extractFrontmatterScalar(e,`cluster`)??void 0,category:extractFrontmatterScalar(e,`category`)??void 0,tags:extractFrontmatterArray(e,`tags`)}:{cluster:void 0,category:void 0,tags:void 0}}function extractFrontmatterArray(e,t){let S=`${t}:`,w=splitFrontmatterLines(e);for(let e=0;e<w.length;e+=1){let t=w[e];if(!t?.startsWith(S))continue;let E=t.slice(S.length).trim();if(E){if(E.startsWith(`[`)&&E.endsWith(`]`)){let e=parseInlineAliases(E.slice(1,-1));return e.length>0?e:void 0}let e=normalizeFrontmatterScalar(E);return e?[e]:void 0}let D=[];for(let t=e+1;t<w.length;t+=1){let e=w[t];if(e?.trim()){if(/^\s*-\s+/.test(e)){let t=normalizeFrontmatterScalar(e.replace(/^\s*-\s+/,``));t&&D.push(t);continue}if(/^[^\s][^:]*:\s*/.test(e))break;break}}return D.length>0?D:void 0}}function extractPageIdentity(e,t){let S=extractPageTitle(e,t),w=extractPageAliases(e),E=dedupeExact([S,...w]),D=[],O=new Set;for(let e of E){let t=toWikiLinkSlug(e);!t||O.has(t)||(O.add(t),D.push(t))}return{docName:t,title:S,aliases:w,matchLabels:E,normalizedMatchLabels:D}}const SHARE_BASE_URL=`https://openknowledge.ai/d/`,SHARE_CONSTRUCT_URL_HANDLER_TAG=`share-construct-url`;function isValidShareDocPath(e){if(e.length===0||e.startsWith(`/`)||e.startsWith(`\\`))return!1;for(let t of e.split(/[/\\]/))if(t===`..`||t===`.git`||t.length===0)return!1;return!0}function buildGitHubBlobUrl(e,t,S,w){return`https://github.com/${e}/${t}/blob/${S.split(`/`).map(encodeURIComponent).join(`/`)}/${w.split(`/`).map(encodeURIComponent).join(`/`)}`}function emitShareConstructUrlLog(e,t){let S=t===void 0?``:` branch_exists=${t}`;console.log(`[share] action=construct-url result=${e}${S}`)}function resolveGitDir$1(e){let t=resolve(e,`.git`);if(!existsSync(t))return null;let S;try{S=statSync(t)}catch{return null}if(S.isDirectory())return t;if(S.isFile()){let S;try{S=readFileSync(t,`utf-8`)}catch{return null}let w=/^gitdir:\s*(.+)$/m.exec(S.trim());if(!w)return null;let E=w[1].trim(),D=isAbsolute(E)?E:resolve(e,E);return existsSync(D)?D:null}return null}function readGitHeadBranch(e){let t=resolveGitDir$1(e);if(!t)return null;let S=join(t,`HEAD`);if(!existsSync(S))return null;let w;try{w=readFileSync(S,`utf-8`)}catch{return null}let E=/^ref:\s*refs\/heads\/(.+)$/.exec(w.trim());return E?E[1]:null}function stripCommentAndTrim(e){let t=e.indexOf(`#`),S=e.indexOf(`;`),w=-1;return t>=0&&S>=0?w=Math.min(t,S):t>=0?w=t:S>=0&&(w=S),(w===-1?e:e.slice(0,w)).trim()}function extractOriginUrl(e){let t=!1;for(let S of e.split(/\r?\n/)){let e=stripCommentAndTrim(S);if(e.length===0)continue;if(e.startsWith(`[`)){t=/^\[\s*remote\s+["']origin["']\s*\]$/.test(e);continue}if(!t)continue;let w=/^url\s*=\s*(.+)$/.exec(e);if(!w)continue;let E=w[1].trim();if((E.startsWith(`"`)&&E.endsWith(`"`)||E.startsWith(`'`)&&E.endsWith(`'`))&&(E=E.slice(1,-1)),E.length>0)return E}return null}function parseGitHubOriginUrl(e){let t=e.trim();if(!t)return null;let S=/^https?:\/\/(?:www\.)?github\.com\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t);return S||(S=/^ssh:\/\/(?:[\w.-]+@)?github\.com(?::\d+)?\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t),S)||(S=/^[\w.-]+@github\.com:([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?$/.exec(t),S)||(S=/^git:\/\/github\.com\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t),S)?{owner:S[1],repo:S[2]}:null}function readOriginGitHubRepo(e){let t=resolveGitDir$1(e);if(!t)return{kind:`no-remote`};let S=join(t,`config`);if(!existsSync(S))return{kind:`no-remote`};let w;try{w=readFileSync(S,`utf-8`)}catch{return{kind:`no-remote`}}let E=extractOriginUrl(w);if(!E)return{kind:`no-remote`};let D=parseGitHubOriginUrl(E);return D?{kind:`ok`,owner:D.owner,repo:D.repo}:{kind:`non-github`}}function branchExistsOnOrigin(e,t){let S=resolveGitDir$1(e);if(!S)return!1;if(existsSync(join(S,`refs`,`remotes`,`origin`,t)))return!0;let w=join(S,`packed-refs`);if(!existsSync(w))return!1;let E;try{E=readFileSync(w,`utf-8`)}catch{return!1}let D=`refs/remotes/origin/${t}`;for(let e of E.split(/\r?\n/)){let t=e.trim();if(t.length===0||t.startsWith(`#`)||t.startsWith(`^`))continue;let S=t.split(/\s+/);if(S.length===2&&S[1]===D)return!0}return!1}const SHARE_PUBLISH_OWNERS_HANDLER_TAG=`share-publish-owners`,SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG=`share-publish-name-check`,SHARE_PUBLISH_HANDLER_TAG=`share-publish`,SHARE_PUBLISH_OWNERS_KEY=`/api/share/publish/owners`,SHARE_PUBLISH_NAME_CHECK_KEY=`/api/share/publish/name-check`,SHARE_PUBLISH_KEY=`/api/share/publish`,SHARE_PUBLISH_TIMEOUT_MS=3e4;function isValidShareRepoName(e){return e.length===0||e.length>100||e.startsWith(`.`)||e.startsWith(`-`)||/^-+$/.test(e)?!1:/^[A-Za-z0-9._-]+$/.test(e)}function isValidShareOwnerName(e){return e.length===0||e.length>39||e.startsWith(`-`)||e.endsWith(`-`)?!1:/^[A-Za-z0-9-]+$/.test(e)}function pickTerminalJsonLine(e){let t=e.split(`
|
|
1186
|
+
`).map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;e--)try{let S=JSON.parse(t[e]);if(S&&typeof S==`object`&&!Array.isArray(S))return S}catch{}return null}function parseOwnersEvent(e){if(e===null)return{ok:!1,error:`network`};if(e.type===`owners`&&Array.isArray(e.owners)){let t=[];for(let S of e.owners){if(!S||typeof S!=`object`)continue;let e=S,w=typeof e.login==`string`?e.login:null,E=e.kind===`user`||e.kind===`org`?e.kind:null;if(w===null||E===null)continue;let D=typeof e.avatarUrl==`string`?e.avatarUrl:void 0;t.push({login:w,kind:E,...D?{avatarUrl:D}:{}})}return{ok:!0,owners:t}}return e.type===`error`?{ok:!1,error:isOwnersErrorCode(e.code)?e.code:`network`}:{ok:!1,error:`network`}}function isOwnersErrorCode(e){return e===`auth-required`||e===`network`}function parseNameCheckEvent(e){return e===null?{ok:!1,error:`network`}:e.type===`name-check`&&typeof e.available==`boolean`?{ok:!0,available:e.available}:e.type===`error`?{ok:!1,error:isOwnersErrorCode(e.code)?e.code:`network`}:{ok:!1,error:`network`}}const PUBLISH_ERROR_CODES=new Set([`name-conflict`,`saml-sso`,`auth-required`,`push-failed`,`init-failed`,`network`,`no-project`]);function isPublishErrorCode(e){return typeof e==`string`&&PUBLISH_ERROR_CODES.has(e)}function parsePublishEvent(e){if(e===null)return{ok:!1,error:`network`};if(e.type===`publish`){let t=typeof e.ownerLogin==`string`?e.ownerLogin:null,S=typeof e.repoName==`string`?e.repoName:null,w=typeof e.cloneUrl==`string`?e.cloneUrl:null,E=typeof e.defaultBranch==`string`?e.defaultBranch:null;return t!==null&&S!==null&&w!==null&&E!==null?{ok:!0,ownerLogin:t,repoName:S,cloneUrl:w,defaultBranch:E}:{ok:!1,error:`network`}}return e.type===`error`?{ok:!1,error:isPublishErrorCode(e.code)?e.code:`network`}:{ok:!1,error:`network`}}function emitSharePublishLog(e,t,S){let w=[`action=${e}`,`result=${t}`];S?.count!==void 0&&w.push(`count=${S.count}`),S?.available!==void 0&&w.push(`available=${S.available}`),console.log(`[share] ${w.join(` `)}`)}function redactShareSubprocessStderr(e){return e.replace(/(https?:\/\/)([^:@\s/]+):([^@\s/]+)@/g,`$1$2:***@`)}const MAX_ZIP_BYTES=102400,BUNDLE_SKILL_NAME={discovery:`open-knowledge-discovery`,project:`open-knowledge`},DESKTOP_SKILLS_REL=`Open Knowledge.app/Contents/Resources/cli/dist/assets/skills`;function resolveBundledSkillDir(e,t={}){let S=t.platform??process.platform,w=t.checkDesktop??!0,E=t.home??homedir(),D=[];w&&S===`darwin`&&(D.push(join(`/Applications`,DESKTOP_SKILLS_REL,e)),D.push(join(E,`Applications`,DESKTOP_SKILLS_REL,e))),D.push(fileURLToPath(new URL(`../dist/assets/skills/${e}`,import.meta.url))),D.push(fileURLToPath(new URL(`../assets/skills/${e}`,import.meta.url))),D.push(fileURLToPath(new URL(`./assets/skills/${e}`,import.meta.url)));for(let e of D)if(existsSync(e))return e;throw Error(`Bundled skill asset directory not found for bundle '${e}'. Tried: ${D.join(`, `)}. This usually means the CLI build did not copy packages/server/assets into dist/assets. Run \`cd packages/cli && bun run build\` before publishing.`)}async function*walkFiles(e,t=e){let S=await readdir(e,{withFileTypes:!0});for(let w of S){let S=join(e,w.name);w.isDirectory()?yield*walkFiles(S,t):w.isFile()&&(yield relative(t,S))}}function computeWrapperFolderName(e,t=basename){return t(e)||`open-knowledge`}function toPosixZipPath(e,t=sep){return t===`/`?e:e.split(t).join(`/`)}async function zipDirectory(e,t,S=computeWrapperFolderName(e)){let w=new import_yazl.ZipFile;w.addEmptyDirectory(`${S}/`);let E=[];for await(let t of walkFiles(e))E.push(t);E.sort();for(let t of E){let E=join(e,t),D=`${S}/${toPosixZipPath(t)}`;w.addFile(E,D)}w.end(),await new Promise((e,S)=>{let E=createWriteStream(t);w.outputStream.pipe(E),E.on(`close`,()=>e()),E.on(`error`,S),w.outputStream.on(`error`,S)})}async function sha256OfFile(e){return new Promise((t,S)=>{let w=createHash(`sha256`),E=createReadStream(e);E.on(`data`,e=>w.update(e)),E.on(`end`,()=>t(w.digest(`hex`))),E.on(`error`,S)})}function extractMetadataVersion(e){let t=e.indexOf(`
|
|
1187
1187
|
---`,4);if(!e.startsWith(`---
|
|
1188
1188
|
`)||t<0)return;let S=e.slice(4,t),w=S.search(/^metadata:/m);if(w<0)return;let E=S.slice(w).split(`
|
|
1189
|
-
`).slice(1);for(let e of E){if(/^[^\s]/.test(e))break;let t=e.match(/^\s+version:\s*["']?([^"'\s]+)["']?$/);if(t)return t[1]}}async function validateSkillZip(e,t){let S=statSync(e).size;if(S>MAX_ZIP_BYTES)throw Error(`Built ${e} is ${S} bytes, exceeds ${MAX_ZIP_BYTES}-byte ceiling`);let w=await sha256OfFile(e),E=await readFile$1(join(resolveBundledSkillDir(),`SKILL.md`),`utf-8`);if(!/^name:\s+open-knowledge$/m.test(E.slice(0,1e3)))throw Error("SKILL.md frontmatter `name:` does not match 'open-knowledge'. Check packages/server/assets/skills/open-knowledge/SKILL.md frontmatter.");let D=extractMetadataVersion(E);if(t!==void 0){if(!D)throw Error("SKILL.md metadata.version missing. Add it to packages/server/assets/skills/open-knowledge/SKILL.md or run `bash scripts/sync-skill-version.sh`.");if(D!==t)throw Error(`SKILL.md metadata.version (${D}) does not match expected version (${t}). Run \`bash scripts/sync-skill-version.sh\` after bumping package versions.`)}return{size:S,sha256:w,skillVersion:D}}async function buildSkillZip(e={}){let t=e.sourceDir??resolveBundledSkillDir(),S=e.outputPath??join(process.cwd(),`openknowledge.skill`);await zipDirectory(t,S);let{size:w,sha256:E,skillVersion:D}=await validateSkillZip(S,e.expectedSkillVersion);return{outputPath:S,size:w,sha256:E,skillVersion:D}}const SKILL_INSTALL_EVENTS_FILE_REL=[`.ok`,`skill-install-events.jsonl`];async function recordSkillInstallEvent(e,t){let S=t?.homedir??(()=>process.env.HOME??``),w=t?.warn??((e,t)=>{console.warn(t,e)}),E=S();if(!E){w({event:`skill-install-events.no-home`},`[skill-install-events] HOME not resolvable; telemetry skipped`);return}let D=join(E,...SKILL_INSTALL_EVENTS_FILE_REL),O=`${JSON.stringify(e)}\n`;try{await tracedMkdir(dirname(D),{recursive:!0})}catch(e){w({event:`skill-install-events.mkdir-failed`,error:String(e)},`[skill-install-events] mkdir failed; telemetry skipped`);return}try{await tracedWriteFile(D,O,{flag:`a`,encoding:`utf-8`})}catch(e){w({event:`skill-install-events.append-failed`,error:String(e)},`[skill-install-events] append failed; telemetry skipped`)}}const readFileAsync=promisify(readFile);function skillStateYamlPath(e){return join(e,...SKILL_STATE_REL)}const DEFAULT_LOGGER={warn:(e,t)=>console.warn(t,e)},TRACED_FS_ADAPTER={writeFile:(e,t,S)=>tracedWriteFile(e,t,S),rename:(e,t)=>tracedRename(e,t)};async function readSkillStateFile(e,t=DEFAULT_LOGGER){let S=skillStateYamlPath(e),w;try{w=await readFileAsync(S,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}let E=(0,import_dist$1.parseDocument)(w);if(E.errors.length>0)return t.warn({event:`skill-state.yaml-parse-error`,path:S,errors:E.errors.map(e=>e.message)},`skill-state.yml parse failed; treating as fresh install`),null;let D=SkillStateSchema.safeParse(E.toJSON());if(!D.success){let e=D.error.issues.find(e=>e.path.length===1&&e.path[0]===`schema`);return e?t.warn({event:`skill-state.invalid-schema-version`,path:S,issue:e.message},`skill-state.yml has unknown schema version; treating as fresh install`):t.warn({event:`skill-state.schema-violation`,path:S,issues:D.error.issues.map(e=>({path:e.path,message:e.message}))},`skill-state.yml failed schema validation; treating as fresh install`),null}return D.data}async function writeSkillStateFile(e,t){let S=SkillStateSchema.safeParse(t);if(!S.success)throw Error(`Refusing to write invalid skill-state: ${S.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `)}`);let w=skillStateYamlPath(e);await tracedMkdir(dirname(w),{recursive:!0});let E=(0,import_dist$1.parseDocument)(``);E.contents=E.createNode(S.data),await atomicWriteFile(w,E.toString(),{fs:TRACED_FS_ADAPTER})}async function readTargetVersion(e,t,S){let w=await readSkillStateFile(e,S);return w===null?null:w.targets[t]?.version??null}async function readTargetRecordedAt(e,t,S){let w=await readSkillStateFile(e,S);return w===null?null:w.targets[t]?.recordedAt??null}async function writeTargetVersion(e,t,S,w,E){if(!SKILL_STATE_VERSION_RE.test(S))throw Error(`Refusing to write invalid version string: ${S}`);let D=await readSkillStateFile(e,E)??emptySkillState(),O=new Date().toISOString(),k=D.targets[t],j=w===void 0?k?.surface??void 0:w,F=j===void 0?{version:S,recordedAt:O}:{version:S,recordedAt:O,surface:j};await writeSkillStateFile(e,{...D,targets:{...D.targets,[t]:F}})}async function readServerPackageVersion(){let e=await readFileAsync(fileURLToPath(new URL(`../package.json`,import.meta.url)),`utf-8`),t=JSON.parse(e);if(typeof t.version!=`string`||t.version.length===0)throw Error(`@inkeep/open-knowledge-server/package.json missing version field`);return t.version}async function readSkillInstallStateSnapshot(e,t){let[S,w]=await Promise.all([readServerPackageVersion(),readAllTargets(e,t)]);return{currentVersion:S,targets:w}}async function readAllTargets(e,t=DEFAULT_LOGGER){let S=null;try{S=await readSkillStateFile(e,t)}catch(w){t.warn({event:`skill-state.read-error`,path:skillStateYamlPath(e),error:String(w)},`non-ENOENT error reading skill-state.yml; treating as absent`),S=null}let w=SKILL_STATE_TARGETS.map(e=>{let t=S?.targets[e];return t?[e,{version:t.version,recordedAt:t.recordedAt}]:[e,null]});return Object.fromEntries(w)}const CENTRAL_SKILL_DIR_REL=[`.agents`,`skills`,`open-knowledge`],SKILLS_CLI_SPEC=`skills@~1.5.0`,DEFAULT_TIMEOUT_MS$3=6e4;function centralSkillDir(e){return join(e,...CENTRAL_SKILL_DIR_REL)}async function centralSkillExists(e){try{return(await stat$1(centralSkillDir(e))).isDirectory()}catch{return!1}}function runSpawn(e,t,S,w,E){return new Promise(D=>{let O;try{O=e(t,S,{env:w,stdio:[`ignore`,`pipe`,`pipe`]})}catch(e){D({kind:`spawn-error`,stderr:``,error:e});return}let k=``,j=!1,F=e=>{j||(j=!0,clearTimeout(L),D(e))};O.stderr?.on(`data`,e=>{k+=typeof e==`string`?e:e.toString(`utf-8`)}),O.on(`error`,e=>{F({kind:`spawn-error`,stderr:k,error:e})}),O.on(`exit`,e=>{F(e===0?{kind:`ok`,exitCode:e,stderr:k}:{kind:`nonzero`,exitCode:e,stderr:k})});let L=setTimeout(()=>{try{O.kill(`SIGTERM`)}catch{}F({kind:`timeout`,stderr:k})},E)})}async function installUserSkill(e={}){let t=e.home??homedir(),S=e.logger??{warn:(e,t)=>console.warn(t,e),info:(e,t)=>console.info(t,e)},w=e.spawn??spawn,E=e.timeoutMs??DEFAULT_TIMEOUT_MS$3,D=e.surface??`cli-npx-skills-add`,O=async(e,w,E)=>{await recordSkillInstallEvent({ts:new Date().toISOString(),surface:D,target:`cli-hosts`,outcome:e,...w===void 0?{}:{version:w},...E===void 0?{}:{reason:E}},{homedir:()=>t,warn:S.warn})},k;try{k=await readServerPackageVersion()}catch(e){return S.warn({event:`skill-install.failed`,reason:`version-read-failed`,error:String(e)},`Skill install aborted — could not read @inkeep/open-knowledge-server version.`),await O(`failed`,void 0,`version-read-failed`),`failed`}let j=await readTargetVersion(t,`cli-hosts`,S).catch(e=>(S.warn({event:`skill-install.gate.read-failed`,error:String(e)},`Could not read cli-hosts install-state; proceeding with fresh install.`),null));if(j!==null&&j===k){if(await centralSkillExists(t))return S.info?.({event:`skill-install.skip-current`,version:k},`Open Knowledge skill already installed at current version; skipping.`),await O(`skip-current`,k),`skip-current`;S.info?.({event:`skill-install.reinstall-missing`,version:k,path:centralSkillDir(t)},`Sidecar matches current version but skill files are missing; reinstalling.`)}let F;try{F=resolveBundledSkillDir()}catch(e){return S.warn({event:`skill-install.failed`,reason:`bundled-asset-missing`,error:String(e)},`Skill install aborted — bundled SKILL.md asset not found.`),await O(`failed`,k,`bundled-asset-missing`),`failed`}let L=await runSpawn(w,`npx`,[`-y`,SKILLS_CLI_SPEC,`add`,F,`--agent`,`*`,`-g`,`-y`,`--copy`],{...process.env,HOME:t},E);if(L.kind===`ok`){try{await writeTargetVersion(t,`cli-hosts`,k,D,S)}catch(e){return S.warn({event:`skill-install.failed`,reason:`sidecar-write-failed`,error:String(e)},`Skill install succeeded but sidecar write failed.`),await O(`failed`,k,`sidecar-write-failed`),`failed`}return S.info?.({event:`skill-install.installed`,version:k},`Open Knowledge skill installed to detected agent hosts.`),await O(`installed`,k),`installed`}return L.kind===`timeout`?(S.warn({event:`skill-install.failed`,reason:`timeout`,timeoutMs:E,stderr:L.stderr},`Skill install subprocess timed out. Run manually: npx ${SKILLS_CLI_SPEC} add ${F} --agent '*' -g -y --copy`),await O(`failed`,k,`timeout`),`failed`):L.kind===`spawn-error`?(S.warn({event:`skill-install.failed`,reason:`spawn-error`,error:String(L.error),stderr:L.stderr},`Skill install failed — \`npx\` unavailable or spawn errored. Run manually: npx ${SKILLS_CLI_SPEC} add ${F} --agent '*' -g -y --copy`),await O(`failed`,k,`spawn-error`),`failed`):(S.warn({event:`skill-install.failed`,reason:`nonzero-exit`,exitCode:L.exitCode,stderr:L.stderr},`Skill install subprocess exited non-zero. Run manually: npx ${SKILLS_CLI_SPEC} add ${F} --agent '*' -g -y --copy`),await O(`failed`,k,`nonzero-exit:${L.exitCode??`unknown`}`),`failed`)}const DOWNLOADS_DIR=`Downloads`,SKILL_FILENAME=`openknowledge.skill`;function defaultDownloadsPath(e){return join(e,DOWNLOADS_DIR,SKILL_FILENAME)}function invokeFileAssociation(e,t,S){let w={detached:!0,stdio:`ignore`};try{return t===`darwin`?(S(`open`,[e],w).unref(),{ok:!0}):t===`win32`?(S(`cmd`,[`/c`,`start`,`""`,e],w).unref(),{ok:!0}):t===`linux`?(S(`xdg-open`,[e],w).unref(),{ok:!0}):{ok:!1,reason:`unsupported-platform`,message:`Platform '${t}' has no file-association invocation wired.`}}catch(e){return{ok:!1,reason:`spawn-error`,message:e instanceof Error?e.message:String(e)}}}async function buildAndOpenSkill(e={}){let t=e.home??homedir(),S=resolve(e.out??defaultDownloadsPath(t)),w=e.platformName??platform(),E=e.spawnFn??spawn,D=e.logger,O=async(e,S,w)=>{await recordSkillInstallEvent({ts:new Date().toISOString(),surface:`server-build-and-open`,target:`claude-cowork`,outcome:e,...S===void 0?{}:{version:S},...w===void 0?{}:{reason:w}},{homedir:()=>t,warn:D?.warn})};if(!e.force){let e=null;try{e=await readServerPackageVersion()}catch(e){D?.warn?.({event:`skill-install.gate.version-read-failed`,error:String(e)},`Could not read @inkeep/open-knowledge-server version for gate check; rebuilding.`)}if(e!==null){let S=null,w=null;try{[S,w]=await Promise.all([readTargetVersion(t,`claude-cowork`,D),readTargetRecordedAt(t,`claude-cowork`,D)])}catch(e){D?.warn?.({event:`skill-install.gate.read-failed`,error:String(e)},`Could not read claude-cowork install-state; rebuilding.`)}if(S!==null&&S===e)return D?.info?.({event:`skill-install.skip-current`,target:`claude-cowork`,version:e},`Open Knowledge skill already delivered at current version; skipping rebuild.`),await O(`skip-current`,e),{status:`skip-current`,skillVersion:e,...w===null?{}:{recordedAt:w}}}}try{await tracedMkdir(dirname(S),{recursive:!0})}catch(e){let t=e instanceof Error?e.message:String(e);return await O(`failed`,void 0,`mkdir-failed:${t}`),{status:`failed`,buildError:`could not create output directory: ${t}`}}let k;try{k=await buildSkillZip({outputPath:S})}catch(e){let t=e instanceof Error?e.message:String(e);return await O(`failed`,void 0,`build-failed:${t}`),{status:`failed`,buildError:t}}let j={status:`built`,outputPath:k.outputPath,size:k.size,sha256:k.sha256,skillVersion:k.skillVersion};if(k.skillVersion)try{await writeTargetVersion(t,`claude-cowork`,k.skillVersion,`server-build-and-open`,D)}catch(e){D?.warn?.({event:`skill-install.state-write-failed`,target:`claude-cowork`,version:k.skillVersion,error:String(e)},`Skill bundle built but install-state write failed; gate will re-trigger build on next click.`)}if(e.noOpen)return await O(`built`,k.skillVersion),j;let F=invokeFileAssociation(k.outputPath,w,E);return F.ok?(await O(`installed`,k.skillVersion),{...j,status:`installed`}):(await O(`built`,k.skillVersion,`handoff-${F.reason}`),{...j,handoffError:{reason:F.reason,message:F.message}})}var UiLockCollisionError=class extends ProcessLockCollisionError{constructor(e,t){super(e,t,`ui`),this.name=`UiLockCollisionError`}};function acquireUiLock(e,t){try{return acquireProcessLock({lockName:`ui`,lockDir:e,metadata:t}).lockPath}catch(e){throw e instanceof ProcessLockCollisionError&&e.lockName===`ui`?new UiLockCollisionError(e.existing,e.lockPath):e}}function updateUiLockPort(e,t){updateProcessLockPort({lockName:`ui`,lockDir:e,port:t})}function readUiLock(e){return readProcessLock({lockName:`ui`,lockDir:e})}function releaseUiLock(e){releaseProcessLock({lockName:`ui`,lockDir:e})}var UploadWriteError=class extends Error{reason;constructor(e,t){super(`UploadWriteError: ${e}`,{cause:t}),this.name=`UploadWriteError`,this.reason=e}};function uploadStatusFor(e){switch(e){case`urn:ok:error:malformed-upload`:return 400;case`urn:ok:error:storage-full`:return 507;case`urn:ok:error:storage-readonly`:return 500;case`urn:ok:error:storage-error`:return 500;case`urn:ok:error:collision-exhaustion`:return 500;default:return assertNeverProblemType(e)}}function classifyUploadErrno(e){return e.code===`ENOSPC`||e.code===`EDQUOT`?`urn:ok:error:storage-full`:e.code===`EROFS`||e.code===`EACCES`||e.code===`EPERM`?`urn:ok:error:storage-readonly`:`urn:ok:error:storage-error`}function uploadTitleFor(e){switch(e){case`urn:ok:error:malformed-upload`:return`Upload payload is malformed.`;case`urn:ok:error:storage-full`:return`Storage is full.`;case`urn:ok:error:storage-readonly`:return`Storage is read-only.`;case`urn:ok:error:storage-error`:return`Failed to write upload.`;case`urn:ok:error:collision-exhaustion`:return`Filename collision retries exhausted.`;default:return assertNeverProblemType(e)}}const log$4=getLogger(`upload-streaming`);var HashingPassThrough=class extends Transform{hash=createHash(`sha256`);bytes=0;digested=!1;_transform(e,t,S){this.hash.update(e),this.bytes+=e.length,S(null,e)}digest(){if(this.digested)throw Error(`HashingPassThrough.digest() already called`);return this.digested=!0,this.hash.digest(`hex`)}byteLength(){return this.bytes}};function tmpUploadDir(e){return resolve(getLocalDir(e),`tmp`)}function mintTempUploadPath(e){let t=tmpUploadDir(e);return tracedMkdirSync(t,{recursive:!0}),resolve(t,`upload-${randomUUID()}`)}function linkTempToFinalWithCollisionRetry(e,t,S){let w=extname(S),E=S.slice(0,S.length-w.length),D=[S,...Array.from({length:99},(e,t)=>`${E}-${t+1}${w}`)];for(let S of D){let w=resolve(t,S);try{tracedLinkSync(e,w);try{tracedUnlinkSync(e)}catch{}return S}catch(t){let S=t.code;if(S===`EEXIST`)continue;try{tracedUnlinkSync(e)}catch{}throw S===`ENOSPC`||S===`EDQUOT`?new UploadWriteError(`urn:ok:error:storage-full`,t):S===`EROFS`||S===`EACCES`||S===`EPERM`?new UploadWriteError(`urn:ok:error:storage-readonly`,t):new UploadWriteError(`urn:ok:error:storage-error`,t)}}try{tracedUnlinkSync(e)}catch{}throw new UploadWriteError(`urn:ok:error:collision-exhaustion`)}function cleanupOrphanUploadTempfiles(e,{ageMs:t=1440*60*1e3}={}){let S=tmpUploadDir(e),w={scanned:0,deleted:0,errors:0};if(!existsSync(S))return w;let E;try{E=readdirSync(S)}catch(e){return log$4.warn({err:e,dir:S},`[upload-tempfile-sweep] readdir failed`),w.errors++,w}let D=Date.now()-t;for(let e of E){if(!e.startsWith(`upload-`))continue;w.scanned++;let t=resolve(S,e);try{if(statSync(t).mtimeMs>=D)continue;tracedUnlinkSync(t),w.deleted++}catch(e){log$4.warn({err:e,path:t},`[upload-tempfile-sweep] entry failed`),w.errors++}}return(w.deleted>0||w.errors>0)&&log$4.info({dir:S,scanned:w.scanned,deleted:w.deleted,errors:w.errors},`[upload-tempfile-sweep] swept ${w.deleted}/${w.scanned} (errors: ${w.errors})`),w}function matchFence$2(e){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(!t)return null;let S=t[1],w=S[0];return w!=="`"&&w!==`~`?null:{char:w,length:S.length}}function isFenceClose$2(e,t){return RegExp(`^\\s{0,3}\\${t.char}{${t.length},}\\s*$`).test(e)}function leadingMarkdownPrefixLength$2(e){let t=/^\s{0,3}(?:#{1,6}\s+|>\s+|(?:[-+*]|\d+[.)])\s+)/.exec(e);return t?t[0].length:0}function readInlineCode$2(e,t){let S=0;for(;e[t+S]==="`";)S++;if(S===0)return null;let w=t+S,E=w;for(;E<e.length;){if(e[E]!=="`"){E++;continue}let t=0;for(;e[E+t]==="`";)t++;if(t===S)return{nextIndex:E+S};E+=t}return{nextIndex:w}}function readWikiLink$2(e,t){let S=/^\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/.exec(e.slice(t));if(!S)return null;let w=S[1]?.trim(),E=S[2]?.trim()||null,D=S[3]?.trim()||null;return w?{target:w,alias:D,anchor:E,nextIndex:t+S[0].length}:null}function readMarkdownLink$2(e,t){let S=/^\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)((?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?)\)/.exec(e.slice(t));if(!S)return null;let w=S[2]??``;return{text:S[1]??``,hrefRaw:w,href:w.startsWith(`<`)&&w.endsWith(`>`)?w.slice(1,-1):w,titleSuffix:S[3]??``,nextIndex:t+S[0].length}}function readImageRef(e,t){let S=/^!\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)((?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?)\)/.exec(e.slice(t));if(!S)return null;let w=S[2]??``;return{alt:S[1]??``,hrefRaw:w,href:w.startsWith(`<`)&&w.endsWith(`>`)?w.slice(1,-1):w,titleSuffix:S[3]??``,nextIndex:t+S[0].length}}function splitLines(e){let t=e.split(/(\r\n|\r|\n)/),S=[];for(let e=0;e<t.length;e+=2)S.push({line:t[e]??``,ending:t[e+1]??``});return S}function rewriteWikiLinksInLine(e,t,S){let w=``,E=0,D=0,O=leadingMarkdownPrefixLength$2(e);for(O>0&&(w+=e.slice(0,O),D=O);D<e.length;){if(e[D]===`\\`&&D+1<e.length){w+=e.slice(D,D+2),D+=2;continue}if(e[D]==="`"){let t=readInlineCode$2(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`[`&&e[D+1]===`[`){let O=readWikiLink$2(e,D);if(O){O.target===t?(w+=`[[${S}${O.anchor?`#${O.anchor}`:``}${O.alias?`|${O.alias}`:``}]]`,E++):w+=e.slice(D,O.nextIndex),D=O.nextIndex;continue}}w+=e[D],D++}return{markdown:w,rewrites:E}}function recomputeRelativeImageHref(e,t,S){let w=e.indexOf(`#`),E=w>=0?e.slice(w):``,D=w>=0?e.slice(0,w):e,O=D.indexOf(`?`),k=O>=0?D.slice(O):``,j=O>=0?D.slice(0,O):D;if(j.startsWith(`/`)||j.startsWith(`//`)||/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(j))return null;let F=posix.dirname(t),L=posix.dirname(S);if(F===L)return null;let B=F===`.`?`/`:`/${F}/`,H=posix.resolve(B,j).slice(1),q=posix.relative(L===`.`?``:L,H);return q||=posix.basename(H),j.startsWith(`./`)&&!q.startsWith(`./`)&&!q.startsWith(`../`)&&(q=`./${q}`),`${q}${k}${E}`}function recomputeRelativeMarkdownHref(e,t,S){let w=e.indexOf(`#`),E=w>=0?e.slice(w):``,D=w>=0?e.slice(0,w):e,O=D.indexOf(`?`),k=O>=0?D.slice(O):``,j=O>=0?D.slice(0,O):D,F=posix.dirname(t),L=posix.relative(F===`.`?``:F,S);return L||=posix.basename(S),j.endsWith(`.mdx`)?L+=`.mdx`:j.endsWith(`.md`)&&(L+=`.md`),j.startsWith(`./`)&&!L.startsWith(`./`)&&!L.startsWith(`../`)&&(L=`./${L}`),`${L}${k}${E}`}function rewriteMarkdownLinksInLine(e,t,S,w){let E=``,D=0,O=0,k=leadingMarkdownPrefixLength$2(e);for(k>0&&(E+=e.slice(0,k),O=k);O<e.length;){if(e[O]===`\\`&&O+1<e.length){E+=e.slice(O,O+2),O+=2;continue}if(e[O]==="`"){let t=readInlineCode$2(e,O);if(t){E+=e.slice(O,t.nextIndex),O=t.nextIndex;continue}}if(e[O]===`[`&&e[O+1]===`[`){let t=readWikiLink$2(e,O);if(t){E+=e.slice(O,t.nextIndex),O=t.nextIndex;continue}}if(e[O]===`!`&&e[O+1]===`[`){let k=readImageRef(e,O);if(k){let j=t===S&&S!==w?recomputeRelativeImageHref(k.href,S,w):null;if(j!==null){let e=k.hrefRaw.startsWith(`<`)&&k.hrefRaw.endsWith(`>`)?`<${j}>`:j;E+=``,D++}else E+=e.slice(O,k.nextIndex);O=k.nextIndex;continue}}if(e[O]===`[`){let k=readMarkdownLink$2(e,O);if(k){if(resolveInternalHref(k.href,t)?.docName===S){let e=recomputeRelativeMarkdownHref(k.href,t,w),S=k.hrefRaw.startsWith(`<`)&&k.hrefRaw.endsWith(`>`)?`<${e}>`:e;E+=`[${k.text}](${S}${k.titleSuffix})`,D++}else E+=e.slice(O,k.nextIndex);O=k.nextIndex;continue}}E+=e[O],O++}return{markdown:E,rewrites:D}}const MIRROR_TAG_RE=/<Mirror\b([^>]*)\/>/g,MIRROR_SRC_ATTR_RE=/(\bsrc=)(["'])([^"']*)\2/g;function rewriteMirrorSrcInLine(e,t,S){let w=``,E=0,D=0;for(;D<e.length;){if(e[D]===`\\`&&D+1<e.length){w+=e.slice(D,D+2),D+=2;continue}if(e[D]==="`"){let t=readInlineCode$2(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`<`){let O=new RegExp(MIRROR_TAG_RE.source),k=e.slice(D),j=O.exec(k);if(j&&j.index===0){let[e,O]=j,k=new RegExp(MIRROR_SRC_ATTR_RE.source,MIRROR_SRC_ATTR_RE.flags),F=O.replace(k,(e,w,D,O)=>O===t?(E++,`${w}${D}${S}${D}`):e);w+=`<Mirror${F}/>`,D+=e.length;continue}}w+=e[D],D++}return{markdown:w,rewrites:E}}function rewriteMirrorSrcForDocumentRename(e,t,S){let w=null,E=0;return{markdown:splitLines(e).map(({line:e,ending:D})=>{if(w)return isFenceClose$2(e,w)&&(w=null),`${e}${D}`;let O=matchFence$2(e);if(O)return w=O,`${e}${D}`;let k=rewriteMirrorSrcInLine(e,t,S);return E+=k.rewrites,`${k.markdown}${D}`}).join(``),rewrites:E}}function rewriteWikiLinksForDocumentRename(e,t,S){let w=null,E=0;return{markdown:splitLines(e).map(({line:e,ending:D})=>{if(w)return isFenceClose$2(e,w)&&(w=null),`${e}${D}`;let O=matchFence$2(e);if(O)return w=O,`${e}${D}`;let k=rewriteWikiLinksInLine(e,t,S);return E+=k.rewrites,`${k.markdown}${D}`}).join(``),rewrites:E}}function rewriteMarkdownLinksForDocumentRename(e,t,S,w){let E=null,D=0;return{markdown:splitLines(e).map(({line:e,ending:O})=>{if(E)return isFenceClose$2(e,E)&&(E=null),`${e}${O}`;let k=matchFence$2(e);if(k)return E=k,`${e}${O}`;let j=rewriteMarkdownLinksInLine(e,t,S,w);return D+=j.rewrites,`${j.markdown}${O}`}).join(``),rewrites:D}}function rewriteOutboundMarkdownLinksInLine(e,t,S){let w=``,E=0,D=0,O=leadingMarkdownPrefixLength$2(e);for(O>0&&(w+=e.slice(0,O),D=O);D<e.length;){if(e[D]===`\\`&&D+1<e.length){w+=e.slice(D,D+2),D+=2;continue}if(e[D]==="`"){let t=readInlineCode$2(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`[`&&e[D+1]===`[`){let t=readWikiLink$2(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`!`&&e[D+1]===`[`){let t=readImageRef(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`[`){let O=readMarkdownLink$2(e,D);if(O){let k=resolveInternalHref(O.href,t);if(k!==null){let t=recomputeRelativeMarkdownHref(O.href,S,k.docName);if(t!==O.href){let e=O.hrefRaw.startsWith(`<`)&&O.hrefRaw.endsWith(`>`)?`<${t}>`:t;w+=`[${O.text}](${e}${O.titleSuffix})`,E++}else w+=e.slice(D,O.nextIndex)}else w+=e.slice(D,O.nextIndex);D=O.nextIndex;continue}}w+=e[D],D++}return{markdown:w,rewrites:E}}function rewriteOutboundMarkdownLinksForSourceMove(e,t,S){if(posix.dirname(t)===posix.dirname(S))return{markdown:e,rewrites:0};let w=null,E=0;return{markdown:splitLines(e).map(({line:e,ending:D})=>{if(w)return isFenceClose$2(e,w)&&(w=null),`${e}${D}`;let O=matchFence$2(e);if(O)return w=O,`${e}${D}`;let k=rewriteOutboundMarkdownLinksInLine(e,t,S);return E+=k.rewrites,`${k.markdown}${D}`}).join(``),rewrites:E}}var ManagedRenameCollisionError=class extends Error{colliding;constructor(e){super(`Managed rename collision: ${e.map(e=>`'${e.existing}' and '${e.incoming}' both target '${e.to}'`).join(`; `)}`),this.name=`ManagedRenameCollisionError`,this.colliding=e}},ManagedRenameSourceNotFoundError=class extends Error{kind;constructor(e){super(`${e} does not exist`),this.name=`ManagedRenameSourceNotFoundError`,this.kind=e}},ManagedRenameDestinationExistsError=class extends Error{constructor(){super(`Destination already exists`),this.name=`ManagedRenameDestinationExistsError`}},ManagedRenameSourceTypeMismatchError=class extends Error{kind;constructor(e){super(`Source path is not a ${e}`),this.name=`ManagedRenameSourceTypeMismatchError`,this.kind=e}},SymlinkEscapeError=class extends Error{constructor(e){super(`symlink-escape: ${e}`),this.name=`SymlinkEscapeError`}},BacklinkIndexRequiredError=class extends Error{constructor(){super(`Managed rename requires backlink index support`),this.name=`BacklinkIndexRequiredError`}},ManagedRenameSnapshotMissingError=class extends Error{docName;constructor(e){super(`Cannot snapshot missing document: ${e}`),this.name=`ManagedRenameSnapshotMissingError`,this.docName=e}},ManagedRenameMissingDocumentError=class extends Error{docName;constructor(e){super(`Cannot rename missing document: ${e}`),this.name=`ManagedRenameMissingDocumentError`,this.docName=e}};function buildRenameMap(e){let t=new Map,S=[];for(let{from:w,to:E}of e){for(let[e,D]of t)e!==w&&D===E&&S.push({existing:e,incoming:w,to:E});t.set(w,E)}if(S.length>0)throw new ManagedRenameCollisionError(S);return t}function rewriteSupportedLinksForRename(e,t,S,w){let{frontmatter:E,body:D}=stripFrontmatter(e),O=rewriteWikiLinksForDocumentRename(D,S,w),k=rewriteMarkdownLinksForDocumentRename(O.markdown,t,S,w),j=rewriteMirrorSrcForDocumentRename(k.markdown,S,w);return{markdown:prependFrontmatter(E,j.markdown),rewrites:O.rewrites+k.rewrites+j.rewrites}}function applyRenameMap(e,t,S){let w=e,E=0,D,O=[];for(let[e,w]of S)e!==w&&(e===t?D=w:O.push([e,w]));if(D!==void 0){let e=rewriteSupportedLinksForRename(w,t,t,D);w=e.markdown,E+=e.rewrites;let{frontmatter:S,body:O}=stripFrontmatter(w),k=rewriteOutboundMarkdownLinksForSourceMove(O,t,D);w=prependFrontmatter(S,k.markdown),E+=k.rewrites}let k=D??t,j=new Map;for(let[e,t]of O){let S=`__OK_RENAME_${randomUUID().replaceAll(`-`,``)}__`,D=rewriteSupportedLinksForRename(w,k,e,S);D.rewrites>0&&(w=D.markdown,E+=D.rewrites,j.set(S,t))}for(let[e,t]of j)w=rewriteSupportedLinksForRename(w,k,e,t).markdown;return{markdown:w,rewrites:E}}const WIKI_LINK_RE$1=/\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/y,MD_LINK_RE$1=/\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y;function createEmptyState$1(){return{backward:new Map,forward:new Map,externalForward:new Map,externalBackward:new Map}}function mergeLinkMeta(e,t){return e?{anchor:e.anchor??t.anchor,snippet:e.snippet??t.snippet}:t}function getRepresentativeAnchor(e){if(!e)return null;for(let[,t]of[...e.entries()].sort(([e],[t])=>e.localeCompare(t)))if(t.anchor)return t.anchor;return null}function externalNodeId(e){return`external:${e}`}function externalUrlFromNodeId(e){return e.startsWith(`external:`)?e.slice(9):null}function normalizeSnippet$1(e){return e.replace(/\s+/g,` `).trim()}function snippetAround$1(e,t,S){if(!normalizeSnippet$1(e))return null;let w=Math.max(e.lastIndexOf(`.`,t-1),e.lastIndexOf(`?`,t-1),e.lastIndexOf(`!`,t-1),e.lastIndexOf(`
|
|
1189
|
+
`).slice(1);for(let e of E){if(/^[^\s]/.test(e))break;let t=e.match(/^\s+version:\s*["']?([^"'\s]+)["']?$/);if(t)return t[1]}}async function validateSkillZip(e,t,S={}){let w=S.bundle??`project`,E=statSync(e).size;if(E>MAX_ZIP_BYTES)throw Error(`Built ${e} is ${E} bytes, exceeds ${MAX_ZIP_BYTES}-byte ceiling`);let D=await sha256OfFile(e),O=await readFile$1(join(S.sourceDir??resolveBundledSkillDir(w,{checkDesktop:!1}),`SKILL.md`),`utf-8`),k=BUNDLE_SKILL_NAME[w];if(!RegExp(`^name:\\s+${k}$`,`m`).test(O.slice(0,1500)))throw Error(`SKILL.md frontmatter \`name:\` does not match '${k}'. Check packages/server/assets/skills/${w}/SKILL.md frontmatter.`);let j=extractMetadataVersion(O);if(t!==void 0){if(!j)throw Error(`SKILL.md metadata.version missing. Add it to packages/server/assets/skills/${w}/SKILL.md.`);if(j!==t)throw Error(`SKILL.md metadata.version (${j}) does not match expected version (${t}).`)}return{size:E,sha256:D,skillVersion:j}}async function buildSkillZip(e={}){let t=e.bundle??`project`,S=e.sourceDir??resolveBundledSkillDir(t,{checkDesktop:!0}),w=e.outputPath??join(process.cwd(),`openknowledge.skill`);await zipDirectory(S,w,BUNDLE_SKILL_NAME[t]);let{size:E,sha256:D,skillVersion:O}=await validateSkillZip(w,e.expectedSkillVersion,{bundle:t,sourceDir:S});return{outputPath:w,size:E,sha256:D,skillVersion:O}}const SKILL_INSTALL_EVENTS_FILE_REL=[`.ok`,`skill-install-events.jsonl`];async function recordSkillInstallEvent(e,t){let S=t?.homedir??(()=>process.env.HOME??``),w=t?.warn??((e,t)=>{console.warn(t,e)}),E=S();if(!E){w({event:`skill-install-events.no-home`},`[skill-install-events] HOME not resolvable; telemetry skipped`);return}let D=join(E,...SKILL_INSTALL_EVENTS_FILE_REL),O=`${JSON.stringify(e)}\n`;try{await tracedMkdir(dirname(D),{recursive:!0})}catch(e){w({event:`skill-install-events.mkdir-failed`,error:String(e)},`[skill-install-events] mkdir failed; telemetry skipped`);return}try{await tracedWriteFile(D,O,{flag:`a`,encoding:`utf-8`})}catch(e){w({event:`skill-install-events.append-failed`,error:String(e)},`[skill-install-events] append failed; telemetry skipped`)}}const readFileAsync=promisify(readFile);function skillStateYamlPath(e){return join(e,...SKILL_STATE_REL)}const DEFAULT_LOGGER={warn:(e,t)=>console.warn(t,e)},TRACED_FS_ADAPTER={writeFile:(e,t,S)=>tracedWriteFile(e,t,S),rename:(e,t)=>tracedRename(e,t)};async function readSkillStateFile(e,t=DEFAULT_LOGGER){let S=skillStateYamlPath(e),w;try{w=await readFileAsync(S,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}let E=(0,import_dist$1.parseDocument)(w);if(E.errors.length>0)return t.warn({event:`skill-state.yaml-parse-error`,path:S,errors:E.errors.map(e=>e.message)},`skill-state.yml parse failed; treating as fresh install`),null;let D=SkillStateSchema.safeParse(E.toJSON());if(!D.success){let e=D.error.issues.find(e=>e.path.length===1&&e.path[0]===`schema`);return e?t.warn({event:`skill-state.invalid-schema-version`,path:S,issue:e.message},`skill-state.yml has unknown schema version; treating as fresh install`):t.warn({event:`skill-state.schema-violation`,path:S,issues:D.error.issues.map(e=>({path:e.path,message:e.message}))},`skill-state.yml failed schema validation; treating as fresh install`),null}return D.data}async function writeSkillStateFile(e,t){let S=SkillStateSchema.safeParse(t);if(!S.success)throw Error(`Refusing to write invalid skill-state: ${S.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `)}`);let w=skillStateYamlPath(e);await tracedMkdir(dirname(w),{recursive:!0});let E=(0,import_dist$1.parseDocument)(``);E.contents=E.createNode(S.data),await atomicWriteFile(w,E.toString(),{fs:TRACED_FS_ADAPTER})}async function readTargetVersion(e,t,S){let w=await readSkillStateFile(e,S);return w===null?null:w.targets[t]?.version??null}async function readTargetRecordedAt(e,t,S){let w=await readSkillStateFile(e,S);return w===null?null:w.targets[t]?.recordedAt??null}async function writeTargetVersion(e,t,S,w,E){if(!SKILL_STATE_VERSION_RE.test(S))throw Error(`Refusing to write invalid version string: ${S}`);let D=await readSkillStateFile(e,E)??emptySkillState(),O=new Date().toISOString(),k=D.targets[t],j=w===void 0?k?.surface??void 0:w,F=j===void 0?{version:S,recordedAt:O}:{version:S,recordedAt:O,surface:j};await writeSkillStateFile(e,{...D,targets:{...D.targets,[t]:F}})}async function readServerPackageVersion(){let e=await readFileAsync(fileURLToPath(new URL(`../package.json`,import.meta.url)),`utf-8`),t=JSON.parse(e);if(typeof t.version!=`string`||t.version.length===0)throw Error(`@inkeep/open-knowledge-server/package.json missing version field`);return t.version}async function readSkillInstallStateSnapshot(e,t){let[S,w]=await Promise.all([readServerPackageVersion(),readAllTargets(e,t)]);return{currentVersion:S,targets:w}}async function readAllTargets(e,t=DEFAULT_LOGGER){let S=null;try{S=await readSkillStateFile(e,t)}catch(w){t.warn({event:`skill-state.read-error`,path:skillStateYamlPath(e),error:String(w)},`non-ENOENT error reading skill-state.yml; treating as absent`),S=null}let w=SKILL_STATE_TARGETS.map(e=>{let t=S?.targets[e];return t?[e,{version:t.version,recordedAt:t.recordedAt}]:[e,null]});return Object.fromEntries(w)}const CENTRAL_SKILL_DIR_REL=[`.agents`,`skills`,`open-knowledge-discovery`],LEGACY_USER_SKILL_NAME=`open-knowledge`,LEGACY_USER_SKILL_HOST_DIRS=[`.claude`,`.cursor`,`.agents`],SKILLS_CLI_SPEC=`skills@~1.5.0`,DEFAULT_TIMEOUT_MS$3=6e4;function centralSkillDir(e){return join(e,...CENTRAL_SKILL_DIR_REL)}async function centralSkillExists(e){try{return(await stat$1(centralSkillDir(e))).isDirectory()}catch{return!1}}function runSpawn(e,t,S,w,E){return new Promise(D=>{let O;try{O=e(t,S,{env:w,stdio:[`ignore`,`pipe`,`pipe`]})}catch(e){D({kind:`spawn-error`,stderr:``,error:e});return}let k=``,j=!1,F=e=>{j||(j=!0,clearTimeout(L),D(e))};O.stderr?.on(`data`,e=>{k+=typeof e==`string`?e:e.toString(`utf-8`)}),O.on(`error`,e=>{F({kind:`spawn-error`,stderr:k,error:e})}),O.on(`exit`,e=>{F(e===0?{kind:`ok`,exitCode:e,stderr:k}:{kind:`nonzero`,exitCode:e,stderr:k})});let L=setTimeout(()=>{try{O.kill(`SIGTERM`)}catch{}F({kind:`timeout`,stderr:k})},E)})}async function anyLegacyUserSkillExists(e){for(let t of LEGACY_USER_SKILL_HOST_DIRS)try{if((await stat$1(join(e,t,`skills`,LEGACY_USER_SKILL_NAME))).isDirectory())return!0}catch{}return!1}async function removeLegacyUserSkill(e,t,S,w,E){if(!await anyLegacyUserSkillExists(e))return;let D=await runSpawn(t,`npx`,[`-y`,SKILLS_CLI_SPEC,`remove`,`--agent`,`*`,`-g`,LEGACY_USER_SKILL_NAME],S,w);D.kind!==`ok`&&E.warn({event:`skill-install.legacy-remove-failed`,reason:D.kind,exitCode:D.exitCode,stderr:D.stderr},"Legacy `open-knowledge` skill removal did not exit cleanly; continuing with install.")}async function installUserSkill(e={}){let t=e.home??homedir(),S=e.logger??{warn:(e,t)=>console.warn(t,e),info:(e,t)=>console.info(t,e)},w=e.spawn??spawn,E=e.timeoutMs??DEFAULT_TIMEOUT_MS$3,D=e.surface??`cli-npx-skills-add`,O=async(e,w,E)=>{await recordSkillInstallEvent({ts:new Date().toISOString(),surface:D,target:`cli-hosts`,bundle:`discovery`,outcome:e,...w===void 0?{}:{version:w},...E===void 0?{}:{reason:E}},{homedir:()=>t,warn:S.warn})},k;try{k=await readServerPackageVersion()}catch(e){return S.warn({event:`skill-install.failed`,reason:`version-read-failed`,error:String(e)},`Skill install aborted — could not read @inkeep/open-knowledge-server version.`),await O(`failed`,void 0,`version-read-failed`),`failed`}let j=await readTargetVersion(t,`cli-hosts`,S).catch(e=>(S.warn({event:`skill-install.gate.read-failed`,error:String(e)},`Could not read cli-hosts install-state; proceeding with fresh install.`),null));if(j!==null&&j===k){if(await centralSkillExists(t))return S.info?.({event:`skill-install.skip-current`,version:k},`Open Knowledge skill already installed at current version; skipping.`),await O(`skip-current`,k),`skip-current`;S.info?.({event:`skill-install.reinstall-missing`,version:k,path:centralSkillDir(t)},`Sidecar matches current version but skill files are missing; reinstalling.`)}let F;try{F=resolveBundledSkillDir(`discovery`,{checkDesktop:!1})}catch(e){return S.warn({event:`skill-install.failed`,reason:`bundled-asset-missing`,error:String(e)},`Skill install aborted — bundled discovery SKILL.md asset not found.`),await O(`failed`,k,`bundled-asset-missing`),`failed`}let L={...process.env,HOME:t};await removeLegacyUserSkill(t,w,L,E,S);let B=await runSpawn(w,`npx`,[`-y`,SKILLS_CLI_SPEC,`add`,F,`--agent`,`*`,`-g`,`-y`,`--copy`],L,E);if(B.kind===`ok`){try{await writeTargetVersion(t,`cli-hosts`,k,D,S)}catch(e){return S.warn({event:`skill-install.failed`,reason:`sidecar-write-failed`,error:String(e)},`Skill install succeeded but sidecar write failed.`),await O(`failed`,k,`sidecar-write-failed`),`failed`}return S.info?.({event:`skill-install.installed`,version:k},`Open Knowledge skill installed to detected agent hosts.`),await O(`installed`,k),`installed`}return B.kind===`timeout`?(S.warn({event:`skill-install.failed`,reason:`timeout`,timeoutMs:E,stderr:B.stderr},`Skill install subprocess timed out. Run manually: npx ${SKILLS_CLI_SPEC} add ${F} --agent '*' -g -y --copy`),await O(`failed`,k,`timeout`),`failed`):B.kind===`spawn-error`?(S.warn({event:`skill-install.failed`,reason:`spawn-error`,error:String(B.error),stderr:B.stderr},`Skill install failed — \`npx\` unavailable or spawn errored. Run manually: npx ${SKILLS_CLI_SPEC} add ${F} --agent '*' -g -y --copy`),await O(`failed`,k,`spawn-error`),`failed`):(S.warn({event:`skill-install.failed`,reason:`nonzero-exit`,exitCode:B.exitCode,stderr:B.stderr},`Skill install subprocess exited non-zero. Run manually: npx ${SKILLS_CLI_SPEC} add ${F} --agent '*' -g -y --copy`),await O(`failed`,k,`nonzero-exit:${B.exitCode??`unknown`}`),`failed`)}const DOWNLOADS_DIR=`Downloads`,SKILL_FILENAME=`openknowledge.skill`;function defaultDownloadsPath(e){return join(e,DOWNLOADS_DIR,SKILL_FILENAME)}function invokeFileAssociation(e,t,S){let w={detached:!0,stdio:`ignore`};try{return t===`darwin`?(S(`open`,[e],w).unref(),{ok:!0}):t===`win32`?(S(`cmd`,[`/c`,`start`,`""`,e],w).unref(),{ok:!0}):t===`linux`?(S(`xdg-open`,[e],w).unref(),{ok:!0}):{ok:!1,reason:`unsupported-platform`,message:`Platform '${t}' has no file-association invocation wired.`}}catch(e){return{ok:!1,reason:`spawn-error`,message:e instanceof Error?e.message:String(e)}}}async function buildAndOpenSkill(e={}){let t=e.home??homedir(),S=resolve(e.out??defaultDownloadsPath(t)),w=e.platformName??platform(),E=e.spawnFn??spawn,D=e.logger,O=async(e,S,w)=>{await recordSkillInstallEvent({ts:new Date().toISOString(),surface:`server-build-and-open`,target:`claude-cowork`,bundle:`project`,outcome:e,...S===void 0?{}:{version:S},...w===void 0?{}:{reason:w}},{homedir:()=>t,warn:D?.warn})};if(!e.force){let e=null;try{e=await readServerPackageVersion()}catch(e){D?.warn?.({event:`skill-install.gate.version-read-failed`,error:String(e)},`Could not read @inkeep/open-knowledge-server version for gate check; rebuilding.`)}if(e!==null){let S=null,w=null;try{[S,w]=await Promise.all([readTargetVersion(t,`claude-cowork`,D),readTargetRecordedAt(t,`claude-cowork`,D)])}catch(e){D?.warn?.({event:`skill-install.gate.read-failed`,error:String(e)},`Could not read claude-cowork install-state; rebuilding.`)}if(S!==null&&S===e)return D?.info?.({event:`skill-install.skip-current`,target:`claude-cowork`,version:e},`Open Knowledge skill already delivered at current version; skipping rebuild.`),await O(`skip-current`,e),{status:`skip-current`,skillVersion:e,...w===null?{}:{recordedAt:w}}}}try{await tracedMkdir(dirname(S),{recursive:!0})}catch(e){let t=e instanceof Error?e.message:String(e);return await O(`failed`,void 0,`mkdir-failed:${t}`),{status:`failed`,buildError:`could not create output directory: ${t}`}}let k;try{k=await buildSkillZip({outputPath:S,bundle:`project`})}catch(e){let t=e instanceof Error?e.message:String(e);return await O(`failed`,void 0,`build-failed:${t}`),{status:`failed`,buildError:t}}let j={status:`built`,outputPath:k.outputPath,size:k.size,sha256:k.sha256,skillVersion:k.skillVersion};if(k.skillVersion)try{await writeTargetVersion(t,`claude-cowork`,k.skillVersion,`server-build-and-open`,D)}catch(e){D?.warn?.({event:`skill-install.state-write-failed`,target:`claude-cowork`,version:k.skillVersion,error:String(e)},`Skill bundle built but install-state write failed; gate will re-trigger build on next click.`)}if(e.noOpen)return await O(`built`,k.skillVersion),j;let F=invokeFileAssociation(k.outputPath,w,E);return F.ok?(await O(`installed`,k.skillVersion),{...j,status:`installed`}):(await O(`built`,k.skillVersion,`handoff-${F.reason}`),{...j,handoffError:{reason:F.reason,message:F.message}})}var UiLockCollisionError=class extends ProcessLockCollisionError{constructor(e,t){super(e,t,`ui`),this.name=`UiLockCollisionError`}};function acquireUiLock(e,t){try{return acquireProcessLock({lockName:`ui`,lockDir:e,metadata:t}).lockPath}catch(e){throw e instanceof ProcessLockCollisionError&&e.lockName===`ui`?new UiLockCollisionError(e.existing,e.lockPath):e}}function updateUiLockPort(e,t){updateProcessLockPort({lockName:`ui`,lockDir:e,port:t})}function readUiLock(e){return readProcessLock({lockName:`ui`,lockDir:e})}function releaseUiLock(e){releaseProcessLock({lockName:`ui`,lockDir:e})}var UploadWriteError=class extends Error{reason;constructor(e,t){super(`UploadWriteError: ${e}`,{cause:t}),this.name=`UploadWriteError`,this.reason=e}};function uploadStatusFor(e){switch(e){case`urn:ok:error:malformed-upload`:return 400;case`urn:ok:error:storage-full`:return 507;case`urn:ok:error:storage-readonly`:return 500;case`urn:ok:error:storage-error`:return 500;case`urn:ok:error:collision-exhaustion`:return 500;default:return assertNeverProblemType(e)}}function classifyUploadErrno(e){return e.code===`ENOSPC`||e.code===`EDQUOT`?`urn:ok:error:storage-full`:e.code===`EROFS`||e.code===`EACCES`||e.code===`EPERM`?`urn:ok:error:storage-readonly`:`urn:ok:error:storage-error`}function uploadTitleFor(e){switch(e){case`urn:ok:error:malformed-upload`:return`Upload payload is malformed.`;case`urn:ok:error:storage-full`:return`Storage is full.`;case`urn:ok:error:storage-readonly`:return`Storage is read-only.`;case`urn:ok:error:storage-error`:return`Failed to write upload.`;case`urn:ok:error:collision-exhaustion`:return`Filename collision retries exhausted.`;default:return assertNeverProblemType(e)}}const log$4=getLogger(`upload-streaming`);var HashingPassThrough=class extends Transform{hash=createHash(`sha256`);bytes=0;digested=!1;_transform(e,t,S){this.hash.update(e),this.bytes+=e.length,S(null,e)}digest(){if(this.digested)throw Error(`HashingPassThrough.digest() already called`);return this.digested=!0,this.hash.digest(`hex`)}byteLength(){return this.bytes}};function tmpUploadDir(e){return resolve(getLocalDir(e),`tmp`)}function mintTempUploadPath(e){let t=tmpUploadDir(e);return tracedMkdirSync(t,{recursive:!0}),resolve(t,`upload-${randomUUID()}`)}function linkTempToFinalWithCollisionRetry(e,t,S){let w=extname(S),E=S.slice(0,S.length-w.length),D=[S,...Array.from({length:99},(e,t)=>`${E}-${t+1}${w}`)];for(let S of D){let w=resolve(t,S);try{tracedLinkSync(e,w);try{tracedUnlinkSync(e)}catch{}return S}catch(t){let S=t.code;if(S===`EEXIST`)continue;try{tracedUnlinkSync(e)}catch{}throw S===`ENOSPC`||S===`EDQUOT`?new UploadWriteError(`urn:ok:error:storage-full`,t):S===`EROFS`||S===`EACCES`||S===`EPERM`?new UploadWriteError(`urn:ok:error:storage-readonly`,t):new UploadWriteError(`urn:ok:error:storage-error`,t)}}try{tracedUnlinkSync(e)}catch{}throw new UploadWriteError(`urn:ok:error:collision-exhaustion`)}function cleanupOrphanUploadTempfiles(e,{ageMs:t=1440*60*1e3}={}){let S=tmpUploadDir(e),w={scanned:0,deleted:0,errors:0};if(!existsSync(S))return w;let E;try{E=readdirSync(S)}catch(e){return log$4.warn({err:e,dir:S},`[upload-tempfile-sweep] readdir failed`),w.errors++,w}let D=Date.now()-t;for(let e of E){if(!e.startsWith(`upload-`))continue;w.scanned++;let t=resolve(S,e);try{if(statSync(t).mtimeMs>=D)continue;tracedUnlinkSync(t),w.deleted++}catch(e){log$4.warn({err:e,path:t},`[upload-tempfile-sweep] entry failed`),w.errors++}}return(w.deleted>0||w.errors>0)&&log$4.info({dir:S,scanned:w.scanned,deleted:w.deleted,errors:w.errors},`[upload-tempfile-sweep] swept ${w.deleted}/${w.scanned} (errors: ${w.errors})`),w}function matchFence$2(e){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(!t)return null;let S=t[1],w=S[0];return w!=="`"&&w!==`~`?null:{char:w,length:S.length}}function isFenceClose$2(e,t){return RegExp(`^\\s{0,3}\\${t.char}{${t.length},}\\s*$`).test(e)}function leadingMarkdownPrefixLength$2(e){let t=/^\s{0,3}(?:#{1,6}\s+|>\s+|(?:[-+*]|\d+[.)])\s+)/.exec(e);return t?t[0].length:0}function readInlineCode$2(e,t){let S=0;for(;e[t+S]==="`";)S++;if(S===0)return null;let w=t+S,E=w;for(;E<e.length;){if(e[E]!=="`"){E++;continue}let t=0;for(;e[E+t]==="`";)t++;if(t===S)return{nextIndex:E+S};E+=t}return{nextIndex:w}}function readWikiLink$2(e,t){let S=/^\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/.exec(e.slice(t));if(!S)return null;let w=S[1]?.trim(),E=S[2]?.trim()||null,D=S[3]?.trim()||null;return w?{target:w,alias:D,anchor:E,nextIndex:t+S[0].length}:null}function readMarkdownLink$2(e,t){let S=/^\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)((?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?)\)/.exec(e.slice(t));if(!S)return null;let w=S[2]??``;return{text:S[1]??``,hrefRaw:w,href:w.startsWith(`<`)&&w.endsWith(`>`)?w.slice(1,-1):w,titleSuffix:S[3]??``,nextIndex:t+S[0].length}}function readImageRef(e,t){let S=/^!\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)((?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?)\)/.exec(e.slice(t));if(!S)return null;let w=S[2]??``;return{alt:S[1]??``,hrefRaw:w,href:w.startsWith(`<`)&&w.endsWith(`>`)?w.slice(1,-1):w,titleSuffix:S[3]??``,nextIndex:t+S[0].length}}function splitLines(e){let t=e.split(/(\r\n|\r|\n)/),S=[];for(let e=0;e<t.length;e+=2)S.push({line:t[e]??``,ending:t[e+1]??``});return S}function rewriteWikiLinksInLine(e,t,S){let w=``,E=0,D=0,O=leadingMarkdownPrefixLength$2(e);for(O>0&&(w+=e.slice(0,O),D=O);D<e.length;){if(e[D]===`\\`&&D+1<e.length){w+=e.slice(D,D+2),D+=2;continue}if(e[D]==="`"){let t=readInlineCode$2(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`[`&&e[D+1]===`[`){let O=readWikiLink$2(e,D);if(O){O.target===t?(w+=`[[${S}${O.anchor?`#${O.anchor}`:``}${O.alias?`|${O.alias}`:``}]]`,E++):w+=e.slice(D,O.nextIndex),D=O.nextIndex;continue}}w+=e[D],D++}return{markdown:w,rewrites:E}}function recomputeRelativeImageHref(e,t,S){let w=e.indexOf(`#`),E=w>=0?e.slice(w):``,D=w>=0?e.slice(0,w):e,O=D.indexOf(`?`),k=O>=0?D.slice(O):``,j=O>=0?D.slice(0,O):D;if(j.startsWith(`/`)||j.startsWith(`//`)||/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(j))return null;let F=posix.dirname(t),L=posix.dirname(S);if(F===L)return null;let B=F===`.`?`/`:`/${F}/`,H=posix.resolve(B,j).slice(1),q=posix.relative(L===`.`?``:L,H);return q||=posix.basename(H),j.startsWith(`./`)&&!q.startsWith(`./`)&&!q.startsWith(`../`)&&(q=`./${q}`),`${q}${k}${E}`}function recomputeRelativeMarkdownHref(e,t,S){let w=e.indexOf(`#`),E=w>=0?e.slice(w):``,D=w>=0?e.slice(0,w):e,O=D.indexOf(`?`),k=O>=0?D.slice(O):``,j=O>=0?D.slice(0,O):D,F=posix.dirname(t),L=posix.relative(F===`.`?``:F,S);return L||=posix.basename(S),j.endsWith(`.mdx`)?L+=`.mdx`:j.endsWith(`.md`)&&(L+=`.md`),j.startsWith(`./`)&&!L.startsWith(`./`)&&!L.startsWith(`../`)&&(L=`./${L}`),`${L}${k}${E}`}function rewriteMarkdownLinksInLine(e,t,S,w){let E=``,D=0,O=0,k=leadingMarkdownPrefixLength$2(e);for(k>0&&(E+=e.slice(0,k),O=k);O<e.length;){if(e[O]===`\\`&&O+1<e.length){E+=e.slice(O,O+2),O+=2;continue}if(e[O]==="`"){let t=readInlineCode$2(e,O);if(t){E+=e.slice(O,t.nextIndex),O=t.nextIndex;continue}}if(e[O]===`[`&&e[O+1]===`[`){let t=readWikiLink$2(e,O);if(t){E+=e.slice(O,t.nextIndex),O=t.nextIndex;continue}}if(e[O]===`!`&&e[O+1]===`[`){let k=readImageRef(e,O);if(k){let j=t===S&&S!==w?recomputeRelativeImageHref(k.href,S,w):null;if(j!==null){let e=k.hrefRaw.startsWith(`<`)&&k.hrefRaw.endsWith(`>`)?`<${j}>`:j;E+=``,D++}else E+=e.slice(O,k.nextIndex);O=k.nextIndex;continue}}if(e[O]===`[`){let k=readMarkdownLink$2(e,O);if(k){if(resolveInternalHref(k.href,t)?.docName===S){let e=recomputeRelativeMarkdownHref(k.href,t,w),S=k.hrefRaw.startsWith(`<`)&&k.hrefRaw.endsWith(`>`)?`<${e}>`:e;E+=`[${k.text}](${S}${k.titleSuffix})`,D++}else E+=e.slice(O,k.nextIndex);O=k.nextIndex;continue}}E+=e[O],O++}return{markdown:E,rewrites:D}}const MIRROR_TAG_RE=/<Mirror\b([^>]*)\/>/g,MIRROR_SRC_ATTR_RE=/(\bsrc=)(["'])([^"']*)\2/g;function rewriteMirrorSrcInLine(e,t,S){let w=``,E=0,D=0;for(;D<e.length;){if(e[D]===`\\`&&D+1<e.length){w+=e.slice(D,D+2),D+=2;continue}if(e[D]==="`"){let t=readInlineCode$2(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`<`){let O=new RegExp(MIRROR_TAG_RE.source),k=e.slice(D),j=O.exec(k);if(j&&j.index===0){let[e,O]=j,k=new RegExp(MIRROR_SRC_ATTR_RE.source,MIRROR_SRC_ATTR_RE.flags),F=O.replace(k,(e,w,D,O)=>O===t?(E++,`${w}${D}${S}${D}`):e);w+=`<Mirror${F}/>`,D+=e.length;continue}}w+=e[D],D++}return{markdown:w,rewrites:E}}function rewriteMirrorSrcForDocumentRename(e,t,S){let w=null,E=0;return{markdown:splitLines(e).map(({line:e,ending:D})=>{if(w)return isFenceClose$2(e,w)&&(w=null),`${e}${D}`;let O=matchFence$2(e);if(O)return w=O,`${e}${D}`;let k=rewriteMirrorSrcInLine(e,t,S);return E+=k.rewrites,`${k.markdown}${D}`}).join(``),rewrites:E}}function rewriteWikiLinksForDocumentRename(e,t,S){let w=null,E=0;return{markdown:splitLines(e).map(({line:e,ending:D})=>{if(w)return isFenceClose$2(e,w)&&(w=null),`${e}${D}`;let O=matchFence$2(e);if(O)return w=O,`${e}${D}`;let k=rewriteWikiLinksInLine(e,t,S);return E+=k.rewrites,`${k.markdown}${D}`}).join(``),rewrites:E}}function rewriteMarkdownLinksForDocumentRename(e,t,S,w){let E=null,D=0;return{markdown:splitLines(e).map(({line:e,ending:O})=>{if(E)return isFenceClose$2(e,E)&&(E=null),`${e}${O}`;let k=matchFence$2(e);if(k)return E=k,`${e}${O}`;let j=rewriteMarkdownLinksInLine(e,t,S,w);return D+=j.rewrites,`${j.markdown}${O}`}).join(``),rewrites:D}}function rewriteOutboundMarkdownLinksInLine(e,t,S){let w=``,E=0,D=0,O=leadingMarkdownPrefixLength$2(e);for(O>0&&(w+=e.slice(0,O),D=O);D<e.length;){if(e[D]===`\\`&&D+1<e.length){w+=e.slice(D,D+2),D+=2;continue}if(e[D]==="`"){let t=readInlineCode$2(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`[`&&e[D+1]===`[`){let t=readWikiLink$2(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`!`&&e[D+1]===`[`){let t=readImageRef(e,D);if(t){w+=e.slice(D,t.nextIndex),D=t.nextIndex;continue}}if(e[D]===`[`){let O=readMarkdownLink$2(e,D);if(O){let k=resolveInternalHref(O.href,t);if(k!==null){let t=recomputeRelativeMarkdownHref(O.href,S,k.docName);if(t!==O.href){let e=O.hrefRaw.startsWith(`<`)&&O.hrefRaw.endsWith(`>`)?`<${t}>`:t;w+=`[${O.text}](${e}${O.titleSuffix})`,E++}else w+=e.slice(D,O.nextIndex)}else w+=e.slice(D,O.nextIndex);D=O.nextIndex;continue}}w+=e[D],D++}return{markdown:w,rewrites:E}}function rewriteOutboundMarkdownLinksForSourceMove(e,t,S){if(posix.dirname(t)===posix.dirname(S))return{markdown:e,rewrites:0};let w=null,E=0;return{markdown:splitLines(e).map(({line:e,ending:D})=>{if(w)return isFenceClose$2(e,w)&&(w=null),`${e}${D}`;let O=matchFence$2(e);if(O)return w=O,`${e}${D}`;let k=rewriteOutboundMarkdownLinksInLine(e,t,S);return E+=k.rewrites,`${k.markdown}${D}`}).join(``),rewrites:E}}var ManagedRenameCollisionError=class extends Error{colliding;constructor(e){super(`Managed rename collision: ${e.map(e=>`'${e.existing}' and '${e.incoming}' both target '${e.to}'`).join(`; `)}`),this.name=`ManagedRenameCollisionError`,this.colliding=e}},ManagedRenameSourceNotFoundError=class extends Error{kind;constructor(e){super(`${e} does not exist`),this.name=`ManagedRenameSourceNotFoundError`,this.kind=e}},ManagedRenameDestinationExistsError=class extends Error{constructor(){super(`Destination already exists`),this.name=`ManagedRenameDestinationExistsError`}},ManagedRenameSourceTypeMismatchError=class extends Error{kind;constructor(e){super(`Source path is not a ${e}`),this.name=`ManagedRenameSourceTypeMismatchError`,this.kind=e}},SymlinkEscapeError=class extends Error{constructor(e){super(`symlink-escape: ${e}`),this.name=`SymlinkEscapeError`}},BacklinkIndexRequiredError=class extends Error{constructor(){super(`Managed rename requires backlink index support`),this.name=`BacklinkIndexRequiredError`}},ManagedRenameSnapshotMissingError=class extends Error{docName;constructor(e){super(`Cannot snapshot missing document: ${e}`),this.name=`ManagedRenameSnapshotMissingError`,this.docName=e}},ManagedRenameMissingDocumentError=class extends Error{docName;constructor(e){super(`Cannot rename missing document: ${e}`),this.name=`ManagedRenameMissingDocumentError`,this.docName=e}};function buildRenameMap(e){let t=new Map,S=[];for(let{from:w,to:E}of e){for(let[e,D]of t)e!==w&&D===E&&S.push({existing:e,incoming:w,to:E});t.set(w,E)}if(S.length>0)throw new ManagedRenameCollisionError(S);return t}function rewriteSupportedLinksForRename(e,t,S,w){let{frontmatter:E,body:D}=stripFrontmatter(e),O=rewriteWikiLinksForDocumentRename(D,S,w),k=rewriteMarkdownLinksForDocumentRename(O.markdown,t,S,w),j=rewriteMirrorSrcForDocumentRename(k.markdown,S,w);return{markdown:prependFrontmatter(E,j.markdown),rewrites:O.rewrites+k.rewrites+j.rewrites}}function applyRenameMap(e,t,S){let w=e,E=0,D,O=[];for(let[e,w]of S)e!==w&&(e===t?D=w:O.push([e,w]));if(D!==void 0){let e=rewriteSupportedLinksForRename(w,t,t,D);w=e.markdown,E+=e.rewrites;let{frontmatter:S,body:O}=stripFrontmatter(w),k=rewriteOutboundMarkdownLinksForSourceMove(O,t,D);w=prependFrontmatter(S,k.markdown),E+=k.rewrites}let k=D??t,j=new Map;for(let[e,t]of O){let S=`__OK_RENAME_${randomUUID().replaceAll(`-`,``)}__`,D=rewriteSupportedLinksForRename(w,k,e,S);D.rewrites>0&&(w=D.markdown,E+=D.rewrites,j.set(S,t))}for(let[e,t]of j)w=rewriteSupportedLinksForRename(w,k,e,t).markdown;return{markdown:w,rewrites:E}}const WIKI_LINK_RE$1=/\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/y,MD_LINK_RE$1=/\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y;function createEmptyState$1(){return{backward:new Map,forward:new Map,externalForward:new Map,externalBackward:new Map}}function mergeLinkMeta(e,t){return e?{anchor:e.anchor??t.anchor,snippet:e.snippet??t.snippet}:t}function getRepresentativeAnchor(e){if(!e)return null;for(let[,t]of[...e.entries()].sort(([e],[t])=>e.localeCompare(t)))if(t.anchor)return t.anchor;return null}function externalNodeId(e){return`external:${e}`}function externalUrlFromNodeId(e){return e.startsWith(`external:`)?e.slice(9):null}function normalizeSnippet$1(e){return e.replace(/\s+/g,` `).trim()}function snippetAround$1(e,t,S){if(!normalizeSnippet$1(e))return null;let w=Math.max(e.lastIndexOf(`.`,t-1),e.lastIndexOf(`?`,t-1),e.lastIndexOf(`!`,t-1),e.lastIndexOf(`
|
|
1190
1190
|
`,t-1)),E=[e.indexOf(`.`,S),e.indexOf(`?`,S),e.indexOf(`!`,S),e.indexOf(`
|
|
1191
1191
|
`,S)].filter(e=>e>=0),D=w>=0?w+1:Math.max(0,t-60),O=E.length>0?Math.min(...E)+1:Math.min(e.length,S+60),k=D>0?`…`:``,j=O<e.length?`…`:``,F=normalizeSnippet$1(e.slice(D,O));return F?`${k}${F}${j}`:null}function matchFence$1(e){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(!t)return null;let S=t[1],w=S[0];return w!=="`"&&w!==`~`?null:{char:w,length:S.length}}function isFenceClose$1(e,t){return RegExp(`^\\s{0,3}\\${t.char}{${t.length},}\\s*$`).test(e)}function leadingMarkdownPrefixLength$1(e){let t=/^\s{0,3}(?:#{1,6}\s+|>\s+|(?:[-+*]|\d+[.)])\s+)/.exec(e);return t?t[0].length:0}function readInlineCode$1(e,t){let S=0;for(;e[t+S]==="`";)S++;if(S===0)return null;let w=t+S,E=w;for(;E<e.length;){if(e[E]!=="`"){E++;continue}let t=0;for(;e[E+t]==="`";)t++;if(t===S)return{text:e.slice(w,E),nextIndex:E+S};E+=t}return{text:e.slice(t,w),nextIndex:w}}function readWikiLink$1(e,t){WIKI_LINK_RE$1.lastIndex=t;let S=WIKI_LINK_RE$1.exec(e);if(!S)return null;let w=S[1]?.trim(),E=S[2]?.trim()||null,D=S[3]?.trim()||null;return w?{target:w,alias:D,anchor:E,nextIndex:t+S[0].length}:null}function extractWikiLinksFromLine(e){let t=``,S=[],w=leadingMarkdownPrefixLength$1(e);for(;w<e.length;){if(e[w]===`\\`&&w+1<e.length){t+=e[w+1],w+=2;continue}if(e[w]==="`"){let S=readInlineCode$1(e,w);if(S){t+=S.text,w=S.nextIndex;continue}}if(e[w]===`[`&&e[w+1]===`[`){let E=readWikiLink$1(e,w);if(E){let e=getWikiLinkText(E),D=t.length;t+=e;let O=classifyWikiLinkTarget(E.target,E.anchor);O?.kind===`doc`&&S.push({target:O.docName,anchor:O.anchor,start:D,end:D+e.length}),w=E.nextIndex;continue}}t+=e[w],w++}return{text:t,occurrences:S}}function extractExternalWikiLinksFromLine(e){let t=``,S=[],w=leadingMarkdownPrefixLength$1(e);for(;w<e.length;){if(e[w]===`\\`&&w+1<e.length){t+=e[w+1],w+=2;continue}if(e[w]==="`"){let S=readInlineCode$1(e,w);if(S){t+=S.text,w=S.nextIndex;continue}}if(e[w]===`[`&&e[w+1]===`[`){let E=readWikiLink$1(e,w);if(E){let e=getWikiLinkText(E),D=t.length;t+=e;let O=classifyWikiLinkTarget(E.target,E.anchor);O?.kind===`external`&&S.push({url:O.url,label:e,start:D,end:D+e.length}),w=E.nextIndex;continue}}t+=e[w],w++}return{text:t,occurrences:S}}function normalizeMarkdownHref$1(e){return e.startsWith(`<`)&&e.endsWith(`>`)?e.slice(1,-1):e}function readMarkdownLink$1(e,t){MD_LINK_RE$1.lastIndex=t;let S=MD_LINK_RE$1.exec(e);return S?{text:S[1]??``,href:normalizeMarkdownHref$1(S[2]??``),nextIndex:t+S[0].length}:null}function extractMarkdownLinksFromLine(e,t){let S=``,w=[],E=leadingMarkdownPrefixLength$1(e);for(;E<e.length;){if(e[E]===`\\`&&E+1<e.length){S+=e[E+1],E+=2;continue}if(e[E]==="`"){let t=readInlineCode$1(e,E);if(t){S+=t.text,E=t.nextIndex;continue}}if(e[E]===`[`&&e[E+1]===`[`){let t=readWikiLink$1(e,E);if(t){S+=getWikiLinkText(t),E=t.nextIndex;continue}}if(e[E]===`[`&&e[E-1]!==`!`){let D=readMarkdownLink$1(e,E);if(D){let e=classifyMarkdownHref(D.href,t);if(e?.kind===`doc`){let t=S.length;S+=D.text,w.push({target:e.docName,anchor:e.anchor,start:t,end:t+D.text.length})}else S+=D.text;E=D.nextIndex;continue}}S+=e[E],E++}return{text:S,occurrences:w}}function extractExternalMarkdownLinksFromLine(e,t){let S=``,w=[],E=leadingMarkdownPrefixLength$1(e);for(;E<e.length;){if(e[E]===`\\`&&E+1<e.length){S+=e[E+1],E+=2;continue}if(e[E]==="`"){let t=readInlineCode$1(e,E);if(t){S+=t.text,E=t.nextIndex;continue}}if(e[E]===`[`&&e[E+1]===`[`){let t=readWikiLink$1(e,E);if(t){S+=getWikiLinkText(t),E=t.nextIndex;continue}}if(e[E]===`[`&&e[E-1]!==`!`){let D=readMarkdownLink$1(e,E);if(D){let e=classifyMarkdownHref(D.href,t);if(S+=D.text,e?.kind===`external`){let t=S.length-D.text.length;w.push({url:e.url,label:D.text||null,start:t,end:t+D.text.length})}E=D.nextIndex;continue}}S+=e[E],E++}return{text:S,occurrences:w}}function extractMarkdownLinksFromMarkdown(e,t){let S=e.replaceAll(`\r
|
|
1192
1192
|
`,`
|
|
@@ -1289,7 +1289,7 @@ What to log:
|
|
|
1289
1289
|
- Folder restructures (\`ok seed\`, manual reorganization)
|
|
1290
1290
|
- \`.ok/config.yml\` changes
|
|
1291
1291
|
|
|
1292
|
-
**Reference docs as markdown links, not bare paths.** Every doc you touched should appear as \`[path/to/doc](./path/to/doc.md)\` so the log shows up in \`
|
|
1292
|
+
**Reference docs as markdown links, not bare paths.** Every doc you touched should appear as \`[path/to/doc](./path/to/doc.md)\` so the log shows up in \`links({ kind: "backlinks" })\` for those docs. A bare path string (\`Files touched: foo/bar.md\`) does not register in the doc graph. The audit trail compounds only when the log is a real linker.
|
|
1293
1293
|
|
|
1294
1294
|
<!-- Example entry shape:
|
|
1295
1295
|
|
|
@@ -1988,7 +1988,7 @@ What to log:
|
|
|
1988
1988
|
- Original-thinking captures
|
|
1989
1989
|
- Folder restructures or rule changes
|
|
1990
1990
|
|
|
1991
|
-
**Reference docs as markdown links, not bare paths.** Every doc you touched should appear as \`[name](./path/to/doc.md)\` so the log shows up in \`
|
|
1991
|
+
**Reference docs as markdown links, not bare paths.** Every doc you touched should appear as \`[name](./path/to/doc.md)\` so the log shows up in \`links({ kind: "backlinks" })\` for those docs.
|
|
1992
1992
|
|
|
1993
1993
|
<!-- Example entry shape:
|
|
1994
1994
|
|
|
@@ -2086,7 +2086,7 @@ description: When the agent does scheduled work: daily briefings, end-of-day dos
|
|
|
2086
2086
|
|
|
2087
2087
|
## Monthly
|
|
2088
2088
|
|
|
2089
|
-
- Run OK's \`
|
|
2089
|
+
- Run OK's \`links({ kind: "dead" })\` across the vault. Triage redlinks into new entities (gbrain creates dossiers), typo fixes (OK edits in place), or intentional placeholders.
|
|
2090
2090
|
|
|
2091
2091
|
`,STARTER_PACKS={"knowledge-base":{id:`knowledge-base`,name:`Knowledge base`,description:`Source-grounded canonical articles. Three layers (sources → research → articles) wired to the ingest / research / consolidate MCP tools.`,defaultSubfolder:`brain`,folders:KNOWLEDGE_BASE_FOLDERS,templates:KNOWLEDGE_BASE_TEMPLATES,rootFiles:{"log.md":KNOWLEDGE_BASE_LOG_MD}},"software-lifecycle":{id:`software-lifecycle`,name:`Software lifecycle`,description:`Proposals, decisions, specs, postmortems, guides. The doc lifecycle for an engineering team or OSS project.`,defaultSubfolder:`project-docs`,folders:SOFTWARE_LIFECYCLE_FOLDERS,templates:SOFTWARE_LIFECYCLE_TEMPLATES},"plain-notes":{id:`plain-notes`,name:`Plain notes`,description:`Just notes/ + daily/. The "I just want to write" escape hatch. No posture imposed, link freely.`,defaultSubfolder:void 0,folders:PLAIN_NOTES_FOLDERS,templates:PLAIN_NOTES_TEMPLATES},worldbuilding:{id:`worldbuilding`,name:`Worldbuilding`,description:`Encyclopedia for fiction: characters, settings, themes, factions, lore. The graph is the product; agent excels at auto-stub creation and dead-link sweeps.`,defaultSubfolder:`world`,folders:WORLDBUILDING_FOLDERS,templates:WORLDBUILDING_TEMPLATES},"writing-pipeline":{id:`writing-pipeline`,name:`Writing pipeline`,description:`Three-stage drafting flow: ideas → drafts → published. Lean by default; CRDT history covers per-file revisions.`,defaultSubfolder:`writing`,folders:WRITING_PIPELINE_FOLDERS,templates:WRITING_PIPELINE_TEMPLATES},gbrain:{id:`gbrain`,name:`Gbrain`,description:`Track people, companies, and meetings. Each gets a dossier with a rewritable summary and an append-only timeline. Inspired by Garry Tan's gbrain.`,defaultSubfolder:`vault`,folders:GBRAIN_FOLDERS,templates:GBRAIN_TEMPLATES,rootFiles:{"log.md":GBRAIN_LOG_MD,"USER.md":GBRAIN_USER_MD,"SOUL.md":GBRAIN_SOUL_MD,"ACCESS_POLICY.md":GBRAIN_ACCESS_POLICY_MD,"HEARTBEAT.md":GBRAIN_HEARTBEAT_MD}}},STARTER_PACK_IDS=Object.keys(STARTER_PACKS);function resolvePack(e){return e&&STARTER_PACKS[e]||STARTER_PACKS[DEFAULT_PACK_ID]}function isKnownPackId(e){return typeof e==`string`&&STARTER_PACK_IDS.includes(e)}function coercePackId(e){return isKnownPackId(e)?e:void 0}function deriveFolderSummary(e){let t=e.trim(),S=(/^([^.!?]+[.!?])/.exec(t)?.[1]??t).trim();return S.length<=140?S:`${S.slice(0,137)}…`}function listStarterPacks(){return STARTER_PACK_IDS.map(e=>{let t=STARTER_PACKS[e];return{id:t.id,name:t.name,description:t.description,defaultSubfolder:t.defaultSubfolder,folders:t.folders.map(e=>({path:e.path,summary:deriveFolderSummary(e.description)})),entryCounts:computePackEntryCounts(t)}})}function computePackEntryCounts(e){let t=e.folders.length,S=0;for(let t of e.folders)S+=1+(t.extraTemplates?.length??0);return S+=e.rootFiles?Object.keys(e.rootFiles).length:0,{files:S,folders:t}}const STARTER_FOLDERS=KNOWLEDGE_BASE_FOLDERS,STARTER_TEMPLATES=KNOWLEDGE_BASE_TEMPLATES,LOG_MD_TEMPLATE=KNOWLEDGE_BASE_LOG_MD,STARTER_FOLDER_FRONTMATTER_FILENAME=`frontmatter.yml`;function buildStarterFolderFrontmatterYaml(e){let t=[];t.push(`title: ${yamlScalar(e.title)}`),t.push(`description: ${yamlScalar(e.description)}`),t.push(`tags:`);for(let S of e.tags)t.push(` - ${yamlScalar(S)}`);return`${t.join(`
|
|
2092
2092
|
`)}\n`}function yamlScalar(e){return e===``?`""`:/[:#\n"'\\]|^\s|\s$/.test(e)?`"${e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`:e}function resolveFileContent(e,t){let S=/^([^/]+)\/\.ok\/frontmatter\.yml$/.exec(e);if(S){let e=t.folders.find(e=>e.path===S[1]);return e?buildStarterFolderFrontmatterYaml(e):void 0}let w=/^([^/]+)\/\.ok\/templates\/([^/]+)\.md$/.exec(e);if(w){let e=w[2]??``;return t.templates[e]}if(!e.includes(`/`)&&t.rootFiles?.[e]!==void 0)return t.rootFiles[e]}async function applySeed(e,t={}){let S=Date.now(),w=resolve(t.projectDir??process.cwd()),E=resolvePack(t.packId??`knowledge-base`),D=0,O=[],k=[];for(let t of e.created)try{let e=assertEntryPathInProject(w,t.path);k.push({entry:t,absPath:e})}catch(e){O.push({path:typeof t.path==`string`?t.path:String(t.path),error:e instanceof SeedRootDirError||e instanceof Error?e.message:String(e)})}for(let{entry:e,absPath:t}of k.filter(e=>e.entry.kind===`folder`))try{mkdirSync(t,{recursive:!0}),D+=1}catch(t){O.push({path:e.path,error:t instanceof Error?t.message:String(t)})}for(let{entry:e,absPath:t}of k.filter(e=>e.entry.kind===`file`)){let S=e.template??e.path,w=resolveFileContent(S,E);if(w===void 0){O.push({path:e.path,error:`No content template registered for template id "${S}" in pack "${E.id}"`});continue}if(!existsSync(t))try{writeFileSync(t,w,`utf-8`),D+=1}catch(t){O.push({path:e.path,error:t instanceof Error?t.message:String(t)})}}return{applied:D,errors:O,durationMs:Date.now()-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 w=dirname(t);if(w===t)return null;t=w,S+=1}return null}function frontmatterTemplateId(e){return`${e}/.ok/frontmatter.yml`}function templateFileTemplateId(e,t){return`${e}/.ok/templates/${t}.md`}function normalizeRootDir(e,t){if(!e)return``;let S=e.trim();if(S===``||S===`.`||S===`./`)return``;if(S.startsWith(`/`))throw new SeedRootDirError(`rootDir must be relative to the project directory, got: ${e}`);let w=S.replace(/\\/g,`/`).replace(/^\.\//,``).replace(/\/+$/,``);if(w.split(`/`).some(e=>e===`..`))throw new SeedRootDirError(`rootDir must not contain '..' segments, got: ${e}`);return assertEntryPathInProject(t,w),w}function joinRelative(e,t){return e===``?t:`${e}/${t}`}async function planSeed(e={}){let t=resolve(e.projectDir??process.cwd());if(!isProjectRoot(t))throw new SeedPrerequisiteError(`No ${OK_PROJECT_MARKER} found at ${t}. Run \`ok init\` first to scaffold the tool config.`);let S=normalizeRootDir(e.rootDir,t),w=resolvePack(e.packId??`knowledge-base`),E=[],D=[],O=[];S!==``&&(existsSync(join(t,S))?D.push({path:S,reason:`already-exists`}):E.push({path:S,kind:`folder`}));for(let e of w.folders){let k=joinRelative(S,e.path);existsSync(join(t,k))?D.push({path:k,reason:`already-exists`}):E.push({path:k,kind:`folder`});let j=`${k}/.ok`;existsSync(join(t,j))?D.push({path:j,reason:`already-exists`}):E.push({path:j,kind:`folder`});let F=`${j}/${STARTER_FOLDER_FRONTMATTER_FILENAME}`;existsSync(join(t,F))?D.push({path:F,reason:`already-exists`}):E.push({path:F,kind:`file`,template:frontmatterTemplateId(e.path)});let L=`${j}/templates`;existsSync(join(t,L))?D.push({path:L,reason:`already-exists`}):E.push({path:L,kind:`folder`});let B=[e.starterTemplate,...e.extraTemplates??[]];for(let S of B){let k=`${L}/${S}.md`;if(existsSync(join(t,k))){D.push({path:k,reason:`already-exists`});continue}if(w.templates[S]===void 0){let t=S===e.starterTemplate;O.push(t?`No starter template body registered for "${S}" in pack "${w.id}". The folder will land without a pre-selected template.`:`No body registered for extra template "${S}" in pack "${w.id}". The folder will land without that optional variant.`);continue}E.push({path:k,kind:`file`,template:templateFileTemplateId(e.path,S)})}}if(w.rootFiles)for(let e of Object.keys(w.rootFiles)){let w=joinRelative(S,e);existsSync(join(t,w))?D.push({path:w,reason:`already-exists`}):E.push({path:w,kind:`file`,template:e})}return{created:E,skipped:D,warnings:O}}const log$3=getLogger(`suggest-links`),WORD_CHAR_RE=/[\p{L}\p{N}]/u,WIKI_LINK_RE=/\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/y,MD_LINK_RE=/\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y,MD_IMAGE_RE=/!\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y;var SuggestLinksTargetNotFoundError=class extends Error{constructor(e){super(`Document not found: ${e}`),this.name=`SuggestLinksTargetNotFoundError`}};function normalizeSnippet(e){return e.replace(/\s+/g,` `).trim()}function snippetAround(e,t,S){if(!normalizeSnippet(e))return null;let w=Math.max(e.lastIndexOf(`.`,t-1),e.lastIndexOf(`?`,t-1),e.lastIndexOf(`!`,t-1),e.lastIndexOf(`
|
|
@@ -2109,7 +2109,7 @@ description: When the agent does scheduled work: daily briefings, end-of-day dos
|
|
|
2109
2109
|
`)[0]??``).split(/\s+/)[2];if(S){let w=await e.raw(`cat-file`,`-p`,S);t.writeHead(200,{"Content-Type":`text/markdown`,"X-Content-Type-Options":`nosniff`}),t.end(w);return}}}catch(e){console.warn(`[rescue] timeline-ref fallback failed:`,e)}errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`rescue-get`})}let Ts=withValidation(CreatePageRequestSchema,async(e,t,S)=>{try{let e=extractActorIdentity(S,fe);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`create-page`});return}let E=S.path;if(!isSupportedDocFile(E)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must end with .md or .mdx.`,{handler:`create-page`});return}if(E.includes(`..`)||E.startsWith(`/`)||E.includes(`\0`)||E.includes(`\\`)){errorResponse(t,400,`urn:ok:error:path-escape`,`Invalid path.`,{handler:`create-page`,detail:`path must not contain .. or start with /`});return}let O=resolve(w),k=resolve(O,E);if(!k.startsWith(`${O}/`)&&k!==O){errorResponse(t,400,`urn:ok:error:path-escape`,`path must not escape content directory.`,{handler:`create-page`});return}let j=stripDocExtension(E);if(isSystemDoc(j)||isConfigDoc(j)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${j}' is a reserved document name.`,{handler:`create-page`});return}let F=typeof S.template==`string`?S.template.trim():``,L=``,B;if(F.length>0){if(!/^[A-Za-z0-9_-]+$/.test(F)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Template name must match [A-Za-z0-9_-]+.`,{handler:`create-page`});return}let S=E.includes(`/`)?E.slice(0,E.lastIndexOf(`/`)):``,w=resolveTemplatesAvailable(O,S),D=w.find(e=>e.name===F);if(!D){let e=w.length===0?`(none)`:w.map(e=>`"${e.name}" (${e.scope})`).join(`, `);errorResponse(t,400,`urn:ok:error:invalid-request`,`Template "${F}" does not resolve for folder "${S||`(root)`}". Available: ${e}`,{handler:`create-page`});return}let k=resolve(O,D.path),j;try{j=readFileSync(k,`utf-8`)}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read template at ${D.path}.`,{handler:`create-page`,cause:e});return}let{body:H}=stripFrontmatter(j),q=e.kind===`agent`||e.kind===`principal`?e.displayName??``:``;L=applySubstitution(H,{date:todayIsoUtc(),user:q}),B=D.scope}mkdirSync(dirname(k),{recursive:!0});try{writeFileSync(k,L,{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 H=stripDocExtension(E);switch(ye?.delete(H),me&&me.incrementMdDir(dirname(H)),registerWrite(k,contentHash(L)),e.kind){case`agent`:case`principal`:recordContributor(H,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)}`)}let q=typeof D==`function`?D():null;q instanceof Map&&updateFileIndex({kind:`create`,path:k,docName:H,content:L},q),ee&&(ee.updateDocumentFromMarkdown(H,L),ee.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist create-page cache for ${H}:`,e)}),ne?.(`backlinks`),ne?.(`graph`)),ne?.(`files`),B!==void 0&&console.warn(JSON.stringify({event:`template-instantiate`,templateName:F,templateScope:B,docName:H})),successResponse(t,200,CreatePageSuccessSchema,{docName:H},{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`}),Ds=withValidation(CreateFolderRequestSchema,async(e,t,S)=>{try{if(extractActorIdentity(S,fe).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(me?.isDirExcluded(e)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Destination folder is excluded by the workspace content config.`,{handler:`create-folder`});return}let E=resolveContentEntryPath(w,`folder`,e);if(existsSync(E)){errorResponse(t,409,`urn:ok:error:doc-already-exists`,`Folder already exists.`,{handler:`create-folder`});return}tracedMkdirSync(E,{recursive:!0}),je(e),ne?.(`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`}),Os=withValidation(DuplicatePathRequestSchema,async(e,t,S)=>{try{let e=extractActorIdentity(S,fe);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`duplicate-path`});return}let{kind:E}=S,O=E===`file`?stripDocExtension(S.path):S.path;if(!isValidRelativeContentPath(O)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`duplicate-path`});return}if(O===`.ok`||O.startsWith(`.ok/`)||E===`file`&&(isSystemDoc(O)||isConfigDoc(O))||E===`folder`&&isReservedSyntheticFolderPath(O)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`Reserved paths cannot be duplicated.`,{handler:`duplicate-path`});return}E===`file`&&probeAndRegisterSourceFileExtension(w,O);let k=resolveContentEntryPath(w,E,O);if(!existsSync(k)){if(E===`file`){let e=resolveContentEntryPath(w,`folder`,O);if(existsSync(e)&&statSync(e).isDirectory()){errorResponse(t,400,`urn:ok:error:invalid-request`,`Target path is not a ${E}.`,{handler:`duplicate-path`});return}}errorResponse(t,404,`urn:ok:error:doc-not-found`,`${E} does not exist.`,{handler:`duplicate-path`});return}let j=statSync(k);if(E===`file`&&!j.isFile()||E===`folder`&&!j.isDirectory()){errorResponse(t,400,`urn:ok:error:invalid-request`,`Target path is not a ${E}.`,{handler:`duplicate-path`});return}let F=typeof D==`function`?D():null,L,B=[];if(E===`file`){let e=extname(k);if(L=nextAvailableDuplicateDocName(w,O).docName,isSystemDoc(L)||isConfigDoc(L)||me?.isExcluded(`${L}${e}`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Duplicated document destination is excluded by the project content config.`,{handler:`duplicate-path`});return}let S=resolveDuplicateDocPath(w,L,e),E=readFileSync(k,`utf-8`),D=dirname(S),j=existsSync(D);try{tracedMkdirSync(D,{recursive:!0}),tracedWriteFileSync(S,E,{encoding:`utf-8`,flag:`wx`})}catch(e){if(isAlreadyExistsError(e)){errorResponse(t,409,`urn:ok:error:doc-already-exists`,`A file at the duplicate destination already exists.`,{handler:`duplicate-path`,cause:e});return}if(!j)try{tracedRmdirSync(D)}catch(e){let t=e.code;t!==`ENOENT`&&t!==`ENOTEMPTY`&&console.warn(`[duplicate-path] failed to clean duplicate parent directory:`,{destinationDir:D,err:e})}throw e}let H=!1;try{registerDocExtension(L,e),ye?.delete(L),me&&(me.incrementMdDir(dirname(L)),H=!0),registerWrite(S,contentHash(E)),F instanceof Map&&updateFileIndex({kind:`create`,path:S,docName:L,content:E},F),ee?.updateDocumentFromMarkdown(L,E),B=[L]}catch(e){try{tracedRmSync(S,{force:!0})}catch(e){console.warn(`[duplicate-path] failed to clean partial file duplicate:`,{destinationPath:S,err:e})}throw forgetDocExtension(L),me&&H&&me.decrementMdDir(dirname(L)),F instanceof Map&&updateFileIndex({kind:`delete`,path:S,docName:L},F),e}}else{if(L=nextAvailableDuplicateFolderPath(w,O).folderPath,me?.isDirExcluded(L)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Duplicated folder destination is excluded by the project content config.`,{handler:`duplicate-path`});return}let e=resolveContentEntryPath(w,`folder`,L);try{tracedCpSync(k,e,{recursive:!0,errorOnExist:!0,force:!1})}catch(e){if(isAlreadyExistsError(e)){errorResponse(t,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(w,L))je(e);let e=collectMarkdownCopies(w,L);B=e.map(e=>e.docName);for(let t of e){let e=extname(t.fullPath);registerDocExtension(t.docName,e),ye?.delete(t.docName),me&&me.incrementMdDir(dirname(t.docName)),registerWrite(t.fullPath,contentHash(t.content)),F instanceof Map&&updateFileIndex({kind:`create`,path:t.fullPath,docName:t.docName,content:t.content},F),ee?.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 B)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)}`)}ee&&B.length>0&&(ee.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist duplicate-path cache:`,e)}),ne?.(`backlinks`),ne?.(`graph`)),ne?.(`files`),successResponse(t,200,DuplicatePathSuccessSchema,{kind:E,path:L,duplicatedDocNames:B},{handler:`duplicate-path`})}catch(e){if(e instanceof DuplicateNameExhaustedError){errorResponse(t,409,`urn:ok:error:doc-already-exists`,`All available duplicate name slots are occupied for this path.`,{handler:`duplicate-path`,cause:e});return}let S=classifyDuplicatePathFilesystemProblem(e);if(S){errorResponse(t,S.status,S.type,S.title,{handler:`duplicate-path`,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to duplicate path.`,{handler:`duplicate-path`,cause:e})}},{handler:`duplicate-path`,method:`POST`}),ks=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 w=ze(S);if(!w){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`page-headings`});return}if(!existsSync(w)){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(w,`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}),As=withValidation(RenamePathRequestSchema,async(e,t,S)=>{try{let e=extractActorIdentity(S,fe);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`rename-path`});return}let{kind:E,fromPath:D,toPath:O}=S;if(!isValidRelativeContentPath(D)||!isValidRelativeContentPath(O)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Paths must be relative content paths.`,{handler:`rename-path`});return}if(E===`file`&&(isSystemDoc(D)||isSystemDoc(O)||isConfigDoc(D)||isConfigDoc(O))){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`Reserved document names cannot be renamed.`,{handler:`rename-path`});return}if(D===`.ok`||D.startsWith(`.ok/`)||O===`.ok`||O.startsWith(`.ok/`)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`.ok is a reserved directory.`,{handler:`rename-path`});return}if(D===O){successResponse(t,200,RenamePathSuccessSchema,{renamed:[],rewrittenDocs:[]},{handler:`rename-path`});return}if(D.toLowerCase()===O.toLowerCase()){errorResponse(t,400,`urn:ok:error:invalid-request`,`Case-only renames are not supported.`,{handler:`rename-path`});return}if(E===`file`&&probeAndRegisterSourceFileExtension(w,D),me&&(E===`file`?me.isExcluded(isSupportedDocFile(O)?O:`${O}${getDocExtension(D)}`):me.isDirExcluded(O))){errorResponse(t,400,`urn:ok:error:invalid-request`,`Destination ${E===`file`?`document`:`folder`} is excluded by the project content config.`,{handler:`rename-path`});return}let k=e.kind===`agent`||e.kind===`principal`?{writerId:e.writerId,displayName:e.displayName,colorSeed:e.colorSeed,actorMetadata:e.actor}:void 0,j;try{j=await Lt(D,O,E,k?{actor:k}:{})}catch(e){if(e instanceof ManagedRenameCollisionError){errorResponse(t,409,`urn:ok:error:doc-already-exists`,vt(e.message),{handler:`rename-path`,extensions:{colliding:e.colliding},cause:e});return}throw e}if(j.renamed.length===0){successResponse(t,200,RenamePathSuccessSchema,{renamed:[],rewrittenDocs:[]},{handler:`rename-path`});return}let F;switch(e.kind){case`agent`:{let t=e.summary.kind===`value`,S=t?e.summary:normalizeSummary(`Renamed ${D} → ${O}`),w=Bt(S);F=t||!w.response?w.response:Vt(w.response);for(let t=0;t<j.renamed.length;t++){let{fromDocName:S,toDocName:E}=j.renamed[t];recordContributor(E,e.writerId,e.displayName,e.colorSeed,formatRenameSubject(S,E),e.actor,t===0?w.stored:void 0)}incrementAgentWriteCalls(),Ht(S,!t);for(let{toDocName:e}of j.renamed)rt(e,`rename-path`);break}case`principal`:{let t=Bt(e.summary);F=t.response;for(let S=0;S<j.renamed.length;S++){let{fromDocName:w,toDocName:E}=j.renamed[S];recordContributor(E,e.writerId,e.displayName,e.colorSeed,formatRenameSubject(w,E),e.actor,S===0?t.stored:void 0)}Ht(e.summary,!1);for(let{toDocName:e}of j.renamed)rt(e,`rename-path`);break}case`anonymous`:log$2.debug({kind:E,fromPath:D,toPath:O,affectedDocs:j.renamed.length},`[rename-path] anonymous actor — no contributor recorded (no agentId in body and getPrincipal() returned null)`);break;default:throw Error(`Unhandled actor kind in handleRenamePath: ${String(e.kind)}`)}if(renameAttributionCounter().add(1,{kind:`rename-${E}`,attribution_kind:e.kind}),H)try{await H()}catch(e){console.warn(`[rename-path] flushContributors failed (commitSha backfill may be deferred):`,e)}successResponse(t,200,RenamePathSuccessSchema,{renamed:j.renamed,rewrittenDocs:j.rewrittenDocs,...F?{summary:F}:{}},{handler:`rename-path`})}catch(e){let{status:S,type:w,error:E}=Tt(e);errorResponse(t,S,w,E,{handler:`rename-path`,cause:e})}},{handler:`rename-path`,method:`POST`}),Ns=withValidation(DeletePathRequestSchema,async(e,t,S)=>{try{Rt(S);let{kind:e,path:E}=S;if(!isValidRelativeContentPath(E)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`delete-path`});return}let O=resolveContentEntryPath(w,e,E);if(!existsSync(O)){errorResponse(t,404,`urn:ok:error:doc-not-found`,`${e} does not exist.`,{handler:`delete-path`});return}let k=statSync(O);if(e===`file`&&!k.isFile()||e===`folder`&&!k.isDirectory()){errorResponse(t,400,`urn:ok:error:invalid-request`,`Target path is not a ${e}.`,{handler:`delete-path`});return}let j=e===`file`?[E]:listAffectedDocNames(D(),e,E);if(await Et(j),ye)for(let e of j)isSystemDoc(e)||isConfigDoc(e)||(ye.setDeleted(e),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:e,kind:`deleted`,source:`handleDeletePath`})));e===`file`?unlinkSync(O):(tracedRmSync(O,{recursive:!0,force:!1}),Me(E));let F=D();if(F instanceof Map)for(let e of j)updateFileIndex({kind:`delete`,path:resolve(w,`${e}${getDocExtension(e)}`),docName:e},F);successResponse(t,200,DeletePathSuccessSchema,{deletedDocNames:j},{handler:`delete-path`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to delete path.`,{handler:`delete-path`,cause:e})}},{handler:`delete-path`,method:`POST`}),Ps=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,fe).kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`trash-cleanup`});return}let{kind:e,path:E}=S;if(!isValidRelativeContentPath(E)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`trash-cleanup`});return}let O=e===`folder`&&isReservedSyntheticFolderPath(E);if(e===`file`&&(isSystemDoc(E)||isConfigDoc(E))||O){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${E}' is a reserved document name.`,{handler:`trash-cleanup`});return}let k=D(),j=e===`file`?k.has(E)?[E]:[]:listAffectedDocNames(k,e,E);if(j.length===0){successResponse(t,200,TrashCleanupSuccessSchema,{deletedDocNames:[]},{handler:`trash-cleanup`});return}if(await Et(j),ye)for(let e of j)isSystemDoc(e)||isConfigDoc(e)||(ye.setDeleted(e),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:e,kind:`deleted`,source:`handleTrashCleanup`})));let F=D();if(F instanceof Map)for(let e of j)updateFileIndex({kind:`delete`,path:resolve(w,`${e}${getDocExtension(e)}`),docName:e},F);e===`folder`&&Me(E),ne?.(`files`),successResponse(t,200,TrashCleanupSuccessSchema,{deletedDocNames:j},{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`}),Is=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=D(),S=[];for(let[t,E]of e){let e=t,D=getDocExtension(t);try{e=extractPageTitle(readFileSync(resolve(w,`${t}${D}`),`utf-8`),t)}catch(e){console.warn(`[pages] Failed to read title for ${t}:`,e)}S.push({docName:t,title:e,docExt:D,size:E.size,modified:E.modified})}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}),Rs=withValidation(EmptyRequestSchema,async(e,S)=>{try{let w=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!w){errorResponse(S,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`suggest-links`});return}if(!isSafeDocName(w)){errorResponse(S,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`suggest-links`});return}if(isSystemDoc(w)||isConfigDoc(w)){errorResponse(S,400,`urn:ok:error:reserved-doc-name`,`'${w}' is a reserved document name.`,{handler:`suggest-links`});return}successResponse(S,200,SuggestLinksSuccessSchema,await suggestLinks({hocuspocus:t,fileIndex:D(),docName:w}),{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 $s(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,de??w)}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:E,tempPath:D,sha:O,byteLength:k,parentDocName:j}=S,F=()=>{if(existsSync(D))try{unlinkSync(D)}catch{}},L=validateBody(UploadRequestSchema,{parentDocName:j},t,{handler:`upload-asset`});if(!L.ok){F();return}let{parentDocName:B}=L.value,{agentId:H,agentName:q}=Rt(Object.fromEntries(new URL(e.url??``,`http://localhost`).searchParams.entries()));if(k===0){F(),errorResponse(t,400,`urn:ok:error:no-file-received`,`No file received.`,{handler:`upload-asset`});return}if(B.includes(`\0`)||B.includes(`..`)||B.startsWith(`/`)){F(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}let J=resolve(w),Y=resolveUploadDestDir(B,`./`,J);if(!isWithinContentDir(Y,J)){F(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}try{assertNoSymlinkEscape(Y,J)}catch(e){if(F(),(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$2.error({err:e,destDir:Y},`[upload] failed to validate destination directory`),errorResponse(t,500,`urn:ok:error:storage-error`,`Storage error.`,{handler:`upload-asset`,cause:e});return}try{mkdirSync(Y,{recursive:!0})}catch(e){if(!isAlreadyExistsError(e)){F();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(Y),S;try{S=realpathSync(J)}catch{S=J}if(!isWithinContentDir(e,S)){F(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}}catch(e){if(e.code!==`ENOENT`){F(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`,cause:e});return}}let ee=await fileTypeFromFile(D),te=ee?.mime,ne=ee?.ext;if(!te){let e=readTempFileHead(D,256).toString(`utf-8`).replace(/^/,``).trimStart();(e.startsWith(`<svg`)||e.startsWith(`<?xml`)&&e.includes(`<svg`))&&(te=`image/svg+xml`,ne=`svg`)}{let S=await findDuplicateAsset(Y,O,k);if(S){F();let E=relative(w,resolve(Y,S));log$2.info({event:`upload`,endpoint:e.url??`/api/upload`,agentId:H,agentName:q,dedup:!0,mime:te??null,size:k,destPath:E,httpStatus:200},`[upload] dedup hit`),successResponse(t,200,UploadAssetSuccessSchema,{src:S,path:E,deduped:!0},{handler:`upload-asset`});return}}let ae;if(!E||E===`upload`||GENERIC_PASTE_NAMES.test(E)){let e=new Date().toISOString().replace(/[-:T]/g,``).slice(0,14).replace(/(\d{8})(\d{6})/,`$1-$2`),t=E?extname(E).slice(1):``,S=ne??t??``;ae=S===``?`pasted-${e}`:`pasted-${e}.${S}`}else ae=sanitizeFilename(E);try{let S=linkTempToFinalWithCollisionRetry(D,Y,ae),E=relative(w,resolve(Y,S));log$2.info({event:`upload`,endpoint:e.url??`/api/upload`,agentId:H,agentName:q,dedup:!1,mime:te??null,size:k,destPath:E,httpStatus:200},`[upload] write ok`),successResponse(t,200,UploadAssetSuccessSchema,{src:S,path:E,deduped:!1},{handler:`upload-asset`})}catch(S){let w=S instanceof UploadWriteError?S.reason:`urn:ok:error:storage-error`;log$2.error({event:`upload`,endpoint:e.url??`/api/upload`,agentId:H,agentName:q,filename:ae,size:k,reason:w,httpStatus:uploadStatusFor(w),err:S},`[upload] write failed`),errorResponse(t,uploadStatusFor(w),w,uploadTitleFor(w),{handler:`upload-asset`,cause:S})}}let ec=`/api/local-op/clone`,tc=`/api/local-op/open`,nc=600*1e3,rc=45e3,ic=`local-op-clone`,ac=withValidation(LocalOpCloneRequestSchema,oc,{handler:ic,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:ic})});async function oc(e,t,S){let{url:w,dir:E}=S;if(!isAllowedGitUrl(w)){errorResponse(t,400,`urn:ok:error:url-not-allowed`,`URL protocol is not allowed for clone.`,{handler:ic,cause:Error(`url=${w}`)});return}if(!isSafeLocalPath(E)){errorResponse(t,400,`urn:ok:error:dir-outside-home`,`Clone destination must be within the user home directory.`,{handler:ic,cause:Error(`dir=${E}`)});return}if(!Ce.tryAcquire(ec)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A clone operation is already in progress.`,{handler:ic,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 D=createStreamingErrorWriter(t,ic),O=null,k=runCloneSubprocess({cliArgs:ue,url:w,dir:E,timeoutMs:nc,onEvent:e=>{if(e.type===`complete`){O=e.dir;return}if(e.type===`error`){e.message&&log$2.warn({stderr:e.message,url:w,dir:E},`[local-op/clone] clone failed`),D(500,`urn:ok:error:clone-failed`,`Clone subprocess reported an error.`,{cause:e.message?Error(e.message):void 0});return}if(!t.writableEnded&&!t.destroyed)try{t.write(`${JSON.stringify(e)}\n`)}catch{}}});(async()=>{try{if(await k.done,O&&!t.writableEnded&&!t.destroyed){let e=await sc(O);!t.writableEnded&&!t.destroyed&&(`port`in e?t.write(`${JSON.stringify({type:`complete`,port:e.port,dir:O})}\n`):D(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?D(500,`urn:ok:error:internal-server-error`,`Unexpected error during clone post-processing.`,{cause:e}):log$2.error({err:e,handler:ic},`clone IIFE rejected after stream ended`)}finally{t.writableEnded||t.end(),Ce.release(ec)}})(),t.on(`close`,()=>{k.cancel()})}async function sc(e){let t=resolve(expandTilde(e)),S=getLocalDir(t),w=readUiLock(S);if(w&&w.port>0)return{port:w.port};let E=readServerLock(S),[D,...O]=ue,k=E&&E.port>0?`ui`:`start`,j=spawn(D,[...O,k],{cwd:t,detached:!0,stdio:[`ignore`,`ignore`,`pipe`],env:{...process.env,OK_LOCK_KIND:`interactive`}}),F=[];j.stderr?.on(`data`,e=>{F.push(e),log$2.warn({cwd:t,cliCmd:k,msg:e.toString(`utf-8`).trim()},`[local-op/open] child stderr`)});let L=null;j.on(`exit`,e=>{L=e??-1}),j.unref();let B=Date.now()+45e3;for(;Date.now()<B;){await setTimeout$1(500);let e=readUiLock(S);if(e&&e.port>0)return{port:e.port};if(L!==null){let e=Buffer.concat(F).toString(`utf-8`).trim();return{error:`\`ok ${k}\` exited (code ${L})${e?` — ${e}`:``}`}}}let H=Buffer.concat(F).toString(`utf-8`).trim();return{error:`UI did not start within the expected time${H?` — ${H}`:``}`}}let cc=`local-op-open`,lc=withValidation(LocalOpOpenRequestSchema,async(e,t,S)=>{let{dir:w}=S;if(!isSafeLocalPath(w)){errorResponse(t,400,`urn:ok:error:dir-outside-home`,`dir must be within the user home directory.`,{handler:cc,cause:Error(`dir=${w}`)});return}if(!Ce.tryAcquire(tc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A server-open operation is already in progress.`,{handler:cc,extraHeaders:{"Retry-After":`5`}});return}try{let e=await sc(w);`port`in e?successResponse(t,200,LocalOpOpenSuccessSchema,{port:e.port},{handler:cc}):errorResponse(t,504,`urn:ok:error:server-open-failed`,`Failed to open project server.`,{handler:cc,cause:Error(e.error)})}finally{Ce.release(tc)}},{handler:cc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:cc})}),uc=`/api/local-op/auth/login`,dc=`/api/local-op/auth/status`,fc=`/api/local-op/auth/repos`,pc=`/api/local-op/auth/signout`,mc=`/api/local-op/auth/pat`,hc=`local-op-auth-login`,gc=withValidation(LocalOpAuthHostRequestSchema,_c,{handler:hc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:hc})});async function _c(e,t,S){let w=S.host??`github.com`;if(!Ce.tryAcquire(uc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth login operation is already in progress.`,{handler:hc,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 E=createStreamingErrorWriter(t,hc),D=runDeviceFlowSubprocess({cliArgs:ue,host:w,timeoutMs:nc,onEvent:e=>{if(e.type===`error`){E(500,`urn:ok:error:auth-failed`,`Auth subprocess reported an error.`,{cause:e.message?Error(e.message):void 0});return}if(!t.writableEnded&&!t.destroyed)try{t.write(`${JSON.stringify(e)}\n`)}catch{}}}),O=()=>{D.cancel()};t.on(`close`,O),D.done.finally(()=>{t.off(`close`,O),t.writableEnded||t.end(),Ce.release(uc)})}let vc=`local-op-auth-status`,yc=withValidation(LocalOpAuthHostRequestSchema,async(e,t,S)=>{let w=S.host??`github.com`;if(!Ce.tryAcquire(dc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth status operation is already in progress.`,{handler:vc,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...S]=ue,E=[...S,`auth`,`status`,`--json`,`--host`,w],D=(await new Promise((t,S)=>{let w=spawn(e,E,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),D=!1,O=setTimeout(()=>{D=!0,w.kill(`SIGTERM`)},3e4),k=[];w.stdout.on(`data`,e=>k.push(e)),w.on(`close`,()=>{if(clearTimeout(O),D){S(Error(`auth status subprocess timed out after 30s`));return}t(Buffer.concat(k).toString(`utf-8`))}),w.on(`error`,e=>{clearTimeout(O),S(e)})})).split(`
|
|
2110
2110
|
`).map(e=>e.trim()).filter(Boolean),O=null;for(let e=D.length-1;e>=0;e--)try{O=JSON.parse(D[e]);break}catch{}O===null?successResponse(t,200,LocalOpAuthStatusSuccessSchema,{authenticated:!1},{handler:vc}):successResponse(t,200,LocalOpAuthStatusSuccessSchema,O,{handler:vc})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth status check failed.`,{handler:vc,cause:e})}finally{Ce.release(dc)}},{handler:vc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:vc})}),bc=`local-op-auth-repos`,xc=withValidation(LocalOpAuthHostRequestSchema,Sc,{handler:bc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:bc})});async function Sc(e,t,S){let w=S.host??`github.com`;if(!Ce.tryAcquire(fc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth repos operation is already in progress.`,{handler:bc,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 E=createStreamingErrorWriter(t,bc),[D,...O]=ue,k=[...O,`auth`,`repos`,`--json`,`--host`,w],j=!1,F=``,L=spawn(D,k,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),B=setTimeout(()=>{L.kill(`SIGTERM`)},nc);L.stdout.on(`data`,e=>{F+=e.toString(`utf-8`);let S=F.split(`
|
|
2111
2111
|
`);F=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`){E(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{}}}),L.stderr.on(`data`,e=>{log$2.debug({msg:e.toString(`utf-8`).trim()},`[local-op/auth/repos] stderr`)}),L.on(`close`,e=>{clearTimeout(B),j||(j=!0,e!==0&&!t.writableEnded&&E(500,`urn:ok:error:auth-failed`,`Auth repos subprocess exited with code ${e}.`),t.end(),Ce.release(fc))}),L.on(`error`,e=>{clearTimeout(B),j||(j=!0,t.writableEnded||(E(500,`urn:ok:error:auth-failed`,`Failed to spawn the auth repos subprocess.`,{cause:e}),t.end()),Ce.release(fc))}),t.on(`close`,()=>{j||(j=!0,clearTimeout(B),L.kill(`SIGTERM`),Ce.release(fc))})}let Cc=`local-op-auth-signout`,wc=withValidation(LocalOpAuthHostRequestSchema,async(e,t,S)=>{let w=S.host??`github.com`;if(!Ce.tryAcquire(pc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth signout operation is already in progress.`,{handler:Cc,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...S]=ue,E=[...S,`auth`,`signout`,`--host`,w];await new Promise((t,S)=>{let w=spawn(e,E,{stdio:`ignore`,env:{...process.env}}),D=setTimeout(()=>{w.kill(`SIGTERM`)},3e4);w.on(`close`,()=>{clearTimeout(D),t()}),w.on(`error`,e=>{clearTimeout(D),S(e)})}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:Cc})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth signout failed.`,{handler:Cc,cause:e})}finally{Ce.release(pc)}},{handler:Cc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Cc})}),Tc=`local-op-auth-pat`,Ec=withValidation(LocalOpAuthPatRequestSchema,async(e,t,S)=>{let{pat:w,host:E}=S,D=E??`github.com`;if(!Ce.tryAcquire(mc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth pat operation is already in progress.`,{handler:Tc,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...S]=ue,E=[...S,`auth`,`pat`,`--json`,`--host`,D],O=(await new Promise((t,S)=>{let D=spawn(e,E,{stdio:[`pipe`,`pipe`,`pipe`],env:{...process.env}}),O=setTimeout(()=>{D.kill(`SIGTERM`)},3e4);D.stdin.write(`${w}\n`),D.stdin.end();let k=[];D.stdout.on(`data`,e=>k.push(e)),D.on(`close`,e=>{clearTimeout(O),e===0?t(Buffer.concat(k).toString(`utf-8`)):S(Error(`auth pat exited with code ${e}`))}),D.on(`error`,e=>{clearTimeout(O),S(e)})})).split(`
|
|
2112
|
-
`).map(e=>e.trim()).filter(Boolean),k=null;for(let e=O.length-1;e>=0;e--)try{k=JSON.parse(O[e]);break}catch{}k===null?successResponse(t,200,LocalOpAuthPatSuccessSchema,{},{handler:Tc}):successResponse(t,200,LocalOpAuthPatSuccessSchema,k,{handler:Tc})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth pat failed.`,{handler:Tc,cause:e})}finally{Ce.release(mc)}},{handler:Tc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Tc})}),Dc=`local-op-auth-identity`;async function Oc(e,t){if(checkLocalOpSecurity(e,t,{handler:Dc})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:Dc,extraHeaders:{Allow:`GET`}});return}if(!de){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:Dc});return}try{successResponse(t,200,LocalOpAuthIdentitySuccessSchema,{identity:await resolveGitIdentity(de)},{handler:Dc})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Identity resolution failed.`,{handler:Dc,cause:e})}}}let kc=`/api/local-op/auth/set-identity`,Ac=`local-op-auth-set-identity`,jc=withValidation(LocalOpAuthSetIdentityRequestSchema,async(e,t,S)=>{let w=S.name.trim(),E=S.email.trim();if(!de){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:Ac});return}if(!Ce.tryAcquire(kc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A set-identity operation is already in progress.`,{handler:Ac,extraHeaders:{"Retry-After":`5`}});return}try{writeGitIdentity(de,w,E),ce?.()?.refreshIdentity().catch(()=>{}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:Ac})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Set-identity failed.`,{handler:Ac,cause:e})}finally{Ce.release(kc)}},{handler:Ac,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Ac})});async function Mc(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=ce?.();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},{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 Nc=withValidation(SyncTriggerRequestSchema,async(e,t,S)=>{let w=ce?.();if(!w){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`});return}let E=S.op??`sync`;successResponse(t,202,SyncTriggerSuccessSchema,{op:E},{handler:`sync-trigger`}),w.trigger(E)},{handler:`sync-trigger`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-trigger`})?ce?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`}),!1):!1});async function Pc(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=ce?.();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 Fc=withValidation(SyncResolveConflictRequestSchema,async(e,t,S)=>{let w=ce?.();if(!w){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`});return}let{file:E,strategy:D,content:O}=S;try{await w.resolveConflict(E,D,O),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})}},{handler:`sync-resolve-conflict`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-resolve-conflict`})?ce?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`}),!1):!1});async function Ic(e,t){if(!checkLocalOpSecurity(e,t,{handler:`sync-conflict-content`}))return;if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflict-content`,extraHeaders:{Allow:`GET`}});return}if(!de){errorResponse(t,503,`urn:ok:error:project-repo-not-configured`,`Project repo not configured.`,{handler:`sync-conflict-content`});return}let S=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`file`);if(!S){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing required query param: file.`,{handler:`sync-conflict-content`});return}if(S.includes(`..`)||S.startsWith(`/`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid file path.`,{handler:`sync-conflict-content`});return}let w=esm_default({baseDir:de,timeout:{block:15e3}});async function E(e){try{return await w.raw([`show`,`:${e}:${S}`])}catch{return``}}try{let[e,w,D]=await Promise.all([E(1),E(2),E(3)]);successResponse(t,200,SyncConflictContentSuccessSchema,{file:S,base:e,ours:w,theirs:D},{handler:`sync-conflict-content`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read conflict content.`,{handler:`sync-conflict-content`,cause:e})}}async function Lc(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`),E=S.searchParams.get(`rootDir`)??void 0,D=S.searchParams.get(`packId`),O=coercePackId(D);if(D!==null&&D!==``&&O===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-plan`,detail:`Pack id "${D}" is not registered.`});return}try{successResponse(t,200,SeedPlanSuccessSchema,{plan:await planSeed({projectDir:w,rootDir:E,packId:O})},{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 Rc=withValidation(SeedApplyRequestSchema,async(e,t,S)=>{let E=S.plan;if(!E||typeof E!=`object`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid plan payload.`,{handler:`seed-apply`});return}let D=E,O=S.packId,k=coercePackId(O);if(typeof O==`string`&&O.length>0&&k===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-apply`,detail:`Pack id "${O}" is not registered.`});return}try{successResponse(t,200,SeedApplySuccessSchema,{result:await applySeed(D,{projectDir:w,packId:k})},{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 zc(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 Bc=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 Vc(e,t){if(checkLocalOpSecurity(e,t,{handler:`installed-agents`}))try{await handleInstalledAgents(e,t,Re.probeAll)}catch(e){t.headersSent||(log$2.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}))}}async function Hc(e,t){if(!checkLocalOpSecurity(e,t,{handler:`sync-abort-merge`}))return;if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-abort-merge`,extraHeaders:{Allow:`POST`}});return}let S=ce?.();if(!S){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-abort-merge`});return}try{await S.abortMerge(),successResponse(t,200,SyncAbortMergeSuccessSchema,{},{handler:`sync-abort-merge`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to abort merge.`,{handler:`sync-abort-merge`,cause:e})}}let Uc=withValidation(EmptyRequestSchema,async(e,t)=>{if(!te){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-list`});return}try{successResponse(t,200,TagsListSuccessSchema,{tags:te.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 Wc(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(!te){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-for-name`});return}let w;try{w=decodeURIComponent(S)}catch{errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid tag name encoding.`,{handler:`tags-for-name`});return}if(!w){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing tag name.`,{handler:`tags-for-name`});return}try{let e=te.getDocsForTagWithMatches(w).map(({docName:e,matchingTags:t})=>({docName:e,title:Be(e),matchingTags:t,snippet:null}));successResponse(t,200,TagsForNameSuccessSchema,{name:w,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 Gc(e,t,S=`path`,E=`folder-config`){let D=e.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``);if(D.split(`/`).some(e=>e===`..`)||e.startsWith(`/`))return errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid ${S}: must be project-root-relative.`,{handler:E}),null;let O=resolve(w),k=D===``?O:resolve(O,D);return k!==O&&!k.startsWith(`${O}${sep}`)?(errorResponse(t,400,`urn:ok:error:invalid-request`,`Path escapes content directory.`,{handler:E}),null):{folderRel:D,resolvedContentDir:O}}let Kc=/^[A-Za-z0-9_-]+$/;function qc(e,t,S=`template`){return!e||!Kc.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 Jc(e){let t={};if(!e||typeof e!=`object`||Array.isArray(e))return t;for(let[S,w]of Object.entries(e))w!==void 0&&(t[S]=w);return t}async function Yc(e,t){if(e.method===`GET`)return Xc(e,t);if(e.method===`PUT`)return Zc(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`folder-config`,extraHeaders:{Allow:`GET, PUT`}})}let Xc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let S=Gc(new URL(e.url??``,`http://localhost`).searchParams.get(`path`)??``,t,`path`,`folder-config-get`);if(!S)return;let w=await enrichDirectory(S.folderRel,{projectDir:S.resolvedContentDir}),E=resolve(S.resolvedContentDir,S.folderRel,`.ok`,`frontmatter.yml`),D=null;if(existsSync(E))try{let e=(0,import_dist$1.parse)(await readFile$1(E,`utf-8`));D=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 ${E}: ${t}`),D=null}successResponse(t,200,FolderConfigGetSuccessSchema,{folder:w,frontmatter_local:D},{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}),Zc=withValidation(FolderConfigPutRequestSchema,async(e,t,S)=>{try{let e=Gc(S.path,t,`path`,`folder-config-put`);if(!e)return;let w=e.folderRel===``?`**`:`${e.folderRel}/**`,E=applyNestedFolderRulesUpsert({projectDir:e.resolvedContentDir,rules:[{match:w,frontmatter:Jc(S.frontmatter)}]});if(!E.ok){let e=E.error.code===`WRITE_ERROR`||E.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 write folder config.`:`Invalid folder config request.`,{handler:`folder-config-put`,detail:E.error.code,cause:Error(E.error.message)});return}successResponse(t,200,FolderConfigPutSuccessSchema,{applied:E.applied},{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`});async function Qc(e,t){if(e.method===`GET`)return il(e,t);if(e.method===`PUT`)return al(e,t);if(e.method===`DELETE`)return cl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`template`,extraHeaders:{Allow:`GET, PUT, DELETE`}})}let $c=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/,nl=e=>{let t=e.match($c),S={},w=e;if(t){try{let e=(0,import_dist$1.parse)(t[1]??``);e&&typeof e==`object`&&!Array.isArray(e)&&(S=e)}catch{}w=e.slice(t[0].length)}return{frontmatter:S,body:w}},il=withValidation(EmptyRequestSchema,async(e,t)=>{try{let S=new URL(e.url??``,`http://localhost`),w=S.searchParams.get(`name`)??``;if(!qc(w,t,`template-get`))return;let E=Gc(S.searchParams.get(`folder`)??``,t,`folder`,`template-get`);if(!E)return;let{folderRel:D,resolvedContentDir:O}=E,k=D===``?[]:D.split(`/`),j=null,F=null,L=null;for(let e=k.length;e>=0;e--){let t=e===0?``:k.slice(0,e).join(`/`),S=t===``?O:resolve(O,t);if(S!==O&&!S.startsWith(`${O}${sep}`))continue;let E=resolve(S,`.ok`,`templates`,`${w}.md`);if(existsSync(E)){j=E,F=t,L=e===k.length?`local`:`inherited`;break}}if(!j||F===null||L===null){errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-get`,detail:`Template "${w}" not found for folder "${D||`.`}". Walked leaf → root.`});return}let{frontmatter:B,body:H}=nl(await readFile$1(j,`utf-8`)),q=relative(O,j).split(/[\\/]/).filter(Boolean).join(`/`);successResponse(t,200,TemplateGetSuccessSchema,{template:{name:w,folder:F,scope:L,path:q,frontmatter:B,body:H}},{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}),al=withValidation(TemplatePutRequestSchema,async(e,t,S)=>{try{let e=S.name;if(!qc(e,t,`template-put`))return;let w=Gc(S.folder,t,`folder`,`template-put`);if(!w)return;let E=applyTemplateWrite({projectDir:w.resolvedContentDir,folder:w.folderRel,name:e,body:typeof S.body==`string`?S.body:``,frontmatter:Jc(S.frontmatter)});if(!E.ok){let e=E.error.code===`WRITE_ERROR`||E.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 write template.`:`Invalid template request.`,{handler:`template-put`,detail:E.error.code,cause:Error(E.error.message)});return}successResponse(t,200,TemplatePutSuccessSchema,{path:E.path,created:E.created,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`}),cl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let S=new URL(e.url??``,`http://localhost`),w=S.searchParams.get(`name`)??``;if(!qc(w,t,`template-delete`))return;let E=Gc(S.searchParams.get(`folder`)??``,t,`folder`,`template-delete`);if(!E)return;let D=applyTemplateDelete({projectDir:E.resolvedContentDir,folder:E.folderRel,name:w});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}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});function ll(e){let t=new Map;for(let S of e){let e=S.path.split(`/`).filter(Boolean);e.pop();for(let w=1;w<=e.length;w++){let E=e.slice(0,w).join(`/`);t.set(E,Math.max(t.get(E)??0,S.modifiedTs))}}return[...t.entries()].map(([e,t])=>createWorkspaceSearchDocument({kind:`folder`,path:e,modifiedTs:t}))}function ul(e,t){let S=t.trim().toLowerCase();if(!S||!e)return;let w=e.toLowerCase().indexOf(S);if(w<0)return;let E=Math.max(0,w-80),D=Math.min(e.length,w+S.length+120),O=E>0?`…`:``,k=D<e.length?`…`:``;return`${O}${e.slice(E,D).replace(/\s+/g,` `).trim()}${k}`}function dl(e){return e===`autocomplete`||e===`full_text`||e===`omnibar`?e:`omnibar`}function fl(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`);return S.length>0?S:void 0}async function pl(){let e=[];for(let[t,S]of D()){if(isSystemDoc(t)||isConfigDoc(t))continue;let w=``,E=t;try{w=await readFile$1(S.canonicalPath,`utf-8`),E=extractPageTitle(w,t)}catch(e){console.warn(`[search] Failed to index ${t}:`,e)}e.push(createWorkspaceSearchDocument({kind:`page`,path:t,title:E,content:w,modifiedTs:Date.parse(S.modified)}))}return[...e,...ll(e)]}function ml(){return[...D()].filter(([e])=>!isSystemDoc(e)&&!isConfigDoc(e)).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}${t.modified}${t.size}${t.canonicalPath}${t.inode}${t.aliases.join(`,`)}`).join(``)}async function hl(){let e=`${w}${de??``}`,t=ml(),S=workspaceSearchCaches.get(e);if(S?.fingerprint===t&&S.corpus)return S.corpus;if(S?.fingerprint===t&&S.pending)return S.pending;let E=pl().then(e=>createWorkspaceSearchCorpus(e));workspaceSearchCaches.set(e,{fingerprint:t,pending:E});try{let S=await E;return workspaceSearchCaches.get(e)?.pending===E&&workspaceSearchCaches.set(e,{fingerprint:t,corpus:S}),S}catch(t){throw workspaceSearchCaches.get(e)?.pending===E&&workspaceSearchCaches.delete(e),t}}function gl(){if(process.env.NODE_ENV!==`test`)for(let e of[0,1e3,3e3])setTimeout(()=>{hl().catch(e=>{console.warn(`[search] Failed to prewarm workspace search cache:`,e)})},e)}gl();async function _l(e,t){if(e.method===`GET`)return vl(e,t);if(e.method===`POST`)return yl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`search`,extraHeaders:{Allow:`GET, POST`}})}let vl=withValidation(EmptyRequestSchema,async(e,t)=>{let S=new URL(e.url??``,`http://localhost`),w=S.searchParams.get(`limit`),E=S.searchParams.get(`query`)??``,D=dl(S.searchParams.get(`intent`)),O=fl(S.searchParams.get(`scope`)??S.searchParams.get(`scopes`)),k=w===null?void 0:Number(w);if(E.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-get`});return}try{let e=performance.now();successResponse(t,200,SearchSuccessSchema,{query:E,intent:D,results:searchWorkspaceCorpus(await hl(),E,{intent:D,scopes:O,limit:k}).map(e=>({kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?ul(e.document.content,E):void 0})),elapsedMs:Math.max(0,performance.now()-e)},{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}),yl=withValidation(SearchRequestSchema,async(e,t,S)=>{let w=typeof S.query==`string`?S.query:``,E=dl(S.intent),D=fl(S.scopes??S.scope),O=typeof S.limit==`number`?S.limit:void 0;if(w.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-post`});return}try{let e=performance.now();successResponse(t,200,SearchSuccessSchema,{query:w,intent:E,results:searchWorkspaceCorpus(await hl(),w,{intent:E,scopes:D,limit:O}).map(e=>({kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?ul(e.document.content,w):void 0})),elapsedMs:Math.max(0,performance.now()-e)},{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`}),xl=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 Cl(e,t){if(checkLocalOpSecurity(e,t,{handler:`handoff`}))try{await handleHandoffDispatch(e,t,{contentDir:w,platform:process.platform})}catch(e){t.headersSent||(log$2.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 Tl(e,t){if(checkLocalOpSecurity(e,t,{handler:`spawn-cursor`}))try{await handleSpawnCursor(e,t,{contentDir:w,platform:process.platform})}catch(e){t.headersSent||(log$2.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 El=withValidation(ShareConstructUrlRequestSchema,async(e,t,S)=>{try{if(!de){emitShareConstructUrlLog(`no-remote`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!isValidShareDocPath(S.docPath)){emitShareConstructUrlLog(`invalid-path`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`invalid-path`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let e=readGitHeadBranch(de);if(e===null){if(readOriginGitHubRepo(de).kind===`no-remote`){emitShareConstructUrlLog(`no-remote`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}emitShareConstructUrlLog(`detached-head`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`detached-head`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let w=readOriginGitHubRepo(de);if(w.kind===`no-remote`){emitShareConstructUrlLog(`no-remote`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(w.kind===`non-github`){emitShareConstructUrlLog(`non-github-remote`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`non-github-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!branchExistsOnOrigin(de,e)){emitShareConstructUrlLog(`branch-not-on-origin`,!1),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`branch-not-on-origin`,branch:e},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let E=buildGitHubBlobUrl(w.owner,w.repo,e,S.docPath),D=`${SHARE_BASE_URL}${encodeShareUrl(E)}`;emitShareConstructUrlLog(`ok`,!0),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!0,shareUrl:D,blobUrl:E,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})});async function Dl(e){let[t,...S]=ue,w=[...S,...e];return await new Promise((e,S)=>{let E=spawn(t,w,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),D=!1,O=setTimeout(()=>{D=!0,E.kill(`SIGTERM`)},SHARE_PUBLISH_TIMEOUT_MS),k=[],j=[];E.stdout.on(`data`,e=>k.push(e)),E.stderr.on(`data`,e=>j.push(e)),E.on(`close`,t=>{if(clearTimeout(O),D){S(Error(`share subprocess timed out after ${SHARE_PUBLISH_TIMEOUT_MS}ms`));return}let w=Buffer.concat(k).toString(`utf-8`);if(t!==0){let e=redactShareSubprocessStderr(Buffer.concat(j).toString(`utf-8`)).slice(0,500);console.warn(`[share] subprocess exited code=${t} stderr=${e}`)}e({stdout:w,code:t})}),E.on(`error`,e=>{clearTimeout(O),S(e)})})}let Ol=withValidation(EmptyRequestSchema,async(e,t)=>{if(!Ce.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 Dl([`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{Ce.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})}),kl=withValidation(EmptyRequestSchema,async(e,t)=>{let S=new URL(e.url??``,`http://localhost`),w=S.searchParams.get(`owner`)??``,E=S.searchParams.get(`name`)??``;if(!isValidShareOwnerName(w)||!isValidShareRepoName(E)){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(!Ce.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 Dl([`share`,`name-check`,`--owner`,w,`--name`,E,`--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{Ce.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})}),jl=withValidation(SharePublishRequestSchema,async(e,t,S)=>{if(!de){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(!Ce.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`,de,`--json`];S.description!==void 0&&S.description.length>0&&e.push(`--description`,S.description);let{stdout:w}=await Dl(e),E=parsePublishEvent(pickTerminalJsonLine(w));emitSharePublishLog(`publish-create`,E.ok?`ok`:E.error),successResponse(t,200,SharePublishResponseSchema,E,{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{Ce.release(SHARE_PUBLISH_KEY)}},{handler:SHARE_PUBLISH_HANDLER_TAG,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_HANDLER_TAG})}),Ml={"/api/asset":Xi,"/api/asset-text":ka,"/api/document":$t,"/api/documents":en,"/api/backlinks":jr,"/api/backlink-counts":Mr,"/api/forward-links":Fr,"/api/link-graph":Ir,"/api/dead-links":Br,"/api/orphans":Lr,"/api/hubs":zr,"/api/tags":Uc,"/api/pages":Is,"/api/folder-config":Yc,"/api/template":Qc,"/api/search":_l,"/api/suggest-links":Rs,"/api/page-headings":ks,"/api/create-page":Ts,"/api/create-folder":Ds,"/api/duplicate-path":Os,"/api/rename-path":As,"/api/delete-path":Ns,"/api/trash/cleanup":Ps,"/api/upload":$s,"/api/agent-write":Ut,"/api/agent-write-md":Wt,"/api/frontmatter-patch":Kt,"/api/agent-patch":Vr,"/api/agent-undo":Hr,"/api/agent-activity":Ur,"/api/agent-burst-diff":Wr,"/api/save-version":Jr,"/api/history":Yr,"/api/diff":Zr,"/api/rollback":Qr,"/api/metrics/reconciliation":ji,"/api/metrics/parse-health":Hi,"/api/metrics/agent-presence":Ki,"/api/server-info":Ui,"/api/share/construct-url":El,"/api/share/publish/owners":Ol,"/api/share/publish/name-check":kl,"/api/share/publish":jl,"/api/principal":Gi,"/api/rescue":xs,"/api/workspace":Yi,"/api/sync/status":Mc,"/api/sync/trigger":Nc,"/api/sync/conflicts":Pc,"/api/sync/conflict-content":Ic,"/api/sync/resolve-conflict":Fc,"/api/sync/abort-merge":Hc,"/api/local-op/clone":ac,"/api/local-op/open":lc,"/api/local-op/auth/login":gc,"/api/local-op/auth/status":yc,"/api/local-op/auth/repos":xc,"/api/local-op/auth/signout":wc,"/api/local-op/auth/pat":Ec,"/api/local-op/auth/identity":Oc,"/api/local-op/auth/set-identity":jc,"/api/installed-agents":Vc,"/api/spawn-cursor":Tl,"/api/handoff":Cl,"/api/install-skill":Bc,"/api/skill/install-state":xl,"/api/seed/plan":Lc,"/api/seed/apply":Rc,"/api/seed/packs":zc};F&&(Ml[`/api/test-reset`]=Gr,Ml[`/api/test-rescan-backlinks`]=Kr,Ml[`/api/test-rescan-files`]=qr);let Pl=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/sync/abort-merge`,`/api/test-reset`,`/api/test-rescan-backlinks`,`/api/test-rescan-files`,`/api/install-skill`,`/api/folder-config`,`/api/template`,`/api/seed/apply`]),Fl=[`/api/local-op/`];return{priority:100,async onRequest({request:e,response:t}){let S=e.url?.split(`?`)[0];if(!S)return;if(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`)),e.method===`OPTIONS`){t.writeHead(204),t.end();return}}if(Pl.has(S)||Fl.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(!S.startsWith(`/api/`))return;let w=propagation.extract(context.active(),e.headers),E=e.method??`GET`,D=S;S.startsWith(`/api/rescue/`)?D=`/api/rescue/:docName`:S.startsWith(`/api/history/`)?D=`/api/history/:sha`:S.startsWith(`/api/tags/`)?D=`/api/tags/:name`:Ml[S]||(D=`/api/*`);let O=getTracer(),k=Date.now();await context.with(w,()=>O.startActiveSpan(`HTTP ${E} ${D}`,{kind:SpanKind.SERVER,attributes:{[ATTR_HTTP_REQUEST_METHOD]:E,[ATTR_HTTP_ROUTE]:D,[ATTR_URL_PATH]:S,[ATTR_URL_SCHEME]:`http`,[ATTR_USER_AGENT_ORIGINAL]:e.headers[`user-agent`]??``}},async w=>{try{let D=Ml[S],O=!1;if(D)O=!0,await D(e,t);else if(S.startsWith(`/api/rescue/`)){let w=decodeURIComponent(S.slice(12));w&&(O=!0,await Cs(e,t,w))}else if(S.startsWith(`/api/history/`)){let w=decodeURIComponent(S.slice(13));w&&(O=!0,await Xr(e,t,w))}else if(S.startsWith(`/api/tags/`)){let w=S.slice(10);w&&(O=!0,await Wc(e,t,w))}O||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`api-dispatch`,detail:`No handler for ${E} ${S}`});let k=t.statusCode;w.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE,k),k>=500&&w.setStatus({code:SpanStatusCode.ERROR,message:`status ${k}`})}catch(e){throw w.recordException(e),w.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:D,cause:e}),e}finally{w.end();let e=(Date.now()-k)/1e3;httpDurationHist().record(e,{[ATTR_HTTP_REQUEST_METHOD]:E,[ATTR_HTTP_ROUTE]:D,[ATTR_HTTP_RESPONSE_STATUS_CODE]:t.statusCode})}}))}}}function isWithinDir(e,t){return e===t?!0:e.startsWith(`${t}${sep}`)}function errnoCode(e){let t=e?.code;return typeof t==`string`?t:void 0}function seedBasenameIndex(e){let t=e.contentDir,S=new Set;function w(E){let D;try{D=readdirSync(E,{withFileTypes:!0})}catch(t){let S=errnoCode(t);S!==`ENOENT`&&e.onSkip?.(`read-failed`,S,E);return}for(let O of D){let D=join(E,O.name),k=relative(t,D);if(k.startsWith(`..`)||e.contentFilter?.isDirExcluded(k)&&O.isDirectory())continue;let j;try{j=lstatSync(D)}catch(t){let S=errnoCode(t);S!==`ENOENT`&&e.onSkip?.(`lstat-failed`,S,D);continue}if(j.isSymbolicLink()){let E;try{E=realpathSync(D)}catch(t){let S=errnoCode(t);S!==`ENOENT`&&e.onSkip?.(`realpath-failed`,S,D);continue}if(!isWithinDir(E,t)){e.onSkip?.(`symlink-escape`,void 0,D);continue}let O;try{O=statSync(E)}catch(t){let S=errnoCode(t);S!==`ENOENT`&&e.onSkip?.(`symlink-stat-failed`,S,E);continue}if(S.has(O.ino))continue;S.add(O.ino),O.isDirectory()?w(E):O.isFile()&&isSupportedAssetFile(D,ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(k)&&e.basenameIndex.add(k);continue}if(j.isDirectory()){if(S.has(j.ino))continue;S.add(j.ino),w(D);continue}j.isFile()&&isSupportedAssetFile(D,ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(k)&&e.basenameIndex.add(k)}}w(t)}const HocuspocusAuthTokenSchema=object$1({principalId:string$2().optional(),tabSessionId:string$2().optional(),expectedServerInstanceId:string$2().optional(),expectedBranch:string$2().optional()}).loose(),HOCUSPOCUS_AUTH_REJECTION_REASONS=[`server-instance-mismatch`,`branch-mismatch`,`rename-redirect`,`doc-deleted`];function isHocuspocusAuthRejectionReason(e){return HOCUSPOCUS_AUTH_REJECTION_REASONS.includes(e)}const WIRE_PAYLOAD_SEPARATOR=`:`;function formatAuthRejectionWire(e,t){return typeof t!=`string`||t.length===0?e:`${e}${WIRE_PAYLOAD_SEPARATOR}${t}`}function parseAuthRejectionWire(e){if(e.length===0)return{kind:null,payload:void 0};let t=e.indexOf(WIRE_PAYLOAD_SEPARATOR),S=t===-1?e:e.slice(0,t);if(!isHocuspocusAuthRejectionReason(S))return{kind:null,payload:void 0};if(t===-1)return{kind:S,payload:void 0};let w=e.slice(t+1);return{kind:S,payload:w.length>0?w:void 0}}var HocuspocusAuthRejection=class extends Error{kind;payload;reason;constructor(e,t,S){super(t),this.name=`HocuspocusAuthRejection`,this.kind=e,this.payload=typeof S==`string`&&S.length>0?S:void 0,this.reason=formatAuthRejectionWire(e,this.payload)}};function parseHocuspocusAuthToken(e){if(typeof e!=`string`||e.length===0)return;let t;try{t=JSON.parse(e)}catch{return}let S=HocuspocusAuthTokenSchema.safeParse(t);return S.success?S.data:void 0}const DEFAULT_WARN_BEFORE_MS=300*1e3;function attachIdleShutdown(e){let t=e.scheduler??defaultScheduler,S=e.warnBeforeMs??DEFAULT_WARN_BEFORE_MS,w=0,E=null,D=null,O=!1,k=!1;function j(){E!==null&&(t.clearTimeout(E),E=null),D!==null&&(t.clearTimeout(D),D=null)}function F(){j(),!(k||O)&&w===0&&(S>0&&S<e.thresholdMs&&(D=t.setTimeout(()=>{D=null,w===0&&!O&&e.log?.warn({msUntilShutdown:S,webSocketClientCount:0},`idle shutdown pending: no WebSocket clients`)},e.thresholdMs-S)),E=t.setTimeout(()=>{if(E=null,!(k||O)&&w===0){O=!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 L=(e,t)=>{e.url?.startsWith(`/collab`)&&(w++,j(),t.once(`close`,()=>{w--,w<0&&(w=0),w===0&&F()}))};return e.httpServer.on(`upgrade`,L),F(),{detach:()=>{k||(k=!0,e.httpServer.off(`upgrade`,L),j())}}}const MCP_SERVER_NAME=`open-knowledge`,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 buildInstructions(e){return'Open Knowledge is a markdown-CRDT knowledge base exposed via MCP.\n\n## STOP — native tools on in-scope `.md` / `.mdx`\n\nWhen this workspace has Open Knowledge MCP configured, do **not** use your host\'s native file tools on markdown paths inside the content directory. The ban covers every common rationalization:\n\n- **Native `Read` / `Grep` / `Glob` on in-scope `.md` / `.mdx`** — the original case.\n- **`Bash ls` / `Bash find` / `Bash cat` on dirs containing in-scope markdown** — use `exec("ls -A …")` / `exec("find … -name \'*.md\'")` / `exec("cat …")` instead. Native returns bare names; `exec` returns frontmatter, backlink counts, and recent activity per child. `-A` shows hidden entries (`.ok/`, `.okignore`) which OK projects carry; omit `.` and `..` rows that `-a` would add.\n- **Glob patterns that target markdown** (`**/*.md`, any dir known to be markdown-heavy like `specs/**`, `reports/**`, `docs/**`) — use `exec` with `find`, or `list_documents({ dir })`.\n- **Dispatching the Explore / general-purpose subagent for markdown-heavy exploration** — subagents use native `Read` / `Grep` / `Glob` internally and bypass Open Knowledge entirely. Do markdown exploration yourself via `exec` / `search` / `grep`. Subagents remain appropriate for **source-code** exploration.\n- **Native `Read` / `Grep` on any in-scope markdown inside `.ok/`** — the `.ok/` directory is in-scope; if it carries `.md` / `.mdx`, treat those the same as any other knowledge-base file.\n\nWhy: native tools skip frontmatter, backlinks, shadow-repo activity, and project git history that OK\'s tools return for every matched knowledge-base file. `exec` is the primary read surface; it runs read-only bash (`cat`, `ls`, `grep`, `find`, `head`, `tail`, `wc`, `sort`, `uniq`, `cut` — pipes OK) and returns raw stdout plus enriched metadata per file.\n\n**MCP tool visibility — not seeing `exec` is NOT the escape hatch.** MCP wiring varies by client. Claude Code, Cursor, Codex, Windsurf, VS Code — each surfaces MCP differently. Server labels are user-defined; tools may not appear as top-level symbols named `exec` in your specific UI. If Open Knowledge is registered as an MCP server in this workspace, route markdown reads through its `exec` / `search` / `grep` / `read_document` via your client\'s documented MCP invocation (including any generic "call MCP tool" flow). Registration is the test, not top-level-symbol visibility.\n\n**Escape hatch.** Native `Read` / `Grep` / `Glob` on `.md` / `.mdx` is allowed **only** when no Open Knowledge MCP server is registered for this project, **or** immediately after you tried an MCP call and it failed — then begin a user-visible sentence with `Open Knowledge MCP unavailable:`. Never use the hatch because you skipped your client\'s MCP path, didn\'t see `exec` as a top-level tool, or rationalized the skill wasn\'t necessary.\n\n**Source code and non-markdown files** (`.ts`, `.py`, `package.json`, …): native `Read` / `Grep` / `Glob` always.\n\n## Reads — examples\n\n- Read a file: `exec("cat <path>.md")` — contents + full rich enrichment\n- List a directory: `exec("ls -A <dir>")` — per-child frontmatter, recursive markdown counts, most-recently-updated doc per subdir. Prefer `-A` over plain `ls`: OK projects carry dot-prefixed entries (`.ok/`, nested `.ok/`, `.okignore`) that plain `ls` omits. `-A` shows hidden entries without the noisy `.`/`..` rows that `-a` adds, and without the verbose long-format columns that `-la` adds (the per-child enrichment already carries the useful metadata `-l` would surface).\n- Search: `exec("grep -rn <term> <dir> | head -5")` — matches + enrichment on matched files\n- Typed tools (`read_document`, `search`, `grep`, `list_documents`) remain available — prefer them when a structured `structuredContent` shape is useful (e.g., passing results to another tool). For interactive reads, `exec` is lighter. **Pick the right search:** `search` for ranked retrieval (cmd-K parity — title boost + body BM25 + recency); `grep` for every literal-string occurrence grouped by file with frontmatter enrichment.\n\n## Preview — open the browser at session start\n\n**The invariant.** If OK Electron is open for this project OR `ok ui` is running for it, every OK tool response carries the preview URL — plain HTTP, no custom URL schemes, works in any browser including agent in-app browsers (Claude Desktop, Cursor, Codex, Cowork). Read tools (`exec`, `grep`, `search`, `list_documents`, `read_document`) carry it in `ui.baseUrl` (top-level) and per-doc `previewUrl` fields; write tools carry it in `previewUrl` + the optional `warning` shape. Never construct this URL; always read it from the latest tool response.\n\n**The default agent move.** Make your first OK tool call (any read works — `list_documents`, `exec("ls -A")`, or `read_document` is enough). The response carries the preview URL. Navigate to it immediately, then proceed with your real work. The user watches edits land live; you can re-navigate later to verify a CRDT edit landed when a response looks ambiguous. Per host:\n\n- **In-app browser hosts** (Claude Desktop, Cursor, Codex, Cowork): navigate the in-app browser to the `previewUrl`. Default.\n- **Claude Code Desktop**: call `preview_start("open-knowledge-ui")` (host tool, not OK MCP).\n- **Stdio-only hosts**: surface the URL in chat; `open <url>` (macOS) if the host can shell out.\n\n**Four signals to check if it\'s already open** (you usually can\'t pre-check, so read these from each write response):\n\n1. You opened/navigated earlier this session → don\'t reopen.\n2. Write response has `previewUrl` (non-null) and NO `warning` → a browser is attached somewhere; do nothing.\n3. `warning: { action: "attach-preview-once", previewUrl, message }` → UI reachable, no browser attached; navigate one-shot.\n4. `warning: { action: "start-ui", previewUrl: null, message }` → no UI running anywhere. Surface the message verbatim — recovery options are in the in-band copy. Don\'t loop on retries.\n\nWarnings fire at most once per session in the fresh-start case.\n\n**`previewUrl: null` only means "no UI reachable" on the three attach-warning tools: `write_document` / `edit_document` / `frontmatter_patch`.** Workflow tools return prose and don\'t carry `previewUrl`. `delete_document` / `rename_document` / `rename_folder` emit `previousPreviewUrl` (different field, for closing stale tabs) and don\'t fire attach warnings.\n\n**Always read `previewUrl` from the latest write response.** Don\'t cache the session-start value — Electron quit/reopen (or `ok ui` restart) can change the port; the resolver picks up the new port automatically.\n\nIf you see `"Hocuspocus server is not running"`, run `ok start` and retry. NEVER construct preview URLs by hand.\n\nOK Electron and `ok ui` cannot serve the same project at once — they share `ui.lock`. A UI-lock collision means the other is running for that project (use that one, or quit it first).\n\n**The preview is read-only for the agent.** Navigate to verify edits landed; you cannot click or type to drive edits — the CRDT flow is one-way (agent → MCP → CRDT → preview).\n\n**No screenshots after every edit.** Do NOT take `preview_screenshot` (host tool, not OK MCP) after every write. Trust the response. Screenshot only when (a) debugging a visual issue, (b) a response looks ambiguous, or (c) the user asks.\n\n## Scope recap\n\nOpen Knowledge looks for documents under the resolved `content.dir` (discoverable at runtime via `get_config({ path: [\'content\', \'dir\'] })`). `.gitignore` and `.okignore` (at the project root and at any folder depth) define exclusions. Folder defaults + templates live in nested `<folder>/.ok/frontmatter.yml` + `<folder>/.ok/templates/` files — NOT in `.ok/config.yml`.\n\nDefault mental model (no jargon): **every `.md` and `.mdx` under `content.dir`** not excluded by `.gitignore` or `.okignore` is an Open Knowledge document — including under `specs/`, `reports/`, `docs/`, etc. Read `.okignore` (and any nested `.okignore` files) once per turn to know what\'s excluded.\n\n**First session in this project?** If `frontmatter_defaults` and `templates_available` are empty for substantial folders, the project hasn\'t been onboarded yet — invoke `discover` (Workflow tools table) before writing. Once onboarded, the cascade carries the discipline.\n\n\nFull guidance lives in the bundled `open-knowledge` skill at `~/.ok/skills/open-knowledge/SKILL.md`.\n'}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,w){if(!e.inputSchema||!isZodSchema(e.inputSchema))return S.call(this,e,t,w);let E=await e.inputSchema.safeParseAsync(t);if(E.success)return E.data;let D=prettifyError(E.error);throw new McpError(ErrorCode.InvalidParams,`Input validation error: Invalid arguments for tool ${w}:\n${D}`)},t.__prettyZodErrorsInstalled=!0}function isZodSchema(e){return typeof e!=`object`||!e?!1:typeof e.safeParseAsync==`function`}const loggerContext=new AsyncLocalStorage;var McpLogger=class e{sessionId;corrId;component;constructor(e=`mcp`,t){this.sessionId=t??randomUUID().slice(0,12),this.corrId=randomUUID().slice(0,8),this.component=e}info(e,t={}){this.emit(`info`,e,t)}warn(e,t={}){this.emit(`warn`,e,t)}error(e,t,S={}){let w=t?{error:t instanceof Error?t.message:String(t),...S}:S;this.emit(`error`,e,w)}debug(e,t={}){(process.env.MCP_DEBUG===`1`||process.env.DEBUG?.includes(`mcp`))&&this.emit(`debug`,e,t)}child(t){return new e(t??this.component,this.sessionId)}asCallback(){return e=>this.info(e)}emit(e,t,S){let w={ts:new Date().toISOString(),level:e,sessionId:this.sessionId,corrId:this.corrId,component:this.component,msg:t,...S},E=`${JSON.stringify(w)}\n`;process.stderr.write(E);let D=process.env.OK_LOG_FILE;if(D)try{appendFileSync(D,E)}catch(e){console.warn(`[mcp-logger] Failed to write to OK_LOG_FILE: ${e instanceof Error?e.message:e}`)}}};function runWithMcpLogger(e,t){return loggerContext.run(e,t)}function getCurrentMcpLogger(){return loggerContext.getStore()}const REDACTED_STRING_KEYS=new Set([`find`,`markdown`,`replace`]),COMMON_ARRAY_KEYS=[`backlinks`,`deadLinks`,`documents`,`enrichedPaths`,`entries`,`forwardLinks`,`hints`,`hubs`,`orphans`,`results`],COMMON_SCALAR_KEYS=[`checkpointRef`,`cwd`,`fileCount`,`matchCount`,`ok`,`query`,`stdoutTruncated`,`truncated`];function isPlainObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function isToolExtraLike(e){return isPlainObject(e)&&`requestId`in e}function summarizeStringForLog(e,t){if(REDACTED_STRING_KEYS.has(e))return{redacted:!0,type:`string`,length:t.length,lines:t.length===0?0:t.split(`
|
|
2112
|
+
`).map(e=>e.trim()).filter(Boolean),k=null;for(let e=O.length-1;e>=0;e--)try{k=JSON.parse(O[e]);break}catch{}k===null?successResponse(t,200,LocalOpAuthPatSuccessSchema,{},{handler:Tc}):successResponse(t,200,LocalOpAuthPatSuccessSchema,k,{handler:Tc})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth pat failed.`,{handler:Tc,cause:e})}finally{Ce.release(mc)}},{handler:Tc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Tc})}),Dc=`local-op-auth-identity`;async function Oc(e,t){if(checkLocalOpSecurity(e,t,{handler:Dc})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:Dc,extraHeaders:{Allow:`GET`}});return}if(!de){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:Dc});return}try{successResponse(t,200,LocalOpAuthIdentitySuccessSchema,{identity:await resolveGitIdentity(de)},{handler:Dc})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Identity resolution failed.`,{handler:Dc,cause:e})}}}let kc=`/api/local-op/auth/set-identity`,Ac=`local-op-auth-set-identity`,jc=withValidation(LocalOpAuthSetIdentityRequestSchema,async(e,t,S)=>{let w=S.name.trim(),E=S.email.trim();if(!de){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:Ac});return}if(!Ce.tryAcquire(kc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A set-identity operation is already in progress.`,{handler:Ac,extraHeaders:{"Retry-After":`5`}});return}try{writeGitIdentity(de,w,E),ce?.()?.refreshIdentity().catch(()=>{}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:Ac})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Set-identity failed.`,{handler:Ac,cause:e})}finally{Ce.release(kc)}},{handler:Ac,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Ac})});async function Mc(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=ce?.();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},{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 Nc=withValidation(SyncTriggerRequestSchema,async(e,t,S)=>{let w=ce?.();if(!w){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`});return}let E=S.op??`sync`;successResponse(t,202,SyncTriggerSuccessSchema,{op:E},{handler:`sync-trigger`}),w.trigger(E)},{handler:`sync-trigger`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-trigger`})?ce?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`}),!1):!1});async function Pc(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=ce?.();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 Fc=withValidation(SyncResolveConflictRequestSchema,async(e,t,S)=>{let w=ce?.();if(!w){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`});return}let{file:E,strategy:D,content:O}=S;try{await w.resolveConflict(E,D,O),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})}},{handler:`sync-resolve-conflict`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-resolve-conflict`})?ce?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`}),!1):!1});async function Ic(e,t){if(!checkLocalOpSecurity(e,t,{handler:`sync-conflict-content`}))return;if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflict-content`,extraHeaders:{Allow:`GET`}});return}if(!de){errorResponse(t,503,`urn:ok:error:project-repo-not-configured`,`Project repo not configured.`,{handler:`sync-conflict-content`});return}let S=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`file`);if(!S){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing required query param: file.`,{handler:`sync-conflict-content`});return}if(S.includes(`..`)||S.startsWith(`/`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid file path.`,{handler:`sync-conflict-content`});return}let w=esm_default({baseDir:de,timeout:{block:15e3}});async function E(e){try{return await w.raw([`show`,`:${e}:${S}`])}catch{return``}}try{let[e,w,D]=await Promise.all([E(1),E(2),E(3)]);successResponse(t,200,SyncConflictContentSuccessSchema,{file:S,base:e,ours:w,theirs:D},{handler:`sync-conflict-content`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read conflict content.`,{handler:`sync-conflict-content`,cause:e})}}async function Lc(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`),E=S.searchParams.get(`rootDir`)??void 0,D=S.searchParams.get(`packId`),O=coercePackId(D);if(D!==null&&D!==``&&O===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-plan`,detail:`Pack id "${D}" is not registered.`});return}try{successResponse(t,200,SeedPlanSuccessSchema,{plan:await planSeed({projectDir:w,rootDir:E,packId:O})},{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 Rc=withValidation(SeedApplyRequestSchema,async(e,t,S)=>{let E=S.plan;if(!E||typeof E!=`object`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid plan payload.`,{handler:`seed-apply`});return}let D=E,O=S.packId,k=coercePackId(O);if(typeof O==`string`&&O.length>0&&k===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-apply`,detail:`Pack id "${O}" is not registered.`});return}try{successResponse(t,200,SeedApplySuccessSchema,{result:await applySeed(D,{projectDir:w,packId:k})},{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 zc(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 Bc=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 Vc(e,t){if(checkLocalOpSecurity(e,t,{handler:`installed-agents`}))try{await handleInstalledAgents(e,t,Re.probeAll)}catch(e){t.headersSent||(log$2.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}))}}async function Hc(e,t){if(!checkLocalOpSecurity(e,t,{handler:`sync-abort-merge`}))return;if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-abort-merge`,extraHeaders:{Allow:`POST`}});return}let S=ce?.();if(!S){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-abort-merge`});return}try{await S.abortMerge(),successResponse(t,200,SyncAbortMergeSuccessSchema,{},{handler:`sync-abort-merge`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to abort merge.`,{handler:`sync-abort-merge`,cause:e})}}let Uc=withValidation(EmptyRequestSchema,async(e,t)=>{if(!te){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-list`});return}try{successResponse(t,200,TagsListSuccessSchema,{tags:te.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 Wc(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(!te){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-for-name`});return}let w;try{w=decodeURIComponent(S)}catch{errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid tag name encoding.`,{handler:`tags-for-name`});return}if(!w){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing tag name.`,{handler:`tags-for-name`});return}try{let e=te.getDocsForTagWithMatches(w).map(({docName:e,matchingTags:t})=>({docName:e,title:Be(e),matchingTags:t,snippet:null}));successResponse(t,200,TagsForNameSuccessSchema,{name:w,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 Gc(e,t,S=`path`,E=`folder-config`){let D=e.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``);if(D.split(`/`).some(e=>e===`..`)||e.startsWith(`/`))return errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid ${S}: must be project-root-relative.`,{handler:E}),null;let O=resolve(w),k=D===``?O:resolve(O,D);return k!==O&&!k.startsWith(`${O}${sep}`)?(errorResponse(t,400,`urn:ok:error:invalid-request`,`Path escapes content directory.`,{handler:E}),null):{folderRel:D,resolvedContentDir:O}}let Kc=/^[A-Za-z0-9_-]+$/;function qc(e,t,S=`template`){return!e||!Kc.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 Jc(e){let t={};if(!e||typeof e!=`object`||Array.isArray(e))return t;for(let[S,w]of Object.entries(e))w!==void 0&&(t[S]=w);return t}async function Yc(e,t){if(e.method===`GET`)return Xc(e,t);if(e.method===`PUT`)return Zc(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`folder-config`,extraHeaders:{Allow:`GET, PUT`}})}let Xc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let S=Gc(new URL(e.url??``,`http://localhost`).searchParams.get(`path`)??``,t,`path`,`folder-config-get`);if(!S)return;let w=await enrichDirectory(S.folderRel,{projectDir:S.resolvedContentDir}),E=resolve(S.resolvedContentDir,S.folderRel,`.ok`,`frontmatter.yml`),D=null;if(existsSync(E))try{let e=(0,import_dist$1.parse)(await readFile$1(E,`utf-8`));D=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 ${E}: ${t}`),D=null}successResponse(t,200,FolderConfigGetSuccessSchema,{folder:w,frontmatter_local:D},{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}),Zc=withValidation(FolderConfigPutRequestSchema,async(e,t,S)=>{try{let e=Gc(S.path,t,`path`,`folder-config-put`);if(!e)return;let w=e.folderRel===``?`**`:`${e.folderRel}/**`,E=applyNestedFolderRulesUpsert({projectDir:e.resolvedContentDir,rules:[{match:w,frontmatter:Jc(S.frontmatter)}]});if(!E.ok){let e=E.error.code===`WRITE_ERROR`||E.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 write folder config.`:`Invalid folder config request.`,{handler:`folder-config-put`,detail:E.error.code,cause:Error(E.error.message)});return}successResponse(t,200,FolderConfigPutSuccessSchema,{applied:E.applied},{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`});async function Qc(e,t){if(e.method===`GET`)return il(e,t);if(e.method===`PUT`)return al(e,t);if(e.method===`DELETE`)return cl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`template`,extraHeaders:{Allow:`GET, PUT, DELETE`}})}let $c=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/,nl=e=>{let t=e.match($c),S={},w=e;if(t){try{let e=(0,import_dist$1.parse)(t[1]??``);e&&typeof e==`object`&&!Array.isArray(e)&&(S=e)}catch{}w=e.slice(t[0].length)}return{frontmatter:S,body:w}},il=withValidation(EmptyRequestSchema,async(e,t)=>{try{let S=new URL(e.url??``,`http://localhost`),w=S.searchParams.get(`name`)??``;if(!qc(w,t,`template-get`))return;let E=Gc(S.searchParams.get(`folder`)??``,t,`folder`,`template-get`);if(!E)return;let{folderRel:D,resolvedContentDir:O}=E,k=D===``?[]:D.split(`/`),j=null,F=null,L=null;for(let e=k.length;e>=0;e--){let t=e===0?``:k.slice(0,e).join(`/`),S=t===``?O:resolve(O,t);if(S!==O&&!S.startsWith(`${O}${sep}`))continue;let E=resolve(S,`.ok`,`templates`,`${w}.md`);if(existsSync(E)){j=E,F=t,L=e===k.length?`local`:`inherited`;break}}if(!j||F===null||L===null){errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-get`,detail:`Template "${w}" not found for folder "${D||`.`}". Walked leaf → root.`});return}let{frontmatter:B,body:H}=nl(await readFile$1(j,`utf-8`)),q=relative(O,j).split(/[\\/]/).filter(Boolean).join(`/`);successResponse(t,200,TemplateGetSuccessSchema,{template:{name:w,folder:F,scope:L,path:q,frontmatter:B,body:H}},{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}),al=withValidation(TemplatePutRequestSchema,async(e,t,S)=>{try{let e=S.name;if(!qc(e,t,`template-put`))return;let w=Gc(S.folder,t,`folder`,`template-put`);if(!w)return;let E=applyTemplateWrite({projectDir:w.resolvedContentDir,folder:w.folderRel,name:e,body:typeof S.body==`string`?S.body:``,frontmatter:Jc(S.frontmatter)});if(!E.ok){let e=E.error.code===`WRITE_ERROR`||E.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 write template.`:`Invalid template request.`,{handler:`template-put`,detail:E.error.code,cause:Error(E.error.message)});return}successResponse(t,200,TemplatePutSuccessSchema,{path:E.path,created:E.created,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`}),cl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let S=new URL(e.url??``,`http://localhost`),w=S.searchParams.get(`name`)??``;if(!qc(w,t,`template-delete`))return;let E=Gc(S.searchParams.get(`folder`)??``,t,`folder`,`template-delete`);if(!E)return;let D=applyTemplateDelete({projectDir:E.resolvedContentDir,folder:E.folderRel,name:w});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}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});function ll(e){let t=new Map;for(let S of e){let e=S.path.split(`/`).filter(Boolean);e.pop();for(let w=1;w<=e.length;w++){let E=e.slice(0,w).join(`/`);t.set(E,Math.max(t.get(E)??0,S.modifiedTs))}}return[...t.entries()].map(([e,t])=>createWorkspaceSearchDocument({kind:`folder`,path:e,modifiedTs:t}))}function ul(e,t){let S=t.trim().toLowerCase();if(!S||!e)return;let w=e.toLowerCase().indexOf(S);if(w<0)return;let E=Math.max(0,w-80),D=Math.min(e.length,w+S.length+120),O=E>0?`…`:``,k=D<e.length?`…`:``;return`${O}${e.slice(E,D).replace(/\s+/g,` `).trim()}${k}`}function dl(e){return e===`autocomplete`||e===`full_text`||e===`omnibar`?e:`omnibar`}function fl(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`);return S.length>0?S:void 0}async function pl(){let e=[];for(let[t,S]of D()){if(isSystemDoc(t)||isConfigDoc(t))continue;let w=``,E=t;try{w=await readFile$1(S.canonicalPath,`utf-8`),E=extractPageTitle(w,t)}catch(e){console.warn(`[search] Failed to index ${t}:`,e)}e.push(createWorkspaceSearchDocument({kind:`page`,path:t,title:E,content:w,modifiedTs:Date.parse(S.modified)}))}return[...e,...ll(e)]}function ml(){return[...D()].filter(([e])=>!isSystemDoc(e)&&!isConfigDoc(e)).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}${t.modified}${t.size}${t.canonicalPath}${t.inode}${t.aliases.join(`,`)}`).join(``)}async function hl(){let e=`${w}${de??``}`,t=ml(),S=workspaceSearchCaches.get(e);if(S?.fingerprint===t&&S.corpus)return S.corpus;if(S?.fingerprint===t&&S.pending)return S.pending;let E=pl().then(e=>createWorkspaceSearchCorpus(e));workspaceSearchCaches.set(e,{fingerprint:t,pending:E});try{let S=await E;return workspaceSearchCaches.get(e)?.pending===E&&workspaceSearchCaches.set(e,{fingerprint:t,corpus:S}),S}catch(t){throw workspaceSearchCaches.get(e)?.pending===E&&workspaceSearchCaches.delete(e),t}}function gl(){if(process.env.NODE_ENV!==`test`)for(let e of[0,1e3,3e3])setTimeout(()=>{hl().catch(e=>{console.warn(`[search] Failed to prewarm workspace search cache:`,e)})},e)}gl();async function _l(e,t){if(e.method===`GET`)return vl(e,t);if(e.method===`POST`)return yl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`search`,extraHeaders:{Allow:`GET, POST`}})}let vl=withValidation(EmptyRequestSchema,async(e,t)=>{let S=new URL(e.url??``,`http://localhost`),w=S.searchParams.get(`limit`),E=S.searchParams.get(`query`)??``,D=dl(S.searchParams.get(`intent`)),O=fl(S.searchParams.get(`scope`)??S.searchParams.get(`scopes`)),k=w===null?void 0:Number(w);if(E.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-get`});return}try{let e=performance.now();successResponse(t,200,SearchSuccessSchema,{query:E,intent:D,results:searchWorkspaceCorpus(await hl(),E,{intent:D,scopes:O,limit:k}).map(e=>({kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?ul(e.document.content,E):void 0})),elapsedMs:Math.max(0,performance.now()-e)},{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}),yl=withValidation(SearchRequestSchema,async(e,t,S)=>{let w=typeof S.query==`string`?S.query:``,E=dl(S.intent),D=fl(S.scopes??S.scope),O=typeof S.limit==`number`?S.limit:void 0;if(w.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-post`});return}try{let e=performance.now();successResponse(t,200,SearchSuccessSchema,{query:w,intent:E,results:searchWorkspaceCorpus(await hl(),w,{intent:E,scopes:D,limit:O}).map(e=>({kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?ul(e.document.content,w):void 0})),elapsedMs:Math.max(0,performance.now()-e)},{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`}),xl=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 Cl(e,t){if(checkLocalOpSecurity(e,t,{handler:`handoff`}))try{await handleHandoffDispatch(e,t,{contentDir:w,platform:process.platform})}catch(e){t.headersSent||(log$2.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 Tl(e,t){if(checkLocalOpSecurity(e,t,{handler:`spawn-cursor`}))try{await handleSpawnCursor(e,t,{contentDir:w,platform:process.platform})}catch(e){t.headersSent||(log$2.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 El=withValidation(ShareConstructUrlRequestSchema,async(e,t,S)=>{try{if(!de){emitShareConstructUrlLog(`no-remote`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!isValidShareDocPath(S.docPath)){emitShareConstructUrlLog(`invalid-path`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`invalid-path`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let e=readGitHeadBranch(de);if(e===null){if(readOriginGitHubRepo(de).kind===`no-remote`){emitShareConstructUrlLog(`no-remote`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}emitShareConstructUrlLog(`detached-head`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`detached-head`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let w=readOriginGitHubRepo(de);if(w.kind===`no-remote`){emitShareConstructUrlLog(`no-remote`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(w.kind===`non-github`){emitShareConstructUrlLog(`non-github-remote`),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`non-github-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!branchExistsOnOrigin(de,e)){emitShareConstructUrlLog(`branch-not-on-origin`,!1),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`branch-not-on-origin`,branch:e},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let E=buildGitHubBlobUrl(w.owner,w.repo,e,S.docPath),D=`${SHARE_BASE_URL}${encodeShareUrl(E)}`;emitShareConstructUrlLog(`ok`,!0),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!0,shareUrl:D,blobUrl:E,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})});async function Dl(e){let[t,...S]=ue,w=[...S,...e];return await new Promise((e,S)=>{let E=spawn(t,w,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),D=!1,O=setTimeout(()=>{D=!0,E.kill(`SIGTERM`)},SHARE_PUBLISH_TIMEOUT_MS),k=[],j=[];E.stdout.on(`data`,e=>k.push(e)),E.stderr.on(`data`,e=>j.push(e)),E.on(`close`,t=>{if(clearTimeout(O),D){S(Error(`share subprocess timed out after ${SHARE_PUBLISH_TIMEOUT_MS}ms`));return}let w=Buffer.concat(k).toString(`utf-8`);if(t!==0){let e=redactShareSubprocessStderr(Buffer.concat(j).toString(`utf-8`)).slice(0,500);console.warn(`[share] subprocess exited code=${t} stderr=${e}`)}e({stdout:w,code:t})}),E.on(`error`,e=>{clearTimeout(O),S(e)})})}let Ol=withValidation(EmptyRequestSchema,async(e,t)=>{if(!Ce.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 Dl([`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{Ce.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})}),kl=withValidation(EmptyRequestSchema,async(e,t)=>{let S=new URL(e.url??``,`http://localhost`),w=S.searchParams.get(`owner`)??``,E=S.searchParams.get(`name`)??``;if(!isValidShareOwnerName(w)||!isValidShareRepoName(E)){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(!Ce.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 Dl([`share`,`name-check`,`--owner`,w,`--name`,E,`--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{Ce.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})}),jl=withValidation(SharePublishRequestSchema,async(e,t,S)=>{if(!de){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(!Ce.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`,de,`--json`];S.description!==void 0&&S.description.length>0&&e.push(`--description`,S.description);let{stdout:w}=await Dl(e),E=parsePublishEvent(pickTerminalJsonLine(w));emitSharePublishLog(`publish-create`,E.ok?`ok`:E.error),successResponse(t,200,SharePublishResponseSchema,E,{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{Ce.release(SHARE_PUBLISH_KEY)}},{handler:SHARE_PUBLISH_HANDLER_TAG,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_HANDLER_TAG})}),Ml={"/api/asset":Xi,"/api/asset-text":ka,"/api/document":$t,"/api/documents":en,"/api/backlinks":jr,"/api/backlink-counts":Mr,"/api/forward-links":Fr,"/api/link-graph":Ir,"/api/dead-links":Br,"/api/orphans":Lr,"/api/hubs":zr,"/api/tags":Uc,"/api/pages":Is,"/api/folder-config":Yc,"/api/template":Qc,"/api/search":_l,"/api/suggest-links":Rs,"/api/page-headings":ks,"/api/create-page":Ts,"/api/create-folder":Ds,"/api/duplicate-path":Os,"/api/rename-path":As,"/api/delete-path":Ns,"/api/trash/cleanup":Ps,"/api/upload":$s,"/api/agent-write":Ut,"/api/agent-write-md":Wt,"/api/frontmatter-patch":Kt,"/api/agent-patch":Vr,"/api/agent-undo":Hr,"/api/agent-activity":Ur,"/api/agent-burst-diff":Wr,"/api/save-version":Jr,"/api/history":Yr,"/api/diff":Zr,"/api/rollback":Qr,"/api/metrics/reconciliation":ji,"/api/metrics/parse-health":Hi,"/api/metrics/agent-presence":Ki,"/api/server-info":Ui,"/api/share/construct-url":El,"/api/share/publish/owners":Ol,"/api/share/publish/name-check":kl,"/api/share/publish":jl,"/api/principal":Gi,"/api/rescue":xs,"/api/workspace":Yi,"/api/sync/status":Mc,"/api/sync/trigger":Nc,"/api/sync/conflicts":Pc,"/api/sync/conflict-content":Ic,"/api/sync/resolve-conflict":Fc,"/api/sync/abort-merge":Hc,"/api/local-op/clone":ac,"/api/local-op/open":lc,"/api/local-op/auth/login":gc,"/api/local-op/auth/status":yc,"/api/local-op/auth/repos":xc,"/api/local-op/auth/signout":wc,"/api/local-op/auth/pat":Ec,"/api/local-op/auth/identity":Oc,"/api/local-op/auth/set-identity":jc,"/api/installed-agents":Vc,"/api/spawn-cursor":Tl,"/api/handoff":Cl,"/api/install-skill":Bc,"/api/skill/install-state":xl,"/api/seed/plan":Lc,"/api/seed/apply":Rc,"/api/seed/packs":zc};F&&(Ml[`/api/test-reset`]=Gr,Ml[`/api/test-rescan-backlinks`]=Kr,Ml[`/api/test-rescan-files`]=qr);let Pl=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/sync/abort-merge`,`/api/test-reset`,`/api/test-rescan-backlinks`,`/api/test-rescan-files`,`/api/install-skill`,`/api/folder-config`,`/api/template`,`/api/seed/apply`]),Fl=[`/api/local-op/`];return{priority:100,async onRequest({request:e,response:t}){let S=e.url?.split(`?`)[0];if(!S)return;if(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`)),e.method===`OPTIONS`){t.writeHead(204),t.end();return}}if(Pl.has(S)||Fl.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(!S.startsWith(`/api/`))return;let w=propagation.extract(context.active(),e.headers),E=e.method??`GET`,D=S;S.startsWith(`/api/rescue/`)?D=`/api/rescue/:docName`:S.startsWith(`/api/history/`)?D=`/api/history/:sha`:S.startsWith(`/api/tags/`)?D=`/api/tags/:name`:Ml[S]||(D=`/api/*`);let O=getTracer(),k=Date.now();await context.with(w,()=>O.startActiveSpan(`HTTP ${E} ${D}`,{kind:SpanKind.SERVER,attributes:{[ATTR_HTTP_REQUEST_METHOD]:E,[ATTR_HTTP_ROUTE]:D,[ATTR_URL_PATH]:S,[ATTR_URL_SCHEME]:`http`,[ATTR_USER_AGENT_ORIGINAL]:e.headers[`user-agent`]??``}},async w=>{try{let D=Ml[S],O=!1;if(D)O=!0,await D(e,t);else if(S.startsWith(`/api/rescue/`)){let w=decodeURIComponent(S.slice(12));w&&(O=!0,await Cs(e,t,w))}else if(S.startsWith(`/api/history/`)){let w=decodeURIComponent(S.slice(13));w&&(O=!0,await Xr(e,t,w))}else if(S.startsWith(`/api/tags/`)){let w=S.slice(10);w&&(O=!0,await Wc(e,t,w))}O||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`api-dispatch`,detail:`No handler for ${E} ${S}`});let k=t.statusCode;w.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE,k),k>=500&&w.setStatus({code:SpanStatusCode.ERROR,message:`status ${k}`})}catch(e){throw w.recordException(e),w.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:D,cause:e}),e}finally{w.end();let e=(Date.now()-k)/1e3;httpDurationHist().record(e,{[ATTR_HTTP_REQUEST_METHOD]:E,[ATTR_HTTP_ROUTE]:D,[ATTR_HTTP_RESPONSE_STATUS_CODE]:t.statusCode})}}))}}}function isWithinDir(e,t){return e===t?!0:e.startsWith(`${t}${sep}`)}function errnoCode(e){let t=e?.code;return typeof t==`string`?t:void 0}function seedBasenameIndex(e){let t=e.contentDir,S=new Set;function w(E){let D;try{D=readdirSync(E,{withFileTypes:!0})}catch(t){let S=errnoCode(t);S!==`ENOENT`&&e.onSkip?.(`read-failed`,S,E);return}for(let O of D){let D=join(E,O.name),k=relative(t,D);if(k.startsWith(`..`)||e.contentFilter?.isDirExcluded(k)&&O.isDirectory())continue;let j;try{j=lstatSync(D)}catch(t){let S=errnoCode(t);S!==`ENOENT`&&e.onSkip?.(`lstat-failed`,S,D);continue}if(j.isSymbolicLink()){let E;try{E=realpathSync(D)}catch(t){let S=errnoCode(t);S!==`ENOENT`&&e.onSkip?.(`realpath-failed`,S,D);continue}if(!isWithinDir(E,t)){e.onSkip?.(`symlink-escape`,void 0,D);continue}let O;try{O=statSync(E)}catch(t){let S=errnoCode(t);S!==`ENOENT`&&e.onSkip?.(`symlink-stat-failed`,S,E);continue}if(S.has(O.ino))continue;S.add(O.ino),O.isDirectory()?w(E):O.isFile()&&isSupportedAssetFile(D,ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(k)&&e.basenameIndex.add(k);continue}if(j.isDirectory()){if(S.has(j.ino))continue;S.add(j.ino),w(D);continue}j.isFile()&&isSupportedAssetFile(D,ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(k)&&e.basenameIndex.add(k)}}w(t)}const HocuspocusAuthTokenSchema=object$1({principalId:string$2().optional(),tabSessionId:string$2().optional(),expectedServerInstanceId:string$2().optional(),expectedBranch:string$2().optional()}).loose(),HOCUSPOCUS_AUTH_REJECTION_REASONS=[`server-instance-mismatch`,`branch-mismatch`,`rename-redirect`,`doc-deleted`];function isHocuspocusAuthRejectionReason(e){return HOCUSPOCUS_AUTH_REJECTION_REASONS.includes(e)}const WIRE_PAYLOAD_SEPARATOR=`:`;function formatAuthRejectionWire(e,t){return typeof t!=`string`||t.length===0?e:`${e}${WIRE_PAYLOAD_SEPARATOR}${t}`}function parseAuthRejectionWire(e){if(e.length===0)return{kind:null,payload:void 0};let t=e.indexOf(WIRE_PAYLOAD_SEPARATOR),S=t===-1?e:e.slice(0,t);if(!isHocuspocusAuthRejectionReason(S))return{kind:null,payload:void 0};if(t===-1)return{kind:S,payload:void 0};let w=e.slice(t+1);return{kind:S,payload:w.length>0?w:void 0}}var HocuspocusAuthRejection=class extends Error{kind;payload;reason;constructor(e,t,S){super(t),this.name=`HocuspocusAuthRejection`,this.kind=e,this.payload=typeof S==`string`&&S.length>0?S:void 0,this.reason=formatAuthRejectionWire(e,this.payload)}};function parseHocuspocusAuthToken(e){if(typeof e!=`string`||e.length===0)return;let t;try{t=JSON.parse(e)}catch{return}let S=HocuspocusAuthTokenSchema.safeParse(t);return S.success?S.data:void 0}const DEFAULT_WARN_BEFORE_MS=300*1e3;function attachIdleShutdown(e){let t=e.scheduler??defaultScheduler,S=e.warnBeforeMs??DEFAULT_WARN_BEFORE_MS,w=0,E=null,D=null,O=!1,k=!1;function j(){E!==null&&(t.clearTimeout(E),E=null),D!==null&&(t.clearTimeout(D),D=null)}function F(){j(),!(k||O)&&w===0&&(S>0&&S<e.thresholdMs&&(D=t.setTimeout(()=>{D=null,w===0&&!O&&e.log?.warn({msUntilShutdown:S,webSocketClientCount:0},`idle shutdown pending: no WebSocket clients`)},e.thresholdMs-S)),E=t.setTimeout(()=>{if(E=null,!(k||O)&&w===0){O=!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 L=(e,t)=>{e.url?.startsWith(`/collab`)&&(w++,j(),t.once(`close`,()=>{w--,w<0&&(w=0),w===0&&F()}))};return e.httpServer.on(`upgrade`,L),F(),{detach:()=>{k||(k=!0,e.httpServer.off(`upgrade`,L),j())}}}const MCP_SERVER_NAME=`open-knowledge`,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 buildInstructions(e){return'Open Knowledge is a markdown-CRDT knowledge base exposed via MCP.\n\n## STOP — native tools on in-scope `.md` / `.mdx`\n\nWhen this workspace has Open Knowledge MCP configured, do **not** use your host\'s native file tools on markdown paths inside the content directory. The ban covers every common rationalization:\n\n- **Native `Read` / `Grep` / `Glob` on in-scope `.md` / `.mdx`** — the original case.\n- **`Bash ls` / `Bash find` / `Bash cat` on dirs containing in-scope markdown** — use `exec("ls -A …")` / `exec("find … -name \'*.md\'")` / `exec("cat …")` instead. Native returns bare names; `exec` returns frontmatter, backlink counts, and recent activity per child. `-A` shows hidden entries (`.ok/`, `.okignore`) which OK projects carry; omit `.` and `..` rows that `-a` would add.\n- **Glob patterns that target markdown** (`**/*.md`, any dir known to be markdown-heavy like `specs/**`, `reports/**`, `docs/**`) — use `exec` with `find`, or `exec("ls -A <dir>")`.\n- **Dispatching the Explore / general-purpose subagent for markdown-heavy exploration** — subagents use native `Read` / `Grep` / `Glob` internally and bypass Open Knowledge entirely. Do markdown exploration yourself via `exec` / `search`. Subagents remain appropriate for **source-code** exploration.\n- **Native `Read` / `Grep` on any in-scope markdown inside `.ok/`** — the `.ok/` directory is in-scope; if it carries `.md` / `.mdx`, treat those the same as any other knowledge-base file.\n\nWhy: native tools skip frontmatter, backlinks, shadow-repo activity, and project git history that OK\'s tools return for every matched knowledge-base file. `exec` is the primary read surface; it runs read-only bash (`cat`, `ls`, `grep`, `find`, `head`, `tail`, `wc`, `sort`, `uniq`, `cut` — pipes OK) and returns raw stdout plus enriched metadata per file.\n\n**MCP tool visibility — not seeing `exec` is NOT the escape hatch.** MCP wiring varies by client. Claude Code, Cursor, Codex, Windsurf, VS Code — each surfaces MCP differently. Server labels are user-defined; tools may not appear as top-level symbols named `exec` in your specific UI. If Open Knowledge is registered as an MCP server in this workspace, route markdown reads through its `exec` / `search` via your client\'s documented MCP invocation (including any generic "call MCP tool" flow). Registration is the test, not top-level-symbol visibility.\n\n**Escape hatch.** Native `Read` / `Grep` / `Glob` on `.md` / `.mdx` is allowed **only** when no Open Knowledge MCP server is registered for this project, **or** immediately after you tried an MCP call and it failed — then begin a user-visible sentence with `Open Knowledge MCP unavailable:`. Never use the hatch because you skipped your client\'s MCP path, didn\'t see `exec` as a top-level tool, or rationalized the skill wasn\'t necessary.\n\n**Source code and non-markdown files** (`.ts`, `.py`, `package.json`, …): native `Read` / `Grep` / `Glob` always.\n\n## Reads — examples\n\n- Read a file: `exec("cat <path>.md")` — contents + full rich enrichment.\n- List a directory: `exec("ls -A <dir>")` — per-child frontmatter, recursive markdown counts, most-recently-updated doc per subdir, folder-level `frontmatter_defaults` + `templates_available`. Prefer `-A` over plain `ls` to surface dot-prefixed entries (`.ok/`, `.okignore`) without the noisy `.`/`..` rows that `-a` adds.\n- Literal search: `exec("grep -rn <term> <dir> | head -5")` — matches + enrichment on matched files.\n- Ranked search: `search({ query })` — cmd-K parity (title boost + body BM25 + recency); use when picking the best doc, not when listing every occurrence.\n\n## Preview — open the browser at session start\n\n**The invariant.** If OK Electron is open for this project OR `ok ui` is running for it, every OK tool response carries the preview URL — plain HTTP, no custom URL schemes, works in any browser including agent in-app browsers (Claude Desktop, Cursor, Codex, Cowork). Read tools (`exec`, `search`, `links`) carry it in `ui.baseUrl` (top-level) and per-doc `previewUrl` fields; write tools carry it in `previewUrl` + the optional `warning` shape. Never construct this URL; always read it from the latest tool response.\n\n**The default agent move.** Make your first OK tool call (any read works — `exec("ls -A")` is enough). The response carries the preview URL. Navigate to it immediately, then proceed with your real work. The user watches edits land live; you can re-navigate later to verify a CRDT edit landed when a response looks ambiguous. Per host:\n\n- **In-app browser hosts** (Claude Desktop, Cursor, Codex, Cowork): navigate the in-app browser to the `previewUrl`. Default.\n- **Claude Code Desktop**: call `preview_start("open-knowledge-ui")` (host tool, not OK MCP) — and nothing else. Do NOT read, diagnose, or edit `.claude/launch.json`; that file is host-managed config, and the OK ui lock-collision proxy handles the UI-already-running case automatically. If `preview_start` fails, surface the `previewUrl` from any recent OK tool response and report the issue to the user — do not try to "fix" `launch.json`.\n- **Stdio-only hosts**: surface the URL in chat; `open <url>` (macOS) if the host can shell out.\n\n**Four signals to check if it\'s already open** (you usually can\'t pre-check, so read these from each write response):\n\n1. You opened/navigated earlier this session → don\'t reopen.\n2. Write response has `previewUrl` (non-null) and NO `warning` → a browser is attached somewhere; do nothing.\n3. `warning: { action: "attach-preview-once", previewUrl, message }` → UI reachable, no browser attached; navigate one-shot.\n4. `warning: { action: "start-ui", previewUrl: null, message }` → no UI running anywhere. Surface the message verbatim — recovery options are in the in-band copy. Don\'t loop on retries.\n\nWarnings fire at most once per session in the fresh-start case.\n\n**`previewUrl: null` only means "no UI reachable" on the three attach-warning tools: `write_document` / `edit_document` / `edit_frontmatter`.** Workflow tools return prose and don\'t carry `previewUrl`. `delete_document` / `rename` emit `previousPreviewUrl` (different field, for closing stale tabs) and don\'t fire attach warnings.\n\n**Always read `previewUrl` from the latest write response.** Don\'t cache the session-start value — Electron quit/reopen (or `ok ui` restart) can change the port; the resolver picks up the new port automatically.\n\nIf you see `"Hocuspocus server is not running"`, run `ok start` and retry. NEVER construct preview URLs by hand.\n\nOK Electron and `ok ui` share `ui.lock` — only one can be the primary server for a project. When a second `ok ui` tries to bind a different port (Claude Code Desktop\'s preview pane spawning a sibling, for example), the OK lock-collision handler proxies the new port to the live UI server transparently. **Do not nudge the user to quit OK Electron to free a port** — the proxy handles it, and quitting would tear down a UI the user is actively using.\n\n**The preview is read-only for the agent.** Navigate to verify edits landed; you cannot click or type to drive edits — the CRDT flow is one-way (agent → MCP → CRDT → preview).\n\n**No screenshots after every edit.** Do NOT take `preview_screenshot` (host tool, not OK MCP) after every write. Trust the response. Screenshot only when (a) debugging a visual issue, (b) a response looks ambiguous, or (c) the user asks.\n\n## Scope recap\n\nOpen Knowledge looks for documents under the resolved `content.dir` (discoverable at runtime via `get_config({ path: [\'content\', \'dir\'] })`). `.gitignore` and `.okignore` (at the project root and at any folder depth) define exclusions. Folder defaults + templates live in nested `<folder>/.ok/frontmatter.yml` + `<folder>/.ok/templates/` files — NOT in `.ok/config.yml`.\n\nDefault mental model (no jargon): **every `.md` and `.mdx` under `content.dir`** not excluded by `.gitignore` or `.okignore` is an Open Knowledge document — including under `specs/`, `reports/`, `docs/`, etc. Read `.okignore` (and any nested `.okignore` files) once per turn to know what\'s excluded.\n\n**First session in this project?** If `frontmatter_defaults` and `templates_available` are empty for substantial folders, the project hasn\'t been onboarded yet — invoke `discover` (Workflow tools table) before writing. Once onboarded, the cascade carries the discipline.\n\n\nFull guidance lives in the bundled `open-knowledge` skill at `~/.ok/skills/open-knowledge/SKILL.md`.\n'}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,w){if(!e.inputSchema||!isZodSchema(e.inputSchema))return S.call(this,e,t,w);let E=await e.inputSchema.safeParseAsync(t);if(E.success)return E.data;let D=prettifyError(E.error);throw new McpError(ErrorCode.InvalidParams,`Input validation error: Invalid arguments for tool ${w}:\n${D}`)},t.__prettyZodErrorsInstalled=!0}function isZodSchema(e){return typeof e!=`object`||!e?!1:typeof e.safeParseAsync==`function`}const loggerContext=new AsyncLocalStorage;var McpLogger=class e{sessionId;corrId;component;constructor(e=`mcp`,t){this.sessionId=t??randomUUID().slice(0,12),this.corrId=randomUUID().slice(0,8),this.component=e}info(e,t={}){this.emit(`info`,e,t)}warn(e,t={}){this.emit(`warn`,e,t)}error(e,t,S={}){let w=t?{error:t instanceof Error?t.message:String(t),...S}:S;this.emit(`error`,e,w)}debug(e,t={}){(process.env.MCP_DEBUG===`1`||process.env.DEBUG?.includes(`mcp`))&&this.emit(`debug`,e,t)}child(t){return new e(t??this.component,this.sessionId)}asCallback(){return e=>this.info(e)}emit(e,t,S){let w={ts:new Date().toISOString(),level:e,sessionId:this.sessionId,corrId:this.corrId,component:this.component,msg:t,...S},E=`${JSON.stringify(w)}\n`;process.stderr.write(E);let D=process.env.OK_LOG_FILE;if(D)try{appendFileSync(D,E)}catch(e){console.warn(`[mcp-logger] Failed to write to OK_LOG_FILE: ${e instanceof Error?e.message:e}`)}}};function runWithMcpLogger(e,t){return loggerContext.run(e,t)}function getCurrentMcpLogger(){return loggerContext.getStore()}const REDACTED_STRING_KEYS=new Set([`find`,`markdown`,`replace`]),COMMON_ARRAY_KEYS=[`backlinks`,`deadLinks`,`documents`,`enrichedPaths`,`entries`,`forwardLinks`,`hints`,`hubs`,`orphans`,`results`],COMMON_SCALAR_KEYS=[`checkpointRef`,`cwd`,`fileCount`,`matchCount`,`ok`,`query`,`stdoutTruncated`,`truncated`];function isPlainObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function isToolExtraLike(e){return isPlainObject(e)&&`requestId`in e}function summarizeStringForLog(e,t){if(REDACTED_STRING_KEYS.has(e))return{redacted:!0,type:`string`,length:t.length,lines:t.length===0?0:t.split(`
|
|
2113
2113
|
`).length};let S=e===`command`?240:120;return t.length<=S?t:{type:`string`,length:t.length,preview:`${t.slice(0,S)}...`}}function summarizeArgValue(e,t){if(t===null)return null;if(typeof t==`string`)return summarizeStringForLog(e,t);if(typeof t==`number`||typeof t==`boolean`)return t;if(Array.isArray(t))return{type:`array`,length:t.length};if(isPlainObject(t)){let e=Object.keys(t).sort();return{type:`object`,keyCount:e.length,keys:e.slice(0,12)}}if(t!==void 0)return{type:typeof t}}function summarizeArgsForLog(e,t){return isPlainObject(t)?Object.fromEntries(Object.entries(t).map(([e,t])=>[e,summarizeArgValue(e,t)])):summarizeArgValue(e,t)}function summarizeStructuredContentForLog(e){let t={structuredKeys:Object.keys(e).sort()};for(let S of COMMON_SCALAR_KEYS)S in e&&(t[S]=e[S]);for(let S of COMMON_ARRAY_KEYS){let w=e[S];Array.isArray(w)&&(t[`${S}Count`]=w.length)}return`previewUrl`in e&&(t.previewUrl=e.previewUrl??null),`previewUrlSource`in e&&(t.previewUrlSource=e.previewUrlSource),typeof e.stdout==`string`&&(t.stdoutChars=e.stdout.length),Array.isArray(e.warnings)&&(t.warningsCount=e.warnings.length),isPlainObject(e.warning)&&(t.warning=!0,`previewUrl`in e.warning&&(t.warningPreviewUrl=e.warning.previewUrl??null)),isPlainObject(e.ui)&&(t.uiBaseUrl=typeof e.ui.baseUrl==`string`||e.ui.baseUrl===null?e.ui.baseUrl:void 0,t.uiPort=typeof e.ui.port==`number`||e.ui.port===null?e.ui.port:void 0),t}function summarizeToolResultForLog(e){if(!isPlainObject(e))return{resultType:typeof e};let t={isError:e.isError===!0};return Array.isArray(e.content)&&(t.contentItems=e.content.length,t.contentTextChars=e.content.reduce((e,t)=>isPlainObject(t)&&typeof t.text==`string`?e+t.text.length:e,0)),isPlainObject(e.structuredContent)&&Object.assign(t,summarizeStructuredContentForLog(e.structuredContent)),t}function summarizeIdentityForLog(e){return{connectionId:e.connectionId.slice(0,8),displayName:e.displayName,...e.clientInfo?.name?{clientName:e.clientInfo.name}:{}}}function splitInvocationArgs(e){let t=e.at(-1);return isToolExtraLike(t)?{toolArgs:e.length>1?e[0]:void 0,extra:t}:{toolArgs:e[0],extra:void 0}}function wrapToolHandlerForLogging(e,t,S){let w=S.logger;return w?async(...E)=>{let D=w.child(),O=Date.now(),{toolArgs:k,extra:j}=splitInvocationArgs(E);D.info(`tool start`,{tool:e,...j?.requestId===void 0?{}:{requestId:j.requestId},...j?.sessionId?{transportSessionId:j.sessionId}:{},...S.identityRef?.current?{agent:summarizeIdentityForLog(S.identityRef.current)}:{},...k===void 0?{}:{args:summarizeArgsForLog(e,k)}});try{let S=await runWithMcpLogger(D,async()=>await t(...E));return D.info(`tool finish`,{tool:e,...j?.requestId===void 0?{}:{requestId:j.requestId},durationMs:Date.now()-O,result:summarizeToolResultForLog(S)}),S}catch(t){throw D.error(`tool error`,t,{tool:e,...j?.requestId===void 0?{}:{requestId:j.requestId},durationMs:Date.now()-O}),t}}:t}function createLoggedServer(e,t){if(!t.logger)return e;let S=e.tool.bind(e),w=e.registerTool,E=typeof w==`function`?w.bind(e):void 0,D=Object.create(e);return D.tool=((...e)=>{let w=String(e[0]),E=e.at(-1);if(typeof E!=`function`)return S(...e);let D=[...e];return D[D.length-1]=wrapToolHandlerForLogging(w,E,t),S(...D)}),E&&(D.registerTool=((e,S,w)=>typeof w==`function`?E(e,S,wrapToolHandlerForLogging(e,w,t)):E(e,S,w))),D}function buildBody$2(e,t){return`Promote existing research on this topic into a canonical article inside the project content directory. **Canonical, not provisional** — the output is the source of truth for future agents.
|
|
2114
2114
|
|
|
2115
2115
|
Topic: ${e}
|
|
@@ -2229,7 +2229,7 @@ Structure:
|
|
|
2229
2229
|
Canonical articles are destinations — they should be **linked heavily from everywhere they're relevant** and link **out to every related page** themselves. Underlinked canonical articles lose most of their value.
|
|
2230
2230
|
|
|
2231
2231
|
- **Inside this article:** every noun-phrase that names another document (other canonical articles, related research, external-source pages, sibling topics) should be a standard markdown link \`[text](./relative/path.md)\`, not plain prose. (Wiki-link syntax \`[[Page]]\` is still parsed for legacy content but no longer the default; matches the OK skill guidance.)
|
|
2232
|
-
- **Redlinks are fine.** If you mention a concept that *should* have a page but doesn't yet, link it anyway — \`[link text](./path/that-should-exist.md)\`. The redlink signals future work; \`
|
|
2232
|
+
- **Redlinks are fine.** If you mention a concept that *should* have a page but doesn't yet, link it anyway — \`[link text](./path/that-should-exist.md)\`. The redlink signals future work; \`links({ kind: "dead" })\` will surface it.
|
|
2233
2233
|
- **Update neighbors.** After writing, find 2–3 closely-related existing pages (via \`exec("grep -rn <topic> ${t}")\`) and add a link to the new article from each — usually under a "See also" section or inline where the new article is relevant. This makes the article discoverable via backlinks, not just by remembering the path.
|
|
2234
2234
|
- **Link to the sources and superseded research** from "Further reading" — readers who want the trail can follow.
|
|
2235
2235
|
|
|
@@ -2257,13 +2257,12 @@ superseded_by: <path-to-new-canonical-article>.md
|
|
|
2257
2257
|
- **Don't delete research articles** — they are the trail; keep them with a \`superseded_by\` marker
|
|
2258
2258
|
- **Don't rewrite research prose verbatim** — canonical articles have a different voice (direct, decided) than research (exploratory, provisional)
|
|
2259
2259
|
- **Don't skip the supersedes / superseded_by links** — the audit trail matters for future readers
|
|
2260
|
-
`}const DESCRIPTION$
|
|
2261
|
-
`);function register$
|
|
2262
|
-
`);function parseDeletedDocNames(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function
|
|
2263
|
-
`)
|
|
2264
|
-
`),{result:E})})}function buildDiscoverBody(e){return`# Discover — Project Convention Extraction + Link Graph Activation
|
|
2260
|
+
`}const DESCRIPTION$16=[`Returns a step-by-step plan to promote stabilized research into a canonical article. Does NOT write — you execute the plan after a STOP gate confirms a real decision was made.`,"Canonical, not provisional — the output becomes the source of truth, with a `supersedes` trail back to the research.",`Use when a team has decided after research and wants the outcome committed as authoritative knowledge.`].join(`
|
|
2261
|
+
`);function register$16(e,t){e.registerTool(`consolidate`,{description:DESCRIPTION$16,inputSchema:{topic:string$2().describe(`The topic to consolidate into a canonical article`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},buildWorkflowHandler(`consolidate`,t,`topic`,buildBody$2))}const PREVIEW_URL_SOURCES=[`lock`];function encodeDocName(e){return e.split(`/`).map(encodeURIComponent).join(`/`)}const START_UI_MESSAGE='No UI is running for this project. Start one to see the preview: `ok ui` (terminal), `preview_start("open-knowledge-ui")` (Claude Code Desktop), or open the project in OK Electron.',ATTACH_PREVIEW_ONCE_MESSAGE=`Open the previewUrl in your preview browser.`;function buildPreviewAttachWarning(e){return e?{action:`attach-preview-once`,previewUrl:e.url,message:ATTACH_PREVIEW_ONCE_MESSAGE}:{action:`start-ui`,previewUrl:null,message:START_UI_MESSAGE}}const START_UI_TEXT_HINT=START_UI_MESSAGE;async function resolvePreviewUrlForTool(e,t,S){return resolvePreviewUrl(e,{lockDir:resolveLockDir(S??await t.resolveCwd())})}function resolveUiInfo(e){try{let t=readUiLock(e.lockDir);if(t&&t.port>0)return{baseUrl:`http://localhost:${t.port}`,port:t.port}}catch(t){process.stderr.write(`[preview-url] readUiLock failed at ${e.lockDir} while building ui block: ${t instanceof Error?t.message:String(t)}\n`)}return{baseUrl:null,port:null}}async function buildListResolver(e,t){let S={lockDir:resolveLockDir(t??await e.resolveCwd())};return{resolve:e=>resolvePreviewUrl(e,S),ui:resolveUiInfo(S)}}function docNameFromPath(e){let t=e.toLowerCase();return t.endsWith(`.md`)?e.slice(0,-3):t.endsWith(`.mdx`)?e.slice(0,-4):e}function resolvePreviewUrl(e,t){let S=`/#/${encodeDocName(e)}`;try{let e=readUiLock(t.lockDir);if(e&&e.port>0)return{url:`http://localhost:${e.port}${S}`,source:`lock`}}catch(e){process.stderr.write(`[preview-url] readUiLock failed at ${t.lockDir}: ${e instanceof Error?e.message:String(e)}\n`)}return null}const DESCRIPTION$15=["[Requires: Hocuspocus server] Delete a document through the managed delete flow at `POST /api/delete-path` (kind: file).",`Closes all open agent sessions for the doc, unloads it from Hocuspocus, and removes the file from disk.`,``,`**Parameters:**`,"- `docName` — A single document to delete, typically extension-less. A trailing `.md` or `.mdx` is stripped automatically.","- `docNames` — Batch form: an array of documents to delete in one call. Mutually exclusive with `docName`. Each is deleted independently; the response reports per-doc status.",``,`**Notes:**`,'- Inbound wiki-links to the deleted doc become dead links (redlinks) — they are NOT rewritten. Call `links({ kind: "backlinks", docName: "your-doc" })` BEFORE deleting to see which docs link here, then update or remove those references first.','- Deletion is irreversible from this tool. Use `version({ action: "save" })` beforehand if you may need to roll back.',"- The structured response includes `previousPreviewUrl` (when a preview source resolves) so agents can close any stale preview tab pointing at the deleted doc.",``,`**Errors:**`,"- 400 — `docName` is not a valid relative content path.",`- 404 — document does not exist.`].join(`
|
|
2262
|
+
`);function parseDeletedDocNames(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}async function deleteOne(e,t,S,w){let E=normalizeDocName(e);if(!E.ok)return{docName:e,ok:!1,error:E.error};let D=w.identityRef?.current,O=await httpPost(t,`/api/delete-path`,{kind:`file`,path:E.docName,...D?{agentId:D.connectionId,agentName:D.displayName,clientName:D.clientInfo?.name,colorSeed:D.colorSeed}:{}});if(!O.ok)return{docName:E.docName,ok:!1,error:O.error};let k=parseDeletedDocNames(O.deletedDocNames),j=await resolvePreviewUrlForTool(E.docName,{config:w.config,resolveCwd:w.resolveCwd},S);return{docName:E.docName,ok:!0,deletedDocNames:k.length>0?k:[E.docName],...j?{previousPreviewUrl:j.url}:{}}}function register$15(e,t){e.registerTool(`delete_document`,{description:DESCRIPTION$15,inputSchema:{docName:string$2().optional().describe(`A single document to delete.`),docNames:array(string$2()).min(1).optional().describe("Batch: documents to delete in one call. Mutually exclusive with `docName`."),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);if(e.docName===void 0&&e.docNames===void 0)return textResult("Error: provide `docName` (single) or `docNames` (batch).",!0);if(e.docName!==void 0&&e.docNames!==void 0)return textResult("Error: `docName` and `docNames` are mutually exclusive.",!0);if(e.docNames!==void 0){let S=await Promise.all(e.docNames.map(e=>deleteOne(e,E,w,t))),D=S.filter(e=>e.ok).length,O=D===S.length,k=S.map(e=>e.ok?`Deleted ${e.docName}.`:`Failed ${e.docName}: ${e.error}`);return textPlusStructured(`${D}/${S.length} deleted.\n${k.join(`
|
|
2263
|
+
`)}`,{ok:O,documents:S},!O)}let D=await deleteOne(e.docName,E,w,t);if(!D.ok){let e={ok:!1,error:D.error??`unknown error`};return textPlusStructured(`Error: ${e.error}`,e,!0)}let O=D.deletedDocNames??[D.docName],k={ok:!0,deletedDocNames:O,...D.previousPreviewUrl?{previousPreviewUrl:D.previousPreviewUrl}:{}};return textPlusStructured(O.length===1?`Deleted ${O[0]}.`:`Deleted ${O.length} documents: ${O.join(`, `)}.`,k)})}function buildDiscoverBody(e){return`# Discover — Project Convention Extraction + Link Graph Activation
|
|
2265
2264
|
|
|
2266
|
-
You're invoked because (a) the user explicitly asked to set up an existing repo, OR (b) \`
|
|
2265
|
+
You're invoked because (a) the user explicitly asked to set up an existing repo, OR (b) an \`exec\` directory listing surfaced a hint because content exists with no folder frontmatter / templates configured. Your job: **extract conventions from existing siblings + activate the link graph, leaving the repo more structured and more navigable than you found it.**
|
|
2267
2266
|
|
|
2268
2267
|
Content directory: \`${e}\` (from \`.ok/config.yml\`)
|
|
2269
2268
|
|
|
@@ -2271,28 +2270,26 @@ Use OK primitives only — no new files outside \`<folder>/.ok/\`, no body rewri
|
|
|
2271
2270
|
|
|
2272
2271
|
**You will work through 7 phases in order. STOP gates (⛔) require user confirmation before proceeding. Do not skip or batch ahead.**
|
|
2273
2272
|
|
|
2274
|
-
**Server requirement.**
|
|
2273
|
+
**Server requirement.** Phases 1-4 run fs-direct — \`exec\` (scan + read) and \`folder_config\` (folder frontmatter + templates) need no running server. Phase 5 (link-graph activation) composes \`links\` and \`search\`, which **require the OK Hocuspocus server** — Phase 5 step 0 checks for it and exits cleanly with a \`run ok start\` instruction if it is down.
|
|
2275
2274
|
|
|
2276
2275
|
---
|
|
2277
2276
|
|
|
2278
|
-
## Phase 1 — Scan + classify (no user interaction)
|
|
2277
|
+
## Phase 1 — Scan + classify (no user interaction, no server needed)
|
|
2279
2278
|
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
2. For each top-level **directory**: \`list_documents({ dir: <dir>, depth: 1 })\` to surface \`.md\` count + per-child frontmatter samples + recursive count.
|
|
2279
|
+
1. \`exec("ls ${e}")\` — list every top-level entry.
|
|
2280
|
+
2. For each top-level **directory**: \`exec("ls <dir>")\` — the enriched listing surfaces the \`.md\` count, per-child frontmatter samples, recursive count, and the folder's \`frontmatter_defaults\` + \`templates_available\`.
|
|
2283
2281
|
3. Classify each directory:
|
|
2284
2282
|
- **Substantial KB folder** — >3 \`.md\` files directly, OR named in known-genre list: \`specs/\`, \`reports/\`, \`docs/\`, \`articles/\`, \`research/\`, \`stories/\`, \`projects/\`, \`external-sources/\`, \`tech-probes/\`, \`rfcs/\`, \`proposals/\`, \`design-docs/\`, \`adrs/\`.
|
|
2285
2283
|
- **Trivial folder** — 1-3 \`.md\` files; treat as one-offs.
|
|
2286
2284
|
- **Likely noise** — known build/vendored patterns: \`node_modules/\`, \`dist/\`, \`build/\`, \`vendor/\`, \`third_party/\`, \`.changeset/\`, \`coverage/\`.
|
|
2287
2285
|
4. Detect total \`.md\` count across content root.
|
|
2288
2286
|
5. Detect seeded layout: do any of \`external-sources/\`, \`research/\`, \`articles/\` exist? (Karpathy three-layer partial presence — informational only.)
|
|
2289
|
-
6. **Confirm-then-extend detection.** For each substantial folder, check the \`
|
|
2287
|
+
6. **Confirm-then-extend detection.** For each substantial folder, check the \`exec("ls <folder>")\` listing:
|
|
2290
2288
|
- If \`frontmatter_defaults\` is non-empty → folder frontmatter already exists; switch THAT folder to "extend mode" (propose additions, not replacement).
|
|
2291
2289
|
- If \`templates_available\` is non-empty → template already exists for that folder; skip template extraction for it.
|
|
2292
2290
|
- If MOST substantial folders are already configured → set up to exit early at Phase 7 with "already configured."
|
|
2293
2291
|
|
|
2294
2292
|
**Early-exit conditions:**
|
|
2295
|
-
- **Step 0 server-down** → STOP, see above.
|
|
2296
2293
|
- If total \`.md\` count is **< 5** → STOP. Tell the user "this looks empty — try \`ok seed\` for the greenfield Karpathy three-layer, OR write your first doc and re-invoke \`discover\` later." Exit.
|
|
2297
2294
|
- If all-greenfield-already (per step 6) → STOP. Exit with "already configured."
|
|
2298
2295
|
|
|
@@ -2357,15 +2354,14 @@ On confirm: read existing \`.okignore\`, append new entries, write via native \`
|
|
|
2357
2354
|
|
|
2358
2355
|
For **each** folder the user marked \`[KB]\`:
|
|
2359
2356
|
|
|
2360
|
-
1. **Pick representative siblings.** From \`
|
|
2357
|
+
1. **Pick representative siblings.** From \`exec("ls <folder>")\`:
|
|
2361
2358
|
- Most-recently-edited doc
|
|
2362
2359
|
- Median-sized doc (roughly: pick the middle entry)
|
|
2363
|
-
- Most-linked doc (via \`get_backlinks\`)
|
|
2364
2360
|
- Up to 3 siblings. If folder has < 2 siblings, skip template extraction; only propose folder frontmatter.
|
|
2365
2361
|
|
|
2366
|
-
2. **Read the siblings.** \`
|
|
2362
|
+
2. **Read the siblings.** \`exec("cat <doc>")\` on each. Extract:
|
|
2367
2363
|
- **Heading set** — list every top-level heading (line starting with \`# \` or \`## \`) in document order.
|
|
2368
|
-
- **Frontmatter shape** — which keys appear in ≥ 2 of the 3 siblings. **Capture ANY recurring key** — not just \`title\` / \`description\` / \`tags\`. If specs commonly carry \`status:\`, \`owner(s):\`, \`baseline-commit:\`, those should land in the proposed folder frontmatter.
|
|
2364
|
+
- **Frontmatter shape** — which keys appear in ≥ 2 of the 3 siblings. **Capture ANY recurring key** — not just \`title\` / \`description\` / \`tags\`. If specs commonly carry \`status:\`, \`owner(s):\`, \`baseline-commit:\`, those should land in the proposed folder frontmatter. \`folder_config\` accepts an open frontmatter shape (any YAML-representable key persists).
|
|
2369
2365
|
- **Filename pattern** — dated (\`YYYY-MM-DD-*\`)? Slugged? Sequential?
|
|
2370
2366
|
- **Link patterns in body** — does the body have a "Related" / "See also" / "References" section? Note the convention.
|
|
2371
2367
|
|
|
@@ -2375,60 +2371,61 @@ For **each** folder the user marked \`[KB]\`:
|
|
|
2375
2371
|
- If \`frontmatter_defaults\` is non-empty for this folder → switch to "extend mode." Show existing keys to user; propose ADDITIONS only.
|
|
2376
2372
|
- If \`templates_available\` includes a template → skip template extraction. Tell user: "existing template \`<name>\` found; preserving."
|
|
2377
2373
|
|
|
2378
|
-
5. **Propose folder frontmatter + template.**
|
|
2374
|
+
5. **Propose folder frontmatter + template.** Both are \`folder_config\` writes — one call per action:
|
|
2379
2375
|
|
|
2380
2376
|
\`\`\`ts
|
|
2381
|
-
|
|
2377
|
+
folder_config({
|
|
2378
|
+
action: 'set-rule',
|
|
2382
2379
|
rules: [{
|
|
2383
2380
|
match: '<folder>/**',
|
|
2384
2381
|
frontmatter: {
|
|
2385
2382
|
title: '<inferred>', // e.g., "Specifications"
|
|
2386
2383
|
description: '<inferred>', // 1-2 sentences describing the folder's purpose
|
|
2387
2384
|
tags: ['<inferred>'], // e.g., ['spec']
|
|
2388
|
-
}
|
|
2389
|
-
}]
|
|
2385
|
+
},
|
|
2386
|
+
}],
|
|
2390
2387
|
})
|
|
2391
2388
|
|
|
2392
|
-
|
|
2389
|
+
folder_config({
|
|
2390
|
+
action: 'write-template',
|
|
2393
2391
|
folder: '<folder>',
|
|
2394
|
-
name: '<inferred-name>',
|
|
2395
|
-
frontmatter: {
|
|
2396
|
-
|
|
2397
|
-
description: '<placeholder>',
|
|
2398
|
-
},
|
|
2399
|
-
body: '<heading skeleton from siblings, with placeholder content under each heading>'
|
|
2392
|
+
name: '<inferred-name>', // e.g., 'SPEC' for specs/, 'REPORT' for reports/
|
|
2393
|
+
frontmatter: { title: '<placeholder>', description: '<placeholder>' },
|
|
2394
|
+
body: '<heading skeleton from siblings, with placeholder content under each heading>',
|
|
2400
2395
|
})
|
|
2401
2396
|
\`\`\`
|
|
2402
2397
|
|
|
2403
2398
|
6. **⛔ STOP gate 4 — Surface proposal to user.** Show: heading set + frontmatter shape + filename pattern + link patterns. Ask: "Apply this proposal? (yes / edit / skip this folder)"
|
|
2404
2399
|
|
|
2405
|
-
7. **Apply confirmed proposals** via
|
|
2400
|
+
7. **Apply confirmed proposals** via the two \`folder_config\` calls above. Re-run \`exec("ls <folder>")\` to confirm \`templates_available\` + \`frontmatter_defaults\` are populated.
|
|
2406
2401
|
|
|
2407
2402
|
Repeat for every \`[KB]\` folder.
|
|
2408
2403
|
|
|
2409
|
-
**v1 scope note:** \`discover\` does NOT attempt nested-pattern detection (e.g., applying the same rule across \`specs/*/evidence/\` for every spec's evidence/ subfolder).
|
|
2404
|
+
**v1 scope note:** \`discover\` does NOT attempt nested-pattern detection (e.g., applying the same rule across \`specs/*/evidence/\` for every spec's evidence/ subfolder). \`folder_config\` rejects multi-folder globs with \`MULTI_FOLDER_GLOB\`. Users who want nested folder frontmatter set it up manually after \`discover\` finishes the top-level work.
|
|
2410
2405
|
|
|
2411
2406
|
---
|
|
2412
2407
|
|
|
2413
2408
|
## Phase 5 — Link-graph activation
|
|
2414
2409
|
|
|
2415
|
-
The largest phase. Uses every link-graph
|
|
2410
|
+
The largest phase. Uses the \`links\` tool (every link-graph view) plus \`search\` and \`edit_document\` to apply confirmed link insertions.
|
|
2411
|
+
|
|
2412
|
+
0. **Server check (required for this phase).** \`links\` and \`search\` need the OK Hocuspocus server. Probe via \`links({ kind: "hubs" })\`. If the response starts with \`"Error: Hocuspocus server is not running"\`, STOP — tell the user "the link-graph phase of discover needs the OK server. Start it with \`ok start\` from a terminal, then re-invoke \`discover\` (Phases 1-4 are already applied; it resumes here)." Exit cleanly.
|
|
2416
2413
|
|
|
2417
2414
|
Six sub-passes, each with its own STOP gate.
|
|
2418
2415
|
|
|
2419
2416
|
### 5a. Orphan triage (⛔ STOP gate 5a)
|
|
2420
2417
|
|
|
2421
|
-
1. Run \`
|
|
2422
|
-
2. For each orphan,
|
|
2418
|
+
1. Run \`links({ kind: "orphans" })\`.
|
|
2419
|
+
2. For each orphan, run \`links({ kind: "suggest", docName: <orphan> })\`:
|
|
2423
2420
|
- If \`mentions[]\` is non-empty → there are docs that mention this orphan without linking. Adoption candidates.
|
|
2424
2421
|
- If \`mentions[]\` is empty → the orphan is **genuinely standalone** (no other doc references it at all). Surface as: "this looks intentionally standalone (e.g., a README). Skip / adopt anyway by linking from a hub / add to \`.okignore\`?"
|
|
2425
|
-
3. Confirm per orphan. For each "link" choice, \`edit_document\` on the source doc at the offset \`
|
|
2422
|
+
3. Confirm per orphan. For each "link" choice, \`edit_document\` on the source doc at the offset \`links({ kind: "suggest" })\` returned to wrap the existing mention in link syntax.
|
|
2426
2423
|
|
|
2427
2424
|
**Note on re-surfacing:** v1 does NOT persist "intentional standalone" markers. Each \`discover\` re-run surfaces the same intentional orphans (root \`README.md\`, \`CONTRIBUTING.md\`, etc.) and the user re-dismisses them. Acceptable minor friction.
|
|
2428
2425
|
|
|
2429
2426
|
### 5b. Hub identification (⛔ STOP gate 5b)
|
|
2430
2427
|
|
|
2431
|
-
1. Run \`
|
|
2428
|
+
1. Run \`links({ kind: "hubs" })\` — surfaces existing high-fan-out docs.
|
|
2432
2429
|
2. For each substantial \`[KB]\` folder (those that got templates in Phase 4):
|
|
2433
2430
|
- Check if a hub already exists (\`<folder>/README.md\`, \`<folder>/INDEX.md\`, \`<folder>/CATALOGUE.md\`).
|
|
2434
2431
|
- If yes: don't create a new one (anti-pattern: don't create INDEX.md hubs).
|
|
@@ -2437,15 +2434,15 @@ Six sub-passes, each with its own STOP gate.
|
|
|
2437
2434
|
|
|
2438
2435
|
### 5c. Dead-link sweep (⛔ STOP gate 5c)
|
|
2439
2436
|
|
|
2440
|
-
1. Run \`
|
|
2437
|
+
1. Run \`links({ kind: "dead" })\` (no \`sourceDocNames\` → audits the whole corpus).
|
|
2441
2438
|
2. For each dead link, propose: fix candidate (via \`search\` for the correct target), mark as redlink (intentional forward-reference), or delete.
|
|
2442
2439
|
3. Confirm per dead-link. Apply confirmed fixes via \`edit_document\`.
|
|
2443
2440
|
|
|
2444
2441
|
### 5d. Untextualized-reference detection (⛔ STOP gate 5d)
|
|
2445
2442
|
|
|
2446
|
-
\`
|
|
2443
|
+
\`links({ kind: "suggest" })\` implements server-side detection of prose mentions of a target doc that aren't wrapped in link syntax. v1 leverages it directly.
|
|
2447
2444
|
|
|
2448
|
-
1. For each substantial \`[KB]\` doc,
|
|
2445
|
+
1. For each substantial \`[KB]\` doc, run \`links({ kind: "suggest", docName: <target> })\`.
|
|
2449
2446
|
2. Each call returns \`mentions[]\` with \`{ source, excerpt, offset }\` — places to insert links pointing TO this target from OTHER docs.
|
|
2450
2447
|
3. Surface batched **by source doc** (not per-link, to keep cognitive load reasonable):
|
|
2451
2448
|
|
|
@@ -2456,18 +2453,18 @@ Six sub-passes, each with its own STOP gate.
|
|
|
2456
2453
|
line 203: "...per AGENTS.md ecosystem convention" → matches root AGENTS.md — accept as link
|
|
2457
2454
|
\`\`\`
|
|
2458
2455
|
|
|
2459
|
-
4. Confirm per source doc (batched). Apply confirmed link insertions via \`edit_document\` using the offsets \`
|
|
2456
|
+
4. Confirm per source doc (batched). Apply confirmed link insertions via \`edit_document\` using the offsets the \`suggest\` view returned.
|
|
2460
2457
|
|
|
2461
|
-
**Truncation handling:** if \`
|
|
2458
|
+
**Truncation handling:** if the \`suggest\` view returns \`truncated: true\`, the scan hit its time budget. Iterate with smaller scope or accept partial coverage and tell the user.
|
|
2462
2459
|
|
|
2463
2460
|
### 5e. Vague-referential detection (⛔ STOP gate 5e)
|
|
2464
2461
|
|
|
2465
|
-
Harder case: prose discusses a concept covered by another doc without naming it. Example: a spec talks about "how we track who wrote what" and there's an \`agent-identity-attribution-worldmodel/REPORT.md\` covering exactly that — but the spec never says "agent identity attribution." \`
|
|
2462
|
+
Harder case: prose discusses a concept covered by another doc without naming it. Example: a spec talks about "how we track who wrote what" and there's an \`agent-identity-attribution-worldmodel/REPORT.md\` covering exactly that — but the spec never says "agent identity attribution." \`links({ kind: "suggest" })\` (title/alias match) misses this; semantic detection requires LLM judgment.
|
|
2466
2463
|
|
|
2467
2464
|
1. For each substantial doc, identify its main concepts. Use frontmatter \`subjects:\` / \`topics:\` if present; else extract from heading text + first 2-3 paragraphs (LLM judgment).
|
|
2468
2465
|
2. For each concept, run \`search({ query: <concept> })\`. Take top 1-2 non-self results.
|
|
2469
2466
|
3. For each candidate sibling:
|
|
2470
|
-
- Verify it is NOT already linked from this doc (\`
|
|
2467
|
+
- Verify it is NOT already linked from this doc (\`links({ kind: "forward", docName: <doc> })\`).
|
|
2471
2468
|
- Verify content is actually relevant (re-read summary; LLM judgment).
|
|
2472
2469
|
4. Surface to user with brief justification per pair. Confirm. Apply via \`edit_document\` (insert link in a "Related" or "References" section).
|
|
2473
2470
|
|
|
@@ -2479,7 +2476,7 @@ Harder case: prose discusses a concept covered by another doc without naming it.
|
|
|
2479
2476
|
- Wiki-link syntax: \`[[Page Title]]\` (legacy)
|
|
2480
2477
|
- Relative-markdown: \`[text](./path.md)\` or \`[text](path.md)\` (current OK recommended)
|
|
2481
2478
|
2. Report ratio to user. If mixed, propose a one-time standardization: convert all \`[[Page]]\` to \`[Page](./path.md)\`. Ambiguous \`[[Page]]\` (multiple matching files) → surface for confirmation.
|
|
2482
|
-
3. Apply via \`edit_document\` on each affected doc, resolving page titles to file paths via \`
|
|
2479
|
+
3. Apply via \`edit_document\` on each affected doc, resolving page titles to file paths via \`exec("ls")\` / \`search\`.
|
|
2483
2480
|
|
|
2484
2481
|
---
|
|
2485
2482
|
|
|
@@ -2487,11 +2484,10 @@ Harder case: prose discusses a concept covered by another doc without naming it.
|
|
|
2487
2484
|
|
|
2488
2485
|
After all confirmed proposals are applied:
|
|
2489
2486
|
|
|
2490
|
-
1. Re-run \`
|
|
2487
|
+
1. Re-run \`exec("ls <folder>")\` on every \`[KB]\` folder. Verify:
|
|
2491
2488
|
- \`frontmatter_defaults\` is populated (folder frontmatter landed)
|
|
2492
2489
|
- \`templates_available\` includes the new template (template landed)
|
|
2493
|
-
2. Re-run
|
|
2494
|
-
3. Re-run \`get_dead_links\` — confirm fixed dead links no longer reported.
|
|
2490
|
+
2. Re-run the orphan + dead-link audit in one call — \`links({ kind: ["orphans", "dead"] })\`. Confirm orphan count dropped vs. Phase 5a baseline and fixed dead links no longer report.
|
|
2495
2491
|
|
|
2496
2492
|
If any validation step fails, surface to the user — do NOT silently pass.
|
|
2497
2493
|
|
|
@@ -2522,7 +2518,7 @@ Link-graph activation:
|
|
|
2522
2518
|
Orphan triage: 7 orphans triaged (4 adopted, 3 left as intentional standalones)
|
|
2523
2519
|
Hub identification: 3 existing hubs surfaced; 2 templates updated with \`## Related\` sections
|
|
2524
2520
|
Dead-link sweep: 5 dead links — 4 fixed, 1 left as intentional redlink
|
|
2525
|
-
Untextualized refs: 12 prose mentions linked (across 8 source docs
|
|
2521
|
+
Untextualized refs: 12 prose mentions linked (across 8 source docs)
|
|
2526
2522
|
Vague-referential: 5 semantic cross-references added (across 4 source docs)
|
|
2527
2523
|
Link-style: standardized 42 wiki-links to relative-markdown
|
|
2528
2524
|
|
|
@@ -2573,37 +2569,32 @@ Link-graph activation:
|
|
|
2573
2569
|
|
|
2574
2570
|
- **Empty project** (Phase 1): < 5 \`.md\` files total → exit with "try \`ok seed\` instead."
|
|
2575
2571
|
- **All-greenfield-already** (Phase 1 step 6): folder frontmatter exists AND templates exist for every substantial folder → exit with "this project is already configured."
|
|
2576
|
-
- **Server down** (Phase
|
|
2572
|
+
- **Server down** (Phase 5 step 0): Phases 1-4 already applied fs-direct; surface "the link-graph phase needs \`ok start\` running" and exit cleanly — re-invoking resumes at Phase 5.
|
|
2577
2573
|
- **User aborts at any STOP gate** → exit cleanly, leaving any already-applied proposals in place (apply is per-phase, not all-or-nothing).
|
|
2578
2574
|
- **Validation failure** (Phase 6) → don't pretend to succeed; surface the failed step to the user.
|
|
2579
|
-
`}const DESCRIPTION$
|
|
2580
|
-
`),InputSchema$
|
|
2581
|
-
`)}\n${renderInventoryFooter()}`;function register$
|
|
2582
|
-
`);if(!F&&!B&&!H&&!q)return textResult(ee);let te={};return F&&(te.previewUrl=F.url,te.previewUrlSource=F.source),B&&(te.warning=buildPreviewAttachWarning(F)),q&&(te.summary=q),textPlusStructured(ee,te)})}const
|
|
2575
|
+
`}const DESCRIPTION$14=[`Returns a step-by-step plan for setting up an existing repo: extract folder conventions, write folder frontmatter + templates, activate the link graph. Does NOT execute the plan — you run it, with per-phase user confirmation.`,``,"Invoke on first arrival at a repo that has markdown content but no folder frontmatter / templates (an `exec` listing shows empty `frontmatter_defaults` + `templates_available`). Skip empty repos (use `ok seed`) and already-configured ones. One-shot per project; idempotent on re-run (extends, never re-proposes).",``,"Phases 1-4 run fs-direct; Phase 5 (link-graph activation) needs `ok start`. Composes existing tools only — `exec`, `links`, `search`, `folder_config`, `edit_document`."].join(`
|
|
2576
|
+
`),InputSchema$3={cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)},OutputSchema$3=outputSchemaWithText({previewUrl:_null()});function register$14(e,t){e.registerTool(`discover`,{description:DESCRIPTION$14,inputSchema:InputSchema$3,outputSchema:OutputSchema$3,annotations:{readOnlyHint:!1,idempotentHint:!0,destructiveHint:!1}},async e=>{let S=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);return S.ok?textPlusStructured(buildDiscoverBody(S.config.content.dir),{previewUrl:null}):textResult(`Error: ${S.error}`,!0)})}const DESCRIPTION$13=`${["[Requires: Hocuspocus server] Find-and-replace on a live document via the CRDT layer. The patch propagates to all connected editors in real-time. Use `offset` to target an exact occurrence; omit for first-match.",``,'**Body-only.** Frontmatter-intersecting find/replace is rejected with HTTP 400. For frontmatter: 1-2 keys → `edit_frontmatter`; full rewrite → `write_document({ position: "replace" })`.',``,`**Parameters:**`,"- `docName` — Document name, extension-less. Trailing `.md`/`.mdx` stripped.","- `find` — Text to find (exact match).","- `replace` — Replacement text.",'- `offset` — Optional JavaScript string offset of the exact occurrence to patch. Stale offsets return an error; re-fetch via `links({ kind: "suggest", docName })`.',"- `summary` — Optional one-line user-outcome (≤80 chars). Avoid secrets or PII — persisted to git history."].join(`
|
|
2577
|
+
`)}\n${renderInventoryFooter()}`;function register$13(e,t){e.registerTool(`edit_document`,{description:DESCRIPTION$13,inputSchema:{docName:string$2().describe(`Document name to edit`),find:string$2().describe(`Text to find (exact match)`),replace:string$2().describe(`Replacement text`),offset:number$1().int().min(0).optional().describe(`Exact occurrence to patch, as a JavaScript string offset in the current markdown`),summary:summaryArgSchema,cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=normalizeDocName(e.docName);if(!D.ok)return textResult(D.error,!0);let O=t.identityRef?.current,k=await httpPost(E,`/api/agent-patch`,{docName:D.docName,find:e.find,replace:e.replace,offset:e.offset,...e.summary===void 0?{}:{summary:e.summary},...O?{agentId:O.connectionId,agentName:O.displayName,clientName:O.clientInfo?.name,colorSeed:O.colorSeed}:{}});if(!k.ok)return textResult(`Error: ${k.error}`,!0);let j=resolveLockDir(w),F=resolvePreviewUrl(D.docName,{lockDir:j}),L=typeof k.subscriberCount==`number`?k.subscriberCount:void 0,B=(typeof k.systemSubscriberCount==`number`?k.systemSubscriberCount:void 0)===0,H=L===0,q=k.summary&&typeof k.summary==`object`?k.summary:void 0,J=typeof q?.hint==`string`?q.hint:void 0,Y=[`Edit applied successfully.`];F&&Y.push(`Preview: ${F.url}`),B&&Y.push(F?`Open ${F.url} in your preview browser.`:START_UI_TEXT_HINT),J&&Y.push(J);let ee=Y.join(`
|
|
2578
|
+
`);if(!F&&!B&&!H&&!q)return textResult(ee);let te={};return F&&(te.previewUrl=F.url,te.previewUrlSource=F.source),B&&(te.warning=buildPreviewAttachWarning(F)),q&&(te.summary=q),textPlusStructured(ee,te)})}const DESCRIPTION$12=[`[Requires: Hocuspocus server] Set, create, or delete frontmatter properties via JSON Merge Patch (RFC 7396).`,``,`Field-level CRDT merge: concurrent patches to different keys (human form + this tool, or two agents) merge cleanly. Same-key concurrent writes resolve last-writer-wins per key.`,``,'**Use this tool — not `edit_document` — for any frontmatter change.** `edit_document` (agent-patch) targets body content; FM-intersecting `edit_document` calls return HTTP 400. For full-document rewrites (≥3-5 frontmatter keys changing), `write_document({ position: "replace" })` remains the canonical pathway.',``,`**Parameters:**`,"- `docName` — Document name. A trailing `.md` or `.mdx` is stripped automatically.","- `patch` — Object whose keys are property names. Each value is the new value (string, number, boolean, or array of strings) to **set or create** the key, or `null` to **delete** the key. Keys not present in `patch` are unchanged.","- `types` (optional) — **Currently ignored.** Shape-validated for forward-compat but not persisted server-side; type is inferred from value shape on read. Reserved for a future per-key widget-type override (`text | number | boolean | date | list`) once persistence ships.",'- `summary` — Optional one-line user-outcome description (≤80 chars). Prefer outcome phrasing ("Marked spec as approved") over structural ("Set status field"). Avoid secrets / PII — summaries persist to git history.',``,`**Atomicity:** any value failing schema validation rejects the WHOLE patch (HTTP 400 with per-key error report). Either every change commits or none do.`].join(`
|
|
2579
|
+
`),PatchValueSchema=union([FrontmatterValueSchema,_null()]).describe("Property value (string|number|boolean|string[]) — `null` deletes the key");function register$12(e,t){e.registerTool(`edit_frontmatter`,{description:DESCRIPTION$12,inputSchema:{docName:string$2().describe(`Document name`),patch:record(string$2(),PatchValueSchema).describe("JSON Merge Patch — `{key: value}` sets, `{key: null}` deletes"),types:record(string$2(),_enum(FRONTMATTER_TYPES)).optional().describe(`Currently ignored (shape-validated for forward-compat but not persisted). Type is inferred from value shape on read. Will become a real per-key widget-type override (text|number|boolean|date|list) once persistence lands.`),summary:summaryArgSchema,cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=normalizeDocName(e.docName);if(!D.ok)return textResult(D.error,!0);let O=t.identityRef?.current,k=await httpPost(E,`/api/frontmatter-patch`,{docName:D.docName,patch:e.patch,...e.types?{types:e.types}:{},...e.summary===void 0?{}:{summary:e.summary},...O?{agentId:O.connectionId,agentName:O.displayName,clientName:O.clientInfo?.name,colorSeed:O.colorSeed}:{}});if(!k.ok){let e=k.error,t=k.fieldErrors&&typeof k.fieldErrors==`object`?k.fieldErrors:void 0;return textResult(t?`Error: ${e}\n${Object.entries(t).map(([e,t])=>` ${e}: ${t}`).join(`
|
|
2580
|
+
`)}`:`Error: ${e}`,!0)}let j=resolveLockDir(w),F=resolvePreviewUrl(D.docName,{lockDir:j}),L=typeof k.subscriberCount==`number`?k.subscriberCount:void 0,B=(typeof k.systemSubscriberCount==`number`?k.systemSubscriberCount:void 0)===0,H=L===0,q=k.summary&&typeof k.summary==`object`?k.summary:void 0,J=typeof q?.hint==`string`?q.hint:void 0,Y=[],ee=[];for(let[t,S]of Object.entries(e.patch))S===null?ee.push(t):Y.push(t);let te=[`Frontmatter patched (${[Y.length?`${Y.length} set`:``,ee.length?`${ee.length} deleted`:``].filter(Boolean).join(`, `)||`${Object.keys(e.patch).length} key(s)`}).`];F&&te.push(`Preview: ${F.url}`),B&&te.push(F?`Open ${F.url} in your preview browser.`:START_UI_TEXT_HINT),J&&te.push(J);let ne=te.join(`
|
|
2581
|
+
`);if(!F&&!B&&!H&&!q)return textResult(ne);let ae={};return F&&(ae.previewUrl=F.url,ae.previewUrlSource=F.source),B&&(ae.warning=buildPreviewAttachWarning(F)),q&&(ae.summary=q),textPlusStructured(ne,ae)})}const PRODUCER_COMMANDS=new Set([`cat`,`ls`,`grep`,`find`]),PATH_FALLBACK_RE=/\b[\w./-]+\.(md|mdx)\b/g;function isWikiPath(e){return/\.(md|mdx)$/.test(e)}function normalize$1(e){let t=e.trim();return t?(t=t.replace(/\/+/g,`/`),t.startsWith(`./`)&&(t=t.slice(2)),t.endsWith(`/`)&&(t=t.slice(0,-1)),t):``}function argsOf(e){return e.args.slice(1)}function nonFlagArgs(e){return e.filter(e=>!e.startsWith(`-`))}function extractFromCat(e){return nonFlagArgs(argsOf(e)).filter(isWikiPath)}function extractFromLs(e,t){let S=nonFlagArgs(argsOf(t)),w=S.length>0?S[S.length-1]:``,E=w&&w!==`.`?normalize$1(w):``,D=[];E&&D.push(E);for(let t of e.split(`
|
|
2583
2582
|
`)){let e=t.trim();if(!e||/\.[a-z0-9]+$/i.test(e)&&!isWikiPath(e))continue;let S=E?`${E}/${e}`:e;D.push(S)}return D}function extractFromGrep(e){let t=[];for(let S of e.split(`
|
|
2584
2583
|
`)){if(!S)continue;let e=S.indexOf(`:`);if(e<0)continue;let w=normalize$1(S.slice(0,e));isWikiPath(w)&&t.push(w)}return t}function extractFromFind(e){let t=[];for(let S of e.split(`
|
|
2585
|
-
`)){let e=normalize$1(S);e&&isWikiPath(e)&&t.push(e)}return t}function extractFromHeadTail(e){return nonFlagArgs(argsOf(e)).filter(isWikiPath)}function headTailActsAsProducer(e){return nonFlagArgs(argsOf(e)).length>0}function fallback(e){let t=[],S=e.matchAll(PATH_FALLBACK_RE);for(let e of S)t.push(normalize$1(e[0]));return t}function extractReferencedPaths(e,t){let S=null;for(let e=t.length-1;e>=0;e--){let w=t[e];if(PRODUCER_COMMANDS.has(w.command)){S=w;break}if((w.command===`head`||w.command===`tail`)&&headTailActsAsProducer(w)){S=w;break}}let w;if(!S)w=fallback(e);else{switch(S.command){case`cat`:w=extractFromCat(S);break;case`ls`:w=extractFromLs(e,S);break;case`grep`:w=extractFromGrep(e);break;case`find`:w=extractFromFind(e);break;case`head`:case`tail`:w=extractFromHeadTail(S);break;default:w=fallback(e)}w.length===0&&(w=fallback(e))}let E=new Set,D=[];for(let e of w){let t=normalize$1(e);!t||E.has(t)||(E.add(t),D.push(t))}return D}function shellEscape(e){return e===``?`''`:/^[\w.\-/]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}const MAX_STDOUT_BYTES=16*1024*1024;var StdoutOverflowError=class extends Error{limitBytes;actualBytes;partial;constructor(e,t,S){super(`Output exceeded ${e} byte buffer (got ${t}); narrow the command`),this.name=`StdoutOverflowError`,this.limitBytes=e,this.actualBytes=t,this.partial=S}};function createBashInstance(e){if(!isAbsolute(e))throw Error(`createBashInstance: cwd must be absolute (got: ${e})`);return new xt({cwd:`/`,fs:new Ss({root:resolve(e),allowSymlinks:!1})})}async function execBash(e,t){let S=await e.exec(t);if(S.stdout.length>MAX_STDOUT_BYTES)throw new StdoutOverflowError(MAX_STDOUT_BYTES,S.stdout.length,{stdout:S.stdout.slice(0,MAX_STDOUT_BYTES),stderr:S.stderr,exitCode:S.exitCode});return{stdout:S.stdout,stderr:S.stderr,exitCode:S.exitCode}}function
|
|
2586
|
-
`)){if(!e)continue;if(j.length>=F)break;let t=e.indexOf(`:`);if(t===-1)continue;let S=e.indexOf(`:`,t+1);if(S===-1)continue;let w=e.slice(0,t),E=e.slice(t+1,S),D=e.slice(S+1),O=Number.parseInt(E,10);Number.isFinite(O)&&j.push({path:w,line:O,text:D})}return j}const SCAN_CAP=1e3,SKIP_DIRS=new Set([`.git`,`.ok`,`node_modules`,`.changeset`,`.claude`,`.agents`,`dist`,`build`]);async function snapshotMtimes(e){let t=resolve(e),S=new Map,w=0,E=!1;async function D(e){if(E)return;let O;try{O=await readdir(e,{withFileTypes:!0})}catch{return}for(let k of O){if(E)return;if(k.isDirectory()&&SKIP_DIRS.has(k.name))continue;let O=resolve(e,k.name);if(k.isDirectory()){await D(O);continue}if(k.isFile()){if(w>=SCAN_CAP){E=!0;return}try{let e=await stat$1(O);S.set(relative(t,O),e.mtimeMs),w++}catch{}}}}return await D(t),{snapshot:S,truncated:E}}function diffMtimes(e,t){let S=[];for(let[w,E]of t){let t=e.get(w);(t===void 0||t!==E)&&S.push(w)}for(let[w]of e)t.has(w)||S.push(w);return{changed:S}}const WIKI_EXCLUDE_DIRS=[`node_modules`,`.git`,`dist`,`build`,`.next`,`.turbo`,`.nuxt`,`coverage`,`.cache`,`.parcel-cache`,`.vercel`,`.ok`,`.claude`];function isRecursiveGrepFlag(e){return e===`--recursive`||e===`--dereference-recursive`?!0:e.startsWith(`--`)||!e.startsWith(`-`)?!1:/[rR]/.test(e.slice(1))}const STRATEGIES=[{command:`grep`,applies:e=>e.slice(1).some(isRecursiveGrepFlag),hasUserExcludes:e=>e.some(e=>e===`--exclude-dir`||e.startsWith(`--exclude-dir=`)),buildExcludeArgs:e=>e.map(e=>`--exclude-dir=${e}`),insertionIndex:()=>1},{command:`find`,applies:()=>!0,hasUserExcludes:e=>e.slice(1).some(e=>e===`-not`||e===`!`||e===`-prune`),buildExcludeArgs:e=>{let t=[];for(let S of e)t.push(`-not`,`-path`,`*/${S}/*`);return t},insertionIndex:e=>{for(let t=1;t<e.length;t++)if(e[t].startsWith(`-`))return t;return e.length}}];function augmentStagesWithExcludes(e){return e.map(e=>{let t=STRATEGIES.find(t=>t.command===e.command);if(!t||!t.applies(e.args)||t.hasUserExcludes(e.args))return e;let S=t.buildExcludeArgs(WIKI_EXCLUDE_DIRS),w=t.insertionIndex(e.args);return{command:e.command,args:[...e.args.slice(0,w),...S,...e.args.slice(w)]}})}function serializeStages(e){return e.map(e=>e.args.map(shellEscape).join(` `)).join(` | `)}const ALLOWLIST=new Set([`cat`,`ls`,`grep`,`find`,`head`,`tail`,`wc`,`sort`,`uniq`,`cut`]),ALLOWLIST_HINT=`cat, ls, grep, find, head, tail, wc, sort, uniq, cut`,WRITE_OPS=new Set([`>`,`>>`,`<`,`>&`,`<&`,`|&`]),SHELL_CONSTRUCT_OPS=new Set([`&`,`;`,`;;`,`&&`,`||`,`(`,`)`,`<(`,`>(`,`<<`,`<<-`]),UNIVERSAL_FLAG_DENY=new Set([`-o`,`--output-file`,`--output`]),UNIVERSAL_FLAG_PREFIX_DENY=[`-o=`,`--output-file=`,`--output=`],FIND_FLAG_DENY=new Set([`-exec`,`-execdir`,`-delete`,`-fprint`,`-fprintf`,`-fprint0`,`-ok`,`-okdir`]),SUSPICIOUS_STRING_RE=/[`]|\$\(|\$\{|\$'/;function isOpToken(e){return typeof e==`object`&&!!e&&`op`in e}function opTokenError(e){let t=typeof e.op==`string`?e.op:`(unknown)`;return WRITE_OPS.has(t)?{category:`write_blocked`,message:`Write operation blocked: '${t}'. exec is read-only. For document changes, use write_document or edit_document.`}:SHELL_CONSTRUCT_OPS.has(t)?{category:`shell_construct_blocked`,message:`Shell construct '${t}' is not supported. Only pipes (|) are allowed between allowlisted stages.`}:{category:`shell_construct_blocked`,message:`Operator '${t}' is not supported.`}}function buildStageArgs(e){let t=[];for(let S of e){if(typeof S==`string`){if(SUSPICIOUS_STRING_RE.test(S))return{error:{category:`shell_construct_blocked`,message:`Argument '${S}' contains a shell-injection pattern (backtick, $(), or \${}); not supported.`}};t.push(S);continue}if(!isOpToken(S))return{error:{category:`shell_construct_blocked`,message:`Unrecognized token shape.`}};if(S.op===`glob`&&typeof S.pattern==`string`){t.push(S.pattern);continue}return typeof S.comment==`string`?{error:{category:`shell_construct_blocked`,message:`Comments are not allowed in exec commands.`}}:{error:opTokenError(S)}}return{args:t}}function checkStage(e){if(!ALLOWLIST.has(e.command))return{category:`unknown_command`,message:`Command '${e.command}' is not in the allowlist. For pattern matching try 'grep'; for file listing try 'ls' or 'find'. Allowlist: ${ALLOWLIST_HINT}.`};for(let t of e.args.slice(1)){if(UNIVERSAL_FLAG_DENY.has(t)||UNIVERSAL_FLAG_PREFIX_DENY.some(e=>t.startsWith(e)))return{category:`write_blocked`,message:`Write operation blocked: '${t}'. exec is read-only. For document changes, use write_document or edit_document.`};if(e.command===`find`&&FIND_FLAG_DENY.has(t))return{category:`write_blocked`,message:`find flag '${t}' is blocked (executes commands or deletes files). Use exec for read-only discovery; chain with another allowlisted tool via '|' if you need to transform output.`}}return null}function parseCommand(e){let t=e.trim();if(!t)return{error:{category:`unknown_command`,message:`Empty command.`}};let S;try{S=import_shell_quote.parse(t)}catch{return{error:{category:`shell_construct_blocked`,message:`Failed to parse command — likely malformed quoting or an unsupported construct.`}}}let w=[],E=[];for(let e of S){if(isOpToken(e)&&e.op===`|`){w.push(E),E=[];continue}E.push(e)}w.push(E);let D=[];for(let e of w){let t=buildStageArgs(e);if(`error`in t)return t;if(t.args.length===0)return{error:{category:`shell_construct_blocked`,message:`Empty pipeline stage (trailing pipe or leading pipe).`}};let S={command:t.args[0],args:t.args},w=checkStage(S);if(w)return{error:w};D.push(S)}return{stages:D}}const SOFT_CAP_LINES=500,SOFT_CAP_BYTES=50*1024,BINARY_EXT_RE=/\.(png|jpe?g|gif|webp|svg|pdf|zip|tar|gz|tgz|mp4|mov|mp3|wav|ico|bmp)$/i,DESCRIPTION$23=["**STOP — native tools on in-scope markdown (when project has `.ok/`).** When the active project contains `.ok/`, do NOT use your host's native `Read`, `Grep`, or `Glob` on `.md` / `.mdx` paths inside OK's content directory — use `exec` (this tool) instead. Native file tools skip frontmatter, backlinks, shadow-repo activity, and project git history that `exec` returns for every matched wiki file. Reserve native `Read`/`Grep`/`Glob` for source code, non-markdown paths, and projects without `.ok/`.",``,`Run a read-only bash-like command against the project content directory. Returns raw stdout plus enriched metadata for every wiki file referenced (frontmatter, backlink/forward-link counts, shadow-repo activity with agent/human attribution).`,``,`Allowlist: cat, ls, grep, find, head, tail, wc, sort, uniq, cut. Pipes (|) work between stages. Redirections, subshells, and writes are rejected.`,``,"cwd: the command runs in the explicit absolute `cwd` you pass, or in the MCP client's only advertised root when there is exactly one. If the client has zero or multiple roots, pass `cwd` explicitly. Paths inside the command resolve relative to that cwd; traversal above it is rejected.",``,"Stdout provenance headers (GNU-style): `ls <dir>/` prepends `<dir>/:`, single-file `cat`/`head`/`tail` prepends `==> <path> <==`, so the subject of the command is visible in raw output. Multi-file `cat a b` emits no header — the `enrichedPaths` array still lists every file. `head`/`tail` used as pipe trimmers (no file arg) defer to the upstream producer.",``,`Examples:`,'- `exec({ command: "cat articles/auth.md" })` — file contents + full enrichment','- `exec({ command: "ls articles/" })` — listing + per-file enrichment (slim)','- `exec({ command: "grep -rn oauth articles/ | head -5" })` — pipe with enrichment on matched files','- `exec({ command: "ls", cwd: "/abs/path/to/other-repo" })` — run in a different project'].join(`
|
|
2584
|
+
`)){let e=normalize$1(S);e&&isWikiPath(e)&&t.push(e)}return t}function extractFromHeadTail(e){return nonFlagArgs(argsOf(e)).filter(isWikiPath)}function headTailActsAsProducer(e){return nonFlagArgs(argsOf(e)).length>0}function fallback(e){let t=[],S=e.matchAll(PATH_FALLBACK_RE);for(let e of S)t.push(normalize$1(e[0]));return t}function extractReferencedPaths(e,t){let S=null;for(let e=t.length-1;e>=0;e--){let w=t[e];if(PRODUCER_COMMANDS.has(w.command)){S=w;break}if((w.command===`head`||w.command===`tail`)&&headTailActsAsProducer(w)){S=w;break}}let w;if(!S)w=fallback(e);else{switch(S.command){case`cat`:w=extractFromCat(S);break;case`ls`:w=extractFromLs(e,S);break;case`grep`:w=extractFromGrep(e);break;case`find`:w=extractFromFind(e);break;case`head`:case`tail`:w=extractFromHeadTail(S);break;default:w=fallback(e)}w.length===0&&(w=fallback(e))}let E=new Set,D=[];for(let e of w){let t=normalize$1(e);!t||E.has(t)||(E.add(t),D.push(t))}return D}function shellEscape(e){return e===``?`''`:/^[\w.\-/]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}const MAX_STDOUT_BYTES=16*1024*1024;var StdoutOverflowError=class extends Error{limitBytes;actualBytes;partial;constructor(e,t,S){super(`Output exceeded ${e} byte buffer (got ${t}); narrow the command`),this.name=`StdoutOverflowError`,this.limitBytes=e,this.actualBytes=t,this.partial=S}};function createBashInstance(e){if(!isAbsolute(e))throw Error(`createBashInstance: cwd must be absolute (got: ${e})`);return new xt({cwd:`/`,fs:new Ss({root:resolve(e),allowSymlinks:!1})})}async function execBash(e,t){let S=await e.exec(t);if(S.stdout.length>MAX_STDOUT_BYTES)throw new StdoutOverflowError(MAX_STDOUT_BYTES,S.stdout.length,{stdout:S.stdout.slice(0,MAX_STDOUT_BYTES),stderr:S.stderr,exitCode:S.exitCode});return{stdout:S.stdout,stderr:S.stderr,exitCode:S.exitCode}}const SCAN_CAP=1e3,SKIP_DIRS=new Set([`.git`,`.ok`,`node_modules`,`.changeset`,`.claude`,`.agents`,`dist`,`build`]);async function snapshotMtimes(e){let t=resolve(e),S=new Map,w=0,E=!1;async function D(e){if(E)return;let O;try{O=await readdir(e,{withFileTypes:!0})}catch{return}for(let k of O){if(E)return;if(k.isDirectory()&&SKIP_DIRS.has(k.name))continue;let O=resolve(e,k.name);if(k.isDirectory()){await D(O);continue}if(k.isFile()){if(w>=SCAN_CAP){E=!0;return}try{let e=await stat$1(O);S.set(relative(t,O),e.mtimeMs),w++}catch{}}}}return await D(t),{snapshot:S,truncated:E}}function diffMtimes(e,t){let S=[];for(let[w,E]of t){let t=e.get(w);(t===void 0||t!==E)&&S.push(w)}for(let[w]of e)t.has(w)||S.push(w);return{changed:S}}const WIKI_EXCLUDE_DIRS=[`node_modules`,`.git`,`dist`,`build`,`.next`,`.turbo`,`.nuxt`,`coverage`,`.cache`,`.parcel-cache`,`.vercel`,`.ok`,`.claude`];function isRecursiveGrepFlag(e){return e===`--recursive`||e===`--dereference-recursive`?!0:e.startsWith(`--`)||!e.startsWith(`-`)?!1:/[rR]/.test(e.slice(1))}const STRATEGIES=[{command:`grep`,applies:e=>e.slice(1).some(isRecursiveGrepFlag),hasUserExcludes:e=>e.some(e=>e===`--exclude-dir`||e.startsWith(`--exclude-dir=`)),buildExcludeArgs:e=>e.map(e=>`--exclude-dir=${e}`),insertionIndex:()=>1},{command:`find`,applies:()=>!0,hasUserExcludes:e=>e.slice(1).some(e=>e===`-not`||e===`!`||e===`-prune`),buildExcludeArgs:e=>{let t=[];for(let S of e)t.push(`-not`,`-path`,`*/${S}/*`);return t},insertionIndex:e=>{for(let t=1;t<e.length;t++)if(e[t].startsWith(`-`))return t;return e.length}}];function augmentStagesWithExcludes(e){return e.map(e=>{let t=STRATEGIES.find(t=>t.command===e.command);if(!t||!t.applies(e.args)||t.hasUserExcludes(e.args))return e;let S=t.buildExcludeArgs(WIKI_EXCLUDE_DIRS),w=t.insertionIndex(e.args);return{command:e.command,args:[...e.args.slice(0,w),...S,...e.args.slice(w)]}})}function serializeStages(e){return e.map(e=>e.args.map(shellEscape).join(` `)).join(` | `)}const ALLOWLIST=new Set([`cat`,`ls`,`grep`,`find`,`head`,`tail`,`wc`,`sort`,`uniq`,`cut`]),ALLOWLIST_HINT=`cat, ls, grep, find, head, tail, wc, sort, uniq, cut`,WRITE_OPS=new Set([`>`,`>>`,`<`,`>&`,`<&`,`|&`]),SHELL_CONSTRUCT_OPS=new Set([`&`,`;`,`;;`,`&&`,`||`,`(`,`)`,`<(`,`>(`,`<<`,`<<-`]),UNIVERSAL_FLAG_DENY=new Set([`-o`,`--output-file`,`--output`]),UNIVERSAL_FLAG_PREFIX_DENY=[`-o=`,`--output-file=`,`--output=`],FIND_FLAG_DENY=new Set([`-exec`,`-execdir`,`-delete`,`-fprint`,`-fprintf`,`-fprint0`,`-ok`,`-okdir`]),SUSPICIOUS_STRING_RE=/[`]|\$\(|\$\{|\$'/;function isOpToken(e){return typeof e==`object`&&!!e&&`op`in e}function opTokenError(e){let t=typeof e.op==`string`?e.op:`(unknown)`;return WRITE_OPS.has(t)?{category:`write_blocked`,message:`Write operation blocked: '${t}'. exec is read-only. For document changes, use write_document or edit_document.`}:SHELL_CONSTRUCT_OPS.has(t)?{category:`shell_construct_blocked`,message:`Shell construct '${t}' is not supported. Only pipes (|) are allowed between allowlisted stages.`}:{category:`shell_construct_blocked`,message:`Operator '${t}' is not supported.`}}function buildStageArgs(e){let t=[];for(let S of e){if(typeof S==`string`){if(SUSPICIOUS_STRING_RE.test(S))return{error:{category:`shell_construct_blocked`,message:`Argument '${S}' contains a shell-injection pattern (backtick, $(), or \${}); not supported.`}};t.push(S);continue}if(!isOpToken(S))return{error:{category:`shell_construct_blocked`,message:`Unrecognized token shape.`}};if(S.op===`glob`&&typeof S.pattern==`string`){t.push(S.pattern);continue}return typeof S.comment==`string`?{error:{category:`shell_construct_blocked`,message:`Comments are not allowed in exec commands.`}}:{error:opTokenError(S)}}return{args:t}}function checkStage(e){if(!ALLOWLIST.has(e.command))return{category:`unknown_command`,message:`Command '${e.command}' is not in the allowlist. For pattern matching try 'grep'; for file listing try 'ls' or 'find'. Allowlist: ${ALLOWLIST_HINT}.`};for(let t of e.args.slice(1)){if(UNIVERSAL_FLAG_DENY.has(t)||UNIVERSAL_FLAG_PREFIX_DENY.some(e=>t.startsWith(e)))return{category:`write_blocked`,message:`Write operation blocked: '${t}'. exec is read-only. For document changes, use write_document or edit_document.`};if(e.command===`find`&&FIND_FLAG_DENY.has(t))return{category:`write_blocked`,message:`find flag '${t}' is blocked (executes commands or deletes files). Use exec for read-only discovery; chain with another allowlisted tool via '|' if you need to transform output.`}}return null}function parseCommand(e){let t=e.trim();if(!t)return{error:{category:`unknown_command`,message:`Empty command.`}};let S;try{S=import_shell_quote.parse(t)}catch{return{error:{category:`shell_construct_blocked`,message:`Failed to parse command — likely malformed quoting or an unsupported construct.`}}}let w=[],E=[];for(let e of S){if(isOpToken(e)&&e.op===`|`){w.push(E),E=[];continue}E.push(e)}w.push(E);let D=[];for(let e of w){let t=buildStageArgs(e);if(`error`in t)return t;if(t.args.length===0)return{error:{category:`shell_construct_blocked`,message:`Empty pipeline stage (trailing pipe or leading pipe).`}};let S={command:t.args[0],args:t.args},w=checkStage(S);if(w)return{error:w};D.push(S)}return{stages:D}}const SOFT_CAP_LINES=500,SOFT_CAP_BYTES=50*1024,BINARY_EXT_RE=/\.(png|jpe?g|gif|webp|svg|pdf|zip|tar|gz|tgz|mp4|mov|mp3|wav|ico|bmp)$/i,DESCRIPTION$11=["**STOP — native tools on in-scope markdown (when project has `.ok/`).** When the active project contains `.ok/`, do NOT use your host's native `Read`, `Grep`, or `Glob` on `.md` / `.mdx` paths inside OK's content directory — use `exec` (this tool) instead. Native file tools skip frontmatter, backlinks, shadow-repo activity, and project git history that `exec` returns for every matched wiki file. Reserve native `Read`/`Grep`/`Glob` for source code, non-markdown paths, and projects without `.ok/`.",``,`Run a read-only bash-like command against the project content directory. Returns raw stdout plus enriched metadata for every wiki file referenced (frontmatter, backlink/forward-link counts, shadow-repo activity with agent/human attribution).`,``,`Allowlist: cat, ls, grep, find, head, tail, wc, sort, uniq, cut. Pipes (|) work between stages. Redirections, subshells, and writes are rejected.`,``,"cwd: the command runs in the explicit absolute `cwd` you pass, or in the MCP client's only advertised root when there is exactly one. If the client has zero or multiple roots, pass `cwd` explicitly. Paths inside the command resolve relative to that cwd; traversal above it is rejected.",``,"Stdout provenance headers (GNU-style): `ls <dir>/` prepends `<dir>/:`, single-file `cat`/`head`/`tail` prepends `==> <path> <==`, so the subject of the command is visible in raw output. Multi-file `cat a b` emits no header — the `enrichedPaths` array still lists every file. `head`/`tail` used as pipe trimmers (no file arg) defer to the upstream producer.",``,`Examples:`,'- `exec({ command: "cat articles/auth.md" })` — file contents + full enrichment','- `exec({ command: "ls articles/" })` — listing + per-file enrichment (slim)','- `exec({ command: "grep -rn oauth articles/ | head -5" })` — pipe with enrichment on matched files','- `exec({ command: "ls", cwd: "/abs/path/to/other-repo" })` — run in a different project'].join(`
|
|
2587
2585
|
`);function applySoftCap(e){let t=e.split(`
|
|
2588
2586
|
`),S=t[t.length-1]===``?t.length-1:t.length;if(S<=SOFT_CAP_LINES&&e.length<=SOFT_CAP_BYTES)return{text:e,truncated:!1,omittedLines:0};let w=Math.min(S,SOFT_CAP_LINES),E=0,D=0;for(let e=0;e<w;e++){let S=t[e];if(E+=S.length+1,E>SOFT_CAP_BYTES)break;D++}let O=t.slice(0,D).join(`
|
|
2589
2587
|
`),k=S-D;return{text:`${O}\n<truncated: ${k} more lines — re-run with a more-specific query>`,truncated:!0,omittedLines:k}}function detectBinaryArgs(e){let t=[];for(let S of e)if(S.command===`cat`)for(let e of S.args.slice(1))e.startsWith(`-`)||BINARY_EXT_RE.test(e)&&t.push(e);return t}function extractHeadTailLimit(e){for(let t=1;t<e.length;t++){let S=e[t],w=S.match(/^--lines=(\d+)$/);if(w)return Number(w[1]);if(S===`--lines`&&t+1<e.length){let S=Number(e[t+1]);if(Number.isFinite(S))return S}if(S===`-n`&&t+1<e.length){let S=Number(e[t+1]);if(Number.isFinite(S))return S}let E=S.match(/^-n(\d+)$/);if(E)return Number(E[1]);let D=S.match(/^-(\d+)$/);if(D)return Number(D[1])}return 10}function detectHeadTailTruncation(e,t){if(e.length<2)return null;let S=e[e.length-1];if(S.command!==`head`&&S.command!==`tail`)return null;let w=extractHeadTailLimit(S.args),E=t.split(`
|
|
2590
2588
|
`),D=E[E.length-1]===``?E.length-1:E.length;if(D<w)return null;let O=E.slice(0,D),k=new Set(O.map(e=>{let t=e.indexOf(`:`);return t>0?e.slice(0,t):e})).size,j=e.slice(0,-1).map(e=>e.command).join(` | `);return{banner:`Output hit \`${S.command} -${w}\` cap (${D} lines, ${k} unique file${k===1?``:`s`}). The \`${j}\` stage may have had more matches that never reached stdout. For existence checks across many files, prefer \`grep -rl PATTERN <dir>\` (list files only, no head). For enumeration, drop the \`| ${S.command}\` or widen the cap.`}}function isDirectoryMeta(e){return e.type===`directory`}function formatDirectoryEntry(e){let t=[e.title?`**${e.title}** (${e.path}/)`:`**${e.path}/** (directory)`];e.description&&t.push(e.description),e.tags&&e.tags.length>0&&t.push(`tags: ${e.tags.join(`, `)}`);let S=[];return S.push(`${e.recursiveMdCount} md file${e.recursiveMdCount===1?``:`s`}`),e.childDirCount>0&&S.push(`${e.childDirCount} subdir${e.childDirCount===1?``:`s`}`),t.push(S.join(`, `)),e.mostRecentMd&&t.push(`most recent: ${e.mostRecentMd.title??e.mostRecentMd.path} (${e.mostRecentMd.path})`),e.truncated&&t.push(`scan truncated`),`- ${t.join(` — `)}`}function formatFileEntry(e){let t=[`**${e.title??e.path}** (${e.path})`];if(e.description&&t.push(e.description),e.tags.length>0&&t.push(`tags: ${e.tags.join(`, `)}`),e.backlinkCount!==null&&t.push(`backlinks: ${e.backlinkCount}`),e.forwardLinkCount!==null&&t.push(`forward links: ${e.forwardLinkCount}`),e.history&&e.history.length>0){let S=e.history.map(e=>{let t=e.writerClassification===`agent`?`agent: ${e.writerName}`:e.writerClassification===`principal`?`human: ${e.writerName}`:`${e.writerClassification}: ${e.writerName}`;return`${e.hash.slice(0,7)} [${t}] ${e.message}`});t.push(`OK edits: ${S.join(` · `)}`)}if(e.projectHistory&&e.projectHistory.length>0){let S=e.projectHistory.map(e=>`${e.hash.slice(0,7)} ${e.authorName}: ${e.subject}`);t.push(`commits: ${S.join(` · `)}`)}return`- ${t.join(` — `)}`}function buildStdoutProvenance(e,t,S){let w=null;for(let t=e.length-1;t>=0;t--){let S=e[t],E=S.command;if(E===`ls`||E===`cat`){w=S;break}if((E===`head`||E===`tail`)&&nonFlagArgs(argsOf(S)).length>0){w=S;break}}if(!w)return``;let E=nonFlagArgs(argsOf(w));if(w.command===`ls`){let e=E[E.length-1];if(!e||e===`.`)return``;let S=e.replace(/\/+/g,`/`);return S.startsWith(`./`)&&(S=S.slice(2)),S.endsWith(`/`)&&(S=S.slice(0,-1)),!S||!t.has(S)?``:`${S}/:\n`}let D=E.filter(e=>/\.(md|mdx)$/.test(e)&&S.has(e));return D.length===1?`==> ${D[0]} <==\n`:``}function formatEnrichedBlock(e){if(e.length===0)return``;let t=[``,`### Referenced files`,``];for(let S of e)t.push(isDirectoryMeta(S)?formatDirectoryEntry(S):formatFileEntry(S));return t.join(`
|
|
2591
|
-
`)}async function classifyPaths(e,t){let S=[],w=[];return await Promise.all(t.map(async t=>{try{let E=await stat$1(resolve(e,t));E.isDirectory()?w.push(t):E.isFile()&&S.push(t)}catch{/\.(md|mdx)$/i.test(t)&&S.push(t)}})),{files:S,dirs:w}}function errorCategoryResult(e,t){return textPlusStructured(t,{enrichedPaths:[],error:{category:e,message:t}},!0)}function withPreviewUrls(e,t){return e.map(e=>{let S=t(docNameFromPath(e.path));return{...e,previewUrl:S?.url??null,...S?{previewUrlSource:S.source}:{}}})}async function buildExecResult(e,t){let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return errorCategoryResult(`shell_construct_blocked`,`exec failed: ${S.error}`);let{cwd:w,config:E,url:D}=S,O=parseCommand(e.command);if(`error`in O)return errorCategoryResult(O.error.category,O.error.message);let k=augmentStagesWithExcludes(O.stages),j=serializeStages(k),F=await snapshotMtimes(w),L=createBashInstance(w),B=``,H=``;try{let e=await execBash(L,j);B=e.stdout,H=e.stderr}catch(e){return e instanceof StdoutOverflowError?errorCategoryResult(`output_overflow`,`Output exceeded 16 MB buffer. Narrow the command (e.g., add a more specific grep pattern, use head, restrict the path).`):errorCategoryResult(`shell_construct_blocked`,`exec failed: ${e instanceof Error?e.message:String(e)}`)}let q=await snapshotMtimes(w),J=diffMtimes(F.snapshot,q.snapshot);if(J.changed.length>0)return errorCategoryResult(`security_invariant_violation`,`Security invariant violated: file(s) in the content directory were modified during a read-only exec call: ${J.changed.join(`, `)}. This indicates a parser bug; the command has been logged.`);let Y=applySoftCap(B),ee=extractReferencedPaths(B,k).filter(e=>resolveWithinRoot(w,e).ok),{files:te,dirs:ne}=await classifyPaths(w,ee),ae=k.length===1&&k[0].command===`cat`&&te.length===1,oe=await Promise.all(te.map(e=>enrichPath(e,{projectDir:w,serverUrl:D},{includeRichFields:ae}).catch(()=>({path:e,tags:[],frontmatter:{},backlinkCount:null,backlinks:null,forwardLinkCount:null,forwardLinks:null,history:null,historySource:null,projectHistory:null,projectHistorySource:null})))),se=await Promise.all(ne.map(e=>
|
|
2592
|
-
`)}\n\n`:``,ve=buildStdoutProvenance(k,ue,ce)+Y.text,ye=`${_e}${ve}${formatEnrichedBlock(de)}`,{resolve:Ce,ui:we}=await buildListResolver({config:E,resolveCwd:async()=>w}),Te=withPreviewUrls(de,Ce),De=we;return textPlusStructured(ye,{enrichedPaths:Te,stdout:ve,stdoutTruncated:Y.truncated,cwd:w,...De?{ui:De}:{},...me.length>0?{warnings:me}:{}})}function register$
|
|
2593
|
-
`),
|
|
2594
|
-
`)}
|
|
2595
|
-
`)
|
|
2596
|
-
`)
|
|
2597
|
-
`),InputSchema$
|
|
2598
|
-
`),InputSchema$
|
|
2599
|
-
`);function register$
|
|
2600
|
-
`);function register$17(e,t){e.registerTool(`get_forward_links`,{description:DESCRIPTION$17,inputSchema:{docName:string$2().describe(`Source page docName`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=normalizeDocName(e.docName);if(!D.ok)return textResult(D.error,!0);let O=await httpGet(E,`/api/forward-links?docName=${encodeURIComponent(D.docName)}`);if(!O.ok)return textResult(`Error: ${O.error}`,!0);let{ok:k,...j}=O,F=j,{resolve:L,ui:B}=await buildListResolver(t,w),H=(F.forwardLinks??[]).map(e=>{let t=e.kind===`doc`&&typeof e.docName==`string`?e.docName:null,S=t?L(t):null;return{...e,previewUrl:S?.url??null,...S?{previewUrlSource:S.source}:{}}}),q={...F,forwardLinks:H,ui:B,cwd:w};return textPlusStructured(JSON.stringify(q,null,2),q)})}const DESCRIPTION$16=[`[Requires: Hocuspocus server] List version history for a document.`,`Returns timeline entries from the shadow repo, sorted by timestamp descending.`,"Each entry includes a commit SHA that can be passed to `rollback_to_version`.",``,`**Parameters:**`,"- `docName` — Document name to query history for, typically without extension. A trailing `.md` or `.mdx` is stripped automatically.","- `branch` (optional) — Branch name (default: current branch)","- `limit` (optional) — Maximum entries to return (default 50, max 200)","- `offset` (optional) — Number of entries to skip for pagination (default 0)",'- `type` (optional) — Filter by entry type: "checkpoint", "upstream", or "wip"',"- `author` (optional) — Filter to entries by this author name or email","- `excludeAuthor` (optional) — Exclude entries by this author name or email"].join(`
|
|
2601
|
-
`);function register$16(e,t){e.registerTool(`get_history`,{description:DESCRIPTION$16,inputSchema:{docName:string$2().describe(`Document name to query history for`),branch:string$2().optional().describe(`Branch name (default: current branch)`),limit:number$1().int().min(1).max(200).optional().describe(`Maximum entries to return (default 50, max 200)`),offset:number$1().int().min(0).optional().describe(`Number of entries to skip for pagination (default 0)`),type:_enum([`checkpoint`,`upstream`,`wip`]).optional().describe(`Filter by entry type`),author:string$2().optional().describe(`Filter to entries by this author name or email`),excludeAuthor:string$2().optional().describe(`Exclude entries by this author name or email`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=normalizeDocName(e.docName);if(!D.ok)return textResult(D.error,!0);let O=new URLSearchParams;O.set(`docName`,D.docName),e.branch&&O.set(`branch`,e.branch),e.limit!=null&&O.set(`limit`,String(e.limit)),e.offset!=null&&O.set(`offset`,String(e.offset)),e.type&&O.set(`type`,e.type),e.author&&O.set(`author`,e.author),e.excludeAuthor&&O.set(`excludeAuthor`,e.excludeAuthor);let k=await httpGet(E,`/api/history?${O.toString()}`);if(!k.ok)return textResult(`Error: ${k.error}`,!0);let{ok:j,...F}=k,L=await resolvePreviewUrlForTool(D.docName,{config:t.config,resolveCwd:t.resolveCwd},w);return textPlusStructured(JSON.stringify(F,null,2),{...F,previewUrl:L?.url??null,...L?{previewUrlSource:L.source}:{}})})}const DESCRIPTION$15=[`[Requires: Hocuspocus server] Find the most-linked pages in the knowledge graph.`,`Returns hub pages ordered by inbound link count as JSON.`,``,`**Parameters:**`,"- `limit` (optional) — Maximum number of hubs to return (default 20)"].join(`
|
|
2602
|
-
`);function register$15(e,t){e.registerTool(`get_hubs`,{description:DESCRIPTION$15,inputSchema:{limit:number$1().int().positive().optional().describe(`Maximum number of hubs to return`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=await httpGet(E,`/api/hubs${e.limit?`?limit=${encodeURIComponent(String(e.limit))}`:``}`);if(!D.ok)return textResult(`Error: ${D.error}`,!0);let{ok:O,...k}=D,j=k,{resolve:F,ui:L}=await buildListResolver(t,w),B=(j.hubs??[]).map(e=>{let t=typeof e.docName==`string`?e.docName:null,S=t?F(t):null;return{...e,previewUrl:S?.url??null,...S?{previewUrlSource:S.source}:{}}}),H={...j,hubs:B,ui:L,cwd:w};return textPlusStructured(JSON.stringify(H,null,2),H)})}const DESCRIPTION$14=[`[Requires: Hocuspocus server] Find disconnected pages in the knowledge graph.`,`Returns orphaned pages as JSON.`,``,`**Parameters:**`,"- `mode` (optional) — Orphan lens: `incoming`, `outgoing`, or `both` (default `both`)"].join(`
|
|
2603
|
-
`);function register$14(e,t){e.registerTool(`get_orphans`,{description:DESCRIPTION$14,inputSchema:{mode:_enum(ORPHAN_MODES).optional().describe(`Filter which type of graph disconnection to surface`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=await httpGet(E,`/api/orphans${e.mode?`?mode=${encodeURIComponent(e.mode)}`:``}`);if(!D.ok)return textResult(`Error: ${D.error}`,!0);let{ok:O,...k}=D,j=k,{resolve:F,ui:L}=await buildListResolver(t,w),B=(j.orphans??[]).map(e=>{let t=typeof e.docName==`string`?e.docName:null,S=t?F(t):null;return{...e,previewUrl:S?.url??null,...S?{previewUrlSource:S.source}:{}}}),H={...j,orphans:B,ui:L,cwd:w};return textPlusStructured(JSON.stringify(H,null,2),H)})}const BUILTIN_SKIP_DIRS=new Set([`node_modules`,`.venv`,`venv`,`env`,`__pycache__`,`vendor`,`dist`,`build`,`out`,`output`,`.next`,`.nuxt`,`.svelte-kit`,`.astro`,`.turbo`,`.cache`,`.parcel-cache`,`coverage`,`.git`,`.ok`,`.open-knowledge`,`.openknowledge`,`Library`,`Applications`,`.Trash`]),IGNORE_FILE_NAMES=[`.gitignore`,`.okignore`];function createContentFilter(e){let{projectDir:t,contentDir:S,onAfterRebuild:w}=e,E=relative(t,S),D=E.startsWith(`..`),O,k,j,F=0,L=0,B=0;function H(){let e=(0,import_ignore.default)();e.add(`.git`);let w=[],H=0,q=0;for(let S of IGNORE_FILE_NAMES){let E=join(t,S);if(existsSync(E))try{let t=readFileSync(E,`utf-8`);H+=t.length;let S=parseIgnorePatterns(t);w.push(...S),e.add(S)}catch(e){console.warn(`[content-filter] Failed to read ${S} at ${E}:`,e)}}if(E&&!D)for(let t of IGNORE_FILE_NAMES){let w=join(S,t);if(existsSync(w))try{let t=readFileSync(w,`utf-8`);H+=t.length,q++;let S=parseIgnorePatterns(t).map(e=>prefixPattern(e,E));e.add(S)}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${w}:`,e)}}let J={value:H};q+=loadNestedIgnoreFiles(S,t,e,J),H=J.value;let Y=w.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`));return O=e,k=w,j=Y,F=w.length,L=q,B=H,{patternCount:F,nestedFileCount:L,bytes:B}}H();let q=new Map;function J(e){if(D)return!1;let t=E?`${E}/${e}`:e;return O.ignores(t)}populateDirCount(S,``,J,q);function Y(e){let t=stripDocExtension(e);return isSystemDoc(t)||isConfigDoc(t)}function ee(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return D?!1:J(e)}return{isExcluded(e,t){if(Y(e))return!0;if(t?.bypassFilters)return!1;if(ee(e))return!0;if(isSupportedDocFile(e))return!1;let S=extname(e).slice(1).toLowerCase();if(ASSET_EXTENSIONS.has(S)){let t=dirname(e),S=t===`.`?``:t;if((q.get(S)??0)>0)return!1}return!0},isDirExcluded(e,t){if(t?.bypassFilters)return!1;for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;if(D)return!1;let S=E?`${E}/${e}`:e;return O.ignores(S)||O.ignores(`${S}/`)},isPathIgnored(e,t){return Y(e)?!0:t?.bypassFilters?!1:ee(e)},getWatcherIgnoreGlobs(){return j},incrementMdDir(e){let t=e===`.`?``:e;q.set(t,(q.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,S=q.get(t)??0;S<=1?q.delete(t):q.set(t,S-1)},rebuildDirCount(){let e=new Map(q);q.clear();try{populateDirCount(S,``,J,q)}catch(t){for(let[t,S]of e)q.set(t,S);getLogger(`content-filter`).warn({err:t instanceof Error?t:Error(String(t))},`content-filter rebuildDirCount walk failed — retaining previous counts`)}},async rebuildIgnorePatterns(){let e=getLogger(`content-filter`),t=O,E=k,D=j,Y=F,ee=L,te=B,ne=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async ae=>{try{let t=H();q.clear(),populateDirCount(S,``,J,q);let E=Date.now()-ne;if(ae.setAttributes({"ok.ignore.pattern_count":t.patternCount,"ok.ignore.nested_file_count":t.nestedFileCount,"ok.ignore.bytes":t.bytes}),e.info({patternCount:t.patternCount,nestedFileCount:t.nestedFileCount,bytes:t.bytes,durationMs:E},`content-filter rebuild succeeded`),w)try{w()}catch(t){e.warn({err:t instanceof Error?t:Error(String(t))},`content-filter onAfterRebuild callback threw — derived views may be stale`)}return{ok:!0,patternCount:t.patternCount,nestedFileCount:t.nestedFileCount,bytes:t.bytes,durationMs:E}}catch(w){O=t,k=E,j=D,F=Y,L=ee,B=te,q.clear();try{populateDirCount(S,``,J,q)}catch(t){e.warn({err:t instanceof Error?t:Error(String(t))},`content-filter rollback dirCount re-walk failed — sibling-asset counts may be stale until next rebuild`)}let H=w instanceof Error?w.message:String(w);return e.warn({err:w instanceof Error?w:Error(H)},`content-filter rebuild failed — rolled back to previous state`),{ok:!1,error:{message:H}}}})}}}function populateDirCount(e,t,S,w){let E;try{E=readdirSync(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory for dir-count: ${e}`,t);return}for(let D of E){let E=t?`${t}/${D.name}`:D.name;if(D.isDirectory()){if(BUILTIN_SKIP_DIRS.has(D.name)||S(E)||S(`${E}/`))continue;populateDirCount(join(e,D.name),E,S,w)}else D.isFile()&&isSupportedDocFile(D.name)&&!S(E)&&w.set(t,(w.get(t)??0)+1)}}function parseIgnorePatterns(e){return e.split(`
|
|
2604
|
-
`).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`#`))}function prefixPattern(e,t){return e.startsWith(`!`)?`!${t}/${e.slice(1)}`:`${t}/${e}`}function loadNestedIgnoreFiles(e,t,S,w){let E;try{E=readdirSync(e,{withFileTypes:!0})}catch(t){return console.warn(`[content-filter] Failed to read directory ${e}:`,t),0}let D=0;for(let O of E){if(!O.isDirectory()||BUILTIN_SKIP_DIRS.has(O.name))continue;let E=join(e,O.name),k=relative(t,E);if(!k.startsWith(`..`)&&!(S.ignores(k)||S.ignores(`${k}/`))){for(let e of IGNORE_FILE_NAMES){let t=join(E,e);if(existsSync(t))try{let e=readFileSync(t,`utf-8`);w.value+=e.length;let E=parseIgnorePatterns(e).map(e=>prefixPattern(e,k));S.add(E),D++}catch(S){console.warn(`[content-filter] Failed to read nested ${e} at ${t}:`,S)}}D+=loadNestedIgnoreFiles(E,t,S,w)}}return D}async function initContentDirStateAsync(e,t,S,w,E,D,O){let k;try{k=await readdir(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory ${e}:`,t);return}for(let j of k){let k=t?`${t}/${j.name}`:j.name;if(j.isDirectory()){if(BUILTIN_SKIP_DIRS.has(j.name))continue;let t=join(e,j.name);if(!D){let e=relative(S,t);if(e.startsWith(`..`)||w.ignores(e)||w.ignores(`${e}/`))continue;for(let S of IGNORE_FILE_NAMES){let E=join(t,S);if(existsSync(E))try{let t=parseIgnorePatterns(await readFile$1(E,`utf-8`));w.add(t.map(t=>prefixPattern(t,e)))}catch(e){console.warn(`[content-filter] Failed to read nested ${S} at ${E}:`,e)}}}await initContentDirStateAsync(t,k,S,w,E,D,O)}else if(j.isFile()&&isSupportedDocFile(j.name)){if(!D){let e=E?`${E}/${k}`:k;if(w.ignores(e))continue}O.set(t,(O.get(t)??0)+1)}}}async function createContentFilterAsync(e){let{projectDir:t,contentDir:S,onAfterRebuild:w}=e,E=relative(t,S),D=E.startsWith(`..`),O=(0,import_ignore.default)(),k=[],j=new Map;function F(e){if(D)return!1;let t=E?`${E}/${e}`:e;return O.ignores(t)}function L(e){let t=stripDocExtension(e);return isSystemDoc(t)||isConfigDoc(t)}function B(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return D?!1:F(e)}async function H(){let e=(0,import_ignore.default)();e.add(`.git`);let w=[];for(let S of IGNORE_FILE_NAMES){let E=join(t,S);if(existsSync(E))try{let t=parseIgnorePatterns(await readFile$1(E,`utf-8`));w.push(...t),e.add(t)}catch(e){console.warn(`[content-filter] Failed to read ${S} at ${E}:`,e)}}if(E&&!D)for(let t of IGNORE_FILE_NAMES){let w=join(S,t);if(existsSync(w))try{let t=parseIgnorePatterns(await readFile$1(w,`utf-8`));e.add(t.map(e=>prefixPattern(e,E)))}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${w}:`,e)}}let F=new Map;await initContentDirStateAsync(S,``,t,e,E,D,F),O=e,k=w.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`)),j.clear();for(let[e,t]of F)j.set(e,t)}return await H(),{isExcluded(e,t){if(L(e))return!0;if(t?.bypassFilters)return!1;if(B(e))return!0;if(isSupportedDocFile(e))return!1;let S=extname(e).slice(1).toLowerCase();if(ASSET_EXTENSIONS.has(S)){let t=dirname(e),S=t===`.`?``:t;if((j.get(S)??0)>0)return!1}return!0},isDirExcluded(e,t){if(t?.bypassFilters)return!1;for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;if(D)return!1;let S=E?`${E}/${e}`:e;return O.ignores(S)||O.ignores(`${S}/`)},isPathIgnored(e,t){return L(e)?!0:t?.bypassFilters?!1:B(e)},getWatcherIgnoreGlobs(){return k},incrementMdDir(e){let t=e===`.`?``:e;j.set(t,(j.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,S=j.get(t)??0;S<=1?j.delete(t):j.set(t,S-1)},rebuildDirCount(){let e=new Map(j);j.clear();try{populateDirCount(S,``,F,j)}catch(t){for(let[t,S]of e)j.set(t,S);getLogger(`content-filter`).warn({err:t instanceof Error?t:Error(String(t))},`content-filter rebuildDirCount walk failed — retaining previous counts`)}},async rebuildIgnorePatterns(){let e=getLogger(`content-filter`),t=O,S=k,E=new Map(j),D=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async F=>{try{await H();let t=Date.now()-D;if(F.setAttributes({"ok.ignore.pattern_count":k.length,"ok.ignore.nested_file_count":0,"ok.ignore.bytes":0}),e.info({durationMs:t},`content-filter async rebuild succeeded`),w)try{w()}catch(t){e.warn({err:t instanceof Error?t:Error(String(t))},`content-filter onAfterRebuild callback threw — derived views may be stale`)}return{ok:!0,patternCount:k.length,nestedFileCount:0,bytes:0,durationMs:t}}catch(w){O=t,k=S,j.clear();for(let[e,t]of E)j.set(e,t);let D=w instanceof Error?w.message:String(w);return e.warn({err:w instanceof Error?w:Error(D)},`content-filter async rebuild failed — rolled back`),{ok:!1,error:{message:D}}}})}}}const DESCRIPTION$13=["Find every line that literally contains a string, grouped by file with frontmatter metadata. For ranked retrieval that mirrors cmd-K, use `search`.",``,`Matches are grouped by file; each file is annotated with its title, description, and tags so you can judge relevance without opening it first.`,``,`**Use when:**`,`- Finding every occurrence of a literal phrase across the wiki`,`- Auditing a term, identifier, or quote — coverage matters more than ranking`,``,"**When the project has `.ok/`**, strongly prefer this over your native `Grep` for wiki search — results include article metadata so you can skip irrelevant matches without extra reads. In projects without `.ok/`, use native `Grep` as usual.",``,`**Parameters:**`,"- `query` — Literal text to search for (fixed-string match, no regex)","- `case_sensitive` (optional, default false) — case-sensitive match","- `cwd` (optional) — Project root the grep runs against. Defaults only when the MCP client advertises exactly one root."].join(`
|
|
2605
|
-
`);function groupByFile(e){let t=new Map;for(let S of e){let e=t.get(S.path);e?e.push(S):t.set(S.path,[S])}return[...t.entries()].map(([e,t])=>({path:e,matches:t}))}async function buildGrepResult(e,t){let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)throw Error(S.error);let{cwd:w,config:E,url:D}=S,O=50,k=await grep(e.query,w,{caseInsensitive:!(e.case_sensitive??!1),include:[`**/*.md`,`**/*.mdx`],exclude:[`node_modules`,`.git`,`.claude`,`.changeset`,`.ok`],maxResults:51}),j=resolveContentDir(E,w),F=createContentFilter({projectDir:w,contentDir:j}),L=k.filter(e=>{let t=relative(j,resolve(w,e.path));return t.startsWith(`..`)?!1:!F.isExcluded(t)}),B=k.length>50,H=L.slice(0,50),{resolve:q,ui:J}=await buildListResolver({config:E,resolveCwd:async()=>w},w);if(H.length===0)return{text:`No matches for "${e.query}".`,structured:{query:e.query,matchCount:0,fileCount:0,truncated:!1,results:[],ui:J,cwd:w}};let Y=groupByFile(H),ee=new Map;await Promise.all(Y.map(async e=>{try{let t=await enrichPath(e.path,{projectDir:w,serverUrl:D});ee.set(e.path,t)}catch{}}));let te=[];te.push(`## Grep results for "${e.query}" (${H.length} match${H.length===1?``:`es`} in ${Y.length} file${Y.length===1?``:`s`})`,``);let ne=[];for(let e of Y){let t=ee.get(e.path),S=t?.title??e.path;te.push(`### ${S} (${e.path})`),t?.tags?.length&&te.push(`Tags: ${t.tags.join(`, `)}`),t?.description&&te.push(`${t.description}`);for(let t of e.matches)te.push(`- Line ${t.line}: ${t.text}`);te.push(``);let w=docNameFromPath(e.path),E=q(w);ne.push({path:e.path,docName:w,title:t?.title??null,description:t?.description??null,tags:t?.tags??[],matches:e.matches.map(e=>({line:e.line,text:e.text})),previewUrl:E?.url??null,...E?{previewUrlSource:E.source}:{}})}return B&&te.push(`_${H.length} of ${k.length}+ matches shown (max 50). Refine your query to narrow results._`),{text:te.join(`
|
|
2606
|
-
`),structured:{query:e.query,matchCount:H.length,fileCount:Y.length,truncated:B,results:ne,ui:J,cwd:w}}}const InputSchema$3={query:string$2().describe(`Literal text to search for`),case_sensitive:boolean$1().optional().describe(`Case-sensitive search (default false)`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)},GrepResultRowSchema=object$1({path:string$2(),docName:string$2(),title:string$2().nullable(),description:string$2().nullable(),tags:array(string$2()),matches:array(object$1({line:number$1().int(),text:string$2()})),previewUrl:string$2().nullable(),previewUrlSource:_enum(PREVIEW_URL_SOURCES).optional()}),OutputSchema$3=outputSchemaWithText({cwd:string$2(),query:string$2(),matchCount:number$1().int(),fileCount:number$1().int(),truncated:boolean$1(),results:array(GrepResultRowSchema),ui:object$1({baseUrl:string$2().nullable(),port:number$1().nullable()})});function register$13(e,t){e.registerTool(`grep`,{description:DESCRIPTION$13,inputSchema:InputSchema$3,outputSchema:OutputSchema$3,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0}},async e=>{try{let{text:S,structured:w}=await buildGrepResult(e,t);return w?textPlusStructured(S,w):textResult(S)}catch(e){return textResult(`Error: ${e instanceof Error?e.message:String(e)}`,!0)}})}function buildBody$1(e,t){return`Capture this external source into the project knowledge base as raw reference material. The KB is **closed-loop**: external sources are pulled INTO the knowledge base here so downstream docs cite local paths, never bare web URLs. This applies whether a user shared the source OR you fetched it yourself to ground a knowledge-base claim — agent-initiated fetches are not exempt. **Raw preservation only** — no summary, no analysis, no interpretation. Summarizing is the job of the \`research\` tool later.
|
|
2589
|
+
`)}async function classifyPaths(e,t){let S=[],w=[];return await Promise.all(t.map(async t=>{try{let E=await stat$1(resolve(e,t));E.isDirectory()?w.push(t):E.isFile()&&S.push(t)}catch{/\.(md|mdx)$/i.test(t)&&S.push(t)}})),{files:S,dirs:w}}function errorCategoryResult(e,t){return textPlusStructured(t,{enrichedPaths:[],error:{category:e,message:t}},!0)}function withPreviewUrls(e,t){return e.map(e=>{let S=t(docNameFromPath(e.path));return{...e,previewUrl:S?.url??null,...S?{previewUrlSource:S.source}:{}}})}async function buildExecResult(e,t){let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return errorCategoryResult(`shell_construct_blocked`,`exec failed: ${S.error}`);let{cwd:w,config:E,url:D}=S,O=parseCommand(e.command);if(`error`in O)return errorCategoryResult(O.error.category,O.error.message);let k=augmentStagesWithExcludes(O.stages),j=serializeStages(k),F=await snapshotMtimes(w),L=createBashInstance(w),B=``,H=``;try{let e=await execBash(L,j);B=e.stdout,H=e.stderr}catch(e){return e instanceof StdoutOverflowError?errorCategoryResult(`output_overflow`,`Output exceeded 16 MB buffer. Narrow the command (e.g., add a more specific grep pattern, use head, restrict the path).`):errorCategoryResult(`shell_construct_blocked`,`exec failed: ${e instanceof Error?e.message:String(e)}`)}let q=await snapshotMtimes(w),J=diffMtimes(F.snapshot,q.snapshot);if(J.changed.length>0)return errorCategoryResult(`security_invariant_violation`,`Security invariant violated: file(s) in the content directory were modified during a read-only exec call: ${J.changed.join(`, `)}. This indicates a parser bug; the command has been logged.`);let Y=applySoftCap(B),ee=extractReferencedPaths(B,k).filter(e=>resolveWithinRoot(w,e).ok),{files:te,dirs:ne}=await classifyPaths(w,ee),ae=k.length===1&&k[0].command===`cat`&&te.length===1,oe=await Promise.all(te.map(e=>enrichPath(e,{projectDir:w,serverUrl:D},{includeRichFields:ae}).catch(()=>({path:e,tags:[],frontmatter:{},backlinkCount:null,backlinks:null,forwardLinkCount:null,forwardLinks:null,history:null,historySource:null,projectHistory:null,projectHistorySource:null})))),se=await Promise.all(ne.map(e=>enrichDirectoryRecursive(e,1,{projectDir:w}).catch(()=>({path:e,type:`directory`,directMdCount:0,recursiveMdCount:0,childDirCount:0,truncated:!1}))));if(!ae&&D&&oe.length>0){let e=await fetchBacklinkCountsBatch(D,oe.map(e=>pathToDocName$1(e.path))).catch(()=>null);if(e)for(let t of oe){let S=e.get(pathToDocName$1(t.path));typeof S==`number`&&(t.backlinkCount=S)}}let ce=new Map(oe.map(e=>[e.path,e])),ue=new Map(se.map(e=>[e.path,e])),de=[];for(let e of ee){let t=ce.get(e);if(t){de.push(t);continue}let S=ue.get(e);S&&de.push(S)}let fe=detectBinaryArgs(k),me=[];fe.length>0&&me.push(`File${fe.length>1?`s`:``} ${fe.join(`, `)} appear${fe.length===1?`s`:``} to be binary (image/PDF/etc.) — exec returns text only (NG8). For binary retrieval, use native Read.`);let ge=detectHeadTailTruncation(k,B);ge&&me.push(ge.banner),H&&me.push(`stderr: ${H.trim()}`);let _e=me.length>0?`${me.join(`
|
|
2590
|
+
`)}\n\n`:``,ve=buildStdoutProvenance(k,ue,ce)+Y.text,ye=`${_e}${ve}${formatEnrichedBlock(de)}`,{resolve:Ce,ui:we}=await buildListResolver({config:E,resolveCwd:async()=>w}),Te=withPreviewUrls(de,Ce),De=we;return textPlusStructured(ye,{enrichedPaths:Te,stdout:ve,stdoutTruncated:Y.truncated,cwd:w,...De?{ui:De}:{},...me.length>0?{warnings:me}:{}})}function register$11(e,t){e.registerTool(`exec`,{description:DESCRIPTION$11,inputSchema:{command:string$2().describe(`Read-only bash command (allowlist: cat, ls, grep, find, head, tail, wc, sort, uniq, cut; pipes OK)`),cwd:string$2().optional().describe("Absolute host path to run the command from. Defaults only when the MCP client advertises exactly one root; otherwise pass `cwd` explicitly.")}},async e=>{try{return await buildExecResult(e,t)}catch(e){return errorCategoryResult(`shell_construct_blocked`,`exec handler error: ${e instanceof Error?e.message:String(e)}`)}})}const DESCRIPTION$10=["[Operates on disk; no running OK server required] Folder-level configuration writes. Dispatches on `action`:",``,'- `action: "set-rule"` — Upsert folder rules (default frontmatter applied to docs in `<folder>/` via cascade). Writes nested `<folder>/.ok/frontmatter.yml`. Always batch-shape: pass `rules: [{...}]` even for one. Empty `frontmatter: {}` removes the rule and auto-cleans `<folder>/.ok/` if empty. Use `new_match` to rename the rule\'s match glob. Multi-folder globs are rejected (split per folder).','- `action: "write-template"` — Create or update `<folder>/.ok/templates/<name>.md`. Templates are markdown starter shapes; agents instantiate via `write_document({ template })`. `title` in frontmatter is REQUIRED (menu surface). Body MAY use `{{date}}` / `{{user}}` substitution tokens; any other `{{...}}` is rejected. Unknown keys are rejected.','- `action: "delete-template"` — Remove `<folder>/.ok/templates/<name>.md`. Idempotent (`existed: false` if missing). Auto-cleans empty `templates/` and `.ok/` dirs. Unknown keys are rejected.',``,"To apply several writes in one call (e.g. set a folder rule and write its template together), pass `operations: [{action, ...}, ...]` instead of a top-level `action`. Operations run in order; the response reports each.",``,`**Cascade merge semantics:** scalars replace last-wins along the leaf → root walk; arrays union-and-dedup with first-occurrence preserved; objects replace last-wins.`,``,`**Parameters:**`,"- `action` — `set-rule` | `write-template` | `delete-template`. Omit when using `operations`.","- `operations` — Array of `{action, ...}` objects. Mutually exclusive with a top-level `action`.","- `rules` — Required for `set-rule`. Array of `{match, frontmatter, new_match?}`. `match` is a folder glob (`specs/**`). `frontmatter` is an open record; common keys: `title`, `description`, `tags`; arbitrary keys also persist.","- `folder` — Required for `write-template`/`delete-template`. Project-root-relative folder. Empty / `.` means project root.","- `name` — Required for `write-template`/`delete-template`. Template filename without `.md`. Letters/digits/`_`/`-` only.","- `body` — Required for `write-template`. Markdown body. May use `{{date}}` / `{{user}}`.","- `frontmatter` — Required for `write-template`. `{title (required), description?, tags?: string[]}`.","- `cwd` (optional) — Project root."].join(`
|
|
2591
|
+
`),ACTIONS$1=[`set-rule`,`write-template`,`delete-template`],FolderRuleUpsertInputSchema=object$1({match:string$2().min(1).describe(`Glob pattern (e.g. "specs/**", "meetings/prep-notes/**") that identifies the target folder.`),frontmatter:record(string$2(),unknown$2()).refine(e=>!(`title`in e&&e.title!==null&&typeof e.title!=`string`||`description`in e&&e.description!==null&&typeof e.description!=`string`||`tags`in e&&e.tags!==null&&!Array.isArray(e.tags)),{message:"Well-known keys must match expected types when present: `title` (string|null), `description` (string|null), `tags` (string[]|null)."}).describe("Default frontmatter to apply to matched docs. Open shape. Common: `{title?, description?, tags?: string[]}`; arbitrary keys also persist. Pass `{}` to remove the rule."),new_match:string$2().min(1).optional().describe("If set, move the rule from `match` to this new folder.")}),TEMPLATE_NAME_REGEX=/^[A-Za-z0-9_-]+$/,TemplateFrontmatterSchema=object$1({title:string$2().min(1,"Template `title` is required — it is the menu surface agents pick from.").describe(`Required. The menu surface agents pick from.`),description:string$2().optional().describe(`Recommended. Disambiguates similarly-named templates.`),tags:array(string$2()).optional().describe(`Optional. Concatenated with cascade tags at instantiation time.`)}),ACTION_FIELDS={rules:array(FolderRuleUpsertInputSchema).min(1).optional().describe("Required for `set-rule`. Array of folder rules to upsert."),folder:string$2().optional().describe("Required for `write-template`/`delete-template`. Project-root-relative folder."),name:string$2().min(1).regex(TEMPLATE_NAME_REGEX,"Template name must use letters, digits, `_`, or `-` only (no slashes, dots, or spaces).").optional().describe("Required for `write-template`/`delete-template`. Template filename without `.md` extension."),body:string$2().optional().describe("Required for `write-template`. Markdown body."),frontmatter:TemplateFrontmatterSchema.optional().describe("Required for `write-template`. Template menu metadata.")},OperationSchema=object$1({action:_enum(ACTIONS$1).describe(`Which folder-config write to perform.`),...ACTION_FIELDS}).strict();function checkActionFields(e,t,S){e.action===`set-rule`?e.rules||t.addIssue({code:`custom`,message:"action=set-rule requires `rules`.",path:[...S,`rules`]}):e.action===`write-template`?(e.folder===void 0&&t.addIssue({code:`custom`,message:"action=write-template requires `folder`.",path:[...S,`folder`]}),e.name||t.addIssue({code:`custom`,message:"action=write-template requires `name`.",path:[...S,`name`]}),e.body===void 0&&t.addIssue({code:`custom`,message:"action=write-template requires `body`.",path:[...S,`body`]}),e.frontmatter||t.addIssue({code:`custom`,message:"action=write-template requires `frontmatter`.",path:[...S,`frontmatter`]})):e.action===`delete-template`&&(e.folder===void 0&&t.addIssue({code:`custom`,message:"action=delete-template requires `folder`.",path:[...S,`folder`]}),e.name||t.addIssue({code:`custom`,message:"action=delete-template requires `name`.",path:[...S,`name`]}))}const FolderConfigInputSchema=object$1({action:_enum(ACTIONS$1).optional().describe("Which folder-config write to perform. Omit when `operations` is set."),...ACTION_FIELDS,operations:array(OperationSchema).min(1).optional().describe("Batch form: apply several folder-config writes in one call. Mutually exclusive with `action`."),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}).strict().superRefine((e,t)=>{if(e.operations!==void 0){e.action!==void 0&&t.addIssue({code:`custom`,message:"`action` and `operations` are mutually exclusive.",path:[`action`]});for(let S of[`rules`,`folder`,`name`,`body`,`frontmatter`])e[S]!==void 0&&t.addIssue({code:`custom`,message:`\`${S}\` belongs inside an \`operations\` entry, not at the top level.`,path:[S]});e.operations.forEach((e,S)=>{checkActionFields(e,t,[`operations`,S])});return}if(e.action===void 0){t.addIssue({code:`custom`,message:"Provide either `action` or `operations`.",path:[`action`]});return}checkActionFields(e,t,[])}),AppliedEntrySchema=object$1({match:string$2(),path:string$2(),action:_enum([`written`,`deleted`])}),SingleResultSchema=union([object$1({ok:literal(!0),applied:array(AppliedEntrySchema)}),object$1({ok:literal(!1),error:object$1({code:_enum([`MULTI_FOLDER_GLOB`,`PATH_ESCAPE`,`BAD_PROJECT_DIR`,`WRITE_ERROR`]),message:string$2(),rule:string$2().optional()}),partiallyApplied:array(AppliedEntrySchema).optional()}),object$1({ok:literal(!0),path:string$2(),created:boolean$1(),warnings:array(string$2())}),object$1({ok:literal(!0),path:string$2(),existed:boolean$1(),cleanedEmpty:object$1({templatesDir:boolean$1(),okDir:boolean$1()})}),object$1({ok:literal(!1),error:object$1({code:string$2(),message:string$2()})})]),FolderConfigOutputSchema=outputSchemaWithText({result:union([SingleResultSchema,object$1({ok:boolean$1(),operations:array(object$1({action:_enum(ACTIONS$1),result:SingleResultSchema}))})])});function register$10(e,t){e.registerTool(`folder_config`,{description:DESCRIPTION$10,inputSchema:FolderConfigInputSchema,outputSchema:FolderConfigOutputSchema,annotations:{readOnlyHint:!1,idempotentHint:!0,destructiveHint:!0}},async e=>{let S=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);if(!S.ok)return{isError:!0,content:[{type:`text`,text:`Error: ${S.error}`}]};let{cwd:w}=S;if(e.operations!==void 0)return handleBatch(e.operations,w);switch(e.action){case`set-rule`:return handleSetRule(e,w);case`write-template`:return handleWriteTemplate(e,w);case`delete-template`:return handleDeleteTemplate(e,w)}return{isError:!0,content:[{type:`text`,text:`Error: no action.`}]}})}function applyOperation(e,t){switch(e.action){case`set-rule`:return e.rules?applyNestedFolderRulesUpsert({projectDir:t,rules:e.rules.map(e=>({match:e.match,frontmatter:e.frontmatter??{},...e.new_match===void 0?{}:{new_match:e.new_match}}))}):{ok:!1,error:{code:`MISSING_FIELD`,message:"set-rule requires `rules`."}};case`write-template`:return e.folder===void 0||!e.name||e.body===void 0||!e.frontmatter?{ok:!1,error:{code:`MISSING_FIELD`,message:"write-template requires `folder`, `name`, `body`, and `frontmatter`."}}:applyTemplateWrite({projectDir:t,folder:e.folder,name:e.name,body:e.body,frontmatter:e.frontmatter});case`delete-template`:return e.folder===void 0||!e.name?{ok:!1,error:{code:`MISSING_FIELD`,message:"delete-template requires `folder` and `name`."}}:applyTemplateDelete({projectDir:t,folder:e.folder,name:e.name})}}function describeResult(e,t){return t.ok?`applied`in t?`${e}: ${t.applied.length} rule(s) applied`:`created`in t?`${e}: ${t.created?`created`:`updated`} ${t.path}`:`existed`in t?`${e}: ${t.existed?`deleted`:`no-op (missing)`} ${t.path}`:e:`${e}: ${t.error.code}: ${t.error.message}`}function handleBatch(e,t){let S=e.map(e=>({action:e.action,result:applyOperation(e,t)})),w=S.every(e=>e.result.ok),E={ok:w,operations:S},D=S.map(e=>describeResult(e.action,e.result)).join(`
|
|
2592
|
+
`);return w?textPlusStructured(D,{result:E}):textPlusStructured(D,{result:E},!0)}function handleSetRule(e,t){let S=applyNestedFolderRulesUpsert({projectDir:t,rules:(e.rules??[]).map(e=>({match:e.match,frontmatter:e.frontmatter??{},...e.new_match===void 0?{}:{new_match:e.new_match}}))});return S.ok?textPlusStructured(JSON.stringify(S,null,2),{result:S}):textPlusStructured(`${S.error.code}: ${S.error.message}`,{result:S},!0)}function handleWriteTemplate(e,t){let S=applyTemplateWrite({projectDir:t,folder:e.folder??``,name:e.name??``,body:e.body??``,frontmatter:e.frontmatter??{title:``}});if(!S.ok)return textPlusStructured(`${S.error.code}: ${S.error.message}`,{result:S},!0);let w=[`${S.created?`Created`:`Updated`} template at ${S.path}`];if(S.warnings.length>0){w.push(``,`Warnings:`);for(let e of S.warnings)w.push(` - ${e}`)}return textPlusStructured(w.join(`
|
|
2593
|
+
`),{result:S})}function handleDeleteTemplate(e,t){let S=applyTemplateDelete({projectDir:t,folder:e.folder??``,name:e.name??``});if(!S.ok)return textPlusStructured(`${S.error.code}: ${S.error.message}`,{result:S},!0);let w=[S.existed?`Deleted template at ${S.path}`:`Template at ${S.path} did not exist (no-op)`];return S.cleanedEmpty.templatesDir&&w.push(`Removed empty .ok/templates/ directory`),S.cleanedEmpty.okDir&&w.push(`Removed empty .ok/ directory`),textPlusStructured(w.join(`
|
|
2594
|
+
`),{result:S})}const ID_CARDINALITY_CAP=32,DESCRIPTION$9=["[Operates on registry data; no running OK server required] Return full per-entry details for the canonical components an agent picked from the inventory rendered in the `write_document` / `edit_document` tool descriptions.",``,"Each entry carries: literal source-form `example` (copy-pasteable) + form-aware `params` (every prop, with `type` / `values?` / `required` / `defaultValue?` / `description`). Unmatched ids surface in `notFound` rather than failing the call.",``,`**Parameters:**`,`- \`ids\` — Array of canonical ids picked from the write-tool inventory (e.g. \`["Callout", "Tabs"]\`). Max ${ID_CARDINALITY_CAP} ids per call. Case-sensitive — must match the inventory exactly (\`Callout\` not \`callout\`; \`img\` not \`Image\`).`,"- `cwd` (optional) — Project root (see `cwd` description below)."].join(`
|
|
2595
|
+
`),InputSchema$2={ids:array(string$2().min(1)).max(ID_CARDINALITY_CAP).describe(`Array of canonical ids to fetch. Max ${ID_CARDINALITY_CAP} ids per call. Empty array returns an empty components list.`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)},ParamSchema=object$1({name:string$2(),type:_enum([`string`,`boolean`,`number`,`enum`,`reactnode`]),values:array(string$2()).optional(),required:boolean$1(),defaultValue:union([string$2(),boolean$1(),number$1()]).optional(),description:string$2().optional(),omitOnDefault:literal(!0).optional(),advanced:literal(!0).optional(),language:_enum([`mermaid`,`latex`,`html`,`json`,`yaml`,`javascript`,`markdown`]).optional(),accept:array(string$2()).optional()}),ComponentEntrySchema=object$1({id:string$2(),displayName:string$2(),description:string$2(),kind:_enum([`jsx-block`,`jsx-void`]),example:string$2(),params:array(ParamSchema)}),OutputSchema$2=outputSchemaWithText({version:literal(1).describe(`Schema version stamp — bump for breaking shape changes.`),components:array(ComponentEntrySchema).describe(`Full per-entry details for ids that matched.`),notFound:array(string$2()).describe(`Ids that did not match any canonical descriptor.`)});function register$9(e,t){e.registerTool(`get_components`,{description:DESCRIPTION$9,inputSchema:InputSchema$2,outputSchema:OutputSchema$2,annotations:{readOnlyHint:!0,idempotentHint:!0}},async e=>{e.cwd;let t=getAgentCanonicalDescriptors(),S=new Map(t.map(e=>[e.name,e])),w=[],E=[],D=new Set;for(let t of e.ids){if(D.has(t))continue;D.add(t);let e=S.get(t);if(e===void 0){E.push(t);continue}w.push(projectFull(e))}let O={version:1,components:w,notFound:E};return textPlusStructured(JSON.stringify(O,null,2),O)})}const DESCRIPTION$8=[`[Operates on disk; no running OK server required] Read the effective merged Open Knowledge config (defaults → user → project).`,``,`Use this when you need to inspect the config mid-session — e.g., after a write that may have changed disk state, or to re-confirm the value of a field before reading it again.`,``,"Read returns the FULL merged config or a sub-tree when `path` is provided. There is no allowlist on reads — every field is readable.",``,"Note: the `server.*`, `mcp.*`, `github.*`, and `preview.*` config sub-trees were removed; their values are now built-in constants in `@inkeep/open-knowledge-core` (or hardcoded behavior, in the case of `preview.*`). Reading those paths returns `exists: false`.",``,`**Parameters:**`,'- `path` (optional) — Dotted-segments array. `["content"]` returns the content sub-tree; `["appearance", "theme"]` returns just that leaf. Omit for full config.',"- `cwd` (optional) — Project root (see `cwd` description below)."].join(`
|
|
2596
|
+
`),InputSchema$1={path:array(string$2()).optional().describe(`Dotted path as array of segments (e.g. ["appearance","theme"]). Omit to return the full merged config.`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)},OutputSchema$1=outputSchemaWithText({value:unknown$2().describe(`Resolved config value at the requested path (or full config).`),exists:boolean$1().optional().describe('Whether the requested path resolved to a value. `false` distinguishes "path absent" from "path explicitly set to null"; absent on full-config reads.'),path:array(string$2()).optional().describe(`Echo of the requested dotted path (empty when reading the full config).`)});function readConfigPath(e,t){let S=e;for(let e of t){if(typeof S!=`object`||!S)return;S=S[e]}return S}function register$8(e,t){e.registerTool(`get_config`,{description:DESCRIPTION$8,inputSchema:InputSchema$1,outputSchema:OutputSchema$1,annotations:{readOnlyHint:!0,idempotentHint:!0}},async e=>{let S=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);if(!S.ok)return{isError:!0,content:[{type:`text`,text:`Error: ${S.error}`}]};let w=e.path??[],E=w.length>0?readConfigPath(S.config,w):S.config;return w.length>0&&E===void 0?textPlusStructured(`(no value at ${w.join(`.`)})`,{value:null,exists:!1,path:w}):textPlusStructured(JSON.stringify(E,null,2),{value:E,exists:!0,path:w})})}const DESCRIPTION$7=[`[Requires: Hocuspocus server] List version history for a document.`,`Returns timeline entries from the shadow repo, sorted by timestamp descending.`,'Each entry includes a commit SHA that can be passed to `version({ action: "rollback" })`.',``,`**Parameters:**`,"- `docName` — Document name to query history for, typically without extension. A trailing `.md` or `.mdx` is stripped automatically.","- `branch` (optional) — Branch name (default: current branch)","- `limit` (optional) — Maximum entries to return (default 50, max 200)","- `offset` (optional) — Number of entries to skip for pagination (default 0)",'- `type` (optional) — Filter by entry type: "checkpoint", "upstream", or "wip"',"- `author` (optional) — Filter to entries by this author name or email","- `excludeAuthor` (optional) — Exclude entries by this author name or email"].join(`
|
|
2597
|
+
`);function register$7(e,t){e.registerTool(`get_history`,{description:DESCRIPTION$7,inputSchema:{docName:string$2().describe(`Document name to query history for`),branch:string$2().optional().describe(`Branch name (default: current branch)`),limit:number$1().int().min(1).max(200).optional().describe(`Maximum entries to return (default 50, max 200)`),offset:number$1().int().min(0).optional().describe(`Number of entries to skip for pagination (default 0)`),type:_enum([`checkpoint`,`upstream`,`wip`]).optional().describe(`Filter by entry type`),author:string$2().optional().describe(`Filter to entries by this author name or email`),excludeAuthor:string$2().optional().describe(`Exclude entries by this author name or email`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=normalizeDocName(e.docName);if(!D.ok)return textResult(D.error,!0);let O=new URLSearchParams;O.set(`docName`,D.docName),e.branch&&O.set(`branch`,e.branch),e.limit!=null&&O.set(`limit`,String(e.limit)),e.offset!=null&&O.set(`offset`,String(e.offset)),e.type&&O.set(`type`,e.type),e.author&&O.set(`author`,e.author),e.excludeAuthor&&O.set(`excludeAuthor`,e.excludeAuthor);let k=await httpGet(E,`/api/history?${O.toString()}`);if(!k.ok)return textResult(`Error: ${k.error}`,!0);let{ok:j,...F}=k,L=await resolvePreviewUrlForTool(D.docName,{config:t.config,resolveCwd:t.resolveCwd},w);return textPlusStructured(JSON.stringify(F,null,2),{...F,previewUrl:L?.url??null,...L?{previewUrlSource:L.source}:{}})})}function buildBody$1(e,t){return`Capture this external source into the project knowledge base as raw reference material. The KB is **closed-loop**: external sources are pulled INTO the knowledge base here so downstream docs cite local paths, never bare web URLs. This applies whether a user shared the source OR you fetched it yourself to ground a knowledge-base claim — agent-initiated fetches are not exempt. **Raw preservation only** — no summary, no analysis, no interpretation. Summarizing is the job of the \`research\` tool later.
|
|
2607
2598
|
|
|
2608
2599
|
**Bias toward binary preservation.** When the source is a binary file (PDF, image, audio, video, Office doc, archive, dataset), preserve the raw bytes — do NOT settle for a text scrape. OK already ships a complete asset-embed surface (\`![[file.ext]]\` wiki-embed, file-watcher pickup, sha256 dedup, blocked-extension enforcement); this tool's job is to bridge \`ingest\` to it via your shell tool.
|
|
2609
2600
|
|
|
@@ -2841,19 +2832,12 @@ If the source is directly relevant to an existing article or research doc, updat
|
|
|
2841
2832
|
- **No OCR / transcription** — binary preservation only. \`research\` may apply analysis layers downstream.
|
|
2842
2833
|
- **No streaming-video direct download** — \`yt-dlp\` is a separate workflow; \`ingest\` STOPs and routes to it (Step 1a STOP gate 1).
|
|
2843
2834
|
- **No executable / scripted-document auto-fetch** — hard-blocked at Step 1b STOP gate 1 (write-path only). User runs \`curl\` manually outside the agent if they need to archive such a file.
|
|
2844
|
-
`}const DESCRIPTION$
|
|
2845
|
-
`);function register$
|
|
2846
|
-
`);function register$
|
|
2847
|
-
`);function
|
|
2848
|
-
`)}function
|
|
2849
|
-
`)}function
|
|
2850
|
-
`)}function formatForwardLinks(e){if(!e||e.length===0)return``;let t=[``,`### Forward links (${e.length})`,``];for(let S of e){if(S.kind===`external`){let e=S.title?` — "${S.title}"`:``,w=S.snippet?` — "${S.snippet}"`:``;t.push(`- ${S.url}${e}${w}`);continue}let e=S.title?` — "${S.title}"`:``,w=S.snippet?` — "${S.snippet}"`:``;t.push(`- ${S.docName}${e}${w}`)}return t.join(`
|
|
2851
|
-
`)}function docNameFromRelPath(e){return e.replace(/\.(md|mdx)$/i,``)}async function buildReadResult(e,t){let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)throw Error(S.error);let{cwd:w,url:E}=S,D=resolveWithinRoot(w,e.path);if(!D.ok)throw Error(`Refusing to read outside project root: ${D.reason}`);let O=D.rel,k=D.abs,j=5,[F,L]=await Promise.all([readFile$1(k,`utf-8`),enrichPath(O,{projectDir:w,serverUrl:E,historyDepth:5},{includeRichFields:!0})]),B=O.split(`/`).pop()?.replace(/\.md$/,``).replace(/\.mdx$/,``)??O,H=L.title??B,q=L.description??``,J=L.tags,Y=[];Y.push(`## ${H}`),q&&Y.push(`**Description:** ${q}`),J.length>0&&Y.push(`**Tags:** ${J.join(`, `)}`),Y.push(`**Path:** ${O}`);let ee=formatShadowHistory(L.history);ee&&Y.push(ee);let te=formatProjectHistory(L.projectHistory);te&&Y.push(te);let ne=formatBacklinks(L.backlinks);ne&&Y.push(ne);let ae=formatForwardLinks(L.forwardLinks);return ae&&Y.push(ae),Y.push(``,`### Content`,``,F),Y.join(`
|
|
2852
|
-
`)}function register$10(e,t){e.registerTool(`read_document`,{description:DESCRIPTION$10,inputSchema:{path:string$2().describe(`Project-root-relative path to the file`),since:string$2().optional().describe(`Reserved; currently unused (§15 Future Work)`),cwd:string$2().optional().describe("Absolute host path to resolve `path` against. Defaults only when the MCP client advertises exactly one root; otherwise pass `cwd` explicitly.")}},async e=>{try{let S=await buildReadResult(e,t),w=await t.resolveCwd(e.cwd),E=resolveWithinRoot(w,e.path),D=await resolvePreviewUrlForTool(E.ok?docNameFromRelPath(E.rel):docNameFromRelPath(e.path),{config:t.config,resolveCwd:t.resolveCwd},w);return D?textPlusStructured(S,{previewUrl:D.url,previewUrlSource:D.source}):textPlusStructured(S,{previewUrl:null})}catch(e){return textResult(`Error: ${e instanceof Error?e.message:String(e)}`,!0)}})}const DESCRIPTION$9=["[Requires: Hocuspocus server] Rename a document through the managed rename flow at `POST /api/rename-path` (kind: file).",`Renames the target document and rewrites inbound wiki-links plus supported internal inline Markdown links in affected docs.`,``,`**Parameters:**`,"- `docName` — Current document name, typically without extension. A trailing `.md` or `.mdx` is stripped automatically.","- `newDocName` — New document name, typically without extension. A trailing `.md` or `.mdx` is stripped automatically.",'- `summary` — Optional one-line user-outcome description (≤80 chars). Appears as a bullet in the timeline. If omitted, a default like "Renamed X → Y" is generated. Provide your own summary to explain the why. Avoid including secrets or PII — summaries are persisted to git history.',``,`**Errors:**`,"- 400 — case-only renames (e.g. `Auth` → `auth`) are not supported.","- 400 — destination document is excluded by `.gitignore` / `.okignore` rules.",`- 404 — source document does not exist.`,`- 409 — destination document already exists.`].join(`
|
|
2853
|
-
`);function parseRenameMappings$1(e){return Array.isArray(e)?e.flatMap(e=>{if(!e||typeof e!=`object`)return[];let{fromDocName:t,toDocName:S}=e;return typeof t==`string`&&typeof S==`string`?[{fromDocName:t,toDocName:S}]:[]}):[]}function parseRewrittenDocs$1(e){return Array.isArray(e)?e.flatMap(e=>{if(!e||typeof e!=`object`)return[];let{docName:t,rewrites:S}=e;return typeof t==`string`&&typeof S==`number`?[{docName:t,rewrites:S}]:[]}):[]}function pluralize(e,t,S=`${t}s`){return e===1?t:S}function register$9(e,t){e.registerTool(`rename_document`,{description:DESCRIPTION$9,inputSchema:{docName:string$2().describe(`Current document name`),newDocName:string$2().describe(`New document name`),summary:summaryArgSchema.describe(`Optional one-line user-outcome description (≤80 chars). Defaults to "Renamed X → Y" when omitted. Appears as a bullet in the timeline.`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=normalizeDocName(e.docName);if(!D.ok)return textResult(D.error,!0);let O=normalizeDocName(e.newDocName);if(!O.ok)return textResult(O.error,!0);let k=t.identityRef?.current,j=await httpPost(E,`/api/rename-path`,{kind:`file`,fromPath:D.docName,toPath:O.docName,...e.summary===void 0?{}:{summary:e.summary},...k?{agentId:k.connectionId,agentName:k.displayName,clientName:k.clientInfo?.name,colorSeed:k.colorSeed}:{}});if(!j.ok){let e=j.error,t=parseRenameCollidingPairs(j.colliding),S={ok:!1,error:e,...t.length>0?{colliding:t}:{}};return textPlusStructured(`Error: ${e}`,S,!0)}let F=parseRenameMappings$1(j.renamed),L=parseRewrittenDocs$1(j.rewrittenDocs),B=F.map(({fromDocName:e,toDocName:t})=>`${e} -> ${t}`).join(`, `)||`${D.docName} -> ${O.docName}`,H=L.length===0?`No inbound links required updates.`:`Rewrote ${L.length} ${pluralize(L.length,`document`)}.`,q={config:t.config,resolveCwd:t.resolveCwd},J=await resolvePreviewUrlForTool(O.docName,q,w),Y=await resolvePreviewUrlForTool(D.docName,q,w),ee=j.summary&&typeof j.summary==`object`?j.summary:void 0,te=typeof ee?.hint==`string`?ee.hint:void 0,ne={ok:!0,renamed:F,rewrittenDocs:L,previewUrl:J?.url??null,...J?{previewUrlSource:J.source}:{},...Y?{previousPreviewUrl:Y.url}:{},...ee?{summary:ee}:{}},ae=[`Renamed ${B}. ${H}`];return te&&ae.push(te),textPlusStructured(ae.join(`
|
|
2854
|
-
`),ne)})}const DESCRIPTION$8=["[Requires: Hocuspocus server] Rename a folder through the managed rename flow at `POST /api/rename-path` (kind: folder).",`Atomically moves the folder and rewrites inbound wiki-links + supported internal inline Markdown links across every affected doc. One call replaces N rename_document calls.`,``,`**Parameters:**`,"- `fromFolder` — Current folder path relative to the content directory (no leading or trailing slash). Example: `articles` or `notes/drafts`.","- `toFolder` — New folder path relative to the content directory. Example: `essays` or `notes/published`. Parent directories are auto-created.",'- `summary` — Optional one-line user-outcome description (≤80 chars). Applied to every affected-doc contributor entry. If omitted, a default like "Renamed X → Y" is generated. Provide your own summary to explain the why. Avoid including secrets or PII — summaries are persisted to git history.',``,`**Errors:**`,"- 400 — case-only renames (e.g. `Articles` → `articles`) are not supported.","- 400 — destination folder is excluded by `.gitignore` / `.okignore` rules.",`- 404 — source folder does not exist.`,`- 409 — destination folder already exists or rename would collide.`].join(`
|
|
2855
|
-
`);function isValidFolderPath(e){return!(typeof e!=`string`||e.length===0||e.startsWith(`/`)||e.endsWith(`/`)||e.includes(`..`))}function parseRenameMappings(e){return Array.isArray(e)?e.flatMap(e=>{if(!e||typeof e!=`object`)return[];let{fromDocName:t,toDocName:S}=e;return typeof t==`string`&&typeof S==`string`?[{fromDocName:t,toDocName:S}]:[]}):[]}function parseRewrittenDocs(e){return Array.isArray(e)?e.flatMap(e=>{if(!e||typeof e!=`object`)return[];let{docName:t,rewrites:S}=e;return typeof t==`string`&&typeof S==`number`?[{docName:t,rewrites:S}]:[]}):[]}function register$8(e,t){e.registerTool(`rename_folder`,{description:DESCRIPTION$8,inputSchema:{fromFolder:string$2().describe(`Current folder path (relative, no trailing slash)`),toFolder:string$2().describe(`New folder path (relative, no trailing slash)`),summary:summaryArgSchema.describe(`Optional one-line user-outcome description (≤80 chars). Applied to every affected-doc contributor entry.`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);if(!isValidFolderPath(e.fromFolder))return textResult(`fromFolder must be a relative path with no leading/trailing slash`,!0);if(!isValidFolderPath(e.toFolder))return textResult(`toFolder must be a relative path with no leading/trailing slash`,!0);let D=t.identityRef?.current,O=await httpPost(E,`/api/rename-path`,{kind:`folder`,fromPath:e.fromFolder,toPath:e.toFolder,...e.summary===void 0?{}:{summary:e.summary},...D?{agentId:D.connectionId,agentName:D.displayName,clientName:D.clientInfo?.name,colorSeed:D.colorSeed}:{}});if(!O.ok){let e=O.error,t=parseRenameCollidingPairs(O.colliding),S={ok:!1,error:e,...t.length>0?{colliding:t}:{}};return textPlusStructured(`Error: ${e}`,S,!0)}let k=parseRenameMappings(O.renamed),j=parseRewrittenDocs(O.rewrittenDocs),F={config:t.config,resolveCwd:t.resolveCwd},L={},B;for(let{toDocName:e}of k){let t=await resolvePreviewUrlForTool(e,F,w);t&&(L[e]=t.url,B??=t.source)}let H=O.summary&&typeof O.summary==`object`?O.summary:void 0,q=typeof H?.hint==`string`?H.hint:void 0,J={ok:!0,renamed:k,rewrittenDocs:j,previewUrls:L,...B?{previewUrlSource:B}:{},...H?{summary:H}:{}},Y=[];return k.length===0?Y.push(`No managed docs under ${e.fromFolder}/ — nothing to rename. Empty folders are not tracked; create a doc inside the folder first.`):Y.push(`Renamed folder ${e.fromFolder}/ → ${e.toFolder}/ (${k.length} doc${k.length===1?``:`s`}, ${j.length} rewrite${j.length===1?``:`s`}).`),q&&Y.push(q),textPlusStructured(Y.join(`
|
|
2856
|
-
`),J)})}function buildBody(e,t){return`Conduct **evidence-driven research** on this topic and produce a provisional research article in the Open Knowledge content directory. This workflow mirrors the discipline of the \`eng:research\` skill, scoped to Open Knowledge's wiki-provisional layer.
|
|
2835
|
+
`}const DESCRIPTION$6=[`Returns a step-by-step plan to capture an external source (URL or local file) into the knowledge base as raw, verbatim reference material — no analysis. Does NOT fetch or write — you execute the plan.`,"Biases toward preserving raw binary files (PDF, image, audio, video) via the shell + `![[file.ext]]` embed, falling back to text extraction on shell-less hosts. The KB is closed-loop: cite the captured local doc, never a bare URL.",`Use when a source needs preserving before analysis — including URLs you fetched yourself to ground a KB claim.`].join(`
|
|
2836
|
+
`);function register$6(e,t){e.registerTool(`ingest`,{description:DESCRIPTION$6,inputSchema:{source:string$2().describe(`URL, file path, or identifier of the source to ingest`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},buildWorkflowHandler(`ingest`,t,`source`,buildBody$1))}const LINK_KINDS=[`backlinks`,`forward`,`dead`,`orphans`,`hubs`,`suggest`],DESCRIPTION$5=["[Requires: Hocuspocus server] Read the wiki-link graph. `kind` takes one value, or an array for a one-call audit — results merge into a single payload; any per-kind failure lands in an `errors` map.",``,"- `backlinks` / `forward` / `suggest` — operate on one page; require `docName`. `suggest` finds prose mentions of the page not yet wrapped in link syntax (each mention `offset` works with `edit_document`).","- `dead` — missing internal link targets corpus-wide; optional `sourceDocNames` filter (OR semantics).","- `orphans` — disconnected pages; optional `mode`: `incoming` | `outgoing` | `both`.","- `hubs` — most-linked pages; optional `limit` (default 20)."].join(`
|
|
2837
|
+
`);function register$5(e,t){e.registerTool(`links`,{description:DESCRIPTION$5,inputSchema:{kind:union([_enum(LINK_KINDS),array(_enum(LINK_KINDS)).min(1)]).describe(`Link-graph view(s) to return — one kind, or an array to fetch several in one call (e.g. ["dead","orphans","hubs"] for a graph audit).`),docName:string$2().optional().describe(`Target page docName. Required for kind=backlinks|forward|suggest.`),sourceDocNames:array(string$2()).optional().describe(`Referring source docs to narrow the audit with OR semantics. Used by kind=dead.`),mode:_enum(ORPHAN_MODES).optional().describe(`Filter which type of graph disconnection to surface. Used by kind=orphans.`),limit:number$1().int().positive().optional().describe(`Maximum number of hubs to return. Used by kind=hubs.`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=Array.isArray(e.kind)?[...new Set(e.kind)]:[e.kind],{resolve:O,ui:k}=await buildListResolver(t,w),j=await Promise.all(D.map(S=>runKind(S,e,E,w,t,O))),F={},L={};if(D.forEach((e,t)=>{let S=j[t];S.ok?Object.assign(F,S.data):L[e]=S.error}),Object.keys(F).length===0){let e=D.length===1?L[D[0]]:`All requested link kinds failed: ${JSON.stringify(L)}`;return textResult(e.startsWith(`Error`)?e:`Error: ${e}`,!0)}let B={...F,...Object.keys(L).length>0?{errors:L}:{},ui:k,cwd:w};return textPlusStructured(JSON.stringify(B,null,2),B)})}function runKind(e,t,S,w,E,D){switch(e){case`backlinks`:return runBacklinks(t,S,D);case`forward`:return runForwardLinks(t,S,D);case`dead`:return runDeadLinks(t,S,D);case`orphans`:return runOrphans(t,S,D);case`hubs`:return runHubs(t,S,D);case`suggest`:return runSuggest(t,S,w,E)}}async function runBacklinks(e,t,S){if(!e.docName)return{ok:!1,error:"kind=backlinks requires `docName`."};let w=normalizeDocName(e.docName);if(!w.ok)return{ok:!1,error:w.error};let E=await httpGet(t,`/api/backlinks?docName=${encodeURIComponent(w.docName)}`);if(!E.ok)return{ok:!1,error:String(E.error)};let{ok:D,...O}=E;return{ok:!0,data:{backlinks:(O.backlinks??[]).map(e=>{let t=typeof e.source==`string`?e.source:null,w=t?S(t):null;return{...e,previewUrl:w?.url??null,...w?{previewUrlSource:w.source}:{}}})}}}async function runForwardLinks(e,t,S){if(!e.docName)return{ok:!1,error:"kind=forward requires `docName`."};let w=normalizeDocName(e.docName);if(!w.ok)return{ok:!1,error:w.error};let E=await httpGet(t,`/api/forward-links?docName=${encodeURIComponent(w.docName)}`);if(!E.ok)return{ok:!1,error:String(E.error)};let{ok:D,...O}=E;return{ok:!0,data:{forwardLinks:(O.forwardLinks??[]).map(e=>{let t=e.kind===`doc`&&typeof e.docName==`string`?e.docName:null,w=t?S(t):null;return{...e,previewUrl:w?.url??null,...w?{previewUrlSource:w.source}:{}}})}}}async function runDeadLinks(e,t,S){let w=new URLSearchParams;for(let t of e.sourceDocNames??[]){let e=normalizeDocName(t);if(!e.ok)return{ok:!1,error:e.error};w.append(`sourceDocName`,e.docName)}let E=w.toString(),D=await httpGet(t,`/api/dead-links${E?`?${E}`:``}`);if(!D.ok)return{ok:!1,error:String(D.error)};let{ok:O,...k}=D;return{ok:!0,data:{deadLinks:(k.deadLinks??[]).map(e=>{let t=typeof e.target==`string`?e.target:null,w=t?S(t):null,E=(e.sources??[]).map(e=>{let t=typeof e.source==`string`?e.source:null,w=t?S(t):null;return{...e,previewUrl:w?.url??null,...w?{previewUrlSource:w.source}:{}}});return{...e,sources:E,previewUrl:w?.url??null,...w?{previewUrlSource:w.source}:{}}})}}}async function runOrphans(e,t,S){let w=await httpGet(t,`/api/orphans${e.mode?`?mode=${encodeURIComponent(e.mode)}`:``}`);if(!w.ok)return{ok:!1,error:String(w.error)};let{ok:E,...D}=w;return{ok:!0,data:{orphans:(D.orphans??[]).map(e=>{let t=typeof e.docName==`string`?e.docName:null,w=t?S(t):null;return{...e,previewUrl:w?.url??null,...w?{previewUrlSource:w.source}:{}}})}}}async function runHubs(e,t,S){let w=await httpGet(t,`/api/hubs${e.limit?`?limit=${encodeURIComponent(String(e.limit))}`:``}`);if(!w.ok)return{ok:!1,error:String(w.error)};let{ok:E,...D}=w;return{ok:!0,data:{hubs:(D.hubs??[]).map(e=>{let t=typeof e.docName==`string`?e.docName:null,w=t?S(t):null;return{...e,previewUrl:w?.url??null,...w?{previewUrlSource:w.source}:{}}})}}}async function runSuggest(e,t,S,w){if(!e.docName)return{ok:!1,error:"kind=suggest requires `docName`."};let E=normalizeDocName(e.docName);if(!E.ok)return{ok:!1,error:E.error};let D=await httpGet(t,`/api/suggest-links?docName=${encodeURIComponent(E.docName)}`);if(!D.ok)return{ok:!1,error:String(D.error)};let{ok:O,...k}=D,j=await resolvePreviewUrlForTool(E.docName,{config:w.config,resolveCwd:w.resolveCwd},S);return{ok:!0,data:{suggest:{...k,previewUrl:j?.url??null,...j?{previewUrlSource:j.source}:{}}}}}const DESCRIPTION$4=["[Requires: Hocuspocus server] Rename a doc or a folder through the managed rename flow at `POST /api/rename-path`. The tool probes the content directory to decide whether `from` is a doc or a folder, then sets `kind` (`file` vs `folder`) accordingly. Renaming rewrites inbound wiki-links plus supported internal inline Markdown links across affected docs.",``,`**Parameters:**`,"- `from` — Source path. For a doc, the docName (typically without extension; trailing `.md`/`.mdx` is stripped). For a folder, the folder path relative to the content directory with no leading/trailing slash (e.g. `notes/drafts`).","- `to` — Destination path. Same shape as `from`. For a folder rename, parent directories are auto-created.",'- `summary` — Optional one-line user-outcome description (≤80 chars). If omitted, defaults to "Renamed X → Y". Appears as a bullet in the timeline. Avoid secrets or PII — summaries persist to git history.',``,`**Output:**`,"- Doc rename — `{previewUrl, previousPreviewUrl?, renamed, rewrittenDocs, ...}`.","- Folder rename — `{previewUrls: Record<newDocName, url>, renamed, rewrittenDocs, ...}`.",``,`**Errors:**`,"- 400 — case-only renames; destination excluded by `.gitignore` / `.okignore`; invalid path shape.",`- 404 — source doc or folder does not exist.`,"- 409 — destination already exists; server returns a structured `colliding[]` list in this case."].join(`
|
|
2838
|
+
`);function parseRenameMappings(e){return Array.isArray(e)?e.flatMap(e=>{if(!e||typeof e!=`object`)return[];let{fromDocName:t,toDocName:S}=e;return typeof t==`string`&&typeof S==`string`?[{fromDocName:t,toDocName:S}]:[]}):[]}function parseRewrittenDocs(e){return Array.isArray(e)?e.flatMap(e=>{if(!e||typeof e!=`object`)return[];let{docName:t,rewrites:S}=e;return typeof t==`string`&&typeof S==`number`?[{docName:t,rewrites:S}]:[]}):[]}function isValidFolderPath(e){return!(typeof e!=`string`||e.length===0||e.startsWith(`/`)||e.endsWith(`/`)||e.includes(`..`))}function pluralize(e,t,S=`${t}s`){return e===1?t:S}function resolveRenameKind(e,t){let S=resolveWithinRoot(e,t);if(!S.ok)return null;let w=S.abs;if(existsSync(w))try{let e=statSync(w);if(e.isDirectory())return`folder`;if(e.isFile()&&(w.endsWith(`.md`)||w.endsWith(`.mdx`)))return`file`}catch(e){let t=e.code;if(t===`EACCES`||t===`EPERM`)return`file`}for(let e of[`.md`,`.mdx`])if(existsSync(`${w}${e}`))return`file`;return null}function register$4(e,t){e.registerTool(`rename`,{description:DESCRIPTION$4,inputSchema:{from:string$2().describe(`Current path. Doc: docName (typically extensionless). Folder: relative path with no leading/trailing slash.`),to:string$2().describe(`New path. Doc: docName (typically extensionless). Folder: relative path with no leading/trailing slash.`),summary:summaryArgSchema.describe(`Optional one-line user-outcome description (≤80 chars). Defaults to "Renamed X → Y" when omitted. Persisted to git history.`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,config:E,url:D}=S;if(!D)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let O=resolveRenameKind(join(w,E.content.dir),e.from);return O===null?textResult(`Error: \`${e.from}\` does not exist as a doc or folder under the content directory.`,!0):O===`file`?handleFileRename(e,D,w,t):handleFolderRename(e,D,w,t)})}async function handleFileRename(e,t,S,w){let E=normalizeDocName(e.from);if(!E.ok)return textResult(E.error,!0);let D=normalizeDocName(e.to);if(!D.ok)return textResult(D.error,!0);let O=w.identityRef?.current,k=await httpPost(t,`/api/rename-path`,{kind:`file`,fromPath:E.docName,toPath:D.docName,...e.summary===void 0?{}:{summary:e.summary},...O?{agentId:O.connectionId,agentName:O.displayName,clientName:O.clientInfo?.name,colorSeed:O.colorSeed}:{}});if(!k.ok){let e=k.error,t=parseRenameCollidingPairs(k.colliding),S={ok:!1,error:e,...t.length>0?{colliding:t}:{}};return textPlusStructured(`Error: ${e}`,S,!0)}let j=parseRenameMappings(k.renamed),F=parseRewrittenDocs(k.rewrittenDocs),L=j.map(({fromDocName:e,toDocName:t})=>`${e} -> ${t}`).join(`, `)||`${E.docName} -> ${D.docName}`,B=F.length===0?`No inbound links required updates.`:`Rewrote ${F.length} ${pluralize(F.length,`document`)}.`,H={config:w.config,resolveCwd:w.resolveCwd},q=await resolvePreviewUrlForTool(D.docName,H,S),J=await resolvePreviewUrlForTool(E.docName,H,S),Y=k.summary&&typeof k.summary==`object`?k.summary:void 0,ee=typeof Y?.hint==`string`?Y.hint:void 0,te={ok:!0,kind:`file`,renamed:j,rewrittenDocs:F,previewUrl:q?.url??null,...q?{previewUrlSource:q.source}:{},...J?{previousPreviewUrl:J.url}:{},...Y?{summary:Y}:{}},ne=[`Renamed ${L}. ${B}`];return ee&&ne.push(ee),textPlusStructured(ne.join(`
|
|
2839
|
+
`),te)}async function handleFolderRename(e,t,S,w){if(!isValidFolderPath(e.from))return textResult("Error: `from` must be a relative path with no leading/trailing slash.",!0);if(!isValidFolderPath(e.to))return textResult("Error: `to` must be a relative path with no leading/trailing slash.",!0);let E=w.identityRef?.current,D=await httpPost(t,`/api/rename-path`,{kind:`folder`,fromPath:e.from,toPath:e.to,...e.summary===void 0?{}:{summary:e.summary},...E?{agentId:E.connectionId,agentName:E.displayName,clientName:E.clientInfo?.name,colorSeed:E.colorSeed}:{}});if(!D.ok){let e=D.error,t=parseRenameCollidingPairs(D.colliding),S={ok:!1,error:e,...t.length>0?{colliding:t}:{}};return textPlusStructured(`Error: ${e}`,S,!0)}let O=parseRenameMappings(D.renamed),k=parseRewrittenDocs(D.rewrittenDocs),j={config:w.config,resolveCwd:w.resolveCwd},F={},L;for(let{toDocName:e}of O){let t=await resolvePreviewUrlForTool(e,j,S);t&&(F[e]=t.url,L??=t.source)}let B=D.summary&&typeof D.summary==`object`?D.summary:void 0,H=typeof B?.hint==`string`?B.hint:void 0,q={ok:!0,kind:`folder`,renamed:O,rewrittenDocs:k,previewUrls:F,...L?{previewUrlSource:L}:{},...B?{summary:B}:{}},J=[];return O.length===0?J.push(`No managed docs under ${e.from}/ — nothing to rename. Empty folders are not tracked; create a doc inside the folder first.`):J.push(`Renamed folder ${e.from}/ → ${e.to}/ (${O.length} doc${O.length===1?``:`s`}, ${k.length} rewrite${k.length===1?``:`s`}).`),H&&J.push(H),textPlusStructured(J.join(`
|
|
2840
|
+
`),q)}function buildBody(e,t){return`Conduct **evidence-driven research** on this topic and produce a provisional research article in the Open Knowledge content directory. This workflow mirrors the discipline of the \`eng:research\` skill, scoped to Open Knowledge's wiki-provisional layer.
|
|
2857
2841
|
|
|
2858
2842
|
Topic: ${e}
|
|
2859
2843
|
Content directory: \`${t}\` (from \`.ok/config.yml\`)
|
|
@@ -3161,7 +3145,7 @@ Run this checklist before marking complete:
|
|
|
3161
3145
|
- [ ] File exists at the chosen path under the content directory
|
|
3162
3146
|
- [ ] Frontmatter has \`title\`, \`description\`, \`status: provisional\`, \`date\`, and a \`sources:\` list
|
|
3163
3147
|
- [ ] \`exec("ls <dir>")\` lists the new file with frontmatter enrichment
|
|
3164
|
-
- [ ] \`
|
|
3148
|
+
- [ ] \`links({ kind: 'dead', sourceDocNames: ['<path-without-ext>'] })\` returns clean (or each redlink is explicitly justified as a forward-reference)
|
|
3165
3149
|
- [ ] Every factual claim in Findings cites a source inline
|
|
3166
3150
|
- [ ] Linked source files from Step 3 all exist (broken source links → \`ingest\` went wrong somewhere)
|
|
3167
3151
|
- [ ] At least 1–2 neighbor docs now link to this research (per Step 6's "After writing, update ..." rule)
|
|
@@ -3203,19 +3187,16 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
3203
3187
|
- **Don't skip the scoping gate in Supervised mode.** The user's rubric shapes everything downstream; you cannot recover a wrong-scope article cheaply.
|
|
3204
3188
|
- **Don't mix 1P codebase analysis into the article unless asked.** Findings drift from factual synthesis to opinion when you do.
|
|
3205
3189
|
- **Don't overwrite existing research silently.** If the topic was researched before, either iterate (Path C) or create a clearly-named successor (\`crdt-alternatives-2.md\`) and mark the old one as superseded.
|
|
3206
|
-
`}const DESCRIPTION$
|
|
3207
|
-
`);function register$
|
|
3208
|
-
`)
|
|
3209
|
-
`),{previewUrl:
|
|
3210
|
-
`);function register$
|
|
3211
|
-
`),
|
|
3212
|
-
`)}function
|
|
3213
|
-
`)
|
|
3214
|
-
`);function register$2(e,t){e.registerTool(`suggest_links`,{description:DESCRIPTION$2,inputSchema:{docName:string$2().describe(`Target page docName`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=normalizeDocName(e.docName);if(!D.ok)return textResult(D.error,!0);let O=await httpGet(E,`/api/suggest-links?docName=${encodeURIComponent(D.docName)}`);if(!O.ok)return textResult(`Error: ${O.error}`,!0);let{ok:k,...j}=O,F=await resolvePreviewUrlForTool(D.docName,{config:t.config,resolveCwd:t.resolveCwd},w);return textPlusStructured(JSON.stringify(j,null,2),{...j,previewUrl:F?.url??null,...F?{previewUrlSource:F.source}:{}})})}const DESCRIPTION$1=`${[`[Requires: Hocuspocus server] Write markdown content to a document via the CRDT layer.`,`Content is applied through Hocuspocus and propagated to all connected editors in real-time.`,``,'**Frontmatter.** The markdown payload may include a YAML frontmatter block (`---`-fenced). For 1-2 frontmatter keys, prefer `frontmatter_patch` (JSON Merge Patch — field-level CRDT, atomic, recommended). For full-document rewrites (≥3-5 keys changing, or body + frontmatter together), call this tool with `position: "replace"` and a payload that includes the new YAML block. `edit_document` rejects frontmatter-intersecting find/replace calls (HTTP 400).',``,'**Link liberally with standard markdown links.** Every noun-phrase that names another document in this knowledge base should be `[text](./relative/path.md)`. Backlinks are the primary navigation surface — underlinked documents become islands. Redlinks (links to pages that don\'t exist yet) are fine; they signal "this should exist." Wiki-link syntax `[[Page]]` is still parsed for legacy content but is no longer the recommended default — write new content with standard markdown links.',``,"**Templates.** When creating a new doc, pass `template: \"<name>\"` to instantiate from a folder-scoped template. The name resolves against `templates_available` for the doc's parent folder (leaf → root walk-up; check `list_documents({ dir, depth: 1 })` to see the menu). The template's body + frontmatter become the doc's starting content; folder cascade merges naturally at read time. Templates scoped to a descendant subfolder are rejected for parent-folder targets. **`template` and `markdown` are mutually exclusive** — pass exactly one. To start from the template body and then customize, instantiate via `template` first, then call `edit_document` to fill placeholders.",``,`**Parameters:**`,'- `docName` — Document name, typically without extension (e.g., "my-doc" or "notes/meeting"). A trailing `.md` or `.mdx` is stripped automatically. New documents are created as `.md` by default; to create a `.mdx` file, first place it on disk, then use this tool for edits.',"- `markdown` — Markdown content to write. Required unless `template` is set (mutually exclusive — pass exactly one).","- `template` (optional) — Template name resolved against the parent folder's `templates_available`. The template body becomes the new doc verbatim. Cannot be combined with `markdown`.",'- `position` — Where to insert: "append", "prepend", or "replace". When `template` is set, `position` is forced to "replace".','- `summary` — Optional one-line user-outcome description of this edit (≤80 chars). Appears as a bullet in the document timeline so readers can scan intent without opening every diff. Prefer outcome phrasing ("Fixed token-refresh race") over structural ("Added 3 lines"). Avoid including secrets or PII — summaries are persisted to git history.'].join(`
|
|
3215
|
-
`)
|
|
3216
|
-
`);if(!B&&!q&&!J&&!Y&&!ee)return textResult(ae);let oe={};return B&&(oe.previewUrl=B.url,oe.previewUrlSource=B.source),q&&(oe.warning=buildPreviewAttachWarning(B)),Y&&(oe.hints=Y),ee&&(oe.summary=ee),textPlusStructured(ae,oe)})}const DESCRIPTION=[`[Operates on disk; no running OK server required] Create or update a template.`,``,"Templates are markdown starter shapes that agents pick from when creating a new doc — `write_document({ template: <name> })` resolves the name against the folder cascade and instantiates the body + frontmatter.",``,'Templates live at `<folder>/.ok/templates/<name>.md`. The `folder` argument selects which project folder owns it (project-wide via `folder: ""`, or scoped to a subfolder).',``,"**`title` is required** in the frontmatter — it is the menu surface agents pick from. Missing or empty title returns `TEMPLATE_TITLE_REQUIRED`. `description` is recommended (soft warning when absent) — it disambiguates similarly-named templates.",``,"**Substitution allowlist.** The body MAY contain `{{date}}` (today, ISO-8601) and `{{user}}` (calling principal display name). Any other `{{...}}` token is rejected at write time with `TEMPLATE_UNKNOWN_VARIABLE`. Substitution happens at instantiation time (when `write_document({ template })` materializes the doc), not at template-write time — templates on disk show the raw `{{date}}` token.",``,`**Parameters:**`,'- `folder` — Project-root-relative folder (e.g. `"meetings"`, `"meetings/prep-notes"`). Empty / `.` means project root.',"- `name` — Template filename without `.md`. Letters, digits, `_`, `-` only.","- `body` — Markdown body. May use `{{date}}` / `{{user}}` substitution tokens. Other placeholder text in `{shape}` form (e.g. `{Meeting Title}`) is LITERAL — agents fill it in via subsequent `edit_document` calls.","- `frontmatter` — `{title (required), description?, tags?: string[]}` for the template menu."].join(`
|
|
3217
|
-
`),InputSchema={folder:string$2().describe("Project-root-relative folder. Empty / `.` means project root."),name:string$2().min(1).regex(/^[A-Za-z0-9_-]+$/,"Template name must use letters, digits, `_`, or `-` only (no slashes, dots, or spaces).").describe("Template filename without `.md` extension."),body:string$2().describe(`Markdown body for the template.`),frontmatter:object$1({title:string$2().min(1,"Template `title` is required — it is the menu surface agents pick from.").describe(`Required. The menu surface agents pick from. Empty / missing returns TEMPLATE_TITLE_REQUIRED.`),description:string$2().optional().describe(`Recommended. Disambiguates similarly-named templates. Soft warning when absent.`),tags:array(string$2()).optional().describe(`Optional. Concatenated with cascade tags at instantiation time.`)}).describe("Template menu metadata. `title` MUST be present (hard error if missing). `description` SHOULD be present (warning)."),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)},OutputSchema=outputSchemaWithText({result:union([object$1({ok:literal(!0),path:string$2(),created:boolean$1(),warnings:array(string$2())}),object$1({ok:literal(!1),error:object$1({code:string$2(),message:string$2()})})])});function register(e,t){e.registerTool(`write_template`,{description:DESCRIPTION,inputSchema:object$1(InputSchema).strict(),outputSchema:OutputSchema,annotations:{readOnlyHint:!1,idempotentHint:!0,destructiveHint:!1}},async e=>{let S=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);if(!S.ok)return{isError:!0,content:[{type:`text`,text:`Error: ${S.error}`}]};let{cwd:w}=S,E=applyTemplateWrite({projectDir:w,folder:e.folder,name:e.name,body:e.body,frontmatter:e.frontmatter});if(!E.ok)return{isError:!0,structuredContent:{result:E},content:[{type:`text`,text:`${E.error.code}: ${E.error.message}`}]};let D=[`${E.created?`Created`:`Updated`} template at ${E.path}`];if(E.warnings.length>0){D.push(``,`Warnings:`);for(let e of E.warnings)D.push(` - ${e}`)}return textPlusStructured(D.join(`
|
|
3218
|
-
`),{result:E})})}function registerAllTools(e,t){let S=t.logger,w=createLoggedServer(e,{logger:t.logger,identityRef:t.identityRef}),E=e=>async w=>{try{let E=await t.resolveCwd(w);return(getCurrentMcpLogger()??S)?.debug(`tool cwd resolved`,{tool:e,cwd:E,...w?{explicit:w}:{}}),E}catch(t){throw(getCurrentMcpLogger()??S)?.warn(`tool call failed`,{tool:e,error:t instanceof Error?t.message:String(t),...w?{explicit:w}:{}}),t}};register$23(w,{resolveCwd:E(`exec`),serverUrl:t.serverUrl,config:t.config}),register$12(w,{config:t.config,resolveCwd:E(`ingest`)}),register$7(w,{config:t.config,resolveCwd:E(`research`)}),register$28(w,{config:t.config,resolveCwd:E(`consolidate`)}),register$25(w,{config:t.config,resolveCwd:E(`discover`)}),register$10(w,{resolveCwd:E(`read_document`),config:t.config,serverUrl:t.serverUrl}),register$4(w,{resolveCwd:E(`search`),config:t.config,serverUrl:t.serverUrl}),register$13(w,{resolveCwd:E(`grep`),config:t.config,serverUrl:t.serverUrl}),register$2(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`suggest_links`)}),register$1(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`write_document`),identityRef:t.identityRef}),register$24(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`edit_document`),identityRef:t.identityRef}),register$27(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`delete_document`),identityRef:t.identityRef}),register$22(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`frontmatter_patch`),identityRef:t.identityRef}),register$9(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`rename_document`),identityRef:t.identityRef}),register$8(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`rename_folder`),identityRef:t.identityRef}),register$16(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`get_history`)}),register$5(w,t.config,t.serverUrl,E(`save_version`),t.identityRef),register$6(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`rollback_to_version`),identityRef:t.identityRef}),register$11(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`list_documents`)}),register$21(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`get_backlinks`)}),register$20(w,{resolveCwd:E(`get_components`),config:t.config}),register$17(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`get_forward_links`)}),register$14(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`get_orphans`)}),register$15(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`get_hubs`)}),register$18(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`get_dead_links`)}),register$19(w,{config:t.config,resolveCwd:E(`get_config`)}),register$3(w,{config:t.config,resolveCwd:E(`set_folder_rule`)}),register(w,{config:t.config,resolveCwd:E(`write_template`)}),register$26(w,{config:t.config,resolveCwd:E(`delete_template`)})}function firstHeader(e){return Array.isArray(e)?e[0]:e}function writePlain(e,t,S){e.writableEnded||(e.statusCode=t,e.setHeader(`Content-Type`,`text/plain; charset=utf-8`),e.end(S))}function createSessionServer(e,t,S){let w=e.config,E=new McpServer({name:MCP_SERVER_NAME,version:RUNTIME_VERSION},{instructions:buildInstructions(w.content)});installPrettyZodErrors(E);let D=S??randomUUID(),O={current:{connectionId:D,displayName:D,colorSeed:D}};E.server.oninitialized=()=>{let e=E.server.getClientVersion(),t=sanitizeClientName(e?.name,D);O.current={connectionId:D,clientInfo:e?{name:t,version:e.version}:void 0,displayName:t,colorSeed:t}};let k=e.projectDir??e.contentDir;return registerAllTools(E,{serverUrl:async()=>e.getServerUrl(),resolveCwd:async e=>{if(e===void 0)return k;let t=resolveWithinRoot(k,e);if(!t.ok)throw Error(`cwd "${e}" is not within the configured project root: ${t.reason}`);return t.abs},config:w,identityRef:O}),{server:E,transport:t}}function createMcpHttpHandler(e){let t=new Map,S=e.sessionTtlMs??1800*1e3,w=e.maxSessions??100;async function E(S,w){let E=t.get(S);if(!E)return;t.delete(S),E.ttlTimer!==void 0&&clearTimeout(E.ttlTimer);let D=await Promise.allSettled([E.server.close(),E.transport.close()]);for(let t of D)t.status===`rejected`&&e.log?.warn?.({err:t.reason,sessionId:S,reason:w},`MCP HTTP session close failed`);e.log?.info?.({sessionId:S,reason:w},`MCP HTTP session closed`)}function D(t,w){w.ttlTimer!==void 0&&clearTimeout(w.ttlTimer),w.ttlTimer=setTimeout(()=>{E(t,`ttl-expired`).catch(S=>{e.log?.warn?.({err:S,sessionId:t},`MCP HTTP session TTL cleanup failed`)})},S),w.ttlTimer.unref?.()}return{async handle(S,O){let k=firstHeader(S.headers[`mcp-session-id`]);if(k){let e=t.get(k);if(!e){writePlain(O,404,`MCP session not found`);return}D(k,e),await e.transport.handleRequest(S,O);return}if(S.method!==`POST`){writePlain(O,400,`Missing MCP session. Initialize with POST /mcp first.`);return}if(t.size>=w){e.log?.warn?.({activeSessions:t.size,maxSessions:w},`MCP HTTP session cap reached`),writePlain(O,503,`Too many active MCP sessions`);return}let j=firstHeader(S.headers[MCP_CONNECTION_ID_HEADER]),F=validateAgentId(j)??void 0;j!==void 0&&F===void 0&&e.log?.warn?.({headerLength:j.length},`MCP HTTP forwarded connectionId header failed validation; falling back to randomUUID`);let L=new StreamableHTTPServerTransport({sessionIdGenerator:()=>randomUUID(),enableJsonResponse:!0,onsessioninitialized:async S=>{try{let w=createSessionServer(e,L,F);await w.server.connect(L),t.set(S,w),D(S,w),e.log?.info?.({sessionId:S},`MCP HTTP session initialized`)}catch(w){throw t.delete(S),e.log?.error?.({err:w,sessionId:S},`MCP HTTP session initialization failed`),w}}});L.onerror=t=>{e.log?.warn?.({err:t},`MCP HTTP transport error`)},L.onclose=()=>{let t=L.sessionId;if(!t){e.log?.info?.({sessionId:t,reason:`transport-closed`},`MCP HTTP session closed`);return}E(t,`transport-closed`).catch(S=>{e.log?.warn?.({err:S,sessionId:t},`MCP HTTP transport-close cleanup failed`)})},await L.handleRequest(S,O)},async close(){let e=[...t.entries()];await Promise.allSettled(e.map(([e])=>E(e,`handler-close`)))}}}const DEFAULT_KEEPALIVE_GRACE_MS=1e4,MAX_COLLAB_MESSAGE_BYTES=1024*1024,MCP_CORS_HEADERS={"Access-Control-Allow-Methods":`GET, POST, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization, traceparent, tracestate, baggage, mcp-session-id, mcp-protocol-version`,"Access-Control-Max-Age":`86400`};function mountMcpAndApi(e){let{httpServer:t,hocuspocus:S,mcpHttpHandler:w,log:E,sessionManager:D,agentFocusBroadcaster:O,agentPresenceBroadcaster:k,contentAssetMiddleware:j,reactShellMiddleware:F}=e,L=e.keepaliveGraceMs??DEFAULT_KEEPALIVE_GRACE_MS,B=new import_websocket_server$1.default({noServer:!0,maxPayload:MAX_COLLAB_MESSAGE_BYTES});B.on(`error`,e=>{E.error({err:e},`WebSocketServer error`)});let H=new Map,q=new Set,J=!1;return t.on(`request`,(e,t)=>{let D=e.url?.split(`?`)[0];if(w!==void 0&&D===`/mcp`){let S=e.headers.origin,D=Array.isArray(e.headers[`mcp-session-id`])?e.headers[`mcp-session-id`][0]:e.headers[`mcp-session-id`];if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback access required.`,{handler:`mcp`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`mcp`});return}if(S!==void 0&&!isAllowedApiOrigin(S)){errorResponse(t,403,`urn:ok:error:invalid-origin`,`Origin not allowed.`,{handler:`mcp`});return}S!==void 0&&(t.setHeader(`Access-Control-Allow-Origin`,S),t.setHeader(`Vary`,`Origin`));for(let[e,S]of Object.entries(MCP_CORS_HEADERS))t.setHeader(e,S);if(e.method===`OPTIONS`){t.writeHead(204),t.end();return}w.handle(e,t).catch(e=>{E.error({err:e,sessionId:D},`Unhandled MCP HTTP error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp`,cause:e}):t.writableEnded||t.end()});return}if(D?.startsWith(`/api/`)){S.hooks(`onRequest`,{request:e,response:t}).then(()=>{t.writableEnded||t.headersSent||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`mcp-mount`,detail:`No handler for ${e.method??`GET`} ${D}`})}).catch(e=>{E.error({err:e},`Unhandled onRequest error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp-mount`,cause:e}):t.writableEnded||t.end()});return}let O=(e,t)=>{if(!(t.writableEnded||t.headersSent)){if(F!==void 0){try{F(e,t,()=>{t.writableEnded||t.headersSent||errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`No handler for ${D??`/`}`})})}catch(e){E.error({err:e},`Unhandled react-shell middleware error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp-mount`,cause:e}):t.writableEnded||t.end()}return}errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`No handler for ${D??`/`}`})}};if(j!==void 0){try{j(e,t,()=>O(e,t))}catch(e){E.error({err:e},`Unhandled content-asset middleware error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp-mount`,cause:e}):t.writableEnded||t.end()}return}if(F!==void 0){O(e,t);return}errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`The React UI is served by \`ok ui\` (run \`ok ui\` and check \`ui.lock.port\`). No handler for ${D??`/`}`})}),t.on(`upgrade`,(e,t,w)=>{if(e.url?.startsWith(`/collab/keepalive`)){if(!isLoopbackAddress(e.socket.remoteAddress)||!isAllowedWorkspaceHostHeader(e.headers.host)){t.destroy();return}t.on(`error`,e=>{handleCollabSocketError(e)||E.error({err:e},`MCP keepalive socket error`)}),B.handleUpgrade(e,t,w,t=>{let S=parseKeepaliveConnectionId(e.url);if(S){let e=H.get(S);e!==void 0&&(clearTimeout(e),H.delete(S),E.info({connectionId:S},`[keepalive] reconnect during grace — timer cancelled`))}if(S&&k){let t=parseKeepaliveIdentity(e.url);if(t)try{let e=iconFromClientName(t.clientName),w=AGENT_ICON_COLORS[e]??colorFromSeed(t.colorSeed);k.setPresence(toBroadcasterKey(S),{displayName:t.displayName,icon:e,color:w,currentDoc:`(connected)`,mode:`idle`,ts:Date.now()})}catch(e){E.error({err:e,connectionId:S},`[keepalive] presence bootstrap failed`)}}let w=setInterval(()=>{try{t.ping()}catch{}},3e4);w.unref?.();let j=S?setInterval(()=>{k?.bumpPresenceTs(toBroadcasterKey(S))},3e3):null;j?.unref?.(),t.on(`close`,()=>{if(clearInterval(w),j!==null&&clearInterval(j),!S)return;let e=setTimeout(()=>{if(H.delete(S),J)return;let e=(async()=>{E.info({connectionId:S},`[keepalive] grace expired — cleaning up sessions`);try{await D?.closeAllForAgent(S)}catch(e){E.error({err:e,connectionId:S},`[keepalive] closeAllForAgent failed`)}try{O?.clearFocus(S)}catch(e){E.error({err:e,connectionId:S},`[keepalive] clearFocus failed`)}try{k?.clearPresence(toBroadcasterKey(S))}catch(e){E.error({err:e,connectionId:S},`[keepalive] clearPresence failed`)}})();q.add(e),e.finally(()=>q.delete(e))},L);e.unref?.(),H.set(S,e),E.info({connectionId:S,graceMs:L},`[keepalive] disconnected — grace timer started`)}),t.on(`error`,e=>{handleCollabSocketError(e)||E.error({err:e},`MCP keepalive WS error`),t.terminate()})});return}if(e.url?.startsWith(`/collab`)){t.on(`error`,e=>{handleCollabSocketError(e)||E.error({err:e},`Upgrade socket error`)}),B.handleUpgrade(e,t,w,t=>{let w=S.handleConnection(t,e),D=!1;t.on(`message`,e=>{if(D)return;let S=e.byteLength;if(S>MAX_COLLAB_MESSAGE_BYTES){D=!0,incrementCollabMessageTooLarge(),E.warn({event:`collab-message-too-large`,bytes:S,limit:MAX_COLLAB_MESSAGE_BYTES},`Collab WebSocket message rejected before Yjs processing`),t.close(1009,`Message Too Big`);return}w.handleMessage(new Uint8Array(e))}),t.on(`close`,(e,t)=>{w.handleClose({code:e,reason:t.toString()})}),t.on(`error`,e=>{if(e.code===`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`){incrementCollabMessageTooLarge(),E.warn({event:`collab-message-too-large`,limit:MAX_COLLAB_MESSAGE_BYTES},`Collab WebSocket frame rejected by ws maxPayload before Yjs processing`),t.terminate();return}handleCollabSocketError(e)||E.error({err:e},`WebSocket error`),t.terminate()})});return}t.destroy()}),{wss:B,shutdown:async()=>{if(!J){J=!0;for(let e of H.values())clearTimeout(e);H.clear(),q.size>0&&await Promise.allSettled(q)}}}}function parseKeepaliveConnectionId(e){if(!e)return null;try{return validateAgentId(new URL(e,`http://localhost`).searchParams.get(`connectionId`))}catch{return null}}const MAX_KEEPALIVE_IDENTITY_LEN=256;function sanitizeIdentityField(e){return e===null||e.length===0||e.length>MAX_KEEPALIVE_IDENTITY_LEN||/[-]/.test(e)?null:e}function parseKeepaliveIdentity(e){if(!e)return null;try{let t=new URL(e,`http://localhost`),S=sanitizeIdentityField(t.searchParams.get(`displayName`)),w=sanitizeIdentityField(t.searchParams.get(`clientName`)),E=sanitizeIdentityField(t.searchParams.get(`colorSeed`));return S===null||w===null||E===null?null:{displayName:S,clientName:w,colorSeed:E}}catch{return null}}const MISSING_OK_CONFIG_MESSAGE=`Open Knowledge config not found at .ok/config.yml. Run ok init to scaffold OK in this directory.`;var MissingOkConfigError=class extends Error{kind;projectDir;constructor(e,t,S){super(MISSING_OK_CONFIG_MESSAGE,S),this.name=`MissingOkConfigError`,this.kind=e,this.projectDir=t}};async function startConfigFileWatcher(e,t){let S=getLogger(`config-file-watcher`),{watch:w}=await import(`./chokidar-CxU7f6JW.mjs`),E=dirname(e);try{tracedMkdirSync(E,{recursive:!0})}catch(e){e.code!==`EEXIST`&&S.warn({err:e,watchDir:E},`failed to create watch directory; watcher may be inert`)}let D=w(E,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:t=>t!==E&&t!==e});await new Promise(e=>{D.once(`ready`,e)});let O=null;try{O=readFileSync(e,`utf-8`)}catch{}let k=(w,E=!0)=>{if(w!==e)return;let D;try{D=readFileSync(w,`utf-8`)}catch(e){if(e.code===`ENOENT`){E&&S.debug({path:w},`config file disappeared between event and read; dropping`);return}S.warn({err:e,path:w},`config file read failed; dropping event`);return}if(D!==O){O=D;try{t(D)}catch(e){S.warn({err:e,path:w},`config file change handler threw`)}}},j=e=>k(e);D.on(`add`,j),D.on(`change`,j),D.on(`unlink`,t=>{t===e&&S.debug({path:t},`config file unlinked; Y.Text retained at current state`)}),D.on(`error`,t=>{S.warn({err:t,watchDir:E,absPath:e},`[config-file-watcher] chokidar error while watching ${e}`)});let F=0,L=setInterval(()=>{F++,k(e,!1),F>=20&&clearInterval(L)},500);L.unref?.();let B=!1;return async()=>{B||(B=!0,clearInterval(L),await D.close())}}async function startMultiPathConfigFileWatcher(e,t){if(e.length===0)throw Error(`startMultiPathConfigFileWatcher requires at least one absolute path`);let S=getLogger(`config-file-watcher`),{watch:w}=await import(`./chokidar-CxU7f6JW.mjs`),E=new Set(e),D=Array.from(new Set(Array.from(E,e=>dirname(e))));for(let e of D)try{tracedMkdirSync(e,{recursive:!0})}catch(t){t.code!==`EEXIST`&&S.warn({err:t,dir:e},`failed to create watch directory; watcher may be inert`)}let O=w(D,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:e=>!E.has(e)&&!D.includes(e)});await new Promise(e=>{O.once(`ready`,e)});let k=new Map;for(let e of E)try{k.set(e,readFileSync(e,`utf-8`))}catch{k.set(e,null)}let j=(e,w=!0)=>{if(!E.has(e))return;let D;try{D=readFileSync(e,`utf-8`)}catch(t){if(t.code===`ENOENT`){w&&S.debug({path:e},`config file disappeared between event and read; dropping`);return}S.warn({err:t,path:e},`config file read failed; dropping event`);return}if(D!==k.get(e)){k.set(e,D);try{t(e,D)}catch(t){S.warn({err:t,path:e},`config file change handler threw`)}}},F=e=>j(e);O.on(`add`,F),O.on(`change`,F),O.on(`unlink`,e=>{E.has(e)&&S.debug({path:e},`config file unlinked; downstream state retained`)}),O.on(`error`,e=>{S.warn({err:e,watchDirs:D,paths:Array.from(E)},`[config-file-watcher] chokidar error in multi-path watcher`)});let L=0,B=setInterval(()=>{L++;for(let e of E)j(e,!1);L>=20&&clearInterval(B)},500);B.unref?.();let H=!1;return async()=>{H||(H=!0,clearInterval(B),await O.close())}}const QUIET_WINDOW_MS=100,BATCH_TIMEOUT_MS=3e4,WATCHED_FILES=new Set([`HEAD`,`MERGE_HEAD`,`ORIG_HEAD`,`index.lock`]);function readHeadSha(e){try{let t=readFileSync(resolve(e,`HEAD`),`utf-8`).trim();if(t.startsWith(`ref: `)){let S=resolve(e,t.slice(5));try{return readFileSync(S,`utf-8`).trim()}catch{try{let S=readFileSync(resolve(e,`packed-refs`),`utf-8`),w=t.slice(5),E=S.split(`
|
|
3190
|
+
`}const DESCRIPTION$3=["Returns a step-by-step plan to research a topic: scan existing coverage, scope a rubric, capture sources via `ingest`, then write a provisional research article. Does NOT fetch or write — you execute the plan.","Provisional, not canonical — findings live here until decisions solidify (`consolidate` promotes them).",`Use when exploring a decision space, comparing alternatives, or synthesizing sources into structured analysis.`].join(`
|
|
3191
|
+
`);function register$3(e,t){e.registerTool(`research`,{description:DESCRIPTION$3,inputSchema:{topic:string$2().describe(`The topic, question, or anchor URL to research`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},buildWorkflowHandler(`research`,t,`topic`,buildBody))}const DESCRIPTION$2=["[Requires: Hocuspocus server] Ranked page retrieval for a query (title boost + body BM25 + recency — the cmd-K engine). For literal search across every line, use `exec` (`grep`) instead.",``,"Returns scored page (and folder, with `omnibar` intent) hits, each with a body snippet. `exec`-grep covers every occurrence and needs no server.",``,`**Parameters:**`,"- `query` — Free-form; tokenized across title, name, path segments, and (with `full_text`) body.","- `intent` (optional) — `omnibar` searches title/path/folders only (fast); `full_text` includes body. Default `full_text`.","- `scopes` (optional) — Result scope: `page` | `folder` | `content`. Defaults derive from `intent`.","- `limit` (optional) — Max rows; default 20, max 100.",``,'If the server is down, the tool returns a recovery hint — use `exec("grep ...")` as the server-free fallback.'].join(`
|
|
3192
|
+
`),InputSchema={query:string$2().describe(`Search query — title, path, or body terms.`),intent:_enum([`omnibar`,`full_text`]).optional().describe(`'omnibar' for title/path/folder only (fast); 'full_text' includes body content. Default 'full_text'.`),scopes:array(_enum([`page`,`folder`,`content`])).optional().describe(`Override the default scope set. Members: 'page', 'folder', 'content'. Defaults derive from intent.`),limit:number$1().int().min(1).max(100).optional().describe(`Max rows; default 20, max 100.`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)},SearchResultRowSchema=object$1({kind:_enum([`page`,`folder`]),path:string$2(),docName:string$2(),title:string$2().nullable(),score:number$1(),signals:object$1({lexical:number$1(),fullText:number$1(),recency:number$1()}),snippet:string$2().optional(),previewUrl:string$2().nullable(),previewUrlSource:_enum(PREVIEW_URL_SOURCES).optional()}),OutputSchema=outputSchemaWithText({cwd:string$2(),query:string$2(),intent:string$2(),resultCount:number$1().int(),results:array(SearchResultRowSchema),elapsedMs:number$1().nullable(),ui:object$1({baseUrl:string$2().nullable(),port:number$1().nullable()})});function isSearchKind(e){return e===`page`||e===`folder`}function normalizeSignals(e){return{lexical:typeof e?.lexical==`number`?e.lexical:0,fullText:typeof e?.fullText==`number`?e.fullText:0,recency:typeof e?.recency==`number`?e.recency:0}}function formatResultsBlock(e){if(e.length===0)return``;let t=[];for(let S of e){let e=S.title?.trim()||S.path;t.push(`### ${e} (${S.path})`),t.push(`Score ${S.score.toFixed(2)} — kind: ${S.kind}`),S.snippet&&t.push(S.snippet),t.push(``)}return t.join(`
|
|
3193
|
+
`)}function register$2(e,t){e.registerTool(`search`,{description:DESCRIPTION$2,inputSchema:InputSchema,outputSchema:OutputSchema,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0}},async e=>{try{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,config:E,url:D}=S;if(!D)return textResult(`${HOCUSPOCUS_NOT_RUNNING_ERROR}\nFor server-free literal-string search, use \`exec("grep ...")\` instead — it walks the filesystem and does not need Hocuspocus.`,!0);let O=e.intent??`full_text`,k=e.limit??20,j={query:e.query,intent:O,limit:k};e.scopes&&(j.scopes=e.scopes);let F=await httpPost(D,`/api/search`,j);if(!F.ok)return textResult(`Error: ${F.error}`,!0);let{resolve:L,ui:B}=await buildListResolver({config:E,resolveCwd:async()=>w},w),H=(F.results??[]).flatMap(e=>{if(!isSearchKind(e.kind)||typeof e.path!=`string`)return[];let t=docNameFromPath(e.path),S=L(t);return[{kind:e.kind,path:e.path,docName:t,title:e.title??null,score:typeof e.score==`number`?e.score:0,signals:normalizeSignals(e.signals),...e.snippet?{snippet:e.snippet}:{},previewUrl:S?.url??null,...S?{previewUrlSource:S.source}:{}}]}),q={cwd:w,query:e.query,intent:O,resultCount:H.length,results:H,elapsedMs:typeof F.elapsedMs==`number`?F.elapsedMs:null,ui:B},J=`## Search results for "${e.query}" (${H.length} hit${H.length===1?``:`s`}, intent: ${O})`;return textPlusStructured(H.length===0?`No matches for "${e.query}".`:`${J}\n\n${formatResultsBlock(H)}`,q)}catch(e){return textResult(`Error: ${e instanceof Error?e.message:String(e)}`,!0)}})}const ACTIONS=[`save`,`rollback`],DESCRIPTION$1=["[Requires: Hocuspocus server] Project version management. Dispatches on `action`:",``,'- `action: "save"` — Project-wide checkpoint of every document. No `docName`. Returns `{checkpointRef, previewUrl: null}`. Find checkpoints later via `get_history`.','- `action: "rollback"` — Restore one document to a historical version via the CRDT layer (append-only — creates a new version with the old content; all connected editors see the change in real-time). Requires `docName` and `commitSha`. Find `commitSha` via `get_history`.',``,`**Parameters:**`,"- `action` — `save` | `rollback`.","- `docName` — Required for `rollback`. Document name, typically without extension; trailing `.md`/`.mdx` is stripped.","- `commitSha` — Required for `rollback`. 40-character SHA from the shadow-repo timeline.",'- `summary` — Optional rollback summary (≤80 chars). If omitted, defaults to "Restored to <sha-short>". Avoid secrets or PII — summaries persist to git history.'].join(`
|
|
3194
|
+
`);function register$1(e,t){e.registerTool(`version`,{description:DESCRIPTION$1,inputSchema:{action:_enum(ACTIONS).describe(`Which version action to perform.`),docName:string$2().optional().describe(`Document name. Required for action=rollback.`),commitSha:string$2().length(40).regex(/^[0-9a-f]+$/i).optional().describe(`40-character commit SHA from the shadow-repo timeline. Required for action=rollback. Find via get_history.`),summary:summaryArgSchema.describe(`Optional rollback summary (≤80 chars). Defaults to "Restored to <sha-short>". Appears as a bullet in the timeline.`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);switch(e.action){case`save`:return handleSave(E,t);case`rollback`:return handleRollback(e,E,w,t);default:return textResult(`Error: unknown version action.`,!0)}})}async function handleSave(e,t){let S=t.identityRef?.current,w=await httpPost(e,`/api/save-version`,S?{writers:[{id:`agent-${S.connectionId}`,name:S.displayName,email:`agent-${S.connectionId}@openknowledge.local`}]}:{});return w.ok?textPlusStructured(`Checkpoint saved. Checkpoint ref: ${w.checkpointRef}`,{checkpointRef:w.checkpointRef,previewUrl:null}):textResult(`Error: ${w.error}`,!0)}async function handleRollback(e,t,S,w){if(!e.docName)return textResult("Error: action=rollback requires `docName`.",!0);if(!e.commitSha)return textResult("Error: action=rollback requires `commitSha`.",!0);let E=normalizeDocName(e.docName);if(!E.ok)return textResult(E.error,!0);let D=E.docName,O=await httpGet(t,`/api/history/${e.commitSha}?docName=${encodeURIComponent(D)}`);if(!O.ok)return textResult(`Error: ${O.error??`Version not found`}`,!0);let k=w.identityRef?.current,j=await httpPost(t,`/api/rollback`,{docName:D,commitSha:e.commitSha,...e.summary===void 0?{}:{summary:e.summary},...k?{agentId:k.connectionId,agentName:k.displayName,clientName:k.clientInfo?.name,colorSeed:k.colorSeed}:{}});if(!j.ok)return textResult(`Error: ${j.error}`,!0);let F=j.summary&&typeof j.summary==`object`?j.summary:void 0,L=typeof F?.hint==`string`?F.hint:void 0,B=typeof O.author==`string`?O.author:void 0,H=typeof O.timestamp==`string`?O.timestamp:void 0,q=B&&H?` (${B}, ${H})`:``,J=[`Restored "${D}" to version ${e.commitSha.slice(0,8)}${q}. The change has been applied to all connected editors.`];L&&J.push(L);let Y=await resolvePreviewUrlForTool(D,{config:w.config,resolveCwd:w.resolveCwd},S);return textPlusStructured(J.join(`
|
|
3195
|
+
`),{previewUrl:Y?.url??null,...Y?{previewUrlSource:Y.source}:{},...F?{summary:F}:{}})}const POSITIONS=[`append`,`prepend`,`replace`],DESCRIPTION=`${[`[Requires: Hocuspocus server] Write markdown to a document via the CRDT layer. Content propagates to all connected editors in real-time.`,``,'Frontmatter changes: 1-2 keys → prefer `edit_frontmatter` (field-level CRDT, atomic). Full rewrite (≥3-5 keys or body + frontmatter together) → this tool with `position: "replace"` and the full YAML block in the payload.',``,'Templates: `template: "<name>"` resolves against the parent folder\'s `templates_available` (see `exec("ls <folder>/")`) and becomes the new doc verbatim. `template` and `markdown` are mutually exclusive. With `template` set, `position` is forced to `"replace"`.',``,"To create several docs in one call (scaffolding a pack, seeding dossiers), pass `docs: [{docName, markdown|template, position, summary?}, ...]` instead of the single-doc fields. Docs write in order; the response reports each.",``,`**Parameters:**`,"- `docName` — A single document, extension-less (`notes/meeting`). Trailing `.md`/`.mdx` is stripped. New docs default to `.md`.","- `docs` — Batch form: array of `{docName, markdown?|template?, position, summary?}`. Mutually exclusive with the single-doc fields.","- `markdown` — Markdown payload. Required unless `template` is set.","- `template` — Template name. Mutually exclusive with `markdown`.","- `position` — `append` | `prepend` | `replace`. Forced to `replace` with `template`.","- `summary` — Optional one-line user-outcome (≤80 chars). Avoid secrets or PII — persisted to git history."].join(`
|
|
3196
|
+
`)}\n${renderInventoryFooter()}`;async function writeOneDoc(e,t,S,w){let E=normalizeDocName(e.docName);if(!E.ok)return{docName:e.docName,ok:!1,error:E.error};let D=E.docName,O=w.identityRef?.current;if(e.template===void 0&&e.markdown===void 0)return{docName:D,ok:!1,error:"either `markdown` or `template` must be provided — omitting both would write empty content."};if(e.template!==void 0&&e.markdown!==void 0)return{docName:D,ok:!1,error:"TEMPLATE_AND_MARKDOWN_BOTH_SET — `template` and `markdown` are mutually exclusive. Pass one; fill placeholders via subsequent `edit_document` calls."};let k=e.markdown??``,j=e.position;if(e.template!==void 0){let S=parentFolderOf(D),w=resolveTemplatesAvailable(t,S,{depth:1}),E=w.find(t=>t.name===e.template);if(!E)return{docName:D,ok:!1,error:`template "${e.template}" not found for folder "${S||`.`}". Available: ${w.length===0?`(none)`:w.map(e=>`${e.name} [${e.scope}]`).join(`, `)}. Templates are resolved by walk-up; check the parent folder's exec listing to see the menu.`};let F;try{F=readFileSync(resolve(t,E.path),`utf-8`)}catch(e){return{docName:D,ok:!1,error:`failed to read template at ${E.path}: ${e.message}`}}k=applySubstitution(F,{date:todayIsoUtc(),user:O?.displayName??``}),j=`replace`}let F=await httpPost(S,`/api/agent-write-md`,{docName:D,markdown:k,position:j,...e.summary===void 0?{}:{summary:e.summary},...O?{agentId:O.connectionId,agentName:O.displayName,clientName:O.clientInfo?.name,colorSeed:O.colorSeed}:{}});return F.ok?{docName:D,ok:!0,position:j,...e.template===void 0?{}:{fromTemplate:e.template},raw:F}:{docName:D,ok:!1,error:String(F.error)}}function register(e,t){let S={docName:string$2().describe(`Document name to write to`),markdown:string$2().optional().describe("Markdown content to write. Optional when `template` is set."),template:string$2().min(1).optional().describe("Template name resolved against the parent folder's templates_available (leaf → root walk-up; closest-wins). Inspect the menu with an `exec` listing of the folder."),position:_enum(POSITIONS).describe(`Where to insert the content`),summary:summaryArgSchema};e.registerTool(`write_document`,{description:DESCRIPTION,inputSchema:{docName:string$2().optional().describe(`A single document to write to.`),markdown:string$2().optional().describe("Markdown content. Optional when `template` is set."),template:string$2().min(1).optional().describe("Template name resolved against the parent folder's templates_available (leaf → root walk-up; closest-wins). Inspect the menu with an `exec` listing of the folder."),position:_enum(POSITIONS).optional().describe(`Where to insert the content. Required for a single write.`),summary:summaryArgSchema,docs:array(object$1(S)).min(1).optional().describe(`Batch: documents to write in one call. Mutually exclusive with the single-doc fields.`),cwd:string$2().optional().describe(ROUTED_CWD_DESCRIPTION)}},async e=>{let S=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{cwd:w,url:E}=S;if(!E)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=resolveLockDir(w);if(e.docs!==void 0){if(e.docName!==void 0||e.markdown!==void 0||e.template!==void 0||e.position!==void 0||e.summary!==void 0)return textResult("Error: `docs` is the batch form — do not also pass top-level `docName` / `markdown` / `template` / `position` / `summary` (each `docs[]` entry carries its own).",!0);let S=[];for(let D of e.docs)S.push(await writeOneDoc(D,w,E,t));let O=S.map(e=>{if(!e.ok)return{docName:e.docName,ok:!1,error:e.error};let t=resolvePreviewUrl(e.docName,{lockDir:D});return{docName:e.docName,ok:!0,position:e.position,...t?{previewUrl:t.url}:{}}}),k=O.filter(e=>e.ok).length,j=k===O.length,F=O.map(e=>e.ok?`Wrote ${e.docName} (${e.position}).`:`Failed ${e.docName}: ${e.error}`),L=`${k}/${O.length} written.\n${F.join(`
|
|
3197
|
+
`)}`,B={ok:j,documents:O},H=S.find(e=>e.ok);return H&&H.raw.systemSubscriberCount===0&&(B.warning=buildPreviewAttachWarning(resolvePreviewUrl(H.docName,{lockDir:D}))),textPlusStructured(L,B,!j)}if(e.docName===void 0)return textResult("Error: provide `docName` (single) or `docs` (batch).",!0);if(e.position===void 0)return textResult("Error: `position` is required (`append` | `prepend` | `replace`).",!0);let O=await writeOneDoc({docName:e.docName,markdown:e.markdown,template:e.template,position:e.position,summary:e.summary},w,E,t);if(!O.ok)return textResult(`Error: ${O.error}`,!0);let k=O.raw,j=resolvePreviewUrl(O.docName,{lockDir:D}),F=typeof k.subscriberCount==`number`?k.subscriberCount:void 0,L=(typeof k.systemSubscriberCount==`number`?k.systemSubscriberCount:void 0)===0,B=F===0,H=Array.isArray(k.hints)?k.hints:void 0,q=k.summary&&typeof k.summary==`object`?k.summary:void 0,J=typeof q?.hint==`string`?q.hint:void 0,Y=[O.fromTemplate===void 0?`Written successfully (${O.position}).`:`Written successfully (instantiated from template "${O.fromTemplate}").`];if(j&&Y.push(`Preview: ${j.url}`),L&&Y.push(j?`Open ${j.url} in your preview browser.`:START_UI_TEXT_HINT),J&&Y.push(J),H)for(let e of H)e.message&&Y.push(e.message);let ee=Y.join(`
|
|
3198
|
+
`);if(!j&&!L&&!B&&!H&&!q)return textResult(ee);let te={};return j&&(te.previewUrl=j.url,te.previewUrlSource=j.source),L&&(te.warning=buildPreviewAttachWarning(j)),H&&(te.hints=H),q&&(te.summary=q),textPlusStructured(ee,te)})}function registerAllTools(e,t){let S=t.logger,w=createLoggedServer(e,{logger:t.logger,identityRef:t.identityRef}),E=e=>async w=>{try{let E=await t.resolveCwd(w);return(getCurrentMcpLogger()??S)?.debug(`tool cwd resolved`,{tool:e,cwd:E,...w?{explicit:w}:{}}),E}catch(t){throw(getCurrentMcpLogger()??S)?.warn(`tool call failed`,{tool:e,error:t instanceof Error?t.message:String(t),...w?{explicit:w}:{}}),t}};register$11(w,{resolveCwd:E(`exec`),serverUrl:t.serverUrl,config:t.config}),register$6(w,{config:t.config,resolveCwd:E(`ingest`)}),register$3(w,{config:t.config,resolveCwd:E(`research`)}),register$16(w,{config:t.config,resolveCwd:E(`consolidate`)}),register$14(w,{config:t.config,resolveCwd:E(`discover`)}),register$2(w,{resolveCwd:E(`search`),config:t.config,serverUrl:t.serverUrl}),register$5(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`links`)}),register(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`write_document`),identityRef:t.identityRef}),register$13(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`edit_document`),identityRef:t.identityRef}),register$15(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`delete_document`),identityRef:t.identityRef}),register$12(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`edit_frontmatter`),identityRef:t.identityRef}),register$4(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`rename`),identityRef:t.identityRef}),register$7(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`get_history`)}),register$1(w,{serverUrl:t.serverUrl,config:t.config,resolveCwd:E(`version`),identityRef:t.identityRef}),register$9(w,{resolveCwd:E(`get_components`),config:t.config}),register$8(w,{config:t.config,resolveCwd:E(`get_config`)}),register$10(w,{config:t.config,resolveCwd:E(`folder_config`)})}function firstHeader(e){return Array.isArray(e)?e[0]:e}function writePlain(e,t,S){e.writableEnded||(e.statusCode=t,e.setHeader(`Content-Type`,`text/plain; charset=utf-8`),e.end(S))}function createSessionServer(e,t,S){let w=e.config,E=new McpServer({name:MCP_SERVER_NAME,version:RUNTIME_VERSION},{instructions:buildInstructions(w.content)});installPrettyZodErrors(E);let D=S??randomUUID(),O={current:{connectionId:D,displayName:D,colorSeed:D}};E.server.oninitialized=()=>{let e=E.server.getClientVersion(),t=sanitizeClientName(e?.name,D);O.current={connectionId:D,clientInfo:e?{name:t,version:e.version}:void 0,displayName:t,colorSeed:t}};let k=e.projectDir??e.contentDir;return registerAllTools(E,{serverUrl:async()=>e.getServerUrl(),resolveCwd:async e=>{if(e===void 0)return k;let t=resolveWithinRoot(k,e);if(!t.ok)throw Error(`cwd "${e}" is not within the configured project root: ${t.reason}`);return t.abs},config:w,identityRef:O}),{server:E,transport:t}}function createMcpHttpHandler(e){let t=new Map,S=e.sessionTtlMs??1800*1e3,w=e.maxSessions??100;async function E(S,w){let E=t.get(S);if(!E)return;t.delete(S),E.ttlTimer!==void 0&&clearTimeout(E.ttlTimer);let D=await Promise.allSettled([E.server.close(),E.transport.close()]);for(let t of D)t.status===`rejected`&&e.log?.warn?.({err:t.reason,sessionId:S,reason:w},`MCP HTTP session close failed`);e.log?.info?.({sessionId:S,reason:w},`MCP HTTP session closed`)}function D(t,w){w.ttlTimer!==void 0&&clearTimeout(w.ttlTimer),w.ttlTimer=setTimeout(()=>{E(t,`ttl-expired`).catch(S=>{e.log?.warn?.({err:S,sessionId:t},`MCP HTTP session TTL cleanup failed`)})},S),w.ttlTimer.unref?.()}return{async handle(S,O){let k=firstHeader(S.headers[`mcp-session-id`]);if(k){let e=t.get(k);if(!e){writePlain(O,404,`MCP session not found`);return}D(k,e),await e.transport.handleRequest(S,O);return}if(S.method!==`POST`){writePlain(O,400,`Missing MCP session. Initialize with POST /mcp first.`);return}if(t.size>=w){e.log?.warn?.({activeSessions:t.size,maxSessions:w},`MCP HTTP session cap reached`),writePlain(O,503,`Too many active MCP sessions`);return}let j=firstHeader(S.headers[MCP_CONNECTION_ID_HEADER]),F=validateAgentId(j)??void 0;j!==void 0&&F===void 0&&e.log?.warn?.({headerLength:j.length},`MCP HTTP forwarded connectionId header failed validation; falling back to randomUUID`);let L=new StreamableHTTPServerTransport({sessionIdGenerator:()=>randomUUID(),enableJsonResponse:!0,onsessioninitialized:async S=>{try{let w=createSessionServer(e,L,F);await w.server.connect(L),t.set(S,w),D(S,w),e.log?.info?.({sessionId:S},`MCP HTTP session initialized`)}catch(w){throw t.delete(S),e.log?.error?.({err:w,sessionId:S},`MCP HTTP session initialization failed`),w}}});L.onerror=t=>{e.log?.warn?.({err:t},`MCP HTTP transport error`)},L.onclose=()=>{let t=L.sessionId;if(!t){e.log?.info?.({sessionId:t,reason:`transport-closed`},`MCP HTTP session closed`);return}E(t,`transport-closed`).catch(S=>{e.log?.warn?.({err:S,sessionId:t},`MCP HTTP transport-close cleanup failed`)})},await L.handleRequest(S,O)},async close(){let e=[...t.entries()];await Promise.allSettled(e.map(([e])=>E(e,`handler-close`)))}}}const DEFAULT_KEEPALIVE_GRACE_MS=1e4,MAX_COLLAB_MESSAGE_BYTES=1024*1024,MCP_CORS_HEADERS={"Access-Control-Allow-Methods":`GET, POST, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization, traceparent, tracestate, baggage, mcp-session-id, mcp-protocol-version`,"Access-Control-Max-Age":`86400`};function mountMcpAndApi(e){let{httpServer:t,hocuspocus:S,mcpHttpHandler:w,log:E,sessionManager:D,agentFocusBroadcaster:O,agentPresenceBroadcaster:k,contentAssetMiddleware:j,reactShellMiddleware:F}=e,L=e.keepaliveGraceMs??DEFAULT_KEEPALIVE_GRACE_MS,B=new import_websocket_server$1.default({noServer:!0,maxPayload:MAX_COLLAB_MESSAGE_BYTES});B.on(`error`,e=>{E.error({err:e},`WebSocketServer error`)});let H=new Map,q=new Set,J=!1;return t.on(`request`,(e,t)=>{let D=e.url?.split(`?`)[0];if(w!==void 0&&D===`/mcp`){let S=e.headers.origin,D=Array.isArray(e.headers[`mcp-session-id`])?e.headers[`mcp-session-id`][0]:e.headers[`mcp-session-id`];if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback access required.`,{handler:`mcp`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`mcp`});return}if(S!==void 0&&!isAllowedApiOrigin(S)){errorResponse(t,403,`urn:ok:error:invalid-origin`,`Origin not allowed.`,{handler:`mcp`});return}S!==void 0&&(t.setHeader(`Access-Control-Allow-Origin`,S),t.setHeader(`Vary`,`Origin`));for(let[e,S]of Object.entries(MCP_CORS_HEADERS))t.setHeader(e,S);if(e.method===`OPTIONS`){t.writeHead(204),t.end();return}w.handle(e,t).catch(e=>{E.error({err:e,sessionId:D},`Unhandled MCP HTTP error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp`,cause:e}):t.writableEnded||t.end()});return}if(D?.startsWith(`/api/`)){S.hooks(`onRequest`,{request:e,response:t}).then(()=>{t.writableEnded||t.headersSent||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`mcp-mount`,detail:`No handler for ${e.method??`GET`} ${D}`})}).catch(e=>{E.error({err:e},`Unhandled onRequest error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp-mount`,cause:e}):t.writableEnded||t.end()});return}let O=(e,t)=>{if(!(t.writableEnded||t.headersSent)){if(F!==void 0){try{F(e,t,()=>{t.writableEnded||t.headersSent||errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`No handler for ${D??`/`}`})})}catch(e){E.error({err:e},`Unhandled react-shell middleware error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp-mount`,cause:e}):t.writableEnded||t.end()}return}errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`No handler for ${D??`/`}`})}};if(j!==void 0){try{j(e,t,()=>O(e,t))}catch(e){E.error({err:e},`Unhandled content-asset middleware error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp-mount`,cause:e}):t.writableEnded||t.end()}return}if(F!==void 0){O(e,t);return}errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`The React UI is served by \`ok ui\` (run \`ok ui\` and check \`ui.lock.port\`). No handler for ${D??`/`}`})}),t.on(`upgrade`,(e,t,w)=>{if(e.url?.startsWith(`/collab/keepalive`)){if(!isLoopbackAddress(e.socket.remoteAddress)||!isAllowedWorkspaceHostHeader(e.headers.host)){t.destroy();return}t.on(`error`,e=>{handleCollabSocketError(e)||E.error({err:e},`MCP keepalive socket error`)}),B.handleUpgrade(e,t,w,t=>{let S=parseKeepaliveConnectionId(e.url);if(S){let e=H.get(S);e!==void 0&&(clearTimeout(e),H.delete(S),E.info({connectionId:S},`[keepalive] reconnect during grace — timer cancelled`))}if(S&&k){let t=parseKeepaliveIdentity(e.url);if(t)try{let e=iconFromClientName(t.clientName),w=AGENT_ICON_COLORS[e]??colorFromSeed(t.colorSeed);k.setPresence(toBroadcasterKey(S),{displayName:t.displayName,icon:e,color:w,currentDoc:`(connected)`,mode:`idle`,ts:Date.now()})}catch(e){E.error({err:e,connectionId:S},`[keepalive] presence bootstrap failed`)}}let w=setInterval(()=>{try{t.ping()}catch{}},3e4);w.unref?.();let j=S?setInterval(()=>{k?.bumpPresenceTs(toBroadcasterKey(S))},3e3):null;j?.unref?.(),t.on(`close`,()=>{if(clearInterval(w),j!==null&&clearInterval(j),!S)return;let e=setTimeout(()=>{if(H.delete(S),J)return;let e=(async()=>{E.info({connectionId:S},`[keepalive] grace expired — cleaning up sessions`);try{await D?.closeAllForAgent(S)}catch(e){E.error({err:e,connectionId:S},`[keepalive] closeAllForAgent failed`)}try{O?.clearFocus(S)}catch(e){E.error({err:e,connectionId:S},`[keepalive] clearFocus failed`)}try{k?.clearPresence(toBroadcasterKey(S))}catch(e){E.error({err:e,connectionId:S},`[keepalive] clearPresence failed`)}})();q.add(e),e.finally(()=>q.delete(e))},L);e.unref?.(),H.set(S,e),E.info({connectionId:S,graceMs:L},`[keepalive] disconnected — grace timer started`)}),t.on(`error`,e=>{handleCollabSocketError(e)||E.error({err:e},`MCP keepalive WS error`),t.terminate()})});return}if(e.url?.startsWith(`/collab`)){t.on(`error`,e=>{handleCollabSocketError(e)||E.error({err:e},`Upgrade socket error`)}),B.handleUpgrade(e,t,w,t=>{let w=S.handleConnection(t,e),D=!1;t.on(`message`,e=>{if(D)return;let S=e.byteLength;if(S>MAX_COLLAB_MESSAGE_BYTES){D=!0,incrementCollabMessageTooLarge(),E.warn({event:`collab-message-too-large`,bytes:S,limit:MAX_COLLAB_MESSAGE_BYTES},`Collab WebSocket message rejected before Yjs processing`),t.close(1009,`Message Too Big`);return}w.handleMessage(new Uint8Array(e))}),t.on(`close`,(e,t)=>{w.handleClose({code:e,reason:t.toString()})}),t.on(`error`,e=>{if(e.code===`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`){incrementCollabMessageTooLarge(),E.warn({event:`collab-message-too-large`,limit:MAX_COLLAB_MESSAGE_BYTES},`Collab WebSocket frame rejected by ws maxPayload before Yjs processing`),t.terminate();return}handleCollabSocketError(e)||E.error({err:e},`WebSocket error`),t.terminate()})});return}t.destroy()}),{wss:B,shutdown:async()=>{if(!J){J=!0;for(let e of H.values())clearTimeout(e);H.clear(),q.size>0&&await Promise.allSettled(q)}}}}function parseKeepaliveConnectionId(e){if(!e)return null;try{return validateAgentId(new URL(e,`http://localhost`).searchParams.get(`connectionId`))}catch{return null}}const MAX_KEEPALIVE_IDENTITY_LEN=256;function sanitizeIdentityField(e){return e===null||e.length===0||e.length>MAX_KEEPALIVE_IDENTITY_LEN||/[-]/.test(e)?null:e}function parseKeepaliveIdentity(e){if(!e)return null;try{let t=new URL(e,`http://localhost`),S=sanitizeIdentityField(t.searchParams.get(`displayName`)),w=sanitizeIdentityField(t.searchParams.get(`clientName`)),E=sanitizeIdentityField(t.searchParams.get(`colorSeed`));return S===null||w===null||E===null?null:{displayName:S,clientName:w,colorSeed:E}}catch{return null}}const MISSING_OK_CONFIG_MESSAGE=`Open Knowledge config not found at .ok/config.yml. Run ok init to scaffold OK in this directory.`;var MissingOkConfigError=class extends Error{kind;projectDir;constructor(e,t,S){super(MISSING_OK_CONFIG_MESSAGE,S),this.name=`MissingOkConfigError`,this.kind=e,this.projectDir=t}};async function startConfigFileWatcher(e,t){let S=getLogger(`config-file-watcher`),{watch:w}=await import(`./chokidar-CxU7f6JW.mjs`),E=dirname(e);try{tracedMkdirSync(E,{recursive:!0})}catch(e){e.code!==`EEXIST`&&S.warn({err:e,watchDir:E},`failed to create watch directory; watcher may be inert`)}let D=w(E,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:t=>t!==E&&t!==e});await new Promise(e=>{D.once(`ready`,e)});let O=null;try{O=readFileSync(e,`utf-8`)}catch{}let k=(w,E=!0)=>{if(w!==e)return;let D;try{D=readFileSync(w,`utf-8`)}catch(e){if(e.code===`ENOENT`){E&&S.debug({path:w},`config file disappeared between event and read; dropping`);return}S.warn({err:e,path:w},`config file read failed; dropping event`);return}if(D!==O){O=D;try{t(D)}catch(e){S.warn({err:e,path:w},`config file change handler threw`)}}},j=e=>k(e);D.on(`add`,j),D.on(`change`,j),D.on(`unlink`,t=>{t===e&&S.debug({path:t},`config file unlinked; Y.Text retained at current state`)}),D.on(`error`,t=>{S.warn({err:t,watchDir:E,absPath:e},`[config-file-watcher] chokidar error while watching ${e}`)});let F=0,L=setInterval(()=>{F++,k(e,!1),F>=20&&clearInterval(L)},500);L.unref?.();let B=!1;return async()=>{B||(B=!0,clearInterval(L),await D.close())}}async function startMultiPathConfigFileWatcher(e,t){if(e.length===0)throw Error(`startMultiPathConfigFileWatcher requires at least one absolute path`);let S=getLogger(`config-file-watcher`),{watch:w}=await import(`./chokidar-CxU7f6JW.mjs`),E=new Set(e),D=Array.from(new Set(Array.from(E,e=>dirname(e))));for(let e of D)try{tracedMkdirSync(e,{recursive:!0})}catch(t){t.code!==`EEXIST`&&S.warn({err:t,dir:e},`failed to create watch directory; watcher may be inert`)}let O=w(D,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:e=>!E.has(e)&&!D.includes(e)});await new Promise(e=>{O.once(`ready`,e)});let k=new Map;for(let e of E)try{k.set(e,readFileSync(e,`utf-8`))}catch{k.set(e,null)}let j=(e,w=!0)=>{if(!E.has(e))return;let D;try{D=readFileSync(e,`utf-8`)}catch(t){if(t.code===`ENOENT`){w&&S.debug({path:e},`config file disappeared between event and read; dropping`);return}S.warn({err:t,path:e},`config file read failed; dropping event`);return}if(D!==k.get(e)){k.set(e,D);try{t(e,D)}catch(t){S.warn({err:t,path:e},`config file change handler threw`)}}},F=e=>j(e);O.on(`add`,F),O.on(`change`,F),O.on(`unlink`,e=>{E.has(e)&&S.debug({path:e},`config file unlinked; downstream state retained`)}),O.on(`error`,e=>{S.warn({err:e,watchDirs:D,paths:Array.from(E)},`[config-file-watcher] chokidar error in multi-path watcher`)});let L=0,B=setInterval(()=>{L++;for(let e of E)j(e,!1);L>=20&&clearInterval(B)},500);B.unref?.();let H=!1;return async()=>{H||(H=!0,clearInterval(B),await O.close())}}const BUILTIN_SKIP_DIRS=new Set([`node_modules`,`.venv`,`venv`,`env`,`__pycache__`,`vendor`,`dist`,`build`,`out`,`output`,`.next`,`.nuxt`,`.svelte-kit`,`.astro`,`.turbo`,`.cache`,`.parcel-cache`,`coverage`,`.git`,`.ok`,`.open-knowledge`,`.openknowledge`,`Library`,`Applications`,`.Trash`]),IGNORE_FILE_NAMES=[`.gitignore`,`.okignore`];function createContentFilter(e){let{projectDir:t,contentDir:S,onAfterRebuild:w}=e,E=relative(t,S),D=E.startsWith(`..`),O,k,j,F=0,L=0,B=0;function H(){let e=(0,import_ignore.default)();e.add(`.git`);let w=[],H=0,q=0;for(let S of IGNORE_FILE_NAMES){let E=join(t,S);if(existsSync(E))try{let t=readFileSync(E,`utf-8`);H+=t.length;let S=parseIgnorePatterns(t);w.push(...S),e.add(S)}catch(e){console.warn(`[content-filter] Failed to read ${S} at ${E}:`,e)}}if(E&&!D)for(let t of IGNORE_FILE_NAMES){let w=join(S,t);if(existsSync(w))try{let t=readFileSync(w,`utf-8`);H+=t.length,q++;let S=parseIgnorePatterns(t).map(e=>prefixPattern(e,E));e.add(S)}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${w}:`,e)}}let J={value:H};q+=loadNestedIgnoreFiles(S,t,e,J),H=J.value;let Y=w.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`));return O=e,k=w,j=Y,F=w.length,L=q,B=H,{patternCount:F,nestedFileCount:L,bytes:B}}H();let q=new Map;function J(e){if(D)return!1;let t=E?`${E}/${e}`:e;return O.ignores(t)}populateDirCount(S,``,J,q);function Y(e){let t=stripDocExtension(e);return isSystemDoc(t)||isConfigDoc(t)}function ee(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return D?!1:J(e)}return{isExcluded(e,t){if(Y(e))return!0;if(t?.bypassFilters)return!1;if(ee(e))return!0;if(isSupportedDocFile(e))return!1;let S=extname(e).slice(1).toLowerCase();if(ASSET_EXTENSIONS.has(S)){let t=dirname(e),S=t===`.`?``:t;if((q.get(S)??0)>0)return!1}return!0},isDirExcluded(e,t){if(t?.bypassFilters)return!1;for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;if(D)return!1;let S=E?`${E}/${e}`:e;return O.ignores(S)||O.ignores(`${S}/`)},isPathIgnored(e,t){return Y(e)?!0:t?.bypassFilters?!1:ee(e)},getWatcherIgnoreGlobs(){return j},incrementMdDir(e){let t=e===`.`?``:e;q.set(t,(q.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,S=q.get(t)??0;S<=1?q.delete(t):q.set(t,S-1)},rebuildDirCount(){let e=new Map(q);q.clear();try{populateDirCount(S,``,J,q)}catch(t){for(let[t,S]of e)q.set(t,S);getLogger(`content-filter`).warn({err:t instanceof Error?t:Error(String(t))},`content-filter rebuildDirCount walk failed — retaining previous counts`)}},async rebuildIgnorePatterns(){let e=getLogger(`content-filter`),t=O,E=k,D=j,Y=F,ee=L,te=B,ne=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async ae=>{try{let t=H();q.clear(),populateDirCount(S,``,J,q);let E=Date.now()-ne;if(ae.setAttributes({"ok.ignore.pattern_count":t.patternCount,"ok.ignore.nested_file_count":t.nestedFileCount,"ok.ignore.bytes":t.bytes}),e.info({patternCount:t.patternCount,nestedFileCount:t.nestedFileCount,bytes:t.bytes,durationMs:E},`content-filter rebuild succeeded`),w)try{w()}catch(t){e.warn({err:t instanceof Error?t:Error(String(t))},`content-filter onAfterRebuild callback threw — derived views may be stale`)}return{ok:!0,patternCount:t.patternCount,nestedFileCount:t.nestedFileCount,bytes:t.bytes,durationMs:E}}catch(w){O=t,k=E,j=D,F=Y,L=ee,B=te,q.clear();try{populateDirCount(S,``,J,q)}catch(t){e.warn({err:t instanceof Error?t:Error(String(t))},`content-filter rollback dirCount re-walk failed — sibling-asset counts may be stale until next rebuild`)}let H=w instanceof Error?w.message:String(w);return e.warn({err:w instanceof Error?w:Error(H)},`content-filter rebuild failed — rolled back to previous state`),{ok:!1,error:{message:H}}}})}}}function populateDirCount(e,t,S,w){let E;try{E=readdirSync(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory for dir-count: ${e}`,t);return}for(let D of E){let E=t?`${t}/${D.name}`:D.name;if(D.isDirectory()){if(BUILTIN_SKIP_DIRS.has(D.name)||S(E)||S(`${E}/`))continue;populateDirCount(join(e,D.name),E,S,w)}else D.isFile()&&isSupportedDocFile(D.name)&&!S(E)&&w.set(t,(w.get(t)??0)+1)}}function parseIgnorePatterns(e){return e.split(`
|
|
3199
|
+
`).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`#`))}function prefixPattern(e,t){return e.startsWith(`!`)?`!${t}/${e.slice(1)}`:`${t}/${e}`}function loadNestedIgnoreFiles(e,t,S,w){let E;try{E=readdirSync(e,{withFileTypes:!0})}catch(t){return console.warn(`[content-filter] Failed to read directory ${e}:`,t),0}let D=0;for(let O of E){if(!O.isDirectory()||BUILTIN_SKIP_DIRS.has(O.name))continue;let E=join(e,O.name),k=relative(t,E);if(!k.startsWith(`..`)&&!(S.ignores(k)||S.ignores(`${k}/`))){for(let e of IGNORE_FILE_NAMES){let t=join(E,e);if(existsSync(t))try{let e=readFileSync(t,`utf-8`);w.value+=e.length;let E=parseIgnorePatterns(e).map(e=>prefixPattern(e,k));S.add(E),D++}catch(S){console.warn(`[content-filter] Failed to read nested ${e} at ${t}:`,S)}}D+=loadNestedIgnoreFiles(E,t,S,w)}}return D}async function initContentDirStateAsync(e,t,S,w,E,D,O){let k;try{k=await readdir(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory ${e}:`,t);return}for(let j of k){let k=t?`${t}/${j.name}`:j.name;if(j.isDirectory()){if(BUILTIN_SKIP_DIRS.has(j.name))continue;let t=join(e,j.name);if(!D){let e=relative(S,t);if(e.startsWith(`..`)||w.ignores(e)||w.ignores(`${e}/`))continue;for(let S of IGNORE_FILE_NAMES){let E=join(t,S);if(existsSync(E))try{let t=parseIgnorePatterns(await readFile$1(E,`utf-8`));w.add(t.map(t=>prefixPattern(t,e)))}catch(e){console.warn(`[content-filter] Failed to read nested ${S} at ${E}:`,e)}}}await initContentDirStateAsync(t,k,S,w,E,D,O)}else if(j.isFile()&&isSupportedDocFile(j.name)){if(!D){let e=E?`${E}/${k}`:k;if(w.ignores(e))continue}O.set(t,(O.get(t)??0)+1)}}}async function createContentFilterAsync(e){let{projectDir:t,contentDir:S,onAfterRebuild:w}=e,E=relative(t,S),D=E.startsWith(`..`),O=(0,import_ignore.default)(),k=[],j=new Map;function F(e){if(D)return!1;let t=E?`${E}/${e}`:e;return O.ignores(t)}function L(e){let t=stripDocExtension(e);return isSystemDoc(t)||isConfigDoc(t)}function B(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return D?!1:F(e)}async function H(){let e=(0,import_ignore.default)();e.add(`.git`);let w=[];for(let S of IGNORE_FILE_NAMES){let E=join(t,S);if(existsSync(E))try{let t=parseIgnorePatterns(await readFile$1(E,`utf-8`));w.push(...t),e.add(t)}catch(e){console.warn(`[content-filter] Failed to read ${S} at ${E}:`,e)}}if(E&&!D)for(let t of IGNORE_FILE_NAMES){let w=join(S,t);if(existsSync(w))try{let t=parseIgnorePatterns(await readFile$1(w,`utf-8`));e.add(t.map(e=>prefixPattern(e,E)))}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${w}:`,e)}}let F=new Map;await initContentDirStateAsync(S,``,t,e,E,D,F),O=e,k=w.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`)),j.clear();for(let[e,t]of F)j.set(e,t)}return await H(),{isExcluded(e,t){if(L(e))return!0;if(t?.bypassFilters)return!1;if(B(e))return!0;if(isSupportedDocFile(e))return!1;let S=extname(e).slice(1).toLowerCase();if(ASSET_EXTENSIONS.has(S)){let t=dirname(e),S=t===`.`?``:t;if((j.get(S)??0)>0)return!1}return!0},isDirExcluded(e,t){if(t?.bypassFilters)return!1;for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;if(D)return!1;let S=E?`${E}/${e}`:e;return O.ignores(S)||O.ignores(`${S}/`)},isPathIgnored(e,t){return L(e)?!0:t?.bypassFilters?!1:B(e)},getWatcherIgnoreGlobs(){return k},incrementMdDir(e){let t=e===`.`?``:e;j.set(t,(j.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,S=j.get(t)??0;S<=1?j.delete(t):j.set(t,S-1)},rebuildDirCount(){let e=new Map(j);j.clear();try{populateDirCount(S,``,F,j)}catch(t){for(let[t,S]of e)j.set(t,S);getLogger(`content-filter`).warn({err:t instanceof Error?t:Error(String(t))},`content-filter rebuildDirCount walk failed — retaining previous counts`)}},async rebuildIgnorePatterns(){let e=getLogger(`content-filter`),t=O,S=k,E=new Map(j),D=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async F=>{try{await H();let t=Date.now()-D;if(F.setAttributes({"ok.ignore.pattern_count":k.length,"ok.ignore.nested_file_count":0,"ok.ignore.bytes":0}),e.info({durationMs:t},`content-filter async rebuild succeeded`),w)try{w()}catch(t){e.warn({err:t instanceof Error?t:Error(String(t))},`content-filter onAfterRebuild callback threw — derived views may be stale`)}return{ok:!0,patternCount:k.length,nestedFileCount:0,bytes:0,durationMs:t}}catch(w){O=t,k=S,j.clear();for(let[e,t]of E)j.set(e,t);let D=w instanceof Error?w.message:String(w);return e.warn({err:w instanceof Error?w:Error(D)},`content-filter async rebuild failed — rolled back`),{ok:!1,error:{message:D}}}})}}}const QUIET_WINDOW_MS=100,BATCH_TIMEOUT_MS=3e4,WATCHED_FILES=new Set([`HEAD`,`MERGE_HEAD`,`ORIG_HEAD`,`index.lock`]);function readHeadSha(e){try{let t=readFileSync(resolve(e,`HEAD`),`utf-8`).trim();if(t.startsWith(`ref: `)){let S=resolve(e,t.slice(5));try{return readFileSync(S,`utf-8`).trim()}catch{try{let S=readFileSync(resolve(e,`packed-refs`),`utf-8`),w=t.slice(5),E=S.split(`
|
|
3219
3200
|
`).find(e=>e.endsWith(` ${w}`));if(E)return E.split(` `)[0]}catch{}return null}}return t.length>=40?t.slice(0,40):null}catch{return null}}function readBranchFromHead(e){try{let t=readFileSync(resolve(e,`HEAD`),`utf-8`).trim();return t.startsWith(`ref: refs/heads/`)?t.slice(16):t.length>=40?`detached-${t.slice(0,12)}`:null}catch{return null}}async function startHeadWatcher(e,t,S){let w=resolveGitDir(e);if(!w)return{unsubscribe:async()=>{},getLastKnownBranch:()=>null};let E=w,D=!1,O=null,k=null,j=null,F=null;async function L(e){if(H&&await H,!D)return;O&&=(clearTimeout(O),null),k&&=(clearTimeout(k),null);let t=readHeadSha(E),w=j!==t,L=readBranchFromHead(E),B;B=L?.startsWith(`detached-`)?`detached-head`:F===L?`within-branch`:`cross-branch`;let q=F;try{await S({headMoved:w,oldHead:j,newHead:t,timeout:e,batchKind:B,oldBranch:q,newBranch:L})}catch(e){console.error(`[head-watcher] onBatchEnd callback failed:`,e)}finally{D=!1,j=t,F=L}}function B(){O&&clearTimeout(O),O=setTimeout(()=>{O=null,L(!1)},QUIET_WINDOW_MS)}let H=null;async function q(e){if(!D){D=!0,j=readHeadSha(E);let S=(async()=>{try{await t({trigger:e})}catch(e){console.error(`[head-watcher] onBatchBegin callback failed:`,e)}})();H=S,await S,H=null,k=setTimeout(()=>{k=null,L(!0)},BATCH_TIMEOUT_MS)}B()}let J,Y;try{Y=await import(`@parcel/watcher`)}catch(e){throw Error(`@parcel/watcher unavailable for HEAD watching: ${e instanceof Error?e.message:e}`)}try{let e=await Y.subscribe(E,(e,t)=>{if(e){console.error(`[head-watcher]`,e);return}for(let e of t){let t=e.path.split(`/`).pop()??``;if(WATCHED_FILES.has(t)){q(t);break}}});J=()=>e.unsubscribe()}catch(e){throw Error(`@parcel/watcher subscribe failed for HEAD watching: ${e instanceof Error?e.message:e}`)}return j=readHeadSha(E),F=readBranchFromHead(E),console.log(`[head-watcher] Watching ${E} for HEAD changes`),{unsubscribe:async()=>{D&&await L(!1),O&&clearTimeout(O),k&&clearTimeout(k),await J()},getLastKnownBranch:()=>F}}const LIVE_DERIVED_INDEX_DEBOUNCE_MS=100;function isLocalOriginLike(e){return typeof e!=`object`||!e?!1:e.source===`local`}function serializeLiveDocument(e){return e.getText(`source`).toString()}function createLiveDerivedIndexExtension(e){let{backlinkIndex:t,tagIndex:S,signalChannel:w,debounceMs:E=100}=e,D=new Map;function O(e){let t=D.get(e);t&&(clearTimeout(t),D.delete(e))}function k(e,k){O(e),D.set(e,setTimeout(()=>{D.delete(e);try{let E=serializeLiveDocument(k);t.updateDocumentFromMarkdown(e,E),w?.(`backlinks`),w?.(`graph`),S&&(S.updateDocumentFromMarkdown(e,E),w?.(`tags`))}catch(t){console.error(`[live-derived-index] Failed to update derived views for ${e}:`,t)}},E))}return{async onChange({documentName:e,document:t,transactionOrigin:S}){isSystemDoc(e)||isConfigDoc(e)||isLocalOriginLike(S)&&S.context?.origin===`file-watcher`||k(e,t)},async beforeUnloadDocument({documentName:e}){O(e)},async onDestroy(){for(let e of D.values())clearTimeout(e);D.clear()}}}const PRINCIPAL_FILE=`principal.json`,GIT_TIMEOUT_MS=3e3;async function readGitConfig(e){try{let t=esm_default({baseDir:e,timeout:{block:GIT_TIMEOUT_MS}});return{name:(await t.raw(`config`,`--get`,`user.name`)).trim()||null,email:(await t.raw(`config`,`--get`,`user.email`)).trim()||null}}catch{return{name:null,email:null}}}async function loadPrincipal(e){let t=getLocalDir(e),S=resolve(t,PRINCIPAL_FILE),{name:w,email:E}=await readGitConfig(e);if(existsSync(S)){let e;try{e=JSON.parse(readFileSync(S,`utf-8`))}catch{e={}}let t=typeof e.id==`string`&&e.id.startsWith(`principal-`)?e.id:`principal-${randomUUID()}`,D=typeof e.created_at==`string`?e.created_at:new Date().toISOString(),O=t.slice(10,18),k={id:t,display_name:w?sanitizeGitIdentity(w):typeof e.display_name==`string`?e.display_name:`Local User`,display_email:E?sanitizeGitIdentity(E):typeof e.display_email==`string`?e.display_email:`principal-${O}@openknowledge.local`,source:w||E?`git-config`:`synthesized`,created_at:D};return writeFileSync(S,JSON.stringify(k,null,2),`utf-8`),k}mkdirSync(t,{recursive:!0});let D=`principal-${randomUUID()}`,O=D.slice(10,18),k={id:D,display_name:w?sanitizeGitIdentity(w):`Local User`,display_email:E?sanitizeGitIdentity(E):`principal-${O}@openknowledge.local`,source:w||E?`git-config`:`synthesized`,created_at:new Date().toISOString()};return writeFileSync(S,JSON.stringify(k,null,2),`utf-8`),k}const DEFAULT_CAPACITY=1e4;var RecentlyRemovedDocs=class{map=new Map;capacity;onEviction;onSizeChange;now;constructor(e=DEFAULT_CAPACITY,t={}){this.capacity=Math.max(0,Math.floor(e)),this.onEviction=t.onEviction,this.onSizeChange=t.onSizeChange,this.now=t.now??Date.now}setRenamed(e,t){this.put(e,{kind:`renamed`,newDocName:t,addedAt:this.now()})}setDeleted(e){this.put(e,{kind:`deleted`,addedAt:this.now()})}get(e){let t=this.map.get(e);if(t!==void 0)return this.map.delete(e),this.map.set(e,t),t}has(e){return this.map.has(e)}peek(e){return this.map.get(e)}delete(e){this.map.delete(e)&&this.onSizeChange?.(this.map.size)}get size(){return this.map.size}put(e,t){if(this.capacity===0){this.onSizeChange?.(0);return}for(this.map.delete(e),this.map.set(e,t);this.map.size>this.capacity;){let e=this.map.keys().next().value;if(e===void 0)break;this.map.delete(e),this.onEviction?.()}this.onSizeChange?.(this.map.size)}};function fileExistsForDocName(e,t){let S=e.resolveFilePath(t);return S!==null&&e.fileExists(S)}async function runRemovalRedirectGuard(e,t){try{if(isSystemDoc(e)||isConfigDoc(e))return;let S=t.recentlyRemovedDocs.get(e);if(S===void 0)return;if(S.kind===`deleted`){if(fileExistsForDocName(t,e)){t.recentlyRemovedDocs.delete(e);return}throw incrementAuthDocDeleted(),setActiveSpanAttributes({"auth.reason":`doc-deleted`}),new HocuspocusAuthRejection(`doc-deleted`,`removed-doc rejection for deleted ${e}`)}let w=new Set([e]),E=S.newDocName;for(;;){if(w.has(E)){incrementRemovalRedirectChainCycle(),console.warn(JSON.stringify({event:`removal-redirect-chain-cycle`,documentName:e,target:E}));return}w.add(E);let S=t.recentlyRemovedDocs.get(E);if(S===void 0)throw incrementAuthRenameRedirect(),setActiveSpanAttributes({"auth.reason":`rename-redirect`}),new HocuspocusAuthRejection(`rename-redirect`,`removed-doc redirect for ${e} → ${E}`,E);if(S.kind===`deleted`)throw fileExistsForDocName(t,E)?(t.recentlyRemovedDocs.delete(E),incrementAuthRenameRedirect(),setActiveSpanAttributes({"auth.reason":`rename-redirect`}),new HocuspocusAuthRejection(`rename-redirect`,`removed-doc redirect for ${e} → ${E}`,E)):(incrementAuthDocDeleted(),setActiveSpanAttributes({"auth.reason":`doc-deleted`}),new HocuspocusAuthRejection(`doc-deleted`,`removed-doc rejection for deleted ${e}`));E=S.newDocName}}catch(t){if(t instanceof HocuspocusAuthRejection)throw t;incrementAuthRemovalGuardError(),console.warn(JSON.stringify({event:`removal-redirect-extension-error`,documentName:e,message:t instanceof Error?t.message:String(t)}))}}function createServerObserverExtension(e){let t=new Map,S=new Map;return{async afterLoadDocument({documentName:w,document:E}){if(isSystemDoc(w)||isConfigDoc(w)||t.has(w))return;let D=E,O=D.getXmlFragment(`default`),k=D.getText(`source`),j=()=>{try{let S=setupServerObservers({doc:D,xmlFragment:O,ytext:k,mdManager:e.mdManager,schema:e.schema,docName:w,shadow:e.shadowRef?()=>e.shadowRef?.current:void 0,getBranch:e.getCurrentBranch?()=>e.getCurrentBranch?.()??`main`:void 0,contentRoot:e.contentRoot,resolveEmbed:e.resolveEmbed,resolveSize:e.resolveSize});return t.set(w,S),!0}catch(e){return console.error(`[ServerObserverExtension] Failed to attach observers for '${w}':`,e),incrementServerObserverError(`a`),incrementServerObserverError(`b`),!1}};if(!j()){let e=setTimeout(()=>{S.delete(w),!t.has(w)&&(console.warn(`[ServerObserverExtension] Retrying observer attachment for '${w}'`),j())},5e3);S.set(w,e)}},async afterUnloadDocument({documentName:e}){let w=S.get(e);w&&(clearTimeout(w),S.delete(e));let E=t.get(e);E&&(E(),t.delete(e))},async onDestroy(){for(let e of S.values())clearTimeout(e);S.clear();for(let[e,S]of t.entries())try{S()}catch(t){console.error(`[ServerObserverExtension] Cleanup failed for '${e}':`,t)}t.clear()}}}const STATE_MANIFEST_FILENAME=`state.json`;function detectProjectShape(e){return e.lockDir,existsSync(e.shadowRepoDir)?`adopt`:`fresh`}function manifestPath(e){return resolve(e,STATE_MANIFEST_FILENAME)}function isCompatibleSchema(e,t){return e===t||e===0&&t===1}var StateManifestError=class extends Error{kind;path;constructor(e){super(e.message),this.name=`StateManifestError`,this.kind=e.kind,this.path=e.path}};function isStateManifestRecord(e){if(!e||typeof e!=`object`)return!1;let t=e;if(typeof t.stateSchemaVersion!=`number`||typeof t.createdAt!=`string`||!t.createdBy||typeof t.createdBy!=`object`)return!1;let S=t.createdBy;return!(typeof S.runtimeVersion!=`string`||S.protocolVersion!==void 0&&typeof S.protocolVersion!=`number`)}function readStateManifest(e){let t=manifestPath(e);if(!existsSync(t))return{status:`absent`};let S;try{S=readFileSync(t,`utf-8`)}catch(e){throw new StateManifestError({kind:`corrupt`,path:t,message:`Failed to read state manifest at ${t}: ${e instanceof Error?e.message:String(e)}`})}let w;try{w=JSON.parse(S)}catch(e){throw new StateManifestError({kind:`corrupt`,path:t,message:`State manifest at ${t} is not valid JSON: ${e instanceof Error?e.message:String(e)}`})}if(!isStateManifestRecord(w))throw new StateManifestError({kind:`corrupt`,path:t,message:`State manifest at ${t} has invalid shape (missing or wrong-typed required fields)`});return{status:`present`,manifest:w}}function writeStateManifest(e,t){let S=manifestPath(e);mkdirSync(dirname(S),{recursive:!0}),writeFileSync(S,JSON.stringify(t,null,2),{encoding:`utf-8`,mode:384})}function assertCompatibleStateManifest(e){let t=getLogger(`state-manifest`),S=e.currentStateSchemaVersion??1,w=e.currentRuntimeVersion??RUNTIME_VERSION,E=e.currentProtocolVersion??1,D=(e.now??(()=>new Date))().toISOString(),O=manifestPath(e.lockDir),k=readStateManifest(e.lockDir);if(k.status===`present`){let j=k.manifest;if(!isCompatibleSchema(j.stateSchemaVersion,S))throw new StateManifestError({kind:`incompatible`,path:O,message:`State manifest at ${O} declares stateSchemaVersion=${j.stateSchemaVersion} but this binary supports ${S}. Refusing to boot — on-the-fly migration is out of scope. (Manifest written by runtime ${j.createdBy.runtimeVersion}, protocol ${j.createdBy.protocolVersion}.)`});try{let t={...j,lastWriteBy:{runtimeVersion:w,protocolVersion:E,at:D}};return writeStateManifest(e.lockDir,t),t}catch(e){return t.warn({err:e},`[state-manifest] failed to update lastWriteBy — proceeding`),j}}if(detectProjectShape({lockDir:e.lockDir,shadowRepoDir:e.shadowRepoDir})===`fresh`){let k={stateSchemaVersion:S,createdAt:D,createdBy:{runtimeVersion:w,protocolVersion:E}};return writeStateManifest(e.lockDir,k),t.info({path:O,stateSchemaVersion:S},`[state-manifest] fresh project — wrote manifest`),k}let j={stateSchemaVersion:0,createdAt:D,createdBy:{runtimeVersion:w,protocolVersion:E,adoptedAt:D}};return writeStateManifest(e.lockDir,j),t.warn({path:O,runtimeVersion:w},`[state-manifest] adopting pre-versioned project — wrote schema-0 manifest. Future binaries with STATE_SCHEMA_VERSION>=2 may refuse if they cannot read schema-0 state.`),j}const log$1=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$1.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$1.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$1.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,w=[]){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:E}=await import(`./git-handle-DwfYp_z--DreW3fNC.mjs`).then(e=>e.n),D=E(this.projectDir,{credentialArgs:w});switch(t){case`mine`:await D.git.raw([`checkout`,`--ours`,`--`,e]),await D.git.raw([`add`,`--`,e]);break;case`theirs`:await D.git.raw([`checkout`,`--theirs`,`--`,e]),await D.git.raw([`add`,`--`,e]);break;case`content`:{if(!S)throw Error(`[conflicts] strategy 'content' requires content parameter`);let t=resolve(this.projectDir),w=resolve(t,e);if(w!==t&&!w.startsWith(`${t}/`))throw Error(`[conflicts] file path escapes project directory: ${e}`);writeFileSync(w,S,`utf-8`),await D.git.raw([`add`,`--`,e]);break}default:throw Error(`[conflicts] unknown resolve strategy: ${t}`)}if(this.removeConflict(e),!this.hasConflicts())try{await D.git.raw([`commit`,`--no-edit`]),log$1.info({file:e},`[conflicts] all conflicts resolved — merge commit created`)}catch(t){let S=new Date().toISOString(),w=!1;try{let e=(await D.git.raw([`diff`,`--name-only`,`--diff-filter=U`])).split(`
|
|
3220
3201
|
`).map(e=>e.trim()).filter(Boolean);for(let t of e)this.addConflict({file:t,detectedAt:S});w=e.length>0}catch(e){log$1.warn({err:e},`[conflicts] commit failed and re-scan of unmerged files failed — falling back to single-file re-add`)}w||this.addConflict({file:e,detectedAt:S}),log$1.warn({err:t},`[conflicts] failed to commit merge after all conflicts resolved — unmerged files re-added`);let E=t instanceof Error?t.message:String(t);throw Error(`Merge commit failed after resolving ${e}; ${w?`unmerged files re-added`:`original file re-added`} — ${E}`,{cause:t})}}};function extractStderr(e){return e.git?.toString()??e.message??``}function matchesAny(e,t){return t.some(t=>t.test(e))}const AUTH_PATTERNS=[/\b(401|403)\b/,/authentication failed/i,/authorization failed/i,/invalid credentials/i,/credential helper/i,/bad credentials/i,/token.*expired/i,/expired.*token/i,/permission denied.*\(publickey\)/i,/host key verification failed/i,/fatal:.*repository.*not found/i],SCOPE_MISMATCH_PATTERNS=[/insufficient scopes/i,/missing.*scope/i,/required scope/i],NON_FAST_FORWARD_PATTERNS=[/non-fast-forward/i,/rejected.*non-fast-forward/i,/would overwrite.*commits/i,/\[rejected\]/,/fetch first/i,/updates were rejected/i],PROTECTED_BRANCH_PATTERNS=[/protected branch/i,/refusing to allow/i,/at least \d+ approving review/i,/required status check/i,/branch policy/i,/GH001/i,/GH002/i,/GH003/i,/GH004/i,/push declined due to repository rule/i,/cannot push to a protected branch/i],MERGE_CONFLICT_PATTERNS=[/\bmerge conflict\b/i,/automatic merge failed/i,/CONFLICT \(/,/\bconflict\b.*\bmerge\b/i,/(?:^|\n)CONFLICTS:\s/i],LFS_PATTERNS=[/lfs.*quota/i,/exceeded.*bandwidth/i,/lfs storage/i],LARGE_FILE_PATTERNS=[/file.*too large/i,/exceeded.*file size/i,/push file size limit/i],PRE_RECEIVE_PATTERNS=[/pre-receive hook/i,/remote:.*rejected/i,/hook declined/i],SECRET_DETECTED_PATTERNS=[/secret.*detected/i,/push.*secret/i,/secret scanning/i,/leaking.*credentials/i,/token.*detected/i],INDEX_LOCK_PATTERNS=[/\.git\/index\.lock/i,/another git process/i,/unable to create.*\.lock/i],DIRTY_TREE_PATTERNS=[/dirty.*working tree/i,/working tree.*not clean/i,/untracked.*files.*would be overwritten/i,/local changes.*would be overwritten/i,/uncommitted changes/i,/changes.*not staged/i,/please.*commit.*changes/i,/please.*stash/i,/commit your changes or stash/i],DISK_FULL_PATTERNS=[/no space left on device/i,/disk quota exceeded/i,/ENOSPC/],NETWORK_PATTERNS=[/could not resolve host/i,/name.*resolution/i,/connection.*timed out/i,/operation timed out/i,/connection refused/i,/network.*unreachable/i,/ssl.*handshake/i,/unable to connect/i,/getaddrinfo/i,/econnrefused/i,/enotfound/i,/etimedout/i,/ehostunreach/i],HTTP_5XX_PATTERNS=[/\bHTTP[\s/]*5[0-9]{2}\b/i,/\bstatus:?\s*5[0-9]{2}\b/i,/\berror\s*5[0-9]{2}\b/i,/\bresponse.*?\b5[0-9]{2}\b/i],HTTP_429_PATTERNS=[/\bHTTP[\s/]*429\b/i,/\bstatus:?\s*429\b/i,/\berror\s*429\b/i,/rate.?limit/i,/too many requests/i];function classifyGitError(e){let t=e instanceof Error?e:Error(String(e)),S=extractStderr(t),w=`${t.message}\n${S}`.toLowerCase();return matchesAny(w,INDEX_LOCK_PATTERNS)?{class:`local`,subclass:`index-lock`,retryable:!0,message:`Git index locked by another process`,rawStderr:S}:matchesAny(w,DIRTY_TREE_PATTERNS)?{class:`local`,subclass:`dirty-tree`,retryable:!0,message:`Working tree has uncommitted changes`,rawStderr:S}:matchesAny(w,DISK_FULL_PATTERNS)?{class:`local`,subclass:`disk-full`,retryable:!0,message:`Disk full or quota exceeded`,rawStderr:S}:matchesAny(w,SCOPE_MISMATCH_PATTERNS)?{class:`auth`,subclass:`scope-mismatch`,retryable:!1,message:`GitHub token missing required scopes`,rawStderr:S}:matchesAny(w,AUTH_PATTERNS)?/\b401\b/.test(w)||/token.*expired/i.test(w)?{class:`auth`,subclass:`401`,retryable:!1,message:`Authentication failed — token may be expired`,rawStderr:S}:/\b403\b/.test(w)?matchesAny(w,PROTECTED_BRANCH_PATTERNS)?{class:`semantic`,subclass:`protected-branch`,retryable:!1,message:`Push rejected — branch is protected`,rawStderr:S}:{class:`auth`,subclass:`403`,retryable:!1,message:`Access denied (403)`,rawStderr:S}:{class:`auth`,subclass:`unknown-auth`,retryable:!1,message:`Authentication failed`,rawStderr:S}:matchesAny(w,PROTECTED_BRANCH_PATTERNS)?{class:`semantic`,subclass:`protected-branch`,retryable:!1,message:`Push rejected — branch is protected`,rawStderr:S}:matchesAny(w,NON_FAST_FORWARD_PATTERNS)?{class:`semantic`,subclass:`non-fast-forward`,retryable:!1,message:`Push rejected — remote has diverged (non-fast-forward)`,rawStderr:S}:matchesAny(w,MERGE_CONFLICT_PATTERNS)?{class:`semantic`,subclass:`merge-conflict`,retryable:!1,message:`Merge conflict — manual resolution required`,rawStderr:S}:matchesAny(w,LFS_PATTERNS)?{class:`structural`,subclass:`lfs-quota`,retryable:!1,message:`Git LFS quota exceeded`,rawStderr:S}:matchesAny(w,LARGE_FILE_PATTERNS)?{class:`structural`,subclass:`large-file`,retryable:!1,message:`File exceeds size limit`,rawStderr:S}:matchesAny(w,SECRET_DETECTED_PATTERNS)?{class:`structural`,subclass:`secret-detected`,retryable:!1,message:`Push blocked — secret or credential detected in content`,rawStderr:S}:matchesAny(w,PRE_RECEIVE_PATTERNS)?{class:`structural`,subclass:`pre-receive-hook`,retryable:!1,message:`Push rejected by server pre-receive hook`,rawStderr:S}:matchesAny(w,HTTP_429_PATTERNS)?{class:`network`,subclass:`429`,retryable:!0,message:`Rate limited — too many requests`,rawStderr:S}:matchesAny(w,HTTP_5XX_PATTERNS)?{class:`network`,subclass:`5xx`,retryable:!0,message:`Server error (5xx)`,rawStderr:S}:matchesAny(w,NETWORK_PATTERNS)?/timed? out/i.test(w)?{class:`network`,subclass:`timeout`,retryable:!0,message:`Connection timed out`,rawStderr:S}:/refused/i.test(w)||/econnrefused/i.test(w)?{class:`network`,subclass:`connection-refused`,retryable:!0,message:`Connection refused`,rawStderr:S}:/resolve.*host/i.test(w)||/enotfound/i.test(w)||/getaddrinfo/i.test(w)?{class:`network`,subclass:`dns`,retryable:!0,message:`DNS resolution failed`,rawStderr:S}:{class:`network`,subclass:`unknown-network`,retryable:!0,message:`Network error`,rawStderr:S}:{class:`local`,subclass:`unknown-local`,retryable:!0,message:t.message||`Unknown git error`,rawStderr:S}}function computeRemainingMs(e,t,S=Date.now()){if(!e)return 0;let w=new Date(e).getTime();if(Number.isNaN(w))return 0;let E=w+t*1e3;return Math.max(0,E-S)}const log=getLogger(`sync-engine`),SHA_HEX_40=/^[0-9a-f]{40}$/i;function jitteredMs(e){let t=e*1e3,S=t*.15*(2*Math.random()-1);return Math.round(t+S)}function isUnbornHead(e){try{let t=join(e,`.git`,`HEAD`);if(!existsSync(t))return!1;let S=readFileSync(t,`utf-8`).trim(),w=/^ref:\s+(refs\/.+)$/.exec(S);if(!w)return!1;let E=w[1];if(existsSync(join(e,`.git`,E)))return!1;let D=join(e,`.git`,`packed-refs`);if(existsSync(D)){let e=readFileSync(D,`utf-8`);if(RegExp(`^[0-9a-f]+\\s+${E}$`,`m`).test(e))return!1}return!0}catch{return!1}}function backoffMs(e){return e>=8?3600*1e3:e>=5?900*1e3:e>=3?300*1e3:0}var SyncEngine=class{state=`dormant`;projectDir;contentDir;contentFilter;contentRoot;pullIntervalSeconds;pushIntervalSeconds;syncEnabled;credentialArgs;cc1Broadcaster;onStateChange;setBatchInProgress;onAutoDisable;pullTimer=null;pushTimer=null;stateSaveTimer=null;lastSyncUtc=null;lastFetchUtc=null;lastPushedSha=null;consecutiveFailures=0;ahead=0;behind=0;conflictCount=0;error;pausedReason;currentBranch=`main`;pullInFlight=!1;pushInFlight=!1;hasRemote=!1;identityUnresolved=!1;statePath;conflictStore;constructor(e){this.projectDir=e.projectDir,this.contentDir=e.contentDir,this.contentFilter=e.contentFilter,this.contentRoot=e.contentRoot??``,this.pullIntervalSeconds=e.pullIntervalSeconds??30,this.pushIntervalSeconds=e.pushIntervalSeconds??60,this.syncEnabled=e.syncEnabled,this.credentialArgs=e.credentialArgs??[],this.cc1Broadcaster=e.cc1Broadcaster??null,this.onStateChange=e.onStateChange,this.setBatchInProgress=e.setBatchInProgress,this.onAutoDisable=e.onAutoDisable,this.statePath=resolve(getLocalDir(this.projectDir),`sync-state.json`),this.conflictStore=new ConflictStore(this.projectDir,this.currentBranch)}async start(){if(this.state!==`dormant`)return;this.loadState();let e=!1;try{let t=createGitInstance(this.projectDir,{credentialArgs:this.credentialArgs});e=(await t.git.raw(`remote`,`-v`)).trim().length>0,this.hasRemote=e;try{let e=(await t.git.raw(`rev-parse`,`--abbrev-ref`,`HEAD`)).trim();e&&e!==`HEAD`&&(this.currentBranch=e,this.conflictStore.setBranch(e))}catch{}}catch(e){log.warn({err:e},`[sync] remote detection failed`)}if(this.syncEnabled!==!0){e&&this.transitionTo(`disabled`),log.info({hasRemote:e,syncEnabled:this.syncEnabled},`[sync] sync not enabled — staying inactive`);return}if(!e){log.info({},`[sync] no remote detected — staying dormant`);return}this.transitionTo(`idle`);let t=existsSync(join(this.projectDir,`.git`,`MERGE_HEAD`));if(this.conflictCount>0&&!t)log.warn({count:this.conflictCount},`[sync] persisted conflicts but no MERGE_HEAD — clearing stale state`),this.conflictStore.clear(),this.conflictCount=0;else if(this.conflictCount>0&&t)try{let e=(await createGitInstance(this.projectDir,{credentialArgs:this.credentialArgs}).git.raw([`diff`,`--name-only`,`--diff-filter=U`])).trim(),t=new Set(e?e.split(`
|
|
3221
3202
|
`).map(e=>e.trim()).filter(Boolean):[]),S=this.conflictCount;for(let e of this.conflictStore.list())t.has(e.file)||this.conflictStore.removeConflict(e.file);this.conflictCount=this.conflictStore.count(),this.conflictCount<S&&log.info({cleared:S-this.conflictCount,remaining:this.conflictCount},`[sync] reconciled conflicts.json against git unmerged index`)}catch(e){log.warn({err:e},`[sync] failed to reconcile conflicts with git index`)}if(t&&this.conflictCount===0){log.warn({},`[sync] stale MERGE_HEAD detected with no tracked conflicts — aborting merge`);try{await createGitInstance(this.projectDir,{credentialArgs:this.credentialArgs}).git.raw([`merge`,`--abort`])}catch(e){log.warn({err:e},`[sync] git merge --abort for stale MERGE_HEAD failed`)}}if(this.conflictCount>0){this.transitionTo(`conflict`),log.warn({count:this.conflictCount},`[sync] restarted with active conflicts — sync paused`);return}let S=computeRemainingMs(this.lastFetchUtc,this.pullIntervalSeconds),w=computeRemainingMs(this.lastSyncUtc,this.pushIntervalSeconds);this.schedulePull(S>0?S:void 0),this.schedulePush(w>0?w:void 0),log.info({branch:this.currentBranch,pullDelayMs:S,pushDelayMs:w},`[sync] started`)}stop(){this.pullTimer!==null&&(clearTimeout(this.pullTimer),this.pullTimer=null),this.pushTimer!==null&&(clearTimeout(this.pushTimer),this.pushTimer=null),this.stateSaveTimer!==null&&(clearTimeout(this.stateSaveTimer),this.stateSaveTimer=null),this.state!==`dormant`&&this.transitionTo(`dormant`)}async destroy(){this.stop(),this.saveStateNow()}async setEnabled(e){if(this.syncEnabled!==e){if(this.syncEnabled=e,!e){this.pullTimer!==null&&(clearTimeout(this.pullTimer),this.pullTimer=null),this.pushTimer!==null&&(clearTimeout(this.pushTimer),this.pushTimer=null);let e=3e4,t=Date.now();for(;this.pullInFlight||this.pushInFlight;){if(Date.now()-t>3e4){log.warn({pullInFlight:this.pullInFlight,pushInFlight:this.pushInFlight},`[sync] setEnabled(false): timed out waiting for in-flight cycle to drain`);break}await setTimeout$1(50)}this.pausedReason=void 0,this.error=void 0,this.transitionTo(this.hasRemote?`disabled`:`dormant`),this.saveStateNow();return}if(this.hasRemote=await this.probeRemote(),this.pausedReason=void 0,this.error=void 0,this.consecutiveFailures=0,!this.hasRemote){this.transitionTo(`dormant`),this.saveStateNow();return}this.transitionTo(`idle`),this.schedulePull(0),this.schedulePush(),this.saveStateNow()}}async trigger(e=`sync`){this.consecutiveFailures=0,(this.pausedReason===`dirty-tree`||this.pausedReason===`external-changes-pending`)&&(this.pausedReason=void 0,this.error=void 0),this.state===`dormant`||this.state===`disabled`||this.state===`conflict`||this.state===`auth-error`?log.warn({op:e,state:this.state,syncEnabled:this.syncEnabled,hasRemote:this.hasRemote,pausedReason:this.pausedReason,conflictCount:this.conflictCount},`[sync] trigger(${e}) ignored — state=${this.state}`):log.info({op:e,state:this.state},`[sync] trigger(${e}) running`),e===`push`?await this.runPushCycle():(e===`pull`||await this.runPushCycle(),await this.runPullCycle())}getStatus(){return{state:this.state,lastSyncUtc:this.lastSyncUtc,lastFetchUtc:this.lastFetchUtc,lastPushedSha:this.lastPushedSha,ahead:this.ahead,behind:this.behind,consecutiveFailures:this.consecutiveFailures,conflictCount:this.conflictCount,hasRemote:this.hasRemote,syncEnabled:this.syncEnabled===!0,identityUnresolved:this.identityUnresolved,error:this.error,pausedReason:this.pausedReason}}async refreshIdentity(){let e=await resolveGitIdentity(this.projectDir)===null;this.identityUnresolved!==e&&(this.identityUnresolved=e,this.cc1Broadcaster?.signal(`sync-status`))}async refreshRemote(){this.hasRemote||await this.probeRemote()&&(this.hasRemote=!0,log.info({syncEnabled:this.syncEnabled},`[sync] remote detected post-boot — re-evaluating state`),this.syncEnabled===!0?(this.transitionTo(`idle`),this.schedulePull(0),this.schedulePush()):this.transitionTo(`disabled`))}async probeRemote(){if(!existsSync(join(this.projectDir,`.git`)))return!1;try{return(await createGitInstance(this.projectDir,{credentialArgs:this.credentialArgs}).git.raw(`remote`,`-v`)).trim().length>0}catch(e){return log.warn({err:e},`[sync] remote detection failed`),!1}}getConflicts(){return this.conflictStore.list()}async resolveConflict(e,t,S){this.setBatchInProgress?.(!0);try{try{await this.conflictStore.resolveConflict(e,t,S)}catch(e){throw this.conflictCount=this.conflictStore.count(),this.scheduleSaveState(),e}this.conflictCount=this.conflictStore.count(),this.conflictCount===0&&this.state===`conflict`&&(this.transitionTo(`idle`),this.pausedReason=void 0,this.schedulePull(),this.schedulePush()),this.scheduleSaveState()}finally{this.setBatchInProgress?.(!1)}}updateCurrentBranch(e){e===null?this.state!==`dormant`&&this.state!==`disabled`&&(this.transitionTo(`disabled`),this.pausedReason=`detached-head`,this.scheduleSaveState()):this.currentBranch!==e&&(this.currentBranch=e,this.conflictStore.setBranch(e),this.state===`disabled`&&this.pausedReason===`detached-head`&&(this.pausedReason=void 0,this.transitionTo(`idle`),this.schedulePull(),this.schedulePush()))}schedulePull(e){this.pullTimer!==null&&clearTimeout(this.pullTimer);let t=e??this.effectivePullDelayMs();this.pullTimer=setTimeout(()=>{this.pullTimer=null,this.runPullCycle().catch(e=>{log.error({err:e},`[sync] pull cycle uncaught error`)})},t)}schedulePush(e){this.pushTimer!==null&&clearTimeout(this.pushTimer);let t=e??jitteredMs(this.pushIntervalSeconds);this.pushTimer=setTimeout(()=>{this.pushTimer=null,this.runPushCycle().catch(e=>{log.error({err:e},`[sync] push cycle uncaught error`)})},t)}effectivePullDelayMs(){let e=this.consecutiveFailures,t=backoffMs(e);return t>0?t:jitteredMs(this.pullIntervalSeconds)}async runPullCycle(){if(!this.pullInFlight&&!(this.state===`dormant`||this.state===`disabled`)){if(this.state===`conflict`){this.schedulePull();return}if(isUnbornHead(this.projectDir)){this.schedulePull();return}this.pullInFlight=!0;try{await this.doPullCycle()}finally{this.pullInFlight=!1,this.schedulePull()}}}async doPullCycle(){let e=createGitInstance(this.projectDir,{credentialArgs:this.credentialArgs}),t;try{let S=(await e.git.raw(`rev-parse`,`--abbrev-ref`,`HEAD`)).trim();if(!S||S===`HEAD`){this.transitionTo(`disabled`),this.pausedReason=`detached-head`,log.warn({},`[sync] detached HEAD — pausing sync`);return}t=S,this.currentBranch=t}catch(e){this.handleError(classifyGitError(e instanceof Error?e:Error(String(e))));return}this.transitionTo(`fetching`);try{await e.git.fetch(`origin`),this.lastFetchUtc=new Date().toISOString(),this.consecutiveFailures=0,this.error=void 0}catch(e){let t=classifyGitError(e instanceof Error?e:Error(String(e)));this.handleError(t);return}try{let t=await e.git.status();this.ahead=t.ahead,this.behind=t.behind}catch{}if(this.behind>0&&this.conflictCount===0){this.transitionTo(`pulling`),this.setBatchInProgress?.(!0);try{if(await this.commitDirtyContentFilesToHead(e),!await this.pauseIfNonContentDirty(e))return;await e.git.merge([`origin/${t}`]),this.lastSyncUtc=new Date().toISOString(),this.behind=0,this.transitionTo(`idle`)}catch(e){let t=classifyGitError(e instanceof Error?e:Error(String(e)));t.class===`semantic`&&t.subclass===`merge-conflict`?await this.handleMergeConflict():this.handleError(t);return}finally{this.setBatchInProgress?.(!1)}}else this.transitionTo(`idle`);this.scheduleSaveState()}async runPushCycle(){if(!this.pushInFlight&&!(this.state===`dormant`||this.state===`disabled`)&&!(this.state===`conflict`||this.state===`auth-error`)){if(isUnbornHead(this.projectDir)){this.schedulePush();return}this.pushInFlight=!0;try{await this.doPushCycle(1)}finally{this.pushInFlight=!1,this.schedulePush()}}}async doPushCycle(e=0){let t=this.gatherContentFilesSync(),S=join(tmpdir(),`ok-sync-idx-${process.pid}-${Date.now()}.idx`),w=null;this.transitionTo(`pushing`);try{await withParentLock(async()=>{let e=createGitInstance(this.projectDir,{credentialArgs:this.credentialArgs,gitIndexFile:S});if(isUnbornHead(this.projectDir)){log.info({},`[sync] repo has no commits yet — skipping push cycle`),this.transitionTo(`idle`);return}let E;try{E=(await e.git.revparse(`HEAD`)).trim()}catch(e){let t=e instanceof Error?e.message:String(e),S=`${t}\n${e.git?.toString()??t}`;if(/unknown revision or path not in the working tree/i.test(S)||/ambiguous argument 'HEAD'/i.test(S)||/does not have any commits yet/i.test(S)){log.info({},`[sync] repo has no commits yet — skipping push cycle`),this.transitionTo(`idle`);return}this.handleError(classifyGitError(e instanceof Error?e:Error(String(e))));return}await e.git.raw([`read-tree`,E]);let D=new Set;try{let t=(await e.git.raw([`ls-tree`,`-r`,`--name-only`,E])).trim();for(let e of t?t.split(`
|
|
@@ -3226,5 +3207,5 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
3226
3207
|
`,`
|
|
3227
3208
|
`).split(`
|
|
3228
3209
|
`),S=[],w=!1,E=``;for(let e of t){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(t){w?RegExp(`^\\s{0,3}${E[0]==="`"?"`":`~`}{${E.length},}\\s*$`).test(e)&&(w=!1,E=``):(w=!0,E=t[1]);continue}if(w)continue;let D=stripInlineCodeSpans(e);for(TAG_VALUE_RE.lastIndex=0;;){let e=TAG_VALUE_RE.exec(D);if(e===null)break;let t=e[2];t&&S.push(t)}}return S}var TagIndex=class{contentDir;contentFilter;state=createEmptyState();constructor(e){this.contentDir=e.contentDir,this.contentFilter=e.contentFilter}updateDocumentFromMarkdown(e,t){if(!(isSystemDoc(e)||isConfigDoc(e)))try{let{frontmatter:S,body:w}=stripFrontmatter(t),E=extractFrontmatterTags(S?unwrapFrontmatterFences(S):``),D=extractInlineTagsFromBody(w),O=new Set([...E,...D]),k=new Set;for(let e of O)for(let t of expandTagToHierarchy(e))k.add(t);this.applyDocSnapshot(e,O,k)}catch(t){console.warn(`[tag-index] Failed to scan ${e} for tag extraction:`,t),this.deleteDocument(e)}}deleteDocument(e){if(isSystemDoc(e)||isConfigDoc(e))return;let t=this.state.byDoc.get(e);if(t){for(let S of t){let t=this.state.byTag.get(S);t&&(t.delete(e),t.size===0&&this.state.byTag.delete(S))}this.state.byDoc.delete(e),this.state.byDocLiteral.delete(e)}}renameDocument(e,t,S){this.deleteDocument(e),this.updateDocumentFromMarkdown(t,S)}getDocsForTag(e){let t=this.state.byTag.get(e);return t?[...t].sort((e,t)=>e.localeCompare(t)):[]}getDocsForTagWithMatches(e){let t=this.state.byTag.get(e);if(!t)return[];let S=[];for(let w of t){let t=this.state.byDocLiteral.get(w);if(!t)continue;let E=tagsMatchingPrefix(t,e);S.push({docName:w,matchingTags:[...E].sort((e,t)=>e.localeCompare(t))})}return S.sort((e,t)=>e.docName.localeCompare(t.docName))}getAllTags(){let e=[...this.state.byTag.entries()],t=e.map(([e])=>e),S=new Set;for(let e of t){let t=e.indexOf(`/`);t>0&&S.add(e.slice(0,t));let w=t;for(;w>0;)S.add(e.slice(0,w)),w=e.indexOf(`/`,w+1)}return e.map(([e,t])=>({name:e,count:t.size,isLeaf:!S.has(e)})).sort((e,t)=>e.name.localeCompare(t.name))}init(){if(this.state=createEmptyState(),!existsSync(this.contentDir))return;let e=this.listDocsWithPaths();for(let{docName:t,filePath:S}of e)try{let e=readFileSync(S,`utf-8`);this.updateDocumentFromMarkdown(t,e)}catch(e){console.warn(`[tag-index] Failed to read ${t} during init:`,e)}}applyDocSnapshot(e,t,S){let w=this.state.byDoc.get(e)??new Set;for(let t of w){if(S.has(t))continue;let w=this.state.byTag.get(t);w&&(w.delete(e),w.size===0&&this.state.byTag.delete(t))}for(let t of S){let S=this.state.byTag.get(t);S||(S=new Set,this.state.byTag.set(t,S)),S.add(e)}S.size===0?(this.state.byDoc.delete(e),this.state.byDocLiteral.delete(e)):(this.state.byDoc.set(e,S),this.state.byDocLiteral.set(e,t))}listDocsWithPaths(){let e=[];this.walkContentDir(this.contentDir,e),e.sort((e,t)=>e.docName===t.docName?t.filePath.localeCompare(e.filePath):e.docName.localeCompare(t.docName));let t=new Set;return e.filter(({docName:e})=>t.has(e)?!1:(t.add(e),!0))}walkContentDir(e,t){let S;try{S=readdirSync(e,{withFileTypes:!0})}catch(t){console.warn(`[tag-index] Failed to read directory ${e}:`,t);return}for(let w of S){let S=join(e,w.name);if(w.isDirectory()){let e=relative(this.contentDir,S);if(this.contentFilter&&e&&this.contentFilter.isDirExcluded(e))continue;this.walkContentDir(S,t);continue}if(!w.isFile()||!isSupportedDocFile(w.name))continue;let E=relative(this.contentDir,S);this.contentFilter?.isExcluded(E)||t.push({docName:stripDocExtension(E),filePath:S})}}};const PARK_SNAPSHOT_ORIGIN=(()=>{let e=Object.freeze({origin:`park-snapshot`,paired:!0});return Object.freeze({source:`local`,skipStoreHooks:!1,context:e})})();function createServer$1(e){let{contentDir:t,projectDir:S=t,quiet:w=!0,debounce:E=2e3,maxDebounce:D=1e4,gitEnabled:O=!0,commitDebounceMs:k=3e4,wipRef:j=`refs/wip/main`,configHomedirOverride:F,enableTestRoutes:L=!1,shadowRepo:B,contentRoot:H,destroyTimeoutMs:q=1e4,localOpCliArgs:J,skipStateManifestCheck:Y=!1}=e,ee=getLogger(`server`);function te(){let e=readConfigSafely({absPath:resolveConfigPath(`project-local`,S),sideline:!1,warn:e=>ee.warn({message:e},`[config] could not read project-local config`)}),t=e.value.autoSync?.enabled;return t==null?(e.valid||ee.warn({},`[config] project-local autoSync.enabled unavailable (config invalid) — falling back to project config`),readConfigSafely({absPath:resolveConfigPath(`project`,S),sideline:!1,warn:e=>ee.warn({message:e},`[config] could not read project config`)}).value.autoSync?.enabled===!0):t===!0}initTelemetry();let ne=randomUUID(),ae=getLocalDir(S);if(acquireServerLock(ae,{port:e.port??0,worktreeRoot:S,kind:e.lockKind??`interactive`,capabilities:[`http`,`ws`]}),!Y)try{assertCompatibleStateManifest({lockDir:ae,shadowRepoDir:resolveShadowDir(S)})}catch(e){throw releaseServerLock(ae),e}let oe=createBasenameIndex(),se=(e,t)=>oe.resolveEmbed(e,t),ce=(e,S)=>{let w=oe.resolveEmbed(e,S);if(!w&&e.includes(`/`)&&(w=e.replace(/^\.?\//,``)),!w)return null;let E=resolve(t,w),D=resolve(t);if(E!==D&&!E.startsWith(`${D}/`))return null;try{let e=statSync(E);return e.isFile()?e.size:null}catch{return null}},ue,de,fe,me,ge,_e,ve,ye=null,Ce=null,we=null,Te=null,De=new Set,je=!1,Me,Pe,Ie,Re=new Promise((e,t)=>{Pe=e,Ie=t});function ze(e){ye?.signal(e)}let Be=2e3,Ve=null;function Ue(){Ve!==null&&clearTimeout(Ve),Ve=setTimeout(()=>{Ve=null,de.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist debounced cache:`,e)})},2e3)}let We=new RecentlyRemovedDocs(void 0,{onEviction:()=>incrementRecentlyRemovedDocsEviction(),onSizeChange:e=>setRecentlyRemovedDocsSize(e)}),Ge=(e,t)=>{isSystemDoc(e)||isConfigDoc(e)||We.setRenamed(e,t)},Ke=e=>{if(!(isSystemDoc(e)||isConfigDoc(e))){if(We.peek(e)?.kind===`renamed`){console.info(JSON.stringify({event:`recently-removed-docs-unpaired-delete-suppressed`,docName:e,source:`watcher-delete`}));return}We.setDeleted(e)}},Xe=e=>{isSystemDoc(e)||isConfigDoc(e)||We.delete(e)};try{ue=createContentFilter({projectDir:S,contentDir:t,onAfterRebuild:()=>{de.rebuildFromDisk(getActiveBranch()).catch(e=>{getLogger(`server-factory`).warn({err:e},`[content-filter] backlink-index rebuild failed after onAfterRebuild`)});try{fe.init()}catch(e){getLogger(`server-factory`).warn({err:e},`[content-filter] tag-index rebuild failed after onAfterRebuild`)}try{let e=Rt?.pruneFileIndexNowExcluded()??0,t=Rt?.pruneFolderIndexNowExcluded()??0,S=e+t;S>0&&getLogger(`server-factory`).info({pruned:S,prunedFiles:e,prunedFolders:t},`[content-filter] pruned now-excluded entries from file indexes`)}catch(e){getLogger(`server-factory`).warn({err:e},`[content-filter] file index prune failed after onAfterRebuild`)}}}),de=new BacklinkIndex({projectDir:S,contentDir:t,contentFilter:ue}),fe=new TagIndex({contentDir:t,contentFilter:ue});try{fe.init()}catch(e){console.warn(`[server-factory] tag-index init failed; continuing with empty index:`,e)}me={current:B},ge=createPersistenceExtension({contentDir:t,projectDir:S,gitEnabled:O,commitDebounceMs:k,wipRef:j,shadowRef:me,contentRoot:H,backlinkIndex:de,configHomedirOverride:F,getCurrentBranch:()=>zt?.getLastKnownBranch()??null,resolveEmbed:se,resolveSize:ce,getPrincipal:()=>Te,onAgentCommit:()=>ye?.signal(`session-activity`),onDiskFlush:(e,t)=>ye?.emitDiskAck(e,t),onConfigRejected:(e,t)=>ye?.emitConfigValidationRejected(e,t),mdManager:e.mdManager}),_e=new Hocuspocus({quiet:w,debounce:E,maxDebounce:D,extensions:[ge.extension]});let q=_e.shouldUnloadDocument.bind(_e);_e.shouldUnloadDocument=e=>{if(De.has(e)||je&&q(e))return!0;let t=e.name;return isSystemDoc(t)||isConfigDoc(t)||getReconciledBase(t)!==void 0||e.getXmlFragment(`default`).length!==0||e.getText(`source`).length!==0?!1:q(e)},Me=async e=>{De.add(e);try{await _e.unloadDocument(e)}finally{De.delete(e)}},ye=new CC1Broadcaster(_e),Ce=new AgentFocusBroadcaster(_e),we=new AgentPresenceBroadcaster(_e),ve=new AgentSessionManager(_e);let Y=createLiveDerivedIndexExtension({backlinkIndex:de,tagIndex:fe,signalChannel:ze});_e.configuration.extensions.push(Y),_e.configuration.extensions.push({__kind:`principal-auth`,async onAuthenticate(e){let t=e.token,S=parseHocuspocusAuthToken(t),w=S?.expectedServerInstanceId;if(typeof w==`string`&&w.length>0&&w!==ne)throw new HocuspocusAuthRejection(`server-instance-mismatch`,`server instance mismatch: client claimed ${w}, this server is ${ne}`);let E=S?.expectedBranch,D=getActiveBranch();if(typeof E==`string`&&E.length>0&&E!==D)throw new HocuspocusAuthRejection(`branch-mismatch`,`branch mismatch: client claimed ${E}, server is on ${D}`);if(!S)return;let O=e.context;typeof S.principalId==`string`&&(Te&&S.principalId===Te.id?O.principalId=Te.id:Te?console.warn(JSON.stringify({event:`principal-token-mismatch`,claimed:S.principalId,loaded:Te.id})):O.principalId=S.principalId),typeof S.tabSessionId==`string`&&(O.tabSessionId=S.tabSessionId),O.kind=`human`}}),_e.configuration.extensions.push({__kind:`config-doc-admission-guard`,async onAuthenticate(e){if(!isConfigDoc(e.documentName))return;let t=e.request,S=t.socket?.remoteAddress;if(S!==void 0&&!isLoopbackAddress(S))throw Error(`config-doc admission requires loopback peer (peer=${S}, doc=${e.documentName})`);let w=e.requestHeaders,E=(w&&typeof w.get==`function`?w.get(`host`):null)??t.headers?.host??void 0;if(!isAllowedWorkspaceHostHeader(E))throw Error(`config-doc admission requires loopback Host header (host=${E??`<absent>`}, doc=${e.documentName})`)}});let ee=resolve(t);function te(e){if(!isSafeDocName(e))return null;let t=resolve(ee,`${e}${getDocExtension(e)}`);return!t.startsWith(`${ee}/`)&&t!==ee?null:t}_e.configuration.extensions.push({__kind:`removal-redirect-guard`,async onAuthenticate(e){await runRemovalRedirectGuard(e.documentName,{recentlyRemovedDocs:We,resolveFilePath:te,fileExists:existsSync})}}),_e.configuration.extensions.push({__kind:`system-doc-broadcast-guard`,async beforeHandleMessage(e){if(e.documentName!==`__system__`)return;let t=new IncomingMessage(e.update);if(t.readVarString(),t.readVarUint()===MessageType.BroadcastStateless)throw Error(`inbound BroadcastStateless on ${SYSTEM_DOC_NAME} rejected — server-only channel`)}});let ae=createApiExtension({hocuspocus:_e,sessionManager:ve,contentDir:t,contentFilter:ue,serverInstanceId:ne,getFileIndex:()=>Rt?Rt.getFileIndex():new Map,getFolderIndex:()=>Rt?Rt.getFolderIndex():new Map,getAliasMap:()=>Rt?Rt.getAliasMap():new Map,rescanFiles:()=>Rt?.rescanFromDisk(),enableTestRoutes:L,shadowRef:me,flushGitCommit:()=>ge.flushPendingGitCommit(),flushContributors:()=>ge.flushContributors(),getCurrentBranch:()=>zt?.getLastKnownBranch()??null,getDiskAckSVs:()=>ye?.getLatestDiskAckSVsAsBase64()??{},contentRoot:H,backlinkIndex:de,tagIndex:fe,signalChannel:ze,agentFocusBroadcaster:Ce,agentPresenceBroadcaster:we,onAgentWrite:e.onAgentWrite,getSyncEngine:()=>Bt,localOpCliArgs:J,projectDir:S,resolveEmbed:se,getPrincipal:()=>Te,forceUnloadDocument:Me,ready:Re,recentlyRemovedDocs:We});_e.configuration.extensions.push(ae),_e.configuration.extensions.push(createServerObserverExtension({mdManager,schema,shadowRef:me,contentRoot:H,getCurrentBranch:()=>zt?.getLastKnownBranch()??null,resolveEmbed:se,resolveSize:ce})),_e.configuration.extensions.push(createSyncHandshakeSpanExtension())}catch(e){throw releaseServerLock(ae),e}let $e=null,nt=new Map,rt=[];function it(e,t){let S=resolve(e,`rescue`),w=resolve(S,`${t}${getDocExtension(t)}`);return w.startsWith(`${S}/`)?w:null}function at(e){let t=_e.documents.get(e);if(!t)return null;let{frontmatter:S,body:w}=stripFrontmatter(t.getText(`source`).toString());return prependFrontmatter(S,w)}let st=(e,t)=>applyExternalChange(_e,e,t,se,ce);function vt(e){let t=e.getMap(`lifecycle`);t.get(`status`)===`conflict`&&(t.delete(`status`),t.delete(`reason`))}let Tt=e=>{if(!e)return;let t=`[[${e}]]`;for(let[S]of _e.documents){if(isSystemDoc(S)||isConfigDoc(S))continue;let w=_e.documents.get(S);if(!w)continue;let E=w.getText(`source`).toString();if(E.includes(t))try{w.transact(()=>{applyDiskContentToDoc(w,E,se,S)},FILE_WATCHER_ORIGIN)}catch(t){ee.error({err:t,docName:S,assetBasename:e},`[asset-event] failed to re-render ${S} for asset basename ${e}`)}}},Et=null,Dt=e=>{e&&(Et===null&&(Et=new Set,setImmediate(()=>{let e=Et;if(Et=null,e)try{for(let t of e)Tt(t)}catch(t){ee.error({err:t,basenames:[...e]},`[asset-event] dedup rerender pass crashed`)}})),Et.add(e))};function jt(e){switch(e.kind){case`rename`:return e.newDocName;case`asset-create`:case`asset-delete`:case`folder-create`:case`folder-delete`:return e.relativePath;case`create`:case`update`:case`delete`:case`conflict`:return e.docName;default:return assertNeverDiskEvent(e)}}async function Mt(e){try{switch(e.kind){case`create`:ee.info({docName:e.docName},`[reconcile] create: ${e.docName}`),de.updateDocumentFromMarkdown(e.docName,e.content),Ue(),fe.updateDocumentFromMarkdown(e.docName,e.content),ze(`files`),ze(`backlinks`),ze(`graph`),ze(`tags`),Xe(e.docName);break;case`update`:{let{docName:t,content:S}=e,w=_e.documents.get(t);if(!w){de.updateDocumentFromMarkdown(t,S),Ue(),fe.updateDocumentFromMarkdown(t,S),ze(`backlinks`),ze(`graph`),ze(`tags`);return}let E=getReconciledBase(t)??``,D=at(t)??E,O=reconcile({docName:t,base:E,ours:D,theirs:S}),k=contentHash(E).slice(0,6),j=contentHash(D).slice(0,6),F=contentHash(S).slice(0,6);switch(ee.info({docName:t,base:k,ours:j,theirs:F,result:O.kind},`[reconcile] ${t} base=${k} ours=${j} theirs=${F} result=${O.kind}`),O.kind){case`noop`:vt(w),de.updateDocumentFromMarkdown(t,S),Ue(),fe.updateDocumentFromMarkdown(t,S),ze(`backlinks`),ze(`graph`),ze(`tags`);break;case`clean`:try{st(t,O.newContent),setReconciledBase(t,O.newContent),incrementReconcile(),vt(w),de.updateDocumentFromMarkdown(t,S),Ue(),fe.updateDocumentFromMarkdown(t,S),ze(`backlinks`),ze(`graph`),ze(`tags`)}catch(e){ee.error({err:e,docName:t},`[reconcile] failed to apply clean content to Y.Doc for ${t}`),setReconciledBase(t,S),vt(w)}break;case`merged`:try{st(t,O.newContent),setReconciledBase(t,O.newContent),incrementReconcile(),vt(w),de.updateDocumentFromMarkdown(t,S),Ue(),fe.updateDocumentFromMarkdown(t,S),ze(`backlinks`),ze(`graph`),ze(`tags`)}catch(e){ee.error({err:e,docName:t},`[reconcile] failed to apply merged content to Y.Doc for ${t}`),setReconciledBase(t,S),vt(w)}break;case`conflicts`:try{st(t,O.newContent),setReconciledBase(t,O.newContent),incrementReconcile(),incrementConflict(),de.updateDocumentFromMarkdown(t,S),Ue(),fe.updateDocumentFromMarkdown(t,S),ze(`backlinks`),ze(`graph`),ze(`tags`)}catch(e){ee.error({err:e,docName:t},`[reconcile] failed to apply conflict content to Y.Doc for ${t}`),setReconciledBase(t,S)}break;case`refused`:{incrementConflict();let e=w.getMap(`lifecycle`);e.set(`status`,`conflict`),e.set(`reason`,O.reason);break}}break}case`delete`:{let{docName:t}=e,S=_e.documents.get(t);if(!S){de.deleteDocument(t),Ue(),fe.deleteDocument(t),ze(`files`),ze(`backlinks`),ze(`graph`),ze(`tags`),Ke(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));return}let w=getReconciledBase(t)??``,E=at(t)??``,D=E!==w;if(D&&me.current){let e=me.current,S=zt?.getLastKnownBranch()??`main`;queueMicrotask(()=>{saveInMemoryCheckpoint(e,H??``,{kind:`external-change-rescue`,docName:t,contents:E,label:`External change recovered @ ${new Date().toISOString()}`,branch:S,metadata:{incomingDiskSha:``}}).then(()=>{incrementRescueBuffer(),ee.info({docName:t},`[reconcile] rescue checkpoint saved (delete): ${t}`)}).catch(e=>{ee.error({docName:t,err:e},`[reconcile] rescue checkpoint write failed: ${t}`)})})}S.getMap(`lifecycle`).set(`status`,`deleted-upstream`),deleteReconciledBase(t),de.deleteDocument(t),Ue(),fe.deleteDocument(t),ee.info({docName:t,isDirty:D},`[reconcile] delete: ${t} (dirty=${D})`),_e.closeConnections(t),await Me(S),ze(`files`),ze(`backlinks`),ze(`graph`),ze(`tags`),Ke(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));break}case`rename`:{let{oldDocName:t,newDocName:S,content:w}=e,E=_e.documents.get(t);if(deleteReconciledBase(t),setReconciledBase(S,w),de.renameDocument(t,S,w),Ue(),fe.renameDocument(t,S,w),E){let e=E.getMap(`lifecycle`);e.set(`status`,`renamed`),e.set(`newPath`,S)}ee.info({oldDocName:t,newDocName:S},`[reconcile] rename: ${t} → ${S}`),ze(`files`),ze(`backlinks`),ze(`graph`),ze(`tags`),Ge(t,S),console.info(JSON.stringify({event:`recently-removed-docs-populate`,from:t,to:S,kind:`renamed`,source:`watcher-rename`}));break}case`conflict`:{let{docName:t}=e,S=_e.documents.get(t);if(!S)return;let w=at(t);w===null?ee.warn({docName:t},`[reconcile] case 'conflict': serializeDoc returned null for ${t}; reconciledBase snapshot skipped — post-resolution reconcile may degrade to 3-way merge`):setReconciledBase(t,w);let E=S.getMap(`lifecycle`);E.set(`status`,`conflict`),E.set(`reason`,`conflict-markers`),ee.info({docName:t},`[reconcile] conflict markers detected: ${t}`);break}case`asset-create`:oe.add(e.relativePath),ze(`files`),Dt(basename(e.relativePath));break;case`asset-delete`:oe.remove(e.relativePath),ze(`files`),Dt(basename(e.relativePath));break;case`folder-create`:case`folder-delete`:ze(`files`);break;default:assertNeverDiskEvent(e)}}catch(t){let S=jt(e);ee.error({err:t,kind:e.kind,label:S},`[reconcile] failed to handle ${e.kind} for ${S}`)}}let Ft=[];async function It(e){if(isBatchInProgress()){Ft.push(e);return}await Mt(e)}async function Lt(){let e=Ft.splice(0,Ft.length);for(let t of e)await Mt(t)}let Rt=null,zt=null,Bt=null,Vt=null;async function Ht(e){if(_e.documents.size===0)return;let t=!1,S=new Promise(e=>{_e.configuration.extensions.push({async afterUnloadDocument({instance:S}){!t&&S.getDocumentsCount()===0&&(t=!0,e())}})}),w=Array.from(_e.documents.keys());_e.closeConnections(),_e.flushPendingStores();for(let e of _e.documents.values())e.getConnectionsCount()===0&&_e.unloadDocument(e).catch(t=>{console.warn(JSON.stringify({event:`ok-shutdown-unload-document-failed`,docName:e.name,reason:t instanceof Error?t.message:String(t)}))});let E,D=new Promise((S,D)=>{E=setTimeout(()=>{t=!0;let S=Array.from(_e.documents.keys()),E=[],O=[];if(me.current){for(let e of S)if(!(isSystemDoc(e)||isConfigDoc(e)))try{let t=at(e);if(t===null){ee.warn({docName:e},`[rescue] skipping ${e} — document dropped from map mid-rescue`),O.push(e);continue}let S=it(me.current.gitDir,e);if(!S){ee.warn({docName:e,gitDir:me.current.gitDir},`[rescue] path-traversal guard rejected docName: ${e}`),O.push(e);continue}mkdirSync(dirname(S),{recursive:!0}),writeFileSync(S,t,`utf-8`),incrementRescueBuffer(),E.push(e),ee.info({docName:e},`[rescue] rescue buffer saved on flush timeout: ${e}`)}catch(t){O.push(e),ee.error({err:t,docName:e},`[rescue] failed to write rescue buffer for ${e}`)}}else ee.warn({stillLoadedCount:S.length},`[rescue] shadow repo unavailable at flush timeout — ${S.length} doc(s) will be lost: [${S.join(`, `)}]`),O.push(...S);let k=E.length>0||O.length>0?` — rescued [${E.join(`, `)}]${O.length>0?`, lost [${O.join(`, `)}]`:``}`:``;D(Error(`flushAllStoresAndWait timeout after ${e}ms — ${S.length}/${w.length} docs did not unload: [${S.join(`, `)}]${k}`))},e)});try{await Promise.race([S,D])}finally{E!==void 0&&clearTimeout(E)}}async function Ut(){return Vt||(Vt=(async()=>{let e=Date.now(),t=[];je=!0,Ve!==null&&(clearTimeout(Ve),Ve=null);let w,E=await Promise.race([Re.then(()=>`completed`,e=>(ee.debug({err:e},`[server] init incomplete during shutdown`),`failed`)),new Promise(e=>{w=setTimeout(()=>e(`timeout`),5e3)})]);w!==void 0&&clearTimeout(w),E===`timeout`&&ee.warn({},`[server] init did not complete within 5s during shutdown`);let D=_e.documents.size;try{try{try{zt&&=(await zt.unsubscribe(),null),Rt&&=(await Rt.unsubscribe(),null);for(let{docName:e,cleanup:t}of rt)try{await t()}catch(t){ee.warn({err:t,docName:e},`[server] failed to stop config-file-watcher for ${e}`)}rt.length=0}catch(e){t.push({phase:`watcher-unsubscribe`,error:e instanceof Error?e.message:String(e)}),ee.error({err:e},`[server] shutdown phase-1 watcher unsubscribe failed`)}try{ye?.destroy(),we?.destroy(),$e&&=(await $e.disconnect(),null);for(let[e,t]of nt)try{await t.disconnect()}catch(t){ee.warn({err:t,docName:e},`[server] failed to disconnect ${e} during shutdown`)}nt.clear()}catch(e){t.push({phase:`cc1-teardown`,error:e instanceof Error?e.message:String(e)}),ee.error({err:e},`[server] shutdown phase-1b CC1 teardown failed`)}try{await ve.closeAll()}catch(e){t.push({phase:`agent-session-drain`,error:e instanceof Error?e.message:String(e)}),ee.error({err:e},`[server] shutdown phase-2 agent session drain failed`)}try{await Ht(q)}catch(e){t.push({phase:`flush-all-stores`,error:e instanceof Error?e.message:String(e)}),ee.error({err:e},`[server] shutdown phase-3 flush failed`)}let e;try{await Promise.race([(async()=>{await ge.flushPendingGitCommit(),await ge.waitForPendingCommits()})(),new Promise((t,S)=>{e=setTimeout(()=>S(Error(`L2 git flush timeout`)),q)})])}catch(e){t.push({phase:`git-commit-flush`,error:e instanceof Error?e.message:String(e)}),ee.error({err:e},`[server] shutdown phase-4 git commit flush failed`)}finally{e!==void 0&&clearTimeout(e)}try{Bt&&=(await Bt.destroy(),null)}catch(e){t.push({phase:`sync-engine-stop`,error:e instanceof Error?e.message:String(e)}),ee.error({err:e},`[server] shutdown sync-engine-stop failed`)}}finally{if(me.current){try{let e=(await esm_default({baseDir:S,timeout:{block:5e3}}).revparse(`HEAD`)).trim();e&&writeFileSync(resolve(me.current.gitDir,`last-known-head`),e,`utf-8`)}catch{}try{destroyShadowRepo(me.current)}catch(e){t.push({phase:`shadow-repo-release`,error:e instanceof Error?e.message:String(e)}),ee.error({err:e},`[server] shutdown phase-5 destroyShadowRepo failed`)}}let w=Date.now()-e;t.length===0?ee.info({documentCount:D,durationMs:w},`[server] shutdown flushed ${D} documents in ${w}ms`):ee.warn({documentCount:D,durationMs:w,phaseErrors:t},`[server] shutdown flushed ${D} documents in ${w}ms with ${t.length} phase error(s)`)}}finally{try{releaseServerLock(ae)}catch(e){t.push({phase:`server-lock-release`,error:e instanceof Error?e.message:String(e)}),ee.error({err:e},`[server] shutdown phase-6 releaseServerLock failed`)}try{await shutdownTelemetry()}catch(e){t.push({phase:`telemetry-shutdown`,error:e instanceof Error?e.message:String(e)})}}})(),Vt)}let Wt=[];async function Kt(){try{Te=await loadPrincipal(S),ee.info({principalId:Te.id},`[server] principal loaded`)}catch(e){ee.warn({err:e},`[server] principal load failed — browser writes will use SERVICE_WRITER`)}if(!me.current)try{me.current=await initShadowRepo(S),ee.info({gitDir:me.current.gitDir},`[server] history repo initialized at ${me.current.gitDir}`)}catch(e){ee.error({err:e},`[server] history repo init failed`),Wt.push(`shadow-repo`)}if(me.current){let e=null;try{e=loadRenameLogIndex(me.current.gitDir),sweepLazyPopOrphans(me.current.gitDir,e),setRenameLogIndex(me.current.gitDir,e),ee.info({entries:e.byTo.size},`[server] rename log loaded (${e.byTo.size} entries)`)}catch(e){ee.warn({err:e},`[rename-log] boot-time load/sweep failed; rename history unavailable`)}if(e){let t=1e4;try{await Promise.race([gcRenameLog(me.current,e,{rebuild:!0}),new Promise((e,S)=>setTimeout(()=>S(Error(`boot-time GC exceeded ${t}ms`)),t))])}catch(e){ee.warn({err:e},`[rename-log] boot-time GC/rebuild failed; index loaded without GC`)}}}if(me.current)try{await shadowGit(me.current).raw(`rev-parse`,`--git-dir`)}catch(e){let t=e instanceof Error?e.message:String(e);if(t.includes(`not a git repository`)||t.includes(`invalid object`)){ee.warn({},`[server] history repo appears corrupted — reinitializing`);try{me.current=await initShadowRepo(S)}catch(e){ee.error({err:e},`[server] history repo reinit failed`),me.current=void 0,Wt.includes(`shadow-repo`)||Wt.push(`shadow-repo`)}}else ee.error({err:e},`[server] history repo check failed (transient?)`)}if(me.current)try{let e=resolve(me.current.gitDir,`last-known-head`),t=null;try{t=readFileSync(e,`utf-8`).trim()||null}catch{}let w=null;try{w=(await esm_default({baseDir:S,timeout:{block:1e4}}).revparse(`HEAD`)).trim()||null}catch{}if(w!==null){if(w!==t){let e=`main`;try{let t=(await esm_default({baseDir:S,timeout:{block:1e4}}).raw(`rev-parse`,`--abbrev-ref`,`HEAD`)).trim();t&&t!==`HEAD`&&(e=t)}catch{}ee.info({lastKnownHead:t,currentHead:w,branch:e},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${w}, action=import`);try{await commitUpstreamImport(me.current,H??``,t,w,e),incrementUpstreamImport()}catch(e){ee.warn({err:e},`[head-drift] commitUpstreamImport failed — continuing`)}}else ee.info({currentHead:w},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${w}, action=noop`);try{writeFileSync(e,w,`utf-8`)}catch(e){ee.warn({err:e},`[head-drift] failed to write last-known-head`)}}}catch(e){ee.warn({err:e},`[head-drift] check failed — continuing`)}try{let e=recoverPendingManagedRename(t,S);if(e.recovered&&e.journal){let t=e.journal.version===2?e.journal.fromPath:e.journal.sourceDocName,S=e.journal.version===2?e.journal.toPath:e.journal.destinationDocName;ee.warn({journalVersion:e.journal.version,fromPath:t,toPath:S,restoredDocNames:e.restoredDocNames},`[managed-rename] recovered pending rename ${t} -> ${S}`)}}catch(e){ee.error({err:e},`[server] managed rename recovery failed`),Wt.push(`managed-rename-recovery`)}try{let e=cleanupOrphanUploadTempfiles(S);(e.deleted>0||e.errors>0)&&ee.info({scanned:e.scanned,deleted:e.deleted,errors:e.errors},`[upload-tempfile-sweep] swept ${e.deleted} orphan tempfile(s)`)}catch(e){ee.error({err:e},`[server] upload-tempfile sweep failed`),Wt.push(`upload-tempfile-sweep`)}try{$e=await _e.openDirectConnection(SYSTEM_DOC_NAME),ye?.emitServerInfo(ne,getActiveBranch())}catch(e){ee.error({err:e},`[server] failed to open __system__ direct connection — CC1 push disabled`),Wt.push(`cc1-push`)}for(let e of CONFIG_DOC_NAMES)try{let t=await _e.openDirectConnection(e);nt.set(e,t)}catch(t){ee.error({err:t,docName:e},`[server] failed to open ${e} direct connection — config bind degraded`),Wt.push(`config-doc:${e}`)}let e=new Map([[CONFIG_DOC_NAME_PROJECT,resolveConfigPath(`project`,S)],[CONFIG_DOC_NAME_PROJECT_LOCAL,resolveConfigPath(`project-local`,S)],[CONFIG_DOC_NAME_USER,resolveConfigPath(`user`,S,F)]]);for(let t of CONFIG_DOC_NAMES){let S=e.get(t);if(S)try{ee.info({docName:t,path:S},`[config-file-watcher] starting`);let e=await startConfigFileWatcher(S,e=>{let S=_e.documents.get(t);ee.info({docName:t,hasDocument:S!==void 0,contentLength:e.length},`[config-file-watcher] file changed`);let w=applyExternalConfigChange(S??null,t,e,ge.configPersistenceCtx);if(ee.info({docName:t,outcome:w},`[config-file-watcher] applyExternalConfigChange outcome`),t===`__config__/project`||t===`__local__/project`){let e=te();Bt?.setEnabled(e).catch(t=>{ee.warn({err:t,enabled:e},`[sync] failed to apply autoSync.enabled from config`)})}});rt.push({docName:t,cleanup:e}),ee.info({docName:t,path:S},`[config-file-watcher] started`)}catch(e){ee.warn({err:e,docName:t,path:S},`[config-file-watcher] failed to start for ${t}`),Wt.push(`config-file-watcher:${t}`)}}try{let e=resolve(t,`.okignore`),w=resolve(S,`.gitignore`),E=ee;E.info({okignorePath:e,gitignorePath:w},`[ignore-watcher] starting multi-path watcher for .okignore + .gitignore`);let D=await startMultiPathConfigFileWatcher([e,w],(t,w)=>{(async()=>{if(t===e)try{let e=applyExternalConfigChange(_e.documents.get(`__config__/okignore`)??null,CONFIG_DOC_NAME_OKIGNORE,w,ge.configPersistenceCtx);E.info({docName:CONFIG_DOC_NAME_OKIGNORE,outcome:e},`[ignore-watcher] applyExternalConfigChange outcome`)}catch(e){E.error({err:e,changedPath:relative(S,t)},`[ignore-watcher] applyExternalConfigChange failed; rebuild proceeds independently`)}let D=await ue.rebuildIgnorePatterns();if(D.ok)E.info({changedPath:relative(S,t),patternCount:D.patternCount,nestedFileCount:D.nestedFileCount,durationMs:D.durationMs},`[ignore-watcher] rebuild succeeded — broadcasting files channel`),ye?.signal(`files`);else{let e=relative(S,t)||`.`;E.warn({changedPath:e,error:D.error.message},`[ignore-watcher] rebuild failed — emitting config-ignore-nested-error`),ye?.emitConfigIgnoreNestedError(e,D.error.message)}})().catch(e=>{E.error({err:e,changedPath:relative(S,t)||`.`},`[ignore-watcher] handler threw`)})});rt.push({docName:`__ignore-files__`,cleanup:D}),E.info({okignorePath:e,gitignorePath:w},`[ignore-watcher] multi-path watcher started`)}catch(e){ee.warn({err:e,projectDir:S,contentDir:t},`[ignore-watcher] failed to start multi-path watcher`),Wt.push(`ignore-files-watcher`)}let w=resolveGitDir(S),E=w?readBranchFromHead(w)??`main`:`main`;switchReconciledBaseScope(E),de.switchBranch(E);try{{let e=getActiveBranch();try{if(await de.loadFromDisk(e)){let t=await de.reconcileWithDisk(e);(t.added>0||t.updated>0||t.deleted>0)&&ee.info(t,`[backlinks] startup reconcile: offline changes applied`)}else await de.rebuildFromDisk(e);de.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist startup cache for ${e}:`,t)})}catch(t){ee.error({err:t,branch:e},`[backlinks] startup init failed; index will populate incrementally via watcher`)}}Rt=await startWatcher(t,It,ue),fe.init();let e=0;try{seedBasenameIndex({contentDir:t,contentFilter:ue,basenameIndex:oe,onSkip:(t,S,w)=>{e++,ee.warn({reason:t,code:S,path:w},`[basename-index] skipped entry during seed (${t}${S?` ${S}`:``})`)}}),e>0&&(ee.warn({count:e},`[basename-index] startup seed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve`),Wt.push(`basename-index-partial`))}catch(e){ee.error({err:e},`[basename-index] startup seed failed`),Wt.push(`basename-index`)}}catch(e){ee.error({err:e},`[server] disk bridge watcher failed to start`),Wt.push(`file-watcher`)}try{zt=await startHeadWatcher(S,async({trigger:e})=>{if(ee.info({trigger:e},`[batch] begin trigger=${e}`),incrementBatch(),_e.flushPendingStores(),await ge.flushPendingGitCommit(),setBatchInProgress(!0),me.current){let e=getActiveBranch(),t=resolveGitDir(S),w=t?readBranchFromHead(t)??e:e,E=[];for(let[e,t]of _e.documents){if(isSystemDoc(e)||isConfigDoc(e))continue;let S=null;if(t.transact(()=>{S=at(e)},PARK_SNAPSHOT_ORIGIN),S===null)continue;let w=getReconciledBase(e)??S;E.push({docName:e,markdown:S,diskSnapshot:w})}if(E.length>0)try{let t=await parkBranch(me.current,e,SERVICE_WRITER.id,E,w);t&&(incrementPark(),ee.info({count:E.length,branch:e,sha:t.slice(0,8)},`[history] parked ${E.length} docs on ${e} → ${t.slice(0,8)}`))}catch(e){ee.error({err:e},`[shadow] park failed`)}}},async e=>{let S=Ft.length,w=e.newBranch??`main`;if(ee.info({kind:e.batchKind,headMoved:e.headMoved,docs:S,timeout:!!e.timeout},`[batch] end kind=${e.batchKind} headMoved=${e.headMoved} docs=${S}${e.timeout?` timeout`:``}`),e.batchKind===`within-branch`)setBatchInProgress(!1),await Lt(),await ge.flushDeferredStores(`within-branch`);else{incrementBranchSwitch(),Ft.splice(0,Ft.length),switchReconciledBaseScope(w),Ve!==null&&(clearTimeout(Ve),Ve=null),de.switchBranch(w),ue.rebuildDirCount();try{let e=0;oe.clear(),seedBasenameIndex({contentDir:t,contentFilter:ue,basenameIndex:oe,onSkip:(t,S,E)=>{e++,ee.warn({reason:t,code:S,path:E,branch:w},`[basename-index] skipped entry during branch-switch reseed (${t}${S?` ${S}`:``})`)}}),e>0&&(ee.warn({count:e,branch:w},`[basename-index] branch-switch reseed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve on this branch`),Wt.includes(`basename-index-partial`)||Wt.push(`basename-index-partial`))}catch(e){ee.error({err:e,branch:w},`[basename-index] branch-switch reseed failed`)}for(let[e,S]of _e.documents)if(!(isSystemDoc(e)||isConfigDoc(e)))try{let E=safeContentPath(e,t);if(!existsSync(E)){let t=getReconciledBase(e)??``,E=at(e)??``;if(E!==t&&me.current){let t=me.current;queueMicrotask(()=>{saveInMemoryCheckpoint(t,H??``,{kind:`external-change-rescue`,docName:e,contents:E,label:`External change recovered @ ${new Date().toISOString()}`,branch:w,metadata:{incomingDiskSha:``}}).then(()=>{incrementRescueBuffer(),ee.info({docName:e},`[reconcile] rescue checkpoint saved on branch switch: ${e}`)}).catch(t=>{ee.error({docName:e,err:t},`[reconcile] rescue checkpoint write failed: ${e}`)})})}S.getMap(`lifecycle`).set(`status`,`deleted-upstream`),ee.info({docName:e,branch:w},`[branch-switch] tombstone: ${e} (not on ${w})`);continue}let D=readFileSync(E,`utf-8`);st(e,D),setReconciledBase(e,D),ee.info({docName:e},`[branch-switch] reset: ${e}`)}catch(t){ee.error({err:t,docName:e},`[branch-switch] failed to reset ${e}`)}ee.info({branch:w,docCount:_e.documents.size},`[branch-switch] loaded branch ${w} (${_e.documents.size} docs)`);try{if(await de.loadFromDisk(w)){let e=await de.reconcileWithDisk(w);(e.added>0||e.updated>0||e.deleted>0)&&ee.info(e,`[backlinks] branch-switch reconcile for ${w}`)}else await de.rebuildFromDisk(w);de.saveToDisk(w).catch(e=>{console.warn(`[backlinks] Failed to persist branch cache for ${w}:`,e)})}catch(e){ee.error({err:e,branch:w},`[backlinks] branch-switch rebuild failed; backlinks may be stale`)}if(fe.init(),me.current&&e.batchKind===`cross-branch`){let e=0;for(let[t]of _e.documents)if(!(isSystemDoc(t)||isConfigDoc(t)))try{let S=await readParkedState(me.current,w,SERVICE_WRITER.id,t);if(!S||S.markdown===S.diskSnapshot)continue;let E=getReconciledBase(t);if(!E)continue;let D=reconcile({docName:t,base:S.diskSnapshot,ours:S.markdown,theirs:E});switch(D.kind){case`merged`:case`clean`:st(t,D.newContent),setReconciledBase(t,D.newContent),e++;break;case`conflicts`:st(t,D.newContent),setReconciledBase(t,D.newContent),incrementConflict(),e++;break;case`noop`:case`refused`:break}}catch(e){ee.error({err:e,docName:t},`[branch-switch] restore WIP failed for ${t}`)}e>0&&ee.info({count:e,branch:w},`[branch-switch] restored ${e} parked docs on ${w}`)}if(e.oldBranch?.startsWith(`detached-`)&&me.current)try{let t=shadowGit(me.current),S=(await t.raw(`for-each-ref`,`refs/wip/${e.oldBranch}/`,`--format=%(refname)`)).trim();if(S){for(let e of S.split(`
|
|
3229
|
-
`))e&&await t.raw(`update-ref`,`-d`,e);ee.info({context:e.oldBranch},`[branch-switch] cleaned up detached context ${e.oldBranch}`)}}catch(e){ee.error({err:e},`[branch-switch] detached cleanup failed`)}setBatchInProgress(!1),await ge.flushDeferredStores(`discard-stale`),ye?.emitBranchSwitched(w)}if(e.headMoved&&e.newHead&&me.current&&S>0){let t=H??`.`;try{let S=await commitUpstreamImport(me.current,t,e.oldHead,e.newHead,w);incrementUpstreamImport(),ee.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){ee.error({err:e},`[shadow] upstream-import failed`)}}})}catch(e){ee.error({err:e},`[server] HEAD watcher failed to start`),Wt.push(`head-watcher`)}let D=J?.[0]??`open-knowledge`,O=[`-c`,`credential.helper=!${J&&J.length>1?J.join(` `):D} auth git-credential`];try{Bt=new SyncEngine({projectDir:S,contentDir:t,contentFilter:ue,contentRoot:H,syncEnabled:te(),credentialArgs:O,cc1Broadcaster:ye,setBatchInProgress:e=>{setBatchInProgress(e),e||ge.flushDeferredStores(`within-branch`).catch(e=>{ee.error({err:e},`[persistence] deferred store drain failed after sync batch`)})},onStateChange:e=>{ee.info({state:e},`[sync] state → ${e}`)},onAutoDisable:async e=>{ee.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||ee.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 Bt.start()}catch(e){ee.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),Bt=null}ze(`files`),ze(`backlinks`),ze(`graph`),ze(`tags`)}return Kt().then(Pe,Ie),{hocuspocus:_e,sessionManager:ve,cc1Broadcaster:ye,agentFocusBroadcaster:Ce,agentPresenceBroadcaster:we,contentFilter:ue,basenameIndex:oe,serverInstanceId:ne,destroy:Ut,ready:Re,degraded:Wt,lockDir:ae,get syncEngine(){return Bt}}}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 w=resolve(e,t);try{existsSync(w)&&statSync(w).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;async function bootServer(e){initTelemetry();let{kind:t,gitdir:S}=computeWorktreeAttributes(e.projectDir??e.contentDir),w={"ok.worktree.kind":t};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,w=e.idleShutdownMs,E=e.log??getLogger(`boot`),D=process.env.OK_LOCK_KIND===`mcp-spawned`||process.env.OK_LOCK_KIND===`interactive`?process.env.OK_LOCK_KIND:void 0,O=e.lockKind??D??`interactive`,{createServer:k}=await import(`node:http`),{updateServerLockPort:j}=await import(`./server-lock-D7DXNVql-B5nINglj.mjs`).then(e=>e.a),F=!1;if(!t&&e.autoInitFn)try{F=!!await e.autoInitFn()}catch(e){E.warn({err:e},`autoInitFn failed`)}let L=e.projectDir??e.contentDir,B=resolve(L,`.ok`);if(!existsSync(resolve(B,`config.yml`)))throw new MissingOkConfigError(existsSync(B)?`config`:`okdir`,L);existsSync(resolve(B,`.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 H=findLegacyRuntimeFiles(B);H.length>0&&console.warn(`[boot] Found legacy runtime files at .ok/${H.join(`, `)}. Delete .ok/ and re-init — these files moved to .ok/${LOCAL_DIR}/.`);let q=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:O,skipStateManifestCheck:e.skipStateManifestCheck}),{hocuspocus:J,destroy:Y,ready:ee,degraded:te,lockDir:ne,sessionManager:ae,agentFocusBroadcaster:oe,agentPresenceBroadcaster:se}=q,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=createMcpHttpHandler({contentDir:e.contentDir,projectDir:e.projectDir??e.contentDir,config:e.config,getServerUrl:()=>`http://${ce}:${ue}`,log:E}),fe=k();fe.headersTimeout=3e4,fe.requestTimeout=6e4;let me=e.serveContentAssets?createAssetServeMiddleware({contentFilter:q.contentFilter,contentSirv:build_default(e.contentDir,{dev:!0,dotfiles:!1}),inlineExtensions:INLINE_RENDERABLE_EXTENSIONS,assetExtensions:ASSET_EXTENSIONS,blocklistExtensions:EXECUTABLE_BLOCKLIST_EXTENSIONS}):void 0;if(e.reactShellDistDir)try{acquireUiLock(ne,{port:0,worktreeRoot:e.projectDir??e.contentDir})}catch(e){throw await Y().catch(()=>{}),e}let ge=e.reactShellDistDir?build_default(e.reactShellDistDir,{single:!0,gzip:!0,immutable:!0}):void 0,_e=mountMcpAndApi({httpServer:fe,hocuspocus:J,mcpHttpHandler:de,log:E,sessionManager:ae,agentFocusBroadcaster:oe,agentPresenceBroadcaster:se,keepaliveGraceMs:e.keepaliveGraceMs,contentAssetMiddleware:me,reactShellMiddleware:ge}),ve=async()=>{throw Error(`bootServer: destroy() invoked before initialization — boot did not complete`)},ye=null;w!==null&&(ye=attachIdleShutdown({httpServer:fe,thresholdMs:w??DEFAULT_IDLE_THRESHOLD_MS,log:E,onShutdown:(e.idleShutdownHandler??(e=>async()=>{await e()}))(async()=>{await ve()})}));try{await new Promise((t,S)=>{let w=e=>S(e);fe.once(`error`,w),fe.listen(e.port,e.host,()=>{fe.removeListener(`error`,w),t()})})}catch(t){if(e.reactShellDistDir)try{releaseUiLock(ne)}catch(e){E.warn({err:e},`releaseUiLock failed during listen-error cleanup`)}throw await Y().catch(()=>{}),t}let Ce=fe.address(),we=typeof Ce==`object`&&Ce?Ce.port:e.port??0;if(ue=we,j(ne,we),e.reactShellDistDir&&updateUiLockPort(ne,we),S&&e.spawnUiSiblingFn)try{await e.spawnUiSiblingFn({lockDir:ne,log:E})}catch(e){E.warn({err:e},`spawnUiSiblingFn failed`)}let Te=!1,De=async(e,t)=>{let S;try{await Promise.race([t(),new Promise((t,w)=>{S=setTimeout(()=>{w(Error(`${e} timed out after ${DESTROY_STEP_TIMEOUT_MS}ms`))},DESTROY_STEP_TIMEOUT_MS),S.unref?.()})])}finally{S!==void 0&&clearTimeout(S)}};return ve=async()=>{if(Te)return;Te=!0;let t=[],S=async(e,S)=>{try{await De(e,S)}catch(S){t.push(S),E.warn({err:S,step:e},`bootServer destroy step failed`)}};try{ye?.detach()}catch(e){t.push(e),E.warn({err:e,step:`idleHandle.detach`},`bootServer destroy step failed`)}if(await S(`mount.shutdown`,()=>_e.shutdown()),await S(`mcpHttpHandler.close`,()=>de.close()),await S(`mount.wss.close`,()=>new Promise((e,t)=>{_e.wss.close(S=>S?t(S):e())})),await S(`httpServer.closeAllConnections`,async()=>{fe.closeAllConnections?.()}),await S(`httpServer.close`,()=>new Promise((e,t)=>{fe.close(S=>S&&S.code!==`ERR_SERVER_NOT_RUNNING`?t(S):e())})),await S(`destroyHocuspocus`,()=>Y()),e.reactShellDistDir&&await S(`releaseUiLock`,async()=>releaseUiLock(ne)),await S(`shutdownTelemetry`,()=>shutdownTelemetry()),t.length>0)throw AggregateError(t,`bootServer destroy completed with errors`)},{httpServer:fe,destroy:ve,lockDir:ne,contentDir:e.contentDir,port:we,ready:ee,degraded:te,didAutoInit:F,serverInstance:q}}const ConfigSchema=ConfigSchema$1;function detectClaudeDesktopPresence(e={}){let t=e.home??homedir(),S=e.platformName??process.platform,w=e.env??process.env;return S===`darwin`?existsSync(join(t,`Library`,`Application Support`,`Claude`)):S===`win32`?existsSync(join(w.APPDATA??join(t,`AppData`,`Roaming`),`Claude`)):!1}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 w=dirname(t);if(w===t)return null;t=w,S+=1}return null}const execFileAsync=promisify(execFile);var ProjectGitInitError=class extends Error{stderr;constructor(e,t=``,S){super(e,S),this.name=`ProjectGitInitError`,this.stderr=t}};async function isInsideExistingWorkTree(e){try{let{stdout:t}=await execFileAsync(`git`,[`rev-parse`,`--is-inside-work-tree`],{cwd:e});return t.trim()===`true`}catch{return!1}}async function ensureProjectGit(e){let t=resolve(e),S=resolve(t,`.git`),w=resolve(S,`HEAD`),E=!1;if(existsSync(S)){if(!statSync(S).isDirectory()||existsSync(w))return{didInit:!1};console.log(`[project-git] detected partial .git/ — running git init to repair`),E=!0}else if(await isInsideExistingWorkTree(t))return{didInit:!1};let D=``;try{D=(await execFileAsync(`git`,[`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(w))throw new ProjectGitInitError(`git init reported success but ${S}/HEAD is missing (partial init detected)`,D);return E?(console.log(`[project-git] backfilled missing .git/HEAD at ${t}`),{didInit:!0,repaired:!0}):(console.log(`[project-git] initialized .git/ at ${t} (branch: main)`),{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),w=0;w<32;w+=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 w=dirname(t);if(w===t)return;t=w}}export{assertNeverDiskEvent as $,rewriteWikiLinksForDocumentRename as $n,ALL_EDITOR_IDS as $r,incrementServerObserverFire as $t,MissingOkConfigError as A,_coercedNumber as Ai,readServerPackageVersion as An,tracedWriteFile as Ar,createStreamingErrorWriter as At,STARTER_PACK_IDS as B,registerWrite as Bn,writeTargetVersion as Br,formatAuthRejectionWire as Bt,LOG_MD_TEMPLATE as C,boolean$1 as Ci,parseAuthRejectionWire as Cn,tracedMkdir as Cr,createExternalChangeHandler as Ct,MCP_SERVER_NAME as D,object$1 as Di,planSeed as Dn,tracedRmSync as Dr,createPersistenceExtension as Dt,MCP_CONNECTION_ID_HEADER as E,number$1 as Ei,pathToDocName as En,tracedRenameSync as Er,createOsProbe as Et,SERVICE_WRITER as F,readUiLock as Fn,validateCloneInputs as Fr,errorResponse as Ft,StateManifestError as G,resolveContentDir as Gn,isInitializedNotification as Gr,getLocalDir as Gt,STATE_MANIFEST_FILENAME as H,removeLastKnownHash as Hn,McpServer as Hr,formatContributorsFrom as Ht,SKILL_INSTALL_EVENTS_FILE_REL as I,reconcile as In,validateSkillZip as Ir,evictStaleTrackerEntries as It,acquireUiLock as J,resolveLockDir as Jn,readConfigSafely as Jr,getMetrics as Jt,TagIndex as K,resolveCursorBinaryDefault as Kn,isJSONRPCRequest as Kr,getLogger as Kt,STARTER_FOLDERS as L,recordContributor as Ln,withSpan as Lr,extractWikiLinksFromMarkdown as Lt,PinoLogger as M,require_dist$2 as Mi,readStateManifest as Mn,updateLastKnownHash as Mr,detectClaudeDesktopPresence as Mt,ProjectGitInitError as N,readTargetRecordedAt as Nn,updateUiLockPort as Nr,detectProjectShape as Nt,MISSING_OK_CONFIG_MESSAGE as O,string$2 as Oi,readAllTargets as On,tracedRmdirSync as Or,createServer$1 as Ot,ROLLBACK_ORIGIN as P,readTargetVersion as Pn,validateAgentId as Pr,ensureProjectGit as Pt,assertCompatibleStateManifest as Q,rewriteMarkdownLinksForDocumentRename as Qn,MalformedGitPointerError as Qr,incrementCollabSocketFilteredError as Qt,STARTER_FOLDER_FRONTMATTER_FILENAME as R,recordSkillInstallEvent as Rn,withSpanSync as Rr,findEnclosingGitRoot as Rt,LIVE_DERIVED_INDEX_DEBOUNCE_MS as S,array as Si,normalizeFsPath as Sn,tracedLinkSync as Sr,createContentFilterAsync as St,MAX_AGENT_SESSIONS as T,looseObject as Ti,parseKeepaliveConnectionId as Tn,tracedRename as Tr,createMcpHttpHandler as Tt,SeedPrerequisiteError as U,resetMetrics as Un,JSONRPCMessageSchema as Ur,gcCheckpointRefs as Ut,STARTER_TEMPLATES as V,releaseUiLock as Vn,writeTracker as Vr,formatContributors as Vt,SeedRootDirError as W,resolveBundledSkillDir as Wn,LATEST_PROTOCOL_VERSION as Wr,getCurrentMcpLogger as Wt,applyExternalChange as X,resolvePackageVersion as Xn,writeConfigPatch as Xr,handleCollabSocketError as Xt,applyAgentMarkdownWrite as Y,resolvePack as Yn,resolveConfigPath as Yr,getTracer as Yt,applySeed as Z,restoreContributors as Zn,GitDirAccessError as Zr,handleSpawnCursor as Zt,GIT_UPSTREAM_WRITER as _,LOCAL_DIR as _i,listRescueCheckpoints as _n,startWatcher as _r,contentHash as _t,AgentPresenceBroadcaster as a,EXECUTABLE_BLOCKLIST_EXTENSIONS as ai,isAllowedApiOrigin as an,safeContentPath as ar,buildReadResult as at,HocuspocusAuthTokenSchema as b,ZodNumber$1 as bi,loggerFactory as bn,toBroadcasterKey as br,createAssetServeMiddleware as bt,BacklinkIndex as c,ProblemDetailsSchema as ci,isHocuspocusAuthRejectionReason as cn,sanitizeClientName as cr,buildWipTree as ct,CURSOR_BUNDLE_PATHS_BY_PLATFORM as d,colorFromSeed as di,isPairedWriteOrigin as dn,seedBasenameIndex as dr,clearContributors as dt,ASSET_EXTENSIONS as ei,initShadowRepo as en,runAuthReposSubprocess as er,attachIdleShutdown as et,ConfigSchema as f,defaultScheduler as fi,isPathWithinDir as fn,setActiveSpanAttributes as fr,coercePackId as ft,FILE_WATCHER_ORIGIN as g,CONFIG_SCHEMA_MAJOR_PATH as gi,lastKnownHash as gn,splitMarkdownBlocks as gr,containsConflictMarkers as gt,FILE_SYSTEM_WRITER as h,isOrphanMode as hi,isSystemDoc as hn,spawnDetached as hr,commitWipFromTree as ht,AgentFocusBroadcaster as i,EDITOR_LABELS as ii,installUserSkill as in,runWithMcpLogger as ir,buildInstructions as it,OBSERVER_SYNC_ORIGIN as j,NEVER as ji,readSkillInstallStateSnapshot as jn,tracedWriteFileSync as jr,createTestLogger as jt,McpLogger as k,url as ki,readBranchFromHead as kn,tracedUnlinkSync as kr,createServerObserverExtension as kt,CC1Broadcaster as l,SKILL_STATE_TARGETS as li,isKnownPackId as ln,saveInMemoryCheckpoint as lr,classifyEvents as lt,DEFAULT_PACK_ID as m,iconFromClientName as mi,isSelfWrite as mn,shutdownTelemetry as mr,commitWip as mt,AGENT_ID_RE as n,DEFAULT_GITHUB_OAUTH_CLIENT_ID as ni,installPrettyZodErrors as nn,runCloneSubprocess as nr,buildAndOpenSkill as nt,AgentSessionCapacityError as o,INLINE_RENDERABLE_EXTENSIONS as oi,isAllowedWorkspaceHostHeader as on,safeSubdir as or,buildSkillZip as ot,DEFAULT_CHECKPOINT_RETENTION as p,humanFormat as pi,isProjectRoot as pn,shadowGit as pr,commitUpstreamImport as pt,UiLockCollisionError as q,resolveCursorSpawnInvocation as qn,isJSONRPCResultResponse as qr,getMeter as qt,AGENT_WRITE_ORIGIN as r,DEFAULT_SERVER_HOST as ri,installTestLoggers as rn,runDeviceFlowSubprocess as rr,buildExecResult as rt,AgentSessionManager as s,ORPHAN_MODES as si,isConfigDoc as sn,safetyCheckpoint as sr,buildStarterFolderFrontmatterYaml as st,AGENT_ID_MAX_LEN as t,CC1_CONTRACT_VERSION as ti,initTelemetry as tn,runAuthStatusSubprocess as tr,bootServer as tt,CONFLICT_MARKER_RE as u,SYSTEM_DOC_NAME as ui,isLoopbackAddress as un,saveVersion as ur,classifyFsPath as ut,HOCUSPOCUS_AUTH_REJECTION_REASONS as v,OK_PROJECT_MARKER as vi,listStarterPacks as vn,streamingProblemEvent as vr,contributorCount as vt,MANAGED_RENAME_ORIGIN as w,literal as wi,parseHocuspocusAuthToken as wn,tracedMkdirSync as wr,createLiveDerivedIndexExtension as wt,INSTALLED_AGENTS_SCHEMES as x,any$1 as xi,mountMcpAndApi as xn,tracedAppendFileSync as xr,createContentFilter as xt,HocuspocusAuthRejection as y,locateIssue as yi,loadPrincipal as yn,swapContributors as yr,createApiExtension as yt,STARTER_PACKS as z,registerAllTools as zn,writeStateManifest as zr,findEnclosingProjectRoot as zt};
|
|
3230
|
-
//# sourceMappingURL=dist-
|
|
3210
|
+
`))e&&await t.raw(`update-ref`,`-d`,e);ee.info({context:e.oldBranch},`[branch-switch] cleaned up detached context ${e.oldBranch}`)}}catch(e){ee.error({err:e},`[branch-switch] detached cleanup failed`)}setBatchInProgress(!1),await ge.flushDeferredStores(`discard-stale`),ye?.emitBranchSwitched(w)}if(e.headMoved&&e.newHead&&me.current&&S>0){let t=H??`.`;try{let S=await commitUpstreamImport(me.current,t,e.oldHead,e.newHead,w);incrementUpstreamImport(),ee.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){ee.error({err:e},`[shadow] upstream-import failed`)}}})}catch(e){ee.error({err:e},`[server] HEAD watcher failed to start`),Wt.push(`head-watcher`)}let D=J?.[0]??`open-knowledge`,O=[`-c`,`credential.helper=!${J&&J.length>1?J.join(` `):D} auth git-credential`];try{Bt=new SyncEngine({projectDir:S,contentDir:t,contentFilter:ue,contentRoot:H,syncEnabled:te(),credentialArgs:O,cc1Broadcaster:ye,setBatchInProgress:e=>{setBatchInProgress(e),e||ge.flushDeferredStores(`within-branch`).catch(e=>{ee.error({err:e},`[persistence] deferred store drain failed after sync batch`)})},onStateChange:e=>{ee.info({state:e},`[sync] state → ${e}`)},onAutoDisable:async e=>{ee.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||ee.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 Bt.start()}catch(e){ee.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),Bt=null}ze(`files`),ze(`backlinks`),ze(`graph`),ze(`tags`)}return Kt().then(Pe,Ie),{hocuspocus:_e,sessionManager:ve,cc1Broadcaster:ye,agentFocusBroadcaster:Ce,agentPresenceBroadcaster:we,contentFilter:ue,basenameIndex:oe,serverInstanceId:ne,destroy:Ut,ready:Re,degraded:Wt,lockDir:ae,get syncEngine(){return Bt}}}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 w=resolve(e,t);try{existsSync(w)&&statSync(w).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;async function bootServer(e){initTelemetry();let{kind:t,gitdir:S}=computeWorktreeAttributes(e.projectDir??e.contentDir),w={"ok.worktree.kind":t};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,w=e.idleShutdownMs,E=e.log??getLogger(`boot`),D=process.env.OK_LOCK_KIND===`mcp-spawned`||process.env.OK_LOCK_KIND===`interactive`?process.env.OK_LOCK_KIND:void 0,O=e.lockKind??D??`interactive`,{createServer:k}=await import(`node:http`),{updateServerLockPort:j}=await import(`./server-lock-D7DXNVql-B5nINglj.mjs`).then(e=>e.a),F=!1;if(!t&&e.autoInitFn)try{F=!!await e.autoInitFn()}catch(e){E.warn({err:e},`autoInitFn failed`)}let L=e.projectDir??e.contentDir,B=resolve(L,`.ok`);if(!existsSync(resolve(B,`config.yml`)))throw new MissingOkConfigError(existsSync(B)?`config`:`okdir`,L);existsSync(resolve(B,`.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 H=findLegacyRuntimeFiles(B);H.length>0&&console.warn(`[boot] Found legacy runtime files at .ok/${H.join(`, `)}. Delete .ok/ and re-init — these files moved to .ok/${LOCAL_DIR}/.`);let q=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:O,skipStateManifestCheck:e.skipStateManifestCheck}),{hocuspocus:J,destroy:Y,ready:ee,degraded:te,lockDir:ne,sessionManager:ae,agentFocusBroadcaster:oe,agentPresenceBroadcaster:se}=q,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=createMcpHttpHandler({contentDir:e.contentDir,projectDir:e.projectDir??e.contentDir,config:e.config,getServerUrl:()=>`http://${ce}:${ue}`,log:E}),fe=k();fe.headersTimeout=3e4,fe.requestTimeout=6e4;let me=e.serveContentAssets?createAssetServeMiddleware({contentFilter:q.contentFilter,contentSirv:build_default(e.contentDir,{dev:!0,dotfiles:!1}),inlineExtensions:INLINE_RENDERABLE_EXTENSIONS,assetExtensions:ASSET_EXTENSIONS,blocklistExtensions:EXECUTABLE_BLOCKLIST_EXTENSIONS}):void 0;if(e.reactShellDistDir)try{acquireUiLock(ne,{port:0,worktreeRoot:e.projectDir??e.contentDir})}catch(e){throw await Y().catch(()=>{}),e}let ge=e.reactShellDistDir?build_default(e.reactShellDistDir,{single:!0,gzip:!0,immutable:!0}):void 0,_e=mountMcpAndApi({httpServer:fe,hocuspocus:J,mcpHttpHandler:de,log:E,sessionManager:ae,agentFocusBroadcaster:oe,agentPresenceBroadcaster:se,keepaliveGraceMs:e.keepaliveGraceMs,contentAssetMiddleware:me,reactShellMiddleware:ge}),ve=async()=>{throw Error(`bootServer: destroy() invoked before initialization — boot did not complete`)},ye=null;w!==null&&(ye=attachIdleShutdown({httpServer:fe,thresholdMs:w??DEFAULT_IDLE_THRESHOLD_MS,log:E,onShutdown:(e.idleShutdownHandler??(e=>async()=>{await e()}))(async()=>{await ve()})}));try{await new Promise((t,S)=>{let w=e=>S(e);fe.once(`error`,w),fe.listen(e.port,e.host,()=>{fe.removeListener(`error`,w),t()})})}catch(t){if(e.reactShellDistDir)try{releaseUiLock(ne)}catch(e){E.warn({err:e},`releaseUiLock failed during listen-error cleanup`)}throw await Y().catch(()=>{}),t}let Ce=fe.address(),we=typeof Ce==`object`&&Ce?Ce.port:e.port??0;if(ue=we,j(ne,we),e.reactShellDistDir&&updateUiLockPort(ne,we),S&&e.spawnUiSiblingFn)try{await e.spawnUiSiblingFn({lockDir:ne,log:E})}catch(e){E.warn({err:e},`spawnUiSiblingFn failed`)}let Te=!1,De=async(e,t)=>{let S;try{await Promise.race([t(),new Promise((t,w)=>{S=setTimeout(()=>{w(Error(`${e} timed out after ${DESTROY_STEP_TIMEOUT_MS}ms`))},DESTROY_STEP_TIMEOUT_MS),S.unref?.()})])}finally{S!==void 0&&clearTimeout(S)}};return ve=async()=>{if(Te)return;Te=!0;let t=[],S=async(e,S)=>{try{await De(e,S)}catch(S){t.push(S),E.warn({err:S,step:e},`bootServer destroy step failed`)}};try{ye?.detach()}catch(e){t.push(e),E.warn({err:e,step:`idleHandle.detach`},`bootServer destroy step failed`)}if(await S(`mount.shutdown`,()=>_e.shutdown()),await S(`mcpHttpHandler.close`,()=>de.close()),await S(`mount.wss.close`,()=>new Promise((e,t)=>{_e.wss.close(S=>S?t(S):e())})),await S(`httpServer.closeAllConnections`,async()=>{fe.closeAllConnections?.()}),await S(`httpServer.close`,()=>new Promise((e,t)=>{fe.close(S=>S&&S.code!==`ERR_SERVER_NOT_RUNNING`?t(S):e())})),await S(`destroyHocuspocus`,()=>Y()),e.reactShellDistDir&&await S(`releaseUiLock`,async()=>releaseUiLock(ne)),await S(`shutdownTelemetry`,()=>shutdownTelemetry()),t.length>0)throw AggregateError(t,`bootServer destroy completed with errors`)},{httpServer:fe,destroy:ve,lockDir:ne,contentDir:e.contentDir,port:we,ready:ee,degraded:te,didAutoInit:F,serverInstance:q}}const ConfigSchema=ConfigSchema$1;function detectClaudeDesktopPresence(e={}){let t=e.home??homedir(),S=e.platformName??process.platform,w=e.env??process.env;return S===`darwin`?existsSync(join(t,`Library`,`Application Support`,`Claude`)):S===`win32`?existsSync(join(w.APPDATA??join(t,`AppData`,`Roaming`),`Claude`)):!1}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 w=dirname(t);if(w===t)return null;t=w,S+=1}return null}const execFileAsync=promisify(execFile);var ProjectGitInitError=class extends Error{stderr;constructor(e,t=``,S){super(e,S),this.name=`ProjectGitInitError`,this.stderr=t}};async function isInsideExistingWorkTree(e){try{let{stdout:t}=await execFileAsync(`git`,[`rev-parse`,`--is-inside-work-tree`],{cwd:e});return t.trim()===`true`}catch{return!1}}async function ensureProjectGit(e){let t=resolve(e),S=resolve(t,`.git`),w=resolve(S,`HEAD`),E=!1;if(existsSync(S)){if(!statSync(S).isDirectory()||existsSync(w))return{didInit:!1};console.log(`[project-git] detected partial .git/ — running git init to repair`),E=!0}else if(await isInsideExistingWorkTree(t))return{didInit:!1};let D=``;try{D=(await execFileAsync(`git`,[`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(w))throw new ProjectGitInitError(`git init reported success but ${S}/HEAD is missing (partial init detected)`,D);return E?(console.log(`[project-git] backfilled missing .git/HEAD at ${t}`),{didInit:!0,repaired:!0}):(console.log(`[project-git] initialized .git/ at ${t} (branch: main)`),{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),w=0;w<32;w+=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 w=dirname(t);if(w===t)return;t=w}}export{assertNeverDiskEvent as $,runAuthReposSubprocess as $n,ASSET_EXTENSIONS as $r,initShadowRepo as $t,MissingOkConfigError as A,NEVER as Ai,readSkillInstallStateSnapshot as An,tracedWriteFileSync as Ar,createTestLogger as At,STARTER_PACK_IDS as B,releaseUiLock as Bn,writeTracker as Br,formatContributors as Bt,LOG_MD_TEMPLATE as C,literal as Ci,parseHocuspocusAuthToken as Cn,tracedMkdirSync as Cr,createLiveDerivedIndexExtension as Ct,MCP_SERVER_NAME as D,string$2 as Di,readAllTargets as Dn,tracedRmdirSync as Dr,createServer$1 as Dt,MCP_CONNECTION_ID_HEADER as E,object$1 as Ei,planSeed as En,tracedRmSync as Er,createPersistenceExtension as Et,SERVICE_WRITER as F,reconcile as Fn,validateSkillZip as Fr,evictStaleTrackerEntries as Ft,StateManifestError as G,resolveCursorBinaryDefault as Gn,isJSONRPCRequest as Gr,getLogger as Gt,STATE_MANIFEST_FILENAME as H,resetMetrics as Hn,JSONRPCMessageSchema as Hr,gcCheckpointRefs as Ht,SKILL_INSTALL_EVENTS_FILE_REL as I,recordContributor as In,withSpan as Ir,extractWikiLinksFromMarkdown as It,acquireUiLock as J,resolvePack as Jn,resolveConfigPath as Jr,getTracer as Jt,TagIndex as K,resolveCursorSpawnInvocation as Kn,isJSONRPCResultResponse as Kr,getMeter as Kt,STARTER_FOLDERS as L,recordSkillInstallEvent as Ln,withSpanSync as Lr,findEnclosingGitRoot as Lt,PinoLogger as M,readTargetRecordedAt as Mn,updateUiLockPort as Mr,detectProjectShape as Mt,ProjectGitInitError as N,readTargetVersion as Nn,validateAgentId as Nr,ensureProjectGit as Nt,MISSING_OK_CONFIG_MESSAGE as O,url as Oi,readBranchFromHead as On,tracedUnlinkSync as Or,createServerObserverExtension as Ot,ROLLBACK_ORIGIN as P,readUiLock as Pn,validateCloneInputs as Pr,errorResponse as Pt,assertCompatibleStateManifest as Q,rewriteWikiLinksForDocumentRename as Qn,ALL_EDITOR_IDS as Qr,incrementServerObserverFire as Qt,STARTER_FOLDER_FRONTMATTER_FILENAME as R,registerAllTools as Rn,writeStateManifest as Rr,findEnclosingProjectRoot as Rt,LIVE_DERIVED_INDEX_DEBOUNCE_MS as S,boolean$1 as Si,parseAuthRejectionWire as Sn,tracedMkdir as Sr,createExternalChangeHandler as St,MAX_AGENT_SESSIONS as T,number$1 as Ti,pathToDocName as Tn,tracedRenameSync as Tr,createOsProbe as Tt,SeedPrerequisiteError as U,resolveBundledSkillDir as Un,LATEST_PROTOCOL_VERSION as Ur,getCurrentMcpLogger as Ut,STARTER_TEMPLATES as V,removeLastKnownHash as Vn,McpServer as Vr,formatContributorsFrom as Vt,SeedRootDirError as W,resolveContentDir as Wn,isInitializedNotification as Wr,getLocalDir as Wt,applyExternalChange as X,restoreContributors as Xn,GitDirAccessError as Xr,handleSpawnCursor as Xt,applyAgentMarkdownWrite as Y,resolvePackageVersion as Yn,writeConfigPatch as Yr,handleCollabSocketError as Yt,applySeed as Z,rewriteMarkdownLinksForDocumentRename as Zn,MalformedGitPointerError as Zr,incrementCollabSocketFilteredError as Zt,GIT_UPSTREAM_WRITER as _,OK_PROJECT_MARKER as _i,listStarterPacks as _n,streamingProblemEvent as _r,contributorCount as _t,AgentPresenceBroadcaster as a,INLINE_RENDERABLE_EXTENSIONS as ai,isAllowedWorkspaceHostHeader as an,safeSubdir as ar,buildSkillZip as at,HocuspocusAuthTokenSchema as b,any$1 as bi,mountMcpAndApi as bn,tracedAppendFileSync as br,createContentFilter as bt,BacklinkIndex as c,SKILL_STATE_TARGETS as ci,isKnownPackId as cn,saveInMemoryCheckpoint as cr,classifyEvents as ct,CURSOR_BUNDLE_PATHS_BY_PLATFORM as d,defaultScheduler as di,isPathWithinDir as dn,setActiveSpanAttributes as dr,coercePackId as dt,CC1_CONTRACT_VERSION as ei,initTelemetry as en,runAuthStatusSubprocess as er,attachIdleShutdown as et,ConfigSchema as f,humanFormat as fi,isProjectRoot as fn,shadowGit as fr,commitUpstreamImport as ft,FILE_WATCHER_ORIGIN as g,LOCAL_DIR as gi,listRescueCheckpoints as gn,startWatcher as gr,contentHash as gt,FILE_SYSTEM_WRITER as h,CONFIG_SCHEMA_MAJOR_PATH as hi,lastKnownHash as hn,splitMarkdownBlocks as hr,containsConflictMarkers as ht,AgentFocusBroadcaster as i,EXECUTABLE_BLOCKLIST_EXTENSIONS as ii,isAllowedApiOrigin as in,safeContentPath as ir,buildInstructions as it,OBSERVER_SYNC_ORIGIN as j,require_dist$2 as ji,readStateManifest as jn,updateLastKnownHash as jr,detectClaudeDesktopPresence as jt,McpLogger as k,_coercedNumber as ki,readServerPackageVersion as kn,tracedWriteFile as kr,createStreamingErrorWriter as kt,CC1Broadcaster as l,SYSTEM_DOC_NAME as li,isLoopbackAddress as ln,saveVersion as lr,classifyFsPath as lt,DEFAULT_PACK_ID as m,isOrphanMode as mi,isSystemDoc as mn,spawnDetached as mr,commitWipFromTree as mt,AGENT_ID_RE as n,DEFAULT_SERVER_HOST as ni,installTestLoggers as nn,runDeviceFlowSubprocess as nr,buildAndOpenSkill as nt,AgentSessionCapacityError as o,ORPHAN_MODES as oi,isConfigDoc as on,safetyCheckpoint as or,buildStarterFolderFrontmatterYaml as ot,DEFAULT_CHECKPOINT_RETENTION as p,iconFromClientName as pi,isSelfWrite as pn,shutdownTelemetry as pr,commitWip as pt,UiLockCollisionError as q,resolveLockDir as qn,readConfigSafely as qr,getMetrics as qt,AGENT_WRITE_ORIGIN as r,EDITOR_LABELS as ri,installUserSkill as rn,runWithMcpLogger as rr,buildExecResult as rt,AgentSessionManager as s,ProblemDetailsSchema as si,isHocuspocusAuthRejectionReason as sn,sanitizeClientName as sr,buildWipTree as st,AGENT_ID_MAX_LEN as t,DEFAULT_GITHUB_OAUTH_CLIENT_ID as ti,installPrettyZodErrors as tn,runCloneSubprocess as tr,bootServer as tt,CONFLICT_MARKER_RE as u,colorFromSeed as ui,isPairedWriteOrigin as un,seedBasenameIndex as ur,clearContributors as ut,HOCUSPOCUS_AUTH_REJECTION_REASONS as v,locateIssue as vi,loadPrincipal as vn,swapContributors as vr,createApiExtension as vt,MANAGED_RENAME_ORIGIN as w,looseObject as wi,parseKeepaliveConnectionId as wn,tracedRename as wr,createMcpHttpHandler as wt,INSTALLED_AGENTS_SCHEMES as x,array as xi,normalizeFsPath as xn,tracedLinkSync as xr,createContentFilterAsync as xt,HocuspocusAuthRejection as y,ZodNumber$1 as yi,loggerFactory as yn,toBroadcasterKey as yr,createAssetServeMiddleware as yt,STARTER_PACKS as z,registerWrite as zn,writeTargetVersion as zr,formatAuthRejectionWire as zt};
|
|
3211
|
+
//# sourceMappingURL=dist-soQLoIV1.mjs.map
|