@inkeep/open-knowledge 0.9.0-beta.13 → 0.9.0-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/skills/discovery/SKILL.md +1 -1
- package/dist/assets/skills/project/SKILL.md +1 -1
- package/dist/cli.mjs +5 -5
- package/dist/constants-D9hc7LX4.mjs +2 -0
- package/dist/{dist-CpYAbkBw.mjs → dist-D-rWIekL.mjs} +1 -1
- package/dist/{dist-BBbP7DxV.mjs → dist-DKgq69uI.mjs} +3 -3
- package/dist/index.mjs +1 -1
- package/dist/init-BPJN5KYj.mjs +1 -0
- package/dist/{init-DIFyMBZs.mjs → init-BrOIE7gK.mjs} +4 -4
- package/dist/loader-BIxKasBW.mjs +1 -0
- package/dist/{loader-Mg7RInsh.mjs → loader-CxaZzLDi.mjs} +2 -2
- package/dist/{preview-BUNvNkcD.mjs → preview-BGoO3Ogd.mjs} +2 -2
- package/dist/preview-CcHJG_2a.mjs +1 -0
- package/dist/{repair-launch-json-CHoyWCeo.mjs → repair-launch-json-k1Ihx-tm.mjs} +2 -2
- package/dist/{repair-mcp-configs-Cbol0R2Q.mjs → repair-mcp-configs-s8YtscAj.mjs} +2 -2
- package/dist/repair-skills-BimjofqV.mjs +1 -0
- package/dist/{repair-skills-DL_fR7iS.mjs → repair-skills-D2S7rOZx.mjs} +2 -2
- package/dist/{src-gAvXPDY3.mjs → src-pmNhkR0H.mjs} +2 -2
- package/dist/start-NCx0aFju.mjs +1 -0
- package/dist/{start-CfcNOkrG.mjs → start-PfFarWKH.mjs} +2 -2
- package/dist/{write-project-skill-BNMnZE-x.mjs → write-project-skill-BQGm1G4f.mjs} +2 -2
- package/package.json +1 -1
- package/dist/constants-EfhRR_gr.mjs +0 -2
- package/dist/init-Cfa2w3tX.mjs +0 -1
- package/dist/loader-Cd8qUPSh.mjs +0 -1
- package/dist/preview-D2GxxtXj.mjs +0 -1
- package/dist/repair-skills-CaLjuijU.mjs +0 -1
- package/dist/start-DzCcS7aH.mjs +0 -1
|
@@ -3,7 +3,7 @@ name: open-knowledge-discovery
|
|
|
3
3
|
description: "Read when the user asks what Open Knowledge is, wants to install it on a repository, wants to share an Open Knowledge project with collaborators, or asks how `ok init` / `ok install-skill` / OK Desktop set up a project. Do NOT load to perform Open Knowledge reads/writes — the runtime guidance for editing markdown inside an initialized OK project ships as a separate project-local skill at `.claude/skills/open-knowledge/` whenever `ok init` runs. If the user appears to be editing markdown inside a `.ok/` project and this is the only OK skill loaded, advise them to re-run `ok init` to install the project-local skill."
|
|
4
4
|
compatibility: "Any agent host — no MCP server required. Pure discovery + install guidance."
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.9.0-beta.
|
|
6
|
+
version: "0.9.0-beta.14"
|
|
7
7
|
author: "Inkeep"
|
|
8
8
|
repository: "https://github.com/inkeep/open-knowledge"
|
|
9
9
|
---
|
|
@@ -3,7 +3,7 @@ name: open-knowledge
|
|
|
3
3
|
description: "MUST invoke before reading or editing any `.md` / `.mdx` file, and before any `mcp__open-knowledge__*` tool call (`exec`, `search`, `write_document`, `edit_document`, and the rest). This skill is installed into the repository by `ok init`, so its presence alone means this is an Open Knowledge project — its runtime contract governs every markdown file here, with no need to probe for a `.ok/` directory. Authoritative agent-runtime contract; supersedes the overlapping MCP server `instructions` echo."
|
|
4
4
|
compatibility: "Claude Code, Claude Desktop, Claude Cowork, Claude.ai web. Requires Open Knowledge MCP server + code execution."
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.9.0-beta.
|
|
6
|
+
version: "0.9.0-beta.14"
|
|
7
7
|
author: "Inkeep"
|
|
8
8
|
repository: "https://github.com/inkeep/open-knowledge"
|
|
9
9
|
---
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{o as e}from"./chunk-FK9Q3tQk.mjs";import{t}from"./esm-CEs3LWY3.mjs";import{Bi as n,Di as r,Li as i,Mi as a,Ni as o,Ri as s,Sn as c,Vr as l,Wi as u,Xi as d,c as f,da as p,f as m,ji as h,l as g,n as _,qi as v,s as y,ua as ee,vr as b,yi as x,zi as te,zr as ne}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{a as S,n as re,r as ie,t as ae}from"./gh-detect-D3_evne3.mjs";import{n as oe,r as se,t as C}from"./dist-bundle-BK4P1EQn.mjs";import{A as ce,C as le,D as ue,E as de,O as fe,S as pe,T as me,b as he,k as ge,o as _e,p as ve,w as ye,x as be}from"./init-
|
|
2
|
+
import{o as e}from"./chunk-FK9Q3tQk.mjs";import{t}from"./esm-CEs3LWY3.mjs";import{Bi as n,Di as r,Li as i,Mi as a,Ni as o,Ri as s,Sn as c,Vr as l,Wi as u,Xi as d,c as f,da as p,f as m,ji as h,l as g,n as _,qi as v,s as y,ua as ee,vr as b,yi as x,zi as te,zr as ne}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{a as S,n as re,r as ie,t as ae}from"./gh-detect-D3_evne3.mjs";import{n as oe,r as se,t as C}from"./dist-bundle-BK4P1EQn.mjs";import{A as ce,C as le,D as ue,E as de,O as fe,S as pe,T as me,b as he,k as ge,o as _e,p as ve,w as ye,x as be}from"./init-BrOIE7gK.mjs";import{r as xe}from"./git-handle-uz8TUFSi-DaMTjKLA.mjs";import{A as Se,Ci as Ce,Ei as we,K as Te,Nt as Ee,Ti as De,X as Oe,_i as ke,ar as Ae,b as je,dr as Me,gi as Ne,h as Pe,hi as Fe,hn as Ie,in as Le,it as Re,j as ze,kn as Be,kr as Ve,mi as He,mr as w,ot as Ue,pi as We,pt as Ge,q as Ke,qn as qe,ut as Je,vi as Ye,vn as Xe,wi as Ze,x as Qe,xi as $e}from"./dist-DKgq69uI.mjs";import{t as et}from"./yazl-DjRp4wSy.mjs";import{n as tt,t as nt}from"./constants-D9hc7LX4.mjs";import{i as rt}from"./src-pmNhkR0H.mjs";import{n as it,t as at}from"./loader-CxaZzLDi.mjs";import{c as ot,f as st,h as ct,m as lt,p as ut,u as dt}from"./start-PfFarWKH.mjs";import{c as ft,i as pt,n as T,o as E,r as D,s as mt,t as O}from"./colors-BtKMHmBX.mjs";import{n as ht}from"./repair-skills-D2S7rOZx.mjs";import{execSync as gt,spawn as _t,spawnSync as k}from"node:child_process";import vt,{basename as A,dirname as yt,isAbsolute as bt,join as j,relative as xt,resolve as M,sep as St}from"node:path";import{accessSync as Ct,closeSync as wt,constants as Tt,cpSync as Et,createWriteStream as Dt,existsSync as N,lstatSync as Ot,mkdirSync as P,mkdtempSync as kt,openSync as At,readFileSync as F,readdirSync as jt,realpathSync as Mt,rmSync as Nt,statSync as Pt,unlinkSync as Ft,writeFileSync as I}from"node:fs";import It from"node:process";import{arch as Lt,freemem as Rt,homedir as zt,hostname as Bt,platform as Vt,release as Ht,tmpdir as Ut,totalmem as Wt,type as Gt,uptime as Kt}from"node:os";import{fileURLToPath as qt}from"node:url";import{AsyncLocalStorage as Jt,AsyncResource as Yt}from"node:async_hooks";import{stripVTControlCharacters as Xt,styleText as L}from"node:util";import*as Zt from"node:readline";import{createHash as Qt,randomUUID as $t}from"node:crypto";import{realpath as en}from"node:fs/promises";import{setTimeout as tn}from"node:timers/promises";import{createInterface as nn}from"node:readline/promises";async function rn(e,t,n){let r=an(await on(e)).host??``;if(!r)return 1;let i=await n.get(r);if(i==null)return 1;let a=e=>e.replace(/[\r\n]/g,``);return t.write(`username=${a(i.login)}\npassword=${a(i.token)}\n`),0}function an(e){let t={};for(let n of e.split(`
|
|
3
3
|
`)){let e=n.trim();if(e===``)continue;let r=e.indexOf(`=`);r!==-1&&(t[e.slice(0,r)]=e.slice(r+1))}return t}function on(e){return new Promise((t,n)=>{let r=[];e.on(`data`,e=>r.push(e)),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf-8`))),e.on(`error`,n)})}function sn(e){let n=new t(`git-credential`);return n.description(`Git credential helper (git credential-helper protocol)`),n.command(`get`).description(`Lookup credentials from TokenStore (called by git)`).action(async()=>{let t=await e(),n=await rn(process.stdin,process.stdout,t);process.exit(n)}),n}function cn(e){let t=e.endpoint.DEFAULTS;return/^https:\/\/(api\.)?github\.com$/.test(t.baseUrl)?`https://github.com`:t.baseUrl.replace(`/api/v3`,``)}async function ln(e,t,n){let r={baseUrl:cn(e),headers:{accept:`application/json`},...n},i=await e(t,r);if(`error`in i.data){let n=new oe(`${i.data.error_description} (${i.data.error}, ${i.data.error_uri})`,400,{request:e.endpoint.merge(t,r)});throw n.response=i,n}return i}async function un(e){let t=e.request||C,n={client_id:e.clientId};return`scopes`in e&&Array.isArray(e.scopes)&&(n.scope=e.scopes.join(` `)),ln(t,`POST /login/device/code`,n)}async function dn(e){let t=await ln(e.request||C,`POST /login/oauth/access_token`,{client_id:e.clientId,device_code:e.code,grant_type:`urn:ietf:params:oauth:grant-type:device_code`}),n={clientType:e.clientType,clientId:e.clientId,token:t.data.access_token,scopes:t.data.scope.split(/\s+/).filter(Boolean)};if(`clientSecret`in e&&(n.clientSecret=e.clientSecret),e.clientType===`github-app`){if(`refresh_token`in t.data){let e=new Date(t.headers.date).getTime();n.refreshToken=t.data.refresh_token,n.expiresAt=fn(e,t.data.expires_in),n.refreshTokenExpiresAt=fn(e,t.data.refresh_token_expires_in)}delete n.scopes}return{...t,authentication:n}}function fn(e,t){return new Date(e+t*1e3).toISOString()}async function pn(e,t){let n=mn(e,t.auth);if(n)return n;let{data:r}=await un({clientType:e.clientType,clientId:e.clientId,request:t.request||e.request,scopes:t.auth.scopes||e.scopes});await e.onVerification(r);let i=await gn(t.request||e.request,e.clientId,e.clientType,r);return e.authentication=i,i}function mn(e,t){if(t.refresh===!0||!e.authentication)return!1;if(e.clientType===`github-app`)return e.authentication;let n=e.authentication;return(`scopes`in t&&t.scopes||e.scopes).join(` `)===n.scopes.join(` `)?n:!1}async function hn(e){await new Promise(t=>setTimeout(t,e*1e3))}async function gn(e,t,n,r){try{let i={clientId:t,request:e,code:r.device_code},{authentication:a}=n===`oauth-app`?await dn({...i,clientType:`oauth-app`}):await dn({...i,clientType:`github-app`});return{type:`token`,tokenType:`oauth`,...a}}catch(i){if(!i.response)throw i;let a=i.response.data.error;if(a===`authorization_pending`)return await hn(r.interval),gn(e,t,n,r);if(a===`slow_down`)return await hn(r.interval+7),gn(e,t,n,r);throw i}}async function _n(e,t){return pn(e,{auth:t})}async function vn(e,t,n,r){let i=t.endpoint.merge(n,r);if(/\/login\/(oauth\/access_token|device\/code)$/.test(i.url))return t(i);let{token:a}=await pn(e,{request:t,auth:{type:`oauth`}});return i.headers.authorization=`token ${a}`,t(i)}var yn=`0.0.0-development`;function bn(e){let t=e.request||C.defaults({headers:{"user-agent":`octokit-auth-oauth-device.js/${yn} ${se()}`}}),{request:n=t,...r}=e,i=e.clientType===`github-app`?{...r,clientType:`github-app`,request:n}:{...r,clientType:`oauth-app`,request:n,scopes:e.scopes||[]};if(!e.clientId)throw Error(`[@octokit/auth-oauth-device] "clientId" option must be set (https://github.com/octokit/auth-oauth-device.js#usage)`);if(!e.onVerification)throw Error(`[@octokit/auth-oauth-device] "onVerification" option must be a function (https://github.com/octokit/auth-oauth-device.js#usage)`);return Object.assign(_n.bind(null,i),{hook:vn.bind(null,i)})}async function xn(e){let{clientId:t,scopes:n=[`repo`,`read:user`,`user:email`],onVerification:r,host:i}=e,a=i&&i!==`github.com`?`https://${i}/api/v3`:`https://api.github.com`,o=bn({clientType:`oauth-app`,clientId:t,scopes:n,onVerification:async e=>{await r({verificationUri:e.verification_uri,userCode:e.user_code,expiresIn:e.expires_in,interval:e.interval})},request:a===`https://api.github.com`?void 0:(await import(`./dist-bundle-CjV1Pdeo.mjs`)).request.defaults({baseUrl:a})}),s;try{s=await o({type:`oauth`})}catch(e){if(e instanceof Error){let t=e.message.toLowerCase();throw t.includes(`access_denied`)?Error(`Device-flow authorization was denied.`):t.includes(`expired_token`)||t.includes(`timeout`)||t.includes(`timed out`)?Error(`Device-flow code expired before authorization — please try again.`):Error(`GitHub sign-in failed: ${e.message}`)}throw e}return{token:s.token,tokenType:s.tokenType,scopes:s.scopes??[]}}const Sn={invalid_type:`invalid_type`,too_big:`too_big`,too_small:`too_small`,invalid_format:`invalid_format`,not_multiple_of:`not_multiple_of`,unrecognized_keys:`unrecognized_keys`,invalid_union:`invalid_union`,invalid_key:`invalid_key`,invalid_element:`invalid_element`,invalid_value:`invalid_value`,custom:`custom`};var Cn;(function(e){})(Cn||={});function wn(e){return d(r,e)}function Tn(){return process.env.OPEN_KNOWLEDGE_GITHUB_CLIENT_ID??`Ov23liqlSd0V1MwR6rhI`}const En=new Set([`gitlab.com`,`bitbucket.org`,`codeberg.org`,`gitea.com`,`sr.ht`,`sourcehut.org`]);function R(e){let t=e.toLowerCase().replace(/:\d+$/,``);En.has(t)&&(process.stderr.write(`Error: ${e} is not a GitHub host. Only GitHub and GitHub Enterprise Server are supported.\n`),process.exit(1))}function Dn(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function On(e,t,n=xn){let r=Tn(),{host:i,json:a}=e;R(i),a||process.stderr.write(`Logging in to ${i}\n`);let o=await n({clientId:r,host:i===`github.com`?void 0:i,onVerification:e=>{e.userCode,e.verificationUri,a?Dn(!0,{type:`verification`,user_code:e.userCode,verification_uri:e.verificationUri,expires_in:e.expiresIn}):process.stderr.write(`Open: ${e.verificationUri}\nEnter code: ${e.userCode}\n`)}}),s=`unknown`,c,l;try{let e=i===`github.com`?`https://api.github.com`:`https://${i}/api/v3`,t=await fetch(`${e}/user`,{headers:{Authorization:`Bearer ${o.token}`,"User-Agent":`open-knowledge-cli`,Accept:`application/vnd.github+json`}});if(t.ok){let e=await t.json();s=e.login??s,c=e.name??void 0,l=e.email??void 0}}catch{}await t.set(i,s,o.token,{gitProtocol:`https`,name:c,email:l}),a?Dn(!0,{type:`complete`,host:i,login:s}):process.stderr.write(`✓ Logged in as ${s} on ${i}\n`)}function kn(e){return new t(`login`).description(`Authenticate with GitHub via Device Flow`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{await On(t,await e())})}const An=e=>e.name===`enter`||e.name===`return`;var jn=class extends Error{name=`AbortPromptError`;message=`Prompt was aborted`;constructor(e){super(),this.cause=e?.cause}},Mn=class extends Error{name=`CancelPromptError`;message=`Prompt was canceled`},Nn=class extends Error{name=`ExitPromptError`},Pn=class extends Error{name=`HookError`},Fn=class extends Error{name=`ValidationError`};const In=new Jt;function Ln(e){return{rl:e,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function Rn(e,t){let n=Ln(e);return In.run(n,()=>{function e(e){n.handleChange=()=>{n.index=0,e()},n.handleChange()}return t(e)})}function z(){let e=In.getStore();if(!e)throw new Pn(`[Inquirer] Hook functions can only be called from within a prompt`);return e}function zn(){return z().rl}function Bn(e){return Yt.bind((...t)=>{let n=z(),r=!1,i=n.handleChange;n.handleChange=()=>{r=!0};let a=e(...t);return r&&i(),n.handleChange=i,a})}function Vn(e){let t=z(),{index:n}=t,r=e({get(){return t.hooks[n]},set(e){t.hooks[n]=e},initialized:n in t.hooks});return t.index++,r}function Hn(){z().handleChange()}const Un={queue(e){let t=z(),{index:n}=t;t.hooksEffect.push(()=>{t.hooksCleanup[n]?.();let r=e(zn());if(r!=null&&typeof r!=`function`)throw new Fn(`useEffect return value must be a cleanup function or nothing.`);t.hooksCleanup[n]=r})},run(){let e=z();Bn(()=>{e.hooksEffect.forEach(e=>{e()}),e.hooksEffect.length=0})()},clearAll(){let e=z();e.hooksCleanup.forEach(e=>{e?.()}),e.hooksEffect.length=0,e.hooksCleanup.length=0}};function Wn(e){return typeof e==`function`}function B(e){return Vn(t=>{let n=Yt.bind(function(e){t.get()!==e&&(t.set(e),Hn())});if(t.initialized)return[t.get(),n];let r=Wn(e)?e():e;return t.set(r),[r,n]})}function Gn(e,t){Vn(n=>{let r=n.get();(!Array.isArray(r)||t.some((e,t)=>!Object.is(e,r[t])))&&Un.queue(e),n.set(t)})}const Kn={prefix:{idle:L(`blue`,`?`),done:L(`green`,ce.tick)},spinner:{interval:80,frames:[`⠋`,`⠙`,`⠹`,`⠸`,`⠼`,`⠴`,`⠦`,`⠧`,`⠇`,`⠏`].map(e=>L(`yellow`,e))},style:{answer:e=>L(`cyan`,e),message:e=>L(`bold`,e),error:e=>L(`red`,`> ${e}`),defaultAnswer:e=>L(`dim`,`(${e})`),help:e=>L(`dim`,e),highlight:e=>L(`cyan`,e),key:e=>L(`cyan`,L(`bold`,`<${e}>`))}};function qn(e){if(typeof e!=`object`||!e)return!1;let t=e;for(;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function Jn(...e){let t={};for(let n of e)for(let[e,r]of Object.entries(n)){let n=t[e];t[e]=qn(n)&&qn(r)?Jn(n,r):r}return t}function Yn(...e){return Jn(Kn,...e.filter(e=>e!=null))}function Xn({status:e=`idle`,theme:t}){let[n,r]=B(!1),[i,a]=B(0),{prefix:o,spinner:s}=Yn(t);return Gn(()=>{if(e===`loading`){let e,t=-1,n=setTimeout(()=>{r(!0),e=setInterval(()=>{t+=1,a(t%s.frames.length)},s.interval)},300);return()=>{clearTimeout(n),clearInterval(e)}}else r(!1)},[e]),n?s.frames[i]:typeof o==`string`?o:o[e===`loading`?`idle`:e]??o.idle}function Zn(e){return B({current:e})[0]}function Qn(e){let t=Zn(e);t.current=e,Gn(e=>{let n=!1,r=Bn((r,i)=>{n||t.current(i,e)});return e.input.on(`keypress`,r),()=>{n=!0,e.input.removeListener(`keypress`,r)}},[])}var $n=e(ge(),1);function er(e,t){return e.split(`
|
|
4
4
|
`).flatMap(e=>fe(e,t,{trim:!1,hard:!0}).split(`
|
|
5
5
|
`).map(e=>e.trimEnd())).join(`
|
|
@@ -20,10 +20,10 @@ import{o as e}from"./chunk-FK9Q3tQk.mjs";import{t}from"./esm-CEs3LWY3.mjs";impor
|
|
|
20
20
|
`),patterns:[...t],lineCount:n}}const yi=j(zt(),`.ok`,`logs`),bi=j(zt(),`.ok`,`bug-reports`);function xi(e){let t=j(e,`.ok`,`config.yml`);if(N(t))try{let e=F(t,`utf8`).match(/^\s*name:\s*['"]?(.+?)['"]?\s*$/m);if(e?.[1])return e[1]}catch{}return N(j(e,`.ok`))?Qt(`sha256`).update(M(e)).digest(`hex`).slice(0,12):null}function Si(){let e={timestamp:new Date().toISOString(),platform:Vt(),osType:Gt(),osRelease:Ht(),hostname:`[redacted]`,uptime:Kt(),freeMem:Rt(),totalMem:Wt(),nodeVersion:process.version,bunVersion:process.versions.bun??null,v8Version:process.versions.v8??null,pid:process.pid};try{e.macosVersion=gt(`sw_vers -productVersion 2>/dev/null`,{encoding:`utf8`}).trim()}catch{}try{let t=j(__dirname,`..`,`..`,`package.json`);N(t)&&(e.okVersion=JSON.parse(F(t,`utf8`)).version)}catch{}return e}function Ci(e){if(!N(yi))return{files:[],dir:yi};let t=jt(yi).filter(e=>e.endsWith(`.log`)||/\.log\.\d+$/.test(e)).map(e=>j(yi,e));if(e&&t.length>0){let n=t.filter(t=>{try{return F(t,`utf8`).includes(`"project":"${e}"`)}catch{return!0}});n.length>0&&(t=n)}return{files:t,dir:yi}}function wi(e){let t=j(e,`.ok`,`local`);return N(t)?{files:[`server.lock`,`last-spawn-error.log`].map(e=>j(t,e)).filter(e=>N(e)),dir:t}:{files:[],dir:null}}function Ti(e){let t=j(e,`.ok`,`local`,`logs`);return N(t)?{files:[`server-current.jsonl`,`server-prev.jsonl`].map(e=>j(t,e)).filter(e=>N(e)),dir:t}:{files:[],dir:null}}async function Ei(t){let n=$l();P(bi,{recursive:!0});let r=j(bi,`${new Date().toISOString().replace(/[:.]/g,`-`)}-bugreport.zip`);n?.info({projectSlug:t.projectSlug},`gathering diagnostic data`);let i=Si(),{files:a}=Ci(t.projectSlug),{files:o}=wi(t.cwd),{files:s}=Ti(t.cwd);n?.info({logFileCount:a.length,lockFileCount:o.length,localSinkFileCount:s.length},`files collected`);let c=[],l=[],{ZipFile:u}=await import(`./yazl-CJayzk0b.mjs`).then(t=>e(t.default,1)),d=new u;for(let e of a)try{let{redacted:t,patterns:n,lineCount:r}=vi(F(e,`utf8`)),i=`logs/${A(e)}`;d.addBuffer(Buffer.from(t,`utf8`),i),l.push(i),n.length>0&&c.push({file:i,lineCount:r,patterns:n})}catch{}for(let e of o)try{let{redacted:t,patterns:n,lineCount:r}=vi(F(e,`utf8`)),i=`lockdir/${A(e)}`;d.addBuffer(Buffer.from(t,`utf8`),i),l.push(i),n.length>0&&c.push({file:i,lineCount:r,patterns:n})}catch{}for(let e of s)try{let{redacted:t,patterns:n,lineCount:r}=vi(F(e,`utf8`)),i=`local-logs/${A(e)}`;d.addBuffer(Buffer.from(t,`utf8`),i),l.push(i),n.length>0&&c.push({file:i,lineCount:r,patterns:n})}catch{}let f=JSON.stringify(i,null,2);d.addBuffer(Buffer.from(f,`utf8`),`sysinfo.json`),l.push(`sysinfo.json`);let p={generatedAt:new Date().toISOString(),disciplineVersion:`1.0.0`,projectSlug:t.projectSlug,files:l,redactions:c,sysinfo:i};d.addBuffer(Buffer.from(JSON.stringify(p,null,2),`utf8`),`MANIFEST.json`);let m=c.reduce((e,t)=>e+t.lineCount,0),h=[`# Bug Report Bundle`,``,`Generated: ${p.generatedAt}`,`Project: ${t.projectSlug??`(unscoped)`}`,`Discipline version: ${p.disciplineVersion}`,``,`## Contents`,``,...l.map(e=>`- ${e}`),``,`## Privacy`,``,`This bundle was auto-redacted before packaging.`,`Patterns checked: ${_i.join(`, `)}`,m>0?`${m} line(s) were scrubbed across ${c.length} file(s).`:`No redactions were needed.`,`See MANIFEST.json for the full redaction audit report.`,``,`This bundle is safe to attach to a GitHub issue.`].join(`
|
|
21
21
|
`);d.addBuffer(Buffer.from(h,`utf8`),`README.md`),d.end();let g=Dt(r);if(d.outputStream.pipe(g),await new Promise((e,t)=>{g.on(`close`,e),g.on(`error`,t)}),n?.info({bundlePath:r,fileCount:l.length,redactionCount:m},`bundle written`),process.stdout.write(`${r}\n`),m>0&&process.stderr.write(`ok bug-report: ${m} line(s) auto-redacted across ${c.length} file(s)\n`),!t.noReveal&&Vt()===`darwin`)try{_t(`/usr/bin/open`,[`-R`,r],{detached:!0,stdio:`ignore`}).unref()}catch{}return r}function Di(){return new t(`bug-report`).description(`Generate a diagnostic bundle for bug reporting`).option(`--reveal`,`Reveal the bundle in Finder (default: true)`,!0).option(`--no-reveal`,`Do not reveal the bundle in Finder`).action(async e=>{let t=process.cwd(),n=xi(t);try{await Ei({projectSlug:n,cwd:t,noReveal:!e.reveal})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`ok bug-report: failed — ${t}\n`),process.exitCode=1}})}function U(e,t,n={}){let r=g(e,t);if(!N(r))return{status:`missing`,lockPath:r};let i;try{i=JSON.parse(F(r,`utf-8`))}catch{return{status:`corrupt`,lockPath:r}}if(!i||typeof i!=`object`||!f(i.pid))return{status:`corrupt`,lockPath:r};let a=i;if(!(n.isAlive??y)(a.pid))return{status:`dead-pid`,lockPath:r,lock:a};let o=n.host??Bt();return a.hostname===o?{status:`alive`,lockPath:r,lock:a}:{status:`foreign-host`,lockPath:r,lock:a}}function Oi(e,t){let n=[];for(let[r,i]of[[`server`,e],[`ui`,t]])(i.status===`dead-pid`||i.status===`corrupt`)&&n.push({name:r,lockPath:i.lockPath,reason:i.status});return{prune:n}}function ki(e){let t=e.inspect??(t=>U(e.lockDir,t)),n=e.unlink??(e=>Ft(e)),r=e.log??(e=>console.log(e)),i=e.error??(e=>console.error(e)),a=Oi(t(`server`),t(`ui`));if(a.prune.length===0)return r(`No stale locks.`),{pruned:[],failed:[]};let o=[],s=[];for(let e of a.prune)try{n(e.lockPath),o.push(e)}catch(t){s.push({target:e,error:t instanceof Error?t.message:String(t)})}if(o.length>0){let e=o.map(e=>`${e.name} (${e.reason})`).join(`, `);r(`Pruned ${o.length} stale lock${o.length===1?``:`s`}: ${e}`)}return s.length>0&&i(`Failed to prune: ${s.map(({target:e,error:t})=>`${e.name} (${e.lockPath}): ${t}`).join(`; `)}`),{pruned:o,failed:s}}function Ai(e){return new t(`clean`).description(`Prune stale / corrupt open-knowledge lock files (never touches live locks)`).action(()=>{e(),ki({lockDir:w(process.cwd())}).failed.length>0&&(process.exitCode=1)})}async function ji(e,t,n={},r=ae){if(!n.skipGhDetect&&r().available)return{tier:`A`,credentialArgs:[`-c`,`credential.helper=!gh auth git-credential`]};let i=await t.get(e);return i==null?{tier:`none`,credentialArgs:[]}:{tier:i.gitProtocol===`ssh`?`C`:`B`,credentialArgs:[`-c`,`credential.helper=!open-knowledge auth git-credential`]}}async function Mi(e,t,n=fetch){let r=new AbortController,i=setTimeout(()=>r.abort(),5e3);try{return(await n(`https://api.github.com/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{signal:r.signal,headers:{"User-Agent":`open-knowledge-cli`,Accept:`application/vnd.github+json`}})).status===200}catch{return!1}finally{clearTimeout(i)}}const Ni=[[`count`,0,10],[`compress`,10,20],[`receiv`,20,60],[`resolv`,60,100]];function Pi(e){let t=/^([\w ]+):\s+(\d+)%/.exec(e.trim());if(!t)return null;let n=t[1].toLowerCase(),r=Number(t[2]);for(let[e,i,a]of Ni)if(n.includes(e))return{stage:t[1],pct:Math.round(i+r/100*(a-i))};return null}function W(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}function Fi(e){return typeof e!=`string`||e.length===0?[`--progress`]:[`--progress`,`-b`,e]}const Ii=l;async function Li(e){try{return await e.clone(Fi(e.branch)),{fellBack:!1}}catch(t){if(e.branch!==null&&Ii(t))return e.onFallback(e.branch),await e.clone(Fi(null)),{fellBack:!0};throw t}}function Ri(e,t,n){return e===`https`&&t===`github.com`&&n}async function zi(e,t,n,r=process.cwd()){let i=rt(e);if(!i)throw Error(`Invalid git URL: ${e}`);let a=t.dir?M(r,t.dir):M(r,i.name);if(N(a)&&jt(a).length>0)throw Error(`Target directory is not empty: ${a}`);let o=S(),s=i.protocol===`https`&&i.hostname===`github.com`?await Mi(i.owner,i.name):!1,c=Ri(i.protocol,i.hostname,s)?{tier:`none`,credentialArgs:[]}:await ji(i.hostname,o,{}),l=xe({baseDir:r,config:c.credentialArgs.length>=2?[c.credentialArgs[1]]:[],unsafe:{allowUnsafeCredentialHelper:!0}}).env({GIT_TERMINAL_PROMPT:`0`}),u=-1;l.outputHandler((e,n,r)=>{r.on(`data`,e=>{let n=e.toString(`utf-8`);for(let e of n.split(`
|
|
22
22
|
`)){let n=Pi(e);n&&n.pct!==u&&(u=n.pct,W(t.json,{type:`progress`,pct:n.pct,stage:n.stage}),t.json||process.stderr.write(`\r Cloning ${n.pct}%`))}})}),await Li({branch:typeof t.branch==`string`&&t.branch.length>0?t.branch:null,clone:t=>l.clone(e,a,t),onFallback:e=>{W(t.json,{type:`branch-fallback`,branch:e}),t.json||process.stderr.write(`\n Branch '${e}' not found upstream — cloning default branch instead.\n`)}}),t.json||process.stderr.write(`
|
|
23
|
-
`);try{let{runInit:e}=await import(`./init-
|
|
23
|
+
`);try{let{runInit:e}=await import(`./init-BPJN5KYj.mjs`),n=await e({cwd:a,mcp:!1});if(n.contentUpdated.length>0){let e=`auto-init: updated ${n.contentUpdated.join(`, `)}`;t.json?W(!0,{type:`warning`,message:e}):process.stderr.write(` ${e}\n`)}}catch(e){let n=e instanceof Error?e.message:String(e);t.json?W(!0,{type:`warning`,message:`auto-init: ${n}`}):process.stderr.write(` auto-init: ${n}\n`)}try{Bi(a)}catch(e){let n=e instanceof Error?e.message:String(e);t.json?W(!0,{type:`warning`,message:`git-exclude: ${n}`}):process.stderr.write(` git-exclude: ${n}\n`)}return a}function Bi(e){let t=j(e,`.git`,`info`,`exclude`);if(!N(t))return`no-exclude`;let n=F(t,`utf-8`),r=new Set([`.ok`,`.ok/`,`/.ok`,`/.ok/`]);return n.split(`
|
|
24
24
|
`).map(e=>e.trim()).some(e=>r.has(e))?`already-present`:(I(t,`${n}${n.length===0||n.endsWith(`
|
|
25
25
|
`)?``:`
|
|
26
|
-
`}.ok/\n`,`utf-8`),`appended`)}function Vi(e){return new t(`clone`).description(`Clone a git repository and open it`).argument(`<url>`,`Repository URL or owner/repo shorthand`).argument(`[dir]`,`Target directory (default: ./<repo-name>)`).option(`--json`,`Output JSONL progress events`,!1).option(`-b, --branch <branch>`,`Branch to check out (falls back to default if missing)`).action(async(t,n,r)=>{let i=e();try{let a=await zi(t,{json:r.json,dir:n,branch:r.branch??null},i);if(r.json)W(!0,{type:`complete`,dir:a});else{process.stderr.write(`✓ Cloned to ${a}\n`),process.chdir(a);let{startCommand:t}=await import(`./start-
|
|
26
|
+
`}.ok/\n`,`utf-8`),`appended`)}function Vi(e){return new t(`clone`).description(`Clone a git repository and open it`).argument(`<url>`,`Repository URL or owner/repo shorthand`).argument(`[dir]`,`Target directory (default: ./<repo-name>)`).option(`--json`,`Output JSONL progress events`,!1).option(`-b, --branch <branch>`,`Branch to check out (falls back to default if missing)`).action(async(t,n,r)=>{let i=e();try{let a=await zi(t,{json:r.json,dir:n,branch:r.branch??null},i);if(r.json)W(!0,{type:`complete`,dir:a});else{process.stderr.write(`✓ Cloned to ${a}\n`),process.chdir(a);let{startCommand:t}=await import(`./start-NCx0aFju.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){let t=e instanceof Error?e.message:String(e);r.json?W(!0,{type:`error`,message:t}):process.stderr.write(`✗ ${t}\n`),process.exitCode=1}})}var Hi=p();const Ui=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],[`server`,`port`],[`content`,`include`],[`content`,`exclude`]];function Wi(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??it;try{let{sources:n}=r(e.cwd);return t(`✓ Configuration valid (sources: ${n.length===0?`defaults only`:n.join(`, `)})`),{ok:!0}}catch(e){return n(e instanceof Error?e.message:String(e)),{ok:!1}}}function Gi(e){let t=(0,Hi.parseDocument)(F(e,`utf-8`));if(t.errors.length>0)throw Error(`Could not parse ${e}: ${t.errors.map(e=>e.message).join(`; `)}`);let n=[];for(let e of Ui)t.hasIn(e)&&n.push(e.join(`.`));return n}function Ki(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function qi(e){let t={};for(let n of e){let e=t;for(let t=0;t<n.length-1;t++){let r=n[t],i=e[r],a=Ki(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}async function Ji(e={}){let t=e.log??(e=>console.log(e)),n=e.error??(e=>console.error(e)),r=e.scope??`both`,i=e.dryRun??!1,a=e.cwd??process.cwd(),o=e.writeConfigPatchFn??Ce,s=[];(r===`project`||r===`both`)&&s.push({scope:`project`,absPath:$e(`project`,a,e.homedirOverride)}),(r===`user`||r===`both`)&&s.push({scope:`user`,absPath:$e(`user`,a,e.homedirOverride)});let c=[],l=!0;for(let{scope:t,absPath:n}of s){if(!N(n)){c.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=Gi(n)}catch(e){let r=e instanceof Error?e.message:String(e);c.push({path:n,scope:t,found:[],removed:[],error:r}),l=!1;continue}if(r.length===0||i){c.push({path:n,scope:t,found:r,removed:[]});continue}let s=await o({cwd:a,scope:t,patch:qi(Ui.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!s.ok){c.push({path:n,scope:t,found:r,removed:[],error:ne(s.error)}),l=!1;continue}c.push({path:n,scope:t,found:r,removed:r})}for(let e of c)e.error&&n(`✗ ${e.path}: ${e.error}`);let u=c.some(e=>e.error!==void 0),d=c.reduce((e,t)=>e+t.found.length,0);if(d===0&&!u)t(`No deprecated fields found.`);else if(d>0)for(let e of c)e.error||(e.found.length===0?t(` ${e.path}: no deprecated fields`):t(i?`[dry-run] ${e.path}: would remove ${e.found.length} field(s): ${e.found.join(`, `)}`:`✓ ${e.path}: removed ${e.removed.length} field(s): ${e.removed.join(`, `)}`));return{outcomes:c,ok:l}}function Yi(){let e=new t(`config`).description(`Inspect and maintain Open Knowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{Wi({}).ok||(process.exitCode=1)}),e.command(`migrate`).description(`Remove deprecated config fields (sync.*, persistence.{debounceMs,maxDebounceMs}, server.port, content.{include,exclude}) idempotently`).option(`--scope <scope>`,`Which scope to migrate: project | user | both`,`both`).option(`--dry-run`,`Preview without writing`,!1).action(async e=>{let t=e.scope;if(t!==`project`&&t!==`user`&&t!==`both`){console.error(`Invalid --scope: ${t}. Expected: project | user | both`),process.exitCode=2;return}(await Ji({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}var Xi=e(et(),1),G=e(ft(),1);const Zi=new Set([`doc.name`]);function Qi(e){return`doc:${Qt(`blake2b512`,{outputLength:32}).update(e).digest(`hex`).slice(0,8)}`}function $i(e,t,n){let r=e.docNameMap[n];if(r===void 0){e.docNameMap[n]=t;return}if(r===t)return;let i=e.docNameCollisions[n];i?i.includes(t)||i.push(t):e.docNameCollisions[n]=[t]}function ea(e,t){let n=t.originalToHashed.get(e);if(n!==void 0)return n;let r=Qi(e);return t.originalToHashed.set(e,r),$i(t,e,r),r}function ta(e,t){return t.length===0||!e.includes(t)?e:e.split(t).join(`<CONTENT_DIR>`)}function na(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ra(e,t){if(typeof e==`string`)return ta(e,t.contentDir);if(Array.isArray(e))return e.map(e=>ra(e,t));if(!na(e))return e;let n=typeof e.key==`string`&&Zi.has(e.key)&&na(e.value)&&typeof e.value.stringValue==`string`?e.value.stringValue:null,r={};for(let[i,a]of Object.entries(e))if(n!==null&&i===`value`&&na(a)){let e=ea(n,t);r[i]={...a,stringValue:e}}else Zi.has(i)&&typeof a==`string`?r[i]=ea(a,t):r[i]=ra(a,t);return r}function ia(e,t){let n=F(e,`utf-8`);if(n.length===0)return;let r=n.endsWith(`
|
|
27
27
|
`),i=n.split(`
|
|
28
28
|
`),a=[];for(let e=0;e<i.length;e++){let n=i[e]??``;if(!(e===i.length-1&&n===``)){if(n.length===0){a.push(``);continue}try{let e=ra(JSON.parse(n),t);a.push(JSON.stringify(e))}catch{a.push(n)}}}I(e,r?`${a.join(`
|
|
29
29
|
`)}\n`:a.join(`
|
|
@@ -57,7 +57,7 @@ ws.addEventListener('error', () => process.exit(1));
|
|
|
57
57
|
setTimeout(() => process.exit(2), ${t+1e4});
|
|
58
58
|
`),r}async function ko(e,t,n,r,i){let a=Oo(e,t,j(r,`cpu.cpuprofile`)),o=!1,s=_t(process.execPath,[a],{stdio:`ignore`}),c=setInterval(()=>{let e=wo(n);e&&i(e)},1e3);await new Promise(e=>{s.once(`close`,t=>{o=t===0,e()}),setTimeout(()=>{s.kill(),e()},t+12e3)}),clearInterval(c);try{Nt(j(a,`..`),{recursive:!0,force:!0})}catch{}return o}function Ao(e){let t;try{t=JSON.parse(e)}catch{return`(could not parse profile)`}let n=new Map(t.nodes.map(e=>[e.id,e])),r=new Map;for(let e of t.nodes)for(let t of e.children??[])r.set(t,e.id);let i=new Map;for(let e of t.samples??[])i.set(e,(i.get(e)??0)+1);let a=t.samples?.length??0,o=t.endTime!=null&&t.startTime!=null?((t.endTime-t.startTime)/1e3).toFixed(2):`?`,s=[...i.entries()].sort((e,t)=>t[1]-e[1]).slice(0,10),c=[`samples ${a} duration_ms ${o}`,``,`Top leaf nodes`];for(let[e,t]of s){let r=n.get(e);if(!r)continue;let i=a>0?(t/a*100).toFixed(1):`0.0`,{functionName:o,url:s,lineNumber:l,columnNumber:u}=r.callFrame;c.push(` ${t} ${i}% id=${e} ${o||`(anonymous)`} ${s}:${l}:${u} hit=${r.hitCount??0}`)}c.push(``,`Top stacks`);let l=e=>{let t=[],i=e;for(;i!=null;){let e=n.get(i);if(!e)break;let{functionName:a,url:o,lineNumber:s,columnNumber:c}=e.callFrame;t.unshift(` ${a||`(anonymous)`} ${o} ${s} ${c}`),i=r.get(i)}return t};for(let[e,t]of s.slice(0,5)){let n=a>0?(t/a*100).toFixed(1):`0.0`;c.push(``,`--- ${t} ${n}%`,...l(e))}return c.join(`
|
|
59
59
|
`)}async function jo(e,t={}){let{pid:n,cpuProfileSecs:r=15,noInspector:i=!1}=e,a=t.log??(e=>console.log(e)),o=t.discover??no,s=t.inspect??U,c=t.resolveCommand??Ya,l=t.resolveUsage??Xa,u=t.collectLsofFn??To,d=t.getEndpoints??Do,f=t.profiler??ko,p=t.isAlive??(e=>{try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}),m=t.sendSignal??((e,t)=>{process.kill(e,t)}),h=t.sleep??(e=>new Promise(t=>setTimeout(t,e))),g=r*1e3;if(!p(n)){a(G.default.red(`No process with pid ${n} found.`));return}let _=await o(),v=null,y=null;for(let e of _){let t=s(e,`server`);if(t.status!==`missing`&&t.status!==`corrupt`&&t.lock.pid===n){v=t.lock.worktreeRoot,y={lockDir:e,state:t.status,lockPath:t.lockPath,lock:t.lock};break}}let ee=new Date().toISOString().replace(/[:.]/g,`-`),b=e.output?e.output:v?j(v,`.ok`,`local`,`diagnostics`,`process-${n}-${ee}`):j(process.cwd(),`ok-diagnose-${n}-${ee}`);try{P(b,{recursive:!0})}catch(e){a(G.default.red(`Cannot create output directory ${b}: ${e.message}`));return}a(G.default.bold(`Diagnosing pid ${n}`)),a(`Output: ${b}`),a(``);let x=(e,t)=>{I(j(b,e),t),a(` wrote ${e}`)},te=c(n),ne=l(n);x(`metadata.json`,JSON.stringify({capturedAt:new Date().toISOString(),pid:n,command:te,usage:ne,lockInfo:y},null,2)),a(` sampling lsof`);let S=u(n);if(S&&x(`lsof.txt`,S),!i){let e=S?Eo(S).find(e=>e>=9229&&e<=9299)??9229:9229,t=d(e);if(!t||t.length===0){a(` no inspector on :${e}, sending SIGUSR1 to pid ${n}`);try{m(n,`SIGUSR1`),await h(2e3),t=d(e)}catch(e){a(G.default.yellow(` SIGUSR1 delivery failed: ${e.message}`))}}if(t&&t.length>0){x(`inspector-endpoints.json`,JSON.stringify(t,null,2));let e=t[0].webSocketDebuggerUrl;if(e){a(` capturing ${r}s CPU profile`);let t=[];await f(e,g,n,b,e=>t.push(e))?a(` wrote cpu.cpuprofile`):a(G.default.yellow(` CPU profile capture failed`)),t.length>0&&x(`process-stats.jsonl`,`${t.map(e=>JSON.stringify(e)).join(`
|
|
60
|
-
`)}\n`);try{x(`stacks.txt`,Ao(F(j(b,`cpu.cpuprofile`),`utf-8`)))}catch(e){a(G.default.yellow(` stacks.txt skipped: ${e.message}`))}}}else a(G.default.yellow(` Node inspector unavailable — skipping CPU profile`))}a(``),a(G.default.yellow(`⚠ Before sharing, review what each file contains:`)),a(` metadata.json — content directory paths, lock file locations, CPU/MEM at capture time`),a(` lsof.txt — all open files, network connections, and private paths for this process`),a(` inspector-endpoints.json — Node debugger metadata (titles, URLs)`),a(` cpu.cpuprofile — function names and source file paths from your Node process`),a(` stacks.txt — call stacks derived from cpu.cpuprofile; includes source paths`),a(` process-stats.jsonl — CPU/MEM/RSS numbers only; safe to share`),a(``),a(`Bundle: ${G.default.bold(b)}`)}async function Mo(e){let t=nn({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function No(e){let t=kt(j(Ut(),`ok-bundle-process-`));return await jo({pid:e,output:t}),t}function Po(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MB`:`${(n/1024).toFixed(1)} GB`}function Fo(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function Io(e,t,n){let{summary:r,manifest:i}=t;e(``),e(G.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${Po(r.totalBytes)} uncompressed`),e(` doc.name attributes: ${r.docNameCount} occurrence(s) in telemetry${r.redacted?` (values hashed)`:``}`),e(` Content-dir path: ${r.contentDirVisible?`visible (${i.contentDir.absolutePath})`:`not visible`}`),e(` Redacted: ${r.redacted?`yes`:`no`}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function Lo(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??Mo,i=t.runProcessDiagnose??No,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=yt(o);if(!N(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=j(e.contentDir,`.ok`,`local`,`diagnostics`);P(n,{recursive:!0}),o=j(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(G.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await Ra({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(G.default.yellow(` server not running — live state unavailable`)),Io(n,c,o),e.yes!==!0&&!Fo(await r(`Write bundle? [y/N]: `))?(n(G.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await za({collected:c,outputPath:o}),n(G.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{Nt(s,{recursive:!0,force:!0})}catch{}}}function Ro(){let e=new t(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(G.default.red(`Invalid pid '${e}': must be a positive integer`)),process.exit(1));let r=Number.parseInt(t.cpuProfile,10);(Number.isNaN(r)||r<=0)&&(console.error(G.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await jo({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(Co()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--redact`,`Hash doc names and strip the content-dir prefix from the staged bundle`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(G.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-
|
|
60
|
+
`)}\n`);try{x(`stacks.txt`,Ao(F(j(b,`cpu.cpuprofile`),`utf-8`)))}catch(e){a(G.default.yellow(` stacks.txt skipped: ${e.message}`))}}}else a(G.default.yellow(` Node inspector unavailable — skipping CPU profile`))}a(``),a(G.default.yellow(`⚠ Before sharing, review what each file contains:`)),a(` metadata.json — content directory paths, lock file locations, CPU/MEM at capture time`),a(` lsof.txt — all open files, network connections, and private paths for this process`),a(` inspector-endpoints.json — Node debugger metadata (titles, URLs)`),a(` cpu.cpuprofile — function names and source file paths from your Node process`),a(` stacks.txt — call stacks derived from cpu.cpuprofile; includes source paths`),a(` process-stats.jsonl — CPU/MEM/RSS numbers only; safe to share`),a(``),a(`Bundle: ${G.default.bold(b)}`)}async function Mo(e){let t=nn({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function No(e){let t=kt(j(Ut(),`ok-bundle-process-`));return await jo({pid:e,output:t}),t}function Po(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MB`:`${(n/1024).toFixed(1)} GB`}function Fo(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function Io(e,t,n){let{summary:r,manifest:i}=t;e(``),e(G.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${Po(r.totalBytes)} uncompressed`),e(` doc.name attributes: ${r.docNameCount} occurrence(s) in telemetry${r.redacted?` (values hashed)`:``}`),e(` Content-dir path: ${r.contentDirVisible?`visible (${i.contentDir.absolutePath})`:`not visible`}`),e(` Redacted: ${r.redacted?`yes`:`no`}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function Lo(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??Mo,i=t.runProcessDiagnose??No,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=yt(o);if(!N(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=j(e.contentDir,`.ok`,`local`,`diagnostics`);P(n,{recursive:!0}),o=j(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(G.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await Ra({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(G.default.yellow(` server not running — live state unavailable`)),Io(n,c,o),e.yes!==!0&&!Fo(await r(`Write bundle? [y/N]: `))?(n(G.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await za({collected:c,outputPath:o}),n(G.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{Nt(s,{recursive:!0,force:!0})}catch{}}}function Ro(){let e=new t(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(G.default.red(`Invalid pid '${e}': must be a positive integer`)),process.exit(1));let r=Number.parseInt(t.cpuProfile,10);(Number.isNaN(r)||r<=0)&&(console.error(G.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await jo({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(Co()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--redact`,`Hash doc names and strip the content-dir prefix from the staged bundle`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(G.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-BIxKasBW.mjs`),{resolveContentDir:r}=await import(`./dist-D-rWIekL.mjs`),i=process.cwd(),{config:a}=n(i);await Lo({contentDir:r(a,i),projectDir:i,pid:t,out:e.out,yes:e.yes===!0,redact:e.redact===!0})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(G.default.red(t)),process.exit(1)}}),e}const zo=[` 1. ${O(`Customize`)} (sidebar) → ${O(`Skills`)}`,` 2. Click the ${O(`+`)} button`,` 3. Click ${O(`Create skill`)}`,` 4. Click ${O(`Upload skill`)}`,` 5. Pick ${O(`openknowledge.skill`)} from Downloads`],Bo=pt(` Open the Claude Desktop App, then: ${O(`Customize → Skills → + → Create skill → Upload skill`)} → pick the file.`);function Vo(e){let t=[E(`Built ${e.outputPath}`),T(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…`)];return e.handoffError&&t.push(mt(` Handoff failed: ${e.handoffError.message}`)),t.push(Bo),t.join(`
|
|
61
61
|
`)}function Ho(e){let t=e.skillVersion??`unknown`,n=e.recordedAt??`unknown`;return[pt(`Open Knowledge skill ${O(`v${t}`)} already delivered to Claude Desktop.`),T(` Recorded at ${n} in ~/.ok/skill-state.yml`),T(` Use ${O(`--force`)} to rebuild and re-open the install dialog.`)].join(`
|
|
62
62
|
`)}function Uo(e){let t=e.skillVersion?` • Skill v${e.skillVersion}`:``;return[E(`Built ${e.outputPath}`),T(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…${t}`),pt(` Claude Desktop App opened. Now upload the file manually:`),...zo,T(` If Claude Desktop didn't open, open it and start at step 1. The file is at ${e.outputPath}`)].join(`
|
|
63
63
|
`)}function Wo(e){return`${D(`Error:`)} ${e.buildError??`unknown build failure`}`}async function Go(e={}){let t=await Je(e);return t.status===`failed`?{...t,message:Wo(t),exitCode:1}:t.status===`skip-current`?{...t,message:Ho(t),exitCode:0}:t.status===`installed`?{...t,message:Uo(t),exitCode:0}:{...t,message:Vo(t),exitCode:0}}function Ko(){return new t(`install-skill`).description("Build openknowledge.skill and open the Claude Desktop App so you can upload it for Claude Chat & Cowork. Not needed for Claude — `ok init` covers that separately.").option(`--out <path>`,`Custom output path (default: ~/Downloads/openknowledge.skill)`).option(`--no-open`,`Build the file but skip the OS file-association handoff`).option(`--force`,`Bypass the install-state gate and rebuild unconditionally`).action(async e=>{let t=await Go({out:e.out,noOpen:!e.open,force:e.force??!1});process.stdout.write(`${t.message}\n`),t.exitCode!==0&&process.exit(t.exitCode)})}const qo=j(`Contents`,`Resources`,`cli`,`bin`,`ok.sh`),Jo=/Contents\/Resources\/cli\/dist\/cli\.mjs$/;function Yo(e,t,n){return e===`darwin`?[j(t,`Applications`,`Open Knowledge.app`,qo),j(`/Applications`,`Open Knowledge.app`,qo)].find(e=>n.existsSync(e))??null:null}function Xo(e,t,n){if(n!==`darwin`)return{proxy:!1,suppressedBy:`platform`};let r=e.OK_BUNDLE_PROXY?.toLowerCase();return r===`0`||r===`false`?{proxy:!1,suppressedBy:`env`}:t.includes(`--no-bundle-proxy`)?{proxy:!1,suppressedBy:`flag`}:typeof t[1]==`string`&&Jo.test(t[1])?{proxy:!1,suppressedBy:`self`}:{proxy:!0,suppressedBy:null}}function Zo(e){e.stderr.write(`${JSON.stringify({event:`mcp-bundle-proxy`,mode:e.mode,bundlePath:e.bundlePath,reason:e.reason,hint:`Suppress with --no-bundle-proxy or OK_BUNDLE_PROXY=0.`})}\n`)}function Qo(e){Zo({stderr:e.stderr,mode:`bundled`,bundlePath:e.bundlePath,reason:null});let t=e.spawnImpl??_t,n=e.exitProcess??(e=>process.exit(e)),r=e.now??(()=>Date.now()),i=r(),a=e.startupFailureWindowMs??1e3;return new Promise((o,s)=>{let c=t(e.bundlePath,e.argv.filter(e=>e!==`--no-bundle-proxy`),{env:{...e.env,OK_BUNDLE_PROXY:`0`},stdio:`inherit`}),l=e=>{c.kill(e)},u=()=>{process.off(`SIGTERM`,l),process.off(`SIGINT`,l)};process.on(`SIGTERM`,l),process.on(`SIGINT`,l),c.once(`error`,e=>{u(),s(e)}),c.once(`exit`,(e,t)=>{if(u(),t){s(Error(`bundle process exited by signal ${t}`));return}let o=e??0,c=r()-i;if(o!==0&&c<=a){s(Error(`bundle process exited during startup with code ${o}`));return}n(o)})})}function $o(e){let t=e.scheduler??{setTimeout:(e,t)=>globalThis.setTimeout(e,t),clearTimeout:e=>globalThis.clearTimeout(e)},n=e.initialBackoffMs??1e3,r=e.maxBackoffMs??3e4,i=e.rng??Math.random,a=e.createWebSocket??(e=>new WebSocket(e)),o=e.logger??null,s=e.log,c=null,l=null,u=!1,d=n;function f(e,t,n){try{o?o[e](t,n):s?.(t)}catch{}}function p(){if(u)return;l!==null&&t.clearTimeout(l);let e=d;d=Math.min(d*2,r);let n=i(),a=Math.max(1,Math.floor(e*(1-n/2)));f(`debug`,`scheduling reconnect`,{backoffMs:a,ceilMs:e}),l=t.setTimeout(()=>{l=null,m().catch(e=>f(`warn`,`reconnect failed`,{error:String(e)}))},a)}async function m(){if(u)return;let t;try{t=await e.resolveWsUrl()}catch(e){f(`warn`,`resolveWsUrl threw`,{error:String(e)}),p();return}if(!t){p();return}let r=e.connectionId?`&connectionId=${encodeURIComponent(e.connectionId)}`:``,i=e.connectionId&&e.displayName!==void 0&&e.clientName!==void 0&&e.colorSeed!==void 0?`&displayName=${encodeURIComponent(e.displayName)}&clientName=${encodeURIComponent(e.clientName)}&colorSeed=${encodeURIComponent(e.colorSeed)}`:``,o=`${t}/collab/keepalive?pid=${process.pid}${r}${i}`;try{c=a(o)}catch(e){f(`warn`,`WebSocket constructor failed`,{url:o,error:String(e)}),c=null,p();return}c.addEventListener(`open`,()=>{f(`info`,`connected`,{url:t}),d=n}),c.addEventListener(`close`,()=>{u||(f(`info`,`disconnected`,{url:t}),c=null,p())}),c.addEventListener(`error`,()=>{f(`debug`,`websocket error observed`,{url:t,readyState:c?.readyState,reason:`error-event`})})}return queueMicrotask(()=>{m().catch(e=>f(`warn`,`initial connect failed`,{error:String(e)}))}),{close:()=>{if(!u&&(u=!0,l!==null&&(t.clearTimeout(l),l=null),c)){try{c.close()}catch{}c=null}},isConnected:()=>c!==null&&c.readyState===1}}var es=class{append(e){this._buffer=this._buffer?Buffer.concat([this._buffer,e]):e}readMessage(){if(!this._buffer)return null;let e=this._buffer.indexOf(`
|
|
@@ -68,7 +68,7 @@ setTimeout(() => process.exit(2), ${t+1e4});
|
|
|
68
68
|
`,r),o=-1;if(i!==-1&&a!==-1?o=Math.min(i,a):i===-1?a!==-1&&(o=a):o=i===e.length-1?-1:i,o===-1){n=e.slice(r);break}else{let n=e.slice(r,o);t.push(n),r=o+1,e[r-1]===`\r`&&e[r]===`
|
|
69
69
|
`&&r++}}return[t,n]}var wc=class extends TransformStream{constructor({onError:e,onRetry:t,onComment:n}={}){let r;super({start(i){r=Sc({onEvent:e=>{i.enqueue(e)},onError(t){e===`terminate`?i.error(t):typeof e==`function`&&e(t)},onRetry:t,onComment:n})},transform(e){r.feed(e)}})}};const Tc={initialReconnectionDelay:1e3,maxReconnectionDelay:3e4,reconnectionDelayGrowFactor:1.5,maxRetries:2};var Ec=class extends Error{constructor(e,t){super(`Streamable HTTP error: ${t}`),this.code=e}},Dc=class{constructor(e,t){this._hasCompletedAuthFlow=!1,this._url=e,this._resourceMetadataUrl=void 0,this._scope=void 0,this._requestInit=t?.requestInit,this._authProvider=t?.authProvider,this._fetch=t?.fetch,this._fetchWithInit=ls(t?.fetch,t?.requestInit),this._sessionId=t?.sessionId,this._reconnectionOptions=t?.reconnectionOptions??Tc}async _authThenStart(){if(!this._authProvider)throw new Z(`No auth provider`);let e;try{e=await $s(this._authProvider,{serverUrl:this._url,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetchWithInit})}catch(e){throw this.onerror?.(e),e}if(e!==`AUTHORIZED`)throw new Z;return await this._startOrAuthSse({resumptionToken:void 0})}async _commonHeaders(){let e={};if(this._authProvider){let t=await this._authProvider.tokens();t&&(e.Authorization=`Bearer ${t.access_token}`)}this._sessionId&&(e[`mcp-session-id`]=this._sessionId),this._protocolVersion&&(e[`mcp-protocol-version`]=this._protocolVersion);let t=cs(this._requestInit?.headers);return new Headers({...e,...t})}async _startOrAuthSse(e){let{resumptionToken:t}=e;try{let n=await this._commonHeaders();n.set(`Accept`,`text/event-stream`),t&&n.set(`last-event-id`,t);let r=await(this._fetch??fetch)(this._url,{method:`GET`,headers:n,signal:this._abortController?.signal});if(!r.ok){if(await r.body?.cancel(),r.status===401&&this._authProvider)return await this._authThenStart();if(r.status===405)return;throw new Ec(r.status,`Failed to open SSE stream: ${r.statusText}`)}this._handleSseStream(r.body,e,!0)}catch(e){throw this.onerror?.(e),e}}_getNextReconnectionDelay(e){if(this._serverRetryMs!==void 0)return this._serverRetryMs;let t=this._reconnectionOptions.initialReconnectionDelay,n=this._reconnectionOptions.reconnectionDelayGrowFactor,r=this._reconnectionOptions.maxReconnectionDelay;return Math.min(t*n**+e,r)}_scheduleReconnection(e,t=0){let n=this._reconnectionOptions.maxRetries;if(t>=n){this.onerror?.(Error(`Maximum reconnection attempts (${n}) exceeded.`));return}let r=this._getNextReconnectionDelay(t);this._reconnectionTimeout=setTimeout(()=>{this._startOrAuthSse(e).catch(n=>{this.onerror?.(Error(`Failed to reconnect SSE stream: ${n instanceof Error?n.message:String(n)}`)),this._scheduleReconnection(e,t+1)})},r)}_handleSseStream(e,t,n){if(!e)return;let{onresumptiontoken:r,replayMessageId:i}=t,a,o=!1,s=!1;(async()=>{try{let t=e.pipeThrough(new TextDecoderStream).pipeThrough(new wc({onRetry:e=>{this._serverRetryMs=e}})).getReader();for(;;){let{value:e,done:n}=await t.read();if(n)break;if(e.id&&(a=e.id,o=!0,r?.(e.id)),e.data&&(!e.event||e.event===`message`))try{let t=He.parse(JSON.parse(e.data));Ye(t)&&(s=!0,i!==void 0&&(t.id=i)),this.onmessage?.(t)}catch(e){this.onerror?.(e)}}(n||o)&&!s&&this._abortController&&!this._abortController.signal.aborted&&this._scheduleReconnection({resumptionToken:a,onresumptiontoken:r,replayMessageId:i},0)}catch(e){if(this.onerror?.(Error(`SSE stream disconnected: ${e}`)),(n||o)&&!s&&this._abortController&&!this._abortController.signal.aborted)try{this._scheduleReconnection({resumptionToken:a,onresumptiontoken:r,replayMessageId:i},0)}catch(e){this.onerror?.(Error(`Failed to reconnect: ${e instanceof Error?e.message:String(e)}`))}}})()}async start(){if(this._abortController)throw Error(`StreamableHTTPClientTransport already started! If using Client class, note that connect() calls start() automatically.`);this._abortController=new AbortController}async finishAuth(e){if(!this._authProvider)throw new Z(`No auth provider`);if(await $s(this._authProvider,{serverUrl:this._url,authorizationCode:e,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetchWithInit})!==`AUTHORIZED`)throw new Z(`Failed to authorize`)}async close(){this._reconnectionTimeout&&=(clearTimeout(this._reconnectionTimeout),void 0),this._abortController?.abort(),this.onclose?.()}async send(e,t){try{let{resumptionToken:n,onresumptiontoken:r}=t||{};if(n){this._startOrAuthSse({resumptionToken:n,replayMessageId:ke(e)?e.id:void 0}).catch(e=>this.onerror?.(e));return}let i=await this._commonHeaders();i.set(`content-type`,`application/json`),i.set(`accept`,`application/json, text/event-stream`);let a={...this._requestInit,method:`POST`,headers:i,body:JSON.stringify(e),signal:this._abortController?.signal},o=await(this._fetch??fetch)(this._url,a),s=o.headers.get(`mcp-session-id`);if(s&&(this._sessionId=s),!o.ok){let t=await o.text().catch(()=>null);if(o.status===401&&this._authProvider){if(this._hasCompletedAuthFlow)throw new Ec(401,`Server returned 401 after successful authentication`);let{resourceMetadataUrl:t,scope:n}=rc(o);if(this._resourceMetadataUrl=t,this._scope=n,await $s(this._authProvider,{serverUrl:this._url,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetchWithInit})!==`AUTHORIZED`)throw new Z;return this._hasCompletedAuthFlow=!0,this.send(e)}if(o.status===403&&this._authProvider){let{resourceMetadataUrl:t,scope:n,error:r}=rc(o);if(r===`insufficient_scope`){let r=o.headers.get(`WWW-Authenticate`);if(this._lastUpscopingHeader===r)throw new Ec(403,`Server returned 403 after trying upscoping`);if(n&&(this._scope=n),t&&(this._resourceMetadataUrl=t),this._lastUpscopingHeader=r??void 0,await $s(this._authProvider,{serverUrl:this._url,resourceMetadataUrl:this._resourceMetadataUrl,scope:this._scope,fetchFn:this._fetch})!==`AUTHORIZED`)throw new Z;return this.send(e)}}throw new Ec(o.status,`Error POSTing to endpoint: ${t}`)}if(this._hasCompletedAuthFlow=!1,this._lastUpscopingHeader=void 0,o.status===202){await o.body?.cancel(),Ne(e)&&this._startOrAuthSse({resumptionToken:void 0}).catch(e=>this.onerror?.(e));return}let c=(Array.isArray(e)?e:[e]).filter(e=>`method`in e&&`id`in e&&e.id!==void 0).length>0,l=o.headers.get(`content-type`);if(c)if(l?.includes(`text/event-stream`))this._handleSseStream(o.body,{onresumptiontoken:r},!1);else if(l?.includes(`application/json`)){let e=await o.json(),t=Array.isArray(e)?e.map(e=>He.parse(e)):[He.parse(e)];for(let e of t)this.onmessage?.(e)}else throw await o.body?.cancel(),new Ec(-1,`Unexpected content type: ${l}`);else await o.body?.cancel()}catch(e){throw this.onerror?.(e),e}}get sessionId(){return this._sessionId}async terminateSession(){if(this._sessionId)try{let e=await this._commonHeaders(),t={...this._requestInit,method:`DELETE`,headers:e,signal:this._abortController?.signal},n=await(this._fetch??fetch)(this._url,t);if(await n.body?.cancel(),!n.ok&&n.status!==405)throw new Ec(n.status,`Failed to terminate session: ${n.statusText}`);this._sessionId=void 0}catch(e){throw this.onerror?.(e),e}}setProtocolVersion(e){this._protocolVersion=e}get protocolVersion(){return this._protocolVersion}async resumeStream(e,t){await this._startOrAuthSse({resumptionToken:e,onresumptiontoken:t?.onresumptiontoken})}};function Oc(e){return(t,n)=>{if((n?.method??`GET`).toUpperCase()===`GET`)return globalThis.fetch(t,n);let r=new AbortController,i=setTimeout(()=>r.abort(Error(`MCP request timed out after ${e}ms`)),e),a=n?.signal instanceof AbortSignal?AbortSignal.any([n.signal,r.signal]):r.signal;return globalThis.fetch(t,{...n,signal:a}).finally(()=>clearTimeout(i))}}function kc(e){if(e===void 0||e===``)return;let t=Number.parseInt(e,10);if(!(Number.isNaN(t)||t<=0))return t}function Ac(e){return e===`0.0.0.0`||e===`::`?`localhost`:e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}function jc(e,t){return`http://${Ac(e)}:${t}/mcp`}function Mc(e,t){return`ws://${Ac(e)}:${t}`}function Nc(e){let t=new URL(e);return t.protocol=t.protocol===`https:`?`wss:`:`ws:`,t.pathname=``,t.search=``,t.hash=``,t.toString().replace(/\/$/,``)}function Pc(e,t){if(!(!e||e.port<=0)&&t(e.pid))return e.port}function Fc(e){return N(e)?F(e,`utf-8`).trim():``}function Ic(e,t){return`server did not start within ${e}ms${t?` stderr:\n${t}`:``}`}function Lc(e){if(e&&typeof e==`object`&&`method`in e&&`id`in e)return e.id}function Rc(e){if(!e||typeof e!=`object`||!(`result`in e))return;let t=e.result;if(!t||typeof t!=`object`||!(`protocolVersion`in t))return;let n=t.protocolVersion;return typeof n==`string`?n:void 0}function zc(e,t){return{jsonrpc:`2.0`,id:e,error:{code:-32e3,message:t instanceof Error?t.message:String(t)}}}async function Bc(e){let t=e.readLock??(()=>m(e.lockDir)),n=e.isAlive??y,r=e.sleep??(e=>tn(e)),i=e.spawn??_t,a=e.readErrorLog??Fc,o=e.openErrorLog??(e=>At(e,`w`)),s=e.closeFd??wt,l=e.timeoutMs??5e3,u=e.pollIntervalMs??100;if(e.portOverride!==void 0){let t=Number.parseInt(e.portOverride,10);if(Number.isNaN(t)||t<=0)throw Error(`invalid --port value '${e.portOverride}' — HTTP MCP shim requires a positive port`);return jc(`localhost`,t)}let d=Pc(t(),n);if(d!==void 0)return jc(`localhost`,d);if(e.envAutoStart===`0`)throw Error(`Open Knowledge server is not running and OK_MCP_AUTOSTART=0 disables auto-start.`);N(e.lockDir)||P(e.lockDir,{recursive:!0});let f=j(e.lockDir,c),p=o(f),h,g,_=st();try{try{h=i(_.command,[..._.prefixArgs,`start`],{detached:!0,stdio:[`ignore`,`ignore`,p],cwd:e.contentDir,env:{...process.env,OK_LOCK_KIND:`mcp-spawned`,ELECTRON_RUN_AS_NODE:`1`}}),h.on(`error`,e=>{g=e instanceof Error?e.message:String(e)}),h.unref()}catch(e){g=e instanceof Error?e.message:String(e)}}finally{try{s(p)}catch{}}let v=Date.now()+l;for(;Date.now()<v;){if(g){let e=a(f),t=e?` stderr:\n${e}`:``;throw Error(`spawn failed: ${g}${t}`)}await r(u);let e=Pc(t(),n);if(e!==void 0)return jc(`localhost`,e)}if(g){let e=a(f),t=e?` stderr:\n${e}`:``;throw Error(`spawn failed: ${g}${t}`)}throw Error(Ic(l,a(f)))}function Vc(e,t){if(e.portOverride!==void 0)return Nc(t);let n=e.readLock??(()=>m(e.lockDir)),r=e.isAlive??y,i=Pc(n(),r);if(i!==void 0)return Mc(`localhost`,i)}async function Hc(e,t={}){let n=t.stderr??process.stderr,r=t.requestTimeoutMs??12e4,i=t.createStdioTransport?t.createStdioTransport(t.stdin,t.stdout):new rs(t.stdin,t.stdout),a=t.createHttpTransport?t.createHttpTransport(new URL(e)):new Dc(new URL(e),{fetch:Oc(r),requestInit:{headers:{...b({kind:`mcp`,runtimeVersion:_}),...t.connectionId===void 0?{}:{[Se]:t.connectionId}}}}),o=!1,s=async()=>{o||(o=!0,t.onclose?.(),await Promise.allSettled([i.close(),a.close()]))};i.onerror=e=>{n.write(`[mcp-shim] stdio error: ${e.message}\n`)},a.onerror=e=>{n.write(`[mcp-shim] HTTP transport error: ${e.message}\n`)},i.onclose=()=>{s()},a.onclose=()=>{s()};let c=Promise.resolve();i.onmessage=e=>{c=c.then(async()=>{try{await a.send(e)}catch(t){let r=Lc(e);if(r===void 0){n.write(`[mcp-shim] failed to forward stdio notification: ${t instanceof Error?t.message:String(t)}\n`);return}await i.send(zc(r,t)).catch(e=>{n.write(`[mcp-shim] failed to write stdio error response: ${e instanceof Error?e.message:String(e)}\n`)})}}).catch(e=>{n.write(`[mcp-shim] unexpected stdio forwarding failure: ${e instanceof Error?e.message:String(e)}\n`)})},a.onmessage=e=>{let t=Rc(e);t&&a.setProtocolVersion?.(t),i.send(e).catch(e=>{n.write(`[mcp-shim] failed to write stdio response: ${e instanceof Error?e.message:String(e)}\n`)})};try{await a.start(),await i.start()}catch(e){throw await s(),e}return{close:s}}async function Uc(e){let t=e.stderr??process.stderr,n=e.bridgeFn??Hc,r=await Bc(e),i=e.createConnectionId?.()??$t(),a=!1,o=(e.startKeepalive??$o)({connectionId:i,resolveWsUrl:async()=>Vc(e,r),log:e=>t.write(`[mcp-shim] keepalive: ${e}\n`)});t.write(`[mcp-shim] proxying stdio to ${r}\n`);let s;try{s=await n(r,{stderr:t,connectionId:i,onclose:()=>{a||(o.close(),process.exit(0))}})}catch(e){throw o.close(),e}let c=()=>{a=!0,o.close(),s.close().finally(()=>{process.exit(0)})};process.once(`SIGINT`,c),process.once(`SIGTERM`,c)}const Wc=qt(import.meta.url);function Gc(e){let t=M(e);for(;;){if(Be(t))return t;let n=yt(t);if(n===t)throw Error(`No Open Knowledge project found at or above ${e}. Pass an explicit \`cwd\` argument that points inside an OK project (a directory with a \`${x}\`).`);t=n}}function Kc(e){try{let t=new URL(e);return t.protocol===`file:`?qt(t):void 0}catch{return}}async function qc(e){if(!e.getClientCapabilities()?.roots)return;let t;try{t=await e.listRoots()}catch(t){e.log?.(`listRoots fallback failed: ${t instanceof Error?t.message:String(t)}`);return}let n=t.roots??[];if(n.length!==1)return;let r=Kc(n[0].uri);return r===void 0&&e.log?.(`single root URI not usable as fs path: ${n[0].uri}`),r}async function Jc(e,t){if(e!==void 0)return Gc(e);let n=await t();if(n!==void 0)return Gc(n);throw Error("`cwd` is required for tool calls against the global MCP server. Pass an absolute path inside an Open Knowledge project, or have the MCP client advertise a single root.")}async function Yc(e){let t=process.stderr,n=e.spawnTimeoutMs??kc(process.env.OK_MCP_SPAWN_TIMEOUT_MS),r=e.envAutoStart??process.env.OK_MCP_AUTOSTART,i=at({startupCwd:e.startupCwd,startupConfig:e.startupConfig}),a=new We({name:ze,version:_},{instructions:Ge({dir:`.`})});Xe(a);let o=$t(),s={current:{connectionId:o,displayName:o,colorSeed:o}},c=new Map,l=e=>{if(c.has(e))return;let n=Le(e),r=s.current,i=$o({connectionId:o,displayName:r.displayName,clientName:r.clientInfo?.name??r.displayName,colorSeed:r.colorSeed,resolveWsUrl:async()=>Vc({lockDir:n,contentDir:e},``),log:n=>t.write(`[mcp] keepalive[${e}]: ${n}\n`)});c.set(e,i)},u=()=>qc({getClientCapabilities:()=>a.server.getClientCapabilities(),listRoots:()=>a.server.listRoots(),log:e=>t.write(`[mcp] ${e}\n`)}),d=e=>Jc(e,u),f=async e=>{let t;if(e===void 0){let e=await u();if(e===void 0)return;t=Gc(e)}else t=Gc(e);let a=await i(t),o=await Bc({lockDir:Le(t),contentDir:Me(a,t),envAutoStart:r,...n===void 0?{}:{timeoutMs:n}});return l(t),o.replace(/\/mcp$/,``)};a.server.oninitialized=()=>{let e=a.server.getClientVersion(),t=Ve(e?.name,o);s.current={connectionId:o,clientInfo:e?{name:t,version:e.version}:void 0,displayName:t,colorSeed:t}},Ae(a,{serverUrl:f,resolveCwd:d,config:i,identityRef:s});let p=new rs,m=!1,h,g=async()=>{if(m)return;m=!0,h?.stop();for(let e of c.values())try{e.close()}catch(e){t.write(`[mcp] keepalive close error: ${e instanceof Error?e.message:String(e)}\n`)}c.clear();let e=await Promise.allSettled([a.close(),p.close()]);for(let n of e)if(n.status===`rejected`){let e=n.reason;t.write(`[mcp] shutdown close error: ${e instanceof Error?e.message:String(e)}\n`)}};await a.connect(p),t.write(`[mcp] global stdio server ready (per-call project routing)
|
|
70
70
|
`);let v=!1,y=()=>{v||(v=!0,setTimeout(()=>{t.write(`[mcp] shutdown deadline (5s) reached — forcing exit(1)
|
|
71
|
-
`),process.exit(1)},5e3).unref(),g().finally(()=>{process.exit(0)}))};if(process.once(`SIGINT`,y),process.once(`SIGTERM`,y),ss({log:e=>t.write(`${e}\n`),transport:p,process,stdin:process.stdin}),process.platform===`darwin`){let e=os(Wc,{realpathSync:Mt,statInoSync:e=>Pt(e).ino,log:e=>t.write(`${e}\n`)});if(e!==void 0){t.write(`[mcp] bundle identity anchor=${e.resolvedPath} inode=${e.inode} version=${_}\n`);let{resolvedPath:n,inode:r}=e;h=as({detect:()=>is({bundleAnchorPath:Wc,currentInode:r,platform:process.platform,realpath:Mt,statInode:e=>Pt(e).ino}),onReplaced:e=>{t.write(`[mcp] bundle replaced anchor=${n} bootInode=${e.currentInode} onDiskInode=${e.onDiskInode} version=${_} — exiting for host respawn\n`),y()},log:e=>t.write(`[mcp] ${e}\n`)})}}return{close:g}}function Xc(e){return new t(`mcp`).description(`Start MCP stdio server for project knowledge base`).option(`-p, --port <port>`,`Override per-call routing and proxy stdio to this HTTP MCP port (skips bundle proxy)`,void 0).option(`--no-bundle-proxy`,`Run the npm-fetched MCP server in-process instead of proxying to the macOS Desktop bundle (equivalent: OK_BUNDLE_PROXY=0)`).action(async t=>{try{let n=e(),r=process.cwd();if(t.port!==void 0){let e=kc(process.env.OK_MCP_SPAWN_TIMEOUT_MS);await Uc({lockDir:``,contentDir:``,portOverride:t.port,envAutoStart:process.env.OK_MCP_AUTOSTART,timeoutMs:e});return}let i=t.bundleProxy===!1?[...process.argv,`--no-bundle-proxy`]:process.argv,a=Xo(process.env,i,process.platform);if(a.proxy){let e=Yo(process.platform,zt(),{existsSync:N});if(e===null)Zo({stderr:process.stderr,mode:`fallback-absent`,bundlePath:null,reason:`no installed Open Knowledge.app bundle found`});else try{await Qo({bundlePath:e,argv:process.argv.slice(2),env:process.env,stderr:process.stderr});return}catch(t){Zo({stderr:process.stderr,mode:`fallback-exec-failed`,bundlePath:e,reason:t instanceof Error?t.message:String(t)})}}else{let e=a.suppressedBy===`env`?`suppressed-env`:a.suppressedBy===`flag`?`suppressed-flag`:a.suppressedBy===`self`?`suppressed-self`:`suppressed-platform`;Zo({stderr:process.stderr,mode:e,bundlePath:null,reason:null})}await Yc({startupCwd:r,startupConfig:n})}catch(e){process.stderr.write(`MCP server failed to start: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}})}function Zc(e){return new t(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-
|
|
71
|
+
`),process.exit(1)},5e3).unref(),g().finally(()=>{process.exit(0)}))};if(process.once(`SIGINT`,y),process.once(`SIGTERM`,y),ss({log:e=>t.write(`${e}\n`),transport:p,process,stdin:process.stdin}),process.platform===`darwin`){let e=os(Wc,{realpathSync:Mt,statInoSync:e=>Pt(e).ino,log:e=>t.write(`${e}\n`)});if(e!==void 0){t.write(`[mcp] bundle identity anchor=${e.resolvedPath} inode=${e.inode} version=${_}\n`);let{resolvedPath:n,inode:r}=e;h=as({detect:()=>is({bundleAnchorPath:Wc,currentInode:r,platform:process.platform,realpath:Mt,statInode:e=>Pt(e).ino}),onReplaced:e=>{t.write(`[mcp] bundle replaced anchor=${n} bootInode=${e.currentInode} onDiskInode=${e.onDiskInode} version=${_} — exiting for host respawn\n`),y()},log:e=>t.write(`[mcp] ${e}\n`)})}}return{close:g}}function Xc(e){return new t(`mcp`).description(`Start MCP stdio server for project knowledge base`).option(`-p, --port <port>`,`Override per-call routing and proxy stdio to this HTTP MCP port (skips bundle proxy)`,void 0).option(`--no-bundle-proxy`,`Run the npm-fetched MCP server in-process instead of proxying to the macOS Desktop bundle (equivalent: OK_BUNDLE_PROXY=0)`).action(async t=>{try{let n=e(),r=process.cwd();if(t.port!==void 0){let e=kc(process.env.OK_MCP_SPAWN_TIMEOUT_MS);await Uc({lockDir:``,contentDir:``,portOverride:t.port,envAutoStart:process.env.OK_MCP_AUTOSTART,timeoutMs:e});return}let i=t.bundleProxy===!1?[...process.argv,`--no-bundle-proxy`]:process.argv,a=Xo(process.env,i,process.platform);if(a.proxy){let e=Yo(process.platform,zt(),{existsSync:N});if(e===null)Zo({stderr:process.stderr,mode:`fallback-absent`,bundlePath:null,reason:`no installed Open Knowledge.app bundle found`});else try{await Qo({bundlePath:e,argv:process.argv.slice(2),env:process.env,stderr:process.stderr});return}catch(t){Zo({stderr:process.stderr,mode:`fallback-exec-failed`,bundlePath:e,reason:t instanceof Error?t.message:String(t)})}}else{let e=a.suppressedBy===`env`?`suppressed-env`:a.suppressedBy===`flag`?`suppressed-flag`:a.suppressedBy===`self`?`suppressed-self`:`suppressed-platform`;Zo({stderr:process.stderr,mode:e,bundlePath:null,reason:null})}await Yc({startupCwd:r,startupConfig:n})}catch(e){process.stderr.write(`MCP server failed to start: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}})}function Zc(e){return new t(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-CcHJG_2a.mjs`),r=e(),i=process.cwd(),a=Me(r,i),o;try{o=t({projectDir:i,contentDir:a})}catch(e){console.error(`Content preview failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}process.stdout.write(`${n(o,i)}\n`),o.totalCount===0&&o.warnings.length>0&&(process.exitCode=1)})}function Qc(e){return e==null?!1:e.includes(`--type=utility`)&&e.includes(`--utility-sub-type=node.mojom.NodeService`)}function $c(e,t=Date.now()){let n=new Date(e).getTime();if(Number.isNaN(n))return`—`;let r=t-n,i=Math.floor(r/1e3);if(i<60)return`${i}s`;let a=Math.floor(i/60);if(a<60)return`${a}m ago`;let o=Math.floor(a/60);return o<24?`${o}h ago`:`${Math.floor(o/24)}d ago`}function el(e,t,n,r,i,a){if(t.status===`missing`||t.status===`corrupt`)return null;let o=t.lock,s=null;if(n.status!==`missing`&&n.status!==`corrupt`){let e=n.lock;s={port:e.port,status:n.status,pid:e.pid,startedAt:e.startedAt,usage:a}}return{directory:o.worktreeRoot,server:{port:o.port,status:t.status,pid:o.pid,startedAt:o.startedAt,usage:i},ui:s,hostname:o.hostname,lockPath:t.lockPath,binary:r==null?null:Ja(r),command:r,isDesktop:Qc(r)}}function tl(e){return e.ui==null?!1:e.ui.status===`alive`||e.ui.status===`foreign-host`}function nl(e){let t=e.server.status;return t===`alive`||t===`foreign-host`?e.isDesktop?`desktop`:t===`alive`?`running`:`foreign`:t===`dead-pid`&&tl(e)?`ui-orphan`:`stale`}const rl=new Set([`running`,`desktop`,`foreign`,`ui-orphan`]);function il(e){switch(e){case`running`:return G.default.green(e);case`desktop`:return G.default.blue(e);case`foreign`:return G.default.cyan(e);case`ui-orphan`:return G.default.magenta(e);case`stale`:return G.default.yellow(e)}}function al(e){return e==null?`—`:`${e.cpuPercent.toFixed(1)}% / ${e.memPercent.toFixed(1)}%`}function ol(e){return`${al(e.server.usage)} | ${al(e.ui?.usage??null)}`}function sl(e){return`${e.server.port===0?`(starting)`:String(e.server.port)} / ${e.ui==null||e.ui.status===`dead-pid`?`—`:String(e.ui.port)}`}function cl(e){if(e.length===0)return`No open-knowledge servers found.`;let t=[`DIRECTORY`,`PORTS (API/UI)`,`CPU/MEM (API | UI)`,`STATUS`,`PID`,`STARTED`,`BINARY`],n=e.map(e=>{let t=nl(e),n=t===`ui-orphan`&&e.ui!=null?e.ui.pid:e.server.pid;return[e.directory,sl(e),ol(e),t,String(n),$c(e.server.startedAt),e.binary??`—`]}),r=t.length,i=t.map(e=>e.length);for(let e of n)for(let t=0;t<r;t++)i[t]=Math.max(i[t]??0,(e[t]??``).length);let a=t.map((e,t)=>e.padEnd(i[t]??0)).join(` `).trimEnd(),o=e.map((e,t)=>{let a=n[t]??[],o=[];for(let t=0;t<r;t++){let n=(a[t]??``).padEnd(i[t]??0);if(t===3){let r=a[t]??``;n=il(nl(e))+` `.repeat(Math.max(0,(i[t]??0)-r.length))}o.push(n)}return o.join(` `).trimEnd()}),s=G.default.dim(`To stop a server: ok stop <port|pid|directory|all>`);return[a,...o,``,s].join(`
|
|
72
72
|
`)}async function ll(e={}){let t=e.discover??no,n=e.inspect??U,r=e.log??(e=>console.log(e)),i=e.resolveCommand??Ya,a=e.resolveUsage??Xa,o=await t(),s=[];for(let e of o){let t=n(e,`server`),r=n(e,`ui`),o=el(e,t,r,t.status===`missing`||t.status===`corrupt`?null:i(t.lock.pid),t.status===`missing`||t.status===`corrupt`?null:a(t.lock.pid),r.status===`missing`||r.status===`corrupt`?null:a(r.lock.pid));o!=null&&s.push(o)}if(e.json){let e=s.map(e=>({...e,displayStatus:nl(e)}));r(JSON.stringify(e,null,2));return}r(cl(e.all?s:s.filter(e=>rl.has(nl(e)))))}function ul(){return new t(`ps`).description(`List all running open-knowledge servers`).argument(`[modifier]`,`"all" to include stale (dead-pid) entries`).option(`--all`,`Include stale (dead-pid) entries (foreign-host shows by default)`).option(`--json`,`Emit structured JSON (always includes all statuses)`).action(async(e,t)=>{await ll({all:t.all===!0||e===`all`,json:t.json===!0})})}function dl(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function fl(e,t,n=process.cwd()){let r=e.op??`sync`,i=m(w(n));if(i&&i.port>0){let t=`http://127.0.0.1:${i.port}/api/sync/trigger`;e.json||process.stderr.write(`Triggering ${r} via running server (port ${i.port})\n`);try{let n=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,...b({kind:`cli`,runtimeVersion:_})},body:JSON.stringify({op:r})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.title??e.error??e.message??`Server responded with ${n.status}`)}dl(e.json,{type:`triggered`,op:r,port:i.port}),e.json||process.stderr.write(`✓ ${r} triggered\n`);return}catch(t){let n=t instanceof Error?t.message:String(t);e.json||process.stderr.write(`Server trigger failed (${n}), running directly\n`)}}e.json||process.stderr.write(`Running ${r} directly (no live server)\n`);let a=xe({baseDir:n});if(r===`sync`||r===`pull`){dl(e.json,{type:`step`,step:`pull`});let t=await a.pull();dl(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(dl(e.json,{type:`step`,step:`push`}),await a.push(),dl(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
|
|
73
73
|
`)),dl(e.json,{type:`complete`,op:r}),e.json||process.stderr.write(`✓ ${r} complete\n`)}function pl(e){return new t(`sync`).description(`Commit, pull, and push to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await fl({json:t.json,op:`sync`},e())}catch(e){let n=e instanceof Error?e.message:String(e);t.json?process.stdout.write(`${JSON.stringify({type:`error`,message:n})}\n`):process.stderr.write(`✗ sync failed: ${n}\n`),process.exit(1)}})}function ml(e){return new t(`pull`).description(`Pull changes from the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await fl({json:t.json,op:`pull`},e())}catch(e){let n=e instanceof Error?e.message:String(e);t.json?process.stdout.write(`${JSON.stringify({type:`error`,message:n})}\n`):process.stderr.write(`✗ pull failed: ${n}\n`),process.exit(1)}})}function hl(e){return new t(`push`).description(`Push commits to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await fl({json:t.json,op:`push`},e())}catch(e){let n=e instanceof Error?e.message:String(e);t.json?process.stdout.write(`${JSON.stringify({type:`error`,message:n})}\n`):process.stderr.write(`✗ push failed: ${n}\n`),process.exit(1)}})}function gl(e){return typeof e==`string`&&Ke.includes(e)}async function _l(e={}){let t=M(e.cwd??process.cwd()),n=e.pack??`knowledge-base`;if(!Te[n])return{status:`failed`,message:`${D(`Error:`)} Unknown pack "${n}". Available: ${Ke.join(`, `)}`,exitCode:1};let r;try{r=await qe({projectDir:t,rootDir:e.root,packId:n})}catch(e){return e instanceof Oe?{status:`prerequisite-missing`,message:`${D(`Error:`)} ${e.message}`,exitCode:1}:{status:`failed`,message:`${D(`Error:`)} ${e instanceof Error?e.message:String(e)}`,exitCode:1}}if(r.created.length===0){let e=Te[n].name;return{status:`no-op`,message:`${E(`Your ${e} pack is already seeded.`)}\n${T(`Nothing to do.`)}`,plan:r,exitCode:0}}if(e.dryRun)return{status:`dry-run`,message:`${O(`Plan (dry-run — no changes made):`)}\n\n${yl(r,t)}`,plan:r,exitCode:0};if(!e.yes&&!await bl(`${O(`Plan:`)}\n\n${yl(r,t)}\n\n${O(`Apply?`)} ${T(`[Y/n] `)}`,e.confirmStream))return{status:`cancelled`,message:T(`Cancelled.`),plan:r,exitCode:0};let i=await Re(r,{projectDir:t,packId:n});if(i.errors.length>0){let e=i.errors.map(e=>` ${D(`✗`)} ${e.path}: ${e.error}`);return{status:`failed`,message:[`${mt(`Applied`)} ${i.applied} entries, ${mt(String(i.errors.length))} error(s):`,...e].join(`
|
|
74
74
|
`),plan:r,exitCode:1}}let a=Te[n].name;return{status:`applied`,message:`${E(`✓ Seeded ${a}`)} ${T(`(${i.applied} entries, ${i.durationMs}ms)`)}`,plan:r,exitCode:0}}function vl(){let e=[O(`Available packs:`)];for(let t of Ke){let n=Te[t];e.push(` ${E(t)} ${T(`—`)} ${n.name}: ${n.description}`)}return e.join(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Br as e,Cn as t,K as n,Wr as r,a as i,an as a,bn as o,c as s,d as c,f as l,g as u,h as d,i as f,l as p,ln as m,m as h,n as g,o as _,p as v,r as y,s as b,t as x,u as S,yr as C}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{$ as w,$n as T,$r as E,$t as D,A as O,An as k,Ar as A,At as j,B as M,Bn as N,Br as P,Bt as F,C as I,Cn as L,Cr as R,Ct as z,D as B,Dn as V,Dr as H,Dt as U,E as W,En as G,Er as K,Et as q,F as J,Fn as Y,Fr as X,Ft as Z,G as Q,Gn as $,Gr as ee,Gt as te,H as ne,Hn as re,Hr as ie,Ht as ae,I as oe,In as se,Ir as ce,It as le,J as ue,Jn as de,Jr as fe,Jt as pe,K as me,Kn as he,Kr as ge,Kt as _e,L as ve,Ln as ye,Lr as be,Lt as xe,M as Se,Mn as Ce,Mr as we,Mt as Te,N as Ee,Nn as De,Nr as Oe,Nt as ke,O as Ae,On as je,Or as Me,Ot as Ne,P as Pe,Pn as Fe,Pr as Ie,Pt as Le,Q as Re,Qn as ze,Qr as Be,Qt as Ve,R as He,Rn as Ue,Rr as We,Rt as Ge,S as Ke,Sn as qe,Sr as Je,St as Ye,T as Xe,Ti as Ze,Tn as Qe,Tr as $e,Tt as et,U as tt,Un as nt,Ur as rt,Ut as it,V as at,Vn as ot,Vr as st,Vt as ct,W as lt,Wn as ut,Wr as dt,Wt as ft,X as pt,Xn as mt,Xr as ht,Xt as gt,Y as _t,Yn as vt,Yr as yt,Yt as bt,Z as xt,Zn as St,Zr as Ct,Zt as wt,_ as Tt,_n as Et,_r as Dt,_t as Ot,a as kt,ai as At,an as jt,ar as Mt,at as Nt,b as Pt,bn as Ft,br as It,bt as Lt,c as Rt,ci as zt,cn as Bt,cr as Vt,ct as Ht,d as Ut,di as Wt,dn as Gt,dr as Kt,dt as qt,ei as Jt,en as Yt,er as Xt,et as Zt,f as Qt,fi as $t,fn as en,fr as tn,ft as nn,g as rn,gn as an,gr as on,gt as sn,h as cn,hn as ln,hr as un,ht as dn,i as fn,ii as pn,in as mn,ir as hn,it as gn,j as _n,jn as vn,jr as yn,jt as bn,k as xn,kn as Sn,kr as Cn,kt as wn,l as Tn,li as En,ln as Dn,lr as On,lt as kn,m as An,mn as jn,mr as Mn,mt as Nn,n as Pn,ni as Fn,nn as In,nr as Ln,nt as Rn,o as zn,oi as Bn,on as Vn,or as Hn,ot as Un,p as Wn,pn as Gn,pr as Kn,pt as qn,q as Jn,qn as Yn,qr as Xn,qt as Zn,r as Qn,ri as $n,rn as er,rr as tr,rt as nr,s as rr,si as ir,sn as ar,sr as or,st as sr,t as cr,ti as lr,tn as ur,tr as dr,tt as fr,u as pr,ui as mr,un as hr,ur as gr,ut as _r,v as vr,vn as yr,vr as br,vt as xr,w as Sr,wi as Cr,wn as wr,wr as Tr,wt as Er,x as Dr,xn as Or,xr as kr,xt as Ar,y as jr,yn as Mr,yr as Nr,yt as Pr,z as Fr,zn as Ir,zr as Lr,zt as Rr}from"./dist-
|
|
1
|
+
import{Br as e,Cn as t,K as n,Wr as r,a as i,an as a,bn as o,c as s,d as c,f as l,g as u,h as d,i as f,l as p,ln as m,m as h,n as g,o as _,p as v,r as y,s as b,t as x,u as S,yr as C}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{$ as w,$n as T,$r as E,$t as D,A as O,An as k,Ar as A,At as j,B as M,Bn as N,Br as P,Bt as F,C as I,Cn as L,Cr as R,Ct as z,D as B,Dn as V,Dr as H,Dt as U,E as W,En as G,Er as K,Et as q,F as J,Fn as Y,Fr as X,Ft as Z,G as Q,Gn as $,Gr as ee,Gt as te,H as ne,Hn as re,Hr as ie,Ht as ae,I as oe,In as se,Ir as ce,It as le,J as ue,Jn as de,Jr as fe,Jt as pe,K as me,Kn as he,Kr as ge,Kt as _e,L as ve,Ln as ye,Lr as be,Lt as xe,M as Se,Mn as Ce,Mr as we,Mt as Te,N as Ee,Nn as De,Nr as Oe,Nt as ke,O as Ae,On as je,Or as Me,Ot as Ne,P as Pe,Pn as Fe,Pr as Ie,Pt as Le,Q as Re,Qn as ze,Qr as Be,Qt as Ve,R as He,Rn as Ue,Rr as We,Rt as Ge,S as Ke,Sn as qe,Sr as Je,St as Ye,T as Xe,Ti as Ze,Tn as Qe,Tr as $e,Tt as et,U as tt,Un as nt,Ur as rt,Ut as it,V as at,Vn as ot,Vr as st,Vt as ct,W as lt,Wn as ut,Wr as dt,Wt as ft,X as pt,Xn as mt,Xr as ht,Xt as gt,Y as _t,Yn as vt,Yr as yt,Yt as bt,Z as xt,Zn as St,Zr as Ct,Zt as wt,_ as Tt,_n as Et,_r as Dt,_t as Ot,a as kt,ai as At,an as jt,ar as Mt,at as Nt,b as Pt,bn as Ft,br as It,bt as Lt,c as Rt,ci as zt,cn as Bt,cr as Vt,ct as Ht,d as Ut,di as Wt,dn as Gt,dr as Kt,dt as qt,ei as Jt,en as Yt,er as Xt,et as Zt,f as Qt,fi as $t,fn as en,fr as tn,ft as nn,g as rn,gn as an,gr as on,gt as sn,h as cn,hn as ln,hr as un,ht as dn,i as fn,ii as pn,in as mn,ir as hn,it as gn,j as _n,jn as vn,jr as yn,jt as bn,k as xn,kn as Sn,kr as Cn,kt as wn,l as Tn,li as En,ln as Dn,lr as On,lt as kn,m as An,mn as jn,mr as Mn,mt as Nn,n as Pn,ni as Fn,nn as In,nr as Ln,nt as Rn,o as zn,oi as Bn,on as Vn,or as Hn,ot as Un,p as Wn,pn as Gn,pr as Kn,pt as qn,q as Jn,qn as Yn,qr as Xn,qt as Zn,r as Qn,ri as $n,rn as er,rr as tr,rt as nr,s as rr,si as ir,sn as ar,sr as or,st as sr,t as cr,ti as lr,tn as ur,tr as dr,tt as fr,u as pr,ui as mr,un as hr,ur as gr,ut as _r,v as vr,vn as yr,vr as br,vt as xr,w as Sr,wi as Cr,wn as wr,wr as Tr,wt as Er,x as Dr,xn as Or,xr as kr,xt as Ar,y as jr,yn as Mr,yr as Nr,yt as Pr,z as Fr,zn as Ir,zr as Lr,zt as Rr}from"./dist-DKgq69uI.mjs";export{cr as AGENT_ID_MAX_LEN,Pn as AGENT_ID_RE,Qn as AGENT_WRITE_ORIGIN,fn as AgentFocusBroadcaster,kt as AgentPresenceBroadcaster,zn as AgentSessionCapacityError,rr as AgentSessionManager,Rt as BacklinkIndex,Tn as CC1Broadcaster,n as CC1_CONTRACT_VERSION,pr as CONFIG_FILENAME,Ut as CONFLICT_MARKER_RE,Qt as CURSOR_BUNDLE_PATHS_BY_PLATFORM,Wn as ConfigSchema,An as DEFAULT_CHECKPOINT_RETENTION,cn as DEFAULT_PACK_ID,rn as FILE_SYSTEM_WRITER,Tt as FILE_WATCHER_ORIGIN,vr as GIT_PREFLIGHT_FAIL_SPAN_NAME,jr as GIT_UPSTREAM_WRITER,Cr as GitDirAccessError,Pt as GitNotAvailableError,Dr as GitTooOldError,Ke as HOCUSPOCUS_AUTH_REJECTION_REASONS,I as HocuspocusAuthRejection,Sr as HocuspocusAuthTokenSchema,Xe as INSTALLED_AGENTS_SCHEMES,W as LIVE_DERIVED_INDEX_DEBOUNCE_MS,B as LOG_MD_TEMPLATE,Ae as MANAGED_RENAME_ORIGIN,xn as MAX_AGENT_SESSIONS,O as MCP_CONNECTION_ID_HEADER,_n as MCP_SERVER_NAME,Se as MIN_GIT_VERSION,Ee as MISSING_OK_CONFIG_MESSAGE,Ze as MalformedGitPointerError,Pe as McpLogger,J as MissingOkConfigError,oe as OBSERVER_SYNC_ORIGIN,ve as OK_OKIGNORE_TEMPLATE,a as ORPHAN_MODES,m as PROTOCOL_VERSION,He as PinoLogger,x as ProcessLockCollisionError,Fr as ProjectGitInitError,M as ROLLBACK_ORIGIN,at as ROOT_GITIGNORE_TEMPLATE,g as RUNTIME_VERSION,ne as SERVICE_WRITER,tt as SKILL_INSTALL_EVENTS_FILE_REL,o as SKILL_STATE_TARGETS,lt as STARTER_FOLDERS,Q as STARTER_FOLDER_FRONTMATTER_FILENAME,me as STARTER_PACKS,Jn as STARTER_PACK_IDS,ue as STARTER_TEMPLATES,_t as STATE_MANIFEST_FILENAME,y as STATE_SCHEMA_VERSION,t as SYSTEM_DOC_NAME,pt as SeedPrerequisiteError,xt as SeedRootDirError,f as ServerLockCollisionError,Re as StateManifestError,w as TagIndex,Zt as UiLockCollisionError,i as acquireProcessLock,_ as acquireServerLock,fr as acquireUiLock,Rn as applyAgentMarkdownWrite,nr as applyExternalChange,gn as applySeed,Nt as assertCompatibleStateManifest,Un as assertGitAvailable,sr as assertNeverDiskEvent,Ht as attachIdleShutdown,kn as bootServer,_r as buildAndOpenSkill,qt as buildConfigYmlContent,nn as buildExecResult,qn as buildInstructions,Nn as buildSkillZip,dn as buildStarterFolderFrontmatterYaml,sn as buildWipTree,Ot as classifyEvents,xr as classifyFsPath,Pr as clearContributors,Lt as coercePackId,C as colorFromSeed,Ar as commitUpstreamImport,Ye as commitWip,z as commitWipFromTree,Er as compareSemver,et as containsConflictMarkers,q as contentHash,U as contributorCount,Ne as createApiExtension,wn as createAssetServeMiddleware,j as createContentFilter,bn as createContentFilterAsync,Te as createExternalChangeHandler,ke as createFileLogger,Le as createLiveDerivedIndexExtension,Z as createMcpHttpHandler,le as createOsProbe,xe as createPersistenceExtension,Ge as createServer,Rr as createServerObserverExtension,F as createStreamingErrorWriter,ct as createTestLogger,ae as detectClaudeDesktopPresence,it as detectGit,ft as detectProjectShape,te as emitPreflightFailureSpan,_e as ensureProjectGit,Zn as errorResponse,pe as evictStaleTrackerEntries,bt as extractWikiLinksFromMarkdown,gt as fallbackPaths,wt as findEnclosingGitRoot,Ve as findEnclosingProjectRoot,D as formatAuthRejectionWire,Yt as formatContributors,ur as formatContributorsFrom,In as gcCheckpointRefs,er as getCurrentMcpLogger,mn as getLocalDir,jt as getLogFilePath,Vn as getLogger,ar as getLogsDir,Bt as getMeter,Dn as getMetrics,hr as getTracer,Gt as handleCollabSocketError,en as handleSpawnCursor,e as iconFromClientName,Gn as incrementCollabSocketFilteredError,jn as incrementServerObserverFire,ln as initContent,an as initShadowRepo,Et as initTelemetry,yr as installPrettyZodErrors,Mr as installTestLoggers,Ft as installUserSkill,Or as isAllowedApiOrigin,qe as isAllowedWorkspaceHostHeader,L as isConfigDoc,wr as isHocuspocusAuthRejectionReason,Qe as isKnownPackId,G as isLoopbackAddress,r as isOrphanMode,V as isPairedWriteOrigin,je as isPathWithinDir,b as isProcessAlive,Sn as isProjectRoot,k as isSelfWrite,vn as isSystemDoc,s as isValidLockPid,Ce as lastKnownHash,De as listRescueCheckpoints,Fe as listStarterPacks,Y as loadPrincipal,p as lockFilePath,se as loggerFactory,ye as logsCurrentPath,Ue as logsPreviousPath,Ir as mountMcpAndApi,N as normalizeFsPath,ot as packageVersionMajorMinor,re as parseAuthRejectionWire,nt as parseGitVersion,ut as parseHocuspocusAuthToken,$ as parseKeepaliveConnectionId,he as pathToDocName,Yn as planSeed,de as readAllTargets,vt as readBranchFromHead,S as readProcessLock,c as readProcessLockDetailed,l as readServerLock,mt as readServerPackageVersion,St as readSkillInstallStateSnapshot,ze as readStateManifest,T as readTargetRecordedAt,Xt as readTargetVersion,dr as readUiLock,Ln as reconcile,tr as recordContributor,hn as recordSkillInstallEvent,Mt as registerAllTools,Hn as registerWrite,v as releaseProcessLock,h as releaseServerLock,or as releaseUiLock,Vt as removeLastKnownHash,On as resetMetrics,gr as resolveBundledSkillDir,Kt as resolveContentDir,tn as resolveCursorBinaryDefault,Kn as resolveCursorSpawnInvocation,Mn as resolveLockDir,un as resolvePack,on as resolvePackageVersion,Dt as restoreContributors,br as restoreLifecycleFromConflictsJson,Nr as rewriteMarkdownLinksForDocumentRename,It as rewriteWikiLinksForDocumentRename,kr as runAuthReposSubprocess,Je as runAuthStatusSubprocess,R as runCloneSubprocess,Tr as runDeviceFlowSubprocess,$e as runWithMcpLogger,K as safeContentPath,H as safeSubdir,Me as safetyCheckpoint,Cn as sanitizeClientName,A as saveInMemoryCheckpoint,yn as saveVersion,we as seedBasenameIndex,Oe as serializeError,Ie as setActiveSpanAttributes,X as shadowGit,ce as shutdownTelemetry,be as spansCurrentPath,We as spansPreviousPath,Lr as spawnDetached,P as splitMarkdownBlocks,st as startWatcher,ie as streamingProblemEvent,rt as swapContributors,dt as toBroadcasterKey,ee as tracedAppendFileSync,ge as tracedLinkSync,Xn as tracedMkdir,fe as tracedMkdirSync,yt as tracedRename,ht as tracedRenameSync,Ct as tracedRmSync,Be as tracedRmdirSync,E as tracedUnlinkSync,Jt as tracedWriteFile,lr as tracedWriteFileSync,Fn as updateLastKnownHash,d as updateProcessLockPort,u as updateServerLockPort,$n as updateUiLockPort,pn as validateAgentId,At as validateCloneInputs,Bn as validateSkillZip,ir as withSpan,zt as withSpanSync,En as writeRootGitignoreForNewRepo,mr as writeStateManifest,Wt as writeTargetVersion,$t as writeTracker};
|
|
@@ -3065,8 +3065,8 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
3065
3065
|
`),{previewUrl:q?.url??null,...q?{previewUrlSource:q.source}:{},...k?{summary:k}:{}})}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`. Optional for a new doc (defaults to `replace`); required for an existing doc. Forced to `replace` with `template`.","- `summary` — Optional one-line user-outcome (≤80 chars). Avoid secrets or PII — persisted to git history.",``,"Folder schema declarations: if the target folder declares fields via `<folder>/.ok/schema.yml`, those declarations surface on each doc's `EnrichedMeta.schema_declarations` (visible through `exec(\"cat <doc>.md\")`). Prefer including declared fields in the new doc's frontmatter when their value is known. Type is advisory, not enforced."].join(`
|
|
3066
3066
|
`)}\n${renderInventoryFooter()}`;function frontmatterIgnoredNote(e,t){return e!==`prepend`&&e!==`append`||!t||stripFrontmatter(t).frontmatter.trim()===``?null:`Note: a \`---\` frontmatter block in this \`${e}\` payload was ignored — frontmatter is written only with \`position: "replace"\`. To change frontmatter, use \`edit_frontmatter\` (1-2 keys) or \`write_document({ position: "replace" })\` (full rewrite).`}function docExistsOnDisk(e,t){return SUPPORTED_DOC_EXTENSIONS.some(s=>{let g=resolveWithinRoot(e,`${t}${s}`);return g.ok&&existsSync(g.abs)})}async function writeOneDoc(e,t,s,g,S){let w=normalizeDocName(e.docName);if(!w.ok)return{docName:e.docName,ok:!1,error:w.error};let E=w.docName,D=S.identityRef?.current;if(e.template===void 0&&e.markdown===void 0)return{docName:E,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:E,ok:!1,error:"TEMPLATE_AND_MARKDOWN_BOTH_SET — `template` and `markdown` are mutually exclusive. Pass one; fill placeholders via subsequent `edit_document` calls."};let O=e.markdown??``,k;if(e.position!==void 0)k=e.position;else if(docExistsOnDisk(s,E))return{docName:E,ok:!1,error:`"${E}" already exists — pass \`position\` (\`append\` | \`prepend\` | \`replace\`), or use \`edit_document\` for a targeted change.`};else k=`replace`;if(e.template!==void 0){let s=parentFolderOf(E),g=resolveTemplatesAvailable(t,s,{depth:1}),S=g.find(t=>t.name===e.template);if(!S)return{docName:E,ok:!1,error:`template "${e.template}" not found for folder "${s||`.`}". Available: ${g.length===0?`(none)`:g.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 w;try{w=readFileSync(resolve(t,S.path),`utf-8`)}catch(e){return{docName:E,ok:!1,error:`failed to read template at ${S.path}: ${e.message}`}}let{body:j}=stripFrontmatter(w);O=applySubstitution(j,{date:todayIsoUtc(),user:D?.displayName??``}),k=`replace`}let j=await httpPost(g,`/api/agent-write-md`,{docName:E,markdown:O,position:k,...e.summary===void 0?{}:{summary:e.summary},...D?{agentId:D.connectionId,agentName:D.displayName,clientName:D.clientInfo?.name,colorSeed:D.colorSeed}:{}});return j.ok?{docName:E,ok:!0,position:k,...e.template===void 0?{}:{fromTemplate:e.template},raw:j}:{docName:E,ok:!1,error:String(j.error)}}function register(e,t){let s={docName:string().describe(`Document name to write to`),markdown:string().optional().describe("Markdown content to write. Optional when `template` is set."),template:string().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. Optional for a new doc (defaults to `replace`); required when the doc already exists."),summary:summaryArgSchema};e.registerTool(`write_document`,{description:DESCRIPTION,inputSchema:{docName:string().optional().describe(`A single document to write to.`),markdown:string().optional().describe("Markdown content. Optional when `template` is set."),template:string().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. Optional for a new doc (defaults to `replace`); required when the doc already exists."),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().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:g,config:S,url:w}=s;if(!w)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let E=resolveLockDir(g),D=resolveContentDir(S,g),O=S.appearance.preview.autoOpen;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 S of e.docs)s.push(await writeOneDoc(S,g,D,w,t));let S=s.map(e=>{if(!e.ok)return{docName:e.docName,ok:!1,error:e.error};let t=resolvePreviewUrl(e.docName,{lockDir:E});return{docName:e.docName,ok:!0,position:e.position,...t?{previewUrl:t.url}:{}}}),k=S.filter(e=>e.ok).length,j=k===S.length,F=S.map(e=>e.ok?`Wrote ${e.docName} (${e.position}).`:`Failed ${e.docName}: ${e.error}`),L=e.docs.flatMap((e,t)=>{let g=s[t];if(!g?.ok)return[];let S=frontmatterIgnoredNote(g.position,e.markdown);return S?[`${e.docName} — ${S}`]:[]}),B=[`${k}/${S.length} written.`,...F,...L].join(`
|
|
3067
3067
|
`),H={ok:j,documents:S},q=s.find(e=>e.ok);return q&&q.raw.systemSubscriberCount===0&&(H.warning=buildPreviewAttachWarning(resolvePreviewUrl(q.docName,{lockDir:E}),O)),textPlusStructured(B,H,!j)}if(e.docName===void 0)return textResult("Error: provide `docName` (single) or `docs` (batch).",!0);let k=await writeOneDoc({docName:e.docName,markdown:e.markdown,template:e.template,position:e.position,summary:e.summary},g,D,w,t);if(!k.ok)return textResult(`Error: ${k.error}`,!0);let j=k.raw,F=resolvePreviewUrl(k.docName,{lockDir:E}),L=typeof j.subscriberCount==`number`?j.subscriberCount:void 0,B=(typeof j.systemSubscriberCount==`number`?j.systemSubscriberCount:void 0)===0,H=L===0,q=Array.isArray(j.hints)?j.hints:void 0,J=j.summary&&typeof j.summary==`object`?j.summary:void 0,Y=typeof J?.hint==`string`?J.hint:void 0,ee=[k.fromTemplate===void 0?`Written successfully (${k.position}).`:`Written successfully (instantiated from template "${k.fromTemplate}").`],te=frontmatterIgnoredNote(k.position,e.markdown);if(te&&ee.push(te),B&&!F&&ee.push(START_UI_TEXT_HINT),Y&&ee.push(Y),q)for(let e of q)e.message&&ee.push(e.message);let ne=ee.join(`
|
|
3068
|
-
`);if(!F&&!B&&!H&&!q&&!J)return textResult(ne);let ae={};return F&&(ae.previewUrl=F.url,ae.previewUrlSource=F.source),B&&(ae.warning=buildPreviewAttachWarning(F,O)),q&&(ae.hints=q),J&&(ae.summary=J),textPlusStructured(ne,ae)})}function registerAllTools(e,t){let s=t.logger,g=createLoggedServer(e,{logger:t.logger,identityRef:t.identityRef}),S=e=>async g=>{try{let S=await t.resolveCwd(g);return(getCurrentMcpLogger()??s)?.debug(`tool cwd resolved`,{tool:e,cwd:S,...g?{explicit:g}:{}}),S}catch(t){throw(getCurrentMcpLogger()??s)?.warn(`tool call failed`,{tool:e,error:t instanceof Error?t.message:String(t),...g?{explicit:g}:{}}),t}};register$17(g,{resolveCwd:S(`exec`),serverUrl:t.serverUrl,config:t.config}),register$9(g,{config:t.config,resolveCwd:S(`ingest`)}),register$5(g,{config:t.config,resolveCwd:S(`research`)}),register$22(g,{config:t.config,resolveCwd:S(`consolidate`)}),register$20(g,{config:t.config,resolveCwd:S(`discover`)}),register$3(g,{resolveCwd:S(`search`),config:t.config,serverUrl:t.serverUrl}),register$8(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`links`)}),register(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`write_document`),identityRef:t.identityRef}),register$19(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`edit_document`),identityRef:t.identityRef}),register$21(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`delete_document`),identityRef:t.identityRef}),register$18(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`edit_frontmatter`),identityRef:t.identityRef}),register$6(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`rename`),identityRef:t.identityRef}),register$11(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_history`)}),register$1(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`version`),identityRef:t.identityRef}),register$14(g,{resolveCwd:S(`get_components`),config:t.config}),register$15(g,{resolveCwd:S(`get_authoring_palette`),config:t.config}),register$13(g,{config:t.config,resolveCwd:S(`get_config`)}),register$10(g,{config:t.config,resolveCwd:S(`get_preview_url`)}),register$16(g,{config:t.config,resolveCwd:S(`folder_config`)}),register$7(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`list_conflicts`)}),register$12(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_conflict_content`)}),register$4(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`resolve_conflict`)}),register$2(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`share_link`)})}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 g=e.config,S=new McpServer({name:MCP_SERVER_NAME,version:RUNTIME_VERSION},{instructions:buildInstructions(g.content)});installPrettyZodErrors(S);let w=s??randomUUID(),E={current:{connectionId:w,displayName:w,colorSeed:w}};S.server.oninitialized=()=>{let e=S.server.getClientVersion(),t=sanitizeClientName(e?.name,w);E.current={connectionId:w,clientInfo:e?{name:t,version:e.version}:void 0,displayName:displayNameFromClientName(t),colorSeed:t}};let D=e.projectDir??e.contentDir;return registerAllTools(S,{serverUrl:async()=>e.getServerUrl(),resolveCwd:async e=>{if(e===void 0)return D;let t=resolveWithinRoot(D,e);if(!t.ok)throw Error(`cwd "${e}" is not within the configured project root: ${t.reason}`);return t.abs},config:g,identityRef:E}),{server:S,transport:t}}function createMcpHttpHandler(e){let t=new Map,s=e.sessionTtlMs??1800*1e3,g=e.maxSessions??100;async function S(s,g){let S=t.get(s);if(!S)return;t.delete(s),S.ttlTimer!==void 0&&clearTimeout(S.ttlTimer);let w=await Promise.allSettled([S.server.close(),S.transport.close()]);for(let t of w)t.status===`rejected`&&e.log?.warn?.({err:t.reason,sessionId:s,reason:g},`MCP HTTP session close failed`);e.log?.info?.({sessionId:s,reason:g},`MCP HTTP session closed`)}function w(t,g){g.ttlTimer!==void 0&&clearTimeout(g.ttlTimer),g.ttlTimer=setTimeout(()=>{S(t,`ttl-expired`).catch(s=>{e.log?.warn?.({err:s,sessionId:t},`MCP HTTP session TTL cleanup failed`)})},s),g.ttlTimer.unref?.()}return{async handle(s,E){let D=firstHeader(s.headers[`mcp-session-id`]);if(D){let e=t.get(D);if(!e){writePlain(E,404,`MCP session not found`);return}w(D,e),await e.transport.handleRequest(s,E);return}if(s.method!==`POST`){writePlain(E,400,`Missing MCP session. Initialize with POST /mcp first.`);return}if(t.size>=g){e.log?.warn?.({activeSessions:t.size,maxSessions:g},`MCP HTTP session cap reached`),writePlain(E,503,`Too many active MCP sessions`);return}let O=firstHeader(s.headers[MCP_CONNECTION_ID_HEADER]),k=validateAgentId(O)??void 0;O!==void 0&&k===void 0&&e.log?.warn?.({headerLength:O.length},`MCP HTTP forwarded connectionId header failed validation; falling back to randomUUID`);let j=new StreamableHTTPServerTransport({sessionIdGenerator:()=>randomUUID(),enableJsonResponse:!0,onsessioninitialized:async s=>{try{let g=createSessionServer(e,j,k);await g.server.connect(j),t.set(s,g),w(s,g),e.log?.info?.({sessionId:s},`MCP HTTP session initialized`)}catch(g){throw t.delete(s),e.log?.error?.({err:g,sessionId:s},`MCP HTTP session initialization failed`),g}}});j.onerror=t=>{e.log?.warn?.({err:t},`MCP HTTP transport error`)},j.onclose=()=>{let t=j.sessionId;if(!t){e.log?.info?.({sessionId:t,reason:`transport-closed`},`MCP HTTP session closed`);return}S(t,`transport-closed`).catch(s=>{e.log?.warn?.({err:s,sessionId:t},`MCP HTTP transport-close cleanup failed`)})},await j.handleRequest(s,E)},async close(){let e=[...t.entries()];await Promise.allSettled(e.map(([e])=>S(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:g,log:S,sessionManager:w,agentFocusBroadcaster:E,agentPresenceBroadcaster:D,contentAssetMiddleware:O,reactShellMiddleware:k}=e,j=e.keepaliveGraceMs??DEFAULT_KEEPALIVE_GRACE_MS,F=new import_websocket_server$1.default({noServer:!0,maxPayload:MAX_COLLAB_MESSAGE_BYTES});F.on(`error`,e=>{S.error({err:e},`WebSocketServer error`)});let L=new Map,B=new Set,H=!1;return t.on(`request`,(e,t)=>{let w=e.url?.split(`?`)[0];if(g!==void 0&&w===`/mcp`){let s=e.headers.origin,w=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}g.handle(e,t).catch(e=>{S.error({err:e,sessionId:w},`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(w?.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`} ${w}`})}).catch(e=>{S.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 E=(s,g,w)=>{if(s===void 0){w();return}try{s(e,t,()=>{t.writableEnded||t.headersSent||w()})}catch(e){S.error({err:e},`Unhandled ${g} 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()}},D=e=>E(O,`content-asset`,e),j=e=>E(k,`react-shell`,e),F=()=>{t.writableEnded||t.headersSent||errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`No handler for ${w??`/`}`})};if(k!==void 0&&w?.startsWith(`/assets/`)){j(()=>D(F));return}if(O!==void 0||k!==void 0){D(()=>j(F));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 ${w??`/`}`})}),t.on(`upgrade`,(e,t,g)=>{if(e.url?.startsWith(`/collab/keepalive`)){if(!isLoopbackAddress(e.socket.remoteAddress)||!isAllowedWorkspaceHostHeader(e.headers.host)){t.destroy();return}t.on(`error`,e=>{handleCollabSocketError(e)||S.error({err:e},`MCP keepalive socket error`)}),F.handleUpgrade(e,t,g,t=>{let s=parseKeepaliveConnectionId(e.url);if(s){let e=L.get(s);e!==void 0&&(clearTimeout(e),L.delete(s),S.info({connectionId:s},`[keepalive] reconnect during grace — timer cancelled`))}if(s&&D){let t=parseKeepaliveIdentity(e.url);if(t)try{let e=iconFromClientName(t.clientName),g=AGENT_ICON_COLORS[e]??colorFromSeed(t.colorSeed);D.setPresence(toBroadcasterKey(s),{displayName:t.displayName,icon:e,color:g,currentDoc:`(connected)`,mode:`idle`,ts:Date.now()})}catch(e){S.error({err:e,connectionId:s},`[keepalive] presence bootstrap failed`)}}let g=setInterval(()=>{try{t.ping()}catch{}},3e4);g.unref?.();let O=s?setInterval(()=>{D?.bumpPresenceTs(toBroadcasterKey(s))},3e3):null;O?.unref?.(),t.on(`close`,()=>{if(clearInterval(g),O!==null&&clearInterval(O),!s)return;let e=setTimeout(()=>{if(L.delete(s),H)return;let e=(async()=>{S.info({connectionId:s},`[keepalive] grace expired — cleaning up sessions`);try{await w?.closeAllForAgent(s)}catch(e){S.error({err:e,connectionId:s},`[keepalive] closeAllForAgent failed`)}try{E?.clearFocus(s)}catch(e){S.error({err:e,connectionId:s},`[keepalive] clearFocus failed`)}try{D?.clearPresence(toBroadcasterKey(s))}catch(e){S.error({err:e,connectionId:s},`[keepalive] clearPresence failed`)}})();B.add(e),e.finally(()=>B.delete(e))},j);e.unref?.(),L.set(s,e),S.info({connectionId:s,graceMs:j},`[keepalive] disconnected — grace timer started`)}),t.on(`error`,e=>{handleCollabSocketError(e)||S.error({err:e},`MCP keepalive WS error`),t.terminate()})});return}if(e.url?.startsWith(`/collab`)){t.on(`error`,e=>{handleCollabSocketError(e)||S.error({err:e},`Upgrade socket error`)}),F.handleUpgrade(e,t,g,t=>{let g=s.handleConnection(t,e),w=!1;t.on(`message`,e=>{if(w)return;let s=e.byteLength;if(s>MAX_COLLAB_MESSAGE_BYTES){w=!0,incrementCollabMessageTooLarge(),S.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}g.handleMessage(new Uint8Array(e))}),t.on(`close`,(e,t)=>{g.handleClose({code:e,reason:t.toString()})}),t.on(`error`,e=>{if(e.code===`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`){incrementCollabMessageTooLarge(),S.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)||S.error({err:e},`WebSocket error`),t.terminate()})});return}t.destroy()}),{wss:F,shutdown:async()=>{if(!H){H=!0;for(let e of L.values())clearTimeout(e);L.clear(),B.size>0&&await Promise.allSettled(B)}}}}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`)),g=sanitizeIdentityField(t.searchParams.get(`clientName`)),S=sanitizeIdentityField(t.searchParams.get(`colorSeed`));return s===null||g===null||S===null?null:{displayName:s,clientName:g,colorSeed:S}}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:g}=await import(`./chokidar-CblsKfnx.mjs`),S=dirname(e);try{tracedMkdirSync(S,{recursive:!0})}catch(e){e.code!==`EEXIST`&&s.warn({err:e,watchDir:S},`failed to create watch directory; watcher may be inert`)}let w=g(S,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:t=>t!==S&&t!==e});await new Promise(e=>{w.once(`ready`,e)});let E=null;try{E=readFileSync(e,`utf-8`)}catch{}let D=(g,S=!0)=>{if(g!==e)return;let w;try{w=readFileSync(g,`utf-8`)}catch(e){if(e.code===`ENOENT`){S&&s.debug({path:g},`config file disappeared between event and read; dropping`);return}s.warn({err:e,path:g},`config file read failed; dropping event`);return}if(w!==E){E=w;try{t(w)}catch(e){s.warn({err:e,path:g},`config file change handler threw`)}}},O=e=>D(e);w.on(`add`,O),w.on(`change`,O),w.on(`unlink`,t=>{t===e&&s.debug({path:t},`config file unlinked; Y.Text retained at current state`)}),w.on(`error`,t=>{s.warn({err:t,watchDir:S,absPath:e},`[config-file-watcher] chokidar error while watching ${e}`)});let k=0,j=setInterval(()=>{k++,D(e,!1),k>=20&&clearInterval(j)},500);j.unref?.();let F=!1;return async()=>{F||(F=!0,clearInterval(j),await w.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:g}=await import(`./chokidar-CblsKfnx.mjs`),S=new Set(e),w=Array.from(new Set(Array.from(S,e=>dirname(e))));for(let e of w)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 E=g(w,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:e=>!S.has(e)&&!w.includes(e)});await new Promise(e=>{E.once(`ready`,e)});let D=new Map;for(let e of S)try{D.set(e,readFileSync(e,`utf-8`))}catch{D.set(e,null)}let O=(e,g=!0)=>{if(!S.has(e))return;let w;try{w=readFileSync(e,`utf-8`)}catch(t){if(t.code===`ENOENT`){g&&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(w!==D.get(e)){D.set(e,w);try{t(e,w)}catch(t){s.warn({err:t,path:e},`config file change handler threw`)}}},k=e=>O(e);E.on(`add`,k),E.on(`change`,k),E.on(`unlink`,e=>{S.has(e)&&s.debug({path:e},`config file unlinked; downstream state retained`)}),E.on(`error`,e=>{s.warn({err:e,watchDirs:w,paths:Array.from(S)},`[config-file-watcher] chokidar error in multi-path watcher`)});let j=0,F=setInterval(()=>{j++;for(let e of S)O(e,!1);j>=20&&clearInterval(F)},500);F.unref?.();let L=!1;return async()=>{L||(L=!0,clearInterval(F),await E.close())}}function entryMatchesDocName(e,t,s,g){let S=relative(g,join(s,e.file));return S.startsWith(`..`)?!1:stripDocExtension(S)===t}function createConflictLifecycleSeedExtension(e){let{getSyncEngine:t,projectDir:s,contentDir:g}=e;return{async afterLoadDocument({documentName:e,document:S}){if(!(isSystemDoc(e)||isConfigDoc(e)))try{let w=t();if(!w)return;let E=w.getConflicts();if(E.length===0||!E.some(t=>entryMatchesDocName(t,e,s,g)))return;let D=S.getMap(`lifecycle`);if(D.get(`status`)===`conflict`)return;D.set(`status`,`conflict`),D.set(`reason`,`conflict-markers`),console.warn(JSON.stringify({event:`lifecycle-seeded-on-load-from-conflict-store`,"doc.name":e}))}catch(t){console.warn(`[conflict-lifecycle-seed] failed to seed lifecycle on load (doc=${e}):`,t instanceof Error?t:String(t))}}}}const execFileAsync$1=promisify(execFile),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 loadGitExcludeSources(e,t){let s=readGitCommonDirSync(e);if(s===null)return[];let g=[];appendExcludeFileIfExists(join(s,`info`,`exclude`),t,g,`info/exclude`);let S=resolveGlobalExcludesfileSync(e);return S&&appendExcludeFileIfExists(S,t,g,`global excludesfile`),g}async function loadGitExcludeSourcesAsync(e,t){let s=await readGitCommonDirAsync(e);if(s===null)return[];let g=[];await appendExcludeFileIfExistsAsync(join(s,`info`,`exclude`),t,g,`info/exclude`);let S=await resolveGlobalExcludesfileAsync(e);return S&&await appendExcludeFileIfExistsAsync(S,t,g,`global excludesfile`),g}function readGitCommonDirSync(e){let t=spawnSync(`git`,[`rev-parse`,`--git-common-dir`],{cwd:e,encoding:`utf-8`,timeout:5e3});return t.status!==0||!t.stdout?null:resolve(e,t.stdout.trim())}async function readGitCommonDirAsync(e){try{let{stdout:t}=await execFileAsync$1(`git`,[`rev-parse`,`--git-common-dir`],{cwd:e,encoding:`utf-8`,timeout:5e3});return t?resolve(e,t.trim()):null}catch{return null}}function resolveGlobalExcludesfileSync(e){let t=spawnSync(`git`,[`config`,`--get`,`--type=path`,`core.excludesfile`],{cwd:e,encoding:`utf-8`,timeout:5e3});if(t.status===0&&t.stdout){let e=t.stdout.trim();if(e)return e}return xdgGlobalIgnoreDefault()}async function resolveGlobalExcludesfileAsync(e){try{let{stdout:t}=await execFileAsync$1(`git`,[`config`,`--get`,`--type=path`,`core.excludesfile`],{cwd:e,encoding:`utf-8`,timeout:5e3}),s=t.trim();if(s)return s}catch{}return xdgGlobalIgnoreDefault()}function xdgGlobalIgnoreDefault(){let e=process.env.XDG_CONFIG_HOME?.trim();return join(e&&e.length>0?e:join(homedir(),`.config`),`git`,`ignore`)}function appendExcludeFileIfExists(e,t,s,g){if(existsSync(e))try{let g=readFileSync(e,`utf-8`);t.value+=g.length,s.push(...parseIgnorePatterns(g))}catch(t){console.warn(`[content-filter] Failed to read ${g} at ${e}:`,t)}}async function appendExcludeFileIfExistsAsync(e,t,s,g){if(existsSync(e))try{let g=await readFile$1(e,`utf-8`);t.value+=g.length,s.push(...parseIgnorePatterns(g))}catch(t){console.warn(`[content-filter] Failed to read ${g} at ${e}:`,t)}}function createContentFilter(e){let{projectDir:t,contentDir:s,onAfterRebuild:g}=e,S=relative(t,s),w=S.startsWith(`..`),E,D,O,k=0,j=0,F=0;function L(){let e=(0,import_ignore.default)();e.add(`.git`);let g=[],L=0,B=0;for(let s of IGNORE_FILE_NAMES){let S=join(t,s);if(existsSync(S))try{let t=readFileSync(S,`utf-8`);L+=t.length;let s=parseIgnorePatterns(t);g.push(...s),e.add(s)}catch(e){console.warn(`[content-filter] Failed to read ${s} at ${S}:`,e)}}if(S&&!w)for(let t of IGNORE_FILE_NAMES){let g=join(s,t);if(existsSync(g))try{let t=readFileSync(g,`utf-8`);L+=t.length,B++;let s=parseIgnorePatterns(t).map(e=>prefixPattern(e,S));e.add(s)}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${g}:`,e)}}let H={value:L};B+=loadNestedIgnoreFiles(s,t,e,H),L=H.value;let q=loadGitExcludeSources(t,H);L=H.value,q.length>0&&(g.push(...q),e.add(q));let J=g.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`));return E=e,D=g,O=J,k=g.length,j=B,F=L,{patternCount:k,nestedFileCount:j,bytes:F}}L();let B=new Map;function H(e){if(w)return!1;let t=S?`${S}/${e}`:e;return E.ignores(t)}populateDirCount(s,``,H,B);function q(e){let t=stripDocExtension(e);return isSystemDoc(t)||isConfigDoc(t)}function J(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return w?!1:H(e)}return{isExcluded(e,t){if(q(e))return!0;if(t?.bypassFilters)return!1;if(J(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((B.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(w)return!1;let s=S?`${S}/${e}`:e;return E.ignores(s)||E.ignores(`${s}/`)},isPathIgnored(e,t){return q(e)?!0:t?.bypassFilters?!1:J(e)},getWatcherIgnoreGlobs(){return O},incrementMdDir(e){let t=e===`.`?``:e;B.set(t,(B.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,s=B.get(t)??0;s<=1?B.delete(t):B.set(t,s-1)},rebuildDirCount(){let e=new Map(B);B.clear();try{populateDirCount(s,``,H,B)}catch(t){for(let[t,s]of e)B.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=E,S=D,w=O,q=k,J=j,Y=F,ee=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async te=>{try{let t=L();B.clear(),populateDirCount(s,``,H,B);let S=Date.now()-ee;if(te.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:S},`content-filter rebuild succeeded`),g)try{g()}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:S}}catch(g){E=t,D=S,O=w,k=q,j=J,F=Y,B.clear();try{populateDirCount(s,``,H,B)}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 L=g instanceof Error?g.message:String(g);return e.warn({err:g instanceof Error?g:Error(L)},`content-filter rebuild failed — rolled back to previous state`),{ok:!1,error:{message:L}}}})}}}function populateDirCount(e,t,s,g){let S;try{S=readdirSync(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory for dir-count: ${e}`,t);return}for(let w of S){let S=t?`${t}/${w.name}`:w.name;if(w.isDirectory()){if(BUILTIN_SKIP_DIRS.has(w.name)||s(S)||s(`${S}/`))continue;populateDirCount(join(e,w.name),S,s,g)}else w.isFile()&&isSupportedDocFile(w.name)&&!s(S)&&g.set(t,(g.get(t)??0)+1)}}function parseIgnorePatterns(e){return e.split(`
|
|
3069
|
-
`).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,g){let S;try{S=readdirSync(e,{withFileTypes:!0})}catch(t){return console.warn(`[content-filter] Failed to read directory ${e}:`,t),0}let w=0;for(let E of S){if(!E.isDirectory()||BUILTIN_SKIP_DIRS.has(E.name))continue;let S=join(e,E.name),D=relative(t,S);if(!D.startsWith(`..`)&&!(s.ignores(D)||s.ignores(`${D}/`))){for(let e of IGNORE_FILE_NAMES){let t=join(S,e);if(existsSync(t))try{let e=readFileSync(t,`utf-8`);g.value+=e.length;let S=parseIgnorePatterns(e).map(e=>prefixPattern(e,D));s.add(S),w++}catch(s){console.warn(`[content-filter] Failed to read nested ${e} at ${t}:`,s)}}w+=loadNestedIgnoreFiles(S,t,s,g)}}return w}async function initContentDirStateAsync(e,t,s,g,S,w,E){let D;try{D=await readdir(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory ${e}:`,t);return}for(let O of D){let D=t?`${t}/${O.name}`:O.name;if(O.isDirectory()){if(BUILTIN_SKIP_DIRS.has(O.name))continue;let t=join(e,O.name);if(!w){let e=relative(s,t);if(e.startsWith(`..`)||g.ignores(e)||g.ignores(`${e}/`))continue;for(let s of IGNORE_FILE_NAMES){let S=join(t,s);if(existsSync(S))try{let t=parseIgnorePatterns(await readFile$1(S,`utf-8`));g.add(t.map(t=>prefixPattern(t,e)))}catch(e){console.warn(`[content-filter] Failed to read nested ${s} at ${S}:`,e)}}}await initContentDirStateAsync(t,D,s,g,S,w,E)}else if(O.isFile()&&isSupportedDocFile(O.name)){if(!w){let e=S?`${S}/${D}`:D;if(g.ignores(e))continue}E.set(t,(E.get(t)??0)+1)}}}async function createContentFilterAsync(e){let{projectDir:t,contentDir:s,onAfterRebuild:g}=e,S=relative(t,s),w=S.startsWith(`..`),E=(0,import_ignore.default)(),D=[],O=new Map;function k(e){if(w)return!1;let t=S?`${S}/${e}`:e;return E.ignores(t)}function j(e){let t=stripDocExtension(e);return isSystemDoc(t)||isConfigDoc(t)}function F(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return w?!1:k(e)}async function L(){let e=(0,import_ignore.default)();e.add(`.git`);let g=[];for(let s of IGNORE_FILE_NAMES){let S=join(t,s);if(existsSync(S))try{let t=parseIgnorePatterns(await readFile$1(S,`utf-8`));g.push(...t),e.add(t)}catch(e){console.warn(`[content-filter] Failed to read ${s} at ${S}:`,e)}}if(S&&!w)for(let t of IGNORE_FILE_NAMES){let g=join(s,t);if(existsSync(g))try{let t=parseIgnorePatterns(await readFile$1(g,`utf-8`));e.add(t.map(e=>prefixPattern(e,S)))}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${g}:`,e)}}let k=await loadGitExcludeSourcesAsync(t,{value:0});k.length>0&&(g.push(...k),e.add(k));let j=new Map;await initContentDirStateAsync(s,``,t,e,S,w,j),E=e,D=g.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`)),O.clear();for(let[e,t]of j)O.set(e,t)}return await L(),{isExcluded(e,t){if(j(e))return!0;if(t?.bypassFilters)return!1;if(F(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((O.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(w)return!1;let s=S?`${S}/${e}`:e;return E.ignores(s)||E.ignores(`${s}/`)},isPathIgnored(e,t){return j(e)?!0:t?.bypassFilters?!1:F(e)},getWatcherIgnoreGlobs(){return D},incrementMdDir(e){let t=e===`.`?``:e;O.set(t,(O.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,s=O.get(t)??0;s<=1?O.delete(t):O.set(t,s-1)},rebuildDirCount(){let e=new Map(O);O.clear();try{populateDirCount(s,``,k,O)}catch(t){for(let[t,s]of e)O.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=E,s=D,S=new Map(O),w=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async k=>{try{await L();let t=Date.now()-w;if(k.setAttributes({"ok.ignore.pattern_count":D.length,"ok.ignore.nested_file_count":0,"ok.ignore.bytes":0}),e.info({durationMs:t},`content-filter async rebuild succeeded`),g)try{g()}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:D.length,nestedFileCount:0,bytes:0,durationMs:t}}catch(g){E=t,D=s,O.clear();for(let[e,t]of S)O.set(e,t);let w=g instanceof Error?g.message:String(g);return e.warn({err:g instanceof Error?g:Error(w)},`content-filter async rebuild failed — rolled back`),{ok:!1,error:{message:w}}}})}}}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`),g=t.slice(5),S=s.split(`
|
|
3068
|
+
`);if(!F&&!B&&!H&&!q&&!J)return textResult(ne);let ae={};return F&&(ae.previewUrl=F.url,ae.previewUrlSource=F.source),B&&(ae.warning=buildPreviewAttachWarning(F,O)),q&&(ae.hints=q),J&&(ae.summary=J),textPlusStructured(ne,ae)})}function registerAllTools(e,t){let s=t.logger,g=createLoggedServer(e,{logger:t.logger,identityRef:t.identityRef}),S=e=>async g=>{try{let S=await t.resolveCwd(g);return(getCurrentMcpLogger()??s)?.debug(`tool cwd resolved`,{tool:e,cwd:S,...g?{explicit:g}:{}}),S}catch(t){throw(getCurrentMcpLogger()??s)?.warn(`tool call failed`,{tool:e,error:t instanceof Error?t.message:String(t),...g?{explicit:g}:{}}),t}};register$17(g,{resolveCwd:S(`exec`),serverUrl:t.serverUrl,config:t.config}),register$9(g,{config:t.config,resolveCwd:S(`ingest`)}),register$5(g,{config:t.config,resolveCwd:S(`research`)}),register$22(g,{config:t.config,resolveCwd:S(`consolidate`)}),register$20(g,{config:t.config,resolveCwd:S(`discover`)}),register$3(g,{resolveCwd:S(`search`),config:t.config,serverUrl:t.serverUrl}),register$8(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`links`)}),register(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`write_document`),identityRef:t.identityRef}),register$19(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`edit_document`),identityRef:t.identityRef}),register$21(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`delete_document`),identityRef:t.identityRef}),register$18(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`edit_frontmatter`),identityRef:t.identityRef}),register$6(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`rename`),identityRef:t.identityRef}),register$11(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_history`)}),register$1(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`version`),identityRef:t.identityRef}),register$14(g,{resolveCwd:S(`get_components`),config:t.config}),register$15(g,{resolveCwd:S(`get_authoring_palette`),config:t.config}),register$13(g,{config:t.config,resolveCwd:S(`get_config`)}),register$10(g,{config:t.config,resolveCwd:S(`get_preview_url`)}),register$16(g,{config:t.config,resolveCwd:S(`folder_config`)}),register$7(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`list_conflicts`)}),register$12(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_conflict_content`)}),register$4(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`resolve_conflict`)}),register$2(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`share_link`)})}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 g=e.config,S=new McpServer({name:MCP_SERVER_NAME,version:RUNTIME_VERSION},{instructions:buildInstructions(g.content)});installPrettyZodErrors(S);let w=s??randomUUID(),E={current:{connectionId:w,displayName:w,colorSeed:w}};S.server.oninitialized=()=>{let e=S.server.getClientVersion(),t=sanitizeClientName(e?.name,w);E.current={connectionId:w,clientInfo:e?{name:t,version:e.version}:void 0,displayName:displayNameFromClientName(t),colorSeed:t}};let D=e.projectDir??e.contentDir;return registerAllTools(S,{serverUrl:async()=>e.getServerUrl(),resolveCwd:async e=>{if(e===void 0)return D;let t=resolveWithinRoot(D,e);if(!t.ok)throw Error(`cwd "${e}" is not within the configured project root: ${t.reason}`);return t.abs},config:g,identityRef:E}),{server:S,transport:t}}function createMcpHttpHandler(e){let t=new Map,s=e.sessionTtlMs??1800*1e3,g=e.maxSessions??100;async function S(s,g){let S=t.get(s);if(!S)return;t.delete(s),S.ttlTimer!==void 0&&clearTimeout(S.ttlTimer);let w=await Promise.allSettled([S.server.close(),S.transport.close()]);for(let t of w)t.status===`rejected`&&e.log?.warn?.({err:t.reason,sessionId:s,reason:g},`MCP HTTP session close failed`);e.log?.info?.({sessionId:s,reason:g},`MCP HTTP session closed`)}function w(t,g){g.ttlTimer!==void 0&&clearTimeout(g.ttlTimer),g.ttlTimer=setTimeout(()=>{S(t,`ttl-expired`).catch(s=>{e.log?.warn?.({err:s,sessionId:t},`MCP HTTP session TTL cleanup failed`)})},s),g.ttlTimer.unref?.()}return{async handle(s,E){let D=firstHeader(s.headers[`mcp-session-id`]);if(D){let e=t.get(D);if(!e){writePlain(E,404,`MCP session not found`);return}w(D,e),await e.transport.handleRequest(s,E);return}if(s.method!==`POST`){writePlain(E,400,`Missing MCP session. Initialize with POST /mcp first.`);return}if(t.size>=g){e.log?.warn?.({activeSessions:t.size,maxSessions:g},`MCP HTTP session cap reached`),writePlain(E,503,`Too many active MCP sessions`);return}let O=firstHeader(s.headers[MCP_CONNECTION_ID_HEADER]),k=validateAgentId(O)??void 0;O!==void 0&&k===void 0&&e.log?.warn?.({headerLength:O.length},`MCP HTTP forwarded connectionId header failed validation; falling back to randomUUID`);let j=new StreamableHTTPServerTransport({sessionIdGenerator:()=>randomUUID(),enableJsonResponse:!0,onsessioninitialized:async s=>{try{let g=createSessionServer(e,j,k);await g.server.connect(j),t.set(s,g),w(s,g),e.log?.info?.({sessionId:s},`MCP HTTP session initialized`)}catch(g){throw t.delete(s),e.log?.error?.({err:g,sessionId:s},`MCP HTTP session initialization failed`),g}}});j.onerror=t=>{e.log?.warn?.({err:t},`MCP HTTP transport error`)},j.onclose=()=>{let t=j.sessionId;if(!t){e.log?.info?.({sessionId:t,reason:`transport-closed`},`MCP HTTP session closed`);return}S(t,`transport-closed`).catch(s=>{e.log?.warn?.({err:s,sessionId:t},`MCP HTTP transport-close cleanup failed`)})},await j.handleRequest(s,E)},async close(){let e=[...t.entries()];await Promise.allSettled(e.map(([e])=>S(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:g,log:S,sessionManager:w,agentFocusBroadcaster:E,agentPresenceBroadcaster:D,contentAssetMiddleware:O,reactShellMiddleware:k}=e,j=e.keepaliveGraceMs??DEFAULT_KEEPALIVE_GRACE_MS,F=new import_websocket_server$1.default({noServer:!0,maxPayload:MAX_COLLAB_MESSAGE_BYTES});F.on(`error`,e=>{S.error({err:e},`WebSocketServer error`)});let L=new Map,B=new Set,H=!1;return t.on(`request`,(e,t)=>{let w=e.url?.split(`?`)[0];if(g!==void 0&&w===`/mcp`){let s=e.headers.origin,w=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}g.handle(e,t).catch(e=>{S.error({err:e,sessionId:w},`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(w?.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`} ${w}`})}).catch(e=>{S.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 E=(s,g,w)=>{if(s===void 0){w();return}try{s(e,t,()=>{t.writableEnded||t.headersSent||w()})}catch(e){S.error({err:e},`Unhandled ${g} 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()}},D=e=>E(O,`content-asset`,e),j=e=>E(k,`react-shell`,e),F=()=>{t.writableEnded||t.headersSent||errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`No handler for ${w??`/`}`})};if(k!==void 0&&w?.startsWith(`/assets/`)){j(()=>D(F));return}if(O!==void 0||k!==void 0){D(()=>j(F));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 ${w??`/`}`})}),t.on(`upgrade`,(e,t,g)=>{if(e.url?.startsWith(`/collab/keepalive`)){if(!isLoopbackAddress(e.socket.remoteAddress)||!isAllowedWorkspaceHostHeader(e.headers.host)){t.destroy();return}t.on(`error`,e=>{handleCollabSocketError(e)||S.error({err:e},`MCP keepalive socket error`)}),F.handleUpgrade(e,t,g,t=>{let s=parseKeepaliveConnectionId(e.url);if(s){let e=L.get(s);e!==void 0&&(clearTimeout(e),L.delete(s),S.info({connectionId:s},`[keepalive] reconnect during grace — timer cancelled`))}if(s&&D){let t=parseKeepaliveIdentity(e.url);if(t)try{let e=iconFromClientName(t.clientName),g=AGENT_ICON_COLORS[e]??colorFromSeed(t.colorSeed);D.setPresence(toBroadcasterKey(s),{displayName:t.displayName,icon:e,color:g,currentDoc:`(connected)`,mode:`idle`,ts:Date.now()})}catch(e){S.error({err:e,connectionId:s},`[keepalive] presence bootstrap failed`)}}let g=setInterval(()=>{try{t.ping()}catch{}},3e4);g.unref?.();let O=s?setInterval(()=>{D?.bumpPresenceTs(toBroadcasterKey(s))},3e3):null;O?.unref?.(),t.on(`close`,()=>{if(clearInterval(g),O!==null&&clearInterval(O),!s)return;let e=setTimeout(()=>{if(L.delete(s),H)return;let e=(async()=>{S.info({connectionId:s},`[keepalive] grace expired — cleaning up sessions`);try{await w?.closeAllForAgent(s)}catch(e){S.error({err:e,connectionId:s},`[keepalive] closeAllForAgent failed`)}try{E?.clearFocus(s)}catch(e){S.error({err:e,connectionId:s},`[keepalive] clearFocus failed`)}try{D?.clearPresence(toBroadcasterKey(s))}catch(e){S.error({err:e,connectionId:s},`[keepalive] clearPresence failed`)}})();B.add(e),e.finally(()=>B.delete(e))},j);e.unref?.(),L.set(s,e),S.info({connectionId:s,graceMs:j},`[keepalive] disconnected — grace timer started`)}),t.on(`error`,e=>{handleCollabSocketError(e)||S.error({err:e},`MCP keepalive WS error`),t.terminate()})});return}if(e.url?.startsWith(`/collab`)){t.on(`error`,e=>{handleCollabSocketError(e)||S.error({err:e},`Upgrade socket error`)}),F.handleUpgrade(e,t,g,t=>{let g=s.handleConnection(t,e),w=!1;t.on(`message`,e=>{if(w)return;let s=e.byteLength;if(s>MAX_COLLAB_MESSAGE_BYTES){w=!0,incrementCollabMessageTooLarge(),S.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}g.handleMessage(new Uint8Array(e))}),t.on(`close`,(e,t)=>{g.handleClose({code:e,reason:t.toString()})}),t.on(`error`,e=>{if(e.code===`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`){incrementCollabMessageTooLarge(),S.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)||S.error({err:e},`WebSocket error`),t.terminate()})});return}t.destroy()}),{wss:F,shutdown:async()=>{if(!H){H=!0;for(let e of L.values())clearTimeout(e);L.clear(),B.size>0&&await Promise.allSettled(B)}}}}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`)),g=sanitizeIdentityField(t.searchParams.get(`clientName`)),S=sanitizeIdentityField(t.searchParams.get(`colorSeed`));return s===null||g===null||S===null?null:{displayName:s,clientName:g,colorSeed:S}}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:g}=await import(`./chokidar-CblsKfnx.mjs`),S=dirname(e);try{tracedMkdirSync(S,{recursive:!0})}catch(e){e.code!==`EEXIST`&&s.warn({err:e,watchDir:S},`failed to create watch directory; watcher may be inert`)}let w=g(S,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:t=>t!==S&&t!==e});await new Promise(e=>{w.once(`ready`,e)});let E=null;try{E=readFileSync(e,`utf-8`)}catch{}let D=(g,S=!0)=>{if(g!==e)return;let w;try{w=readFileSync(g,`utf-8`)}catch(e){if(e.code===`ENOENT`){S&&s.debug({path:g},`config file disappeared between event and read; dropping`);return}s.warn({err:e,path:g},`config file read failed; dropping event`);return}if(w!==E){E=w;try{t(w)}catch(e){s.warn({err:e,path:g},`config file change handler threw`)}}},O=e=>D(e);w.on(`add`,O),w.on(`change`,O),w.on(`unlink`,t=>{t===e&&s.debug({path:t},`config file unlinked; Y.Text retained at current state`)}),w.on(`error`,t=>{s.warn({err:t,watchDir:S,absPath:e},`[config-file-watcher] chokidar error while watching ${e}`)});let k=0,j=setInterval(()=>{k++,D(e,!1),k>=20&&clearInterval(j)},500);j.unref?.();let F=!1;return async()=>{F||(F=!0,clearInterval(j),await w.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:g}=await import(`./chokidar-CblsKfnx.mjs`),S=new Set(e),w=Array.from(new Set(Array.from(S,e=>dirname(e))));for(let e of w)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 E=g(w,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:e=>!S.has(e)&&!w.includes(e)});await new Promise(e=>{E.once(`ready`,e)});let D=new Map;for(let e of S)try{D.set(e,readFileSync(e,`utf-8`))}catch{D.set(e,null)}let O=(e,g=!0)=>{if(!S.has(e))return;let w;try{w=readFileSync(e,`utf-8`)}catch(t){if(t.code===`ENOENT`){g&&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(w!==D.get(e)){D.set(e,w);try{t(e,w)}catch(t){s.warn({err:t,path:e},`config file change handler threw`)}}},k=e=>O(e);E.on(`add`,k),E.on(`change`,k),E.on(`unlink`,e=>{S.has(e)&&s.debug({path:e},`config file unlinked; downstream state retained`)}),E.on(`error`,e=>{s.warn({err:e,watchDirs:w,paths:Array.from(S)},`[config-file-watcher] chokidar error in multi-path watcher`)});let j=0,F=setInterval(()=>{j++;for(let e of S)O(e,!1);j>=20&&clearInterval(F)},500);F.unref?.();let L=!1;return async()=>{L||(L=!0,clearInterval(F),await E.close())}}function entryMatchesDocName(e,t,s,g){let S=relative(g,join(s,e.file));return S.startsWith(`..`)?!1:stripDocExtension(S)===t}function createConflictLifecycleSeedExtension(e){let{getSyncEngine:t,projectDir:s,contentDir:g}=e;return{async afterLoadDocument({documentName:e,document:S}){if(!(isSystemDoc(e)||isConfigDoc(e)))try{let w=t();if(!w)return;let E=w.getConflicts();if(E.length===0||!E.some(t=>entryMatchesDocName(t,e,s,g)))return;let D=S.getMap(`lifecycle`);if(D.get(`status`)===`conflict`)return;D.set(`status`,`conflict`),D.set(`reason`,`conflict-markers`),console.warn(JSON.stringify({event:`lifecycle-seeded-on-load-from-conflict-store`,"doc.name":e}))}catch(t){console.warn(`[conflict-lifecycle-seed] failed to seed lifecycle on load (doc=${e}):`,t instanceof Error?t:String(t))}}}}const execFileAsync$1=promisify(execFile),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`]),ALWAYS_SKIP_DIRS=new Set([`.git`,`node_modules`,`.ok`,`.open-knowledge`,`.openknowledge`]);function pathHasAlwaysSkipSegment(e){for(let t of e.split(`/`))if(ALWAYS_SKIP_DIRS.has(t))return!0;return!1}const IGNORE_FILE_NAMES=[`.gitignore`,`.okignore`];function loadGitExcludeSources(e,t){let s=readGitCommonDirSync(e);if(s===null)return[];let g=[];appendExcludeFileIfExists(join(s,`info`,`exclude`),t,g,`info/exclude`);let S=resolveGlobalExcludesfileSync(e);return S&&appendExcludeFileIfExists(S,t,g,`global excludesfile`),g}async function loadGitExcludeSourcesAsync(e,t){let s=await readGitCommonDirAsync(e);if(s===null)return[];let g=[];await appendExcludeFileIfExistsAsync(join(s,`info`,`exclude`),t,g,`info/exclude`);let S=await resolveGlobalExcludesfileAsync(e);return S&&await appendExcludeFileIfExistsAsync(S,t,g,`global excludesfile`),g}function readGitCommonDirSync(e){let t=spawnSync(`git`,[`rev-parse`,`--git-common-dir`],{cwd:e,encoding:`utf-8`,timeout:5e3});return t.status!==0||!t.stdout?null:resolve(e,t.stdout.trim())}async function readGitCommonDirAsync(e){try{let{stdout:t}=await execFileAsync$1(`git`,[`rev-parse`,`--git-common-dir`],{cwd:e,encoding:`utf-8`,timeout:5e3});return t?resolve(e,t.trim()):null}catch{return null}}function resolveGlobalExcludesfileSync(e){let t=spawnSync(`git`,[`config`,`--get`,`--type=path`,`core.excludesfile`],{cwd:e,encoding:`utf-8`,timeout:5e3});if(t.status===0&&t.stdout){let e=t.stdout.trim();if(e)return e}return xdgGlobalIgnoreDefault()}async function resolveGlobalExcludesfileAsync(e){try{let{stdout:t}=await execFileAsync$1(`git`,[`config`,`--get`,`--type=path`,`core.excludesfile`],{cwd:e,encoding:`utf-8`,timeout:5e3}),s=t.trim();if(s)return s}catch{}return xdgGlobalIgnoreDefault()}function xdgGlobalIgnoreDefault(){let e=process.env.XDG_CONFIG_HOME?.trim();return join(e&&e.length>0?e:join(homedir(),`.config`),`git`,`ignore`)}function appendExcludeFileIfExists(e,t,s,g){if(existsSync(e))try{let g=readFileSync(e,`utf-8`);t.value+=g.length,s.push(...parseIgnorePatterns(g))}catch(t){console.warn(`[content-filter] Failed to read ${g} at ${e}:`,t)}}async function appendExcludeFileIfExistsAsync(e,t,s,g){if(existsSync(e))try{let g=await readFile$1(e,`utf-8`);t.value+=g.length,s.push(...parseIgnorePatterns(g))}catch(t){console.warn(`[content-filter] Failed to read ${g} at ${e}:`,t)}}function createContentFilter(e){let{projectDir:t,contentDir:s,onAfterRebuild:g}=e,S=relative(t,s),w=S.startsWith(`..`),E,D,O,k=0,j=0,F=0;function L(){let e=(0,import_ignore.default)();e.add(`.git`);let g=[],L=0,B=0;for(let s of IGNORE_FILE_NAMES){let S=join(t,s);if(existsSync(S))try{let t=readFileSync(S,`utf-8`);L+=t.length;let s=parseIgnorePatterns(t);g.push(...s),e.add(s)}catch(e){console.warn(`[content-filter] Failed to read ${s} at ${S}:`,e)}}if(S&&!w)for(let t of IGNORE_FILE_NAMES){let g=join(s,t);if(existsSync(g))try{let t=readFileSync(g,`utf-8`);L+=t.length,B++;let s=parseIgnorePatterns(t).map(e=>prefixPattern(e,S));e.add(s)}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${g}:`,e)}}let H={value:L};B+=loadNestedIgnoreFiles(s,t,e,H),L=H.value;let q=loadGitExcludeSources(t,H);L=H.value,q.length>0&&(g.push(...q),e.add(q));let J=g.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`));return E=e,D=g,O=J,k=g.length,j=B,F=L,{patternCount:k,nestedFileCount:j,bytes:F}}L();let B=new Map;function H(e){if(w)return!1;let t=S?`${S}/${e}`:e;return E.ignores(t)}populateDirCount(s,``,H,B);function q(e){let t=stripDocExtension(e);return isSystemDoc(t)||isConfigDoc(t)}function J(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return w?!1:H(e)}return{isExcluded(e,t){if(q(e)||pathHasAlwaysSkipSegment(e))return!0;if(t?.bypassFilters)return!1;if(J(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((B.get(s)??0)>0)return!1}return!0},isDirExcluded(e,t){if(pathHasAlwaysSkipSegment(e))return!0;if(t?.bypassFilters)return!1;for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;if(w)return!1;let s=S?`${S}/${e}`:e;return E.ignores(s)||E.ignores(`${s}/`)},isPathIgnored(e,t){return q(e)||pathHasAlwaysSkipSegment(e)?!0:t?.bypassFilters?!1:J(e)},getWatcherIgnoreGlobs(){return O},incrementMdDir(e){let t=e===`.`?``:e;B.set(t,(B.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,s=B.get(t)??0;s<=1?B.delete(t):B.set(t,s-1)},rebuildDirCount(){let e=new Map(B);B.clear();try{populateDirCount(s,``,H,B)}catch(t){for(let[t,s]of e)B.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=E,S=D,w=O,q=k,J=j,Y=F,ee=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async te=>{try{let t=L();B.clear(),populateDirCount(s,``,H,B);let S=Date.now()-ee;if(te.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:S},`content-filter rebuild succeeded`),g)try{g()}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:S}}catch(g){E=t,D=S,O=w,k=q,j=J,F=Y,B.clear();try{populateDirCount(s,``,H,B)}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 L=g instanceof Error?g.message:String(g);return e.warn({err:g instanceof Error?g:Error(L)},`content-filter rebuild failed — rolled back to previous state`),{ok:!1,error:{message:L}}}})}}}function populateDirCount(e,t,s,g){let S;try{S=readdirSync(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory for dir-count: ${e}`,t);return}for(let w of S){let S=t?`${t}/${w.name}`:w.name;if(w.isDirectory()){if(BUILTIN_SKIP_DIRS.has(w.name)||s(S)||s(`${S}/`))continue;populateDirCount(join(e,w.name),S,s,g)}else w.isFile()&&isSupportedDocFile(w.name)&&!s(S)&&g.set(t,(g.get(t)??0)+1)}}function parseIgnorePatterns(e){return e.split(`
|
|
3069
|
+
`).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,g){let S;try{S=readdirSync(e,{withFileTypes:!0})}catch(t){return console.warn(`[content-filter] Failed to read directory ${e}:`,t),0}let w=0;for(let E of S){if(!E.isDirectory()||BUILTIN_SKIP_DIRS.has(E.name))continue;let S=join(e,E.name),D=relative(t,S);if(!D.startsWith(`..`)&&!(s.ignores(D)||s.ignores(`${D}/`))){for(let e of IGNORE_FILE_NAMES){let t=join(S,e);if(existsSync(t))try{let e=readFileSync(t,`utf-8`);g.value+=e.length;let S=parseIgnorePatterns(e).map(e=>prefixPattern(e,D));s.add(S),w++}catch(s){console.warn(`[content-filter] Failed to read nested ${e} at ${t}:`,s)}}w+=loadNestedIgnoreFiles(S,t,s,g)}}return w}async function initContentDirStateAsync(e,t,s,g,S,w,E){let D;try{D=await readdir(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory ${e}:`,t);return}for(let O of D){let D=t?`${t}/${O.name}`:O.name;if(O.isDirectory()){if(BUILTIN_SKIP_DIRS.has(O.name))continue;let t=join(e,O.name);if(!w){let e=relative(s,t);if(e.startsWith(`..`)||g.ignores(e)||g.ignores(`${e}/`))continue;for(let s of IGNORE_FILE_NAMES){let S=join(t,s);if(existsSync(S))try{let t=parseIgnorePatterns(await readFile$1(S,`utf-8`));g.add(t.map(t=>prefixPattern(t,e)))}catch(e){console.warn(`[content-filter] Failed to read nested ${s} at ${S}:`,e)}}}await initContentDirStateAsync(t,D,s,g,S,w,E)}else if(O.isFile()&&isSupportedDocFile(O.name)){if(!w){let e=S?`${S}/${D}`:D;if(g.ignores(e))continue}E.set(t,(E.get(t)??0)+1)}}}async function createContentFilterAsync(e){let{projectDir:t,contentDir:s,onAfterRebuild:g}=e,S=relative(t,s),w=S.startsWith(`..`),E=(0,import_ignore.default)(),D=[],O=new Map;function k(e){if(w)return!1;let t=S?`${S}/${e}`:e;return E.ignores(t)}function j(e){let t=stripDocExtension(e);return isSystemDoc(t)||isConfigDoc(t)}function F(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return w?!1:k(e)}async function L(){let e=(0,import_ignore.default)();e.add(`.git`);let g=[];for(let s of IGNORE_FILE_NAMES){let S=join(t,s);if(existsSync(S))try{let t=parseIgnorePatterns(await readFile$1(S,`utf-8`));g.push(...t),e.add(t)}catch(e){console.warn(`[content-filter] Failed to read ${s} at ${S}:`,e)}}if(S&&!w)for(let t of IGNORE_FILE_NAMES){let g=join(s,t);if(existsSync(g))try{let t=parseIgnorePatterns(await readFile$1(g,`utf-8`));e.add(t.map(e=>prefixPattern(e,S)))}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${g}:`,e)}}let k=await loadGitExcludeSourcesAsync(t,{value:0});k.length>0&&(g.push(...k),e.add(k));let j=new Map;await initContentDirStateAsync(s,``,t,e,S,w,j),E=e,D=g.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`)),O.clear();for(let[e,t]of j)O.set(e,t)}return await L(),{isExcluded(e,t){if(j(e)||pathHasAlwaysSkipSegment(e))return!0;if(t?.bypassFilters)return!1;if(F(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((O.get(s)??0)>0)return!1}return!0},isDirExcluded(e,t){if(pathHasAlwaysSkipSegment(e))return!0;if(t?.bypassFilters)return!1;for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;if(w)return!1;let s=S?`${S}/${e}`:e;return E.ignores(s)||E.ignores(`${s}/`)},isPathIgnored(e,t){return j(e)||pathHasAlwaysSkipSegment(e)?!0:t?.bypassFilters?!1:F(e)},getWatcherIgnoreGlobs(){return D},incrementMdDir(e){let t=e===`.`?``:e;O.set(t,(O.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,s=O.get(t)??0;s<=1?O.delete(t):O.set(t,s-1)},rebuildDirCount(){let e=new Map(O);O.clear();try{populateDirCount(s,``,k,O)}catch(t){for(let[t,s]of e)O.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=E,s=D,S=new Map(O),w=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async k=>{try{await L();let t=Date.now()-w;if(k.setAttributes({"ok.ignore.pattern_count":D.length,"ok.ignore.nested_file_count":0,"ok.ignore.bytes":0}),e.info({durationMs:t},`content-filter async rebuild succeeded`),g)try{g()}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:D.length,nestedFileCount:0,bytes:0,durationMs:t}}catch(g){E=t,D=s,O.clear();for(let[e,t]of S)O.set(e,t);let w=g instanceof Error?g.message:String(g);return e.warn({err:g instanceof Error?g:Error(w)},`content-filter async rebuild failed — rolled back`),{ok:!1,error:{message:w}}}})}}}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`),g=t.slice(5),S=s.split(`
|
|
3070
3070
|
`).find(e=>e.endsWith(` ${g}`));if(S)return S.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 g=resolveGitDir(e);if(!g)return{unsubscribe:async()=>{},getLastKnownBranch:()=>null};let S=g,w=!1,E=null,D=null,O=null,k=null;async function j(e){if(L&&await L,!w)return;E&&=(clearTimeout(E),null),D&&=(clearTimeout(D),null);let t=readHeadSha(S),g=O!==t,j=readBranchFromHead(S),F;F=j?.startsWith(`detached-`)?`detached-head`:k===j?`within-branch`:`cross-branch`;let B=k;try{await s({headMoved:g,oldHead:O,newHead:t,timeout:e,batchKind:F,oldBranch:B,newBranch:j})}catch(e){console.error(`[head-watcher] onBatchEnd callback failed:`,e)}finally{w=!1,O=t,k=j}}function F(){E&&clearTimeout(E),E=setTimeout(()=>{E=null,j(!1)},QUIET_WINDOW_MS)}let L=null;async function B(e){if(!w){w=!0,O=readHeadSha(S);let s=(async()=>{try{await t({trigger:e})}catch(e){console.error(`[head-watcher] onBatchBegin callback failed:`,e)}})();L=s,await s,L=null,D=setTimeout(()=>{D=null,j(!0)},BATCH_TIMEOUT_MS)}F()}let H,q;try{q=await import(`@parcel/watcher`)}catch(e){throw Error(`@parcel/watcher unavailable for HEAD watching: ${e instanceof Error?e.message:e}`)}try{let e=await q.subscribe(S,(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)){B(t);break}}});H=()=>e.unsubscribe()}catch(e){throw Error(`@parcel/watcher subscribe failed for HEAD watching: ${e instanceof Error?e.message:e}`)}return O=readHeadSha(S),k=readBranchFromHead(S),getLogger(`head-watcher`).info({gitDir:S},`watching for HEAD changes`),{unsubscribe:async()=>{w&&await j(!1),E&&clearTimeout(E),D&&clearTimeout(D),await H()},getLastKnownBranch:()=>k}}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:g,debounceMs:S=100}=e,w=new Map;function E(e){let t=w.get(e);t&&(clearTimeout(t),w.delete(e))}function D(e,D){E(e),w.set(e,setTimeout(()=>{w.delete(e);try{let S=serializeLiveDocument(D);t.updateDocumentFromMarkdown(e,S),g?.(`backlinks`),g?.(`graph`),s&&(s.updateDocumentFromMarkdown(e,S),g?.(`tags`))}catch(t){console.error(`[live-derived-index] Failed to update derived views for ${e}:`,t)}},S))}return{async onChange({documentName:e,document:t,transactionOrigin:s}){isSystemDoc(e)||isConfigDoc(e)||isLocalOriginLike(s)&&s.context?.origin===`file-watcher`||D(e,t)},async beforeUnloadDocument({documentName:e}){E(e)},async onDestroy(){for(let e of w.values())clearTimeout(e);w.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:g,email:S}=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()}`,w=typeof e.created_at==`string`?e.created_at:new Date().toISOString(),E=t.slice(10,18),D={id:t,display_name:g?sanitizeGitIdentity(g):typeof e.display_name==`string`?e.display_name:`Local User`,display_email:S?sanitizeGitIdentity(S):typeof e.display_email==`string`?e.display_email:`principal-${E}@openknowledge.local`,source:g||S?`git-config`:`synthesized`,created_at:w};return writeFileSync(s,JSON.stringify(D,null,2),`utf-8`),D}mkdirSync(t,{recursive:!0});let w=`principal-${randomUUID()}`,E=w.slice(10,18),D={id:w,display_name:g?sanitizeGitIdentity(g):`Local User`,display_email:S?sanitizeGitIdentity(S):`principal-${E}@openknowledge.local`,source:g||S?`git-config`:`synthesized`,created_at:new Date().toISOString()};return writeFileSync(s,JSON.stringify(D,null,2),`utf-8`),D}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 g=new Set([e]),S=s.newDocName;for(;;){if(g.has(S)){incrementRemovalRedirectChainCycle(),console.warn(JSON.stringify({event:`removal-redirect-chain-cycle`,documentName:e,target:S}));return}g.add(S);let s=t.recentlyRemovedDocs.get(S);if(s===void 0)throw incrementAuthRenameRedirect(),setActiveSpanAttributes({"auth.reason":`rename-redirect`}),new HocuspocusAuthRejection(`rename-redirect`,`removed-doc redirect for ${e} → ${S}`,S);if(s.kind===`deleted`)throw fileExistsForDocName(t,S)?(t.recentlyRemovedDocs.delete(S),incrementAuthRenameRedirect(),setActiveSpanAttributes({"auth.reason":`rename-redirect`}),new HocuspocusAuthRejection(`rename-redirect`,`removed-doc redirect for ${e} → ${S}`,S)):(incrementAuthDocDeleted(),setActiveSpanAttributes({"auth.reason":`doc-deleted`}),new HocuspocusAuthRejection(`doc-deleted`,`removed-doc rejection for deleted ${e}`));S=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:g,document:S}){if(isSystemDoc(g)||isConfigDoc(g)||t.has(g))return;let w=S,E=w.getXmlFragment(`default`),D=w.getText(`source`),O=()=>{try{let s=setupServerObservers({doc:w,xmlFragment:E,ytext:D,mdManager:e.mdManager,schema:e.schema,docName:g,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(g,s),!0}catch(e){return console.error(`[ServerObserverExtension] Failed to attach observers for '${g}':`,e),incrementServerObserverError(`a`),incrementServerObserverError(`b`),!1}};if(!O()){let e=setTimeout(()=>{s.delete(g),!t.has(g)&&(console.warn(`[ServerObserverExtension] Retrying observer attachment for '${g}'`),O())},5e3);s.set(g,e)}},async afterUnloadDocument({documentName:e}){let g=s.get(e);g&&(clearTimeout(g),s.delete(e));let S=t.get(e);S&&(S(),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 g;try{g=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(g))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:g}}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,g=e.currentRuntimeVersion??RUNTIME_VERSION,S=e.currentProtocolVersion??1,w=(e.now??(()=>new Date))().toISOString(),E=manifestPath(e.lockDir),D=readStateManifest(e.lockDir);if(D.status===`present`){let O=D.manifest;if(!isCompatibleSchema(O.stateSchemaVersion,s))throw new StateManifestError({kind:`incompatible`,path:E,message:`State manifest at ${E} declares stateSchemaVersion=${O.stateSchemaVersion} but this binary supports ${s}. Refusing to boot — on-the-fly migration is out of scope. (Manifest written by runtime ${O.createdBy.runtimeVersion}, protocol ${O.createdBy.protocolVersion}.)`});try{let t={...O,lastWriteBy:{runtimeVersion:g,protocolVersion:S,at:w}};return writeStateManifest(e.lockDir,t),t}catch(e){return t.warn({err:e},`[state-manifest] failed to update lastWriteBy — proceeding`),O}}if(detectProjectShape({lockDir:e.lockDir,shadowRepoDir:e.shadowRepoDir})===`fresh`){let D={stateSchemaVersion:s,createdAt:w,createdBy:{runtimeVersion:g,protocolVersion:S}};return writeStateManifest(e.lockDir,D),t.info({path:E,stateSchemaVersion:s},`[state-manifest] fresh project — wrote manifest`),D}let O={stateSchemaVersion:0,createdAt:w,createdBy:{runtimeVersion:g,protocolVersion:S,adoptedAt:w}};return writeStateManifest(e.lockDir,O),t.warn({path:E,runtimeVersion:g},`[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.`),O}function deriveUserFacingCode(e,t){return e===`auth`&&t===`403`?`auth-403`:e===`auth`&&t===`401`?`auth-401`:e===`auth`&&t===`scope-mismatch`?`auth-scope-mismatch`:e===`semantic`&&t===`protected-branch`?`semantic-protected-branch`:null}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=classifyGitErrorBase(e);return{...t,userFacingCode:deriveUserFacingCode(t.class,t.subclass)}}function classifyGitErrorBase(e){let t=e instanceof Error?e:Error(String(e)),s=extractStderr(t),g=`${t.message}\n${s}`.toLowerCase();return matchesAny(g,INDEX_LOCK_PATTERNS)?{class:`local`,subclass:`index-lock`,retryable:!0,message:`Git index locked by another process`,rawStderr:s}:matchesAny(g,DIRTY_TREE_PATTERNS)?{class:`local`,subclass:`dirty-tree`,retryable:!0,message:`Working tree has uncommitted changes`,rawStderr:s}:matchesAny(g,DISK_FULL_PATTERNS)?{class:`local`,subclass:`disk-full`,retryable:!0,message:`Disk full or quota exceeded`,rawStderr:s}:matchesAny(g,SCOPE_MISMATCH_PATTERNS)?{class:`auth`,subclass:`scope-mismatch`,retryable:!1,message:`GitHub token missing required scopes`,rawStderr:s}:matchesAny(g,AUTH_PATTERNS)?/\b401\b/.test(g)||/token.*expired/i.test(g)?{class:`auth`,subclass:`401`,retryable:!1,message:`Authentication failed — token may be expired`,rawStderr:s}:/\b403\b/.test(g)?matchesAny(g,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(g,PROTECTED_BRANCH_PATTERNS)?{class:`semantic`,subclass:`protected-branch`,retryable:!1,message:`Push rejected — branch is protected`,rawStderr:s}:matchesAny(g,NON_FAST_FORWARD_PATTERNS)?{class:`semantic`,subclass:`non-fast-forward`,retryable:!1,message:`Push rejected — remote has diverged (non-fast-forward)`,rawStderr:s}:matchesAny(g,MERGE_CONFLICT_PATTERNS)?{class:`semantic`,subclass:`merge-conflict`,retryable:!1,message:`Merge conflict — manual resolution required`,rawStderr:s}:matchesAny(g,LFS_PATTERNS)?{class:`structural`,subclass:`lfs-quota`,retryable:!1,message:`Git LFS quota exceeded`,rawStderr:s}:matchesAny(g,LARGE_FILE_PATTERNS)?{class:`structural`,subclass:`large-file`,retryable:!1,message:`File exceeds size limit`,rawStderr:s}:matchesAny(g,SECRET_DETECTED_PATTERNS)?{class:`structural`,subclass:`secret-detected`,retryable:!1,message:`Push blocked — secret or credential detected in content`,rawStderr:s}:matchesAny(g,PRE_RECEIVE_PATTERNS)?{class:`structural`,subclass:`pre-receive-hook`,retryable:!1,message:`Push rejected by server pre-receive hook`,rawStderr:s}:matchesAny(g,HTTP_429_PATTERNS)?{class:`network`,subclass:`429`,retryable:!0,message:`Rate limited — too many requests`,rawStderr:s}:matchesAny(g,HTTP_5XX_PATTERNS)?{class:`network`,subclass:`5xx`,retryable:!0,message:`Server error (5xx)`,rawStderr:s}:matchesAny(g,NETWORK_PATTERNS)?/timed? out/i.test(g)?{class:`network`,subclass:`timeout`,retryable:!0,message:`Connection timed out`,rawStderr:s}:/refused/i.test(g)||/econnrefused/i.test(g)?{class:`network`,subclass:`connection-refused`,retryable:!0,message:`Connection refused`,rawStderr:s}:/resolve.*host/i.test(g)||/enotfound/i.test(g)||/getaddrinfo/i.test(g)?{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}}const log$2=getLogger(`github-permissions`),PROBE_TIMEOUT_MS=5e3;function githubApiBase(e){return e===`github.com`?`https://api.github.com`:`https://${e}/api/v3`}function buildHeaders(e){let t={"User-Agent":`open-knowledge-server`,Accept:`application/vnd.github+json`};return e&&(t.Authorization=`Bearer ${e}`),t}function readPushFlag(e){if(typeof e!=`object`||!e)return null;let t=e.permissions;if(typeof t!=`object`||!t)return null;let s=t.push;return typeof s==`boolean`?s:null}async function classify(e,t){switch(e.status){case 200:{let t;try{t=await e.json()}catch(e){return log$2.warn({err:e},`[permissions] probe got 200 with unparseable JSON body`),{kind:`unknown`,error:`malformed-response`}}let s=readPushFlag(t);return s===null?(log$2.warn({bodyKeys:typeof t==`object`&&t?Object.keys(t):[]},`[permissions] probe got 200 without permissions.push field`),{kind:`unknown`,error:`malformed-response`}):s?{kind:`allowed`}:{kind:`denied`,reason:`no-collaborator`}}case 401:return{kind:`unknown`,error:`token-invalid`};case 403:return e.headers.get(`x-ratelimit-remaining`)===`0`?{kind:`unknown`,error:`rate-limit`}:{kind:`unknown`,error:`token-invalid`};case 429:return{kind:`unknown`,error:`rate-limit`};case 404:return t?{kind:`denied`,reason:`private-no-access`}:{kind:`denied`,reason:`repo-not-found`};default:return log$2.warn({httpStatus:e.status},`[permissions] probe got unexpected HTTP status`),{kind:`unknown`,error:`malformed-response`}}}async function resolveProbeTokenWithSource(e,t,s){let g=t(e);if(g.available&&g.token)return{token:g.token,source:`gh`};if(s)try{let t=await s.get(e);if(t?.token)return{token:t.token,source:`token-store`}}catch(t){log$2.warn({err:t,host:e},`[permissions] tokenStore.get threw; falling through to anonymous`)}return{token:void 0,source:`anonymous`}}async function runProbe(e){let{owner:t,repo:s,host:g=`github.com`,detectGh:S=()=>({available:!1}),tokenStore:w,_fetchFn:E=fetch,_timeoutMs:D=PROBE_TIMEOUT_MS}=e,{token:O,source:k}=await resolveProbeTokenWithSource(g,S,w),j=`${githubApiBase(g)}/repos/${encodeURIComponent(t)}/${encodeURIComponent(s)}`;log$2.info({host:g,tokenSource:k,tokenLen:O===void 0?0:O.length},`[permissions] probe starting`);let F=new AbortController,L=setTimeout(()=>F.abort(),D);try{let e=await E(j,{signal:F.signal,headers:buildHeaders(O)}),t=await classify(e,O!==void 0);return log$2.info({host:g,tokenSource:k,httpStatus:e.status,kind:t.kind,reason:t.kind===`denied`?t.reason:void 0,error:t.kind===`unknown`?t.error:void 0},`[permissions] probe classified`),t}catch(e){return F.signal.aborted?(log$2.warn({host:g,timeoutMs:D},`[permissions] probe timed out`),{kind:`unknown`,error:`timeout`}):(log$2.warn({err:e,host:g},`[permissions] probe failed`),{kind:`unknown`,error:`network`})}finally{clearTimeout(L)}}async function checkPushPermission(e){let t=performance.now(),s=await runProbe(e);return recordProbeTelemetry(s,performance.now()-t),s}function outcomeAttributes(e){return{outcome:e.kind,denied_reason:e.kind===`denied`?e.reason:`none`,error_class:e.kind===`unknown`?e.error:`none`}}let _outcomeCounter=null;function outcomeCounter(){return _outcomeCounter||=getMeter().createCounter(`ok.permissions.probe.outcome_total`,{description:`Push-permission probe outcomes. Bounded labels: outcome ∈ {allowed,denied,unknown}; denied_reason ∈ {no-collaborator,private-no-access,repo-not-found,none}; error_class ∈ {network,timeout,rate-limit,token-invalid,malformed-response,none}.`}),_outcomeCounter}let _durationHist=null;function durationHist(){return _durationHist||=getMeter().createHistogram(`ok.permissions.probe.duration_ms`,{description:`Push-permission probe wall-clock duration.`,unit:`ms`}),_durationHist}function recordProbeTelemetry(e,t){let s=outcomeAttributes(e);outcomeCounter().add(1,s),durationHist().record(t,{outcome:s.outcome})}function computeRemainingMs(e,t,s=Date.now()){if(!e)return 0;let g=new Date(e).getTime();if(Number.isNaN(g))return 0;let S=g+t*1e3;return Math.max(0,S-s)}const log$1=getLogger(`sync-engine`),SHA_HEX_40=/^[0-9a-f]{40}$/i;function pushPermissionStatusFrom(e){return e.kind===`allowed`?{checkStatus:`allowed`}:e.kind===`denied`?{checkStatus:`denied`,deniedReason:e.reason}:{checkStatus:`unknown`,unknownError:e.error}}function pushPermissionStatusEqual(e,t){return e===t?!0:e===null||t===null||e.checkStatus!==t.checkStatus?!1:e.checkStatus===`denied`&&t.checkStatus===`denied`?e.deniedReason===t.deniedReason:e.checkStatus===`unknown`&&t.checkStatus===`unknown`?e.unknownError===t.unknownError:!0}function 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(),g=/^ref:\s+(refs\/.+)$/.exec(s);if(!g)return!1;let S=g[1];if(existsSync(join(e,`.git`,S)))return!1;let w=join(e,`.git`,`packed-refs`);if(existsSync(w)){let e=readFileSync(w,`utf-8`);if(RegExp(`^[0-9a-f]+\\s+${S}$`,`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;onContentConflictsDetected;setBatchInProgress;onAutoDisable;detectGh;tokenStore;checkPushPermissionFn;pushPermission=null;pushPermissionProbeInFlight=!1;pullTimer=null;pushTimer=null;stateSaveTimer=null;lastSyncUtc=null;lastFetchUtc=null;lastPushedSha=null;consecutiveFailures=0;ahead=0;behind=0;conflictCount=0;error;errorCode;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.onContentConflictsDetected=e.onContentConflictsDetected,this.setBatchInProgress=e.setBatchInProgress,this.onAutoDisable=e.onAutoDisable,this.detectGh=e.detectGh,this.tokenStore=e.tokenStore,this.checkPushPermissionFn=e.checkPushPermissionFn??checkPushPermission,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$1.warn({err:e},`[sync] remote detection failed`)}if(e&&this.probePushPermissionInternal(`start`),this.syncEnabled!==!0){e&&this.transitionTo(`disabled`),log$1.info({hasRemote:e,syncEnabled:this.syncEnabled},`[sync] sync not enabled — staying inactive`);return}if(!e){log$1.info({},`[sync] no remote detected — staying dormant`);return}this.transitionTo(`idle`);let t=resolveGitDir(this.projectDir),s=t?join(t,`MERGE_HEAD`):null,g=s!==null&&existsSync(s);if(this.conflictCount>0&&!g)log$1.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&&g)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(`
|
|
3071
3071
|
`).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$1.info({cleared:s-this.conflictCount,remaining:this.conflictCount},`[sync] reconciled conflicts.json against git unmerged index`)}catch(e){log$1.warn({err:e},`[sync] failed to reconcile conflicts with git index`)}if(g&&this.conflictCount===0){log$1.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$1.warn({err:e},`[sync] git merge --abort for stale MERGE_HEAD failed`)}}if(this.conflictCount>0){await this.notifyContentConflictsDetected(this.conflictStore.list().map(e=>e.file)),this.transitionTo(`conflict`),log$1.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$1.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$1.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.errorCode=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.errorCode=void 0,this.consecutiveFailures=0,!this.hasRemote){this.transitionTo(`dormant`),this.saveStateNow();return}this.transitionTo(`idle`),this.schedulePull(0),this.schedulePush(),this.saveStateNow(),this.probePushPermissionInternal(`refresh`)}}async trigger(e=`sync`){this.consecutiveFailures=0,(this.pausedReason===`dirty-tree`||this.pausedReason===`external-changes-pending`||this.pausedReason===`non-content-merge-failure`)&&(this.pausedReason=void 0,this.error=void 0,this.errorCode=void 0),this.probePushPermissionInternal(`refresh`),this.state===`dormant`||this.state===`disabled`||this.state===`conflict`||this.state===`auth-error`?log$1.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$1.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,remote:this.hasRemote?readSyncRemoteInfo(this.projectDir):null,error:this.error,...this.errorCode===void 0?{}:{errorCode:this.errorCode},pausedReason:this.pausedReason,...this.pushPermission===null?{}:{pushPermission:this.pushPermission}}}async refreshPushPermission(){return this.probePushPermissionInternal(`refresh`)}async refreshIdentity(){let e=await resolveGitIdentity(this.projectDir)===null;this.identityUnresolved!==e&&(this.identityUnresolved=e,this.cc1Broadcaster?.signal(`sync-status`))}async probePushPermissionInternal(e){if(!this.hasRemote||this.pushPermissionProbeInFlight)return null;let t=readOriginGitHubRepo(this.projectDir);if(t.kind!==`ok`){let e={checkStatus:`unknown`},t=this.pushPermission;return this.pushPermission=e,pushPermissionStatusEqual(t,e)||this.cc1Broadcaster?.signal(`sync-status`),e}this.pushPermissionProbeInFlight=!0,log$1.info({caller:e,host:`github.com`,hasDetectGh:this.detectGh!==void 0,hasTokenStore:this.tokenStore!==void 0&&this.tokenStore!==null},`[sync] push-permission probe dispatching`);let s;try{s=await this.checkPushPermissionFn({owner:t.owner,repo:t.repo,host:`github.com`,detectGh:this.detectGh,tokenStore:this.tokenStore})}catch(t){log$1.warn({err:t,caller:e},`[sync] push-permission probe threw — recording unknown/network`),s={kind:`unknown`,error:`network`}}finally{this.pushPermissionProbeInFlight=!1}let g=pushPermissionStatusFrom(s),S=this.pushPermission;this.pushPermission=g;let w=!1;return g.checkStatus===`denied`&&this.syncEnabled===!0?(this.pausedReason!==`no-push-permission`||this.state!==`disabled`)&&(this.pausedReason=`no-push-permission`,this.transitionTo(`disabled`),w=!0,log$1.info({reason:g.deniedReason,caller:e},`[sync] paused — no push permission on origin`)):g.checkStatus===`allowed`&&this.pausedReason===`no-push-permission`&&(this.pausedReason=void 0,this.state===`disabled`&&this.syncEnabled===!0&&this.transitionTo(`idle`),w=!0,log$1.info({caller:e,priorState:this.state},`[sync] push permission restored`)),!w&&!pushPermissionStatusEqual(S,g)&&this.cc1Broadcaster?.signal(`sync-status`),g}async refreshRemote(){this.hasRemote||await this.probeRemote()&&(this.hasRemote=!0,log$1.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$1.warn({err:e},`[sync] remote detection failed`),!1}}getConflicts(){return this.conflictStore.list()}async reconcileConflictsFromGit(){if(this.conflictCount===0)return;let e=this.conflictCount,t=resolveGitDir(this.projectDir),s=t?join(t,`MERGE_HEAD`):null;if(!(s!==null&&existsSync(s)))log$1.info({cleared:e},`[sync] external resolve detected (no MERGE_HEAD) — clearing tracked conflicts`),this.conflictStore.clear(),this.conflictCount=0;else try{let t=(await createGitInstance(this.projectDir,{credentialArgs:this.credentialArgs}).git.raw([`diff`,`--name-only`,`--diff-filter=U`])).trim(),s=new Set(t?t.split(`
|
|
3072
3072
|
`).map(e=>e.trim()).filter(Boolean):[]);for(let e of this.conflictStore.list())s.has(e.file)||this.conflictStore.removeConflict(e.file);this.conflictCount=this.conflictStore.count(),this.conflictCount<e&&log$1.info({cleared:e-this.conflictCount,remaining:this.conflictCount},`[sync] external resolve detected (mid-merge) — pruned resolved entries`)}catch(e){log$1.warn({err:e},`[sync] reconcileConflictsFromGit: git probe failed`);return}this.conflictCount!==e&&(this.conflictCount===0&&this.state===`conflict`?(this.transitionTo(`idle`),this.pausedReason=void 0,this.schedulePull(),this.schedulePush()):this.cc1Broadcaster?.signal(`sync-status`),this.scheduleSaveState())}async resolveConflict(e,t,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.cc1Broadcaster?.signal(`sync-status`),this.scheduleSaveState()}finally{this.setBatchInProgress?.(!1)}}updateCurrentBranch(e){e===null?this.state!==`dormant`&&this.state!==`disabled`&&(this.transitionTo(`disabled`),this.pausedReason=`detached-head`,this.scheduleSaveState()):this.currentBranch!==e&&(this.currentBranch=e,this.conflictStore.setBranch(e),this.state===`disabled`&&this.pausedReason===`detached-head`&&(this.pausedReason=void 0,this.transitionTo(`idle`),this.schedulePull(),this.schedulePush()))}schedulePull(e){this.pullTimer!==null&&clearTimeout(this.pullTimer);let t=e??this.effectivePullDelayMs();this.pullTimer=setTimeout(()=>{this.pullTimer=null,this.runPullCycle().catch(e=>{log$1.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$1.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$1.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,this.errorCode=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{await this.commitDirtyContentFilesToHead(e);let s=await this.prepareForMerge(e,t);if(!s.proceed)return;try{await e.git.merge([`origin/${t}`]),this.lastSyncUtc=new Date().toISOString(),this.behind=0,this.transitionTo(`idle`)}finally{s.needsStashPop&&await this.popPreMergeStash(e)}}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`),g=null;this.transitionTo(`pushing`);try{await withParentLock(async()=>{let e=createGitInstance(this.projectDir,{credentialArgs:this.credentialArgs,gitIndexFile:s});if(isUnbornHead(this.projectDir)){log$1.info({},`[sync] repo has no commits yet — skipping push cycle`),this.transitionTo(`idle`);return}let S;try{S=(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$1.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`,S]);let w=await this.listHeadContentPaths(e,S);if(t.length>0){let s=100;for(let s=0;s<t.length;s+=100){let g=t.slice(s,s+100).map(e=>e.projectRelPath);await e.git.raw([`add`,`--`,...g])}}let E=new Set(t.map(e=>e.projectRelPath)),D=[...w].filter(e=>!E.has(e));await this.removePathsFromIndex(e,D);let O=(await e.git.raw([`write-tree`])).trim(),k=``;try{k=(await e.git.raw([`rev-parse`,`${S}^{tree}`])).trim()}catch{}if(k&&k===O){let s=null;try{s=(await e.git.raw([`rev-parse`,`origin/${this.currentBranch}`])).trim()}catch{}if(s===S){log$1.info({contentFileCount:t.length,headSha:S},`[sync] push cycle: nothing to commit (tree unchanged, origin matches HEAD)`),this.lastPushedSha=S,this.lastSyncUtc=new Date().toISOString(),this.transitionTo(`idle`);return}log$1.info({headSha:S,upstreamSha:s},`[sync] push cycle: tree unchanged but local ahead of origin — pushing existing commits`);let w=!1;try{await e.git.raw([`rev-parse`,`--abbrev-ref`,`${this.currentBranch}@{u}`]),w=!0}catch{}w?await e.git.raw([`push`,`origin`,this.currentBranch]):await e.git.raw([`push`,`--set-upstream`,`origin`,this.currentBranch]),g=S;return}let j=[],F=[];try{let s=(await e.git.raw([`diff-tree`,`--name-only`,`-r`,S,O])).trim();if(s){let e=new Map(t.map(e=>[e.projectRelPath,e.contentRelPath]));for(let t of s.split(`
|
|
@@ -3081,4 +3081,4 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
3081
3081
|
`),s=[],g=!1,S=``;for(let e of t){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(t){g?RegExp(`^\\s{0,3}${S[0]==="`"?"`":`~`}{${S.length},}\\s*$`).test(e)&&(g=!1,S=``):(g=!0,S=t[1]);continue}if(g)continue;let w=stripInlineCodeSpans(e);for(TAG_VALUE_RE.lastIndex=0;;){let e=TAG_VALUE_RE.exec(w);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:g}=stripFrontmatter(t),S=extractFrontmatterTags(s?unwrapFrontmatterFences(s):``),w=extractInlineTagsFromBody(g),E=new Set([...S,...w]),D=new Set;for(let e of E)for(let t of expandTagToHierarchy(e))D.add(t);this.applyDocSnapshot(e,E,D)}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 g of t){let t=this.state.byDocLiteral.get(g);if(!t)continue;let S=tagsMatchingPrefix(t,e);s.push({docName:g,matchingTags:[...S].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 g=t;for(;g>0;)s.add(e.slice(0,g)),g=e.indexOf(`/`,g+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 g=this.state.byDoc.get(e)??new Set;for(let t of g){if(s.has(t))continue;let g=this.state.byTag.get(t);g&&(g.delete(e),g.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 g of s){let s=join(e,g.name);if(g.isDirectory()){let e=relative(this.contentDir,s);if(this.contentFilter&&e&&this.contentFilter.isDirExcluded(e))continue;this.walkContentDir(s,t);continue}if(!g.isFile()||!isSupportedDocFile(g.name))continue;let S=relative(this.contentDir,s);this.contentFilter?.isExcluded(S)||t.push({docName:stripDocExtension(S),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:g=!0,debounce:S=2e3,maxDebounce:w=1e4,gitEnabled:E=!0,commitDebounceMs:D=3e4,wipRef:O=`refs/wip/main`,configHomedirOverride:k,enableTestRoutes:j=!1,shadowRepo:F,contentRoot:L,destroyTimeoutMs:B=1e4,localOpCliArgs:H,skipStateManifestCheck:q=!1}=e,J=getLogger(`server`);function Y(){let e=readConfigSafely({absPath:resolveConfigPath(`project-local`,s),sideline:!1,warn:e=>J.warn({message:e},`[config] could not read project-local config`)}),t=e.value.autoSync?.enabled;return t==null?(e.valid||J.warn({},`[config] project-local autoSync.enabled unavailable (config invalid) — falling back to project config`),readConfigSafely({absPath:resolveConfigPath(`project`,s),sideline:!1,warn:e=>J.warn({message:e},`[config] could not read project config`)}).value.autoSync?.enabled===!0):t===!0}initTelemetry();let ee=randomUUID(),te=getLocalDir(s);if(acquireServerLock(te,{port:e.port??0,worktreeRoot:s,kind:e.lockKind??`interactive`,capabilities:[`http`,`ws`]}),!q)try{assertCompatibleStateManifest({lockDir:te,shadowRepoDir:resolveShadowDir(s)})}catch(e){throw releaseServerLock(te),e}let ne=createBasenameIndex(),ae=(e,t)=>ne.resolveEmbed(e,t),oe=(e,s)=>{let g=ne.resolveEmbed(e,s);if(!g&&e.includes(`/`)&&(g=e.replace(/^\.?\//,``)),!g)return null;let S=resolve(t,g),w=resolve(t);if(S!==w&&!S.startsWith(`${w}/`))return null;try{let e=statSync(S);return e.isFile()?e.size:null}catch{return null}},se,ce,ue,de,fe,me,ge,_e=null,ve=null,ye=null,Ce=null,we=null,Te=new Set,De=!1,je,Me,Pe,Ie=new Promise((e,t)=>{Me=e,Pe=t});function Re(e){_e?.signal(e)}let ze=2e3,Be=null;function Ve(){Be!==null&&clearTimeout(Be),Be=setTimeout(()=>{Be=null,ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist debounced cache:`,e)})},2e3)}let Ue=new RecentlyRemovedDocs(void 0,{onEviction:()=>incrementRecentlyRemovedDocsEviction(),onSizeChange:e=>setRecentlyRemovedDocsSize(e)}),We=(e,t)=>{isSystemDoc(e)||isConfigDoc(e)||Ue.setRenamed(e,t)},Ge=e=>{if(!(isSystemDoc(e)||isConfigDoc(e))){if(Ue.peek(e)?.kind===`renamed`){console.info(JSON.stringify({event:`recently-removed-docs-unpaired-delete-suppressed`,docName:e,source:`watcher-delete`}));return}Ue.setDeleted(e)}},Ke=e=>{isSystemDoc(e)||isConfigDoc(e)||Ue.delete(e)};try{se=createContentFilter({projectDir:s,contentDir:t,onAfterRebuild:()=>{ce.rebuildFromDisk(getActiveBranch()).catch(e=>{getLogger(`server-factory`).warn({err:e},`[content-filter] backlink-index rebuild failed after onAfterRebuild`)});try{ue.init()}catch(e){getLogger(`server-factory`).warn({err:e},`[content-filter] tag-index rebuild failed after onAfterRebuild`)}try{let{prunedFiles:e,prunedFolders:t}=reconcileFileIndexAfterFilterRebuild(Lt),s=e+t;s>0?getLogger(`server-factory`).info({pruned:s,prunedFiles:e,prunedFolders:t},`[content-filter] reconciled file indexes after onAfterRebuild`):getLogger(`server-factory`).debug({prunedFiles:e,prunedFolders:t},`[content-filter] file index reconcile completed after onAfterRebuild (no entries pruned; rescan may have added entries)`)}catch(e){getLogger(`server-factory`).warn({err:e},`[content-filter] file index reconcile failed after onAfterRebuild`)}}}),ce=new BacklinkIndex({projectDir:s,contentDir:t,contentFilter:se}),ue=new TagIndex({contentDir:t,contentFilter:se});try{ue.init()}catch(e){console.warn(`[server-factory] tag-index init failed; continuing with empty index:`,e)}de={current:F},fe=createPersistenceExtension({contentDir:t,projectDir:s,gitEnabled:E,commitDebounceMs:D,wipRef:O,shadowRef:de,contentRoot:L,backlinkIndex:ce,configHomedirOverride:k,getCurrentBranch:()=>Rt?.getLastKnownBranch()??null,resolveEmbed:ae,resolveSize:oe,getPrincipal:()=>we,onAgentCommit:()=>_e?.signal(`session-activity`),onDiskFlush:(e,t,s,g)=>{_e?.emitDiskAck(e,t),!(isSystemDoc(e)||isConfigDoc(e))&&assetReferencesChanged(g,s)&&(Ce?.(),Re(`files`))},onConfigRejected:(e,t)=>_e?.emitConfigValidationRejected(e,t),mdManager:e.mdManager}),me=new Hocuspocus({quiet:g,debounce:S,maxDebounce:w,extensions:[fe.extension]});let B=me.shouldUnloadDocument.bind(me);me.shouldUnloadDocument=e=>{if(Te.has(e)||De&&B(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:B(e)},je=async e=>{Te.add(e);try{await me.unloadDocument(e)}finally{Te.delete(e)}},_e=new CC1Broadcaster(me),ve=new AgentFocusBroadcaster(me),ye=new AgentPresenceBroadcaster(me),ge=new AgentSessionManager(me);let q=createLiveDerivedIndexExtension({backlinkIndex:ce,tagIndex:ue,signalChannel:Re});me.configuration.extensions.push(q),me.configuration.extensions.push({__kind:`principal-auth`,async onAuthenticate(e){let t=e.token,s=parseHocuspocusAuthToken(t),g=s?.expectedServerInstanceId;if(typeof g==`string`&&g.length>0&&g!==ee)throw new HocuspocusAuthRejection(`server-instance-mismatch`,`server instance mismatch: client claimed ${g}, this server is ${ee}`);let S=s?.expectedBranch,w=getActiveBranch();if(typeof S==`string`&&S.length>0&&S!==w)throw new HocuspocusAuthRejection(`branch-mismatch`,`branch mismatch: client claimed ${S}, server is on ${w}`);if(!s)return;let E=e.context;typeof s.principalId==`string`&&(we&&s.principalId===we.id?E.principalId=we.id:we?console.warn(JSON.stringify({event:`principal-token-mismatch`,claimed:s.principalId,loaded:we.id})):E.principalId=s.principalId),typeof s.tabSessionId==`string`&&(E.tabSessionId=s.tabSessionId),E.kind=`human`}}),me.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 g=e.requestHeaders,S=(g&&typeof g.get==`function`?g.get(`host`):null)??t.headers?.host??void 0;if(!isAllowedWorkspaceHostHeader(S))throw Error(`config-doc admission requires loopback Host header (host=${S??`<absent>`}, doc=${e.documentName})`)}});let J=resolve(t);function Y(e){if(!isSafeDocName(e))return null;let t=resolve(J,`${e}${getDocExtension(e)}`);return!t.startsWith(`${J}/`)&&t!==J?null:t}me.configuration.extensions.push({__kind:`removal-redirect-guard`,async onAuthenticate(e){await runRemovalRedirectGuard(e.documentName,{recentlyRemovedDocs:Ue,resolveFilePath:Y,fileExists:existsSync})}}),me.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 te=createApiExtension({hocuspocus:me,sessionManager:ge,contentDir:t,contentFilter:se,serverInstanceId:ee,getFileIndex:()=>Lt?Lt.getFileIndex():new Map,getFolderIndex:()=>Lt?Lt.getFolderIndex():new Map,getAliasMap:()=>Lt?Lt.getAliasMap():new Map,rescanFiles:()=>Lt?.rescanFromDisk(),enableTestRoutes:j,shadowRef:de,flushGitCommit:()=>fe.flushPendingGitCommit(),flushContributors:()=>fe.flushContributors(),getCurrentBranch:()=>Rt?.getLastKnownBranch()??null,getDiskAckSVs:()=>_e?.getLatestDiskAckSVsAsBase64()??{},contentRoot:L,backlinkIndex:ce,tagIndex:ue,signalChannel:Re,agentFocusBroadcaster:ve,agentPresenceBroadcaster:ye,onAgentWrite:e.onAgentWrite,getSyncEngine:()=>zt,localOpCliArgs:H,projectDir:s,resolveEmbed:ae,getPrincipal:()=>we,forceUnloadDocument:je,ready:Ie,recentlyRemovedDocs:Ue,serializeDoc:it,onReferencedAssetsCacheInvalidator:e=>{Ce=e}});me.configuration.extensions.push(te),me.configuration.extensions.push(createServerObserverExtension({mdManager,schema,shadowRef:de,contentRoot:L,getCurrentBranch:()=>Rt?.getLastKnownBranch()??null,resolveEmbed:ae,resolveSize:oe})),me.configuration.extensions.push(createSyncHandshakeSpanExtension()),me.configuration.extensions.push(createConflictLifecycleSeedExtension({getSyncEngine:()=>zt,projectDir:s,contentDir:t}))}catch(e){throw releaseServerLock(te),e}let Xe=null,$e=new Map,nt=[];function rt(e,t){let s=resolve(e,`rescue`),g=resolve(s,`${t}${getDocExtension(t)}`);return g.startsWith(`${s}/`)?g:null}function it(e){let t=me.documents.get(e);if(!t)return null;let{frontmatter:s,body:g}=stripFrontmatter(t.getText(`source`).toString());return prependFrontmatter(s,g)}let at=(e,t)=>applyExternalChange(me,e,t,ae,oe);function st(e){if(!isDocInConflict(e))return;let t=e.getMap(`lifecycle`);t.delete(`status`),t.delete(`reason`)}let vt=e=>{if(!e)return;let t=`[[${e}]]`;for(let[s]of me.documents){if(isSystemDoc(s)||isConfigDoc(s))continue;let g=me.documents.get(s);if(!g)continue;let S=g.getText(`source`).toString();if(S.includes(t))try{g.transact(()=>{applyDiskContentToDoc(g,S,ae,s)},FILE_WATCHER_ORIGIN)}catch(t){J.error({err:t,docName:s,assetBasename:e},`[asset-event] failed to re-render ${s} for asset basename ${e}`)}}},Tt=null,Et=e=>{e&&(Tt===null&&(Tt=new Set,setImmediate(()=>{let e=Tt;if(Tt=null,e)try{for(let t of e)vt(t)}catch(t){J.error({err:t,basenames:[...e]},`[asset-event] dedup rerender pass crashed`)}})),Tt.add(e))};function Dt(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 jt(e){try{switch(e.kind){case`create`:J.info({docName:e.docName},`[reconcile] create: ${e.docName}`),ce.updateDocumentFromMarkdown(e.docName,e.content),Ve(),ue.updateDocumentFromMarkdown(e.docName,e.content),Re(`files`),Re(`backlinks`),Re(`graph`),Re(`tags`),Ke(e.docName);break;case`update`:{let{docName:t,content:s}=e,g=me.documents.get(t);if(!g){ce.updateDocumentFromMarkdown(t,s),Ve(),ue.updateDocumentFromMarkdown(t,s),Re(`backlinks`),Re(`graph`),Re(`tags`);return}let S=getReconciledBase(t)??``,w=it(t)??S,E=reconcile({docName:t,base:S,ours:w,theirs:s}),D=contentHash(S).slice(0,6),O=contentHash(w).slice(0,6),k=contentHash(s).slice(0,6);switch(J.info({docName:t,base:D,ours:O,theirs:k,result:E.kind},`[reconcile] ${t} base=${D} ours=${O} theirs=${k} result=${E.kind}`),E.kind){case`noop`:st(g),ce.updateDocumentFromMarkdown(t,s),Ve(),ue.updateDocumentFromMarkdown(t,s),Re(`backlinks`),Re(`graph`),Re(`tags`);break;case`clean`:try{at(t,E.newContent),setReconciledBase(t,E.newContent),incrementReconcile(),st(g),ce.updateDocumentFromMarkdown(t,s),Ve(),ue.updateDocumentFromMarkdown(t,s),Re(`backlinks`),Re(`graph`),Re(`tags`)}catch(e){J.error({err:e,docName:t},`[reconcile] failed to apply clean content to Y.Doc for ${t}`),setReconciledBase(t,s),st(g)}break;case`merged`:try{at(t,E.newContent),setReconciledBase(t,E.newContent),incrementReconcile(),st(g),ce.updateDocumentFromMarkdown(t,s),Ve(),ue.updateDocumentFromMarkdown(t,s),Re(`backlinks`),Re(`graph`),Re(`tags`)}catch(e){J.error({err:e,docName:t},`[reconcile] failed to apply merged content to Y.Doc for ${t}`),setReconciledBase(t,s),st(g)}break;case`conflicts`:try{at(t,E.newContent),setReconciledBase(t,E.newContent),incrementReconcile(),incrementConflict(),ce.updateDocumentFromMarkdown(t,s),Ve(),ue.updateDocumentFromMarkdown(t,s),Re(`backlinks`),Re(`graph`),Re(`tags`)}catch(e){J.error({err:e,docName:t},`[reconcile] failed to apply conflict content to Y.Doc for ${t}`),setReconciledBase(t,s)}{let e=g.getMap(`lifecycle`);e.set(`status`,`conflict`),e.set(`reason`,`merged-with-markers`)}break;case`refused`:{incrementConflict();let e=g.getMap(`lifecycle`);e.set(`status`,`conflict`),e.set(`reason`,E.reason);break}}break}case`delete`:{let{docName:t}=e,s=me.documents.get(t);if(!s){ce.deleteDocument(t),Ve(),ue.deleteDocument(t),Re(`files`),Re(`backlinks`),Re(`graph`),Re(`tags`),Ge(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));return}let g=getReconciledBase(t)??``,S=it(t)??``,w=S!==g;if(w&&de.current){let e=de.current,s=Rt?.getLastKnownBranch()??`main`;queueMicrotask(()=>{saveInMemoryCheckpoint(e,L??``,{kind:`external-change-rescue`,docName:t,contents:S,label:`External change recovered @ ${new Date().toISOString()}`,branch:s,metadata:{incomingDiskSha:``}}).then(()=>{incrementRescueBuffer(),J.info({docName:t},`[reconcile] rescue checkpoint saved (delete): ${t}`)}).catch(e=>{J.error({docName:t,err:e},`[reconcile] rescue checkpoint write failed: ${t}`)})})}s.getMap(`lifecycle`).set(`status`,`deleted-upstream`),deleteReconciledBase(t),ce.deleteDocument(t),Ve(),ue.deleteDocument(t),J.info({docName:t,isDirty:w},`[reconcile] delete: ${t} (dirty=${w})`),me.closeConnections(t),await je(s),Re(`files`),Re(`backlinks`),Re(`graph`),Re(`tags`),Ge(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:g}=e,S=me.documents.get(t);if(deleteReconciledBase(t),setReconciledBase(s,g),ce.renameDocument(t,s,g),Ve(),ue.renameDocument(t,s,g),S){let e=S.getMap(`lifecycle`);e.set(`status`,`renamed`),e.set(`newPath`,s)}J.info({oldDocName:t,newDocName:s},`[reconcile] rename: ${t} → ${s}`),Re(`files`),Re(`backlinks`),Re(`graph`),Re(`tags`),We(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=me.documents.get(t);if(!s)return;let g=it(t);g===null?J.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,g);let S=s.getMap(`lifecycle`);S.set(`status`,`conflict`),S.set(`reason`,`conflict-markers`),J.info({docName:t},`[reconcile] conflict markers detected: ${t}`);break}case`asset-create`:ne.add(e.relativePath),Re(`files`),Et(basename(e.relativePath));break;case`asset-delete`:ne.remove(e.relativePath),Re(`files`),Et(basename(e.relativePath));break;case`folder-create`:case`folder-delete`:Re(`files`);break;default:assertNeverDiskEvent(e)}}catch(t){let s=Dt(e);J.error({err:t,kind:e.kind,label:s},`[reconcile] failed to handle ${e.kind} for ${s}`)}}let Mt=[];async function Ft(e){if(isBatchInProgress()){Mt.push(e);return}await jt(e)}async function It(){let e=Mt.splice(0,Mt.length);for(let t of e)await jt(t)}let Lt=null,Rt=null,zt=null,Bt=null;async function Vt(e){if(me.documents.size===0)return;let t=!1,s=new Promise(e=>{me.configuration.extensions.push({async afterUnloadDocument({instance:s}){!t&&s.getDocumentsCount()===0&&(t=!0,e())}})}),g=Array.from(me.documents.keys());me.closeConnections(),me.flushPendingStores();for(let e of me.documents.values())e.getConnectionsCount()===0&&me.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 S,w=new Promise((s,w)=>{S=setTimeout(()=>{t=!0;let s=Array.from(me.documents.keys()),S=[],E=[];if(de.current){for(let e of s)if(!(isSystemDoc(e)||isConfigDoc(e)))try{let t=it(e);if(t===null){J.warn({docName:e},`[rescue] skipping ${e} — document dropped from map mid-rescue`),E.push(e);continue}let s=rt(de.current.gitDir,e);if(!s){J.warn({docName:e,gitDir:de.current.gitDir},`[rescue] path-traversal guard rejected docName: ${e}`),E.push(e);continue}mkdirSync(dirname(s),{recursive:!0}),writeFileSync(s,t,`utf-8`),incrementRescueBuffer(),S.push(e),J.info({docName:e},`[rescue] rescue buffer saved on flush timeout: ${e}`)}catch(t){E.push(e),J.error({err:t,docName:e},`[rescue] failed to write rescue buffer for ${e}`)}}else J.warn({stillLoadedCount:s.length},`[rescue] shadow repo unavailable at flush timeout — ${s.length} doc(s) will be lost: [${s.join(`, `)}]`),E.push(...s);let D=S.length>0||E.length>0?` — rescued [${S.join(`, `)}]${E.length>0?`, lost [${E.join(`, `)}]`:``}`:``;w(Error(`flushAllStoresAndWait timeout after ${e}ms — ${s.length}/${g.length} docs did not unload: [${s.join(`, `)}]${D}`))},e)});try{await Promise.race([s,w])}finally{S!==void 0&&clearTimeout(S)}}async function Ht(){return Bt||(Bt=(async()=>{let e=Date.now(),t=[];De=!0,Be!==null&&(clearTimeout(Be),Be=null);let g,S=await Promise.race([Ie.then(()=>`completed`,e=>(J.debug({err:e},`[server] init incomplete during shutdown`),`failed`)),new Promise(e=>{g=setTimeout(()=>e(`timeout`),5e3)})]);g!==void 0&&clearTimeout(g),S===`timeout`&&J.warn({},`[server] init did not complete within 5s during shutdown`);let w=me.documents.size;try{try{try{Rt&&=(await Rt.unsubscribe(),null),Lt&&=(await Lt.unsubscribe(),null);for(let{docName:e,cleanup:t}of nt)try{await t()}catch(t){J.warn({err:t,docName:e},`[server] failed to stop config-file-watcher for ${e}`)}nt.length=0}catch(e){t.push({phase:`watcher-unsubscribe`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-1 watcher unsubscribe failed`)}try{_e?.destroy(),ye?.destroy(),Xe&&=(await Xe.disconnect(),null);for(let[e,t]of $e)try{await t.disconnect()}catch(t){J.warn({err:t,docName:e},`[server] failed to disconnect ${e} during shutdown`)}$e.clear()}catch(e){t.push({phase:`cc1-teardown`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-1b CC1 teardown failed`)}try{await ge.closeAll()}catch(e){t.push({phase:`agent-session-drain`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-2 agent session drain failed`)}try{await Vt(B)}catch(e){t.push({phase:`flush-all-stores`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-3 flush failed`)}let e;try{await Promise.race([(async()=>{await fe.flushPendingGitCommit(),await fe.waitForPendingCommits()})(),new Promise((t,s)=>{e=setTimeout(()=>s(Error(`L2 git flush timeout`)),B)})])}catch(e){t.push({phase:`git-commit-flush`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-4 git commit flush failed`)}finally{e!==void 0&&clearTimeout(e)}try{zt&&=(await zt.destroy(),null)}catch(e){t.push({phase:`sync-engine-stop`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown sync-engine-stop failed`)}}finally{if(de.current){try{let e=(await esm_default({baseDir:s,timeout:{block:5e3}}).revparse(`HEAD`)).trim();e&&writeFileSync(resolve(de.current.gitDir,`last-known-head`),e,`utf-8`)}catch{}try{destroyShadowRepo(de.current)}catch(e){t.push({phase:`shadow-repo-release`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-5 destroyShadowRepo failed`)}}let g=Date.now()-e;t.length===0?J.info({documentCount:w,durationMs:g},`[server] shutdown flushed ${w} documents in ${g}ms`):J.warn({documentCount:w,durationMs:g,phaseErrors:t},`[server] shutdown flushed ${w} documents in ${g}ms with ${t.length} phase error(s)`)}}finally{try{releaseServerLock(te)}catch(e){t.push({phase:`server-lock-release`,error:e instanceof Error?e.message:String(e)}),J.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)})}}})(),Bt)}let Ut=[];async function Wt(){try{we=await loadPrincipal(s),J.info({principalId:we.id},`[server] principal loaded`)}catch(e){J.warn({err:e},`[server] principal load failed — browser writes will use SERVICE_WRITER`)}if(!de.current)try{de.current=await initShadowRepo(s),J.info({gitDir:de.current.gitDir},`[server] history repo initialized at ${de.current.gitDir}`)}catch(e){J.error({err:e},`[server] history repo init failed`),Ut.push(`shadow-repo`)}if(de.current){let e=null;try{e=loadRenameLogIndex(de.current.gitDir),sweepLazyPopOrphans(de.current.gitDir,e),setRenameLogIndex(de.current.gitDir,e),J.info({entries:e.byTo.size},`[server] rename log loaded (${e.byTo.size} entries)`)}catch(e){J.warn({err:e},`[rename-log] boot-time load/sweep failed; rename history unavailable`)}if(e){let t=1e4;try{await Promise.race([gcRenameLog(de.current,e,{rebuild:!0}),new Promise((e,s)=>setTimeout(()=>s(Error(`boot-time GC exceeded ${t}ms`)),t))])}catch(e){J.warn({err:e},`[rename-log] boot-time GC/rebuild failed; index loaded without GC`)}}}if(de.current)try{await shadowGit(de.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`)){J.warn({},`[server] history repo appears corrupted — reinitializing`);try{de.current=await initShadowRepo(s)}catch(e){J.error({err:e},`[server] history repo reinit failed`),de.current=void 0,Ut.includes(`shadow-repo`)||Ut.push(`shadow-repo`)}}else J.error({err:e},`[server] history repo check failed (transient?)`)}if(de.current)try{let e=resolve(de.current.gitDir,`last-known-head`),t=null;try{t=readFileSync(e,`utf-8`).trim()||null}catch{}let g=null;try{g=(await esm_default({baseDir:s,timeout:{block:1e4}}).revparse(`HEAD`)).trim()||null}catch{}if(g!==null){if(g!==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{}J.info({lastKnownHead:t,currentHead:g,branch:e},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${g}, action=import`);try{await commitUpstreamImport(de.current,L??``,t,g,e),incrementUpstreamImport()}catch(e){J.warn({err:e},`[head-drift] commitUpstreamImport failed — continuing`)}}else J.info({currentHead:g},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${g}, action=noop`);try{writeFileSync(e,g,`utf-8`)}catch(e){J.warn({err:e},`[head-drift] failed to write last-known-head`)}}}catch(e){J.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;J.warn({journalVersion:e.journal.version,fromPath:t,toPath:s,restoredDocNames:e.restoredDocNames},`[managed-rename] recovered pending rename ${t} -> ${s}`)}}catch(e){J.error({err:e},`[server] managed rename recovery failed`),Ut.push(`managed-rename-recovery`)}try{let e=cleanupOrphanUploadTempfiles(s);(e.deleted>0||e.errors>0)&&J.info({scanned:e.scanned,deleted:e.deleted,errors:e.errors},`[upload-tempfile-sweep] swept ${e.deleted} orphan tempfile(s)`)}catch(e){J.error({err:e},`[server] upload-tempfile sweep failed`),Ut.push(`upload-tempfile-sweep`)}try{Xe=await me.openDirectConnection(SYSTEM_DOC_NAME),_e?.emitServerInfo(ee,getActiveBranch())}catch(e){J.error({err:e},`[server] failed to open __system__ direct connection — CC1 push disabled`),Ut.push(`cc1-push`)}for(let e of CONFIG_DOC_NAMES)try{let t=await me.openDirectConnection(e);$e.set(e,t)}catch(t){J.error({err:t,docName:e},`[server] failed to open ${e} direct connection — config bind degraded`),Ut.push(`config-doc:${e}`)}let g=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,k)]]);for(let e of CONFIG_DOC_NAMES){let t=g.get(e);if(t)try{J.info({docName:e,path:t},`[config-file-watcher] starting`);let s=await startConfigFileWatcher(t,t=>{let s=me.documents.get(e);J.info({docName:e,hasDocument:s!==void 0,contentLength:t.length},`[config-file-watcher] file changed`);let g=applyExternalConfigChange(s??null,e,t,fe.configPersistenceCtx);if(J.info({docName:e,outcome:g},`[config-file-watcher] applyExternalConfigChange outcome`),e===`__config__/project`||e===`__local__/project`){let e=Y();zt?.setEnabled(e).catch(t=>{J.warn({err:t,enabled:e},`[sync] failed to apply autoSync.enabled from config`)})}});nt.push({docName:e,cleanup:s}),J.info({docName:e,path:t},`[config-file-watcher] started`)}catch(s){J.warn({err:s,docName:e,path:t},`[config-file-watcher] failed to start for ${e}`),Ut.push(`config-file-watcher:${e}`)}}try{let e=resolve(t,`.okignore`),g=resolve(s,`.gitignore`),S=null;try{let e=spawnSync(`git`,[`rev-parse`,`--git-common-dir`],{cwd:s,encoding:`utf-8`,timeout:5e3});if(e.status===0&&e.stdout){let t=join(resolve(s,e.stdout.trim()),`info`,`exclude`);existsSync(dirname(t))&&(S=t)}}catch{}let w=S?[e,g,S]:[e,g],E=J;E.info({okignorePath:e,gitignorePath:g,gitInfoExcludePath:S},`[ignore-watcher] starting multi-path watcher for .okignore + .gitignore (+ .git/info/exclude when present)`);let D=await startMultiPathConfigFileWatcher(w,(t,g)=>{(async()=>{if(t===e)try{let e=applyExternalConfigChange(me.documents.get(`__config__/okignore`)??null,CONFIG_DOC_NAME_OKIGNORE,g,fe.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 S=await se.rebuildIgnorePatterns();if(S.ok)E.info({changedPath:relative(s,t),patternCount:S.patternCount,nestedFileCount:S.nestedFileCount,durationMs:S.durationMs},`[ignore-watcher] rebuild succeeded — broadcasting files channel`),_e?.signal(`files`);else{let e=relative(s,t)||`.`;E.warn({changedPath:e,error:S.error.message},`[ignore-watcher] rebuild failed — emitting config-ignore-nested-error`),_e?.emitConfigIgnoreNestedError(e,S.error.message)}})().catch(e=>{E.error({err:e,changedPath:relative(s,t)||`.`},`[ignore-watcher] handler threw`)})});nt.push({docName:`__ignore-files__`,cleanup:D}),E.info({okignorePath:e,gitignorePath:g},`[ignore-watcher] multi-path watcher started`)}catch(e){J.warn({err:e,projectDir:s,contentDir:t},`[ignore-watcher] failed to start multi-path watcher`),Ut.push(`ignore-files-watcher`)}let S=resolveGitDir(s),w=S?readBranchFromHead(S)??`main`:`main`;switchReconciledBaseScope(w),ce.switchBranch(w);try{{let e=getActiveBranch();try{if(await ce.loadFromDisk(e)){let t=await ce.reconcileWithDisk(e);(t.added>0||t.updated>0||t.deleted>0)&&J.info(t,`[backlinks] startup reconcile: offline changes applied`)}else await ce.rebuildFromDisk(e);ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist startup cache for ${e}:`,t)})}catch(t){J.error({err:t,branch:e},`[backlinks] startup init failed; index will populate incrementally via watcher`)}}Lt=await startWatcher(t,Ft,se),ue.init();let e=0;try{seedBasenameIndex({contentDir:t,contentFilter:se,basenameIndex:ne,onSkip:(t,s,g)=>{e++,J.warn({reason:t,code:s,path:g},`[basename-index] skipped entry during seed (${t}${s?` ${s}`:``})`)}}),e>0&&(J.warn({count:e},`[basename-index] startup seed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve`),Ut.push(`basename-index-partial`))}catch(e){J.error({err:e},`[basename-index] startup seed failed`),Ut.push(`basename-index`)}}catch(e){J.error({err:e},`[server] disk bridge watcher failed to start`),Ut.push(`file-watcher`)}try{Rt=await startHeadWatcher(s,async({trigger:e})=>{if(J.info({trigger:e},`[batch] begin trigger=${e}`),incrementBatch(),me.flushPendingStores(),await fe.flushPendingGitCommit(),setBatchInProgress(!0),de.current){let e=getActiveBranch(),t=resolveGitDir(s),g=t?readBranchFromHead(t)??e:e,S=[];for(let[e,t]of me.documents){if(isSystemDoc(e)||isConfigDoc(e))continue;let s=null;if(t.transact(()=>{s=it(e)},PARK_SNAPSHOT_ORIGIN),s===null)continue;let g=getReconciledBase(e)??s;S.push({docName:e,markdown:s,diskSnapshot:g})}if(S.length>0)try{let t=await parkBranch(de.current,e,SERVICE_WRITER.id,S,g);t&&(incrementPark(),J.info({count:S.length,branch:e,sha:t.slice(0,8)},`[history] parked ${S.length} docs on ${e} → ${t.slice(0,8)}`))}catch(e){J.error({err:e},`[shadow] park failed`)}}},async e=>{let s=Mt.length,g=e.newBranch??`main`;if(J.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`){if(setBatchInProgress(!1),await It(),await fe.flushDeferredStores(`within-branch`),zt!==null)try{await zt.reconcileConflictsFromGit()}catch(e){J.warn({err:e},`[head-watcher] sync engine conflict reconcile failed`)}}else{incrementBranchSwitch(),Mt.splice(0,Mt.length),switchReconciledBaseScope(g),Be!==null&&(clearTimeout(Be),Be=null),ce.switchBranch(g),se.rebuildDirCount();try{let e=0;ne.clear(),seedBasenameIndex({contentDir:t,contentFilter:se,basenameIndex:ne,onSkip:(t,s,S)=>{e++,J.warn({reason:t,code:s,path:S,branch:g},`[basename-index] skipped entry during branch-switch reseed (${t}${s?` ${s}`:``})`)}}),e>0&&(J.warn({count:e,branch:g},`[basename-index] branch-switch reseed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve on this branch`),Ut.includes(`basename-index-partial`)||Ut.push(`basename-index-partial`))}catch(e){J.error({err:e,branch:g},`[basename-index] branch-switch reseed failed`)}for(let[e,s]of me.documents)if(!(isSystemDoc(e)||isConfigDoc(e)))try{let S=safeContentPath(e,t);if(!existsSync(S)){let t=getReconciledBase(e)??``,S=it(e)??``;if(S!==t&&de.current){let t=de.current;queueMicrotask(()=>{saveInMemoryCheckpoint(t,L??``,{kind:`external-change-rescue`,docName:e,contents:S,label:`External change recovered @ ${new Date().toISOString()}`,branch:g,metadata:{incomingDiskSha:``}}).then(()=>{incrementRescueBuffer(),J.info({docName:e},`[reconcile] rescue checkpoint saved on branch switch: ${e}`)}).catch(t=>{J.error({docName:e,err:t},`[reconcile] rescue checkpoint write failed: ${e}`)})})}s.getMap(`lifecycle`).set(`status`,`deleted-upstream`),J.info({docName:e,branch:g},`[branch-switch] tombstone: ${e} (not on ${g})`);continue}let w=readFileSync(S,`utf-8`);at(e,w),setReconciledBase(e,w),J.info({docName:e},`[branch-switch] reset: ${e}`)}catch(t){J.error({err:t,docName:e},`[branch-switch] failed to reset ${e}`)}J.info({branch:g,docCount:me.documents.size},`[branch-switch] loaded branch ${g} (${me.documents.size} docs)`);try{if(await ce.loadFromDisk(g)){let e=await ce.reconcileWithDisk(g);(e.added>0||e.updated>0||e.deleted>0)&&J.info(e,`[backlinks] branch-switch reconcile for ${g}`)}else await ce.rebuildFromDisk(g);ce.saveToDisk(g).catch(e=>{console.warn(`[backlinks] Failed to persist branch cache for ${g}:`,e)})}catch(e){J.error({err:e,branch:g},`[backlinks] branch-switch rebuild failed; backlinks may be stale`)}if(ue.init(),de.current&&e.batchKind===`cross-branch`){let e=0;for(let[t]of me.documents)if(!(isSystemDoc(t)||isConfigDoc(t)))try{let s=await readParkedState(de.current,g,SERVICE_WRITER.id,t);if(!s||s.markdown===s.diskSnapshot)continue;let S=getReconciledBase(t);if(!S)continue;let w=reconcile({docName:t,base:s.diskSnapshot,ours:s.markdown,theirs:S});switch(w.kind){case`merged`:case`clean`:at(t,w.newContent),setReconciledBase(t,w.newContent),e++;break;case`conflicts`:at(t,w.newContent),setReconciledBase(t,w.newContent),incrementConflict(),e++;{let e=me.documents.get(t);if(e){let t=e.getMap(`lifecycle`);t.set(`status`,`conflict`),t.set(`reason`,`merged-with-markers`)}}break;case`noop`:case`refused`:break}}catch(e){J.error({err:e,docName:t},`[branch-switch] restore WIP failed for ${t}`)}e>0&&J.info({count:e,branch:g},`[branch-switch] restored ${e} parked docs on ${g}`)}if(e.oldBranch?.startsWith(`detached-`)&&de.current)try{let t=shadowGit(de.current),s=(await t.raw(`for-each-ref`,`refs/wip/${e.oldBranch}/`,`--format=%(refname)`)).trim();if(s){for(let e of s.split(`
|
|
3082
3082
|
`))e&&await t.raw(`update-ref`,`-d`,e);J.info({context:e.oldBranch},`[branch-switch] cleaned up detached context ${e.oldBranch}`)}}catch(e){J.error({err:e},`[branch-switch] detached cleanup failed`)}setBatchInProgress(!1),await fe.flushDeferredStores(`discard-stale`),_e?.emitBranchSwitched(g)}if(e.headMoved&&e.newHead&&de.current&&s>0){let t=L??`.`;try{let s=await commitUpstreamImport(de.current,t,e.oldHead,e.newHead,g);incrementUpstreamImport(),J.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){J.error({err:e},`[shadow] upstream-import failed`)}}})}catch(e){J.error({err:e},`[server] HEAD watcher failed to start`),Ut.push(`head-watcher`)}function E(e){for(let g of e)try{let e=relative(t,join(s,g));if(e.startsWith(`..`))continue;let S=stripDocExtension(e),w=me.documents.get(S);if(!w)continue;let E=it(S);E===null?J.warn({docName:S,file:g},`[sync] content conflict: serializeDoc returned null; reconciledBase snapshot skipped`):setReconciledBase(S,E);let D=w.getMap(`lifecycle`);D.set(`status`,`conflict`),D.set(`reason`,`sync-merge-conflict`),J.info({docName:S,file:g},`[sync] marked loaded content conflict`)}catch(e){J.warn({err:e,file:g},`[sync] failed to mark loaded content conflict`)}}let D=H?.[0]??`open-knowledge`,O=[`-c`,`credential.helper=!${H&&H.length>1?H.join(` `):D} auth git-credential`];try{zt=new SyncEngine({projectDir:s,contentDir:t,contentFilter:se,contentRoot:L,syncEnabled:Y(),credentialArgs:O,cc1Broadcaster:_e,detectGh:e.detectGh,tokenStore:e.tokenStore,checkPushPermissionFn:e.checkPushPermissionFn,setBatchInProgress:e=>{setBatchInProgress(e),e||fe.flushDeferredStores(`within-branch`).catch(e=>{J.error({err:e},`[persistence] deferred store drain failed after sync batch`)})},onStateChange:e=>{J.info({state:e},`[sync] state → ${e}`)},onContentConflictsDetected:E,onAutoDisable:async e=>{J.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||J.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 zt.start()}catch(e){J.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),zt=null}Re(`files`),Re(`backlinks`),Re(`graph`),Re(`tags`)}return Wt().then(Me,Pe),{hocuspocus:me,sessionManager:ge,cc1Broadcaster:_e,agentFocusBroadcaster:ve,agentPresenceBroadcaster:ye,contentFilter:se,basenameIndex:ne,serverInstanceId:ee,destroy:Ht,ready:Ie,degraded:Ut,lockDir:te,get syncEngine(){return zt}}}const LEGACY_RUNTIME_FILENAMES=[`server.lock`,`ui.lock`,`state.json`,`principal.json`,`sync-state.json`,`conflicts.json`,`last-spawn-error.log`],LEGACY_RUNTIME_DIRNAMES=[`cache`,`tmp`];function findLegacyRuntimeFiles(e){let t=resolve(e,LOCAL_DIR);if(!(()=>{if(!existsSync(t))return!0;try{return readdirSync(t).length===0}catch{return!0}})())return[];let s=[];for(let t of LEGACY_RUNTIME_FILENAMES)existsSync(resolve(e,t))&&s.push(t);for(let t of LEGACY_RUNTIME_DIRNAMES){let g=resolve(e,t);try{existsSync(g)&&statSync(g).isDirectory()&&s.push(`${t}/`)}catch{}}return s}function computeWorktreeAttributes(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return{kind:`main`,gitdir:t.path};case`linked`:return{kind:`linked`,gitdir:t.path};case`malformed-pointer`:return{kind:`linked`,gitdir:null};case`inaccessible`:case`absent`:return{kind:`main`,gitdir:null}}}const DEFAULT_IDLE_THRESHOLD_MS=1800*1e3,DESTROY_STEP_TIMEOUT_MS=5e3;async function bootServer(e){let t=resolveLocalSinkConfig({projectDir:e.projectDir??e.contentDir,contentDir:e.contentDir});if(t){let e=t.telemetry.attributeDenylist,s=[];for(let t of e)s.push(t),s.push(`*.${t}`);loggerFactory.configure({pinoConfig:{fileSink:t.logs,redactPaths:s}})}initTelemetry({localSink:t?.telemetry});let{kind:s,gitdir:g}=computeWorktreeAttributes(e.projectDir??e.contentDir),S={"ok.worktree.kind":s};return g!==null&&(S[`ok.worktree.gitdir`]=normalizeFsPath(g)),withSpan(`ok.boot`,{attributes:S},async()=>bootServerInner(e))}async function bootServerInner(e){let t=e.skipAutoInit??!1,s=e.attachUiSibling??!0,g=e.idleShutdownMs,S=e.log??getLogger(`boot`),w=process.env.OK_LOCK_KIND===`mcp-spawned`||process.env.OK_LOCK_KIND===`interactive`?process.env.OK_LOCK_KIND:void 0,E=e.lockKind??w??`interactive`,{createServer:D}=await import(`node:http`),{updateServerLockPort:O}=await import(`./server-lock-CyhBidkz-Bp84kpW5.mjs`),k=!1;if(!t&&e.autoInitFn)try{k=!!await e.autoInitFn()}catch(e){S.warn({err:e},`autoInitFn failed`)}let j=e.projectDir??e.contentDir,F=resolve(j,`.ok`);if(!existsSync(resolve(F,`config.yml`)))throw new MissingOkConfigError(existsSync(F)?`config`:`okdir`,j);existsSync(resolve(F,`.gitignore`))||console.warn("[boot] Note: .ok/.gitignore is missing — per-machine state files in .ok/ may show up as untracked changes. Run `ok init` to add the recommended ignore entries.");let L=e.gitPreflight??assertGitAvailable;try{L()}catch(e){if(e instanceof GitNotAvailableError||e instanceof GitTooOldError){let t=e instanceof GitTooOldError?e.detected:``,s=e instanceof GitTooOldError?`too_old`:`not_available`;emitPreflightFailureSpan(e),S.warn({event:`git_preflight_fail`,platform:e.platform,reason:s,detectedVersion:t},s===`not_available`?`git binary not found`:`git binary too old`),process.stderr.write(`${e.message}\n`)}throw await shutdownTelemetry(),e}let B=findLegacyRuntimeFiles(F);B.length>0&&console.warn(`[boot] Found legacy runtime files at .ok/${B.join(`, `)}. Delete .ok/ and re-init — these files moved to .ok/${LOCAL_DIR}/.`);let H=createServer$1({contentDir:e.contentDir,projectDir:e.projectDir,contentRoot:e.contentRoot,port:e.port,host:e.host,quiet:e.quiet??!1,debounce:e.debounce,maxDebounce:e.maxDebounce,gitEnabled:e.gitEnabled,commitDebounceMs:e.commitDebounceMs,wipRef:e.wipRef,enableTestRoutes:e.enableTestRoutes,shadowRepo:e.shadowRepo,destroyTimeoutMs:e.destroyTimeoutMs,localOpCliArgs:e.localOpCliArgs,onAgentWrite:e.onAgentWrite,lockKind:E,skipStateManifestCheck:e.skipStateManifestCheck,detectGh:e.detectGh,tokenStore:e.tokenStore}),{hocuspocus:q,destroy:J,ready:Y,degraded:ee,lockDir:te,sessionManager:ne,agentFocusBroadcaster:ae,agentPresenceBroadcaster:oe}=H,se=(()=>{let t=e.host??`localhost`;return t===`0.0.0.0`||t===`::`?`localhost`:t.includes(`:`)&&!t.startsWith(`[`)?`[${t}]`:t})(),ce=e.port??0,ue=createMcpHttpHandler({contentDir:e.contentDir,projectDir:e.projectDir??e.contentDir,config:e.config,getServerUrl:()=>`http://${se}:${ce}`,log:S}),de=D();de.headersTimeout=3e4,de.requestTimeout=6e4;let fe=e.serveContentAssets?createAssetServeMiddleware({contentFilter:H.contentFilter,contentSirv:build_default(e.contentDir,{dev:!0,dotfiles:!1}),inlineExtensions:INLINE_RENDERABLE_EXTENSIONS,assetExtensions:ASSET_EXTENSIONS,blocklistExtensions:EXECUTABLE_BLOCKLIST_EXTENSIONS}):void 0,me=!1;if(e.reactShellDistDir)try{acquireUiLock(te,{port:0,worktreeRoot:e.projectDir??e.contentDir}),me=!0}catch(e){if(e instanceof UiLockCollisionError)S.info({event:`ui-lock-yielded-to-live-holder`,pid:process.pid,existingPid:e.existing.pid,existingPort:e.existing.port,lockDir:te},`ui.lock already held by a live process — yielding (advertisement is fulfilled)`);else throw await J().catch(()=>{}),e}let ge=e.reactShellDistDir?build_default(e.reactShellDistDir,{single:!0,gzip:!0,immutable:!0}):void 0,_e=mountMcpAndApi({httpServer:de,hocuspocus:q,mcpHttpHandler:ue,log:S,sessionManager:ne,agentFocusBroadcaster:ae,agentPresenceBroadcaster:oe,keepaliveGraceMs:e.keepaliveGraceMs,contentAssetMiddleware:fe,reactShellMiddleware:ge}),ve=async()=>{throw Error(`bootServer: destroy() invoked before initialization — boot did not complete`)},ye=null;g!==null&&(ye=attachIdleShutdown({httpServer:de,thresholdMs:g??DEFAULT_IDLE_THRESHOLD_MS,log:S,onShutdown:(e.idleShutdownHandler??(e=>async()=>{await e()}))(async()=>{await ve()})})),await restoreLifecycleFromConflictsJson({hocuspocus:q,projectDir:e.projectDir??e.contentDir,log:S});try{await new Promise((t,s)=>{let g=e=>s(e);de.once(`error`,g),de.listen(e.port,e.host,()=>{de.removeListener(`error`,g),t()})})}catch(e){if(me)try{releaseUiLock(te)}catch(e){S.warn({err:e},`releaseUiLock failed during listen-error cleanup`)}throw await J().catch(()=>{}),e}let Ce=de.address(),we=typeof Ce==`object`&&Ce?Ce.port:e.port??0;if(ce=we,O(te,we),me&&updateUiLockPort(te,we),s&&e.spawnUiSiblingFn)try{await e.spawnUiSiblingFn({lockDir:te,log:S})}catch(e){S.warn({err:e},`spawnUiSiblingFn failed`)}let Te=!1,De=async(e,t)=>{let s;try{await Promise.race([t(),new Promise((t,g)=>{s=setTimeout(()=>{g(Error(`${e} timed out after ${DESTROY_STEP_TIMEOUT_MS}ms`))},DESTROY_STEP_TIMEOUT_MS),s.unref?.()})])}finally{s!==void 0&&clearTimeout(s)}};return ve=async()=>{if(Te)return;Te=!0;let e=[],t=async(t,s)=>{try{await De(t,s)}catch(s){e.push(s),S.warn({err:s,step:t},`bootServer destroy step failed`)}};try{ye?.detach()}catch(t){e.push(t),S.warn({err:t,step:`idleHandle.detach`},`bootServer destroy step failed`)}if(await t(`mount.shutdown`,()=>_e.shutdown()),await t(`mcpHttpHandler.close`,()=>ue.close()),await t(`mount.wss.close`,()=>new Promise((e,t)=>{_e.wss.close(s=>s?t(s):e())})),await t(`httpServer.closeAllConnections`,async()=>{de.closeAllConnections?.()}),await t(`httpServer.close`,()=>new Promise((e,t)=>{de.close(s=>s&&s.code!==`ERR_SERVER_NOT_RUNNING`?t(s):e())})),await t(`destroyHocuspocus`,()=>J()),me&&await t(`releaseUiLock`,async()=>releaseUiLock(te)),await t(`shutdownTelemetry`,()=>shutdownTelemetry()),await t(`flushLogFileSinks`,()=>loggerFactory.flushAllFileSinks()),e.length>0)throw AggregateError(e,`bootServer destroy completed with errors`)},{httpServer:de,destroy:ve,lockDir:te,contentDir:e.contentDir,port:we,ready:Y,degraded:ee,didAutoInit:k,serverInstance:H}}async function restoreLifecycleFromConflictsJson(e){let{hocuspocus:t,projectDir:s,log:g}=e,S,w;try{S=new ConflictStore(s),w=S.list()}catch(e){g.warn({err:e,projectDir:s},`[boot] lifecycle restore: failed to read conflicts.json — skipping`);return}if(w.length===0)return;let E=null;try{let e=resolveGitDir(s),t=e?join(e,`MERGE_HEAD`):null;if(!t||!existsSync(t)){S.clear(),console.warn(JSON.stringify({event:`lifecycle-restore-cleared-stale-conflicts`,reason:`no-merge-head`,count:w.length}));return}let g=(await simpleGit({baseDir:s,timeout:{block:5e3}}).raw([`diff`,`--name-only`,`--diff-filter=U`])).trim();E=new Set(g?g.split(`
|
|
3083
3083
|
`).map(e=>e.trim()).filter(Boolean):[])}catch(e){g.warn({err:e,projectDir:s},`[boot] lifecycle restore: git unmerged probe failed — restoring all entries`)}if(E!==null){let e=0;for(let t of w)E.has(t.file)||(S.removeConflict(t.file),e++);if(e>0&&console.warn(JSON.stringify({event:`lifecycle-restore-pruned-resolved-entries`,pruned:e,remaining:w.length-e})),w=w.filter(e=>E?.has(e.file)),w.length===0)return}for(let e of w){let s=stripDocExtension(e.file),S=null,w=!1;try{S=await t.openDirectConnection(s);let e=S.document;if(!e)continue;let g=e.getMap(`lifecycle`);g.set(`status`,`conflict`),g.set(`reason`,`conflict-markers`),w=!0,console.warn(JSON.stringify({event:`lifecycle-restored-from-conflicts-json`,"doc.name":s}))}catch(e){g.warn({err:e,docName:s},`[boot] lifecycle restore: failed to set lifecycle for doc — skipping`)}finally{if(S)try{await S.disconnect()}catch(e){g.warn({err:e,docName:s,restored:w},`[boot] lifecycle restore: disconnect failed after lifecycle write`)}}}}const ConfigSchema=ConfigSchema$1;function detectClaudeDesktopPresence(e={}){let t=e.home??homedir(),s=e.platformName??process.platform,g=e.env??process.env;return s===`darwin`?existsSync(join(t,`Library`,`Application Support`,`Claude`)):s===`win32`?existsSync(join(g.APPDATA??join(t,`AppData`,`Roaming`),`Claude`)):!1}const OK_LOGS_DIR=join(homedir(),`.ok`,`logs`),MAX_ROTATED_FILES=2,MAX_AGE_DAYS=7,MAX_DIR_SIZE_BYTES=45*1024*1024,REDACT_PATHS=[`authorization`,`password`,`token`,`apiKey`,`secret`,`*.authorization`,`*.password`,`*.token`,`*.apiKey`,`*.secret`];function resolveLogLevel(){let e=process.env.OK_LOG_LEVEL??process.env.LOG_LEVEL;if(e){let t=[`fatal`,`error`,`warn`,`info`,`debug`],s=e.toLowerCase();if(t.includes(s))return s}return process.env.NODE_ENV===`test`?`silent`:`info`}function ensureDir(e){mkdirSync(e,{recursive:!0})}function todayDateString(){return new Date().toISOString().slice(0,10)}function rotateIfNeeded(e){try{if(statSync(e).size<5242880)return}catch{return}for(let t=MAX_ROTATED_FILES;t>=1;t--){let s=t===1?e:`${e}.${t-1}`,g=`${e}.${t}`;try{renameSync(s,g)}catch{}}try{unlinkSync(`${e}.${MAX_ROTATED_FILES+1}`)}catch{}}function pruneLogsDir(e){try{let t=Date.now(),s=MAX_AGE_DAYS*24*60*60*1e3,g=readdirSync(e).filter(e=>e.endsWith(`.log`)||/\.log\.\d+$/.test(e)).map(t=>{try{let s=statSync(join(e,t));return{name:t,mtime:s.mtimeMs,size:s.size}}catch{return null}}).filter(Boolean);for(let S of g)if(t-S.mtime>s)try{unlinkSync(join(e,S.name))}catch{}let S=g.filter(e=>t-e.mtime<=s).sort((e,t)=>e.mtime-t.mtime),w=S.reduce((e,t)=>e+t.size,0);for(let t of S){if(w<=MAX_DIR_SIZE_BYTES)break;try{unlinkSync(join(e,t.name)),w-=t.size}catch{}}}catch{}}function createFileLogger(e){ensureDir(OK_LOGS_DIR);let t=todayDateString(),s=e.filePath??join(OK_LOGS_DIR,`${e.name}.${t}.log`);rotateIfNeeded(s),setTimeout(()=>pruneLogsDir(OK_LOGS_DIR),5e3);let g=import_pino.default.destination({dest:s,append:!0,sync:!1});return(0,import_pino.default)({level:resolveLogLevel(),name:e.name,redact:{paths:REDACT_PATHS,censor:`[REDACTED]`},base:{pid:process.pid,hostname:void 0,runtime:`cli`,project:e.project??`<no-project>`},timestamp:import_pino.default.stdTimeFunctions.isoTime,...e.additionalOptions},g)}function getLogFilePath(e){return join(OK_LOGS_DIR,`${e}.${todayDateString()}.log`)}function getLogsDir(){return OK_LOGS_DIR}const ANCESTOR_WALK_DEPTH_LIMIT=30,GIT_MARKER=`.git`;function findEnclosingGitRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT;){let e=!1;try{e=existsSync(resolve(t,GIT_MARKER))}catch{e=!1}if(e)return{gitRoot:t,distance:s};let g=dirname(t);if(g===t)return null;t=g,s+=1}return null}const execFileAsync=promisify(execFile),log=getLogger(`project-git`);var ProjectGitInitError=class extends Error{stderr;constructor(e,t=``,s){super(e,s),this.name=`ProjectGitInitError`,this.stderr=t}};async function isInsideExistingWorkTree(e){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`),g=resolve(s,`HEAD`),S=!1;if(existsSync(s)){if(!statSync(s).isDirectory()||existsSync(g))return{didInit:!1};log.info({},`detected partial .git/ — running git init to repair`),S=!0}else if(await isInsideExistingWorkTree(t))return{didInit:!1};let w=``;try{w=(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(g))throw new ProjectGitInitError(`git init reported success but ${s}/HEAD is missing (partial init detected)`,w);return S?(log.info({path:t},`backfilled missing .git/HEAD`),{didInit:!0,repaired:!0}):(log.info({path:t,branch:`main`},`initialized .git/`),{didInit:!0})}async function resolvePackageVersion(e,t){let s;try{s=createRequire(t).resolve(e)}catch(e){if(e?.code===`MODULE_NOT_FOUND`)return;throw e}for(let t=dirname(s),g=0;g<32;g+=1){let s=join(t,`package.json`);if(existsSync(s))try{let t=JSON.parse(await readFile$1(s,`utf-8`));if(t.name===e&&typeof t.version==`string`)return t.version}catch{}let g=dirname(t);if(g===t)return;t=g}}const MAX_CAUSE_DEPTH=5,HOME_PATH_PATTERNS=[{regex:/\/Users\/[^/]+\//g,replacement:`~/`},{regex:/\/home\/[^/]+\//g,replacement:`~/`},{regex:/C:\\\\Users\\\\[^\\\\]+\\\\/g,replacement:`~\\`},{regex:/C:\\Users\\[^\\]+\\/g,replacement:`~\\`}];function scrubPaths(e){if(e===void 0)return;let t=e;for(let{regex:e,replacement:s}of HOME_PATH_PATTERNS)t=t.replace(e,s);return t}function serializeError(e,t=0,s=new WeakSet){if(t>=MAX_CAUSE_DEPTH)return{name:`SerializedError.CauseDepthExceeded`,message:`cause chain depth > ${MAX_CAUSE_DEPTH}; truncated`};if(typeof e==`object`&&e){if(s.has(e))return{name:`SerializedError.CauseCycle`,message:`cyclic cause; truncated`};s.add(e)}if(e instanceof Error)return{name:e.name,message:scrubPaths(e.message)??``,stack:scrubPaths(e.stack),code:e.code,cause:e.cause===void 0?void 0:serializeError(e.cause,t+1,s)};if(e==null)return{name:`UnknownError`,message:String(e)};if(typeof e==`string`)return{name:`StringError`,message:scrubPaths(e)??e};if(typeof e==`object`){let g=e;return{name:String(g.name??`ObjectError`),message:scrubPaths(String(g.message??``))??``,stack:scrubPaths(g.stack),code:g.code,cause:g.cause===void 0?void 0:serializeError(g.cause,t+1,s)}}return{name:`UnknownError`,message:String(e)}}export{TagIndex as $,readTargetRecordedAt as $n,tracedUnlinkSync as $r,formatAuthRejectionWire as $t,MCP_CONNECTION_ID_HEADER as A,isSelfWrite as An,saveInMemoryCheckpoint as Ar,createContentFilter as At,ROLLBACK_ORIGIN as B,normalizeFsPath as Bn,splitMarkdownBlocks as Br,createStreamingErrorWriter as Bt,HocuspocusAuthRejection as C,writeConfigPatch as Ci,isConfigDoc as Cn,runCloneSubprocess as Cr,commitWipFromTree as Ct,LOG_MD_TEMPLATE as D,isPairedWriteOrigin as Dn,safeSubdir as Dr,contributorCount as Dt,LIVE_DERIVED_INDEX_DEBOUNCE_MS as E,resolveShadowDir as Ei,isLoopbackAddress as En,safeContentPath as Er,contentHash as Et,MissingOkConfigError as F,loadPrincipal as Fn,shadowGit as Fr,createMcpHttpHandler as Ft,STARTER_FOLDER_FRONTMATTER_FILENAME as G,parseKeepaliveConnectionId as Gn,tracedAppendFileSync as Gr,emitPreflightFailureSpan as Gt,SERVICE_WRITER as H,parseAuthRejectionWire as Hn,streamingProblemEvent as Hr,detectClaudeDesktopPresence as Ht,OBSERVER_SYNC_ORIGIN as I,loggerFactory as In,shutdownTelemetry as Ir,createOsProbe as It,STARTER_TEMPLATES as J,readAllTargets as Jn,tracedMkdirSync as Jr,evictStaleTrackerEntries as Jt,STARTER_PACKS as K,pathToDocName as Kn,tracedLinkSync as Kr,ensureProjectGit as Kt,OK_OKIGNORE_TEMPLATE as L,logsCurrentPath as Ln,spansCurrentPath as Lr,createPersistenceExtension as Lt,MIN_GIT_VERSION as M,lastKnownHash as Mn,seedBasenameIndex as Mr,createExternalChangeHandler as Mt,MISSING_OK_CONFIG_MESSAGE as N,listRescueCheckpoints as Nn,serializeError as Nr,createFileLogger as Nt,MANAGED_RENAME_ORIGIN as O,isPathWithinDir as On,safetyCheckpoint as Or,createApiExtension as Ot,McpLogger as P,listStarterPacks as Pn,setActiveSpanAttributes as Pr,createLiveDerivedIndexExtension as Pt,StateManifestError as Q,readStateManifest as Qn,tracedRmdirSync as Qr,findEnclosingProjectRoot as Qt,PinoLogger as R,logsPreviousPath as Rn,spansPreviousPath as Rr,createServer$1 as Rt,HOCUSPOCUS_AUTH_REJECTION_REASONS as S,withFileLockSync as Si,isAllowedWorkspaceHostHeader as Sn,runAuthStatusSubprocess as Sr,commitWip as St,INSTALLED_AGENTS_SCHEMES as T,MalformedGitPointerError as Ti,isKnownPackId as Tn,runWithMcpLogger as Tr,containsConflictMarkers as Tt,SKILL_INSTALL_EVENTS_FILE_REL as U,parseGitVersion as Un,swapContributors as Ur,detectGit as Ut,ROOT_GITIGNORE_TEMPLATE as V,packageVersionMajorMinor as Vn,startWatcher as Vr,createTestLogger as Vt,STARTER_FOLDERS as W,parseHocuspocusAuthToken as Wn,toBroadcasterKey as Wr,detectProjectShape as Wt,SeedPrerequisiteError as X,readServerPackageVersion as Xn,tracedRenameSync as Xr,fallbackPaths as Xt,STATE_MANIFEST_FILENAME as Y,readBranchFromHead as Yn,tracedRename as Yr,extractWikiLinksFromMarkdown as Yt,SeedRootDirError as Z,readSkillInstallStateSnapshot as Zn,tracedRmSync as Zr,findEnclosingGitRoot as Zt,FILE_WATCHER_ORIGIN as _,isJSONRPCRequest as _i,initTelemetry as _n,restoreContributors as _r,classifyEvents as _t,AgentPresenceBroadcaster as a,validateCloneInputs as ai,getLogFilePath as an,registerAllTools as ar,assertCompatibleStateManifest as at,GitNotAvailableError as b,readConfigSafely as bi,installUserSkill as bn,rewriteWikiLinksForDocumentRename as br,coercePackId as bt,BacklinkIndex as c,withSpanSync as ci,getMeter as cn,removeLastKnownHash as cr,attachIdleShutdown as ct,CONFLICT_MARKER_RE as d,writeTargetVersion as di,handleCollabSocketError as dn,resolveContentDir as dr,buildConfigYmlContent as dt,tracedWriteFile as ei,formatContributors as en,readTargetVersion as er,UiLockCollisionError as et,CURSOR_BUNDLE_PATHS_BY_PLATFORM as f,writeTracker as fi,handleSpawnCursor as fn,resolveCursorBinaryDefault as fr,buildExecResult as ft,FILE_SYSTEM_WRITER as g,isInitializedNotification as gi,initShadowRepo as gn,resolvePackageVersion as gr,buildWipTree as gt,DEFAULT_PACK_ID as h,LATEST_PROTOCOL_VERSION as hi,initContent as hn,resolvePack as hr,buildStarterFolderFrontmatterYaml as ht,AgentFocusBroadcaster as i,validateAgentId as ii,getLocalDir as in,recordSkillInstallEvent as ir,applySeed as it,MCP_SERVER_NAME as j,isSystemDoc as jn,saveVersion as jr,createContentFilterAsync as jt,MAX_AGENT_SESSIONS as k,isProjectRoot as kn,sanitizeClientName as kr,createAssetServeMiddleware as kt,CC1Broadcaster as l,writeRootGitignoreForNewRepo as li,getMetrics as ln,resetMetrics as lr,bootServer as lt,DEFAULT_CHECKPOINT_RETENTION as m,JSONRPCMessageSchema as mi,incrementServerObserverFire as mn,resolveLockDir as mr,buildSkillZip as mt,AGENT_ID_RE as n,updateLastKnownHash as ni,gcCheckpointRefs as nn,reconcile as nr,applyAgentMarkdownWrite as nt,AgentSessionCapacityError as o,validateSkillZip as oi,getLogger as on,registerWrite as or,assertGitAvailable as ot,ConfigSchema as p,McpServer as pi,incrementCollabSocketFilteredError as pn,resolveCursorSpawnInvocation as pr,buildInstructions as pt,STARTER_PACK_IDS as q,planSeed as qn,tracedMkdir as qr,errorResponse as qt,AGENT_WRITE_ORIGIN as r,updateUiLockPort as ri,getCurrentMcpLogger as rn,recordContributor as rr,applyExternalChange as rt,AgentSessionManager as s,withSpan as si,getLogsDir as sn,releaseUiLock as sr,assertNeverDiskEvent as st,AGENT_ID_MAX_LEN as t,tracedWriteFileSync as ti,formatContributorsFrom as tn,readUiLock as tr,acquireUiLock as tt,CONFIG_FILENAME as u,writeStateManifest as ui,getTracer as un,resolveBundledSkillDir as ur,buildAndOpenSkill as ut,GIT_PREFLIGHT_FAIL_SPAN_NAME as v,isJSONRPCResultResponse as vi,installPrettyZodErrors as vn,restoreLifecycleFromConflictsJson as vr,classifyFsPath as vt,HocuspocusAuthTokenSchema as w,GitDirAccessError as wi,isHocuspocusAuthRejectionReason as wn,runDeviceFlowSubprocess as wr,compareSemver as wt,GitTooOldError as x,resolveConfigPath as xi,isAllowedApiOrigin as xn,runAuthReposSubprocess as xr,commitUpstreamImport as xt,GIT_UPSTREAM_WRITER as y,atomicWriteFileSync as yi,installTestLoggers as yn,rewriteMarkdownLinksForDocumentRename as yr,clearContributors as yt,ProjectGitInitError as z,mountMcpAndApi as zn,spawnDetached as zr,createServerObserverExtension as zt};
|
|
3084
|
-
//# sourceMappingURL=dist-
|
|
3084
|
+
//# sourceMappingURL=dist-DKgq69uI.mjs.map
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e,r as t,t as n}from"./gh-detect-D3_evne3.mjs";import{_ as r,d as i,f as a,g as o,h as s,i as c,m as l,r as u,s as d,t as f,u as p,v as m,y as h}from"./init-
|
|
1
|
+
import{i as e,r as t,t as n}from"./gh-detect-D3_evne3.mjs";import{_ as r,d as i,f as a,g as o,h as s,i as c,m as l,r as u,s as d,t as f,u as p,v as m,y as h}from"./init-BrOIE7gK.mjs";import{i as g,n as _,r as v,t as y}from"./src-pmNhkR0H.mjs";import{n as b}from"./loader-CxaZzLDi.mjs";import{n as x}from"./preview-BGoO3Ogd.mjs";import{n as S,t as C}from"./mcp-migrate-event-BF8ILHwp.mjs";export{l as ALL_EDITOR_IDS,s as EDITOR_LABELS,o as EDITOR_TARGETS,f as LAUNCH_CONFIG_NAME,r as buildManagedServerEntry,C as buildMcpConfigMigrateEvent,u as classifyExistingMcpEntry,t as createTokenStore,n as detectGh,c as detectInstalledEditors,m as isEntryUpToDate,b as loadConfig,e as makeLazyProbeTokenStore,v as parseGitHubBlobUrl,g as parseGitUrl,x as previewContent,d as readExistingMcpEntry,h as resolveProjectRoot,p as scaffoldLaunchJson,S as truncatePriorEntry,_ as validateLocalFolderForShare,i as writeEditorMcpConfig,y as writeProjectAiIntegrations,a as writeUserMcpConfigs};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{l as e}from"./init-BrOIE7gK.mjs";export{e as runInit};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as e,o as t,t as n}from"./chunk-FK9Q3tQk.mjs";import{r,t as i}from"./esm-CEs3LWY3.mjs";import{Ct as a,Rt as o,St as s,Tr as c,pn as l,v as u,y as d}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{En as f,Ht as p,Kt as m,Si as h,Sn as g,bn as _,hn as v,j as y,kn as b,li as x,xn as S,yi as C,z as w}from"./dist-BBbP7DxV.mjs";import"./constants-EfhRR_gr.mjs";import{t as T}from"./is-object-C-4FJ0rP.mjs";import{i as E,o as D,r as O,s as ee,t as k}from"./colors-BtKMHmBX.mjs";import{t as A}from"./preview-BUNvNkcD.mjs";import{n as te,t as ne}from"./write-project-skill-BNMnZE-x.mjs";import{execFileSync as re}from"node:child_process";import ie,{basename as j,dirname as M,isAbsolute as N,join as P,posix as ae,relative as F,resolve as I,sep as L,win32 as R}from"node:path";import{existsSync as z,mkdirSync as oe,readFileSync as se,realpathSync as ce,writeFileSync as le}from"node:fs";import B from"node:process";import{homedir as V}from"node:os";import{AsyncLocalStorage as ue,AsyncResource as de}from"node:async_hooks";import{stripVTControlCharacters as fe,styleText as H}from"node:util";import*as pe from"node:readline";import{randomUUID as me}from"node:crypto";import{createServer as he,request as ge}from"node:http";import{connect as _e}from"node:net";function ve(){return B.platform.startsWith(`win`)?!!B.env.CI||!!B.env.WT_SESSION||!!B.env.TERMINUS_SUBLIME||B.env.ConEmuTask===`{cmd::Cmder}`||B.env.TERM_PROGRAM===`Terminus-Sublime`||B.env.TERM_PROGRAM===`vscode`||B.env.TERM===`xterm-256color`||B.env.TERM===`alacritty`||B.env.TERMINAL_EMULATOR===`JetBrains-JediTerm`:B.env.TERM!==`linux`}const ye={circleQuestionMark:`(?)`,questionMarkPrefix:`(?)`,square:`█`,squareDarkShade:`▓`,squareMediumShade:`▒`,squareLightShade:`░`,squareTop:`▀`,squareBottom:`▄`,squareLeft:`▌`,squareRight:`▐`,squareCenter:`■`,bullet:`●`,dot:`․`,ellipsis:`…`,pointerSmall:`›`,triangleUp:`▲`,triangleUpSmall:`▴`,triangleDown:`▼`,triangleDownSmall:`▾`,triangleLeftSmall:`◂`,triangleRightSmall:`▸`,home:`⌂`,heart:`♥`,musicNote:`♪`,musicNoteBeamed:`♫`,arrowUp:`↑`,arrowDown:`↓`,arrowLeft:`←`,arrowRight:`→`,arrowLeftRight:`↔`,arrowUpDown:`↕`,almostEqual:`≈`,notEqual:`≠`,lessOrEqual:`≤`,greaterOrEqual:`≥`,identical:`≡`,infinity:`∞`,subscriptZero:`₀`,subscriptOne:`₁`,subscriptTwo:`₂`,subscriptThree:`₃`,subscriptFour:`₄`,subscriptFive:`₅`,subscriptSix:`₆`,subscriptSeven:`₇`,subscriptEight:`₈`,subscriptNine:`₉`,oneHalf:`½`,oneThird:`⅓`,oneQuarter:`¼`,oneFifth:`⅕`,oneSixth:`⅙`,oneEighth:`⅛`,twoThirds:`⅔`,twoFifths:`⅖`,threeQuarters:`¾`,threeFifths:`⅗`,threeEighths:`⅜`,fourFifths:`⅘`,fiveSixths:`⅚`,fiveEighths:`⅝`,sevenEighths:`⅞`,line:`─`,lineBold:`━`,lineDouble:`═`,lineDashed0:`┄`,lineDashed1:`┅`,lineDashed2:`┈`,lineDashed3:`┉`,lineDashed4:`╌`,lineDashed5:`╍`,lineDashed6:`╴`,lineDashed7:`╶`,lineDashed8:`╸`,lineDashed9:`╺`,lineDashed10:`╼`,lineDashed11:`╾`,lineDashed12:`−`,lineDashed13:`–`,lineDashed14:`‐`,lineDashed15:`⁃`,lineVertical:`│`,lineVerticalBold:`┃`,lineVerticalDouble:`║`,lineVerticalDashed0:`┆`,lineVerticalDashed1:`┇`,lineVerticalDashed2:`┊`,lineVerticalDashed3:`┋`,lineVerticalDashed4:`╎`,lineVerticalDashed5:`╏`,lineVerticalDashed6:`╵`,lineVerticalDashed7:`╷`,lineVerticalDashed8:`╹`,lineVerticalDashed9:`╻`,lineVerticalDashed10:`╽`,lineVerticalDashed11:`╿`,lineDownLeft:`┐`,lineDownLeftArc:`╮`,lineDownBoldLeftBold:`┓`,lineDownBoldLeft:`┒`,lineDownLeftBold:`┑`,lineDownDoubleLeftDouble:`╗`,lineDownDoubleLeft:`╖`,lineDownLeftDouble:`╕`,lineDownRight:`┌`,lineDownRightArc:`╭`,lineDownBoldRightBold:`┏`,lineDownBoldRight:`┎`,lineDownRightBold:`┍`,lineDownDoubleRightDouble:`╔`,lineDownDoubleRight:`╓`,lineDownRightDouble:`╒`,lineUpLeft:`┘`,lineUpLeftArc:`╯`,lineUpBoldLeftBold:`┛`,lineUpBoldLeft:`┚`,lineUpLeftBold:`┙`,lineUpDoubleLeftDouble:`╝`,lineUpDoubleLeft:`╜`,lineUpLeftDouble:`╛`,lineUpRight:`└`,lineUpRightArc:`╰`,lineUpBoldRightBold:`┗`,lineUpBoldRight:`┖`,lineUpRightBold:`┕`,lineUpDoubleRightDouble:`╚`,lineUpDoubleRight:`╙`,lineUpRightDouble:`╘`,lineUpDownLeft:`┤`,lineUpBoldDownBoldLeftBold:`┫`,lineUpBoldDownBoldLeft:`┨`,lineUpDownLeftBold:`┥`,lineUpBoldDownLeftBold:`┩`,lineUpDownBoldLeftBold:`┪`,lineUpDownBoldLeft:`┧`,lineUpBoldDownLeft:`┦`,lineUpDoubleDownDoubleLeftDouble:`╣`,lineUpDoubleDownDoubleLeft:`╢`,lineUpDownLeftDouble:`╡`,lineUpDownRight:`├`,lineUpBoldDownBoldRightBold:`┣`,lineUpBoldDownBoldRight:`┠`,lineUpDownRightBold:`┝`,lineUpBoldDownRightBold:`┡`,lineUpDownBoldRightBold:`┢`,lineUpDownBoldRight:`┟`,lineUpBoldDownRight:`┞`,lineUpDoubleDownDoubleRightDouble:`╠`,lineUpDoubleDownDoubleRight:`╟`,lineUpDownRightDouble:`╞`,lineDownLeftRight:`┬`,lineDownBoldLeftBoldRightBold:`┳`,lineDownLeftBoldRightBold:`┯`,lineDownBoldLeftRight:`┰`,lineDownBoldLeftBoldRight:`┱`,lineDownBoldLeftRightBold:`┲`,lineDownLeftRightBold:`┮`,lineDownLeftBoldRight:`┭`,lineDownDoubleLeftDoubleRightDouble:`╦`,lineDownDoubleLeftRight:`╥`,lineDownLeftDoubleRightDouble:`╤`,lineUpLeftRight:`┴`,lineUpBoldLeftBoldRightBold:`┻`,lineUpLeftBoldRightBold:`┷`,lineUpBoldLeftRight:`┸`,lineUpBoldLeftBoldRight:`┹`,lineUpBoldLeftRightBold:`┺`,lineUpLeftRightBold:`┶`,lineUpLeftBoldRight:`┵`,lineUpDoubleLeftDoubleRightDouble:`╩`,lineUpDoubleLeftRight:`╨`,lineUpLeftDoubleRightDouble:`╧`,lineUpDownLeftRight:`┼`,lineUpBoldDownBoldLeftBoldRightBold:`╋`,lineUpDownBoldLeftBoldRightBold:`╈`,lineUpBoldDownLeftBoldRightBold:`╇`,lineUpBoldDownBoldLeftRightBold:`╊`,lineUpBoldDownBoldLeftBoldRight:`╉`,lineUpBoldDownLeftRight:`╀`,lineUpDownBoldLeftRight:`╁`,lineUpDownLeftBoldRight:`┽`,lineUpDownLeftRightBold:`┾`,lineUpBoldDownBoldLeftRight:`╂`,lineUpDownLeftBoldRightBold:`┿`,lineUpBoldDownLeftBoldRight:`╃`,lineUpBoldDownLeftRightBold:`╄`,lineUpDownBoldLeftBoldRight:`╅`,lineUpDownBoldLeftRightBold:`╆`,lineUpDoubleDownDoubleLeftDoubleRightDouble:`╬`,lineUpDoubleDownDoubleLeftRight:`╫`,lineUpDownLeftDoubleRightDouble:`╪`,lineCross:`╳`,lineBackslash:`╲`,lineSlash:`╱`},be={tick:`✔`,info:`ℹ`,warning:`⚠`,cross:`✘`,squareSmall:`◻`,squareSmallFilled:`◼`,circle:`◯`,circleFilled:`◉`,circleDotted:`◌`,circleDouble:`◎`,circleCircle:`ⓞ`,circleCross:`ⓧ`,circlePipe:`Ⓘ`,radioOn:`◉`,radioOff:`◯`,checkboxOn:`☒`,checkboxOff:`☐`,checkboxCircleOn:`ⓧ`,checkboxCircleOff:`Ⓘ`,pointer:`❯`,triangleUpOutline:`△`,triangleLeft:`◀`,triangleRight:`▶`,lozenge:`◆`,lozengeOutline:`◇`,hamburger:`☰`,smiley:`㋡`,mustache:`෴`,star:`★`,play:`▶`,nodejs:`⬢`,oneSeventh:`⅐`,oneNinth:`⅑`,oneTenth:`⅒`},xe={tick:`√`,info:`i`,warning:`‼`,cross:`×`,squareSmall:`□`,squareSmallFilled:`■`,circle:`( )`,circleFilled:`(*)`,circleDotted:`( )`,circleDouble:`( )`,circleCircle:`(○)`,circleCross:`(×)`,circlePipe:`(│)`,radioOn:`(*)`,radioOff:`( )`,checkboxOn:`[×]`,checkboxOff:`[ ]`,checkboxCircleOn:`(×)`,checkboxCircleOff:`( )`,pointer:`>`,triangleUpOutline:`∆`,triangleLeft:`◄`,triangleRight:`►`,lozenge:`♦`,lozengeOutline:`◊`,hamburger:`≡`,smiley:`☺`,mustache:`┌─┐`,star:`✶`,play:`►`,nodejs:`♦`,oneSeventh:`1/7`,oneNinth:`1/9`,oneTenth:`1/10`},Se={...ye,...be},Ce={...ye,...xe},U=ve()?Se:Ce;Object.entries(be);var we=n(((t,n)=>{n.exports=i;function r(t){let n={defaultWidth:0,output:process.stdout,tty:e(`tty`)};return t?(Object.keys(n).forEach(function(e){t[e]||(t[e]=n[e])}),t):n}function i(e){let t=r(e);if(t.output.getWindowSize)return t.output.getWindowSize()[0]||t.defaultWidth;if(t.tty.getWindowSize)return t.tty.getWindowSize()[1]||t.defaultWidth;if(t.output.columns)return t.output.columns;if(process.env.CLI_WIDTH){let e=parseInt(process.env.CLI_WIDTH,10);if(!isNaN(e)&&e!==0)return e}return t.defaultWidth}}));const Te=(()=>{let e=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return t=>{let n=0;for(e.lastIndex=0;e.test(t);)n+=1;return t.length-n}})(),Ee=e=>e===12288||e>=65281&&e<=65376||e>=65504&&e<=65510,De=e=>e===8987||e===9001||e>=12272&&e<=12287||e>=12289&&e<=12350||e>=12441&&e<=12543||e>=12549&&e<=12591||e>=12593&&e<=12686||e>=12688&&e<=12771||e>=12783&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=19903||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=127488&&e<=127490||e>=127504&&e<=127547||e>=127552&&e<=127560||e>=131072&&e<=196605||e>=196608&&e<=262141,Oe=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,ke=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,Ae=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/uy,je=/\t{1,1000}/y,Me=/[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/uy,Ne=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,Pe=/\p{M}+/gu,Fe={limit:1/0,ellipsis:``},Ie=(e,t={},n={})=>{let r=t.limit??1/0,i=t.ellipsis??``,a=t?.ellipsisWidth??(i?Ie(i,Fe,n).width:0),o=n.controlWidth??0,s=n.tabWidth??8,c=n.emojiWidth??2,l=n.regularWidth??1,u=n.wideWidth??2,d=[[Ne,l],[Oe,0],[ke,o],[je,s],[Me,c],[Ae,u]],f=0,p=0,m=e.length,h=0,g=!1,_=m,v=Math.max(0,r-a),y=0,b=0,x=0,S=0;outer:for(;;){if(b>y||p>=m&&p>f){let t=e.slice(y,b)||e.slice(f,p);h=0;for(let e of t.replaceAll(Pe,``)){let t=e.codePointAt(0)||0;if(S=Ee(t)?2:De(t)?u:l,x+S>v&&(_=Math.min(_,Math.max(y,f)+h)),x+S>r){g=!0;break outer}h+=e.length,x+=S}y=b=0}if(p>=m)break outer;for(let t=0,n=d.length;t<n;t++){let[n,i]=d[t];if(n.lastIndex=p,n.test(e)){if(h=n===Ae?Te(e.slice(p,n.lastIndex)):n===Me?1:n.lastIndex-p,S=h*i,x+S>v&&(_=Math.min(_,p+Math.floor((v-x)/i))),x+S>r){g=!0;break outer}x+=S,y=f,b=p,p=f=n.lastIndex;continue outer}}p+=1}return{width:g?v:x,index:g?_:m,truncated:g,ellipsed:g&&r>=a}},Le={limit:1/0,ellipsis:``,ellipsisWidth:0},W=(e,t={})=>Ie(e,Le,t).width,Re=`]8;;`,ze=RegExp(`(?:\\[(?<code>\\d+)m|\\${Re}(?<uri>.*))`,`y`),Be=e=>{if(e>=30&&e<=37||e>=90&&e<=97)return 39;if(e>=40&&e<=47||e>=100&&e<=107)return 49;if(e===1||e===2)return 22;if(e===3)return 23;if(e===4)return 24;if(e===7)return 27;if(e===8)return 28;if(e===9)return 29;if(e===0)return 0},Ve=e=>`[${e}m`,He=e=>`${Re}${e}`,Ue=(e,t,n)=>{let r=t[Symbol.iterator](),i=!1,a=!1,o=e.at(-1),s=o===void 0?0:W(o),c=r.next(),l=r.next(),u=0;for(;!c.done;){let o=c.value,d=W(o);s+d<=n?e[e.length-1]+=o:(e.push(o),s=0),(o===`\x1B`||o===``)&&(i=!0,a=t.startsWith(Re,u+1)),i?a?o===`\x07`&&(i=!1,a=!1):o===`m`&&(i=!1):(s+=d,s===n&&!l.done&&(e.push(``),s=0)),c=l,l=r.next(),u+=o.length}o=e.at(-1),!s&&o!==void 0&&o.length&&e.length>1&&(e[e.length-2]+=e.pop())},We=e=>{let t=e.split(` `),n=t.length;for(;n&&!W(t[n-1]);)n--;return n===t.length?e:t.slice(0,n).join(` `)+t.slice(n).join(``)},Ge=(e,t,n={})=>{if(n.trim!==!1&&e.trim()===``)return``;let r=``,i,a,o=e.split(` `),s=[``],c=0;for(let e=0;e<o.length;e++){let r=o[e];if(n.trim!==!1){let e=s.at(-1)??``,t=e.trimStart();e.length!==t.length&&(s[s.length-1]=t,c=W(t))}e!==0&&(c>=t&&(n.wordWrap===!1||n.trim===!1)&&(s.push(``),c=0),(c||n.trim===!1)&&(s[s.length-1]+=` `,c++));let i=W(r);if(n.hard&&i>t){let e=t-c,n=1+Math.floor((i-e-1)/t);Math.floor((i-1)/t)<n&&s.push(``),Ue(s,r,t),c=W(s.at(-1)??``);continue}if(c+i>t&&c&&i){if(n.wordWrap===!1&&c<t){Ue(s,r,t),c=W(s.at(-1)??``);continue}s.push(``),c=0}if(c+i>t&&n.wordWrap===!1){Ue(s,r,t),c=W(s.at(-1)??``);continue}s[s.length-1]+=r,c+=i}n.trim!==!1&&(s=s.map(e=>We(e)));let l=s.join(`
|
|
1
|
+
import{i as e,o as t,t as n}from"./chunk-FK9Q3tQk.mjs";import{r,t as i}from"./esm-CEs3LWY3.mjs";import{Ct as a,Rt as o,St as s,Tr as c,pn as l,v as u,y as d}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{En as f,Ht as p,Kt as m,Si as h,Sn as g,bn as _,hn as v,j as y,kn as b,li as x,xn as S,yi as C,z as w}from"./dist-DKgq69uI.mjs";import"./constants-D9hc7LX4.mjs";import{t as T}from"./is-object-C-4FJ0rP.mjs";import{i as E,o as D,r as O,s as ee,t as k}from"./colors-BtKMHmBX.mjs";import{t as A}from"./preview-BGoO3Ogd.mjs";import{n as te,t as ne}from"./write-project-skill-BQGm1G4f.mjs";import{execFileSync as re}from"node:child_process";import ie,{basename as j,dirname as M,isAbsolute as N,join as P,posix as ae,relative as F,resolve as I,sep as L,win32 as R}from"node:path";import{existsSync as z,mkdirSync as oe,readFileSync as se,realpathSync as ce,writeFileSync as le}from"node:fs";import B from"node:process";import{homedir as V}from"node:os";import{AsyncLocalStorage as ue,AsyncResource as de}from"node:async_hooks";import{stripVTControlCharacters as fe,styleText as H}from"node:util";import*as pe from"node:readline";import{randomUUID as me}from"node:crypto";import{createServer as he,request as ge}from"node:http";import{connect as _e}from"node:net";function ve(){return B.platform.startsWith(`win`)?!!B.env.CI||!!B.env.WT_SESSION||!!B.env.TERMINUS_SUBLIME||B.env.ConEmuTask===`{cmd::Cmder}`||B.env.TERM_PROGRAM===`Terminus-Sublime`||B.env.TERM_PROGRAM===`vscode`||B.env.TERM===`xterm-256color`||B.env.TERM===`alacritty`||B.env.TERMINAL_EMULATOR===`JetBrains-JediTerm`:B.env.TERM!==`linux`}const ye={circleQuestionMark:`(?)`,questionMarkPrefix:`(?)`,square:`█`,squareDarkShade:`▓`,squareMediumShade:`▒`,squareLightShade:`░`,squareTop:`▀`,squareBottom:`▄`,squareLeft:`▌`,squareRight:`▐`,squareCenter:`■`,bullet:`●`,dot:`․`,ellipsis:`…`,pointerSmall:`›`,triangleUp:`▲`,triangleUpSmall:`▴`,triangleDown:`▼`,triangleDownSmall:`▾`,triangleLeftSmall:`◂`,triangleRightSmall:`▸`,home:`⌂`,heart:`♥`,musicNote:`♪`,musicNoteBeamed:`♫`,arrowUp:`↑`,arrowDown:`↓`,arrowLeft:`←`,arrowRight:`→`,arrowLeftRight:`↔`,arrowUpDown:`↕`,almostEqual:`≈`,notEqual:`≠`,lessOrEqual:`≤`,greaterOrEqual:`≥`,identical:`≡`,infinity:`∞`,subscriptZero:`₀`,subscriptOne:`₁`,subscriptTwo:`₂`,subscriptThree:`₃`,subscriptFour:`₄`,subscriptFive:`₅`,subscriptSix:`₆`,subscriptSeven:`₇`,subscriptEight:`₈`,subscriptNine:`₉`,oneHalf:`½`,oneThird:`⅓`,oneQuarter:`¼`,oneFifth:`⅕`,oneSixth:`⅙`,oneEighth:`⅛`,twoThirds:`⅔`,twoFifths:`⅖`,threeQuarters:`¾`,threeFifths:`⅗`,threeEighths:`⅜`,fourFifths:`⅘`,fiveSixths:`⅚`,fiveEighths:`⅝`,sevenEighths:`⅞`,line:`─`,lineBold:`━`,lineDouble:`═`,lineDashed0:`┄`,lineDashed1:`┅`,lineDashed2:`┈`,lineDashed3:`┉`,lineDashed4:`╌`,lineDashed5:`╍`,lineDashed6:`╴`,lineDashed7:`╶`,lineDashed8:`╸`,lineDashed9:`╺`,lineDashed10:`╼`,lineDashed11:`╾`,lineDashed12:`−`,lineDashed13:`–`,lineDashed14:`‐`,lineDashed15:`⁃`,lineVertical:`│`,lineVerticalBold:`┃`,lineVerticalDouble:`║`,lineVerticalDashed0:`┆`,lineVerticalDashed1:`┇`,lineVerticalDashed2:`┊`,lineVerticalDashed3:`┋`,lineVerticalDashed4:`╎`,lineVerticalDashed5:`╏`,lineVerticalDashed6:`╵`,lineVerticalDashed7:`╷`,lineVerticalDashed8:`╹`,lineVerticalDashed9:`╻`,lineVerticalDashed10:`╽`,lineVerticalDashed11:`╿`,lineDownLeft:`┐`,lineDownLeftArc:`╮`,lineDownBoldLeftBold:`┓`,lineDownBoldLeft:`┒`,lineDownLeftBold:`┑`,lineDownDoubleLeftDouble:`╗`,lineDownDoubleLeft:`╖`,lineDownLeftDouble:`╕`,lineDownRight:`┌`,lineDownRightArc:`╭`,lineDownBoldRightBold:`┏`,lineDownBoldRight:`┎`,lineDownRightBold:`┍`,lineDownDoubleRightDouble:`╔`,lineDownDoubleRight:`╓`,lineDownRightDouble:`╒`,lineUpLeft:`┘`,lineUpLeftArc:`╯`,lineUpBoldLeftBold:`┛`,lineUpBoldLeft:`┚`,lineUpLeftBold:`┙`,lineUpDoubleLeftDouble:`╝`,lineUpDoubleLeft:`╜`,lineUpLeftDouble:`╛`,lineUpRight:`└`,lineUpRightArc:`╰`,lineUpBoldRightBold:`┗`,lineUpBoldRight:`┖`,lineUpRightBold:`┕`,lineUpDoubleRightDouble:`╚`,lineUpDoubleRight:`╙`,lineUpRightDouble:`╘`,lineUpDownLeft:`┤`,lineUpBoldDownBoldLeftBold:`┫`,lineUpBoldDownBoldLeft:`┨`,lineUpDownLeftBold:`┥`,lineUpBoldDownLeftBold:`┩`,lineUpDownBoldLeftBold:`┪`,lineUpDownBoldLeft:`┧`,lineUpBoldDownLeft:`┦`,lineUpDoubleDownDoubleLeftDouble:`╣`,lineUpDoubleDownDoubleLeft:`╢`,lineUpDownLeftDouble:`╡`,lineUpDownRight:`├`,lineUpBoldDownBoldRightBold:`┣`,lineUpBoldDownBoldRight:`┠`,lineUpDownRightBold:`┝`,lineUpBoldDownRightBold:`┡`,lineUpDownBoldRightBold:`┢`,lineUpDownBoldRight:`┟`,lineUpBoldDownRight:`┞`,lineUpDoubleDownDoubleRightDouble:`╠`,lineUpDoubleDownDoubleRight:`╟`,lineUpDownRightDouble:`╞`,lineDownLeftRight:`┬`,lineDownBoldLeftBoldRightBold:`┳`,lineDownLeftBoldRightBold:`┯`,lineDownBoldLeftRight:`┰`,lineDownBoldLeftBoldRight:`┱`,lineDownBoldLeftRightBold:`┲`,lineDownLeftRightBold:`┮`,lineDownLeftBoldRight:`┭`,lineDownDoubleLeftDoubleRightDouble:`╦`,lineDownDoubleLeftRight:`╥`,lineDownLeftDoubleRightDouble:`╤`,lineUpLeftRight:`┴`,lineUpBoldLeftBoldRightBold:`┻`,lineUpLeftBoldRightBold:`┷`,lineUpBoldLeftRight:`┸`,lineUpBoldLeftBoldRight:`┹`,lineUpBoldLeftRightBold:`┺`,lineUpLeftRightBold:`┶`,lineUpLeftBoldRight:`┵`,lineUpDoubleLeftDoubleRightDouble:`╩`,lineUpDoubleLeftRight:`╨`,lineUpLeftDoubleRightDouble:`╧`,lineUpDownLeftRight:`┼`,lineUpBoldDownBoldLeftBoldRightBold:`╋`,lineUpDownBoldLeftBoldRightBold:`╈`,lineUpBoldDownLeftBoldRightBold:`╇`,lineUpBoldDownBoldLeftRightBold:`╊`,lineUpBoldDownBoldLeftBoldRight:`╉`,lineUpBoldDownLeftRight:`╀`,lineUpDownBoldLeftRight:`╁`,lineUpDownLeftBoldRight:`┽`,lineUpDownLeftRightBold:`┾`,lineUpBoldDownBoldLeftRight:`╂`,lineUpDownLeftBoldRightBold:`┿`,lineUpBoldDownLeftBoldRight:`╃`,lineUpBoldDownLeftRightBold:`╄`,lineUpDownBoldLeftBoldRight:`╅`,lineUpDownBoldLeftRightBold:`╆`,lineUpDoubleDownDoubleLeftDoubleRightDouble:`╬`,lineUpDoubleDownDoubleLeftRight:`╫`,lineUpDownLeftDoubleRightDouble:`╪`,lineCross:`╳`,lineBackslash:`╲`,lineSlash:`╱`},be={tick:`✔`,info:`ℹ`,warning:`⚠`,cross:`✘`,squareSmall:`◻`,squareSmallFilled:`◼`,circle:`◯`,circleFilled:`◉`,circleDotted:`◌`,circleDouble:`◎`,circleCircle:`ⓞ`,circleCross:`ⓧ`,circlePipe:`Ⓘ`,radioOn:`◉`,radioOff:`◯`,checkboxOn:`☒`,checkboxOff:`☐`,checkboxCircleOn:`ⓧ`,checkboxCircleOff:`Ⓘ`,pointer:`❯`,triangleUpOutline:`△`,triangleLeft:`◀`,triangleRight:`▶`,lozenge:`◆`,lozengeOutline:`◇`,hamburger:`☰`,smiley:`㋡`,mustache:`෴`,star:`★`,play:`▶`,nodejs:`⬢`,oneSeventh:`⅐`,oneNinth:`⅑`,oneTenth:`⅒`},xe={tick:`√`,info:`i`,warning:`‼`,cross:`×`,squareSmall:`□`,squareSmallFilled:`■`,circle:`( )`,circleFilled:`(*)`,circleDotted:`( )`,circleDouble:`( )`,circleCircle:`(○)`,circleCross:`(×)`,circlePipe:`(│)`,radioOn:`(*)`,radioOff:`( )`,checkboxOn:`[×]`,checkboxOff:`[ ]`,checkboxCircleOn:`(×)`,checkboxCircleOff:`( )`,pointer:`>`,triangleUpOutline:`∆`,triangleLeft:`◄`,triangleRight:`►`,lozenge:`♦`,lozengeOutline:`◊`,hamburger:`≡`,smiley:`☺`,mustache:`┌─┐`,star:`✶`,play:`►`,nodejs:`♦`,oneSeventh:`1/7`,oneNinth:`1/9`,oneTenth:`1/10`},Se={...ye,...be},Ce={...ye,...xe},U=ve()?Se:Ce;Object.entries(be);var we=n(((t,n)=>{n.exports=i;function r(t){let n={defaultWidth:0,output:process.stdout,tty:e(`tty`)};return t?(Object.keys(n).forEach(function(e){t[e]||(t[e]=n[e])}),t):n}function i(e){let t=r(e);if(t.output.getWindowSize)return t.output.getWindowSize()[0]||t.defaultWidth;if(t.tty.getWindowSize)return t.tty.getWindowSize()[1]||t.defaultWidth;if(t.output.columns)return t.output.columns;if(process.env.CLI_WIDTH){let e=parseInt(process.env.CLI_WIDTH,10);if(!isNaN(e)&&e!==0)return e}return t.defaultWidth}}));const Te=(()=>{let e=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return t=>{let n=0;for(e.lastIndex=0;e.test(t);)n+=1;return t.length-n}})(),Ee=e=>e===12288||e>=65281&&e<=65376||e>=65504&&e<=65510,De=e=>e===8987||e===9001||e>=12272&&e<=12287||e>=12289&&e<=12350||e>=12441&&e<=12543||e>=12549&&e<=12591||e>=12593&&e<=12686||e>=12688&&e<=12771||e>=12783&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=19903||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=127488&&e<=127490||e>=127504&&e<=127547||e>=127552&&e<=127560||e>=131072&&e<=196605||e>=196608&&e<=262141,Oe=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,ke=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,Ae=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/uy,je=/\t{1,1000}/y,Me=/[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/uy,Ne=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,Pe=/\p{M}+/gu,Fe={limit:1/0,ellipsis:``},Ie=(e,t={},n={})=>{let r=t.limit??1/0,i=t.ellipsis??``,a=t?.ellipsisWidth??(i?Ie(i,Fe,n).width:0),o=n.controlWidth??0,s=n.tabWidth??8,c=n.emojiWidth??2,l=n.regularWidth??1,u=n.wideWidth??2,d=[[Ne,l],[Oe,0],[ke,o],[je,s],[Me,c],[Ae,u]],f=0,p=0,m=e.length,h=0,g=!1,_=m,v=Math.max(0,r-a),y=0,b=0,x=0,S=0;outer:for(;;){if(b>y||p>=m&&p>f){let t=e.slice(y,b)||e.slice(f,p);h=0;for(let e of t.replaceAll(Pe,``)){let t=e.codePointAt(0)||0;if(S=Ee(t)?2:De(t)?u:l,x+S>v&&(_=Math.min(_,Math.max(y,f)+h)),x+S>r){g=!0;break outer}h+=e.length,x+=S}y=b=0}if(p>=m)break outer;for(let t=0,n=d.length;t<n;t++){let[n,i]=d[t];if(n.lastIndex=p,n.test(e)){if(h=n===Ae?Te(e.slice(p,n.lastIndex)):n===Me?1:n.lastIndex-p,S=h*i,x+S>v&&(_=Math.min(_,p+Math.floor((v-x)/i))),x+S>r){g=!0;break outer}x+=S,y=f,b=p,p=f=n.lastIndex;continue outer}}p+=1}return{width:g?v:x,index:g?_:m,truncated:g,ellipsed:g&&r>=a}},Le={limit:1/0,ellipsis:``,ellipsisWidth:0},W=(e,t={})=>Ie(e,Le,t).width,Re=`]8;;`,ze=RegExp(`(?:\\[(?<code>\\d+)m|\\${Re}(?<uri>.*))`,`y`),Be=e=>{if(e>=30&&e<=37||e>=90&&e<=97)return 39;if(e>=40&&e<=47||e>=100&&e<=107)return 49;if(e===1||e===2)return 22;if(e===3)return 23;if(e===4)return 24;if(e===7)return 27;if(e===8)return 28;if(e===9)return 29;if(e===0)return 0},Ve=e=>`[${e}m`,He=e=>`${Re}${e}`,Ue=(e,t,n)=>{let r=t[Symbol.iterator](),i=!1,a=!1,o=e.at(-1),s=o===void 0?0:W(o),c=r.next(),l=r.next(),u=0;for(;!c.done;){let o=c.value,d=W(o);s+d<=n?e[e.length-1]+=o:(e.push(o),s=0),(o===`\x1B`||o===``)&&(i=!0,a=t.startsWith(Re,u+1)),i?a?o===`\x07`&&(i=!1,a=!1):o===`m`&&(i=!1):(s+=d,s===n&&!l.done&&(e.push(``),s=0)),c=l,l=r.next(),u+=o.length}o=e.at(-1),!s&&o!==void 0&&o.length&&e.length>1&&(e[e.length-2]+=e.pop())},We=e=>{let t=e.split(` `),n=t.length;for(;n&&!W(t[n-1]);)n--;return n===t.length?e:t.slice(0,n).join(` `)+t.slice(n).join(``)},Ge=(e,t,n={})=>{if(n.trim!==!1&&e.trim()===``)return``;let r=``,i,a,o=e.split(` `),s=[``],c=0;for(let e=0;e<o.length;e++){let r=o[e];if(n.trim!==!1){let e=s.at(-1)??``,t=e.trimStart();e.length!==t.length&&(s[s.length-1]=t,c=W(t))}e!==0&&(c>=t&&(n.wordWrap===!1||n.trim===!1)&&(s.push(``),c=0),(c||n.trim===!1)&&(s[s.length-1]+=` `,c++));let i=W(r);if(n.hard&&i>t){let e=t-c,n=1+Math.floor((i-e-1)/t);Math.floor((i-1)/t)<n&&s.push(``),Ue(s,r,t),c=W(s.at(-1)??``);continue}if(c+i>t&&c&&i){if(n.wordWrap===!1&&c<t){Ue(s,r,t),c=W(s.at(-1)??``);continue}s.push(``),c=0}if(c+i>t&&n.wordWrap===!1){Ue(s,r,t),c=W(s.at(-1)??``);continue}s[s.length-1]+=r,c+=i}n.trim!==!1&&(s=s.map(e=>We(e)));let l=s.join(`
|
|
2
2
|
`),u=!1;for(let e=0;e<l.length;e++){let t=l[e];if(r+=t,u)u=!1;else if(u=t>=`\ud800`&&t<=`\udbff`,u)continue;if(t===`\x1B`||t===``){ze.lastIndex=e+1;let t=ze.exec(l)?.groups;if(t?.code!==void 0){let e=Number.parseFloat(t.code);i=e===39?void 0:e}else t?.uri!==void 0&&(a=t.uri.length===0?void 0:t.uri)}if(l[e+1]===`
|
|
3
3
|
`){a&&(r+=He(``));let e=i?Be(i):void 0;i&&e&&(r+=Ve(e))}else t===`
|
|
4
4
|
`&&(i&&Be(i)&&(r+=Ve(i)),a&&(r+=He(a)))}return r},Ke=/\r?\n/;function qe(e,t,n){return String(e).normalize().split(Ke).map(e=>Ge(e,t,n)).join(`
|
|
@@ -273,9 +273,9 @@ for d in "$HOME/.nvm/versions/node"/*/bin "$HOME/.fnm/node-versions"/*/installat
|
|
|
273
273
|
done
|
|
274
274
|
echo "Open Knowledge: install OK Desktop or Node.js 24+, then restart your editor" >&2
|
|
275
275
|
exit 127`]}}function $n(e){return e===`win32`?R:ae}function er(e={}){let t=e.platformName??process.platform,n=e.home??V();return $n(t).join(n,`.claude.json`)}function tr(e={}){let t=e.platformName??process.platform,n=e.home??V(),r=e.env??process.env;if(t===`darwin`)return ae.join(n,`Library`,`Application Support`,`Claude`,`claude_desktop_config.json`);if(t===`win32`){let e=r.APPDATA??R.join(n,`AppData`,`Roaming`);return R.join(e,`Claude`,`claude_desktop_config.json`)}throw Error(`Claude Desktop is not available on ${t}. Supported: macOS, Windows.`)}function nr(e={}){let t=e.platformName??process.platform,n=e.home??V();return $n(t).join(n,`.cursor`,`mcp.json`)}function rr(e={}){let t=e.platformName??process.platform,n=e.home??V();return(e.env??process.env).CODEX_HOME??$n(t).join(n,`.codex`)}function ir(e={}){return $n(e.platformName??process.platform).join(rr(e),`config.toml`)}const Q={claude:{id:`claude`,label:Jn.claude,configPath:(e,t)=>er({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>y,buildEntry:(e,t)=>Qn(t),scope:`global`,detectPath:(e,t)=>P(t??V(),`.claude`),projectConfigPath:e=>P(e,`.mcp.json`),projectSkillPath:e=>P(e,`.claude`,`skills`,`open-knowledge`,`SKILL.md`)},"claude-desktop":{id:`claude-desktop`,label:Jn[`claude-desktop`],configPath:(e,t)=>tr({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>y,buildEntry:(e,t)=>Qn(t),scope:`global`,detectPath:(e,t)=>M(tr({home:t}))},cursor:{id:`cursor`,label:Jn.cursor,configPath:(e,t)=>nr({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>y,buildEntry:(e,t)=>Qn(t),scope:`global`,detectPath:(e,t)=>M(nr({home:t})),projectConfigPath:e=>P(e,`.cursor`,`mcp.json`),projectSkillPath:e=>P(e,`.cursor`,`skills`,`open-knowledge`,`SKILL.md`)},codex:{id:`codex`,label:Jn.codex,configPath:(e,t)=>ir({home:t}),format:`toml`,topLevelKey:`mcp_servers`,serverName:()=>y,buildEntry:(e,t)=>Qn(t),scope:`global`,detectPath:(e,t)=>M(ir({home:t})),projectConfigPath:e=>P(e,`.codex`,`config.toml`),projectSkillPath:e=>P(e,`.agents`,`skills`,`open-knowledge`,`SKILL.md`)}};function ar(e){let t=e.filter(e=>!Object.hasOwn(Q,e));if(t.length>0)throw Error(`Unknown editor(s): ${t.join(`, `)}. Valid options: ${qn.join(`, `)}`);return e.map(e=>Q[e])}function $(e,t,n,r,i){let a=`urn:uuid:${me()}`;if(e.headersSent||e.writableEnded||e.destroyed){console.error(`[ok ui] emitProblem called after headers sent — suppressed`,{type:n,status:t,instance:a});return}let o={type:n,title:r,status:t,instance:a,...i===void 0?{}:{detail:i}},s=l.safeParse(o);if(!s.success){console.error(`[ok ui] emitProblem produced an invalid ProblemDetails body:`,{issues:s.error.issues,originalStatus:t,body:o}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-store`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:a}));return}e.writeHead(t,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-store`}),e.end(JSON.stringify(o))}const or=1e4;function sr(e,t){let n=e.socket?.remoteAddress;if(n!==void 0&&!f(n))return $(t,403,`urn:ok:error:loopback-required`,`Request must originate from a loopback address.`),!0;if(!g(e.headers.host))return $(t,403,`urn:ok:error:host-not-allowed`,`Host header is not in the loopback allowlist.`),!0;let r=e.headers.origin;return r!==void 0&&!S(r)?($(t,403,`urn:ok:error:invalid-origin`,`Origin header is not in the loopback allowlist.`),!0):!1}const cr=3e4;function lr(e,t){let n=e.socket?.remoteAddress;if(n!==void 0&&!f(n)||!g(e.headers.host))return t.destroy(),!0;let r=e.headers.origin;return typeof r==`string`&&!S(r)?(t.destroy(),!0):!1}function ur(e,t,n,r,i,a){a.add(t),t.once(`close`,()=>a.delete(t));let o=_e({host:r,port:i,timeout:or});a.add(o),o.once(`close`,()=>a.delete(o));let s=!1,c=n=>{if(!s){if(s=!0,n!==void 0){let t=n.err;console.warn(JSON.stringify({event:n.event,upstreamHost:r,upstreamPort:i,url:e.url,code:t instanceof Error?t.code:void 0,message:t instanceof Error?t.message:void 0}))}try{o.destroy()}catch{}try{t.destroy()}catch{}}};o.once(`connect`,()=>{o.setTimeout(0);let a=[`${e.method??`GET`} ${e.url??`/`} HTTP/1.1`,`host: ${r}:${i}`];for(let[t,n]of Object.entries(e.headers))if(t.toLowerCase()!==`host`&&n!==void 0)if(Array.isArray(n))for(let e of n)a.push(`${t}: ${e}`);else a.push(`${t}: ${n}`);try{o.write(`${a.join(`\r
|
|
276
|
-
`)}\r\n\r\n`),n.length>0&&o.write(n)}catch(e){c({event:`proxy-upgrade-handshake-write-failed`,err:e});return}o.on(`data`,e=>{t.writable&&t.write(e)}),t.on(`data`,e=>{o.writable&&o.write(e)})}),o.once(`timeout`,()=>{c({event:`proxy-upgrade-upstream-connect-timeout`})}),o.on(`error`,e=>c({event:`proxy-upgrade-upstream-error`,err:e})),t.on(`error`,e=>c({event:`proxy-upgrade-client-error`,err:e})),o.once(`close`,()=>c()),t.once(`close`,()=>c())}const dr=[`connection`,`keep-alive`,`proxy-authenticate`,`proxy-authorization`,`te`,`trailer`,`transfer-encoding`,`upgrade`,`cookie`,`set-cookie`];async function fr(e){let t=e.upstreamTimeoutMs??or,n=new Set,r=he((n,r)=>{sr(n,r)||mr(n,r,e.upstreamHost,e.upstreamPort,t)});r.on(`upgrade`,(t,r,i)=>{lr(t,r)||ur(t,r,i,e.upstreamHost,e.upstreamPort,n)}),await new Promise((t,n)=>{let i=e=>n(e);r.once(`error`,i),r.listen(e.listenPort,e.host,()=>{r.off(`error`,i),t()})});let i=r.address();return{httpServer:r,port:typeof i==`object`&&i?i.port:e.listenPort,close:()=>new Promise(e=>{for(let e of n)try{e.destroy()}catch{}n.clear(),r.close(()=>e()),r.closeIdleConnections()})}}function pr(e,t,n){mr(e,t,n.upstreamHost,n.upstreamPort,n.upstreamTimeoutMs??or)}function mr(e,t,n,r,i){let a={...e.headers};delete a.host;for(let e of dr)delete a[e];e.setTimeout(cr,()=>{if(t.headersSent)try{t.end()}catch{}else try{$(t,408,`urn:ok:error:request-timeout`,`Proxy request exceeded the per-request deadline.`,`Slow-loris-class: client did not finish within ${cr/1e3}s.`)}catch{}try{e.socket?.destroy()}catch{}});let o=ge({host:n,port:r,method:e.method,path:e.url,headers:{...a,host:`${n}:${r}`}},e=>{let n={...e.headers};for(let e of dr)delete n[e];t.writeHead(e.statusCode??502,n),e.pipe(t),e.once(`error`,()=>{try{t.end()}catch{}})});i>0&&o.setTimeout(i,()=>{if(!t.headersSent)$(t,504,`urn:ok:error:gateway-timeout`,`Upstream did not respond before the gateway deadline.`,`Upstream timeout: ${i/1e3}s elapsed without a response.`);else try{t.end()}catch{}o.destroy()}),o.on(`error`,()=>{if(!t.headersSent)$(t,502,`urn:ok:error:collab-server-not-running`,`Collab server is unreachable.`,`Upstream connection failed or dropped before a response was received.`);else try{t.end()}catch{}}),e.on(`error`,()=>{o.destroy()}),e.pipe(o)}const hr=39847,gr=39848;async function _r(e){await Promise.all(e.map(e=>new Promise(t=>{e.close(()=>t())})))}async function vr(e){let{existsSync:t}=await import(`node:fs`),{createServer:n}=await import(`node:http`),{resolve:r}=await import(`node:path`),{acquireUiLock:i,createAssetServeMiddleware:s,createContentFilter:l,readServerLock:u,releaseUiLock:f,updateUiLockPort:p}=await import(`./dist-
|
|
276
|
+
`)}\r\n\r\n`),n.length>0&&o.write(n)}catch(e){c({event:`proxy-upgrade-handshake-write-failed`,err:e});return}o.on(`data`,e=>{t.writable&&t.write(e)}),t.on(`data`,e=>{o.writable&&o.write(e)})}),o.once(`timeout`,()=>{c({event:`proxy-upgrade-upstream-connect-timeout`})}),o.on(`error`,e=>c({event:`proxy-upgrade-upstream-error`,err:e})),t.on(`error`,e=>c({event:`proxy-upgrade-client-error`,err:e})),o.once(`close`,()=>c()),t.once(`close`,()=>c())}const dr=[`connection`,`keep-alive`,`proxy-authenticate`,`proxy-authorization`,`te`,`trailer`,`transfer-encoding`,`upgrade`,`cookie`,`set-cookie`];async function fr(e){let t=e.upstreamTimeoutMs??or,n=new Set,r=he((n,r)=>{sr(n,r)||mr(n,r,e.upstreamHost,e.upstreamPort,t)});r.on(`upgrade`,(t,r,i)=>{lr(t,r)||ur(t,r,i,e.upstreamHost,e.upstreamPort,n)}),await new Promise((t,n)=>{let i=e=>n(e);r.once(`error`,i),r.listen(e.listenPort,e.host,()=>{r.off(`error`,i),t()})});let i=r.address();return{httpServer:r,port:typeof i==`object`&&i?i.port:e.listenPort,close:()=>new Promise(e=>{for(let e of n)try{e.destroy()}catch{}n.clear(),r.close(()=>e()),r.closeIdleConnections()})}}function pr(e,t,n){mr(e,t,n.upstreamHost,n.upstreamPort,n.upstreamTimeoutMs??or)}function mr(e,t,n,r,i){let a={...e.headers};delete a.host;for(let e of dr)delete a[e];e.setTimeout(cr,()=>{if(t.headersSent)try{t.end()}catch{}else try{$(t,408,`urn:ok:error:request-timeout`,`Proxy request exceeded the per-request deadline.`,`Slow-loris-class: client did not finish within ${cr/1e3}s.`)}catch{}try{e.socket?.destroy()}catch{}});let o=ge({host:n,port:r,method:e.method,path:e.url,headers:{...a,host:`${n}:${r}`}},e=>{let n={...e.headers};for(let e of dr)delete n[e];t.writeHead(e.statusCode??502,n),e.pipe(t),e.once(`error`,()=>{try{t.end()}catch{}})});i>0&&o.setTimeout(i,()=>{if(!t.headersSent)$(t,504,`urn:ok:error:gateway-timeout`,`Upstream did not respond before the gateway deadline.`,`Upstream timeout: ${i/1e3}s elapsed without a response.`);else try{t.end()}catch{}o.destroy()}),o.on(`error`,()=>{if(!t.headersSent)$(t,502,`urn:ok:error:collab-server-not-running`,`Collab server is unreachable.`,`Upstream connection failed or dropped before a response was received.`);else try{t.end()}catch{}}),e.on(`error`,()=>{o.destroy()}),e.pipe(o)}const hr=39847,gr=39848;async function _r(e){await Promise.all(e.map(e=>new Promise(t=>{e.close(()=>t())})))}async function vr(e){let{existsSync:t}=await import(`node:fs`),{createServer:n}=await import(`node:http`),{resolve:r}=await import(`node:path`),{acquireUiLock:i,createAssetServeMiddleware:s,createContentFilter:l,readServerLock:u,releaseUiLock:f,updateUiLockPort:p}=await import(`./dist-D-rWIekL.mjs`),{default:m}=await import(`./build-DxnNKCqf.mjs`),{resolveContentDir:h,resolveLockDir:g}=await import(`./dist-D-rWIekL.mjs`),_=h(e.config,e.cwd),v=g(e.cwd);i(v,{port:0,worktreeRoot:e.cwd});let y=import.meta.dirname??new URL(`.`,import.meta.url).pathname,b=[r(y,`public`),r(y,`../../app/dist`),r(y,`../../../app/dist`)].find(e=>t(e)),x=b?m(b,{single:!0,gzip:!0,immutable:!0,extensions:[]}):null,S=t(_)?s({contentFilter:l({projectDir:e.cwd,contentDir:_}),contentSirv:m(_,{dotfiles:!1,dev:!0,extensions:[]}),inlineExtensions:o,assetExtensions:d,blocklistExtensions:a}):null,C=e.port,w=null,T=(e,t)=>{let n=e.url?.split(`?`)[0];if((n===`/`||n===``)&&(e.url=`/index.html`),!(n?.startsWith(`/api/`)&&sr(e,t))){if(n===`/api/config`&&(e.method===`GET`||e.method===`HEAD`)){w?.();let n=u(v),r=e.headers.host??`localhost:${C}`,i=n&&n.port>0?`ws://${r}/collab`:null,a=JSON.stringify({collabUrl:i,previewUrl:null,port:C});t.setHeader(`Content-Type`,`application/json`),t.setHeader(`Cache-Control`,`no-store`),t.setHeader(`X-Content-Type-Options`,`nosniff`),t.statusCode=200,e.method===`HEAD`?t.end():t.end(a);return}if(n?.startsWith(`/api/`)){w?.();let r=u(v);if(!r||r.port<=0){$(t,503,`urn:ok:error:collab-server-not-running`,"Collab server not running. Start `ok start` or run `ok status`.",`Path: ${n}`);return}pr(e,t,{upstreamHost:`localhost`,upstreamPort:r.port});return}if(x&&n?.startsWith(`/assets/`)){x(e,t,()=>{S?S(e,t,()=>yr(t,n)):yr(t,n)});return}if(S){S(e,t,()=>{x?x(e,t):yr(t,n)});return}if(x){x(e,t);return}yr(t,n)}},E=new Set,D=(e,t,n)=>{if(lr(e,t))return;let r=e.url?.split(`?`)[0]??``;if(r!==`/collab`&&!r.startsWith(`/collab/`)){t.destroy();return}let i=u(v);if(!i||i.port<=0){console.warn(JSON.stringify({event:`ok-ui-upgrade-no-collab-lock`,url:r,reason:"server.lock missing or port unbound — is `ok start` running?"})),t.destroy();return}ur(e,t,n,`localhost`,i.port,E)},O=()=>{for(let e of E)try{e.destroy()}catch{}E.clear()},ee=e.host===void 0?[`::1`,`127.0.0.1`]:[e.host],k=[],A=e.port,te=e=>e instanceof Error&&e.code===`EADDRINUSE`,ne=async()=>{await Promise.all(k.splice(0).map(e=>new Promise(t=>{try{e.close(()=>t())}catch{t()}})))},re=async e=>{A=e;for(let e of ee){let t=n(T);t.on(`upgrade`,D),k.push(t),await new Promise((n,r)=>{let i=e=>r(e);t.once(`error`,i),t.listen(A,e,()=>{t.off(`error`,i);let e=t.address();typeof e==`object`&&e&&(A=e.port),n()})})}};try{try{await re(e.port)}catch(t){if(e.fallbackToKernel===!0&&te(t))await ne(),await re(0);else throw t}}catch(e){await ne();try{f(v)}catch{}throw e}let ie=A;C=ie,p(v,ie);let j=e.scheduler??c,M=e.safetyNetMs??432e5,N=null,P=!1,ae=!1,F=()=>{P||(P=!0,N!==null&&(j.clearTimeout(N),N=null))},I=()=>{if(F(),!ae){ae=!0;try{f(v)}catch{}}},L=()=>{P||M<=0||(N!==null&&(j.clearTimeout(N),N=null),N=j.setTimeout(()=>{N=null,console.warn(`[ui] safety-net (${M}ms) reached — shutting down (D-025 backstop)`);try{e.onSafetyNet?.()}catch{}O();for(let e of k)try{e.close()}catch{}I()},M))},R=()=>{P||M<=0||L()};return w=R,L(),{httpServers:k,port:ie,release:I,detachSafetyNet:F,nudgeSafetyNet:R,drainUpgradeSockets:O}}function yr(e,t){$(e,404,`urn:ok:error:not-found`,`Resource not found.`,t===void 0?void 0:`Path: ${t}`)}function br(e,t){if(e!==void 0){let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<0||t>65535)throw Error(`Invalid --port value '${e}'`);return{port:t,fallbackToKernel:!1}}if(t!==void 0&&t!==``){let e=Number.parseInt(t,10);if(Number.isNaN(e)||e<0||e>65535)throw Error(`Invalid PORT env value '${t}'`);return{port:e,fallbackToKernel:!1}}return{port:hr,fallbackToKernel:!0}}async function xr(e){let t=e.readLock??(async()=>{let{readUiLock:t}=await import(`./dist-D-rWIekL.mjs`);return t(e.lockDir)}),n=await t();if(!n)throw Error(`UI lock collision reported but the lock disappeared before handling — retry acquiring.`);if(n.port===e.requestedPort&&n.port>0)return{mode:`already-running`,port:n.port};let r=n.port;if(r===0){let n=Date.now()+(e.pollDeadlineMs??2e3),i=e.pollIntervalMs??100;for(;Date.now()<n;){await new Promise(e=>{setTimeout(e,i)});let e=await t();if(e&&e.port>0){r=e.port;break}}if(r===0)throw Error("UI did not bind within 2s; run `ok clean`");if(r===e.requestedPort)return{mode:`already-running`,port:r}}return{mode:`proxy`,handle:await fr({listenPort:e.requestedPort,host:e.host,upstreamHost:`localhost`,upstreamPort:r}),upstreamPort:r}}function Sr(e){return new i(`ui`).description(`Serve the Open Knowledge React editor UI`).option(`-p, --port <port>`,`UI port (default: $PORT env or ${hr}, kernel-allocated fallback if busy)`).option(`-H, --host <host>`,"UI host. Default: two-socket loopback bind (`[::1]` + `127.0.0.1`) so cross-family collisions fail loud. Pass an explicit host (e.g. `127.0.0.1`, `0.0.0.0`) to bind a single socket on that host.").action(async t=>{let{dim:n}=await import(`./colors-t2HkW8lF.mjs`),{UiLockCollisionError:r}=await import(`./dist-D-rWIekL.mjs`),{resolveLockDir:i}=await import(`./dist-D-rWIekL.mjs`),a=e(),o=t.host,s;try{s=br(t.port,process.env.PORT)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=1;return}let c=s.port;try{let e=await vr({config:a,cwd:process.cwd(),port:c,fallbackToKernel:s.fallbackToKernel,host:o}),t=o===void 0||o===`::`||o===`0.0.0.0`?`localhost`:o;console.log(`${n(`[ui]`)} listening on http://${t}:${e.port}`);let r=!1,i=t=>{if(r)return;r=!0,console.log(n(`\n[ui] Shutting down (${t})`)),e.detachSafetyNet();let i=()=>{try{e.release()}finally{process.exit(process.exitCode??0)}};e.drainUpgradeSockets(),_r(e.httpServers).then(i,i),setTimeout(i,2e3).unref()};process.once(`SIGINT`,()=>i(`SIGINT`)),process.once(`SIGTERM`,()=>i(`SIGTERM`));return}catch(e){if(!(e instanceof r))throw e;let t=i(process.cwd()),a=o??`localhost`,s;try{s=await xr({requestedPort:c,host:a,lockDir:t})}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}if(s.mode===`already-running`){if(console.log(`UI already running at http://${a}:${s.port}`),Cr(process)){await new Promise(e=>{let t=t=>{console.log(n(`\n[ui-keepalive] Shutting down (${t})`)),e()};process.once(`SIGINT`,()=>t(`SIGINT`)),process.once(`SIGTERM`,()=>t(`SIGTERM`))});return}process.exit(0)}console.log(`UI running at http://${a}:${s.upstreamPort}; acting as HTTP proxy on port ${s.handle.port}`);let l=!1,u=e=>{l||(l=!0,console.log(n(`\n[ui-proxy] Shutting down (${e})`)),s.handle.close().finally(()=>process.exit(process.exitCode??0)),setTimeout(()=>process.exit(process.exitCode??0),2e3).unref())};process.once(`SIGINT`,()=>u(`SIGINT`)),process.once(`SIGTERM`,()=>u(`SIGTERM`))}})}function Cr(e){let t=e.stdout.isTTY===!0,n=typeof e.env.PORT==`string`&&e.env.PORT!==``;return!t||n}function wr(e){if(!z(e))return{};let t=se(e,`utf-8`).trim();if(t===``)return{};try{let n=JSON.parse(t);if(T(n))return n;throw Error(`${e} root must be a JSON object`)}catch(t){throw t instanceof SyntaxError?Error(`${e} contains invalid JSON: ${t.message}`):t}}function Tr(e){if(!z(e))return{};let t=se(e,`utf-8`).trim();if(t===``)return{};try{let n=Nn(t);if(T(n))return n;throw Error(`${e} root must be a TOML table`)}catch(t){throw Error(`${e} contains invalid TOML: ${t instanceof Error?t.message:String(t)}`)}}function Er(e,t){C(e,`${JSON.stringify(t,null,2)}\n`)}function Dr(e,t){let n=Un(t);C(e,n.endsWith(`
|
|
277
277
|
`)?n:`${n}\n`)}const Or=e=>e!==`project`,kr=e=>e!==`user`;async function Ar(){let e=await ln({message:`Where should the MCP server be configured?
|
|
278
278
|
`,required:!1,theme:{icon:{checked:`[x]`,unchecked:`[ ]`}},choices:[{name:`User-level (~/.claude.json, ~/.cursor/mcp.json, …)`,value:`user`,checked:!0},{name:`Project-level (.mcp.json, .cursor/mcp.json, …)`,value:`project`,checked:!0}]});return e.includes(`user`)&&e.includes(`project`)?`both`:e.includes(`user`)?`user`:e.includes(`project`)?`project`:null}async function jr(e){return e.mcp===!1?null:e.scope?e.scope:e.isTTY??process.stdout.isTTY?(e.promptFn??Ar)():`both`}const Mr=`0.0.1`,Nr=`open-knowledge-ui`,Pr=[`-y`,`@inkeep/open-knowledge@latest`,`ui`];function Fr(e,t={}){let n=P(e,`.claude`,`launch.json`),r=t.mode===`dev`?{name:Nr,runtimeExecutable:`node`,runtimeArgs:[Zn(),`ui`],port:gr,autoPort:!0}:{name:Nr,runtimeExecutable:`npx`,runtimeArgs:[...Pr],port:gr,autoPort:!0};try{if(ne(n,e),!z(n))return oe(M(n),{recursive:!0}),le(n,`${JSON.stringify({version:Mr,configurations:[r]},null,2)}\n`,`utf-8`),{action:`created`,configPath:n};let t=se(n,`utf-8`).trim(),i=t?JSON.parse(t):{};if(!T(i))return{action:`failed`,configPath:n,error:`launch.json root is not an object`};let a=Array.isArray(i.configurations)?i.configurations:[],o=a.findIndex(e=>T(e)&&e.name===`open-knowledge-ui`);o>=0?a[o]=r:a.push(r);let s={...i,version:i.version??Mr,configurations:a};return le(n,`${JSON.stringify(s,null,2)}\n`,`utf-8`),{action:o>=0?`merged`:`created`,configPath:n}}catch(e){return{action:`failed`,configPath:n,error:e instanceof Error?e.message:String(e)}}}function Ir(e,t,n){try{return z(e.detectPath?.(t,n)??M(e.configPath(t,n)))}catch{return!1}}function Lr(e,t,n,r,i){let a=e.serverName(t),o;try{o=i??e.configPath(t,r)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:``,serverName:a,error:t instanceof Error?t.message:String(t)}}if(!i&&!n.skipAvailabilityCheck&&!Ir(e,t,r))return{editorId:e.id,label:e.label,action:`skipped-missing`,configPath:o,serverName:a};if(i!==void 0)try{ne(o,t)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:o,serverName:a,error:t instanceof Error?t.message:String(t),configScope:`project`}}let s;try{s=e.buildEntry(t,n)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:o,serverName:a,error:t instanceof Error?t.message:String(t),...i===void 0?{}:{configScope:`project`}}}try{oe(M(o),{recursive:!0})}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:o,serverName:a,error:t instanceof Error?t.message:String(t),...i===void 0?{}:{configScope:`project`}}}let c,l;try{h(`${o}.lock`,()=>{let t=e.format===`toml`?Tr(o):wr(o),n=t[e.topLevelKey]??{};c=n[a];let r={...t,[e.topLevelKey]:{...n,[a]:s}};e.format===`toml`?Dr(o,r):Er(o,r)},{onWarn:(e,t)=>process.stderr.write(`[ok] ${e} ${JSON.stringify(t)}\n`)})}catch(e){l=e instanceof Error?e:Error(String(e))}return l?{editorId:e.id,label:e.label,action:`failed`,configPath:o,serverName:a,error:l.message,...i===void 0?{}:{configScope:`project`}}:{editorId:e.id,label:e.label,action:c===void 0?`written`:`overwritten`,configPath:o,serverName:a,...i===void 0?{}:{configScope:`project`}}}function Rr(e,t){let n=e.projectConfigPath?.(t);if(!(!n||!z(n)))return{editorId:e.id,label:e.label,path:n}}async function zr(e){let t=ar(e.editors),n={mode:`published`,skipAvailabilityCheck:!0};return t.map(t=>Lr(t,``,n,e.home))}function Br(e,t,n,r){let i=Vr(e,t,n,r);return i.kind===`present`?i.entry:null}function Vr(e,t,n,r){let i;try{i=r??e.configPath(t,n)}catch{return{kind:`absent`}}if(!z(i))return{kind:`absent`};let a;try{a=se(i,`utf-8`)}catch(e){return{kind:`corrupt`,error:e instanceof Error?e.message:String(e)}}if(a.trim()===``)return{kind:`corrupt`,error:`file is empty`};let o;try{o=e.format===`toml`?Tr(i):wr(i)}catch(e){return{kind:`corrupt`,error:e instanceof Error?e.message:String(e)}}let s=o[e.topLevelKey];if(!T(s))return{kind:`no-entry`};let c=s[e.serverName(t)];return T(c)?{kind:`present`,entry:c}:{kind:`no-entry`}}async function Hr(e={}){let t=I(e.cwd??process.cwd()),n=Kn(t,{homeDir:e.home}),r=n.projectRoot,i=!z(P(r,`.ok`));n.ancestorPromoted?console.log(`[ok] Opened existing project at ${r}`):n.gitRootPromoted&&i&&console.log(`[ok] Initialized OK at ${r} — opened parent of ${F(r,t)} because it contains a .git folder`);let a={mode:e.devMcp?`dev`:`published`},o=await m(r),s;try{s=v(r,{contentDir:n.defaultContentDir})}catch(t){let n=Q.claude.configPath(r,e.home);return{projectRoot:r,contentCreated:[],contentUpdated:[],contentSkipped:[],editors:[],projectSkills:[],legacyProjectConfigs:[],didGitInit:o.didInit,rootGitignoreCreated:!1,claudeDesktopDetected:!1,mcpAction:`failed`,mcpPath:n,mcpError:`Content scaffolding failed: ${t instanceof Error?t.message:String(t)}`}}let c=!1;if(o.didInit)try{c=x(r)===`created`}catch(e){console.warn(`[ok] Skipping .gitignore seed at ${r}: ${e instanceof Error?e.message:String(e)}`)}let l=await jr({scope:e.scope,mcp:e.mcp,isTTY:e.isTTY,promptFn:e.promptFn}),u=e.editors??Wr(r,e.home),d=e.editors??qn.filter(e=>Q[e].projectConfigPath!==void 0),f=ar(u),h=ar(d),g=e.mcp===!1||l===null,y=Array.from(new Map([...f,...g?[]:h].map(e=>[e.id,e])).values()),b=f.filter(t=>Ir(t,r,e.home)),S=[],C=[],w=new Set;for(let t of y){if(g){let n=``;try{n=t.configPath(r,e.home)}catch{}S.push({editorId:t.id,label:t.label,action:`skipped-flag`,configPath:n,serverName:t.serverName(r)});continue}if(Or(l)&&f.includes(t)&&S.push(Lr(t,r,a,e.home)),kr(l)&&h.includes(t)&&t.projectConfigPath){let n=t.projectConfigPath(r),i=Lr(t,r,a,e.home,n);S.push(i),(i.action===`written`||i.action===`overwritten`)&&w.add(n)}}for(let e of h)e.projectSkillPath&&C.push(te(e,r));let T=!g&&l!==null&&kr(l)?h.filter(e=>!e.projectConfigPath).map(e=>e.label):void 0,E=g?[]:b.map(e=>Rr(e,r)).filter(e=>e!==void 0).filter(e=>!w.has(e.path)),D=b.some(e=>e.id===`claude`)&&!g?Fr(r,a):void 0,O=await(e.installUserSkill??_)({home:e.home}),ee=p({home:e.home}),k=g?`skipped-flag`:`skipped-missing`,A=S.find(e=>e.editorId===`claude`)??S[0]??{action:k,configPath:Q.claude.configPath(r,e.home)};return{projectRoot:r,contentCreated:s.created,contentUpdated:s.updated,contentSkipped:s.skipped,editors:S,projectSkills:C,legacyProjectConfigs:E,launchJson:D,skillInstall:O,didGitInit:o.didInit,rootGitignoreCreated:c,claudeDesktopDetected:ee,mcpAction:A.action,mcpPath:A.configPath,mcpError:`error`in A?A.error:void 0,projectScopeUnsupportedLabels:T}}function Ur(e,t){let n=[],r=e.editors.some(e=>e.action===`written`||e.action===`overwritten`),i=e.editors.some(e=>e.action===`failed`)||e.projectSkills.some(e=>e.action===`failed`),a=e.editors.length>0&&e.editors.every(e=>e.action===`skipped-flag`),o=e.editors.length>0&&e.editors.every(e=>e.action===`skipped-missing`),s=e=>{let n=e.configPath.startsWith(t)?F(t,e.configPath):e.configPath;switch(e.action){case`created`:return` app preview server ${n} configured for Claude Code Desktop embedded browser`;case`merged`:return` app preview server ${n} updated for Claude Code Desktop embedded browser`;case`failed`:return` app preview server ${n} FAILED: ${e.error}`}};e.didGitInit&&n.push(`Initialized git repo at ${t}/.git/ (default branch: main)`),e.rootGitignoreCreated&&n.push(`Seeded .gitignore at ${t}/.gitignore (.DS_Store)`);let c=P(t,`.ok`);if(e.contentCreated.length>0||e.contentUpdated.length>0?(n.push(k(`Content scaffolded at ${c}/`)),e.contentCreated.length>0&&n.push(` Created: ${e.contentCreated.join(`, `)}`),e.contentUpdated.length>0&&n.push(` Updated: ${e.contentUpdated.join(`, `)}`)):n.push(k(`Content already present at ${c}/`)),e.contentSkipped.length>0&&n.push(` Skipped (already exist): ${e.contentSkipped.join(`, `)}`),n.push(``),e.mcpError&&e.editors.length===0)n.push(`Warning: ${e.mcpError}`);else if(e.editors.length===0)if(n.push(k(`MCP server configuration:`)),e.mcpAction===`skipped-flag`)n.push(` MCP config not written — use without --no-mcp to configure editors`);else if(e.projectScopeUnsupportedLabels&&e.projectScopeUnsupportedLabels.length>0){let t=e.projectScopeUnsupportedLabels.join(`, `),r=e.projectScopeUnsupportedLabels.length===1?`does`:`do`;n.push(` ${t} ${r} not support project-level config; skipped`)}else n.push(` No supported editor config directories detected; skipped MCP registration`);else if(a)n.push(`MCP config not written — use without --no-mcp to configure editors`);else if(o)n.push(k(`MCP server configuration:`)),n.push(` No supported editor config directories detected; skipped MCP registration`);else{n.push(k(`MCP server configuration:`));for(let r of e.editors){let i=r.configPath.startsWith(t)?F(t,r.configPath):r.configPath.replace(/^\/Users\/[^/]+/,`~`),a=r.serverName===`open-knowledge`?``:` (${r.serverName})`,o=r.configScope===`project`?` (project)`:``,c=`${r.label}${o}`,l=` `.repeat(Math.max(1,20-c.length)),u=r.editorId===`claude-desktop`&&(r.action===`written`||r.action===`overwritten`)?` — quit and relaunch Claude Desktop to activate`:``;switch(r.action){case`written`:n.push(` ${c}${l}${i} ${D(`registered`)}${a}${u}`);break;case`overwritten`:n.push(` ${c}${l}${i} ${D(`updated`)}${a}${u}`);break;case`skipped-missing`:n.push(` ${c}${l}${i} config root missing; skipped`);break;case`failed`:n.push(` ${c}${l}${i} ${O(`FAILED`)}: ${r.error}`);break;case`skipped-flag`:break}r.editorId===`claude`&&e.launchJson&&n.push(s(e.launchJson))}if(e.projectScopeUnsupportedLabels&&e.projectScopeUnsupportedLabels.length>0){let t=e.projectScopeUnsupportedLabels.join(`, `),r=e.projectScopeUnsupportedLabels.length===1?`does`:`do`;n.push(` ${t} ${r} not support project-level config; skipped`)}}if(e.projectSkills.length>0){n.push(``),n.push(k(`Project-local skills:`));for(let r of e.projectSkills){let e=`${r.label} (project)`,i=` `.repeat(Math.max(1,20-e.length)),a=r.path?F(t,r.path):``;switch(r.action){case`written`:n.push(` ${e}${i}${a} ${D(`installed`)}`);break;case`overwritten`:n.push(` ${e}${i}${a} ${D(`updated`)}`);break;case`skipped-unsupported`:n.push(` ${e}${i}no known project skill surface; skipped`);break;case`failed`:n.push(` ${e}${i}${a} ${O(`FAILED`)}: ${r.error}`);break}}}if(i&&(n.push(``),n.push(`For failed editors, add the MCP server entry or project skill manually. See:`),n.push(` https://github.com/inkeep/open-knowledge#mcp-setup`)),e.legacyProjectConfigs.length>0){n.push(``),n.push(`Project MCP configs found:`);for(let r of e.legacyProjectConfigs)n.push(` ${r.label} ${F(t,r.path)}`);n.push(` These project-local files may override the global config. Remove them if you want fully user-scoped MCP setup in this project.`)}if(e.skillInstall)switch(n.push(``),n.push(k(`User-global skill:`)),e.skillInstall){case`installed`:n.push(` open-knowledge ${D(`installed to detected agent hosts`)} via \`npx skills\``);break;case`skip-current`:n.push(` open-knowledge ${D(`already installed at current version`)}`);break;case`failed`:n.push(` ${ee(`open-knowledge install failed — MCP still configured; run manually:`)}`),n.push(` ${ee(` npx skills@~1.5.0 add <bundled-path> --agent '*' -g -y --copy`)}`);break}if(e.claudeDesktopDetected&&(n.push(``),n.push(`Claude Desktop App detected. To enable in Claude Chat & Cowork, run: ${k(`ok install-skill`)}`)),e.preview?(n.push(``),n.push(A(e.preview,t))):e.previewWarning&&(n.push(``),n.push(`Content preview unavailable: ${e.previewWarning}`)),r){let t=new Set,r=e.editors.filter(e=>e.action===`written`||e.action===`overwritten`).filter(e=>!t.has(e.editorId)&&t.add(e.editorId)).map(e=>e.label);n.push(``),n.push(`${D(`✓`)} ${k(`Next steps:`)}`),n.push(` 1. Open your editor (${E(r.join(` / `))})`),n.push(` 2. Approve the MCP server when prompted`),n.push(` 3. (Optional) scaffold the starter knowledge-base structure:`),n.push(` - ${E(`ok seed`)} — empty repo, Karpathy 3-layer`),n.push(` - ${E(`mcp__open-knowledge__discover`)} — existing repo, extract conventions`),n.push(` 4. Use the MCP workflow tools as you build the wiki:`),n.push(` - ${E(`mcp__open-knowledge__ingest`)} — capture an external source`),n.push(` - ${E(`mcp__open-knowledge__research`)} — gather sources and write findings`),n.push(` - ${E(`mcp__open-knowledge__consolidate`)} — promote research to canonical articles`)}return n.join(`
|
|
279
279
|
`)}function Wr(e,t){let n=[];for(let r of qn)Ir(Q[r],e,t)&&n.push(r);return n}function Gr(){return new i(`init`).description(`Scaffold .ok/ in the current directory and register the MCP server for your editor(s)`).option(`--mcp`,`Register the MCP server for selected editors (default: true)`,!0).option(`--no-mcp`,`Scaffold the .ok/ directory but do not touch MCP config`).option(`--dev-mcp`,`Register a local dev MCP entry using node + packages/cli/dist/cli.mjs with debug logging`).addOption(new r(`--scope <scope>`,`Write MCP config at user level, project level, or both`).choices([`user`,`project`,`both`])).action(async e=>{let t=process.cwd(),n;try{n=await Hr({cwd:t,mcp:e.mcp,devMcp:e.devMcp,scope:e.scope})}catch(e){if(e instanceof w){process.stderr.write(`open-knowledge requires git to initialize a parent repo. Install git or run 'git init' yourself, then re-run.
|
|
280
|
-
`),e.stderr&&process.stderr.write(`${e.stderr.trim()}\n`),process.exitCode=1;return}throw e}try{let{previewContent:e}=await import(`./preview-
|
|
281
|
-
//# sourceMappingURL=init-
|
|
280
|
+
`),e.stderr&&process.stderr.write(`${e.stderr.trim()}\n`),process.exitCode=1;return}throw e}try{let{previewContent:e}=await import(`./preview-CcHJG_2a.mjs`),{loadConfig:t}=await import(`./loader-BIxKasBW.mjs`),{resolveContentDir:r}=await import(`./dist-D-rWIekL.mjs`),{config:i}=t(n.projectRoot),a=r(i,n.projectRoot);n.preview=e({projectDir:n.projectRoot,contentDir:a})}catch(e){n.previewWarning=e instanceof Error?e.message:String(e)}process.stdout.write(`${Ur(n,n.projectRoot)}\n`),(n.editors.some(e=>e.action===`failed`)||n.mcpAction===`failed`)&&(process.exitCode=1)})}export{U as A,ft as C,Je as D,at as E,qe as O,lt as S,mt as T,Qn as _,Ur as a,dt as b,jr as c,Lr as d,zr as f,Q as g,Jn as h,Wr as i,we as k,Hr as l,qn as m,Pr as n,Gr as o,Sr as p,Vr as r,Br as s,Nr as t,Fr as u,Xn as v,ut as w,ct as x,Kn as y};
|
|
281
|
+
//# sourceMappingURL=init-BrOIE7gK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./loader-CxaZzLDi.mjs";export{e as loadConfig};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Si as e,da as t,zr as n}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{bi as r,p as i,xi as a}from"./dist-
|
|
1
|
+
import{Si as e,da as t,zr as n}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{bi as r,p as i,xi as a}from"./dist-DKgq69uI.mjs";import{t as o}from"./constants-D9hc7LX4.mjs";import{t as s}from"./is-object-C-4FJ0rP.mjs";import{resolve as c}from"node:path";import{existsSync as l,readFileSync as u}from"node:fs";import{realpath as d}from"node:fs/promises";async function f(e){let t=c(e);try{return await d(t)}catch(e){if(e.code!==`ENOENT`){let n=e instanceof Error?e.message:String(e);console.warn(`[normalize-cwd] realpath failed for ${t}: ${n}`)}return t}}var p=t();function m(e,t){let n={...e};for(let r of Object.keys(t)){let i=e[r],a=t[r];s(a)&&s(i)?n[r]=m(i,a):a!==void 0&&(n[r]=a)}return n}function h(e){if(!l(e))return{value:null,path:e,source:null,doc:null};let t;try{t=u(e,`utf-8`)}catch(t){return console.warn(`[config] Failed to read ${e}: ${t instanceof Error?t.message:t}`),{value:null,path:e,source:null,doc:null}}let n=(0,p.parseDocument)(t);if(n.errors.length>0)return console.warn(`[config] Failed to parse ${e}: ${n.errors.map(e=>e.message).join(`; `)}`),{value:null,path:e,source:t,doc:null};let r=n.toJSON();return s(r)?{value:r,path:e,source:t,doc:n}:{value:null,path:e,source:t,doc:n}}const g=[`include`,`exclude`];function _(e){let t="Run `ok config migrate` to strip the obsolete key from config.yml automatically, or remove it by hand.";return e===`exclude`?[`Move these patterns to .okignore at the project root (gitignore syntax, 1:1 migration).`,t].join(` `):[`content.include has been removed.`,`For subdirectory scoping, set content.dir in .ok/config.yml instead.`,`For pattern-based filtering, use .okignore (gitignore syntax — exclude-only; do not copy include patterns directly).`,t].join(` `)}function v(t){let n=t.value;if(!s(n))return[];let r=n.content;if(!s(r))return[];let i=[];for(let n of g)if(n in r){let r=[`content`,n],a;t.doc!==null&&t.source!==null&&(a=e({file:t.path,source:t.source,doc:t.doc,path:r})),i.push({code:`REMOVED_KEY`,path:r,redirect:_(n),...a===void 0?{}:{source:a}})}return i}function y(t,n){return t.map(t=>{let r=t.path.map(e=>typeof e==`symbol`?String(e):e),i={path:r,message:t.message,issueCode:t.code};if(n.doc!==null&&n.source!==null){let t=e({file:n.path,source:n.source,doc:n.doc,path:r});if(t!==void 0)return{...i,source:t}}return i})}function b(e){let t=e??process.cwd(),s=[],l=a(`user`,t),u=r({absPath:l}),d={};u.valid&&u.source!==void 0?(d=m(d,u.value),s.push(l)):u.valid;let f=c(t,`.ok`,o),p=h(f);if(p.value!==null){let e=v(p);if(e.length>0)throw Error(e.map(n).join(`
|
|
2
2
|
|
|
3
3
|
`));d=m(d,p.value),s.push(f)}x(d,[`upload`,`maxBytes`],`streaming uploads have no user-facing cap`),x(d,[`github`,`oauthAppClientId`],`use the OPEN_KNOWLEDGE_GITHUB_CLIENT_ID env var instead`),x(d,[`server`,`host`],`use the --host flag or HOST env var instead`),x(d,[`server`,`openOnAgentEdit`]),x(d,[`mcp`,`autoStart`],`to disable auto-start, set OK_MCP_AUTOSTART=0`),x(d,[`mcp`,`tools`,`read_document`,`historyDepth`]),x(d,[`mcp`,`tools`,`grep`,`maxResults`]),x(d,[`mcp`,`tools`,`search`,`maxResults`]),x(d,[`preview`,`baseUrl`],"preview URLs now resolve only to the running UI process — start one with `ok ui`");let g=i.safeParse(d);if(!g.success){let e={code:`SCHEMA_INVALID`,issues:y(g.error.issues,p)};throw Error(n(e))}return{config:g.data,sources:s}}function x(e,t,n){let r=e;for(let e=0;e<t.length-1;e++){if(!s(r))return;r=r[t[e]]}if(!s(r))return;let i=t[t.length-1];if(r[i]===void 0)return;let a=t.join(`.`);console.warn(`[config] ${a} is no longer user-configurable; ${n??`the value is hardcoded in @inkeep/open-knowledge-core`}. Remove the key to silence this warning.`)}function S(e){let t=e.cacheMs??1e3,n=e.loadConfigFn??b,r=new Map,i=new Map,a=f(e.startupCwd);return async o=>{let s=await f(o??e.startupCwd),c=Date.now(),l=r.get(s);if(l&&l.expiresAt>c)return l.config;let u=i.get(s);if(u)return await u;let d=(async()=>{if(s===await a)return r.set(s,{config:e.startupConfig,expiresAt:Date.now()+t}),e.startupConfig;let i=n(s).config;return r.set(s,{config:i,expiresAt:Date.now()+t}),i})();i.set(s,d);try{return await d}finally{i.delete(s)}}}export{b as n,S as t};
|
|
4
|
-
//# sourceMappingURL=loader-
|
|
4
|
+
//# sourceMappingURL=loader-CxaZzLDi.mjs.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{At as e}from"./dist-
|
|
1
|
+
import{At as e}from"./dist-DKgq69uI.mjs";import"./constants-D9hc7LX4.mjs";import{join as t,relative as n}from"node:path";import{existsSync as r,lstatSync as i,readdirSync as a,realpathSync as o,statSync as s}from"node:fs";function c(r){let{projectDir:c,contentDir:l,sampleCap:u=5}=r,d=[],f=[];try{i(l)}catch(e){return{totalCount:0,sample:[],contentDir:l,warnings:[`cannot access content directory ${l}: ${e instanceof Error?e.message:String(e)}`]}}let p;try{p=e({projectDir:c,contentDir:l})}catch(e){return{totalCount:0,sample:[],contentDir:l,warnings:[e instanceof Error?e.message:String(e)]}}function m(e){let r;try{r=a(e,{withFileTypes:!0})}catch(t){let r=t instanceof Error?t.message:String(t);d.push(`could not read directory ${n(l,e)||`.`}: ${r}`);return}for(let i of r){let r=t(e,i.name);if(i.isSymbolicLink()){let e;try{e=o(r)}catch(e){let t=e.code;t===`ENOENT`||t===`ELOOP`?d.push(`broken or cyclic symlink: ${n(l,r)}`):d.push(`cannot resolve symlink ${n(l,r)}: ${t??`unknown error`}`);continue}let t;try{t=s(e)}catch{continue}if(t.isDirectory()){let e=n(l,r);if(p.isDirExcluded(e))continue;m(r)}else if(t.isFile()){let e=n(l,r);if(p.isExcluded(e))continue;f.push(e)}}else if(i.isDirectory()){let e=n(l,r);if(p.isDirExcluded(e))continue;m(r)}else if(i.isFile()){let e=n(l,r);if(p.isExcluded(e))continue;f.push(e)}}}return m(l),{totalCount:f.length,sample:f.slice(0,u),contentDir:l,warnings:d}}function l(e,i){let a=[],o=n(i,e.contentDir),s=o===``?`./`:`./${o}`;if(a.push(`Content:`),a.push(` Found ${e.totalCount} markdown files in ${s}`),e.sample.length>0){let t=e.sample.join(`, `),n=e.totalCount>e.sample.length?`, …`:``;a.push(` Sample: ${t}${n}`)}if(e.warnings.length>0)for(let t of e.warnings)a.push(` Warning: ${t}`);return a.push(``),r(t(i,`.ok`,`config.yml`))?(a.push(` To adjust scope, add patterns to .okignore at the project root.`),a.push(` To change the content root, edit .ok/config.yml → content.dir.`)):a.push(" Run `open-knowledge init` to scaffold config + .okignore."),a.push(``),a.push(` Re-check anytime: open-knowledge preview`),a.join(`
|
|
2
2
|
`)}export{c as n,l as t};
|
|
3
|
-
//# sourceMappingURL=preview-
|
|
3
|
+
//# sourceMappingURL=preview-BGoO3Ogd.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e,t}from"./preview-BGoO3Ogd.mjs";export{t as formatPreviewBlock,e as previewContent};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e,u as t}from"./init-
|
|
2
|
-
//# sourceMappingURL=repair-launch-json-
|
|
1
|
+
import{n as e,u as t}from"./init-BrOIE7gK.mjs";import{t as n}from"./is-object-C-4FJ0rP.mjs";import{join as r}from"node:path";import{existsSync as i,readFileSync as a}from"node:fs";const o=[[`@inkeep/open-knowledge`,`ui`],[`-y`,`@inkeep/open-knowledge`,`ui`]];function s(t){if(t.runtimeExecutable!==`npx`||!Array.isArray(t.runtimeArgs))return`preserved`;if(c(t.runtimeArgs,e))return`canonical`;for(let e of o)if(c(t.runtimeArgs,e))return`legacy-bare`;return`preserved`}function c(e,t){if(e.length!==t.length)return!1;for(let n=0;n<t.length;n++)if(e[n]!==t[n])return!1;return!0}function l(e){let o=e.logger??u,c=r(e.projectDir,`.claude`,`launch.json`);if(e.reclaimDisableEnv===`1`)return o({event:`launch-json-repair-skipped`,reason:`reclaim-disabled`}),{outcome:{configPath:c,outcome:`skipped-reclaim-disabled`},repairedCount:0};if(!i(c))return{outcome:{configPath:c,outcome:`no-file`},repairedCount:0};let l;try{let e=a(c,`utf-8`).trim();l=e?JSON.parse(e):{}}catch(e){let t=e instanceof Error?e.message:String(e);return o({event:`launch-json-repair-read-failed`,configPath:c,error:t}),{outcome:{configPath:c,outcome:`read-failed`,error:t},repairedCount:0}}if(!n(l)){let e=`launch.json root is not an object`;return o({event:`launch-json-repair-read-failed`,configPath:c,error:e}),{outcome:{configPath:c,outcome:`read-failed`,error:e},repairedCount:0}}let d=l.configurations;if(!Array.isArray(d))return{outcome:{configPath:c,outcome:`no-entry`},repairedCount:0};let f=d.find(e=>n(e)&&e.name===`open-knowledge-ui`);if(!f)return{outcome:{configPath:c,outcome:`no-entry`},repairedCount:0};let p=s(f);if(p===`canonical`)return{outcome:{configPath:c,outcome:`canonical`},repairedCount:0};if(p===`preserved`)return{outcome:{configPath:c,outcome:`preserved`},repairedCount:0};let m=t(e.projectDir,{mode:`published`});if(m.action===`failed`){let e=m.error??`unknown write failure`;return o({event:`launch-json-repair-write-failed`,configPath:c,error:e}),{outcome:{configPath:c,outcome:`write-failed`,error:e},repairedCount:0}}return o({event:`launch-json-repair-applied`,configPath:c}),{outcome:{configPath:c,outcome:`repaired`},repairedCount:1}}function u(e){process.stderr.write(`${JSON.stringify(e)}\n`)}export{l as repairLaunchJson};
|
|
2
|
+
//# sourceMappingURL=repair-launch-json-k1Ihx-tm.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{d as e,g as t,m as n,s as r,v as i}from"./init-
|
|
2
|
-
//# sourceMappingURL=repair-mcp-configs-
|
|
1
|
+
import{d as e,g as t,m as n,s as r,v as i}from"./init-BrOIE7gK.mjs";import{t as a}from"./mcp-migrate-event-BF8ILHwp.mjs";import{homedir as o}from"node:os";function s(e){let r=e.logger??u,i=e.home??o(),a=[];if(e.reclaimDisableEnv===`1`)return r({event:`mcp-config-repair-skipped`,reason:`reclaim-disabled`}),{outcomes:a,repairedCount:0};for(let o of n){let n=t[o],s=c(()=>n.configPath(``,i));if(s!==null&&a.push(l({scope:`user`,editorId:o,target:n,home:i,cwd:``,configPath:s,configPathOverride:void 0,logger:r})),n.projectConfigPath){let t=n.projectConfigPath,i=c(()=>t(e.projectDir));i!==null&&a.push(l({scope:`project`,editorId:o,target:n,home:void 0,cwd:e.projectDir,configPath:i,configPathOverride:i,logger:r}))}}return{outcomes:a,repairedCount:a.filter(e=>e.outcome===`repaired`).length}}function c(e){try{return e()}catch{return null}}function l(t){let n={scope:t.scope,editorId:t.editorId,configPath:t.configPath},o=r(t.target,t.cwd,t.home,t.configPathOverride);if(o===null)return{...n,outcome:`no-entry`};if(i(o))return{...n,outcome:`canonical`};t.logger(a({scope:t.scope,surface:`cli-repair`,editorId:t.editorId,configPath:t.configPath,priorEntry:o}));let s=e(t.target,t.cwd,{mode:`published`,skipAvailabilityCheck:!0},t.home,t.configPathOverride);if(s.action===`failed`){let e=s.error??`unknown write failure`;return t.logger({event:`mcp-config-repair-write-failed`,scope:t.scope,editorId:t.editorId,configPath:t.configPath,error:e}),{...n,outcome:`write-failed`,error:e}}return{...n,outcome:`repaired`}}function u(e){process.stderr.write(`${JSON.stringify(e)}\n`)}export{s as repairMcpConfigs};
|
|
2
|
+
//# sourceMappingURL=repair-mcp-configs-s8YtscAj.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./repair-skills-D2S7rOZx.mjs";export{e as repairSkills};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{t as e}from"./esm-CEs3LWY3.mjs";import{Xn as t,di as n,er as r,ir as i,ur as a}from"./dist-
|
|
1
|
+
import{t as e}from"./esm-CEs3LWY3.mjs";import{Xn as t,di as n,er as r,ir as i,ur as a}from"./dist-DKgq69uI.mjs";import{t as o}from"./write-project-skill-BQGm1G4f.mjs";import{dirname as s,join as c,resolve as l}from"node:path";import{existsSync as u,mkdirSync as d,readFileSync as f,readdirSync as p,rmSync as m,statSync as h,writeFileSync as g}from"node:fs";import{homedir as _}from"node:os";const v=[{hostDir:`.claude`,editorId:`claude`},{hostDir:`.cursor`,editorId:`cursor`},{hostDir:`.agents`,editorId:`codex`}],y=`open-knowledge-discovery`,b=[`.agents`,`skills`,y],x={existsSync:e=>u(e),isDirectory:e=>{try{return h(e).isDirectory()}catch(e){if(e.code===`ENOENT`)return!1;throw e}},readdirSync:e=>p(e),readFileSync:e=>f(e),writeFileSync:(e,t)=>{g(e,t)},mkdirSync:(e,t)=>{d(e,t)},rmSync:(e,t)=>{m(e,t)}},S={resolveProjectBundledSkillDir:()=>a(`project`,{checkDesktop:!1}),resolveDiscoveryBundledSkillDir:()=>a(`discovery`,{checkDesktop:!1}),readBundledVersion:()=>t(),readRecordedVersion:e=>r(e,`cli-hosts`),writeRecordedVersion:(e,t)=>n(e,`cli-hosts`,t,`cli-start`),recordEvent:e=>i(e)};function C(e){process.stderr.write(`${JSON.stringify(e)}\n`)}function w(e,t,n){n.rmSync(t,{recursive:!0,force:!0}),n.mkdirSync(s(t),{recursive:!0}),T(e,t,n)}function T(e,t,n){n.mkdirSync(t,{recursive:!0});for(let r of n.readdirSync(e)){let i=c(e,r),a=c(t,r);n.isDirectory(i)?T(i,a,n):n.writeFileSync(a,n.readFileSync(i))}}function E(e,t,n,r){let i;try{i=t.resolveProjectBundledSkillDir()}catch(e){return r({event:`project-skill-reclaim-bundle-missing`,scope:`project`,error:e instanceof Error?e.message:String(e)}),{outcome:`skipped`,reason:`bundle-missing`}}let a=[];for(let t of v){let s=c(e,t.hostDir,`skills`,`open-knowledge`),l=c(s,`SKILL.md`);if(!n.existsSync(l)){a.push({editorId:t.editorId,hostDir:t.hostDir,path:s,outcome:`no-token`}),r({event:`project-skill-reclaim-no-token`,scope:`project`,editorId:t.editorId,path:s});continue}try{o(s,e),w(i,s,n),a.push({editorId:t.editorId,hostDir:t.hostDir,path:s,outcome:`reclaimed`}),r({event:`project-skill-reclaim-reclaimed`,scope:`project`,editorId:t.editorId,path:s})}catch(e){let n=e instanceof Error?e.message:String(e);a.push({editorId:t.editorId,hostDir:t.hostDir,path:s,outcome:`failed`,error:n}),r({event:`project-skill-reclaim-failed`,scope:`project`,editorId:t.editorId,path:s,error:n})}}return{outcome:`done`,entries:a}}async function D(e,t,n,r){let i=e=>{t.recordEvent(e).catch(()=>{})},a=()=>new Date().toISOString(),o;try{o=await t.readBundledVersion()}catch(e){let t=e instanceof Error?e.message:String(e);return r({event:`user-skill-reclaim-version-read-failed`,scope:`user`,error:t}),i({ts:a(),surface:`cli-start`,target:`cli-hosts`,bundle:`discovery`,outcome:`failed`,reason:`version-read-failed:${t}`}),{outcome:`skipped`,reason:`version-read-failed`}}let s;try{s=await t.readRecordedVersion(e)}catch(e){r({event:`user-skill-reclaim-version-read-error`,scope:`user`,error:e instanceof Error?e.message:String(e)}),s=null}if(s!==null&&s===o)return r({event:`user-skill-reclaim-skipped-version-current`,scope:`user`,version:o}),{outcome:`skipped`,reason:`version-current`};let l;try{l=t.resolveDiscoveryBundledSkillDir()}catch(e){let t=e instanceof Error?e.message:String(e);return r({event:`user-skill-reclaim-bundle-missing`,scope:`user`,error:t}),i({ts:a(),surface:`cli-start`,target:`cli-hosts`,bundle:`discovery`,outcome:`failed`,reason:`bundle-missing:${t}`}),{outcome:`skipped`,reason:`bundle-missing`}}let u=[],d=c(e,...b),f=n.existsSync(d);try{w(l,d,n),u.push({kind:`central`,path:d,outcome:f?`overwritten`:`written`}),r({event:`user-skill-reclaim-central-written`,scope:`user`,path:d,preexisting:f,version:o})}catch(e){let t=e instanceof Error?e.message:String(e);u.push({kind:`central`,path:d,outcome:`failed`,error:t}),r({event:`user-skill-reclaim-central-failed`,scope:`user`,path:d,error:t})}for(let t of v){let i=c(e,t.hostDir),a=c(i,`skills`,y);if(a===d){u.push({kind:`host`,editorId:t.editorId,hostDir:t.hostDir,path:a,outcome:`skipped-collapsed-with-central`});continue}if(!n.existsSync(i)){u.push({kind:`host`,editorId:t.editorId,hostDir:t.hostDir,path:a,outcome:`skipped-host-absent`});continue}let s=n.existsSync(a);try{w(l,a,n),u.push({kind:`host`,editorId:t.editorId,hostDir:t.hostDir,path:a,outcome:s?`overwritten`:`written`}),r({event:`user-skill-reclaim-host-written`,scope:`user`,editorId:t.editorId,hostDir:t.hostDir,path:a,preexisting:s,version:o})}catch(e){let n=e instanceof Error?e.message:String(e);u.push({kind:`host`,editorId:t.editorId,hostDir:t.hostDir,path:a,outcome:`failed`,error:n}),r({event:`user-skill-reclaim-host-failed`,scope:`user`,editorId:t.editorId,hostDir:t.hostDir,path:a,error:n})}}let p=u.find(e=>e.kind===`central`);if(p?.outcome===`written`||p?.outcome===`overwritten`){let n=null;try{await t.writeRecordedVersion(e,o),r({event:`user-skill-reclaim-version-recorded`,scope:`user`,version:o})}catch(e){n=e instanceof Error?e.message:String(e),r({event:`user-skill-reclaim-version-record-failed`,scope:`user`,version:o,error:n})}i({ts:a(),surface:`cli-start`,target:`cli-hosts`,bundle:`discovery`,outcome:n===null?`installed`:`failed`,version:o,...n===null?{}:{reason:`state-write-failed:${n}`}})}else{let e=u.some(e=>e.kind===`host`&&e.outcome===`failed`);i({ts:a(),surface:`cli-start`,target:`cli-hosts`,bundle:`discovery`,outcome:`failed`,version:o,reason:e?`all-writes-failed`:`no-hosts-installed`})}return{outcome:`done`,version:o,entries:u}}async function O(e){let t=e.logger??C,n=e.fs??x,r=e.home??_(),i={...S,...e.deps};return e.reclaimDisableEnv===`1`?(t({event:`skill-repair-skipped`,reason:`reclaim-disabled`}),{status:`skipped`,reason:`reclaim-disabled`}):{status:`done`,project:E(e.projectDir,i,n,t),user:await D(r,i,n,t)}}function k(e){return e.status===`skipped`?e.reason===`reclaim-disabled`?0:1:e.project.outcome===`skipped`||e.user.outcome===`skipped`&&e.user.reason!==`version-current`||e.project.entries.some(e=>e.outcome===`failed`)||e.user.outcome===`done`&&e.user.entries.some(e=>e.outcome===`failed`)?1:0}function A(e){if(e.status===`skipped`)return`Skipped: ${e.reason}`;let t=[`Skill reclaim complete.`];if(e.project.outcome===`done`){let n=e.project.entries.filter(e=>e.outcome===`reclaimed`).length,r=e.project.entries.filter(e=>e.outcome===`no-token`).length,i=e.project.entries.filter(e=>e.outcome===`failed`).length;t.push(` Project: ${n} reclaimed, ${r} no-token, ${i} failed.`)}else t.push(` Project: skipped (${e.project.reason}).`);if(e.user.outcome===`done`){let n=e.user.entries.filter(e=>e.outcome===`written`||e.outcome===`overwritten`).length,r=e.user.entries.filter(e=>e.outcome===`skipped-host-absent`||e.outcome===`skipped-collapsed-with-central`).length,i=e.user.entries.filter(e=>e.outcome===`failed`).length;t.push(` User (${e.user.version}): ${n} written, ${r} skipped, ${i} failed.`)}else t.push(` User: skipped (${e.user.reason}).`);return t.join(`
|
|
2
2
|
`)}function j(){return new e(`repair-skills`).description("Refresh bundled SKILL.md files for installed AI editors (project-local + user-global). Runs automatically during `ok start`; this command forces an explicit sweep.").action(async()=>{let e=await O({projectDir:l(process.cwd()),reclaimDisableEnv:process.env.OK_RECLAIM_DISABLE??null});process.stdout.write(`${A(e)}\n`),process.exitCode=k(e)})}export{j as n,O as t};
|
|
3
|
-
//# sourceMappingURL=repair-skills-
|
|
3
|
+
//# sourceMappingURL=repair-skills-D2S7rOZx.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"./gh-detect-D3_evne3.mjs";import{d as e,g as t,u as n}from"./init-
|
|
2
|
-
//# sourceMappingURL=src-
|
|
1
|
+
import"./gh-detect-D3_evne3.mjs";import{d as e,g as t,u as n}from"./init-BrOIE7gK.mjs";import"./loader-CxaZzLDi.mjs";import"./preview-BGoO3Ogd.mjs";import{n as r}from"./write-project-skill-BQGm1G4f.mjs";import{dirname as i,isAbsolute as a,join as o,relative as s,resolve as c}from"node:path";import{statSync as l}from"node:fs";import{readFile as u,realpath as d}from"node:fs/promises";function f(e){return e.replace(/:\d+$/,``)}function p(e){let t=e.trim();if(!t)return null;{let e=/^https?:\/\/([^/?#]+)\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t);if(e)return{protocol:`https`,hostname:f(e[1]),owner:e[2],name:e[3]}}{let e=/^ssh:\/\/(?:[\w.-]+@)?([^/?#]+)\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t);if(e)return{protocol:`ssh`,hostname:f(e[1]),owner:e[2],name:e[3]}}{let e=/^git:\/\/([^/?#]+)\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t);if(e)return{protocol:`git`,hostname:f(e[1]),owner:e[2],name:e[3]}}{let e=/^(?:[\w.-]+@)?([\w.-]+):([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?$/.exec(t);if(e?.[1].includes(`.`)||e&&t.startsWith(`git@`))return{protocol:`ssh`,hostname:e[1],owner:e[2],name:e[3]}}{let e=/^git:([\w.-]+)\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t);if(e)return{protocol:`git`,hostname:e[1],owner:e[2],name:e[3]}}if(!t.includes(`://`)&&!t.includes(`@`)&&!t.startsWith(`/`)){let e=/^([\w.-]+)\/([\w.\-~%]+?)(?:\.git)?$/.exec(t);if(e)return{protocol:`https`,hostname:`github.com`,owner:e[1],name:e[2]}}return null}function m(e){let t;try{t=new URL(e)}catch{return null}if(t.hostname!==`github.com`&&t.hostname!==`www.github.com`)return null;let n=t.pathname.split(`/`).filter(e=>e.length>0);if(n.length<5||n[2]!==`blob`)return null;let r,i,a,o;try{r=decodeURIComponent(n[0]),i=decodeURIComponent(n[1]),a=decodeURIComponent(n[3]),o=n.slice(4).map(e=>decodeURIComponent(e))}catch{return null}return!r||!i||!a||o.length===0||o.some(e=>e.length===0)?null:{owner:r,repo:i,branch:a,path:o.join(`/`)}}async function h(e,t){let n,r;try{n=await d(c(e)),r=await d(c(i(e)))}catch{return{kind:`not-git`}}if(!_(n,r))return{kind:`symlink-escape`};let s=o(n,`.git`),f;try{f=l(s)}catch{return{kind:`not-git`}}let m;if(f.isDirectory()){let e;try{e=await d(s)}catch{return{kind:`not-git`}}if(!_(e,n))return{kind:`symlink-escape`};m=e}else if(f.isFile()){let e;try{e=await u(s,`utf-8`)}catch{return{kind:`not-git`}}let t=/^gitdir:\s*(.+)$/m.exec(e.trim());if(!t)return{kind:`not-git`};let r=t[1].trim(),i=a(r)?r:c(n,r);try{m=await d(i)}catch{return{kind:`not-git`}}}else return{kind:`not-git`};let h=o(await g(m),`config`),v;try{v=await u(h,`utf-8`)}catch{return{kind:`not-git`}}let b=y(v);if(b===null)return{kind:`no-origin`};let x=p(b);if(x===null||x.hostname!==`github.com`)return{kind:`non-github`};let S=x.owner.toLowerCase()===t.owner.toLowerCase(),C=x.name.toLowerCase()===t.repo.toLowerCase();return!S||!C?{kind:`wrong-repo`,actualOwner:x.owner,actualRepo:x.name}:{kind:`ok`,gitRemoteUrl:`https://github.com/${x.owner}/${x.name}.git`}}async function g(e){let t;try{t=(await u(o(e,`commondir`),`utf-8`)).trim()}catch{return e}if(t.length===0)return e;let n=a(t)?t:c(e,t);try{return await d(n)}catch{return n}}function _(e,t){if(e===t)return!0;let n=s(t,e);return n.length>0&&!n.startsWith(`..`)&&!a(n)}function v(e){let t=e.indexOf(`#`),n=e.indexOf(`;`),r=-1;return t>=0&&n>=0?r=Math.min(t,n):t>=0?r=t:n>=0&&(r=n),(r===-1?e:e.slice(0,r)).trim()}function y(e){let t=!1;for(let n of e.split(/\r?\n/)){let e=v(n);if(e.length===0)continue;if(e.startsWith(`[`)){t=/^\[\s*remote\s+["']origin["']\s*\]$/.test(e);continue}if(!t)continue;let r=/^url\s*=\s*(.+)$/.exec(e);if(r)return b(r[1])}return null}function b(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1):t}const x=[{id:`mcp-config`,write(t,n,r){let i=t.projectConfigPath?.(n);if(!i)return{integration:`mcp-config`,editorId:t.id,action:`skipped-unsupported`};try{let a=e(t,n,r,void 0,i);return a.action===`written`||a.action===`overwritten`?{integration:`mcp-config`,editorId:t.id,action:a.action,path:a.configPath}:a.action===`failed`?{integration:`mcp-config`,editorId:t.id,action:`failed`,path:a.configPath,error:a.error??`unknown failure`}:{integration:`mcp-config`,editorId:t.id,action:`failed`,path:a.configPath,error:`unexpected project-scope action: ${a.action}`}}catch(e){return{integration:`mcp-config`,editorId:t.id,action:`failed`,path:i,error:e instanceof Error?e.message:String(e)}}}},{id:`project-skill`,write(e,t,n){try{let n=r(e,t);return{integration:`project-skill`,editorId:e.id,action:n.action,...n.path?{path:n.path}:{},...n.error?{error:n.error}:{}}}catch(t){return{integration:`project-skill`,editorId:e.id,action:`failed`,error:t instanceof Error?t.message:String(t)}}}}];function S(e,n,r={},i=x){let a=[];for(let o of n){let n=t[o];for(let t of i)a.push(t.write(n,e,r))}return a}function C(e,t,r={}){return{integrations:S(e,t,r),claudeLaunchJson:t.includes(`claude`)?n(e,r):void 0}}export{p as i,h as n,m as r,C as t};
|
|
2
|
+
//# sourceMappingURL=src-pmNhkR0H.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{u as e}from"./start-PfFarWKH.mjs";export{e as startCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{n as e,t}from"./esm-CEs3LWY3.mjs";import{Sn as n,dt as r}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{i,t as a}from"./gh-detect-D3_evne3.mjs";import{kn as o}from"./dist-BBbP7DxV.mjs";import{n as s}from"./constants-EfhRR_gr.mjs";import{spawn as c}from"node:child_process";import{basename as l,dirname as u,join as d}from"node:path";import{closeSync as f,existsSync as p,mkdirSync as m,openSync as h,statSync as g}from"node:fs";import{homedir as _}from"node:os";import{setTimeout as v}from"node:timers/promises";const y=`Open Knowledge.app`,b=`/Applications/${y}`;function x(){return{platform:process.platform,env:process.env,execPath:process.execPath,isTTY:process.stdout.isTTY,statSync:e=>{try{return g(e,{throwIfNoEntry:!1})??null}catch{return null}}}}function S(e){if(e.env.ELECTRON_RUN_AS_NODE===`1`){let t=/(.+?\.app)\/Contents\/MacOS\//.exec(e.execPath);if(t?.[1])return t[1]}if(C(e,b))return b;let t=d(e.homeDir??_(),`Applications`,y);return C(e,t)?t:null}function C(e,t){try{let n=d(t,`Contents`,`MacOS`,`Open Knowledge`),r=e.statSync(n);return r&&typeof r.isFile==`function`?r.isFile():!1}catch{return!1}}function w(e){if(e.env.OK_FORCE_BROWSER===`1`)return{available:!1,reason:`force-browser`};if(e.platform!==`darwin`)return{available:!1,reason:`darwin-only`};let t;try{t=S(e)}catch{return{available:!1,reason:`stat-error`}}return t?e.env.OK_FORCE_DESKTOP===`1`?{available:!0,reason:`available`,bundlePath:t}:e.isTTY!==!0||e.env.SSH_CONNECTION||e.env.SSH_TTY?{available:!1,reason:`headless`,bundlePath:t}:{available:!0,reason:`available`,bundlePath:t}:{available:!1,reason:`no-bundle`}}function T(e){(e.log??(e=>console.error(e)))("Launching Open Knowledge desktop (use `ok start` for the browser server, or `OK_FORCE_BROWSER=1` to always skip)");let t={...process.env};delete t.ELECTRON_RUN_AS_NODE,e.spawn(`open`,[`-b`,`com.inkeep.open-knowledge`],{detached:!0,stdio:`ignore`,env:t}).unref()}function E(e=`no-bundle`){switch(e){case`no-bundle`:return`Desktop app not found at ${b}. Install via DMG, or omit --mode for browser mode.`;case`darwin-only`:return`Desktop app is macOS-only on this release. Use --mode=browser, or omit --mode for the server fallback.`;case`headless`:return`Desktop launch is gated in headless contexts (CI, SSH, non-TTY stdout). Set OK_FORCE_DESKTOP=1 to override, or use --mode=browser.`;case`force-browser`:return`OK_FORCE_BROWSER=1 is set — desktop dispatch is disabled. Unset it to use --mode=app.`;case`stat-error`:return`Failed to inspect desktop bundle at ${b} (filesystem error). Check permissions or use --mode=browser.`;case`available`:return`Desktop app appears available at ${b} but launch dispatch did not fire (caller bug).`}}function D(e){return d(u(e),`..`,`Frameworks`,`Open Knowledge Server.app`,`Contents`,`MacOS`,`Open Knowledge Helper`)}const O=/\/[^/]+\.app\/Contents\/MacOS\/[^/]+$/;function k(e){if(e.platform!==`darwin`||!O.test(e.execPath))return null;let t=D(e.execPath);return e.exists(t)?t:null}function A(e={}){let t=e.execPath??process.execPath,n=e.platform??process.platform,r=e.argv??process.argv,i=e.exists??p,a=r[1];return a?{command:k({execPath:t,platform:n,exists:i})??t,prefixArgs:[a]}:(console.warn(`[self-spawn] process.argv[1] is empty — falling back to \`npx -y @inkeep/open-knowledge@latest\`. This re-introduces the registry-fetch surface that re-exec was fixing. Observed argv: ${JSON.stringify(r)}`),{command:`npx`,prefixArgs:[`-y`,`@inkeep/open-knowledge@latest`]})}function j(e,t){return e.host??t.HOST??`localhost`}function M(e){let t=l(e).replace(/[^\x20-\x7E]/g,``).trim().slice(0,64);return`open-knowledge-server ${t.length>0?t:`unknown`}`}var N=class extends Error{cwd;constructor(e){super("This directory isn't set up yet. Run `ok init` first, then `ok start` again."),this.name=`OkDirMissingError`,this.cwd=e}};function P(e){return e.uiLock?e.isAlive(e.uiLock.pid)?{action:`skip`,reason:`alive`,pid:e.uiLock.pid,port:e.uiLock.port}:{action:`spawn`,reason:`stale`,stalePid:e.uiLock.pid}:{action:`spawn`,reason:`absent`}}function F(e){p(e.lockDir)||m(e.lockDir,{recursive:!0});let t=h(d(e.lockDir,n),`w`),r=e.spawn??c,{PORT:i,...a}=process.env,o=A();try{let n=r(o.command,[...o.prefixArgs,...e.args??[`ui`]],{detached:!0,stdio:[`ignore`,`ignore`,t],cwd:e.cwd,env:{...a,ELECTRON_RUN_AS_NODE:`1`}});return n.unref(),n}finally{try{f(t)}catch{}}}async function I(e){let t=e.now()+e.timeoutMs;for(;e.now()<t;){let t=e.readUiLock();if(t&&t.port>0)return t.port;await e.sleep(e.pollIntervalMs)}let n=e.readUiLock();return n&&n.port>0?n.port:null}const L=r;function R(e){let t=e.sigtermGraceMs??L,n=e.sigtermPollIntervalMs??200,r=e.sleep??(e=>v(e));return async()=>{try{let i=e.readUiLock();if(i&&e.isAlive(i.pid))try{e.killPid(i.pid,`SIGTERM`),e.log?.info({pid:i.pid,port:i.port},`idle-shutdown: SIGTERM UI sibling`);let a=Date.now()+t;for(;Date.now()<a&&e.isAlive(i.pid);)await r(n);if(e.isAlive(i.pid))try{e.killPid(i.pid,`SIGKILL`),e.log?.warn({pid:i.pid,graceMs:t},`idle-shutdown: SIGTERM grace expired — escalated to SIGKILL`)}catch(t){e.log?.error({pid:i.pid,err:t instanceof Error?t.message:String(t)},`idle-shutdown: SIGKILL failed`)}}catch(t){e.log?.warn({pid:i.pid,err:t instanceof Error?t.message:String(t)},`idle-shutdown: failed to SIGTERM UI sibling`)}}catch(t){e.log?.warn({err:t instanceof Error?t.message:String(t)},`idle-shutdown: UI lookup failed; proceeding with destroy`)}await e.destroy()}}async function z(e){let{config:t,cwd:n,host:r}=e,s=e.skipAutoInit??!1,c=e.skipUiAutoSpawn??!1,l=e.idleThresholdMs??18e5,{existsSync:u,mkdirSync:d}=await import(`node:fs`),{bootServer:f,getLogger:p,isProcessAlive:m,readUiLock:h,resolveContentDir:g}=await import(`./dist-CpYAbkBw.mjs`),_=e.log??p(`start`);if(!s&&!o(n))throw new N(n);let y=process.env.OK_RECLAIM_DISABLE??null;try{(e.repairMcpConfigsFn??(await import(`./repair-mcp-configs-Cbol0R2Q.mjs`)).repairMcpConfigs)({projectDir:n,reclaimDisableEnv:y})}catch(e){_.warn({err:e},`[start] mcp-config repair sweep failed; continuing`)}try{(e.repairLaunchJsonFn??(await import(`./repair-launch-json-CHoyWCeo.mjs`)).repairLaunchJson)({projectDir:n,reclaimDisableEnv:y})}catch(e){_.warn({err:e},`[start] launch.json repair sweep failed; continuing`)}try{await(e.repairSkillsFn??(await import(`./repair-skills-CaLjuijU.mjs`)).repairSkills)({projectDir:n,reclaimDisableEnv:y})}catch(e){_.warn({err:e},`[start] skill repair sweep failed; continuing`)}let b=g(t,n);u(b)||(d(b,{recursive:!0}),_.info({contentDir:b},`Created content directory`));let x=null,S=async({lockDir:t})=>{if(x=P({uiLock:h(t),isAlive:m}),x.action===`spawn`&&!c)try{F({lockDir:t,cwd:n,spawn:e.spawn}),_.info({reason:x.reason},`[start] auto-spawned ok ui sibling`)}catch(e){console.warn(`[start] failed to auto-spawn ok ui: ${e instanceof Error?e.message:String(e)}`)}else x.action===`skip`&&_.info({port:x.port,pid:x.pid},`UI already running at port ${x.port}`)},C=e.reactShellDistDir===void 0,w=i(),T=await f({config:t,contentDir:b,projectDir:n,contentRoot:t.content.dir,port:e.port,host:r,quiet:!1,detectGh:a,tokenStore:w,localOpCliArgs:[process.execPath,process.argv[1]],attachUiSibling:C,idleShutdownMs:l,skipAutoInit:!0,...C?{spawnUiSiblingFn:S}:{},idleShutdownHandler:e=>R({readUiLock:()=>h(T.lockDir),isAlive:m,killPid:(e,t)=>{process.kill(e,t)},destroy:e,log:_}),log:_,...e.serveContentAssets?{serveContentAssets:!0}:{},...e.reactShellDistDir?{reactShellDistDir:e.reactShellDistDir}:{}});x||={action:`skip`,reason:`alive`,pid:0,port:0};let E=x,D=null;if(E.action===`skip`)D=E.port>0?E.port:null;else if(!c){let t=e.uiBindTimeoutMs??3e3;D=await I({readUiLock:()=>h(T.lockDir),now:Date.now,sleep:e=>v(e),timeoutMs:t,pollIntervalMs:50}),D===null&&_.warn({timeoutMs:t},`[start] ok ui did not bind within timeout — banner falls back to API URL`)}return{httpServer:T.httpServer,destroy:T.destroy,lockDir:T.lockDir,contentDir:b,port:T.port,ready:T.ready,degraded:T.degraded,uiSpawnDecision:x,resolvedUiPort:D}}function B(t){if(t===`browser`||t===`app`)return t;throw new e(`--mode must be 'browser' or 'app'`)}async function V(e,t){let{renderBanner:n}=await import(`./banner-D39r_H1d.mjs`),{dim:r,error:i,warning:a}=await import(`./colors-t2HkW8lF.mjs`),o=process.cwd(),c=e;process.title=M(o);let l=j(t,process.env),u=t.port===void 0?void 0:Number(t.port),d=process.env.PORT?Number(process.env.PORT):void 0,f=u??d,p;try{p=await z({config:c,cwd:o,host:l,port:f,...t.serveContentAssets?{serveContentAssets:!0}:{},...t.reactShellDistDir?{reactShellDistDir:t.reactShellDistDir}:{}})}catch(e){e instanceof N&&(console.error(i(e.message)),process.exit(1));let t=await import(`./dist-CpYAbkBw.mjs`);(e instanceof t.GitNotAvailableError||e instanceof t.GitTooOldError)&&process.exit(78);let n=H(e,o,t);n!==null&&(console.error(i(n)),process.exit(1)),console.error(`${i(`Failed to start:`)} ${e instanceof Error?e.stack??e.message:String(e)}`),process.exit(1)}let m=!1,h=async e=>{if(!m){m=!0,console.log(r(`\nShutting down (${e})`));try{await p.destroy()}catch(e){console.error(`${i(`destroy() failed:`)} ${e instanceof Error?e.stack??e.message:String(e)}`),process.exitCode=1}process.exit(process.exitCode??0)}};process.once(`SIGINT`,()=>{h(`SIGINT`)}),process.once(`SIGTERM`,()=>{h(`SIGTERM`)});let g=`http://${l}:${p.port}`,_=l===`0.0.0.0`||l===`::`?`http://0.0.0.0:${p.port}`:void 0,v=p.resolvedUiPort,y=v!==null&&v>0?`http://${l}:${v}`:g;console.log(n({name:`open-knowledge`,version:s,localUrl:y,apiUrl:y===g?void 0:g,networkUrl:_}));let b={"shadow-repo":`Version history and branch-switch safety unavailable`,"file-watcher":`External file changes will not sync to the editor`,"head-watcher":`Git branch switches may cause document inconsistency`};p.ready.then(async()=>{if(p.degraded.length>0){console.log();for(let e of p.degraded){let t=b[e]??`${e} (check server logs for details)`;console.warn(` ${a(`⚠`)} ${a(e)}: ${r(t)}`)}console.log()}if(t.open){let{openBrowser:e}=await import(`./open-browser-C6LU_1mt.mjs`);e(y)}}).catch(e=>{console.error(` ${i(`Server initialization failed:`)} ${e instanceof Error?e.message:String(e)}`)})}function H(e,t,n){let r=n.ServerLockCollisionError;if(r===void 0||!(e instanceof r))return null;try{let e=d(t,`.ok`),r=n.readServerLock(e);return r?r.kind===`interactive`?`Open Knowledge desktop is currently running on this project. Quit it or use --cwd to point elsewhere.`:r.kind===`mcp-spawned`?"An MCP-spawned server holds this lock; it should release on idle-shutdown (~30 min). Or run `ok stop`.":"Open Knowledge server is already running on this project — check `ok status` or `ok stop`.":"Open Knowledge server is already running on this project — check `ok status` or `ok stop`."}catch{return null}}function U(e){return new t(`start`).description(`Start the knowledge base collab server`).option(`-p, --port <port>`,`Server port`,void 0).option(`-H, --host <host>`,`Server host`,void 0).option(`--open`,`Open browser after start`).option(`--mode <mode>`,`Force dispatch mode: 'browser' or 'app'`,B).option(`--serve-content-assets`,`Serve content assets from this server`).option(`--react-shell-dist-dir <path>`,`Serve React shell from <path> (suppresses ok ui sibling)`).action(async t=>{let n=e();if(t.mode===`app`){t.open&&(process.stderr.write(`error: option '--mode=app' cannot be combined with '--open' (--open opens a browser tab against the local server, which app mode does not boot)
|
|
1
|
+
import{n as e,t}from"./esm-CEs3LWY3.mjs";import{Sn as n,dt as r}from"./server-lock-BpjJj3OD-B9uBbH7Z.mjs";import{i,t as a}from"./gh-detect-D3_evne3.mjs";import{kn as o}from"./dist-DKgq69uI.mjs";import{n as s}from"./constants-D9hc7LX4.mjs";import{spawn as c}from"node:child_process";import{basename as l,dirname as u,join as d}from"node:path";import{closeSync as f,existsSync as p,mkdirSync as m,openSync as h,statSync as g}from"node:fs";import{homedir as _}from"node:os";import{setTimeout as v}from"node:timers/promises";const y=`Open Knowledge.app`,b=`/Applications/${y}`;function x(){return{platform:process.platform,env:process.env,execPath:process.execPath,isTTY:process.stdout.isTTY,statSync:e=>{try{return g(e,{throwIfNoEntry:!1})??null}catch{return null}}}}function S(e){if(e.env.ELECTRON_RUN_AS_NODE===`1`){let t=/(.+?\.app)\/Contents\/MacOS\//.exec(e.execPath);if(t?.[1])return t[1]}if(C(e,b))return b;let t=d(e.homeDir??_(),`Applications`,y);return C(e,t)?t:null}function C(e,t){try{let n=d(t,`Contents`,`MacOS`,`Open Knowledge`),r=e.statSync(n);return r&&typeof r.isFile==`function`?r.isFile():!1}catch{return!1}}function w(e){if(e.env.OK_FORCE_BROWSER===`1`)return{available:!1,reason:`force-browser`};if(e.platform!==`darwin`)return{available:!1,reason:`darwin-only`};let t;try{t=S(e)}catch{return{available:!1,reason:`stat-error`}}return t?e.env.OK_FORCE_DESKTOP===`1`?{available:!0,reason:`available`,bundlePath:t}:e.isTTY!==!0||e.env.SSH_CONNECTION||e.env.SSH_TTY?{available:!1,reason:`headless`,bundlePath:t}:{available:!0,reason:`available`,bundlePath:t}:{available:!1,reason:`no-bundle`}}function T(e){(e.log??(e=>console.error(e)))("Launching Open Knowledge desktop (use `ok start` for the browser server, or `OK_FORCE_BROWSER=1` to always skip)");let t={...process.env};delete t.ELECTRON_RUN_AS_NODE,e.spawn(`open`,[`-b`,`com.inkeep.open-knowledge`],{detached:!0,stdio:`ignore`,env:t}).unref()}function E(e=`no-bundle`){switch(e){case`no-bundle`:return`Desktop app not found at ${b}. Install via DMG, or omit --mode for browser mode.`;case`darwin-only`:return`Desktop app is macOS-only on this release. Use --mode=browser, or omit --mode for the server fallback.`;case`headless`:return`Desktop launch is gated in headless contexts (CI, SSH, non-TTY stdout). Set OK_FORCE_DESKTOP=1 to override, or use --mode=browser.`;case`force-browser`:return`OK_FORCE_BROWSER=1 is set — desktop dispatch is disabled. Unset it to use --mode=app.`;case`stat-error`:return`Failed to inspect desktop bundle at ${b} (filesystem error). Check permissions or use --mode=browser.`;case`available`:return`Desktop app appears available at ${b} but launch dispatch did not fire (caller bug).`}}function D(e){return d(u(e),`..`,`Frameworks`,`Open Knowledge Server.app`,`Contents`,`MacOS`,`Open Knowledge Helper`)}const O=/\/[^/]+\.app\/Contents\/MacOS\/[^/]+$/;function k(e){if(e.platform!==`darwin`||!O.test(e.execPath))return null;let t=D(e.execPath);return e.exists(t)?t:null}function A(e={}){let t=e.execPath??process.execPath,n=e.platform??process.platform,r=e.argv??process.argv,i=e.exists??p,a=r[1];return a?{command:k({execPath:t,platform:n,exists:i})??t,prefixArgs:[a]}:(console.warn(`[self-spawn] process.argv[1] is empty — falling back to \`npx -y @inkeep/open-knowledge@latest\`. This re-introduces the registry-fetch surface that re-exec was fixing. Observed argv: ${JSON.stringify(r)}`),{command:`npx`,prefixArgs:[`-y`,`@inkeep/open-knowledge@latest`]})}function j(e,t){return e.host??t.HOST??`localhost`}function M(e){let t=l(e).replace(/[^\x20-\x7E]/g,``).trim().slice(0,64);return`open-knowledge-server ${t.length>0?t:`unknown`}`}var N=class extends Error{cwd;constructor(e){super("This directory isn't set up yet. Run `ok init` first, then `ok start` again."),this.name=`OkDirMissingError`,this.cwd=e}};function P(e){return e.uiLock?e.isAlive(e.uiLock.pid)?{action:`skip`,reason:`alive`,pid:e.uiLock.pid,port:e.uiLock.port}:{action:`spawn`,reason:`stale`,stalePid:e.uiLock.pid}:{action:`spawn`,reason:`absent`}}function F(e){p(e.lockDir)||m(e.lockDir,{recursive:!0});let t=h(d(e.lockDir,n),`w`),r=e.spawn??c,{PORT:i,...a}=process.env,o=A();try{let n=r(o.command,[...o.prefixArgs,...e.args??[`ui`]],{detached:!0,stdio:[`ignore`,`ignore`,t],cwd:e.cwd,env:{...a,ELECTRON_RUN_AS_NODE:`1`}});return n.unref(),n}finally{try{f(t)}catch{}}}async function I(e){let t=e.now()+e.timeoutMs;for(;e.now()<t;){let t=e.readUiLock();if(t&&t.port>0)return t.port;await e.sleep(e.pollIntervalMs)}let n=e.readUiLock();return n&&n.port>0?n.port:null}const L=r;function R(e){let t=e.sigtermGraceMs??L,n=e.sigtermPollIntervalMs??200,r=e.sleep??(e=>v(e));return async()=>{try{let i=e.readUiLock();if(i&&e.isAlive(i.pid))try{e.killPid(i.pid,`SIGTERM`),e.log?.info({pid:i.pid,port:i.port},`idle-shutdown: SIGTERM UI sibling`);let a=Date.now()+t;for(;Date.now()<a&&e.isAlive(i.pid);)await r(n);if(e.isAlive(i.pid))try{e.killPid(i.pid,`SIGKILL`),e.log?.warn({pid:i.pid,graceMs:t},`idle-shutdown: SIGTERM grace expired — escalated to SIGKILL`)}catch(t){e.log?.error({pid:i.pid,err:t instanceof Error?t.message:String(t)},`idle-shutdown: SIGKILL failed`)}}catch(t){e.log?.warn({pid:i.pid,err:t instanceof Error?t.message:String(t)},`idle-shutdown: failed to SIGTERM UI sibling`)}}catch(t){e.log?.warn({err:t instanceof Error?t.message:String(t)},`idle-shutdown: UI lookup failed; proceeding with destroy`)}await e.destroy()}}async function z(e){let{config:t,cwd:n,host:r}=e,s=e.skipAutoInit??!1,c=e.skipUiAutoSpawn??!1,l=e.idleThresholdMs??18e5,{existsSync:u,mkdirSync:d}=await import(`node:fs`),{bootServer:f,getLogger:p,isProcessAlive:m,readUiLock:h,resolveContentDir:g}=await import(`./dist-D-rWIekL.mjs`),_=e.log??p(`start`);if(!s&&!o(n))throw new N(n);let y=process.env.OK_RECLAIM_DISABLE??null;try{(e.repairMcpConfigsFn??(await import(`./repair-mcp-configs-s8YtscAj.mjs`)).repairMcpConfigs)({projectDir:n,reclaimDisableEnv:y})}catch(e){_.warn({err:e},`[start] mcp-config repair sweep failed; continuing`)}try{(e.repairLaunchJsonFn??(await import(`./repair-launch-json-k1Ihx-tm.mjs`)).repairLaunchJson)({projectDir:n,reclaimDisableEnv:y})}catch(e){_.warn({err:e},`[start] launch.json repair sweep failed; continuing`)}try{await(e.repairSkillsFn??(await import(`./repair-skills-BimjofqV.mjs`)).repairSkills)({projectDir:n,reclaimDisableEnv:y})}catch(e){_.warn({err:e},`[start] skill repair sweep failed; continuing`)}let b=g(t,n);u(b)||(d(b,{recursive:!0}),_.info({contentDir:b},`Created content directory`));let x=null,S=async({lockDir:t})=>{if(x=P({uiLock:h(t),isAlive:m}),x.action===`spawn`&&!c)try{F({lockDir:t,cwd:n,spawn:e.spawn}),_.info({reason:x.reason},`[start] auto-spawned ok ui sibling`)}catch(e){console.warn(`[start] failed to auto-spawn ok ui: ${e instanceof Error?e.message:String(e)}`)}else x.action===`skip`&&_.info({port:x.port,pid:x.pid},`UI already running at port ${x.port}`)},C=e.reactShellDistDir===void 0,w=i(),T=await f({config:t,contentDir:b,projectDir:n,contentRoot:t.content.dir,port:e.port,host:r,quiet:!1,detectGh:a,tokenStore:w,localOpCliArgs:[process.execPath,process.argv[1]],attachUiSibling:C,idleShutdownMs:l,skipAutoInit:!0,...C?{spawnUiSiblingFn:S}:{},idleShutdownHandler:e=>R({readUiLock:()=>h(T.lockDir),isAlive:m,killPid:(e,t)=>{process.kill(e,t)},destroy:e,log:_}),log:_,...e.serveContentAssets?{serveContentAssets:!0}:{},...e.reactShellDistDir?{reactShellDistDir:e.reactShellDistDir}:{}});x||={action:`skip`,reason:`alive`,pid:0,port:0};let E=x,D=null;if(E.action===`skip`)D=E.port>0?E.port:null;else if(!c){let t=e.uiBindTimeoutMs??3e3;D=await I({readUiLock:()=>h(T.lockDir),now:Date.now,sleep:e=>v(e),timeoutMs:t,pollIntervalMs:50}),D===null&&_.warn({timeoutMs:t},`[start] ok ui did not bind within timeout — banner falls back to API URL`)}return{httpServer:T.httpServer,destroy:T.destroy,lockDir:T.lockDir,contentDir:b,port:T.port,ready:T.ready,degraded:T.degraded,uiSpawnDecision:x,resolvedUiPort:D}}function B(t){if(t===`browser`||t===`app`)return t;throw new e(`--mode must be 'browser' or 'app'`)}async function V(e,t){let{renderBanner:n}=await import(`./banner-D39r_H1d.mjs`),{dim:r,error:i,warning:a}=await import(`./colors-t2HkW8lF.mjs`),o=process.cwd(),c=e;process.title=M(o);let l=j(t,process.env),u=t.port===void 0?void 0:Number(t.port),d=process.env.PORT?Number(process.env.PORT):void 0,f=u??d,p;try{p=await z({config:c,cwd:o,host:l,port:f,...t.serveContentAssets?{serveContentAssets:!0}:{},...t.reactShellDistDir?{reactShellDistDir:t.reactShellDistDir}:{}})}catch(e){e instanceof N&&(console.error(i(e.message)),process.exit(1));let t=await import(`./dist-D-rWIekL.mjs`);(e instanceof t.GitNotAvailableError||e instanceof t.GitTooOldError)&&process.exit(78);let n=H(e,o,t);n!==null&&(console.error(i(n)),process.exit(1)),console.error(`${i(`Failed to start:`)} ${e instanceof Error?e.stack??e.message:String(e)}`),process.exit(1)}let m=!1,h=async e=>{if(!m){m=!0,console.log(r(`\nShutting down (${e})`));try{await p.destroy()}catch(e){console.error(`${i(`destroy() failed:`)} ${e instanceof Error?e.stack??e.message:String(e)}`),process.exitCode=1}process.exit(process.exitCode??0)}};process.once(`SIGINT`,()=>{h(`SIGINT`)}),process.once(`SIGTERM`,()=>{h(`SIGTERM`)});let g=`http://${l}:${p.port}`,_=l===`0.0.0.0`||l===`::`?`http://0.0.0.0:${p.port}`:void 0,v=p.resolvedUiPort,y=v!==null&&v>0?`http://${l}:${v}`:g;console.log(n({name:`open-knowledge`,version:s,localUrl:y,apiUrl:y===g?void 0:g,networkUrl:_}));let b={"shadow-repo":`Version history and branch-switch safety unavailable`,"file-watcher":`External file changes will not sync to the editor`,"head-watcher":`Git branch switches may cause document inconsistency`};p.ready.then(async()=>{if(p.degraded.length>0){console.log();for(let e of p.degraded){let t=b[e]??`${e} (check server logs for details)`;console.warn(` ${a(`⚠`)} ${a(e)}: ${r(t)}`)}console.log()}if(t.open){let{openBrowser:e}=await import(`./open-browser-C6LU_1mt.mjs`);e(y)}}).catch(e=>{console.error(` ${i(`Server initialization failed:`)} ${e instanceof Error?e.message:String(e)}`)})}function H(e,t,n){let r=n.ServerLockCollisionError;if(r===void 0||!(e instanceof r))return null;try{let e=d(t,`.ok`),r=n.readServerLock(e);return r?r.kind===`interactive`?`Open Knowledge desktop is currently running on this project. Quit it or use --cwd to point elsewhere.`:r.kind===`mcp-spawned`?"An MCP-spawned server holds this lock; it should release on idle-shutdown (~30 min). Or run `ok stop`.":"Open Knowledge server is already running on this project — check `ok status` or `ok stop`.":"Open Knowledge server is already running on this project — check `ok status` or `ok stop`."}catch{return null}}function U(e){return new t(`start`).description(`Start the knowledge base collab server`).option(`-p, --port <port>`,`Server port`,void 0).option(`-H, --host <host>`,`Server host`,void 0).option(`--open`,`Open browser after start`).option(`--mode <mode>`,`Force dispatch mode: 'browser' or 'app'`,B).option(`--serve-content-assets`,`Serve content assets from this server`).option(`--react-shell-dist-dir <path>`,`Serve React shell from <path> (suppresses ok ui sibling)`).action(async t=>{let n=e();if(t.mode===`app`){t.open&&(process.stderr.write(`error: option '--mode=app' cannot be combined with '--open' (--open opens a browser tab against the local server, which app mode does not boot)
|
|
2
2
|
`),process.exit(2));let e=[];if(t.port!==void 0&&e.push(`--port`),t.host!==void 0&&e.push(`--host`),e.length>0){let t=process.env.OK_LOG_LEVEL??`info`;(t===`debug`||t===`trace`)&&console.error(`--mode=app: ignoring ${e.join(`, `)}`)}let n=w(x());if(n.available){T({spawn:c});return}console.error(E(n.reason)),process.exit(1)}await V(n,t)})}export{P as a,V as c,H as d,A as f,T as h,R as i,F as l,w as m,I as n,M as o,x as p,z as r,j as s,N as t,U as u};
|
|
3
|
-
//# sourceMappingURL=start-
|
|
3
|
+
//# sourceMappingURL=start-PfFarWKH.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ur as e}from"./dist-
|
|
2
|
-
//# sourceMappingURL=write-project-skill-
|
|
1
|
+
import{ur as e}from"./dist-DKgq69uI.mjs";import{dirname as t,isAbsolute as n,relative as r,resolve as i,sep as a}from"node:path";import{cpSync as o,existsSync as s,lstatSync as c,mkdirSync as l,realpathSync as u,rmSync as d}from"node:fs";function f(e,o){let s;try{s=u(o)}catch{s=i(o)}let l;try{l=c(e)}catch(e){if(e.code!==`ENOENT`)throw e}if(l?.isSymbolicLink())throw Error(`Refusing to write through a symbolic link at ${e}. Remove the symlink and re-run project setup.`);let d=t(e);for(;d.length>1&&d!==a;){let i;try{i=u(d)}catch(e){if(e.code===`ENOENT`){d=t(d);continue}throw e}let a=r(s,i);if(a===``||!a.startsWith(`..`)&&!n(a))return;throw Error(`Refusing to write at ${e}: ancestor ${d} resolves to ${i}, which is outside the project directory ${s}. A symbolic link in the path likely escapes the project. Remove the symlink and re-run project setup.`)}}function p(n,r){let i=n.projectSkillPath?.(r);if(!i)return{editorId:n.id,label:n.label,action:`skipped-unsupported`,path:``};try{let a=e(`project`,{checkDesktop:!0}),c=t(i);f(c,r);let u=s(i)?`overwritten`:`written`;return d(c,{recursive:!0,force:!0}),l(t(c),{recursive:!0}),o(a,c,{recursive:!0}),{editorId:n.id,label:n.label,action:u,path:i}}catch(e){return{editorId:n.id,label:n.label,action:`failed`,path:i,error:e instanceof Error?e.message:String(e)}}}export{p as n,f as t};
|
|
2
|
+
//# sourceMappingURL=write-project-skill-BQGm1G4f.mjs.map
|
package/package.json
CHANGED
package/dist/init-Cfa2w3tX.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as e}from"./init-DIFyMBZs.mjs";export{e as runInit};
|
package/dist/loader-Cd8qUPSh.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./loader-Mg7RInsh.mjs";export{e as loadConfig};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e,t}from"./preview-BUNvNkcD.mjs";export{t as formatPreviewBlock,e as previewContent};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./repair-skills-DL_fR7iS.mjs";export{e as repairSkills};
|
package/dist/start-DzCcS7aH.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{u as e}from"./start-CfcNOkrG.mjs";export{e as startCommand};
|