@inkeep/open-knowledge 0.0.0-dev-20260423231521 → 0.0.0-dev-20260424010642

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/cli.mjs +4 -4
  2. package/dist/constants-Cs463jly.mjs +2 -0
  3. package/dist/index.mjs +1 -1
  4. package/dist/init-2VnOB85F.mjs +1 -0
  5. package/dist/init-CCx9nR5M.mjs +1 -0
  6. package/dist/{init-CODC0Drd.mjs → init-DgjpYMQB.mjs} +2 -2
  7. package/dist/{init-DysAQtCG.mjs → init-Xod4U7aY.mjs} +3 -3
  8. package/dist/loader-Cm1Bwe2n.mjs +1 -0
  9. package/dist/{loader-DfTFnc2z.mjs → loader-Dw_7CMz3.mjs} +2 -2
  10. package/dist/{paths-B9hXoumv.mjs → paths-BQwE2DU0.mjs} +2 -2
  11. package/dist/paths-a8wNIBFD.mjs +1 -0
  12. package/dist/{preview-jDZwLSul.mjs → preview-Bn5MTCPO.mjs} +2 -2
  13. package/dist/preview-_ahVwbF3.mjs +1 -0
  14. package/dist/public/assets/{GraphPanel-nbYklZ9C.js → GraphPanel-CdNqMYNB.js} +2 -2
  15. package/dist/public/assets/McpConsentDialogBody-Bgy0eAJw.js +1 -0
  16. package/dist/public/assets/{SourceEditor-CEqBKP5f.js → SourceEditor-DFAP44AB.js} +2 -2
  17. package/dist/public/assets/{clipboard-ZQ-AEssh.js → clipboard-Bau-T9ly.js} +6 -6
  18. package/dist/public/assets/{dialog-C2kd-BJI.js → dialog-XDohhbSr.js} +3 -3
  19. package/dist/public/assets/index-CVv4yIuY.css +1 -0
  20. package/dist/public/assets/index-Dpc5ZsZ1.js +27 -0
  21. package/dist/public/assets/{panel-CnHxXki4.js → panel-B3Oezbzt.js} +1 -1
  22. package/dist/public/assets/toggle-group-DRnV5hAP.js +1 -0
  23. package/dist/public/index.html +6 -6
  24. package/dist/{src-rqPIkHTi.mjs → src-C1Um6yPF.mjs} +3 -3
  25. package/dist/{src-DHnGx64r.mjs → src-C445dwsE.mjs} +1 -1
  26. package/dist/src-DblXU7Ud.mjs +1 -0
  27. package/dist/start-C-cNVeh0.mjs +1 -0
  28. package/dist/{start-DAAnFlO5.mjs → start-z2CFfZyW.mjs} +2 -2
  29. package/package.json +1 -1
  30. package/dist/constants-DA7Qh-Kl.mjs +0 -2
  31. package/dist/init-CFVYH-16.mjs +0 -1
  32. package/dist/init-DQNJ_f3z.mjs +0 -1
  33. package/dist/loader-89zKhhvs.mjs +0 -1
  34. package/dist/paths-BhmQnYL9.mjs +0 -1
  35. package/dist/preview-CULBnUoI.mjs +0 -1
  36. package/dist/public/assets/McpConsentDialogBody-BTLTOjWM.js +0 -1
  37. package/dist/public/assets/index-CGTgnYOo.css +0 -1
  38. package/dist/public/assets/index-DUIfxmm6.js +0 -21
  39. package/dist/public/assets/toggle-group-BNTPJpXY.js +0 -1
  40. package/dist/src-CBVTx8JJ.mjs +0 -1
  41. package/dist/start-D0wsbZmD.mjs +0 -1
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{a as e,i as t}from"./constants-DA7Qh-Kl.mjs";import{O as n,c as r,k as i}from"./src-CQw-HNNM.mjs";import{n as a,t as o}from"./paths-B9hXoumv.mjs";import{ct as s,lt as c,m as l,nt as u,st as d,ut as f}from"./src-rqPIkHTi.mjs";import{c as p,f as m,r as h}from"./server-lock-BI-SqMWk.mjs";import{i as g}from"./init-CODC0Drd.mjs";import{t as _}from"./is-object-DaHwJLOe.mjs";import{r as v}from"./init-DysAQtCG.mjs";import{i as y,n as ee,t as b}from"./loader-DfTFnc2z.mjs";import{o as x,s as S}from"./start-DAAnFlO5.mjs";import"./src-CBVTx8JJ.mjs";import{Command as C}from"commander";import{appendFileSync as w,closeSync as T,existsSync as E,mkdirSync as D,openSync as te,readFileSync as O,readdirSync as ne,realpathSync as re,statSync as ie,unlinkSync as ae,writeFileSync as oe}from"node:fs";import{homedir as se,hostname as ce}from"node:os";import{basename as le,dirname as ue,isAbsolute as de,join as fe,relative as pe,resolve as k}from"node:path";import{parse as me,stringify as he}from"yaml";import{createOAuthDeviceAuth as ge}from"@octokit/auth-oauth-device";import _e from"@inquirer/password";import{Octokit as ve}from"@octokit/rest";import{fileURLToPath as ye}from"node:url";import{randomUUID as be}from"node:crypto";import{execFileSync as xe,spawn as Se}from"node:child_process";import Ce from"simple-git";import{readFile as we,readdir as Te,stat as Ee}from"node:fs/promises";import{createServer as De,request as Oe}from"node:http";import ke from"picomatch";import{z as A}from"zod";import{McpServer as Ae}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as je}from"@modelcontextprotocol/sdk/server/stdio.js";import{RootsListChangedNotificationSchema as Me}from"@modelcontextprotocol/sdk/types.js";import{AsyncLocalStorage as Ne}from"node:async_hooks";import{Bash as Pe,ReadWriteFs as Fe}from"just-bash";import Ie from"shell-quote";const Le=`open-knowledge`;var Re=class{backend=`keyring`;async get(e){let{Entry:t}=await import(`@napi-rs/keyring`);try{let n=new t(Le,e).getPassword();return n==null?null:JSON.parse(n)}catch{return null}}async set(e,t,n,r){let{Entry:i}=await import(`@napi-rs/keyring`),a=new i(Le,e),o={login:t,token:n,...r};a.setPassword(JSON.stringify(o))}async clear(e){let{Entry:t}=await import(`@napi-rs/keyring`);try{new t(Le,e).deletePassword()}catch{}}},ze=class{backend=`file`;authFile;constructor(e){this.authFile=e??fe(se(),`.open-knowledge`,`auth.yml`)}read(){if(!E(this.authFile))return{};try{return me(O(this.authFile,`utf-8`))??{}}catch(e){let t=e instanceof Error?e.message:`unknown error`;return process.stderr.write(`[auth] Failed to parse ${this.authFile}: ${t}. Starting with empty credentials.\n`),{}}}write(e){let t=ue(this.authFile);E(t)||D(t,{recursive:!0,mode:448}),oe(this.authFile,he(e),{mode:384})}async get(e){return this.read()[e]??null}async set(e,t,n,r){let i=this.read();i[e]={login:t,token:n,...r},this.write(i)}async clear(e){let t=this.read();delete t[e],this.write(t)}};async function Be(e){try{let{Entry:e}=await import(`@napi-rs/keyring`);return new e(Le,`__probe__`),process.stderr.write(`[auth] token storage: OS keychain
2
+ import{a as e,i as t}from"./constants-Cs463jly.mjs";import{O as n,c as r,k as i}from"./src-CQw-HNNM.mjs";import{n as a,t as o}from"./paths-BQwE2DU0.mjs";import{ct as s,lt as c,m as l,nt as u,st as d,ut as f}from"./src-C1Um6yPF.mjs";import{c as p,f as m,r as h}from"./server-lock-BI-SqMWk.mjs";import{i as g}from"./init-DgjpYMQB.mjs";import{t as _}from"./is-object-DaHwJLOe.mjs";import{r as v}from"./init-Xod4U7aY.mjs";import{i as y,n as ee,t as b}from"./loader-Dw_7CMz3.mjs";import{o as x,s as S}from"./start-z2CFfZyW.mjs";import"./src-DblXU7Ud.mjs";import{Command as C}from"commander";import{appendFileSync as w,closeSync as T,existsSync as E,mkdirSync as D,openSync as te,readFileSync as O,readdirSync as ne,realpathSync as re,statSync as ie,unlinkSync as ae,writeFileSync as oe}from"node:fs";import{homedir as se,hostname as ce}from"node:os";import{basename as le,dirname as ue,isAbsolute as de,join as fe,relative as pe,resolve as k}from"node:path";import{parse as me,stringify as he}from"yaml";import{createOAuthDeviceAuth as ge}from"@octokit/auth-oauth-device";import _e from"@inquirer/password";import{Octokit as ve}from"@octokit/rest";import{fileURLToPath as ye}from"node:url";import{randomUUID as be}from"node:crypto";import{execFileSync as xe,spawn as Se}from"node:child_process";import Ce from"simple-git";import{readFile as we,readdir as Te,stat as Ee}from"node:fs/promises";import{createServer as De,request as Oe}from"node:http";import ke from"picomatch";import{z as A}from"zod";import{McpServer as Ae}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as je}from"@modelcontextprotocol/sdk/server/stdio.js";import{RootsListChangedNotificationSchema as Me}from"@modelcontextprotocol/sdk/types.js";import{AsyncLocalStorage as Ne}from"node:async_hooks";import{Bash as Pe,ReadWriteFs as Fe}from"just-bash";import Ie from"shell-quote";const Le=`open-knowledge`;var Re=class{backend=`keyring`;async get(e){let{Entry:t}=await import(`@napi-rs/keyring`);try{let n=new t(Le,e).getPassword();return n==null?null:JSON.parse(n)}catch{return null}}async set(e,t,n,r){let{Entry:i}=await import(`@napi-rs/keyring`),a=new i(Le,e),o={login:t,token:n,...r};a.setPassword(JSON.stringify(o))}async clear(e){let{Entry:t}=await import(`@napi-rs/keyring`);try{new t(Le,e).deletePassword()}catch{}}},ze=class{backend=`file`;authFile;constructor(e){this.authFile=e??fe(se(),`.open-knowledge`,`auth.yml`)}read(){if(!E(this.authFile))return{};try{return me(O(this.authFile,`utf-8`))??{}}catch(e){let t=e instanceof Error?e.message:`unknown error`;return process.stderr.write(`[auth] Failed to parse ${this.authFile}: ${t}. Starting with empty credentials.\n`),{}}}write(e){let t=ue(this.authFile);E(t)||D(t,{recursive:!0,mode:448}),oe(this.authFile,he(e),{mode:384})}async get(e){return this.read()[e]??null}async set(e,t,n,r){let i=this.read();i[e]={login:t,token:n,...r},this.write(i)}async clear(e){let t=this.read();delete t[e],this.write(t)}};async function Be(e){try{let{Entry:e}=await import(`@napi-rs/keyring`);return new e(Le,`__probe__`),process.stderr.write(`[auth] token storage: OS keychain
3
3
  `),new Re}catch{return process.stderr.write(`[auth] token storage: file (~/.open-knowledge/auth.yml)
4
4
  `),new ze(e)}}async function Ve(e,t,n){let r=He(await Ue(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 He(e){let t={};for(let n of e.split(`
5
5
  `)){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 Ue(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 We(e){let t=new C(`git-credential`);return t.description(`Git credential helper (git credential-helper protocol)`),t.command(`get`).description(`Lookup credentials from TokenStore (called by git)`).action(async()=>{let t=await e(),n=await Ve(process.stdin,process.stdout,t);process.exit(n)}),t}async function Ge(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=ge({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(`@octokit/request`)).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??[]}}function Ke(e){return process.env.OPEN_KNOWLEDGE_GITHUB_CLIENT_ID??e?.github?.oauthAppClientId??`Ov23liqlSd0V1MwR6rhI`}const qe=new Set([`gitlab.com`,`bitbucket.org`,`codeberg.org`,`gitea.com`,`sr.ht`,`sourcehut.org`]);function Je(e){let t=e.toLowerCase().replace(/:\d+$/,``);qe.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 Ye(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function Xe(e,t,n,r=Ge){let i=Ke(n),{host:a,json:o}=e;Je(a),o||process.stderr.write(`Logging in to ${a}…\n`);let s=await r({clientId:i,host:a===`github.com`?void 0:a,onVerification:e=>{e.userCode,e.verificationUri,o?Ye(!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`)}}),c=`unknown`,l,u;try{let e=a===`github.com`?`https://api.github.com`:`https://${a}/api/v3`,t=await fetch(`${e}/user`,{headers:{Authorization:`Bearer ${s.token}`,"User-Agent":`open-knowledge-cli`,Accept:`application/vnd.github+json`}});if(t.ok){let e=await t.json();c=e.login??c,l=e.name??void 0,u=e.email??void 0}}catch{}await t.set(a,c,s.token,{gitProtocol:`https`,name:l,email:u}),o?Ye(!0,{type:`complete`,host:a,login:c}):process.stderr.write(`✓ Logged in as ${c} on ${a}\n`)}function Ze(e,t){return new C(`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 n=>{await Xe(n,await t(),e())})}async function Qe(e,t,n){let{host:r,json:i}=e;Je(r);let a=await(n??(()=>_e({message:`Enter PAT:`})))();a||(process.stderr.write(`No token provided
@@ -7,7 +7,7 @@ import{a as e,i as t}from"./constants-DA7Qh-Kl.mjs";import{O as n,c as r,k as i}
7
7
  `),process.exit(1)}await t.set(r,c,a,{gitProtocol:`https`,name:l,email:u}),i?process.stdout.write(`${JSON.stringify({type:`complete`,host:r,login:c})}\n`):process.stderr.write(`✓ PAT stored for ${c} on ${r}\n`)}function $e(e){return new C(`pat`).description(`Store a Personal Access Token`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{await Qe(t,await e())})}async function et(e,t){let{host:n,json:r}=e;Je(n);let i=await t.get(n);i??(process.stderr.write(`Not logged in to ${n}\n`),process.exit(1));let a=n===`github.com`?void 0:`https://${n}/api/v3`,o=new ve({auth:i.token,...a?{baseUrl:a}:{}}),s=[];for await(let e of o.paginate.iterator(o.repos.listForAuthenticatedUser,{per_page:100,sort:`updated`}))for(let t of e.data)s.push({full_name:t.full_name,clone_url:t.clone_url,private:t.private});if(r)process.stdout.write(`${JSON.stringify({type:`repos`,host:n,repos:s})}\n`);else for(let e of s)process.stdout.write(`${e.full_name} ${e.clone_url}\n`)}function tt(e){return new C(`repos`).description(`List accessible repositories`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{await et(t,await e())})}async function nt(e,t){let{host:n}=e;await t.clear(n),process.stderr.write(`✓ Signed out from ${n}\n`)}function rt(e){return new C(`signout`).description(`Remove stored credentials`).option(`--host <host>`,`GitHub hostname`,`github.com`).action(async t=>{await nt(t,await e())})}async function it(e,t){let{host:n,json:r}=e;Je(n);let i=await t.get(n);i??(r?process.stdout.write(`${JSON.stringify({type:`status`,host:n,authenticated:!1})}\n`):process.stderr.write(`Not logged in to ${n}\n`),process.exit(1));let a=n===`github.com`?void 0:`https://${n}/api/v3`,o=new ve({auth:i.token,...a?{baseUrl:a}:{}});try{let{data:e}=await o.users.getAuthenticated();r?process.stdout.write(`${JSON.stringify({type:`status`,host:n,authenticated:!0,login:e.login,name:e.name,email:e.email})}\n`):process.stderr.write(`✓ Logged in as ${e.login} on ${n}\n`)}catch{r?process.stdout.write(JSON.stringify({type:`status`,host:n,authenticated:!1,error:`token invalid`})+`
8
8
  `):process.stderr.write(`✗ Token invalid for ${n}\n`),process.exit(1)}}function at(e){return new C(`status`).description(`Show authentication status`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{await it(t,await e())})}function ot(e){let t=new C(`auth`);t.description(`GitHub authentication management`);let n=()=>Be(),r=e??(()=>({}));return t.addCommand(Ze(r,n)),t.addCommand(at(n)),t.addCommand(tt(n)),t.addCommand(rt(n)),t.addCommand($e(n)),t.addCommand(We(n)),t}function st(e,t,n={}){let r=p(e,t);if(!E(r))return{status:`missing`,lockPath:r};let i;try{i=JSON.parse(O(r,`utf-8`))}catch{return{status:`corrupt`,lockPath:r}}if(!i||typeof i!=`object`||typeof i.pid!=`number`)return{status:`corrupt`,lockPath:r};let a=i,o=n.host??ce();return a.hostname===o?(n.isAlive??m)(a.pid)?{status:`alive`,lockPath:r,lock:a}:{status:`dead-pid`,lockPath:r,lock:a}:{status:`foreign-host`,lockPath:r,lock:a}}function ct(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 lt(e){let t=e.inspect??(t=>st(e.lockDir,t)),n=e.unlink??(e=>ae(e)),r=e.log??(e=>console.log(e)),i=e.error??(e=>console.error(e)),a=ct(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 ut(e){return new C(`clean`).description(`Prune stale / corrupt open-knowledge lock files (never touches live locks)`).action(()=>{lt({lockDir:a(o(e(),process.cwd()))}).failed.length>0&&(process.exitCode=1)})}function dt(){try{let e=xe(`gh`,[`auth`,`token`],{encoding:`utf-8`,stdio:[`ignore`,`pipe`,`pipe`],timeout:5e3}).trim();return e.length===0?{available:!1}:{available:!0,token:e}}catch{return{available:!1}}}async function ft(e,t,n={},r=dt){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`]}}function pt(e){return e.replace(/:\d+$/,``)}function mt(e){let t=e.trim();if(!t)return null;{let e=/^https?:\/\/([^/?#]+)\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t);if(e)return{protocol:`https`,hostname:pt(e[1]),owner:e[2],name:e[3]}}{let e=/^ssh:\/\/(?:[\w.-]+@)?([^/?#]+)\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t);if(e)return{protocol:`ssh`,hostname:pt(e[1]),owner:e[2],name:e[3]}}{let e=/^git:\/\/([^/?#]+)\/([\w.\-~%]+)\/([\w.\-~%]+?)(?:\.git)?\/?$/.exec(t);if(e)return{protocol:`git`,hostname:pt(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}const ht=[[`count`,0,10],[`compress`,10,20],[`receiv`,20,60],[`resolv`,60,100]];function gt(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 ht)if(n.includes(e))return{stage:t[1],pct:Math.round(i+r/100*(a-i))};return null}function _t(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function vt(e,t,n,r=process.cwd()){let i=mt(e);if(!i)throw Error(`Invalid git URL: ${e}`);let a=t.dir?k(r,t.dir):k(r,i.name);if(E(a)&&ne(a).length>0)throw Error(`Target directory is not empty: ${a}`);let o=await Be(),s=await ft(i.hostname,o,{}),c=Ce({baseDir:r,config:s.credentialArgs.length>=2?[s.credentialArgs[1]]:[],unsafe:{allowUnsafeCredentialHelper:!0}}).env({GIT_TERMINAL_PROMPT:`0`}),l=-1;if(c.outputHandler((e,n,r)=>{r.on(`data`,e=>{let n=e.toString(`utf-8`);for(let e of n.split(`
9
9
  `)){let n=gt(e);n&&n.pct!==l&&(l=n.pct,_t(t.json,{type:`progress`,pct:n.pct,stage:n.stage}),t.json||process.stderr.write(`\r Cloning… ${n.pct}%`))}})}),await c.clone(e,a,[`--progress`]),t.json||process.stderr.write(`
10
- `),!E(k(a,`.open-knowledge`)))try{let[{runInit:e},{ensureOkGitignoredAtRoot:t}]=await Promise.all([import(`./init-DQNJ_f3z.mjs`),import(`./init-CFVYH-16.mjs`)]);await e({cwd:a,mcp:!1});try{t(a)}catch{}}catch{}return a}function yt(e){return new C(`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).action(async(t,n,r)=>{let i=e();try{let a=await vt(t,{json:r.json,dir:n},i);if(r.json)_t(!0,{type:`complete`,dir:a});else{process.stderr.write(`✓ Cloned to ${a}\n`),process.chdir(a);let{startCommand:t}=await import(`./start-D0wsbZmD.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){let t=e instanceof Error?e.message:String(e);r.json?_t(!0,{type:`error`,message:t}):process.stderr.write(`✗ ${t}\n`),process.exitCode=1}})}const bt=new Ne;var xt=class e{sessionId;corrId;component;constructor(e=`mcp`,t){this.sessionId=t??be().slice(0,12),this.corrId=be().slice(0,8),this.component=e}info(e,t={}){this.emit(`info`,e,t)}warn(e,t={}){this.emit(`warn`,e,t)}error(e,t,n={}){let r=t?{error:t instanceof Error?t.message:String(t),...n}:n;this.emit(`error`,e,r)}debug(e,t={}){(process.env.MCP_DEBUG===`1`||process.env.DEBUG?.includes(`mcp`))&&this.emit(`debug`,e,t)}child(t){return new e(t??this.component,this.sessionId)}asCallback(){return e=>this.info(e)}emit(e,t,n){let r={ts:new Date().toISOString(),level:e,sessionId:this.sessionId,corrId:this.corrId,component:this.component,msg:t,...n},i=`${JSON.stringify(r)}\n`;process.stderr.write(i);let a=process.env.OK_LOG_FILE;if(a)try{w(a,i)}catch(e){console.warn(`[mcp-logger] Failed to write to OK_LOG_FILE: ${e instanceof Error?e.message:e}`)}}};function St(e=`mcp`){return new xt(e)}function Ct(e,t){return bt.run(e,t)}function wt(){return bt.getStore()}const Tt=new Set([`find`,`markdown`,`replace`]),Et=[`backlinks`,`deadLinks`,`documents`,`enrichedPaths`,`entries`,`forwardLinks`,`hints`,`hubs`,`orphans`,`results`],Dt=[`checkpointRef`,`cwd`,`fileCount`,`matchCount`,`ok`,`query`,`stdoutTruncated`,`truncated`];function j(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ot(e){return j(e)&&`requestId`in e}function kt(e,t){if(Tt.has(e))return{redacted:!0,type:`string`,length:t.length,lines:t.length===0?0:t.split(`
10
+ `),!E(k(a,`.open-knowledge`)))try{let[{runInit:e},{ensureOkGitignoredAtRoot:t}]=await Promise.all([import(`./init-2VnOB85F.mjs`),import(`./init-CCx9nR5M.mjs`)]);await e({cwd:a,mcp:!1});try{t(a)}catch{}}catch{}return a}function yt(e){return new C(`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).action(async(t,n,r)=>{let i=e();try{let a=await vt(t,{json:r.json,dir:n},i);if(r.json)_t(!0,{type:`complete`,dir:a});else{process.stderr.write(`✓ Cloned to ${a}\n`),process.chdir(a);let{startCommand:t}=await import(`./start-C-cNVeh0.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){let t=e instanceof Error?e.message:String(e);r.json?_t(!0,{type:`error`,message:t}):process.stderr.write(`✗ ${t}\n`),process.exitCode=1}})}const bt=new Ne;var xt=class e{sessionId;corrId;component;constructor(e=`mcp`,t){this.sessionId=t??be().slice(0,12),this.corrId=be().slice(0,8),this.component=e}info(e,t={}){this.emit(`info`,e,t)}warn(e,t={}){this.emit(`warn`,e,t)}error(e,t,n={}){let r=t?{error:t instanceof Error?t.message:String(t),...n}:n;this.emit(`error`,e,r)}debug(e,t={}){(process.env.MCP_DEBUG===`1`||process.env.DEBUG?.includes(`mcp`))&&this.emit(`debug`,e,t)}child(t){return new e(t??this.component,this.sessionId)}asCallback(){return e=>this.info(e)}emit(e,t,n){let r={ts:new Date().toISOString(),level:e,sessionId:this.sessionId,corrId:this.corrId,component:this.component,msg:t,...n},i=`${JSON.stringify(r)}\n`;process.stderr.write(i);let a=process.env.OK_LOG_FILE;if(a)try{w(a,i)}catch(e){console.warn(`[mcp-logger] Failed to write to OK_LOG_FILE: ${e instanceof Error?e.message:e}`)}}};function St(e=`mcp`){return new xt(e)}function Ct(e,t){return bt.run(e,t)}function wt(){return bt.getStore()}const Tt=new Set([`find`,`markdown`,`replace`]),Et=[`backlinks`,`deadLinks`,`documents`,`enrichedPaths`,`entries`,`forwardLinks`,`hints`,`hubs`,`orphans`,`results`],Dt=[`checkpointRef`,`cwd`,`fileCount`,`matchCount`,`ok`,`query`,`stdoutTruncated`,`truncated`];function j(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ot(e){return j(e)&&`requestId`in e}function kt(e,t){if(Tt.has(e))return{redacted:!0,type:`string`,length:t.length,lines:t.length===0?0:t.split(`
11
11
  `).length};let n=e===`command`?240:120;return t.length<=n?t:{type:`string`,length:t.length,preview:`${t.slice(0,n)}...`}}function At(e,t){if(t===null)return null;if(typeof t==`string`)return kt(e,t);if(typeof t==`number`||typeof t==`boolean`)return t;if(Array.isArray(t))return{type:`array`,length:t.length};if(j(t)){let e=Object.keys(t).sort();return{type:`object`,keyCount:e.length,keys:e.slice(0,12)}}if(t!==void 0)return{type:typeof t}}function jt(e,t){return j(t)?Object.fromEntries(Object.entries(t).map(([e,t])=>[e,At(e,t)])):At(e,t)}function Mt(e){let t={structuredKeys:Object.keys(e).sort()};for(let n of Dt)n in e&&(t[n]=e[n]);for(let n of Et){let r=e[n];Array.isArray(r)&&(t[`${n}Count`]=r.length)}return`previewUrl`in e&&(t.previewUrl=e.previewUrl??null),`previewUrlSource`in e&&(t.previewUrlSource=e.previewUrlSource),typeof e.stdout==`string`&&(t.stdoutChars=e.stdout.length),Array.isArray(e.warnings)&&(t.warningsCount=e.warnings.length),j(e.warning)&&(t.warning=!0,`previewUrl`in e.warning&&(t.warningPreviewUrl=e.warning.previewUrl??null)),j(e.ui)&&(t.uiBaseUrl=typeof e.ui.baseUrl==`string`||e.ui.baseUrl===null?e.ui.baseUrl:void 0,t.uiPort=typeof e.ui.port==`number`||e.ui.port===null?e.ui.port:void 0),t}function Nt(e){if(!j(e))return{resultType:typeof e};let t={isError:e.isError===!0};return Array.isArray(e.content)&&(t.contentItems=e.content.length,t.contentTextChars=e.content.reduce((e,t)=>j(t)&&typeof t.text==`string`?e+t.text.length:e,0)),j(e.structuredContent)&&Object.assign(t,Mt(e.structuredContent)),t}function Pt(e){return{connectionId:e.connectionId.slice(0,8),displayName:e.displayName,...e.clientInfo?.name?{clientName:e.clientInfo.name}:{},...e.label?{label:e.label}:{}}}function Ft(e){let t=e.at(-1);return Ot(t)?{toolArgs:e.length>1?e[0]:void 0,extra:t}:{toolArgs:e[0],extra:void 0}}function It(e,t,n){let r=n.logger;return r?async(...i)=>{let a=r.child(),o=Date.now(),{toolArgs:s,extra:c}=Ft(i);a.info(`tool start`,{tool:e,...c?.requestId===void 0?{}:{requestId:c.requestId},...c?.sessionId?{transportSessionId:c.sessionId}:{},...n.identityRef?.current?{agent:Pt(n.identityRef.current)}:{},...s===void 0?{}:{args:jt(e,s)}});try{let n=await Ct(a,async()=>await t(...i));return a.info(`tool finish`,{tool:e,...c?.requestId===void 0?{}:{requestId:c.requestId},durationMs:Date.now()-o,result:Nt(n)}),n}catch(t){throw a.error(`tool error`,t,{tool:e,...c?.requestId===void 0?{}:{requestId:c.requestId},durationMs:Date.now()-o}),t}}:t}function Lt(e,t){if(!t.logger)return e;let n=e.tool.bind(e),r=Object.create(e);return r.tool=((...e)=>{let r=String(e[0]),i=e.at(-1);if(typeof i!=`function`)return n(...e);let a=[...e];return a[a.length-1]=It(r,i,t),n(...a)}),r}const M="Absolute host path to resolve the request against. Defaults only when the MCP client advertises exactly one root; otherwise pass `cwd` explicitly.",Rt=A.string().max(200).optional().describe(`Optional one-line user-outcome description (≤80 chars). Appears as a bullet in the timeline.`);function N(e,t){return{content:[{type:`text`,text:e}],...t?{isError:!0}:{}}}function P(e,t,n){return{content:[{type:`text`,text:e}],structuredContent:t,...n?{isError:!0}:{}}}const F="Error: Hocuspocus server is not running. Start it with `open-knowledge start`, then retry.\nFor disk-only writes without real-time sync, use your native Edit tool directly.";async function zt(e,t){return typeof e==`function`?await e(t):e}async function Bt(e,t){return typeof e==`function`?await e(t):e}async function I(e,t,n){let r;try{r=await e(n)}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}try{let e=await Bt(t,r);return{ok:!0,cwd:r,config:e}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async function L(e,t,n,r){let i=await I(e,t,r);if(!i.ok)return i;let{cwd:a,config:o}=i;try{return{ok:!0,cwd:a,config:o,url:await zt(n,a)}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}function R(e){let t=e.toLowerCase();return t.endsWith(`.md`)?{ok:!0,docName:e.slice(0,-3)}:t.endsWith(`.mdx`)?{ok:!0,docName:e.slice(0,-4)}:t.endsWith(`.markdown`)?{ok:!1,error:`Error: docName "${e}" ends in ".markdown", which is not a supported extension. Use ".md" or ".mdx", or strip the extension to let the server auto-detect.`}:{ok:!0,docName:e}}async function z(e,t){let n;try{n=await fetch(`${e}${t}`,{signal:AbortSignal.timeout(3e4)})}catch(e){return{ok:!1,error:`Server unreachable: ${e instanceof Error?e.message:e}`}}try{return await n.json()}catch{return{ok:!1,error:`Server returned HTTP ${n.status} with non-JSON body`}}}async function B(e,t,n){let r;try{r=await fetch(`${e}${t}`,{method:`POST`,headers:{"Content-Type":`application/json`},body:n?JSON.stringify(n):void 0,signal:AbortSignal.timeout(3e4)})}catch(e){return{ok:!1,error:`Server unreachable: ${e instanceof Error?e.message:e}`}}try{return await r.json()}catch{return{ok:!1,error:`Server returned HTTP ${r.status} with non-JSON body`}}}function Vt(e,t){return`Promote existing research on this topic into a canonical article inside the project content directory. **Canonical, not provisional** — the output is the source of truth for future agents.
12
12
 
13
13
  Topic: ${e}
@@ -593,6 +593,6 @@ Folder metadata lives in \`config.yml\`, **not** in content files — this is in
593
593
  ${Object.entries(xi).map(([e,t])=>`### \`${e}\`\n${t}`).join(`
594
594
 
595
595
  `)}
596
- `}async function Oi(e,t){try{let t=e.replace(`ws://`,`http://`).replace(`wss://`,`https://`);return(await fetch(`${t}/api/document`,{signal:AbortSignal.timeout(2e3)})).ok}catch(n){return t.warn(`Hocuspocus probe failed`,{serverUrl:e,error:n instanceof Error?n.message:String(n)}),!1}}async function ki(n){let{projectDir:r,serverUrl:i,config:a,startupConfig:o,bypassProjectSelection:s=!1}=n;if(X=St(),X.info(`MCP server starting`,{startupCwd:r,bypassProjectSelection:s,serverUrlType:typeof i==`string`?`explicit`:`lazy`}),typeof i==`string`){let e=await Oi(i,X);X.info(`Hocuspocus detection complete`,{serverUrl:i,available:e})}else X.info(`server discovery is lazy per effective cwd`);let c=new Ae({name:t,version:e},{instructions:Di(o,{dynamicConfig:typeof a==`function`&&!s})}),l=Ti({startupCwd:r,bypassProjectSelection:s,listRoots:()=>c.server.listRoots(),logger:X}),u=Ei({startupCwd:r,resolveCwd:l.resolveCwd,bypassProjectSelection:s}),d=u.resolveCwdForTools;c.server.setNotificationHandler(Me,async()=>{l.invalidateRoots()});let f=async e=>{if(typeof i==`string`)return i.replace(`ws://`,`http://`).replace(`wss://`,`https://`);let t=e??await d();return(typeof i==`function`?await i(t):i)?.replace(`ws://`,`http://`).replace(`wss://`,`https://`)},p=be(),m=process.env.AGENT_LABEL||void 0,h={current:{connectionId:p,label:m,displayName:m??`Agent`,colorSeed:m??p}};c.server.oninitialized=()=>{let e=c.server.getClientVersion();h.current={connectionId:p,clientInfo:e?{name:e.name,version:e.version}:void 0,label:m,displayName:m??e?.name??`Agent`,colorSeed:m??e?.name??p},X?.info(`agent identity established`,{displayName:h.current.displayName,connectionId:p.slice(0,8),clientName:e?.name})},Si(c,{serverUrl:f,resolveCwd:d,config:a,identityRef:h,logger:X});let g=new je;await c.connect(g),X.info(`MCP server running on stdio`);let{startKeepalive:_}=await import(`./keepalive-UJIeMtkM.mjs`),v=_({resolveWsUrl:async()=>{let e=await u.getKeepaliveCwd();if(!e)return;let t=await f(e);if(t)return t.replace(/^http:/,`ws:`).replace(/^https:/,`wss:`)},connectionId:`agent-${p}`,logger:X.child(`keepalive`)}),y=e=>{X?.info(`MCP server shutting down`,{signal:e});try{v.close()}catch{}process.exit(0)};process.on(`SIGINT`,()=>y(`SIGINT`)),process.on(`SIGTERM`,()=>y(`SIGTERM`))}function Ai(e){if(e===void 0||e===``)return;let t=Number.parseInt(e,10);if(!(Number.isNaN(t)||t<=0))return t}function ji(e){if(e.portOverride!==void 0){let t=Number.parseInt(e.portOverride,10);if(Number.isNaN(t))return{action:`disk-only`,message:`invalid --port value '${e.portOverride}' — disk-only mode`};if(t>0){let n=`ws://${e.host}:${t}`;return{action:`connect`,url:n,message:`using --port override, connecting to ${n}`}}return{action:`disk-only`,message:`--port=0 — disk-only mode`}}let t=e.readLock();if(t&&t.port>0&&e.isAlive(t.pid)){let e=`ws://localhost:${t.port}`;return{action:`connect`,url:e,message:`connected to running instance at ${e} (pid ${t.pid})`}}return e.envAutoStart===`0`?{action:`disk-only`,message:`auto-spawn disabled via OK_MCP_AUTOSTART=0 — disk-only mode`}:e.configAutoStart?t?{action:`spawn`,message:`existing lock is not usable (port=${t.port}, pid=${t.pid}) — spawning ok start`}:{action:`spawn`,message:`no running instance — spawning ok start`}:{action:`disk-only`,message:`auto-spawn disabled via config.mcp.autoStart=false — disk-only mode`}}async function Mi(e){let t=e.readLock??(()=>h(e.lockDir)),n=e.isAlive??m,r=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),i=e.spawn??Se,a=e.readErrorLog??(e=>E(e)?O(e,`utf-8`).trim():``),o=e.openErrorLog??(e=>te(e,`w`)),s=e.closeFd??(e=>T(e)),c=e.timeoutMs??5e3,l=e.pollIntervalMs??100,u=ji({host:e.host,portOverride:e.portOverride,envAutoStart:e.envAutoStart,configAutoStart:e.configAutoStart,readLock:t,isAlive:n});if(e.logger?.info(`auto-start decision`,{action:u.action,message:u.message,contentDir:e.contentDir}),u.action===`connect`)return{serverUrl:u.url,message:u.message};if(u.action===`disk-only`)return{serverUrl:void 0,message:u.message};E(e.lockDir)||D(e.lockDir,{recursive:!0});let d=fe(e.lockDir,`last-spawn-error.log`),f=o(d),p,g,_=S();e.logger?.info(`spawning server`,{command:_.command,cwd:e.contentDir,timeoutMs:c});try{try{p=i(_.command,[..._.prefixArgs,`start`],{detached:!0,stdio:[`ignore`,`ignore`,f],cwd:e.contentDir}),p.on(`error`,e=>{g=e instanceof Error?e.message:String(e)}),p.unref()}catch(e){g=e instanceof Error?e.message:String(e)}}finally{try{s(f)}catch{}}let v=Date.now()+c;for(;Date.now()<v;){if(g){let t=a(d);throw e.logger?.error(`spawn failed`,void 0,{error:g,stderr:t}),Error(`Error: spawn failed: ${g}${t?` stderr:\n${t}`:``}`)}await r(l);let i=t();if(i&&i.port>0&&n(i.pid)){let t=`ws://localhost:${i.port}`;return e.logger?.info(`server ready after spawn`,{url:t,pid:i.pid}),{serverUrl:t,message:`spawned ok start; connected at ${t} (pid ${i.pid})`}}}if(g){let t=a(d);throw e.logger?.error(`spawn failed (post-deadline)`,void 0,{error:g,stderr:t}),Error(`Error: spawn failed: ${g}${t?` stderr:\n${t}`:``}`)}let y=a(d),ee=(c/1e3).toFixed(c%1e3==0?0:2),b=p?.pid,x=``;throw typeof b==`number`&&(x=n(b)?` child pid=${b} is still running — raise OK_MCP_SPAWN_TIMEOUT_MS if this is a slow boot.`:` child pid=${b} exited — check last-spawn-error.log.`),e.logger?.error(`spawn poll timeout`,void 0,{timeoutMs:c,childPid:b,childAlive:typeof b==`number`?n(b):void 0,stderr:y||void 0}),Error(`Error: server did not start within ${ee}s.${x}${y?` stderr:\n${y}`:``}`)}function Ni(e){if(e.portOverride!==void 0){let t=Number.parseInt(e.portOverride,10);if(Number.isNaN(t)||t<=0)return async()=>void 0;let n=`ws://${e.host}:${t}`;return async()=>n}let t=e.ensureServerRunningFn??Mi,n=e.cacheMs??1e3,r=new Map,i=new Map;return async s=>{let c=await y(s??e.startupCwd),l=Date.now(),u=r.get(c);if(u&&u.expiresAt>l)return e.logger?.debug(`server url cache hit`,{cwd:c,url:u.url}),u.url;let d=i.get(c);if(d)return e.logger?.debug(`server url resolution pending`,{cwd:c}),await d;e.logger?.debug(`server url cache miss`,{cwd:c});let f=(async()=>{let i=await e.resolveConfig(c),s=o(i,c),l=a(s),u=e.readLock,d=u?()=>u(l):void 0,f=await t({lockDir:l,contentDir:s,host:i.server.host,portOverride:void 0,envAutoStart:e.envAutoStart,configAutoStart:i.mcp.autoStart,logger:e.logger,timeoutMs:e.timeoutMs,pollIntervalMs:e.pollIntervalMs,spawn:e.spawn,readLock:d,isAlive:e.isAlive,sleep:e.sleep,readErrorLog:e.readErrorLog,openErrorLog:e.openErrorLog,closeFd:e.closeFd});return r.set(c,{url:f.serverUrl,expiresAt:Date.now()+n}),f.serverUrl})();i.set(c,f);try{return await f}finally{i.delete(c)}}}function Pi(e){return new C(`mcp`).description(`Start MCP stdio server for project knowledge base`).option(`-p, --port <port>`,`Override port discovery and connect to this port (0 = disk-only)`,void 0).action(async t=>{try{let n=e(),r=process.cwd(),i=b({startupCwd:r,startupConfig:n}),a=Ai(process.env.OK_MCP_SPAWN_TIMEOUT_MS),o,s;if(t.port!==void 0){let e=Number.parseInt(t.port,10);Number.isNaN(e)?(o=void 0,s=`invalid --port value '${t.port}' — disk-only mode`):e>0?(o=`ws://${n.server.host}:${e}`,s=`using --port override, connecting to ${o}`):(o=void 0,s=`--port=0 — disk-only mode`)}else o=Ni({startupCwd:r,resolveConfig:i,host:n.server.host,portOverride:void 0,envAutoStart:process.env.OK_MCP_AUTOSTART,timeoutMs:a}),s=`project server discovery/autostart is lazy per effective cwd`;process.stderr.write(`[mcp] ${s}\n`),await ki({projectDir:r,serverUrl:o,config:i,startupConfig:n,bypassProjectSelection:t.port!==void 0})}catch(e){process.stderr.write(`MCP server failed to start: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}})}function Fi(e){return new C(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-CULBnUoI.mjs`),r=e(),i=process.cwd(),a=o(r,i),s;try{s=t({projectDir:i,contentDir:a,include:r.content.include,exclude:r.content.exclude})}catch(e){console.error(`Content preview failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}process.stdout.write(`${n(s,i)}\n`),s.totalCount===0&&s.warnings.length>0&&(process.exitCode=1)})}function Z(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function Ii(e,t,n=process.cwd()){let r=e.op??`sync`,i=h(a(o(t,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`},body:JSON.stringify({op:r})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`Server responded with ${n.status}`)}Z(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 s=Ce({baseDir:n});if(r===`sync`||r===`pull`){Z(e.json,{type:`step`,step:`pull`});let t=await s.pull();Z(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Z(e.json,{type:`step`,step:`push`}),await s.push(),Z(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
597
- `)),Z(e.json,{type:`complete`,op:r}),e.json||process.stderr.write(`✓ ${r} complete\n`)}function Li(e){return new C(`sync`).description(`Commit, pull, and push to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ii({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 Ri(e){return new C(`pull`).description(`Pull changes from the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ii({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 zi(e){return new C(`push`).description(`Push commits to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ii({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 Bi(e,t){return{server:Vi(`server`,e),ui:Vi(`ui`,t)}}function Vi(e,t){switch(t.status){case`missing`:return{name:e,state:`missing`,alive:!1};case`corrupt`:return{name:e,state:`corrupt`,alive:!1};case`foreign-host`:return{name:e,state:`foreign-host`,pid:t.lock.pid,port:t.lock.port,startedAt:t.lock.startedAt,host:t.lock.hostname,alive:`unknown`};case`dead-pid`:return{name:e,state:`dead-pid`,pid:t.lock.pid,port:t.lock.port,startedAt:t.lock.startedAt,host:t.lock.hostname,alive:!1};case`alive`:return{name:e,state:`alive`,pid:t.lock.pid,port:t.lock.port,startedAt:t.lock.startedAt,host:t.lock.hostname,alive:!0}}}function Hi(e){return`${Ui(e.server)}\n${Ui(e.ui)}`}function Ui(e){let t=e.name===`server`?`server`:`ui `;return e.state===`missing`?`${t} not running`:e.state===`corrupt`?`${t} lock file corrupt — run \`ok clean\``:e.state===`foreign-host`?`${t} foreign host (${e.host}) pid=${e.pid} port=${e.port}`:e.state===`dead-pid`?`${t} stale (dead pid=${e.pid}) — run \`ok clean\``:`${t} alive pid=${e.pid} port=${e.port} started=${e.startedAt}`}function Wi(e){let t=e.inspect??(t=>st(e.lockDir,t)),n=e.log??(e=>console.log(e)),r=Bi(t(`server`),t(`ui`));return e.json?n(JSON.stringify(r,null,2)):n(Hi(r)),r}function Gi(e){return new C(`status`).description(`Show live state of the server + ui lockfiles for this project`).option(`--json`,`Emit structured JSON instead of formatted text`).action(t=>{Wi({lockDir:a(o(e(),process.cwd())),json:t.json===!0})})}function Ki(e,t){let n=[];return e.status===`alive`&&n.push({name:`server`,pid:e.lock.pid,port:e.lock.port}),t.status===`alive`&&n.push({name:`ui`,pid:t.lock.pid,port:t.lock.port}),{targets:n}}function qi(e){let t=e.inspect??(t=>st(e.lockDir,t)),n=e.kill??((e,t)=>process.kill(e,t)),r=e.log??(e=>console.log(e)),i=e.error??(e=>console.error(e)),a=Ki(t(`server`),t(`ui`));if(a.targets.length===0)return r(`No running open-knowledge processes.`),{stopped:[],failed:[],hadTargets:!1};let o=[],s=[];for(let e of a.targets)try{n(e.pid,`SIGTERM`),o.push(e)}catch(t){s.push({target:e,error:t instanceof Error?t.message:String(t)})}return o.length>0&&r(`Stopped: ${o.map(e=>`${e.name} (pid=${e.pid}, port=${e.port})`).join(`, `)}`),s.length>0&&i(`Failed to stop: ${s.map(({target:e,error:t})=>`${e.name} (pid=${e.pid}): ${t}`).join(`; `)}`),{stopped:o,failed:s,hadTargets:!0}}function Ji(e){return new C(`stop`).description(`Stop the running open-knowledge server and UI (live only)`).action(()=>{qi({lockDir:a(o(e(),process.cwd()))}).failed.length>0&&(process.exitCode=1)})}const Yi=1e4,Xi=[`connection`,`keep-alive`,`proxy-authenticate`,`proxy-authorization`,`te`,`trailer`,`transfer-encoding`,`upgrade`,`cookie`,`set-cookie`];async function Zi(e){let t=e.upstreamTimeoutMs??Yi,n=De((n,r)=>{$i(n,r,e.upstreamHost,e.upstreamPort,t)});await new Promise((t,r)=>{let i=e=>r(e);n.once(`error`,i),n.listen(e.listenPort,e.host,()=>{n.off(`error`,i),t()})});let r=n.address();return{httpServer:n,port:typeof r==`object`&&r?r.port:e.listenPort,close:()=>new Promise(e=>{n.close(()=>e())})}}function Qi(e,t,n){$i(e,t,n.upstreamHost,n.upstreamPort,n.upstreamTimeoutMs??Yi)}function $i(e,t,n,r,i){let a={...e.headers};delete a.host;for(let e of Xi)delete a[e];e.setTimeout(3e4,()=>{if(t.headersSent)try{t.end()}catch{}else try{t.writeHead(408,{"Content-Type":`text/plain`}),t.end(`Request Timeout`)}catch{}try{e.socket?.destroy()}catch{}});let o=Oe({host:n,port:r,method:e.method,path:e.url,headers:{...a,host:`${n}:${r}`}},e=>{let n={...e.headers};for(let e of Xi)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.writeHead(504,{"Content-Type":`text/plain`}),t.end(`Gateway Timeout`);else try{t.end()}catch{}o.destroy()}),o.on(`error`,()=>{if(!t.headersSent)t.writeHead(502,{"Content-Type":`text/plain`}),t.end(`Bad Gateway`);else try{t.end()}catch{}}),e.on(`error`,()=>{o.destroy()}),e.pipe(o)}async function ea(e){await Promise.all(e.map(e=>new Promise(t=>{e.close(()=>t())})))}async function ta(e){let{existsSync:t}=await import(`node:fs`),{createServer:n}=await import(`node:http`),{resolve:i}=await import(`node:path`),{acquireUiLock:a,readServerLock:o,releaseUiLock:s,updateUiLockPort:c}=await import(`./src-DHnGx64r.mjs`),{default:l}=await import(`sirv`),{resolveContentDir:u,resolveLockDir:d}=await import(`./paths-BhmQnYL9.mjs`),f=u(e.config,e.cwd),p=d(f);a(p,{port:0,worktreeRoot:e.cwd});let m=import.meta.dirname??new URL(`.`,import.meta.url).pathname,h=[i(m,`public`),i(m,`../../app/dist`),i(m,`../../../app/dist`)].find(e=>t(e)),g=h?l(h,{single:!0,gzip:!0,immutable:!0}):null,_=t(f)?l(f,{dotfiles:!1,dev:!0}):null,v=e.port,y=null,ee=(e,t)=>{let n=e.url?.split(`?`)[0];if(n===`/api/config`&&(e.method===`GET`||e.method===`HEAD`)){y?.();let n=o(p),r=n&&n.port>0?`ws://localhost:${n.port}/collab`:null,i=JSON.stringify({collabUrl:r,previewUrl:null,port:v});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(i);return}if(n?.startsWith(`/api/`)){y?.();let r=o(p);if(!r||r.port<=0){t.writeHead(503,{"Content-Type":`application/json`,"Cache-Control":`no-store`}),t.end(JSON.stringify({error:"Collab server not running. Start `ok start` or run `ok status`.",path:n}));return}Qi(e,t,{upstreamHost:`localhost`,upstreamPort:r.port});return}if(decodeURIComponent(n?.replace(/^\//,``)??``)&&_){t.setHeader(`X-Content-Type-Options`,`nosniff`),_(e,t,()=>{g?g(e,t):na(t)});return}if(g){g(e,t);return}na(t)},b=e.host===void 0?[`::1`,`127.0.0.1`]:[e.host],x=[],S=e.port;try{for(let e of b){let t=n(ee);x.push(t),await new Promise((n,r)=>{let i=e=>r(e);t.once(`error`,i),t.listen(S,e,()=>{t.off(`error`,i);let e=t.address();typeof e==`object`&&e&&(S=e.port),n()})})}}catch(e){await Promise.all(x.map(e=>new Promise(t=>{try{e.close(()=>t())}catch{t()}})));try{s(p)}catch{}throw e}let C=S;v=C,c(p,C);let w=e.scheduler??r,T=e.safetyNetMs??432e5,E=null,D=!1,te=!1,O=()=>{D||(D=!0,E!==null&&(w.clearTimeout(E),E=null))},ne=()=>{if(O(),!te){te=!0;try{s(p)}catch{}}},re=()=>{D||T<=0||(E!==null&&(w.clearTimeout(E),E=null),E=w.setTimeout(()=>{E=null,console.warn(`[ui] safety-net (${T}ms) reached — shutting down (D-025 backstop)`);try{e.onSafetyNet?.()}catch{}for(let e of x)try{e.close()}catch{}ne()},T))},ie=()=>{D||T<=0||re()};return y=ie,re(),{httpServers:x,port:C,release:ne,detachSafetyNet:O,nudgeSafetyNet:ie}}function na(e){e.writeHead(404),e.end(`Not found`)}function ra(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 t}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 e}return 0}async function ia(e){let t=e.readLock??(async()=>{let{readUiLock:t}=await import(`./src-DHnGx64r.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 Zi({listenPort:e.requestedPort,host:e.host,upstreamHost:`localhost`,upstreamPort:r}),upstreamPort:r}}function aa(e){return new C(`ui`).description(`Serve the Open Knowledge React editor UI`).option(`-p, --port <port>`,`UI port (default: $PORT env or 0 / kernel-allocated)`).option(`-H, --host <host>`,"UI host. Default: two-socket loopback bind (`[::1]` + `127.0.0.1`) so cross-family collisions fail loud (D-033). 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-xJqYhQcY.mjs`),{UiLockCollisionError:r}=await import(`./src-DHnGx64r.mjs`),{resolveContentDir:i,resolveLockDir:a}=await import(`./paths-BhmQnYL9.mjs`),o=e(),s=t.host,c;try{c=ra(t.port,process.env.PORT)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=1;return}try{let e=await ta({config:o,cwd:process.cwd(),port:c,host:s}),t=s===void 0||s===`::`||s===`0.0.0.0`?`localhost`:s;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)}};ea(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=a(i(o,process.cwd())),l=s??`localhost`,u;try{u=await ia({requestedPort:c,host:l,lockDir:t})}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}u.mode===`already-running`&&(console.log(`UI already running at http://${l}:${u.port}`),process.exit(0)),console.log(`UI running at http://${l}:${u.upstreamPort}; acting as HTTP proxy on port ${u.handle.port}`);let d=!1,f=e=>{d||(d=!0,console.log(n(`\n[ui-proxy] Shutting down (${e})...`)),u.handle.close().finally(()=>process.exit(process.exitCode??0)),setTimeout(()=>process.exit(process.exitCode??0),2e3).unref())};process.once(`SIGINT`,()=>f(`SIGINT`)),process.once(`SIGTERM`,()=>f(`SIGTERM`))}})}process.argv.includes(`--no-color`)?(process.env.NO_COLOR=`1`,delete process.env.FORCE_COLOR):process.argv.includes(`--color`)&&(process.env.FORCE_COLOR=`1`,delete process.env.NO_COLOR);const Q=new C;let $;Q.name(`open-knowledge`).description(`Local-first knowledge base with CRDT collaboration`).version(e).option(`--cwd <path>`,`Working directory`).option(`--log-level <level>`,`Log level`,`info`).option(`--no-color`,`Disable color output`).option(`--color`,`Force color output`).hook(`preAction`,e=>{let t=e.opts(),n=t.cwd;n!==void 0&&process.chdir(n);let{config:r}=ee(n),i=e.args.length===0?t:e.commands[0]?.opts()??{};i.port!==void 0&&(r.server.port=Number(i.port)),i.host!==void 0&&(r.server.host=i.host),process.env.PORT&&(r.server.port=Number(process.env.PORT)),process.env.HOST&&(r.server.host=process.env.HOST),$=r});const oa=x(()=>$);Q.addCommand(oa,{isDefault:!0});const sa=Pi(()=>$);Q.addCommand(sa),Q.addCommand(v());const ca=Fi(()=>$);Q.addCommand(ca);const la=aa(()=>$);Q.addCommand(la),Q.addCommand(Ji(()=>$)),Q.addCommand(ut(()=>$)),Q.addCommand(Gi(()=>$)),Q.addCommand(ot(()=>$)),Q.addCommand(yt(()=>$)),Q.addCommand(Li(()=>$)),Q.addCommand(zi(()=>$)),Q.addCommand(Ri(()=>$)),await Q.parseAsync();export{};
596
+ `}async function Oi(e,t){try{let t=e.replace(`ws://`,`http://`).replace(`wss://`,`https://`);return(await fetch(`${t}/api/document`,{signal:AbortSignal.timeout(2e3)})).ok}catch(n){return t.warn(`Hocuspocus probe failed`,{serverUrl:e,error:n instanceof Error?n.message:String(n)}),!1}}async function ki(n){let{projectDir:r,serverUrl:i,config:a,startupConfig:o,bypassProjectSelection:s=!1}=n;if(X=St(),X.info(`MCP server starting`,{startupCwd:r,bypassProjectSelection:s,serverUrlType:typeof i==`string`?`explicit`:`lazy`}),typeof i==`string`){let e=await Oi(i,X);X.info(`Hocuspocus detection complete`,{serverUrl:i,available:e})}else X.info(`server discovery is lazy per effective cwd`);let c=new Ae({name:t,version:e},{instructions:Di(o,{dynamicConfig:typeof a==`function`&&!s})}),l=Ti({startupCwd:r,bypassProjectSelection:s,listRoots:()=>c.server.listRoots(),logger:X}),u=Ei({startupCwd:r,resolveCwd:l.resolveCwd,bypassProjectSelection:s}),d=u.resolveCwdForTools;c.server.setNotificationHandler(Me,async()=>{l.invalidateRoots()});let f=async e=>{if(typeof i==`string`)return i.replace(`ws://`,`http://`).replace(`wss://`,`https://`);let t=e??await d();return(typeof i==`function`?await i(t):i)?.replace(`ws://`,`http://`).replace(`wss://`,`https://`)},p=be(),m=process.env.AGENT_LABEL||void 0,h={current:{connectionId:p,label:m,displayName:m??`Agent`,colorSeed:m??p}};c.server.oninitialized=()=>{let e=c.server.getClientVersion();h.current={connectionId:p,clientInfo:e?{name:e.name,version:e.version}:void 0,label:m,displayName:m??e?.name??`Agent`,colorSeed:m??e?.name??p},X?.info(`agent identity established`,{displayName:h.current.displayName,connectionId:p.slice(0,8),clientName:e?.name})},Si(c,{serverUrl:f,resolveCwd:d,config:a,identityRef:h,logger:X});let g=new je;await c.connect(g),X.info(`MCP server running on stdio`);let{startKeepalive:_}=await import(`./keepalive-UJIeMtkM.mjs`),v=_({resolveWsUrl:async()=>{let e=await u.getKeepaliveCwd();if(!e)return;let t=await f(e);if(t)return t.replace(/^http:/,`ws:`).replace(/^https:/,`wss:`)},connectionId:`agent-${p}`,logger:X.child(`keepalive`)}),y=e=>{X?.info(`MCP server shutting down`,{signal:e});try{v.close()}catch{}process.exit(0)};process.on(`SIGINT`,()=>y(`SIGINT`)),process.on(`SIGTERM`,()=>y(`SIGTERM`))}function Ai(e){if(e===void 0||e===``)return;let t=Number.parseInt(e,10);if(!(Number.isNaN(t)||t<=0))return t}function ji(e){if(e.portOverride!==void 0){let t=Number.parseInt(e.portOverride,10);if(Number.isNaN(t))return{action:`disk-only`,message:`invalid --port value '${e.portOverride}' — disk-only mode`};if(t>0){let n=`ws://${e.host}:${t}`;return{action:`connect`,url:n,message:`using --port override, connecting to ${n}`}}return{action:`disk-only`,message:`--port=0 — disk-only mode`}}let t=e.readLock();if(t&&t.port>0&&e.isAlive(t.pid)){let e=`ws://localhost:${t.port}`;return{action:`connect`,url:e,message:`connected to running instance at ${e} (pid ${t.pid})`}}return e.envAutoStart===`0`?{action:`disk-only`,message:`auto-spawn disabled via OK_MCP_AUTOSTART=0 — disk-only mode`}:e.configAutoStart?t?{action:`spawn`,message:`existing lock is not usable (port=${t.port}, pid=${t.pid}) — spawning ok start`}:{action:`spawn`,message:`no running instance — spawning ok start`}:{action:`disk-only`,message:`auto-spawn disabled via config.mcp.autoStart=false — disk-only mode`}}async function Mi(e){let t=e.readLock??(()=>h(e.lockDir)),n=e.isAlive??m,r=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),i=e.spawn??Se,a=e.readErrorLog??(e=>E(e)?O(e,`utf-8`).trim():``),o=e.openErrorLog??(e=>te(e,`w`)),s=e.closeFd??(e=>T(e)),c=e.timeoutMs??5e3,l=e.pollIntervalMs??100,u=ji({host:e.host,portOverride:e.portOverride,envAutoStart:e.envAutoStart,configAutoStart:e.configAutoStart,readLock:t,isAlive:n});if(e.logger?.info(`auto-start decision`,{action:u.action,message:u.message,contentDir:e.contentDir}),u.action===`connect`)return{serverUrl:u.url,message:u.message};if(u.action===`disk-only`)return{serverUrl:void 0,message:u.message};E(e.lockDir)||D(e.lockDir,{recursive:!0});let d=fe(e.lockDir,`last-spawn-error.log`),f=o(d),p,g,_=S();e.logger?.info(`spawning server`,{command:_.command,cwd:e.contentDir,timeoutMs:c});try{try{p=i(_.command,[..._.prefixArgs,`start`],{detached:!0,stdio:[`ignore`,`ignore`,f],cwd:e.contentDir}),p.on(`error`,e=>{g=e instanceof Error?e.message:String(e)}),p.unref()}catch(e){g=e instanceof Error?e.message:String(e)}}finally{try{s(f)}catch{}}let v=Date.now()+c;for(;Date.now()<v;){if(g){let t=a(d);throw e.logger?.error(`spawn failed`,void 0,{error:g,stderr:t}),Error(`Error: spawn failed: ${g}${t?` stderr:\n${t}`:``}`)}await r(l);let i=t();if(i&&i.port>0&&n(i.pid)){let t=`ws://localhost:${i.port}`;return e.logger?.info(`server ready after spawn`,{url:t,pid:i.pid}),{serverUrl:t,message:`spawned ok start; connected at ${t} (pid ${i.pid})`}}}if(g){let t=a(d);throw e.logger?.error(`spawn failed (post-deadline)`,void 0,{error:g,stderr:t}),Error(`Error: spawn failed: ${g}${t?` stderr:\n${t}`:``}`)}let y=a(d),ee=(c/1e3).toFixed(c%1e3==0?0:2),b=p?.pid,x=``;throw typeof b==`number`&&(x=n(b)?` child pid=${b} is still running — raise OK_MCP_SPAWN_TIMEOUT_MS if this is a slow boot.`:` child pid=${b} exited — check last-spawn-error.log.`),e.logger?.error(`spawn poll timeout`,void 0,{timeoutMs:c,childPid:b,childAlive:typeof b==`number`?n(b):void 0,stderr:y||void 0}),Error(`Error: server did not start within ${ee}s.${x}${y?` stderr:\n${y}`:``}`)}function Ni(e){if(e.portOverride!==void 0){let t=Number.parseInt(e.portOverride,10);if(Number.isNaN(t)||t<=0)return async()=>void 0;let n=`ws://${e.host}:${t}`;return async()=>n}let t=e.ensureServerRunningFn??Mi,n=e.cacheMs??1e3,r=new Map,i=new Map;return async s=>{let c=await y(s??e.startupCwd),l=Date.now(),u=r.get(c);if(u&&u.expiresAt>l)return e.logger?.debug(`server url cache hit`,{cwd:c,url:u.url}),u.url;let d=i.get(c);if(d)return e.logger?.debug(`server url resolution pending`,{cwd:c}),await d;e.logger?.debug(`server url cache miss`,{cwd:c});let f=(async()=>{let i=await e.resolveConfig(c),s=o(i,c),l=a(s),u=e.readLock,d=u?()=>u(l):void 0,f=await t({lockDir:l,contentDir:s,host:i.server.host,portOverride:void 0,envAutoStart:e.envAutoStart,configAutoStart:i.mcp.autoStart,logger:e.logger,timeoutMs:e.timeoutMs,pollIntervalMs:e.pollIntervalMs,spawn:e.spawn,readLock:d,isAlive:e.isAlive,sleep:e.sleep,readErrorLog:e.readErrorLog,openErrorLog:e.openErrorLog,closeFd:e.closeFd});return r.set(c,{url:f.serverUrl,expiresAt:Date.now()+n}),f.serverUrl})();i.set(c,f);try{return await f}finally{i.delete(c)}}}function Pi(e){return new C(`mcp`).description(`Start MCP stdio server for project knowledge base`).option(`-p, --port <port>`,`Override port discovery and connect to this port (0 = disk-only)`,void 0).action(async t=>{try{let n=e(),r=process.cwd(),i=b({startupCwd:r,startupConfig:n}),a=Ai(process.env.OK_MCP_SPAWN_TIMEOUT_MS),o,s;if(t.port!==void 0){let e=Number.parseInt(t.port,10);Number.isNaN(e)?(o=void 0,s=`invalid --port value '${t.port}' — disk-only mode`):e>0?(o=`ws://${n.server.host}:${e}`,s=`using --port override, connecting to ${o}`):(o=void 0,s=`--port=0 — disk-only mode`)}else o=Ni({startupCwd:r,resolveConfig:i,host:n.server.host,portOverride:void 0,envAutoStart:process.env.OK_MCP_AUTOSTART,timeoutMs:a}),s=`project server discovery/autostart is lazy per effective cwd`;process.stderr.write(`[mcp] ${s}\n`),await ki({projectDir:r,serverUrl:o,config:i,startupConfig:n,bypassProjectSelection:t.port!==void 0})}catch(e){process.stderr.write(`MCP server failed to start: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}})}function Fi(e){return new C(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-_ahVwbF3.mjs`),r=e(),i=process.cwd(),a=o(r,i),s;try{s=t({projectDir:i,contentDir:a,include:r.content.include,exclude:r.content.exclude})}catch(e){console.error(`Content preview failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}process.stdout.write(`${n(s,i)}\n`),s.totalCount===0&&s.warnings.length>0&&(process.exitCode=1)})}function Z(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function Ii(e,t,n=process.cwd()){let r=e.op??`sync`,i=h(a(o(t,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`},body:JSON.stringify({op:r})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`Server responded with ${n.status}`)}Z(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 s=Ce({baseDir:n});if(r===`sync`||r===`pull`){Z(e.json,{type:`step`,step:`pull`});let t=await s.pull();Z(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Z(e.json,{type:`step`,step:`push`}),await s.push(),Z(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
597
+ `)),Z(e.json,{type:`complete`,op:r}),e.json||process.stderr.write(`✓ ${r} complete\n`)}function Li(e){return new C(`sync`).description(`Commit, pull, and push to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ii({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 Ri(e){return new C(`pull`).description(`Pull changes from the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ii({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 zi(e){return new C(`push`).description(`Push commits to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ii({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 Bi(e,t){return{server:Vi(`server`,e),ui:Vi(`ui`,t)}}function Vi(e,t){switch(t.status){case`missing`:return{name:e,state:`missing`,alive:!1};case`corrupt`:return{name:e,state:`corrupt`,alive:!1};case`foreign-host`:return{name:e,state:`foreign-host`,pid:t.lock.pid,port:t.lock.port,startedAt:t.lock.startedAt,host:t.lock.hostname,alive:`unknown`};case`dead-pid`:return{name:e,state:`dead-pid`,pid:t.lock.pid,port:t.lock.port,startedAt:t.lock.startedAt,host:t.lock.hostname,alive:!1};case`alive`:return{name:e,state:`alive`,pid:t.lock.pid,port:t.lock.port,startedAt:t.lock.startedAt,host:t.lock.hostname,alive:!0}}}function Hi(e){return`${Ui(e.server)}\n${Ui(e.ui)}`}function Ui(e){let t=e.name===`server`?`server`:`ui `;return e.state===`missing`?`${t} not running`:e.state===`corrupt`?`${t} lock file corrupt — run \`ok clean\``:e.state===`foreign-host`?`${t} foreign host (${e.host}) pid=${e.pid} port=${e.port}`:e.state===`dead-pid`?`${t} stale (dead pid=${e.pid}) — run \`ok clean\``:`${t} alive pid=${e.pid} port=${e.port} started=${e.startedAt}`}function Wi(e){let t=e.inspect??(t=>st(e.lockDir,t)),n=e.log??(e=>console.log(e)),r=Bi(t(`server`),t(`ui`));return e.json?n(JSON.stringify(r,null,2)):n(Hi(r)),r}function Gi(e){return new C(`status`).description(`Show live state of the server + ui lockfiles for this project`).option(`--json`,`Emit structured JSON instead of formatted text`).action(t=>{Wi({lockDir:a(o(e(),process.cwd())),json:t.json===!0})})}function Ki(e,t){let n=[];return e.status===`alive`&&n.push({name:`server`,pid:e.lock.pid,port:e.lock.port}),t.status===`alive`&&n.push({name:`ui`,pid:t.lock.pid,port:t.lock.port}),{targets:n}}function qi(e){let t=e.inspect??(t=>st(e.lockDir,t)),n=e.kill??((e,t)=>process.kill(e,t)),r=e.log??(e=>console.log(e)),i=e.error??(e=>console.error(e)),a=Ki(t(`server`),t(`ui`));if(a.targets.length===0)return r(`No running open-knowledge processes.`),{stopped:[],failed:[],hadTargets:!1};let o=[],s=[];for(let e of a.targets)try{n(e.pid,`SIGTERM`),o.push(e)}catch(t){s.push({target:e,error:t instanceof Error?t.message:String(t)})}return o.length>0&&r(`Stopped: ${o.map(e=>`${e.name} (pid=${e.pid}, port=${e.port})`).join(`, `)}`),s.length>0&&i(`Failed to stop: ${s.map(({target:e,error:t})=>`${e.name} (pid=${e.pid}): ${t}`).join(`; `)}`),{stopped:o,failed:s,hadTargets:!0}}function Ji(e){return new C(`stop`).description(`Stop the running open-knowledge server and UI (live only)`).action(()=>{qi({lockDir:a(o(e(),process.cwd()))}).failed.length>0&&(process.exitCode=1)})}const Yi=1e4,Xi=[`connection`,`keep-alive`,`proxy-authenticate`,`proxy-authorization`,`te`,`trailer`,`transfer-encoding`,`upgrade`,`cookie`,`set-cookie`];async function Zi(e){let t=e.upstreamTimeoutMs??Yi,n=De((n,r)=>{$i(n,r,e.upstreamHost,e.upstreamPort,t)});await new Promise((t,r)=>{let i=e=>r(e);n.once(`error`,i),n.listen(e.listenPort,e.host,()=>{n.off(`error`,i),t()})});let r=n.address();return{httpServer:n,port:typeof r==`object`&&r?r.port:e.listenPort,close:()=>new Promise(e=>{n.close(()=>e())})}}function Qi(e,t,n){$i(e,t,n.upstreamHost,n.upstreamPort,n.upstreamTimeoutMs??Yi)}function $i(e,t,n,r,i){let a={...e.headers};delete a.host;for(let e of Xi)delete a[e];e.setTimeout(3e4,()=>{if(t.headersSent)try{t.end()}catch{}else try{t.writeHead(408,{"Content-Type":`text/plain`}),t.end(`Request Timeout`)}catch{}try{e.socket?.destroy()}catch{}});let o=Oe({host:n,port:r,method:e.method,path:e.url,headers:{...a,host:`${n}:${r}`}},e=>{let n={...e.headers};for(let e of Xi)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.writeHead(504,{"Content-Type":`text/plain`}),t.end(`Gateway Timeout`);else try{t.end()}catch{}o.destroy()}),o.on(`error`,()=>{if(!t.headersSent)t.writeHead(502,{"Content-Type":`text/plain`}),t.end(`Bad Gateway`);else try{t.end()}catch{}}),e.on(`error`,()=>{o.destroy()}),e.pipe(o)}async function ea(e){await Promise.all(e.map(e=>new Promise(t=>{e.close(()=>t())})))}async function ta(e){let{existsSync:t}=await import(`node:fs`),{createServer:n}=await import(`node:http`),{resolve:i}=await import(`node:path`),{acquireUiLock:a,readServerLock:o,releaseUiLock:s,updateUiLockPort:c}=await import(`./src-C445dwsE.mjs`),{default:l}=await import(`sirv`),{resolveContentDir:u,resolveLockDir:d}=await import(`./paths-a8wNIBFD.mjs`),f=u(e.config,e.cwd),p=d(f);a(p,{port:0,worktreeRoot:e.cwd});let m=import.meta.dirname??new URL(`.`,import.meta.url).pathname,h=[i(m,`public`),i(m,`../../app/dist`),i(m,`../../../app/dist`)].find(e=>t(e)),g=h?l(h,{single:!0,gzip:!0,immutable:!0}):null,_=t(f)?l(f,{dotfiles:!1,dev:!0}):null,v=e.port,y=null,ee=(e,t)=>{let n=e.url?.split(`?`)[0];if(n===`/api/config`&&(e.method===`GET`||e.method===`HEAD`)){y?.();let n=o(p),r=n&&n.port>0?`ws://localhost:${n.port}/collab`:null,i=JSON.stringify({collabUrl:r,previewUrl:null,port:v});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(i);return}if(n?.startsWith(`/api/`)){y?.();let r=o(p);if(!r||r.port<=0){t.writeHead(503,{"Content-Type":`application/json`,"Cache-Control":`no-store`}),t.end(JSON.stringify({error:"Collab server not running. Start `ok start` or run `ok status`.",path:n}));return}Qi(e,t,{upstreamHost:`localhost`,upstreamPort:r.port});return}if(decodeURIComponent(n?.replace(/^\//,``)??``)&&_){t.setHeader(`X-Content-Type-Options`,`nosniff`),_(e,t,()=>{g?g(e,t):na(t)});return}if(g){g(e,t);return}na(t)},b=e.host===void 0?[`::1`,`127.0.0.1`]:[e.host],x=[],S=e.port;try{for(let e of b){let t=n(ee);x.push(t),await new Promise((n,r)=>{let i=e=>r(e);t.once(`error`,i),t.listen(S,e,()=>{t.off(`error`,i);let e=t.address();typeof e==`object`&&e&&(S=e.port),n()})})}}catch(e){await Promise.all(x.map(e=>new Promise(t=>{try{e.close(()=>t())}catch{t()}})));try{s(p)}catch{}throw e}let C=S;v=C,c(p,C);let w=e.scheduler??r,T=e.safetyNetMs??432e5,E=null,D=!1,te=!1,O=()=>{D||(D=!0,E!==null&&(w.clearTimeout(E),E=null))},ne=()=>{if(O(),!te){te=!0;try{s(p)}catch{}}},re=()=>{D||T<=0||(E!==null&&(w.clearTimeout(E),E=null),E=w.setTimeout(()=>{E=null,console.warn(`[ui] safety-net (${T}ms) reached — shutting down (D-025 backstop)`);try{e.onSafetyNet?.()}catch{}for(let e of x)try{e.close()}catch{}ne()},T))},ie=()=>{D||T<=0||re()};return y=ie,re(),{httpServers:x,port:C,release:ne,detachSafetyNet:O,nudgeSafetyNet:ie}}function na(e){e.writeHead(404),e.end(`Not found`)}function ra(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 t}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 e}return 0}async function ia(e){let t=e.readLock??(async()=>{let{readUiLock:t}=await import(`./src-C445dwsE.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 Zi({listenPort:e.requestedPort,host:e.host,upstreamHost:`localhost`,upstreamPort:r}),upstreamPort:r}}function aa(e){return new C(`ui`).description(`Serve the Open Knowledge React editor UI`).option(`-p, --port <port>`,`UI port (default: $PORT env or 0 / kernel-allocated)`).option(`-H, --host <host>`,"UI host. Default: two-socket loopback bind (`[::1]` + `127.0.0.1`) so cross-family collisions fail loud (D-033). 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-xJqYhQcY.mjs`),{UiLockCollisionError:r}=await import(`./src-C445dwsE.mjs`),{resolveContentDir:i,resolveLockDir:a}=await import(`./paths-a8wNIBFD.mjs`),o=e(),s=t.host,c;try{c=ra(t.port,process.env.PORT)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=1;return}try{let e=await ta({config:o,cwd:process.cwd(),port:c,host:s}),t=s===void 0||s===`::`||s===`0.0.0.0`?`localhost`:s;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)}};ea(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=a(i(o,process.cwd())),l=s??`localhost`,u;try{u=await ia({requestedPort:c,host:l,lockDir:t})}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}u.mode===`already-running`&&(console.log(`UI already running at http://${l}:${u.port}`),process.exit(0)),console.log(`UI running at http://${l}:${u.upstreamPort}; acting as HTTP proxy on port ${u.handle.port}`);let d=!1,f=e=>{d||(d=!0,console.log(n(`\n[ui-proxy] Shutting down (${e})...`)),u.handle.close().finally(()=>process.exit(process.exitCode??0)),setTimeout(()=>process.exit(process.exitCode??0),2e3).unref())};process.once(`SIGINT`,()=>f(`SIGINT`)),process.once(`SIGTERM`,()=>f(`SIGTERM`))}})}process.argv.includes(`--no-color`)?(process.env.NO_COLOR=`1`,delete process.env.FORCE_COLOR):process.argv.includes(`--color`)&&(process.env.FORCE_COLOR=`1`,delete process.env.NO_COLOR);const Q=new C;let $;Q.name(`open-knowledge`).description(`Local-first knowledge base with CRDT collaboration`).version(e).option(`--cwd <path>`,`Working directory`).option(`--log-level <level>`,`Log level`,`info`).option(`--no-color`,`Disable color output`).option(`--color`,`Force color output`).hook(`preAction`,e=>{let t=e.opts(),n=t.cwd;n!==void 0&&process.chdir(n);let{config:r}=ee(n),i=e.args.length===0?t:e.commands[0]?.opts()??{};i.port!==void 0&&(r.server.port=Number(i.port)),i.host!==void 0&&(r.server.host=i.host),process.env.PORT&&(r.server.port=Number(process.env.PORT)),process.env.HOST&&(r.server.host=process.env.HOST),$=r});const oa=x(()=>$);Q.addCommand(oa,{isDefault:!0});const sa=Pi(()=>$);Q.addCommand(sa),Q.addCommand(v());const ca=Fi(()=>$);Q.addCommand(ca);const la=aa(()=>$);Q.addCommand(la),Q.addCommand(Ji(()=>$)),Q.addCommand(ut(()=>$)),Q.addCommand(Gi(()=>$)),Q.addCommand(ot(()=>$)),Q.addCommand(yt(()=>$)),Q.addCommand(Li(()=>$)),Q.addCommand(zi(()=>$)),Q.addCommand(Ri(()=>$)),await Q.parseAsync();export{};
598
598
  //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1,2 @@
1
+ import"./src-CQw-HNNM.mjs";var e=`0.0.0-dev-20260424010642`;const t=`AGENTS.md`,n=`config.yml`,r=`cache`,i=e,a=`open-knowledge`;export{i as a,a as i,r as n,n as r,t};
2
+ //# sourceMappingURL=constants-Cs463jly.mjs.map
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{c as e,i as t,l as n,o as r,s as i,t as a}from"./init-DysAQtCG.mjs";import{n as o,r as s}from"./loader-DfTFnc2z.mjs";import"./src-CBVTx8JJ.mjs";export{e as ALL_EDITOR_IDS,s as ConfigSchema,n as EDITOR_TARGETS,a as detectInstalledEditors,o as loadConfig,t as readExistingMcpEntry,r as writeEditorMcpConfig,i as writeUserMcpConfigs};
1
+ import{c as e,i as t,l as n,o as r,s as i,t as a}from"./init-Xod4U7aY.mjs";import{n as o,r as s}from"./loader-Dw_7CMz3.mjs";import"./src-DblXU7Ud.mjs";export{e as ALL_EDITOR_IDS,s as ConfigSchema,n as EDITOR_TARGETS,a as detectInstalledEditors,o as loadConfig,t as readExistingMcpEntry,r as writeEditorMcpConfig,i as writeUserMcpConfigs};
@@ -0,0 +1 @@
1
+ import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./init-Xod4U7aY.mjs";export{o as detectInstalledEditors,n as formatInitResult,i as initCommand,t as readExistingMcpEntry,e as runInit,r as writeEditorMcpConfig,a as writeUserMcpConfigs};
@@ -0,0 +1 @@
1
+ import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./init-DgjpYMQB.mjs";export{o as CLAUDE_MD_SECTION,n as OK_MARKER_BEGIN,i as OK_MARKER_END,t as PREVIEW_GUIDANCE,e as ensureOkGitignoredAtRoot,r as initContent,a as upsertRootInstructions};
@@ -1,4 +1,4 @@
1
- import{n as e,r as t,t as n}from"./constants-DA7Qh-Kl.mjs";import{O as r}from"./src-CQw-HNNM.mjs";import{existsSync as i,mkdirSync as a,readFileSync as o,realpathSync as s,writeFileSync as c}from"node:fs";import{join as l,resolve as u}from"node:path";const d=`<!-- open-knowledge:begin -->`,f=`<!-- open-knowledge:end -->`,p=/<!-- open-knowledge:begin -->[\s\S]*?<!-- open-knowledge:end -->/,m=`# ${r}/ — Open Knowledge config
1
+ import{n as e,r as t,t as n}from"./constants-Cs463jly.mjs";import{O as r}from"./src-CQw-HNNM.mjs";import{existsSync as i,mkdirSync as a,readFileSync as o,realpathSync as s,writeFileSync as c}from"node:fs";import{join as l,resolve as u}from"node:path";const d=`<!-- open-knowledge:begin -->`,f=`<!-- open-knowledge:end -->`,p=/<!-- open-knowledge:begin -->[\s\S]*?<!-- open-knowledge:end -->/,m=`# ${r}/ — Open Knowledge config
2
2
 
3
3
  This directory holds Open Knowledge's configuration for this project. It's **not** where content lives — content lives wherever \`content.dir\` + \`content.include\` in \`config.yml\` point. The default is the repo root with \`**/*.md\`, so any markdown file in the project is fair game. Inspect \`config.yml\` for the actual setting.
4
4
 
@@ -227,4 +227,4 @@ ${f}`;function v(e,t,r){let a=[n,...r??[]],u=new Set,d=[];for(let n of a){let r=
227
227
 
228
228
  `)?`
229
229
  `:``}${n}`,`utf-8`),`appended`)}const x=[{name:n,content:m},{name:`.gitignore`,content:`${e}/\nserver.lock\nui.lock\nsync-state.json\n`},{name:t,content:h}];function S(t){let n=u(t,r),i=[],o=[];a(n,{recursive:!0}),a(l(n,e),{recursive:!0});for(let e of x)y(l(n,e.name),e.content)?i.push(e.name):o.push(e.name);return{created:i,skipped:o}}export{b as a,g as i,d as n,S as o,f as r,v as s,_ as t};
230
- //# sourceMappingURL=init-CODC0Drd.mjs.map
230
+ //# sourceMappingURL=init-DgjpYMQB.mjs.map
@@ -1,5 +1,5 @@
1
- import{i as e}from"./constants-DA7Qh-Kl.mjs";import{O as t}from"./src-CQw-HNNM.mjs";import{n,t as r}from"./src-rqPIkHTi.mjs";import{o as i,s as a}from"./init-CODC0Drd.mjs";import{t as o}from"./preview-jDZwLSul.mjs";import{t as s}from"./is-object-DaHwJLOe.mjs";import{Command as c}from"commander";import{existsSync as l,mkdirSync as u,readFileSync as d,writeFileSync as f}from"node:fs";import{homedir as p}from"node:os";import{basename as m,dirname as h,isAbsolute as g,join as _,posix as v,relative as y,resolve as b,sep as x,win32 as S}from"node:path";import{parse as C,stringify as w}from"smol-toml";const T=[`claude`,`claude-desktop`,`cursor`,`vscode`,`windsurf`,`codex`],ee=[`@inkeep/open-knowledge`,`mcp`],te={MCP_DEBUG:`1`,OK_LOG_FILE:`/tmp/ok-mcp.log`};function E(e=process.argv[1]){if(!e)throw Error(`Cannot infer the local CLI entry for --dev-mcp because process.argv[1] is empty.`);let t=b(e);if(m(t)===`cli.mjs`&&m(h(t))===`dist`)return t;let n=t.split(x),r=n.lastIndexOf(`packages`);if(r===-1||n[r+1]!==`cli`)throw Error(`Cannot infer the repo root for --dev-mcp from ${t}. Run the local CLI from this repo so the built dist path can be derived.`);let i=n.slice(0,r);return _(i.length===0?x:i.join(x),`packages`,`cli`,`dist`,`cli.mjs`)}function D(e={}){return e.cliPath?{command:e.cliPath,args:[`mcp`]}:e.mode===`dev`?{command:`node`,args:[E(e.cliEntryPath),`mcp`],env:{...te}}:{command:`npx`,args:[...ee]}}function O(e){return e===`win32`?S:v}function k(e={}){let t=e.platformName??process.platform,n=e.home??p(),r=e.env??process.env,i=O(t);return t===`darwin`?i.join(n,`Library`,`Application Support`):t===`win32`?r.APPDATA??i.join(n,`AppData`,`Roaming`):r.XDG_CONFIG_HOME??i.join(n,`.config`)}function A(e={}){let t=e.platformName??process.platform,n=e.home??p();return O(t).join(n,`.claude.json`)}function j(e={}){let t=e.platformName??process.platform,n=e.home??p(),r=e.env??process.env;if(t===`darwin`)return v.join(n,`Library`,`Application Support`,`Claude`,`claude_desktop_config.json`);if(t===`win32`){let e=r.APPDATA??S.join(n,`AppData`,`Roaming`);return S.join(e,`Claude`,`claude_desktop_config.json`)}throw Error(`Claude Desktop is not available on ${t}. Supported: macOS, Windows.`)}function M(e={}){let t=e.platformName??process.platform,n=e.home??p();return O(t).join(n,`.cursor`,`mcp.json`)}function N(e={}){return O(e.platformName??process.platform).join(k(e),`Code`,`User`,`mcp.json`)}function P(e={}){let t=e.platformName??process.platform,n=e.home??p();return O(t).join(n,`.codeium`,`windsurf`,`mcp_config.json`)}function F(e={}){let t=e.platformName??process.platform,n=e.home??p();return(e.env??process.env).CODEX_HOME??O(t).join(n,`.codex`)}function I(e={}){return O(e.platformName??process.platform).join(F(e),`config.toml`)}function L(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>L(e,t[n]));if(s(e)&&s(t)){let n=Object.keys(e).sort(),r=Object.keys(t).sort();return n.length===r.length&&n.every((e,t)=>e===r[t])&&n.every(n=>L(e[n],t[n]))}return!1}function R(e,t){return Object.entries(t).every(([t,n])=>L(e[t],n))}function z(e,t){return{...e,...t}}function B(e){return{...e,isCompatible(t,n,r){return R(t,e.buildEntry(n,r))},mergeManagedFields(t,n,r){return z(t,e.buildEntry(n,r))}}}const V={claude:B({id:`claude`,label:`Claude Code`,configPath:(e,t)=>A({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>_(t??p(),`.claude`),legacyProjectConfigPath:e=>_(e,`.mcp.json`),instructionsPath:e=>_(e,`CLAUDE.md`)}),"claude-desktop":B({id:`claude-desktop`,label:`Claude Desktop`,configPath:(e,t)=>j({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>h(j({home:t}))}),cursor:B({id:`cursor`,label:`Cursor`,configPath:(e,t)=>M({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>h(M({home:t})),legacyProjectConfigPath:e=>_(e,`.cursor`,`mcp.json`)}),vscode:B({id:`vscode`,label:`VS Code`,configPath:(e,t)=>N({home:t}),format:`json`,topLevelKey:`servers`,serverName:()=>e,buildEntry:(e,t)=>({type:`stdio`,...D(t)}),scope:`global`,detectPath:(e,t)=>h(N({home:t})),legacyProjectConfigPath:e=>_(e,`.vscode`,`mcp.json`)}),windsurf:B({id:`windsurf`,label:`Windsurf`,configPath:(e,t)=>P({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>h(P({home:t}))}),codex:B({id:`codex`,label:`Codex`,configPath:(e,t)=>I({home:t}),format:`toml`,topLevelKey:`mcp_servers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>h(I({home:t})),legacyProjectConfigPath:e=>_(e,`.codex`,`config.toml`)})};function H(e){let t=e.filter(e=>!(e in V));if(t.length>0)throw Error(`Unknown editor(s): ${t.join(`, `)}. Valid options: ${T.join(`, `)}`);return e.map(e=>V[e])}function U(e){if(!l(e))return{};let t=d(e,`utf-8`).trim();if(t===``)return{};try{let n=JSON.parse(t);if(s(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 W(e){if(!l(e))return{};let t=d(e,`utf-8`).trim();if(t===``)return{};try{let n=C(t);if(s(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 G(e,t){u(h(e),{recursive:!0}),f(e,`${JSON.stringify(t,null,2)}\n`,`utf-8`)}function K(e,t){u(h(e),{recursive:!0});let n=w(t);f(e,n.endsWith(`
1
+ import{i as e}from"./constants-Cs463jly.mjs";import{O as t}from"./src-CQw-HNNM.mjs";import{n,t as r}from"./src-C1Um6yPF.mjs";import{o as i,s as a}from"./init-DgjpYMQB.mjs";import{t as o}from"./preview-Bn5MTCPO.mjs";import{t as s}from"./is-object-DaHwJLOe.mjs";import{Command as c}from"commander";import{existsSync as l,mkdirSync as u,readFileSync as d,writeFileSync as f}from"node:fs";import{homedir as p}from"node:os";import{basename as m,dirname as h,isAbsolute as g,join as _,posix as v,relative as y,resolve as b,sep as x,win32 as S}from"node:path";import{parse as C,stringify as w}from"smol-toml";const T=[`claude`,`claude-desktop`,`cursor`,`vscode`,`windsurf`,`codex`],ee=[`@inkeep/open-knowledge`,`mcp`],te={MCP_DEBUG:`1`,OK_LOG_FILE:`/tmp/ok-mcp.log`};function E(e=process.argv[1]){if(!e)throw Error(`Cannot infer the local CLI entry for --dev-mcp because process.argv[1] is empty.`);let t=b(e);if(m(t)===`cli.mjs`&&m(h(t))===`dist`)return t;let n=t.split(x),r=n.lastIndexOf(`packages`);if(r===-1||n[r+1]!==`cli`)throw Error(`Cannot infer the repo root for --dev-mcp from ${t}. Run the local CLI from this repo so the built dist path can be derived.`);let i=n.slice(0,r);return _(i.length===0?x:i.join(x),`packages`,`cli`,`dist`,`cli.mjs`)}function D(e={}){return e.cliPath?{command:e.cliPath,args:[`mcp`]}:e.mode===`dev`?{command:`node`,args:[E(e.cliEntryPath),`mcp`],env:{...te}}:{command:`npx`,args:[...ee]}}function O(e){return e===`win32`?S:v}function k(e={}){let t=e.platformName??process.platform,n=e.home??p(),r=e.env??process.env,i=O(t);return t===`darwin`?i.join(n,`Library`,`Application Support`):t===`win32`?r.APPDATA??i.join(n,`AppData`,`Roaming`):r.XDG_CONFIG_HOME??i.join(n,`.config`)}function A(e={}){let t=e.platformName??process.platform,n=e.home??p();return O(t).join(n,`.claude.json`)}function j(e={}){let t=e.platformName??process.platform,n=e.home??p(),r=e.env??process.env;if(t===`darwin`)return v.join(n,`Library`,`Application Support`,`Claude`,`claude_desktop_config.json`);if(t===`win32`){let e=r.APPDATA??S.join(n,`AppData`,`Roaming`);return S.join(e,`Claude`,`claude_desktop_config.json`)}throw Error(`Claude Desktop is not available on ${t}. Supported: macOS, Windows.`)}function M(e={}){let t=e.platformName??process.platform,n=e.home??p();return O(t).join(n,`.cursor`,`mcp.json`)}function N(e={}){return O(e.platformName??process.platform).join(k(e),`Code`,`User`,`mcp.json`)}function P(e={}){let t=e.platformName??process.platform,n=e.home??p();return O(t).join(n,`.codeium`,`windsurf`,`mcp_config.json`)}function F(e={}){let t=e.platformName??process.platform,n=e.home??p();return(e.env??process.env).CODEX_HOME??O(t).join(n,`.codex`)}function I(e={}){return O(e.platformName??process.platform).join(F(e),`config.toml`)}function L(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>L(e,t[n]));if(s(e)&&s(t)){let n=Object.keys(e).sort(),r=Object.keys(t).sort();return n.length===r.length&&n.every((e,t)=>e===r[t])&&n.every(n=>L(e[n],t[n]))}return!1}function R(e,t){return Object.entries(t).every(([t,n])=>L(e[t],n))}function z(e,t){return{...e,...t}}function B(e){return{...e,isCompatible(t,n,r){return R(t,e.buildEntry(n,r))},mergeManagedFields(t,n,r){return z(t,e.buildEntry(n,r))}}}const V={claude:B({id:`claude`,label:`Claude Code`,configPath:(e,t)=>A({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>_(t??p(),`.claude`),legacyProjectConfigPath:e=>_(e,`.mcp.json`),instructionsPath:e=>_(e,`CLAUDE.md`)}),"claude-desktop":B({id:`claude-desktop`,label:`Claude Desktop`,configPath:(e,t)=>j({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>h(j({home:t}))}),cursor:B({id:`cursor`,label:`Cursor`,configPath:(e,t)=>M({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>h(M({home:t})),legacyProjectConfigPath:e=>_(e,`.cursor`,`mcp.json`)}),vscode:B({id:`vscode`,label:`VS Code`,configPath:(e,t)=>N({home:t}),format:`json`,topLevelKey:`servers`,serverName:()=>e,buildEntry:(e,t)=>({type:`stdio`,...D(t)}),scope:`global`,detectPath:(e,t)=>h(N({home:t})),legacyProjectConfigPath:e=>_(e,`.vscode`,`mcp.json`)}),windsurf:B({id:`windsurf`,label:`Windsurf`,configPath:(e,t)=>P({home:t}),format:`json`,topLevelKey:`mcpServers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>h(P({home:t}))}),codex:B({id:`codex`,label:`Codex`,configPath:(e,t)=>I({home:t}),format:`toml`,topLevelKey:`mcp_servers`,serverName:()=>e,buildEntry:(e,t)=>D(t),scope:`global`,detectPath:(e,t)=>h(I({home:t})),legacyProjectConfigPath:e=>_(e,`.codex`,`config.toml`)})};function H(e){let t=e.filter(e=>!(e in V));if(t.length>0)throw Error(`Unknown editor(s): ${t.join(`, `)}. Valid options: ${T.join(`, `)}`);return e.map(e=>V[e])}function U(e){if(!l(e))return{};let t=d(e,`utf-8`).trim();if(t===``)return{};try{let n=JSON.parse(t);if(s(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 W(e){if(!l(e))return{};let t=d(e,`utf-8`).trim();if(t===``)return{};try{let n=C(t);if(s(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 G(e,t){u(h(e),{recursive:!0}),f(e,`${JSON.stringify(t,null,2)}\n`,`utf-8`)}function K(e,t){u(h(e),{recursive:!0});let n=w(t);f(e,n.endsWith(`
2
2
  `)?n:`${n}\n`,`utf-8`)}const q=`0.0.1`,J=`open-knowledge-ui`;function ne(e,t={}){let n=_(e,`.claude`,`launch.json`),r=t.mode===`dev`?{name:J,runtimeExecutable:`node`,runtimeArgs:[E(t.cliEntryPath),`ui`],port:3e3}:{name:J,runtimeExecutable:`npx`,runtimeArgs:[`@inkeep/open-knowledge`,`ui`],port:3e3};try{if(!l(n))return u(h(n),{recursive:!0}),f(n,`${JSON.stringify({version:q,configurations:[r]},null,2)}\n`,`utf-8`),{action:`created`,configPath:n};let e=d(n,`utf-8`).trim(),t=e?JSON.parse(e):{};if(!s(t))return{action:`failed`,configPath:n,error:`launch.json root is not an object`};let i=Array.isArray(t.configurations)?t.configurations:[],a=i.findIndex(e=>s(e)&&e.name===J);a>=0?i[a]=r:i.push(r);let o={...t,version:t.version??q,configurations:i};return f(n,`${JSON.stringify(o,null,2)}\n`,`utf-8`),{action:a>=0?`merged`:`created`,configPath:n}}catch(e){return{action:`failed`,configPath:n,error:e instanceof Error?e.message:String(e)}}}function Y(e,t,n){try{return l(e.detectPath?.(t,n)??h(e.configPath(t,n)))}catch{return!1}}function X(e,t,n,r){let i=e.serverName(t),a;try{a=e.configPath(t,r)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:``,serverName:i,error:t instanceof Error?t.message:String(t)}}if(!n.skipAvailabilityCheck&&!Y(e,t,r))return{editorId:e.id,label:e.label,action:`skipped-missing`,configPath:a,serverName:i};let o;try{o=e.format===`toml`?W(a):U(a)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:a,serverName:i,error:t instanceof Error?t.message:String(t)}}let s=o[e.topLevelKey]??{},c=s[i],l;try{l=e.buildEntry(t,n)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:a,serverName:i,error:t instanceof Error?t.message:String(t)}}let u={...o,[e.topLevelKey]:{...s,[i]:l}};try{e.format===`toml`?K(a,u):G(a,u)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:a,serverName:i,error:t instanceof Error?t.message:String(t)}}return{editorId:e.id,label:e.label,action:c===void 0?`written`:`overwritten`,configPath:a,serverName:i}}function re(e,t){let n=e.legacyProjectConfigPath?.(t);if(!(!n||!l(n)))return{editorId:e.id,label:e.label,path:n}}async function ie(e){let t=H(e.editors),n={mode:`published`,cliPath:e.cliPath,skipAvailabilityCheck:!0};return t.map(t=>X(t,``,n,e.home))}function ae(e,t,n){let r;try{r=e.configPath(t,n)}catch{return null}let i;try{i=e.format===`toml`?W(r):U(r)}catch{return null}let a=i[e.topLevelKey];if(!s(a))return null;let o=a[e.serverName(t)];return s(o)?o:null}async function Z(e={}){let t=b(e.cwd??process.cwd()),r={mode:e.devMcp?`dev`:`published`,cliEntryPath:e.cliEntryPath},o=await n(t),s;try{s=i(t)}catch(n){let r=V.claude.configPath(t,e.home);return{contentCreated:[],contentSkipped:[],editors:[],legacyProjectConfigs:[],rootInstructions:[],didGitInit:o.didInit,mcpAction:`failed`,mcpPath:r,mcpError:`Content scaffolding failed: ${n instanceof Error?n.message:String(n)}`}}let c=H(e.editors??$(t,e.home)),l=c.filter(n=>Y(n,t,e.home)),u=[];for(let n of c){if(e.mcp===!1){let r=``;try{r=n.configPath(t,e.home)}catch{}u.push({editorId:n.id,label:n.label,action:`skipped-flag`,configPath:r,serverName:n.serverName(t)});continue}u.push(X(n,t,r,e.home))}let d=e.mcp===!1?[]:l.map(e=>re(e,t)).filter(e=>e!==void 0),f=l.some(e=>e.id===`claude`)&&e.mcp!==!1?ne(t,r):void 0,p=l.map(e=>e.instructionsPath?.(t)).filter(e=>e!==void 0).map(e=>g(e)?y(t,e):e),m=e.rootInstructions===!1?[]:a(t,!0,p),h=e.mcp===!1?`skipped-flag`:`skipped-missing`,_=u.find(e=>e.editorId===`claude`)??u[0]??{action:h,configPath:V.claude.configPath(t,e.home)};return{contentCreated:s.created,contentSkipped:s.skipped,editors:u,legacyProjectConfigs:d,rootInstructions:m,launchJson:f,didGitInit:o.didInit,mcpAction:_.action,mcpPath:_.configPath,mcpError:`error`in _?_.error:void 0}}function Q(e,n){let r=[],i=e.editors.some(e=>e.action===`written`||e.action===`overwritten`),a=e.editors.some(e=>e.action===`failed`),s=e.editors.length>0&&e.editors.every(e=>e.action===`skipped-flag`),c=e.editors.length>0&&e.editors.every(e=>e.action===`skipped-missing`),l=e=>{let t=e.configPath.startsWith(n)?y(n,e.configPath):e.configPath;switch(e.action){case`created`:return` app preview server ${t} configured for Claude Code Desktop embedded browser`;case`merged`:return` app preview server ${t} updated for Claude Code Desktop embedded browser`;case`failed`:return` app preview server ${t} FAILED: ${e.error}`}};e.didGitInit&&r.push(`Initialized git repo at ${n}/.git/ (default branch: main)`);let u=_(n,t);if(e.contentCreated.length>0?(r.push(`Content scaffolded at ${u}/`),r.push(` Created: ${e.contentCreated.join(`, `)}`)):r.push(`Content already present at ${u}/`),e.contentSkipped.length>0&&r.push(` Skipped (already exist): ${e.contentSkipped.join(`, `)}`),r.push(``),e.mcpError&&e.editors.length===0)r.push(`Warning: ${e.mcpError}`);else if(e.editors.length===0)r.push(`MCP server configuration:`),r.push(e.mcpAction===`skipped-flag`?` MCP config not written — use without --no-mcp to configure editors`:` No supported editor config directories detected; skipped MCP registration`);else if(s)r.push(`MCP config not written — use without --no-mcp to configure editors`);else if(c)r.push(`MCP server configuration:`),r.push(` No supported editor config directories detected; skipped MCP registration`);else{r.push(`MCP server configuration:`);for(let t of e.editors){let i=t.configPath.startsWith(n)?y(n,t.configPath):t.configPath.replace(/^\/Users\/[^/]+/,`~`),a=t.serverName===`open-knowledge`?``:` (${t.serverName})`,o=` `.repeat(Math.max(1,14-t.label.length)),s=t.editorId===`claude-desktop`&&(t.action===`written`||t.action===`overwritten`)?` — quit and relaunch Claude Desktop to activate`:``;switch(t.action){case`written`:r.push(` ${t.label}${o}${i} registered${a}${s}`);break;case`overwritten`:r.push(` ${t.label}${o}${i} updated${a}${s}`);break;case`skipped-missing`:r.push(` ${t.label}${o}${i} config root missing; skipped`);break;case`failed`:r.push(` ${t.label}${o}${i} FAILED: ${t.error}`);break;case`skipped-flag`:break}t.editorId===`claude`&&e.launchJson&&r.push(l(e.launchJson))}}if(a&&(r.push(``),r.push(`For failed editors, add the MCP server entry manually. See:`),r.push(` https://github.com/inkeep/open-knowledge#mcp-setup`)),e.legacyProjectConfigs.length>0){r.push(``),r.push(`Legacy project MCP configs detected:`);for(let t of e.legacyProjectConfigs)r.push(` ${t.label} ${y(n,t.path)}`);r.push(` These project-local files may override the new global config. Remove them if you want fully user-scoped MCP setup in this project.`)}if(e.rootInstructions.length>0){let t=e.rootInstructions.filter(e=>e.action!==`skipped-symlink`);if(t.length>0){r.push(``),r.push(`Root instructions:`);for(let e of t){let t=e.path.startsWith(n)?y(n,e.path):e.path,i=` `.repeat(Math.max(1,14-e.file.length));switch(e.action){case`created`:r.push(` ${e.file}${i}${t} created`);break;case`appended`:r.push(` ${e.file}${i}${t} appended Open Knowledge section`);break;case`replaced`:r.push(` ${e.file}${i}${t} replaced Open Knowledge section`);break;case`skipped-existing`:r.push(` ${e.file}${i}${t} already has Open Knowledge section`);break}}}}if(e.preview?(r.push(``),r.push(o(e.preview,n))):e.previewWarning&&(r.push(``),r.push(`Content preview unavailable: ${e.previewWarning}`)),i){let t=e.editors.filter(e=>e.action===`written`||e.action===`overwritten`).map(e=>e.label);r.push(``),r.push(`Next steps:`),r.push(` 1. Open your editor (${t.join(` / `)})`),r.push(` 2. Approve the MCP server when prompted`),r.push(` 3. The knowledge base is ready — use the three workflow tools:`),r.push(` - mcp__open-knowledge__init-content — bootstrap articles from the codebase`),r.push(` - mcp__open-knowledge__ingest — capture an external source`),r.push(` - mcp__open-knowledge__research — gather sources and write findings`)}return r.join(`
3
3
  `)}function $(e,t){let n=[];for(let r of T)Y(V[r],e,t)&&n.push(r);return n}function oe(){return new c(`init`).description(`Scaffold ${t}/ 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 ${t}/ 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`).action(async e=>{let t=process.cwd(),n;try{n=await Z({cwd:t,mcp:e.mcp,devMcp:e.devMcp})}catch(e){if(e instanceof r){process.stderr.write(`open-knowledge requires git to initialize a parent repo. Install git or run 'git init' yourself, then re-run.
4
- `),e.stderr&&process.stderr.write(`${e.stderr.trim()}\n`),process.exitCode=1;return}throw e}try{let{previewContent:e}=await import(`./preview-CULBnUoI.mjs`),{loadConfig:r}=await import(`./loader-89zKhhvs.mjs`),{resolveContentDir:i}=await import(`./paths-BhmQnYL9.mjs`),{config:a}=r(t),o=i(a,t);n.preview=e({projectDir:t,contentDir:o,include:a.content.include,exclude:a.content.exclude})}catch(e){n.previewWarning=e instanceof Error?e.message:String(e)}process.stdout.write(`${Q(n,t)}\n`),(n.editors.some(e=>e.action===`failed`)||n.mcpAction===`failed`)&&(process.exitCode=1)})}export{Z as a,T as c,ae as i,V as l,Q as n,X as o,oe as r,ie as s,$ as t};
5
- //# sourceMappingURL=init-DysAQtCG.mjs.map
4
+ `),e.stderr&&process.stderr.write(`${e.stderr.trim()}\n`),process.exitCode=1;return}throw e}try{let{previewContent:e}=await import(`./preview-_ahVwbF3.mjs`),{loadConfig:r}=await import(`./loader-Cm1Bwe2n.mjs`),{resolveContentDir:i}=await import(`./paths-a8wNIBFD.mjs`),{config:a}=r(t),o=i(a,t);n.preview=e({projectDir:t,contentDir:o,include:a.content.include,exclude:a.content.exclude})}catch(e){n.previewWarning=e instanceof Error?e.message:String(e)}process.stdout.write(`${Q(n,t)}\n`),(n.editors.some(e=>e.action===`failed`)||n.mcpAction===`failed`)&&(process.exitCode=1)})}export{Z as a,T as c,ae as i,V as l,Q as n,X as o,oe as r,ie as s,$ as t};
5
+ //# sourceMappingURL=init-Xod4U7aY.mjs.map
@@ -0,0 +1 @@
1
+ import{n as e}from"./loader-Dw_7CMz3.mjs";export{e as loadConfig};
@@ -1,3 +1,3 @@
1
- import{r as e}from"./constants-DA7Qh-Kl.mjs";import{O as t}from"./src-CQw-HNNM.mjs";import{t as n}from"./is-object-DaHwJLOe.mjs";import{existsSync as r,readFileSync as i}from"node:fs";import{homedir as a}from"node:os";import{resolve as o}from"node:path";import{parse as s}from"yaml";import{realpath as c}from"node:fs/promises";import{z as l}from"zod";async function u(e){let t=o(e);try{return await c(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}}const d=l.object({title:l.string().optional(),description:l.string().optional(),tags:l.array(l.string()).optional()}).strict(),f=l.object({match:l.string().min(1,"`match` must be a non-empty glob pattern (e.g. 'specs/**' or 'reports/*/**')"),frontmatter:d}).strict(),p=l.object({content:l.object({dir:l.string().default(`.`),include:l.array(l.string()).min(1).default([`**/*.md`,`**/*.mdx`]),exclude:l.array(l.string()).default([])}).default({dir:`.`,include:[`**/*.md`,`**/*.mdx`],exclude:[]}),github:l.object({oauthAppClientId:l.string().default(`Ov23liqlSd0V1MwR6rhI`)}).default({oauthAppClientId:`Ov23liqlSd0V1MwR6rhI`}),sync:l.object({enabled:l.boolean().optional(),pushIntervalSeconds:l.number().int().min(1).default(60),pullIntervalSeconds:l.number().int().min(1).default(30),autoCommit:l.boolean().default(!0),autoPush:l.boolean().default(!0),autoPull:l.boolean().default(!0),commitMessage:l.string().default(`auto`)}).default({pushIntervalSeconds:60,pullIntervalSeconds:30,autoCommit:!0,autoPush:!0,autoPull:!0,commitMessage:`auto`}),server:l.object({port:l.number().int().min(0).max(65535).default(0),host:l.string().regex(/^[\w.\-:]+$/,`Invalid hostname`).default(`localhost`),openOnAgentEdit:l.boolean().default(!1)}).default({port:0,host:`localhost`,openOnAgentEdit:!1}),persistence:l.object({debounceMs:l.number().int().min(0).default(2e3),maxDebounceMs:l.number().int().min(0).default(1e4)}).default({debounceMs:2e3,maxDebounceMs:1e4}),preview:l.object({baseUrl:l.url().optional()}).default({}),folders:l.array(f).default([]),mcp:l.object({autoStart:l.boolean().default(!0),tools:l.object({read_document:l.object({historyDepth:l.number().int().min(0).default(5)}).default({historyDepth:5}),search:l.object({maxResults:l.number().int().min(1).default(50)}).default({maxResults:50})}).default({read_document:{historyDepth:5},search:{maxResults:50}})}).default({autoStart:!0,tools:{read_document:{historyDepth:5},search:{maxResults:50}}})});function m(e,t){let r={...e};for(let i of Object.keys(t)){let a=e[i],o=t[i];n(o)&&n(a)?r[i]=m(a,o):o!==void 0&&(r[i]=o)}return r}function h(e){if(!r(e))return null;try{let t=s(i(e,`utf-8`));return n(t)?t:null}catch(t){return console.warn(`[config] Failed to parse ${e}: ${t instanceof Error?t.message:t}`),null}}function g(n){let r=n??process.cwd(),i=[],s=o(a(),t,e),c={},l=h(s);l&&(c=m(c,l),i.push(s));let u=o(r,t,e),d=h(u);d&&(c=m(c,d),i.push(u));let f=p.safeParse(c);if(!f.success){let e=f.error.issues.map(e=>` ${e.path.join(`.`)}: ${e.message}`);throw Error(`Invalid configuration:\n${e.join(`
1
+ import{r as e}from"./constants-Cs463jly.mjs";import{O as t}from"./src-CQw-HNNM.mjs";import{t as n}from"./is-object-DaHwJLOe.mjs";import{existsSync as r,readFileSync as i}from"node:fs";import{homedir as a}from"node:os";import{resolve as o}from"node:path";import{parse as s}from"yaml";import{realpath as c}from"node:fs/promises";import{z as l}from"zod";async function u(e){let t=o(e);try{return await c(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}}const d=l.object({title:l.string().optional(),description:l.string().optional(),tags:l.array(l.string()).optional()}).strict(),f=l.object({match:l.string().min(1,"`match` must be a non-empty glob pattern (e.g. 'specs/**' or 'reports/*/**')"),frontmatter:d}).strict(),p=l.object({content:l.object({dir:l.string().default(`.`),include:l.array(l.string()).min(1).default([`**/*.md`,`**/*.mdx`]),exclude:l.array(l.string()).default([])}).default({dir:`.`,include:[`**/*.md`,`**/*.mdx`],exclude:[]}),github:l.object({oauthAppClientId:l.string().default(`Ov23liqlSd0V1MwR6rhI`)}).default({oauthAppClientId:`Ov23liqlSd0V1MwR6rhI`}),sync:l.object({enabled:l.boolean().optional(),pushIntervalSeconds:l.number().int().min(1).default(60),pullIntervalSeconds:l.number().int().min(1).default(30),autoCommit:l.boolean().default(!0),autoPush:l.boolean().default(!0),autoPull:l.boolean().default(!0),commitMessage:l.string().default(`auto`)}).default({pushIntervalSeconds:60,pullIntervalSeconds:30,autoCommit:!0,autoPush:!0,autoPull:!0,commitMessage:`auto`}),server:l.object({port:l.number().int().min(0).max(65535).default(0),host:l.string().regex(/^[\w.\-:]+$/,`Invalid hostname`).default(`localhost`),openOnAgentEdit:l.boolean().default(!1)}).default({port:0,host:`localhost`,openOnAgentEdit:!1}),persistence:l.object({debounceMs:l.number().int().min(0).default(2e3),maxDebounceMs:l.number().int().min(0).default(1e4)}).default({debounceMs:2e3,maxDebounceMs:1e4}),preview:l.object({baseUrl:l.url().optional()}).default({}),folders:l.array(f).default([]),mcp:l.object({autoStart:l.boolean().default(!0),tools:l.object({read_document:l.object({historyDepth:l.number().int().min(0).default(5)}).default({historyDepth:5}),search:l.object({maxResults:l.number().int().min(1).default(50)}).default({maxResults:50})}).default({read_document:{historyDepth:5},search:{maxResults:50}})}).default({autoStart:!0,tools:{read_document:{historyDepth:5},search:{maxResults:50}}})});function m(e,t){let r={...e};for(let i of Object.keys(t)){let a=e[i],o=t[i];n(o)&&n(a)?r[i]=m(a,o):o!==void 0&&(r[i]=o)}return r}function h(e){if(!r(e))return null;try{let t=s(i(e,`utf-8`));return n(t)?t:null}catch(t){return console.warn(`[config] Failed to parse ${e}: ${t instanceof Error?t.message:t}`),null}}function g(n){let r=n??process.cwd(),i=[],s=o(a(),t,e),c={},l=h(s);l&&(c=m(c,l),i.push(s));let u=o(r,t,e),d=h(u);d&&(c=m(c,d),i.push(u));let f=p.safeParse(c);if(!f.success){let e=f.error.issues.map(e=>` ${e.path.join(`.`)}: ${e.message}`);throw Error(`Invalid configuration:\n${e.join(`
2
2
  `)}`)}return{config:f.data,sources:i}}function _(e,t=process.env){let n=e;return t.PORT&&(n={...n,server:{...n.server,port:Number(t.PORT)}}),t.HOST&&(n={...n,server:{...n.server,host:t.HOST}}),n}function v(e){let t=e.env??process.env,n=e.cacheMs??1e3,r=e.loadConfigFn??g,i=new Map,a=new Map,o=u(e.startupCwd);return async s=>{let c=await u(s??e.startupCwd),l=Date.now(),d=i.get(c);if(d&&d.expiresAt>l)return d.config;let f=a.get(c);if(f)return await f;let p=(async()=>{if(c===await o){let r=_(e.startupConfig,t);return i.set(c,{config:r,expiresAt:Date.now()+n}),r}let a=_(r(c).config,t);return i.set(c,{config:a,expiresAt:Date.now()+n}),a})();a.set(c,p);try{return await p}finally{a.delete(c)}}}export{u as i,g as n,p as r,v as t};
3
- //# sourceMappingURL=loader-DfTFnc2z.mjs.map
3
+ //# sourceMappingURL=loader-Dw_7CMz3.mjs.map
@@ -1,2 +1,2 @@
1
- import"./constants-DA7Qh-Kl.mjs";import{O as e}from"./src-CQw-HNNM.mjs";import{resolve as t}from"node:path";function n(e,n){return t(n,e.content.dir)}function r(n){return t(n,e)}export{r as n,n as t};
2
- //# sourceMappingURL=paths-B9hXoumv.mjs.map
1
+ import"./constants-Cs463jly.mjs";import{O as e}from"./src-CQw-HNNM.mjs";import{resolve as t}from"node:path";function n(e,n){return t(n,e.content.dir)}function r(n){return t(n,e)}export{r as n,n as t};
2
+ //# sourceMappingURL=paths-BQwE2DU0.mjs.map
@@ -0,0 +1 @@
1
+ import{n as e,t}from"./paths-BQwE2DU0.mjs";export{t as resolveContentDir,e as resolveLockDir};
@@ -1,3 +1,3 @@
1
- import"./constants-DA7Qh-Kl.mjs";import{O as e}from"./src-CQw-HNNM.mjs";import{m as t}from"./src-rqPIkHTi.mjs";import{existsSync as n,lstatSync as r,readdirSync as i,realpathSync as a,statSync as o}from"node:fs";import{join as s,relative as c}from"node:path";function l(e){let{projectDir:n,contentDir:l,include:u,exclude:d,sampleCap:f=5}=e,p=[],m=[];try{r(l)}catch(e){return{totalCount:0,sample:[],contentDir:l,include:u,exclude:d,warnings:[`cannot access content directory ${l}: ${e instanceof Error?e.message:String(e)}`]}}let h;try{h=t({projectDir:n,contentDir:l,includePatterns:u,excludePatterns:d})}catch(e){return{totalCount:0,sample:[],contentDir:l,include:u,exclude:d,warnings:[e instanceof Error?e.message:String(e)]}}function g(e){let t;try{t=i(e,{withFileTypes:!0})}catch(t){let n=t instanceof Error?t.message:String(t);p.push(`could not read directory ${c(l,e)||`.`}: ${n}`);return}for(let n of t){let t=s(e,n.name);if(n.isSymbolicLink()){let e;try{e=a(t)}catch(e){let n=e.code;n===`ENOENT`||n===`ELOOP`?p.push(`broken or cyclic symlink: ${c(l,t)}`):p.push(`cannot resolve symlink ${c(l,t)}: ${n??`unknown error`}`);continue}let n;try{n=o(e)}catch{continue}if(n.isDirectory()){let e=c(l,t);if(h.isDirExcluded(e))continue;g(t)}else if(n.isFile()){let e=c(l,t);if(h.isExcluded(e))continue;m.push(e)}}else if(n.isDirectory()){let e=c(l,t);if(h.isDirExcluded(e))continue;g(t)}else if(n.isFile()){let e=c(l,t);if(h.isExcluded(e))continue;m.push(e)}}}return g(l),{totalCount:m.length,sample:m.slice(0,f),contentDir:l,include:u,exclude:d,warnings:p}}function u(t,r){let i=[],a=c(r,t.contentDir),o=a===``?`./`:`./${a}`;i.push(`Content:`),i.push(` Found ${t.totalCount} markdown files in ${o}`);let l=t.include.join(`, `),u=t.exclude.length>0?t.exclude.join(`, `):`(none)`;if(i.push(` Scope: include=${l} exclude=${u}`),t.sample.length>0){let e=t.sample.join(`, `),n=t.totalCount>t.sample.length?`, …`:``;i.push(` Sample: ${e}${n}`)}if(t.warnings.length>0)for(let e of t.warnings)i.push(` Warning: ${e}`);return i.push(``),n(s(r,`.open-knowledge`,`config.yml`))?(i.push(` To adjust, edit ${e}/config.yml:`),i.push(` content:`),i.push(` include: ${JSON.stringify(t.include)}`),i.push(` exclude: ${JSON.stringify(t.exclude)}`)):(i.push(" Run `open-knowledge init` to scaffold config, then adjust:"),i.push(` ${e}/config.yml → content.include / content.exclude`)),i.push(``),i.push(` Re-check anytime: open-knowledge preview`),i.join(`
1
+ import"./constants-Cs463jly.mjs";import{O as e}from"./src-CQw-HNNM.mjs";import{m as t}from"./src-C1Um6yPF.mjs";import{existsSync as n,lstatSync as r,readdirSync as i,realpathSync as a,statSync as o}from"node:fs";import{join as s,relative as c}from"node:path";function l(e){let{projectDir:n,contentDir:l,include:u,exclude:d,sampleCap:f=5}=e,p=[],m=[];try{r(l)}catch(e){return{totalCount:0,sample:[],contentDir:l,include:u,exclude:d,warnings:[`cannot access content directory ${l}: ${e instanceof Error?e.message:String(e)}`]}}let h;try{h=t({projectDir:n,contentDir:l,includePatterns:u,excludePatterns:d})}catch(e){return{totalCount:0,sample:[],contentDir:l,include:u,exclude:d,warnings:[e instanceof Error?e.message:String(e)]}}function g(e){let t;try{t=i(e,{withFileTypes:!0})}catch(t){let n=t instanceof Error?t.message:String(t);p.push(`could not read directory ${c(l,e)||`.`}: ${n}`);return}for(let n of t){let t=s(e,n.name);if(n.isSymbolicLink()){let e;try{e=a(t)}catch(e){let n=e.code;n===`ENOENT`||n===`ELOOP`?p.push(`broken or cyclic symlink: ${c(l,t)}`):p.push(`cannot resolve symlink ${c(l,t)}: ${n??`unknown error`}`);continue}let n;try{n=o(e)}catch{continue}if(n.isDirectory()){let e=c(l,t);if(h.isDirExcluded(e))continue;g(t)}else if(n.isFile()){let e=c(l,t);if(h.isExcluded(e))continue;m.push(e)}}else if(n.isDirectory()){let e=c(l,t);if(h.isDirExcluded(e))continue;g(t)}else if(n.isFile()){let e=c(l,t);if(h.isExcluded(e))continue;m.push(e)}}}return g(l),{totalCount:m.length,sample:m.slice(0,f),contentDir:l,include:u,exclude:d,warnings:p}}function u(t,r){let i=[],a=c(r,t.contentDir),o=a===``?`./`:`./${a}`;i.push(`Content:`),i.push(` Found ${t.totalCount} markdown files in ${o}`);let l=t.include.join(`, `),u=t.exclude.length>0?t.exclude.join(`, `):`(none)`;if(i.push(` Scope: include=${l} exclude=${u}`),t.sample.length>0){let e=t.sample.join(`, `),n=t.totalCount>t.sample.length?`, …`:``;i.push(` Sample: ${e}${n}`)}if(t.warnings.length>0)for(let e of t.warnings)i.push(` Warning: ${e}`);return i.push(``),n(s(r,`.open-knowledge`,`config.yml`))?(i.push(` To adjust, edit ${e}/config.yml:`),i.push(` content:`),i.push(` include: ${JSON.stringify(t.include)}`),i.push(` exclude: ${JSON.stringify(t.exclude)}`)):(i.push(" Run `open-knowledge init` to scaffold config, then adjust:"),i.push(` ${e}/config.yml → content.include / content.exclude`)),i.push(``),i.push(` Re-check anytime: open-knowledge preview`),i.join(`
2
2
  `)}export{l as n,u as t};
3
- //# sourceMappingURL=preview-jDZwLSul.mjs.map
3
+ //# sourceMappingURL=preview-Bn5MTCPO.mjs.map
@@ -0,0 +1 @@
1
+ import{n as e,t}from"./preview-Bn5MTCPO.mjs";export{t as formatPreviewBlock,e as previewContent};