@inkeep/open-knowledge 0.40.0-beta.1 → 0.40.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/{acp-harness-probe-CI5eMrtp.mjs → acp-harness-probe-DR1ZKGnH.mjs} +2 -2
  2. package/dist/assets/skills/discovery/SKILL.md +1 -1
  3. package/dist/assets/skills/project/SKILL.md +1 -1
  4. package/dist/cli.mjs +7 -7
  5. package/dist/constants-BJzJKgN0.mjs +2 -0
  6. package/dist/index.d.mts +1 -1
  7. package/dist/index.mjs +1 -1
  8. package/dist/init-BNoSqnre.mjs +1 -0
  9. package/dist/{init-DqAj6DLP.mjs → init-CRqHukN0.mjs} +3 -3
  10. package/dist/{launch-json-removal-DMBq4-k5.mjs → launch-json-removal-D2RKDIfa.mjs} +2 -2
  11. package/dist/loader-3kHXROAa.mjs +1 -0
  12. package/dist/{loader-CuzKavqN.mjs → loader-B2FwNLO-.mjs} +2 -2
  13. package/dist/{open-browser-D3OpxES8.mjs → open-browser-B_gopYWU.mjs} +2 -2
  14. package/dist/{preview-DNAkJMSB.mjs → preview-2zt9BjS6.mjs} +2 -2
  15. package/dist/preview-rVAd6E5r.mjs +1 -0
  16. package/dist/{repair-launch-json-tt6Tjedd.mjs → repair-launch-json-C3uqYkeS.mjs} +2 -2
  17. package/dist/{repair-mcp-configs-Bn1d1oSd.mjs → repair-mcp-configs-i7dMnghP.mjs} +2 -2
  18. package/dist/repair-skills-DJ7FOTZZ.mjs +1 -0
  19. package/dist/{repair-skills-BVXDXZaA.mjs → repair-skills-P9l196Qv.mjs} +2 -2
  20. package/dist/{src-DVrFd0vk.mjs → src-7LOBasfG.mjs} +316 -316
  21. package/dist/{src-DQTDRmqk.mjs → src-CgblAAT9.mjs} +1 -1
  22. package/dist/{src-VT3q7v5V.mjs → src-Dj-HA_-C.mjs} +2 -2
  23. package/dist/start-Br97vCln.mjs +1 -0
  24. package/dist/{start-BQRik_0l.mjs → start-CcMTV_IU.mjs} +2 -2
  25. package/dist/{write-project-skill-SrjlunKm.mjs → write-project-skill-Cm0CAVv2.mjs} +2 -2
  26. package/package.json +5 -5
  27. package/dist/constants-CkXW_O1Z.mjs +0 -2
  28. package/dist/init-BG8F8jyV.mjs +0 -1
  29. package/dist/loader-48vYo7np.mjs +0 -1
  30. package/dist/preview-hDB5CK12.mjs +0 -1
  31. package/dist/repair-skills-D7MJ6bSo.mjs +0 -1
  32. package/dist/start-3HnyNbf6.mjs +0 -1
@@ -1,3 +1,3 @@
1
- import{G as e}from"./sleep-CnRgOMGV.mjs";import{h as t,l as n,v as r}from"./write-project-skill-SrjlunKm.mjs";import{d as i}from"./init-DqAj6DLP.mjs";import{execFileSync as a}from"node:child_process";import{dirname as o,join as s}from"node:path";import{existsSync as c,mkdirSync as l,readFileSync as u,writeFileSync as d}from"node:fs";import{homedir as f}from"node:os";var p=e();const m=`open-knowledge`;function h(e){try{e()}catch{}}var g=class{backend=`keyring`;constructor(e){this.onKeychainRead=e}async get(e){let{Entry:t}=await import(`@napi-rs/keyring`),n;try{n=new t(m,e).getPassword()}catch(t){return h(()=>this.onKeychainRead?.({kind:`read-error`,host:e,error:t instanceof Error?t.name:`unknown`})),null}if(n==null)return h(()=>this.onKeychainRead?.({kind:`absent`,host:e})),null;try{return JSON.parse(n)}catch{return h(()=>this.onKeychainRead?.({kind:`corrupt-entry`,host:e,error:`corrupt-entry`})),null}}async set(e,t,n,r){let{Entry:i}=await import(`@napi-rs/keyring`),a=new i(m,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(m,e).deletePassword()}catch{}}},_=class{backend=`file`;authFile;constructor(e){this.authFile=e??s(f(),`.ok`,`auth.yml`)}read(){if(!c(this.authFile))return{};try{return(0,p.parse)(u(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=o(this.authFile);c(t)||l(t,{recursive:!0,mode:448}),d(this.authFile,(0,p.stringify)(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)}},v=class{backend=`keyring`;constructor(e,t){this.keychain=e,this.file=t}async get(e){let t=await this.keychain.get(e);if(t!=null)return t;let n=await this.file.get(e);if(n==null)return null;try{await this.keychain.set(e,n.login,n.token,{gitProtocol:n.gitProtocol,name:n.name,email:n.email}),await this.file.clear(e),process.stderr.write(`[auth] migrated ${e} credential from ~/.ok/auth.yml to the OS keychain\n`)}catch{}return n}set(e,t,n,r){return this.keychain.set(e,t,n,r)}async clear(e){await this.keychain.clear(e),await this.file.get(e)!=null&&await this.file.clear(e)}};async function y(e,t){try{let{Entry:n}=await import(`@napi-rs/keyring`);return new n(m,`__probe__`),process.stderr.write(`[auth] token storage: OS keychain
1
+ import{G as e}from"./sleep-CnRgOMGV.mjs";import{h as t,l as n,v as r}from"./write-project-skill-Cm0CAVv2.mjs";import{d as i}from"./init-CRqHukN0.mjs";import{execFileSync as a}from"node:child_process";import{dirname as o,join as s}from"node:path";import{existsSync as c,mkdirSync as l,readFileSync as u,writeFileSync as d}from"node:fs";import{homedir as f}from"node:os";var p=e();const m=`open-knowledge`;function h(e){try{e()}catch{}}var g=class{backend=`keyring`;constructor(e){this.onKeychainRead=e}async get(e){let{Entry:t}=await import(`@napi-rs/keyring`),n;try{n=new t(m,e).getPassword()}catch(t){return h(()=>this.onKeychainRead?.({kind:`read-error`,host:e,error:t instanceof Error?t.name:`unknown`})),null}if(n==null)return h(()=>this.onKeychainRead?.({kind:`absent`,host:e})),null;try{return JSON.parse(n)}catch{return h(()=>this.onKeychainRead?.({kind:`corrupt-entry`,host:e,error:`corrupt-entry`})),null}}async set(e,t,n,r){let{Entry:i}=await import(`@napi-rs/keyring`),a=new i(m,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(m,e).deletePassword()}catch{}}},_=class{backend=`file`;authFile;constructor(e){this.authFile=e??s(f(),`.ok`,`auth.yml`)}read(){if(!c(this.authFile))return{};try{return(0,p.parse)(u(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=o(this.authFile);c(t)||l(t,{recursive:!0,mode:448}),d(this.authFile,(0,p.stringify)(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)}},v=class{backend=`keyring`;constructor(e,t){this.keychain=e,this.file=t}async get(e){let t=await this.keychain.get(e);if(t!=null)return t;let n=await this.file.get(e);if(n==null)return null;try{await this.keychain.set(e,n.login,n.token,{gitProtocol:n.gitProtocol,name:n.name,email:n.email}),await this.file.clear(e),process.stderr.write(`[auth] migrated ${e} credential from ~/.ok/auth.yml to the OS keychain\n`)}catch{}return n}set(e,t,n,r){return this.keychain.set(e,t,n,r)}async clear(e){await this.keychain.clear(e),await this.file.get(e)!=null&&await this.file.clear(e)}};async function y(e,t){try{let{Entry:n}=await import(`@napi-rs/keyring`);return new n(m,`__probe__`),process.stderr.write(`[auth] token storage: OS keychain
2
2
  `),h(()=>t?.onBackendSelected?.({backend:`keyring`})),new v(new g(t?.onKeychainRead),new _(e))}catch(n){let r=n instanceof Error?`${n.name}: ${n.message}`:String(n);return process.stderr.write(`[auth] token storage: file (~/.ok/auth.yml) — OS keychain unavailable: ${r}\n`),h(()=>t?.onBackendSelected?.({backend:`file`,reason:r})),new _(e)}}function b(e){let t=null;return function(){if(t)return t;let n=2e3;return t=(async()=>{let t=null,r=new Promise(r=>{t=setTimeout(()=>{process.stderr.write(`[auth] token storage: keyring init exceeded ${n}ms; falling back to file (~/.ok/auth.yml)\n`),r(new _(e))},n)});try{return await Promise.race([y(e),r])}catch{return new _(e)}finally{t!==null&&clearTimeout(t)}})(),t}}function x(e){let t=b(e);return{async get(e){let n=await(await t()).get(e);return n===null?null:{token:n.token}}}}function S(e){let t=b(e);return{backend:`file`,async get(e){return(await t()).get(e)},async set(e,n,r,i){return(await t()).set(e,n,r,i)},async clear(e){return(await t()).clear(e)}}}async function C(e,t){let n=[],r=new _(t);await r.get(e)!=null&&(await r.clear(e),n.push(`file`));let i;try{let{Entry:t}=await import(`@napi-rs/keyring`);new t(m,`__probe__`);let r,a=await new g(e=>{e.kind===`read-error`&&(r=e.error??`read-error`)}).get(e);if(r!==void 0)i=r;else if(a!=null)try{new t(m,e).deletePassword(),n.push(`keychain`)}catch(e){i=e instanceof Error?e.name:`delete-error`}}catch{}return{touched:n,keychainError:i}}const w=[`/opt/homebrew/bin/gh`,`/usr/local/bin/gh`,`/opt/local/bin/gh`,`/snap/bin/gh`,`/usr/bin/gh`],T={encoding:`utf-8`,stdio:[`ignore`,`pipe`,`pipe`],timeout:5e3,windowsHide:!0};function E(e,t={}){let n=t._exec??a,r=t._fileExists??c,i=[`auth`,`token`,...e?[`--hostname`,e]:[]],o=[`gh`,...w.filter(r)];for(let e of o)try{let t=n(e,i,T).toString().trim();if(t.length>0)return{available:!0,token:t}}catch{}return{available:!1}}function D(e,a,o){let s=n[e],c=e===`opencode`?r:t,l=[],u=s.projectConfigPath?.(a);u!==void 0&&l.push({scope:`project`,configPath:u});try{l.push({scope:`user`,configPath:s.configPath(a,o)})}catch{}for(let t of l){let n=i(s,a,o,t.configPath);if(n!==null&&c(n))return{editorId:e,scope:t.scope,configPath:t.configPath}}return null}export{x as a,y as i,E as n,S as o,C as r,D as t};
3
- //# sourceMappingURL=acp-harness-probe-CI5eMrtp.mjs.map
3
+ //# sourceMappingURL=acp-harness-probe-DR1ZKGnH.mjs.map
@@ -3,7 +3,7 @@ name: open-knowledge-discovery
3
3
  description: "Read when the user asks what OpenKnowledge is, wants to install it on a repository, wants to share an OpenKnowledge project with collaborators, or asks how `ok init` / `ok cowork` / OK Desktop set up a project. Do NOT load to perform OpenKnowledge reads/writes — the runtime guidance for editing markdown inside an initialized OK project ships as a separate project-local skill at `.claude/skills/open-knowledge/` whenever `ok init` runs. If the user appears to be editing markdown inside a `.ok/` project and this is the only OK skill loaded, advise them to re-run `ok init` to install the project-local skill."
4
4
  compatibility: "Any agent host — no MCP server required. Pure discovery + install guidance."
5
5
  metadata:
6
- version: "0.40.0-beta.1"
6
+ version: "0.40.0-beta.2"
7
7
  author: "Inkeep"
8
8
  repository: "https://github.com/inkeep/open-knowledge"
9
9
  ---
@@ -3,7 +3,7 @@ name: open-knowledge
3
3
  description: "Authoritative agent-runtime contract for working inside an OpenKnowledge project — a markdown-CRDT knowledge base exposed over MCP. Use whenever reading, listing, searching, editing, or linting any `.md` or `.mdx` file in the project, and before any `mcp__open-knowledge__*` tool call (`exec`, `search`, `write`, `edit`, `lint`, and the rest). Installed by `ok init`, so its presence means this is an OpenKnowledge project and it governs every markdown file here. Covers the read/write tool surface, grounding and linking rules, folder/template conventions, the live browser preview, and the rule that OK's MCP tools — never native file tools — handle in-scope markdown."
4
4
  compatibility: "Claude Code, Claude Desktop, Claude Cowork, Claude.ai web. Requires OpenKnowledge MCP server + code execution."
5
5
  metadata:
6
- version: "0.40.0-beta.1"
6
+ version: "0.40.0-beta.2"
7
7
  author: "Inkeep"
8
8
  repository: "https://github.com/inkeep/open-knowledge"
9
9
  ---
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{o as e}from"./chunk-DTipWd-i.mjs";import{B as t,Ea as n,Fa as r,Hi as i,Ja as a,Ji as o,L as s,Sa as c,Ti as l,Ui as u,Wi as d,aa as f,ct as p,hi as m,ia as h,ii as g,la as _,lt as v,mi as y,pa as b,pi as x,ri as S}from"./src-IQdx1yfl.mjs";import{$ as ee,$t as C,B as w,Br as te,Ei as T,Ft as ne,Ht as E,Ir as D,It as re,Lt as ie,Qt as ae,R as oe,Rr as se,Rt as ce,Ti as O,Ut as k,V as le,Xr as ue,Xt as de,Z as fe,_ as pe,_t as me,a as he,ar as ge,bt as _e,ci as A,ct as ve,da as ye,di as be,dt as xe,et as Se,f as Ce,fa as we,fi as Te,fn as Ee,fr as De,ft as Oe,gi as ke,gn as Ae,gr as je,gt as Me,hn as Ne,hr as Pe,ht as Fe,ir as Ie,ki as Le,li as Re,lt as ze,mt as Be,n as Ve,nt as He,ot as Ue,p as We,pa as Ge,pi as Ke,pt as qe,r as Je,sr as Ye,t as Xe,tt as Ze,ua as Qe,ut as $e,vt as et,w as tt,wi as nt,z as rt}from"./src-DVrFd0vk.mjs";import{$ as it,C as at,F as ot,G as st,M as ct,Nt as lt,R as ut,Y as dt,_t as ft,a as pt,bt as mt,ct as ht,et as j,l as gt,lt as _t,mt as M,r as vt,st as yt,tt as N,ut as bt,v as xt}from"./sleep-CnRgOMGV.mjs";import{O as St,P as Ct,k as wt}from"./fs-traced-PoaSX4-V.mjs";import{a as Tt}from"./git-handle-DQgl5oTH.mjs";import{g as Et,i as Dt,v as Ot}from"./server-lock-DWsOY8Sf.mjs";import{l as kt,n as At,o as jt,s as Mt,x as P,y as Nt}from"./write-project-skill-SrjlunKm.mjs";import{C as Pt,D as Ft,E as It,S as Lt,T as Rt,a as zt,b as Bt,d as Vt,i as Ht,m as Ut,o as Wt,p as Gt,s as Kt,v as qt,x as Jt,y as Yt}from"./src-VT3q7v5V.mjs";import{c as Xt,i as F,n as I,o as L,r as R,s as z,t as B}from"./colors-BsmVIwfM.mjs";import{i as Zt,n as Qt,o as $t,r as en}from"./acp-harness-probe-CI5eMrtp.mjs";import{n as tn,r as nn,t as rn}from"./dist-bundle-CFfKBclM.mjs";import{A as an,B as on,C as sn,F as cn,H as ln,L as un,M as dn,N as fn,O as pn,P as mn,R as hn,T as gn,U as _n,V as vn,j as yn,u as bn,w as xn,z as Sn}from"./init-DqAj6DLP.mjs";import{n as Cn,t as wn}from"./constants-CkXW_O1Z.mjs";import{C as Tn,E as En,S as Dn,T as On,_ as kn,m as An,w as jn}from"./start-BQRik_0l.mjs";import{n as Mn,t as Nn}from"./loader-CuzKavqN.mjs";import{t as Pn}from"./launch-json-removal-DMBq4-k5.mjs";import{n as Fn}from"./repair-skills-BVXDXZaA.mjs";import{execFile as In,execFileSync as Ln,execSync as Rn,spawn as zn,spawnSync as Bn}from"node:child_process";import{basename as Vn,dirname as Hn,isAbsolute as Un,join as V,relative as H,resolve as U,sep as Wn}from"node:path";import{accessSync as Gn,appendFileSync as Kn,closeSync as qn,constants as Jn,existsSync as W,lstatSync as Yn,mkdirSync as Xn,mkdtempSync as Zn,openSync as Qn,readFileSync as G,readdirSync as $n,realpathSync as er,renameSync as tr,rmSync as nr,statSync as K,unlinkSync as rr,writeFileSync as ir}from"node:fs";import{homedir as ar,platform as or,tmpdir as sr}from"node:os";import{rm as cr}from"node:fs/promises";import lr from"node:process";import{fileURLToPath as ur}from"node:url";import{randomUUID as dr}from"node:crypto";import{setTimeout as fr}from"node:timers/promises";import{promisify as pr}from"node:util";import{createServer as mr,request as hr}from"node:http";import{createInterface as gr}from"node:readline/promises";import{connect as _r}from"node:net";const vr={invalid_type:`invalid_type`,too_big:`too_big`,too_small:`too_small`,invalid_format:`invalid_format`,not_multiple_of:`not_multiple_of`,unrecognized_keys:`unrecognized_keys`,invalid_union:`invalid_union`,invalid_key:`invalid_key`,invalid_element:`invalid_element`,invalid_value:`invalid_value`,custom:`custom`};var yr;(function(e){})(yr||={});function br(e){return mt(dt,e)}async function xr(e){let{projectDir:t,contentDir:n,baseConfig:r,targetPath:i,fix:a=!1}=e,o=[],s=ue({projectDir:t,contentDir:n}),c=new Map,l=new Set,u=e=>{let t=Hn(e),i=c.get(t);if(i)return i;let a=se(r,te(n,e,e=>{l.has(e)||(l.add(e),o.push(e))}));return c.set(t,a),a},d=[],f=Sr(i,n);f.kind===`file`?d.push(H(n,f.path)):p(f.path);function p(e){let t;try{t=$n(e,{withFileTypes:!0})}catch(t){o.push(`could not read directory ${H(n,e)||`.`}: ${wr(t)}`);return}for(let r of t){if(r.name.startsWith(`.`))continue;let t=V(e,r.name),i=H(n,t);if(r.isDirectory()){if(s.isDirExcluded(i))continue;p(t)}else if(r.isFile()){if(!Cr(r.name)||s.isExcluded(i))continue;d.push(i)}}}d.sort();let m=[],h=0,_=0,v=0;for(let e of d){let t=V(n,e),r;try{r=G(t,`utf-8`)}catch(t){o.push(`could not read ${e}: ${wr(t)}`);continue}let i=u(e),s=!1;if(a&&i.enabled){let n=S(r,i);if(n!==r){let i=`${t}.tmp.${process.pid}.${Date.now()}`;try{ir(i,n,`utf-8`),tr(i,t),r=n,s=!0,v++}catch(t){try{rr(i)}catch{}o.push(`could not write fix to ${e}: ${wr(t)}`)}}}let c=await g(r,i,e);for(let e of c)e.severity===`error`?h++:_++;m.push({file:e,diagnostics:c,fixed:s})}return{contentDir:n,files:m,warnings:o,fileCount:d.length,errorCount:h,warningCount:_,fixedCount:v}}function Sr(e,t){if(e===void 0||e===``)return{kind:`dir`,path:t};let n=Un(e)?e:U(t,e);try{if(K(n).isFile())return{kind:`file`,path:n}}catch{}return{kind:`dir`,path:n}}function Cr(e){let t=e.toLowerCase();return n.some(e=>t.endsWith(e))}function wr(e){return e instanceof Error?e.message:String(e)}function Tr(e){return new P(`lint`).description(`Lint markdown content (headless) — whole project, a folder, or a single file`).argument(`[path]`,`Folder or file to lint, relative to where you run the command`).option(`--json`,`Emit structured JSON instead of formatted text`).option(`--fix`,`Auto-fix fixable issues in place (markdownlint rules only)`).option(`--errors-only`,`Exit non-zero only on error-severity problems (findings are warning-severity unless your .markdownlint.* assigns a rule "error")`).action(async(t,n)=>{let r=e(),i=process.cwd(),a=O(r,i),o=t===void 0?void 0:Er(t,Rt()),s=r.contentRules,c=await xr({projectDir:i,contentDir:a,baseConfig:s?y(s):m,targetPath:o,fix:n.fix===!0});n.json===!0?process.stdout.write(`${JSON.stringify(c,null,2)}\n`):process.stdout.write(`${kr(c)}\n`),(n.errorsOnly===!0?c.errorCount>0:Dr(c))&&(process.exitCode=1)})}function Er(e,t){return U(t,e)}function Dr(e){return e.errorCount>0||e.warningCount>0}function Or(e){let t=[B(e.file)+(e.fixed?I(` (fixed)`):``)];for(let n of e.diagnostics){let e=I(`${n.range.start.line+1}:${n.range.start.character+1}`.padEnd(7)),r=n.severity===`error`?R(`error `):z(`warning`);t.push(` ${e} ${r} ${n.message} ${I(`${n.source}/${n.code}`)}`)}return t.push(``),t}function kr(e){let t=[];for(let n of e.files)n.diagnostics.length>0&&t.push(...Or(n));for(let n of e.warnings)t.push(z(`! ${n}`));e.warnings.length>0&&t.push(``);let n=e.errorCount+e.warningCount;if(n===0)t.push(L(`✓ No problems in ${e.fileCount} file${e.fileCount===1?``:`s`}.`));else{let r=[`${n} problem${n===1?``:`s`}`];r.push(`${e.errorCount} error${e.errorCount===1?``:`s`}`),r.push(`${e.warningCount} warning${e.warningCount===1?``:`s`}`),t.push(`${R(r[0]??``)} (${r[1]}, ${r[2]}) across ${e.fileCount} file${e.fileCount===1?``:`s`}.`)}return e.fixedCount>0&&t.push(I(`Fixed ${e.fixedCount} file${e.fixedCount===1?``:`s`}.`)),t.join(`
2
+ import{o as e}from"./chunk-DTipWd-i.mjs";import{B as t,Ea as n,Fa as r,Hi as i,Ja as a,Ji as o,L as s,Sa as c,Ti as l,Ui as u,Wi as d,aa as f,ct as p,hi as m,ia as h,ii as g,la as _,lt as v,mi as y,pa as b,pi as x,ri as S}from"./src-IQdx1yfl.mjs";import{$ as ee,$t as C,B as w,Br as te,Ei as T,Ft as ne,Ht as E,Ir as D,It as re,Lt as ie,Qt as ae,R as oe,Rr as se,Rt as ce,Ti as O,Ut as k,V as le,Xr as ue,Xt as de,Z as fe,_ as pe,_t as me,a as he,ar as ge,bt as _e,ci as A,ct as ve,da as ye,di as be,dt as xe,et as Se,f as Ce,fa as we,fi as Te,fn as Ee,fr as De,ft as Oe,gi as ke,gn as Ae,gr as je,gt as Me,hn as Ne,hr as Pe,ht as Fe,ir as Ie,ki as Le,li as Re,lt as ze,mt as Be,n as Ve,nt as He,ot as Ue,p as We,pa as Ge,pi as Ke,pt as qe,r as Je,sr as Ye,t as Xe,tt as Ze,ua as Qe,ut as $e,vt as et,w as tt,wi as nt,z as rt}from"./src-7LOBasfG.mjs";import{$ as it,C as at,F as ot,G as st,M as ct,Nt as lt,R as ut,Y as dt,_t as ft,a as pt,bt as mt,ct as ht,et as j,l as gt,lt as _t,mt as M,r as vt,st as yt,tt as N,ut as bt,v as xt}from"./sleep-CnRgOMGV.mjs";import{O as St,P as Ct,k as wt}from"./fs-traced-PoaSX4-V.mjs";import{a as Tt}from"./git-handle-DQgl5oTH.mjs";import{g as Et,i as Dt,v as Ot}from"./server-lock-DWsOY8Sf.mjs";import{l as kt,n as At,o as jt,s as Mt,x as P,y as Nt}from"./write-project-skill-Cm0CAVv2.mjs";import{C as Pt,D as Ft,E as It,S as Lt,T as Rt,a as zt,b as Bt,d as Vt,i as Ht,m as Ut,o as Wt,p as Gt,s as Kt,v as qt,x as Jt,y as Yt}from"./src-Dj-HA_-C.mjs";import{c as Xt,i as F,n as I,o as L,r as R,s as z,t as B}from"./colors-BsmVIwfM.mjs";import{i as Zt,n as Qt,o as $t,r as en}from"./acp-harness-probe-DR1ZKGnH.mjs";import{n as tn,r as nn,t as rn}from"./dist-bundle-CFfKBclM.mjs";import{A as an,B as on,C as sn,F as cn,H as ln,L as un,M as dn,N as fn,O as pn,P as mn,R as hn,T as gn,U as _n,V as vn,j as yn,u as bn,w as xn,z as Sn}from"./init-CRqHukN0.mjs";import{n as Cn,t as wn}from"./constants-BJzJKgN0.mjs";import{C as Tn,E as En,S as Dn,T as On,_ as kn,m as An,w as jn}from"./start-CcMTV_IU.mjs";import{n as Mn,t as Nn}from"./loader-B2FwNLO-.mjs";import{t as Pn}from"./launch-json-removal-D2RKDIfa.mjs";import{n as Fn}from"./repair-skills-P9l196Qv.mjs";import{execFile as In,execFileSync as Ln,execSync as Rn,spawn as zn,spawnSync as Bn}from"node:child_process";import{basename as Vn,dirname as Hn,isAbsolute as Un,join as V,relative as H,resolve as U,sep as Wn}from"node:path";import{accessSync as Gn,appendFileSync as Kn,closeSync as qn,constants as Jn,existsSync as W,lstatSync as Yn,mkdirSync as Xn,mkdtempSync as Zn,openSync as Qn,readFileSync as G,readdirSync as $n,realpathSync as er,renameSync as tr,rmSync as nr,statSync as K,unlinkSync as rr,writeFileSync as ir}from"node:fs";import{homedir as ar,platform as or,tmpdir as sr}from"node:os";import{rm as cr}from"node:fs/promises";import lr from"node:process";import{fileURLToPath as ur}from"node:url";import{randomUUID as dr}from"node:crypto";import{setTimeout as fr}from"node:timers/promises";import{promisify as pr}from"node:util";import{createServer as mr,request as hr}from"node:http";import{createInterface as gr}from"node:readline/promises";import{connect as _r}from"node:net";const vr={invalid_type:`invalid_type`,too_big:`too_big`,too_small:`too_small`,invalid_format:`invalid_format`,not_multiple_of:`not_multiple_of`,unrecognized_keys:`unrecognized_keys`,invalid_union:`invalid_union`,invalid_key:`invalid_key`,invalid_element:`invalid_element`,invalid_value:`invalid_value`,custom:`custom`};var yr;(function(e){})(yr||={});function br(e){return mt(dt,e)}async function xr(e){let{projectDir:t,contentDir:n,baseConfig:r,targetPath:i,fix:a=!1}=e,o=[],s=ue({projectDir:t,contentDir:n}),c=new Map,l=new Set,u=e=>{let t=Hn(e),i=c.get(t);if(i)return i;let a=se(r,te(n,e,e=>{l.has(e)||(l.add(e),o.push(e))}));return c.set(t,a),a},d=[],f=Sr(i,n);f.kind===`file`?d.push(H(n,f.path)):p(f.path);function p(e){let t;try{t=$n(e,{withFileTypes:!0})}catch(t){o.push(`could not read directory ${H(n,e)||`.`}: ${wr(t)}`);return}for(let r of t){if(r.name.startsWith(`.`))continue;let t=V(e,r.name),i=H(n,t);if(r.isDirectory()){if(s.isDirExcluded(i))continue;p(t)}else if(r.isFile()){if(!Cr(r.name)||s.isExcluded(i))continue;d.push(i)}}}d.sort();let m=[],h=0,_=0,v=0;for(let e of d){let t=V(n,e),r;try{r=G(t,`utf-8`)}catch(t){o.push(`could not read ${e}: ${wr(t)}`);continue}let i=u(e),s=!1;if(a&&i.enabled){let n=S(r,i);if(n!==r){let i=`${t}.tmp.${process.pid}.${Date.now()}`;try{ir(i,n,`utf-8`),tr(i,t),r=n,s=!0,v++}catch(t){try{rr(i)}catch{}o.push(`could not write fix to ${e}: ${wr(t)}`)}}}let c=await g(r,i,e);for(let e of c)e.severity===`error`?h++:_++;m.push({file:e,diagnostics:c,fixed:s})}return{contentDir:n,files:m,warnings:o,fileCount:d.length,errorCount:h,warningCount:_,fixedCount:v}}function Sr(e,t){if(e===void 0||e===``)return{kind:`dir`,path:t};let n=Un(e)?e:U(t,e);try{if(K(n).isFile())return{kind:`file`,path:n}}catch{}return{kind:`dir`,path:n}}function Cr(e){let t=e.toLowerCase();return n.some(e=>t.endsWith(e))}function wr(e){return e instanceof Error?e.message:String(e)}function Tr(e){return new P(`lint`).description(`Lint markdown content (headless) — whole project, a folder, or a single file`).argument(`[path]`,`Folder or file to lint, relative to where you run the command`).option(`--json`,`Emit structured JSON instead of formatted text`).option(`--fix`,`Auto-fix fixable issues in place (markdownlint rules only)`).option(`--errors-only`,`Exit non-zero only on error-severity problems (findings are warning-severity unless your .markdownlint.* assigns a rule "error")`).action(async(t,n)=>{let r=e(),i=process.cwd(),a=O(r,i),o=t===void 0?void 0:Er(t,Rt()),s=r.contentRules,c=await xr({projectDir:i,contentDir:a,baseConfig:s?y(s):m,targetPath:o,fix:n.fix===!0});n.json===!0?process.stdout.write(`${JSON.stringify(c,null,2)}\n`):process.stdout.write(`${kr(c)}\n`),(n.errorsOnly===!0?c.errorCount>0:Dr(c))&&(process.exitCode=1)})}function Er(e,t){return U(t,e)}function Dr(e){return e.errorCount>0||e.warningCount>0}function Or(e){let t=[B(e.file)+(e.fixed?I(` (fixed)`):``)];for(let n of e.diagnostics){let e=I(`${n.range.start.line+1}:${n.range.start.character+1}`.padEnd(7)),r=n.severity===`error`?R(`error `):z(`warning`);t.push(` ${e} ${r} ${n.message} ${I(`${n.source}/${n.code}`)}`)}return t.push(``),t}function kr(e){let t=[];for(let n of e.files)n.diagnostics.length>0&&t.push(...Or(n));for(let n of e.warnings)t.push(z(`! ${n}`));e.warnings.length>0&&t.push(``);let n=e.errorCount+e.warningCount;if(n===0)t.push(L(`✓ No problems in ${e.fileCount} file${e.fileCount===1?``:`s`}.`));else{let r=[`${n} problem${n===1?``:`s`}`];r.push(`${e.errorCount} error${e.errorCount===1?``:`s`}`),r.push(`${e.warningCount} warning${e.warningCount===1?``:`s`}`),t.push(`${R(r[0]??``)} (${r[1]}, ${r[2]}) across ${e.fileCount} file${e.fileCount===1?``:`s`}.`)}return e.fixedCount>0&&t.push(I(`Fixed ${e.fixedCount} file${e.fixedCount===1?``:`s`}.`)),t.join(`
3
3
  `)}const Ar={out:e=>process.stdout.write(`${e}\n`),err:e=>process.stderr.write(`${e}\n`)};function jr(e){return new P(`audit`).description(`Unified validation audit (markdown lint + broken internal links) via the running project server`).argument(`[path]`,`Folder or file to audit, relative to where you run the command`).option(`--json`,`Emit the full structured JSON response instead of formatted text`).option(`--errors-only`,`Exit non-zero only on error-severity problems (broken links default to warnings; the project's validation.links setting can raise them to errors)`).action(async(t,n)=>{let r=await Mr(t,n,e(),process.cwd(),Rt());r!==0&&(process.exitCode=r)})}async function Mr(e,t,n,r,i,o=Ar){let s=O(n,r),c;if(e!==void 0){let t=Nr(e,i,s);if(t===null)return o.err(`Path is outside the content directory (${s}): ${e}`),1;c=t===``?void 0:t}let l=Dt(T(r));if(!l||l.port<=0)return o.err("OpenKnowledge server is not running — the links validator needs the live backlink index. Start it with `ok start` (or open OK Desktop) and re-run. For headless lint-only checks, use `ok lint`."),1;let u=c===void 0?``:`?path=${encodeURIComponent(c)}`,d;try{d=await fetch(`http://127.0.0.1:${l.port}/api/audit${u}`,{headers:a({kind:`cli`,runtimeVersion:Et})})}catch(e){return o.err(`Could not reach the OpenKnowledge server on port ${l.port}: ${String(e)}`),1}if(!d.ok){let e=await d.json().catch(()=>({}));return o.err(`Audit failed: ${e.title??e.error??e.message??`server responded with ${d.status}`}`),1}let f=x.safeParse(await d.json().catch(()=>null));if(!f.success){let e=f.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `);return o.err(`Audit failed: unexpected response shape from the server. Schema issues: ${e}`),1}let p=f.data;return t.json===!0?o.out(JSON.stringify(p,null,2)):o.out(kr(Pr(p))),+(t.errorsOnly===!0?p.errorCount>0:p.errorCount+p.warningCount>0)}function Nr(e,t,n){let r=H(n,U(t,e));return r===``?``:r.startsWith(`..`)||Un(r)?null:r.split(Wn).join(`/`)}function Pr(e){return{files:e.files.map(e=>({file:e.file,fixed:!1,diagnostics:e.diagnostics})),warnings:e.warnings,fileCount:e.fileCount,errorCount:e.errorCount,warningCount:e.warningCount,fixedCount:0}}async function Fr(e,t,n,r){let i=Ir(await Lr(e)).host??``,a=e=>e.replace(/[\r\n]/g,``);if(!i)return r?.log?.warn({outcome:`no-host`,backend:n.backend},`[auth] git-credential get`),1;let o=process.env.OK_GH_TOKEN,s=process.env.OK_GH_TOKEN_HOST;if(o&&s===i)return r?.log?.debug({host:i,outcome:`gh-env-token`,backend:n.backend},`[auth] git-credential get`),t.write(`username=x-access-token\npassword=${a(o)}\n`),0;let c=await n.get(i),l=r?.getDiag?.(),u=c==null?l?.kind??`absent`:`found`;if(r?.log){let e={host:i,outcome:u,backend:n.backend,...l?.error?{keychainError:l.error}:{}};u===`found`?r.log.debug(e,`[auth] git-credential get`):r.log.warn(e,`[auth] git-credential get`)}return c==null?1:(t.write(`username=${a(c.login)}\npassword=${a(c.token)}\n`),0)}function Ir(e){let t={};for(let n of e.split(`
4
4
  `)){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 Lr(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 Rr(e,t){let n=new P(`git-credential`);return n.description(`Git credential helper (git credential-helper protocol)`),n.command(`get`).description(`Lookup credentials from TokenStore (called by git)`).action(async()=>{let n=t?.();try{let t,r=await e({onKeychainRead:e=>{t=e},onBackendSelected:e=>{e.backend===`file`&&e.reason&&n?.warn({backend:`file`,reason:e.reason},`[auth] token storage fallback`)}}),i=await Fr(process.stdin,process.stdout,r,{log:n,getDiag:()=>t});await We(n),process.exit(i)}catch(e){n?.error({err:e},`[auth] git-credential get: unexpected error`),await We(n),process.exit(1)}}),n}function zr(e){let t=e.endpoint.DEFAULTS;return/^https:\/\/(api\.)?github\.com$/.test(t.baseUrl)?`https://github.com`:t.baseUrl.replace(`/api/v3`,``)}async function Br(e,t,n){let r={baseUrl:zr(e),headers:{accept:`application/json`},...n},i=await e(t,r);if(`error`in i.data){let n=new tn(`${i.data.error_description} (${i.data.error}, ${i.data.error_uri})`,400,{request:e.endpoint.merge(t,r)});throw n.response=i,n}return i}async function Vr(e){let t=e.request||rn,n={client_id:e.clientId};return`scopes`in e&&Array.isArray(e.scopes)&&(n.scope=e.scopes.join(` `)),Br(t,`POST /login/device/code`,n)}async function Hr(e){let t=await Br(e.request||rn,`POST /login/oauth/access_token`,{client_id:e.clientId,device_code:e.code,grant_type:`urn:ietf:params:oauth:grant-type:device_code`}),n={clientType:e.clientType,clientId:e.clientId,token:t.data.access_token,scopes:t.data.scope.split(/\s+/).filter(Boolean)};if(`clientSecret`in e&&(n.clientSecret=e.clientSecret),e.clientType===`github-app`){if(`refresh_token`in t.data){let e=new Date(t.headers.date).getTime();n.refreshToken=t.data.refresh_token,n.expiresAt=Ur(e,t.data.expires_in),n.refreshTokenExpiresAt=Ur(e,t.data.refresh_token_expires_in)}delete n.scopes}return{...t,authentication:n}}function Ur(e,t){return new Date(e+t*1e3).toISOString()}async function Wr(e,t){let n=Gr(e,t.auth);if(n)return n;let{data:r}=await Vr({clientType:e.clientType,clientId:e.clientId,request:t.request||e.request,scopes:t.auth.scopes||e.scopes});await e.onVerification(r);let i=await qr(t.request||e.request,e.clientId,e.clientType,r);return e.authentication=i,i}function Gr(e,t){if(t.refresh===!0||!e.authentication)return!1;if(e.clientType===`github-app`)return e.authentication;let n=e.authentication;return(`scopes`in t&&t.scopes||e.scopes).join(` `)===n.scopes.join(` `)?n:!1}async function Kr(e){await new Promise(t=>setTimeout(t,e*1e3))}async function qr(e,t,n,r){try{let i={clientId:t,request:e,code:r.device_code},{authentication:a}=n===`oauth-app`?await Hr({...i,clientType:`oauth-app`}):await Hr({...i,clientType:`github-app`});return{type:`token`,tokenType:`oauth`,...a}}catch(i){if(!i.response)throw i;let a=i.response.data.error;if(a===`authorization_pending`)return await Kr(r.interval),qr(e,t,n,r);if(a===`slow_down`)return await Kr(r.interval+7),qr(e,t,n,r);throw i}}async function Jr(e,t){return Wr(e,{auth:t})}async function Yr(e,t,n,r){let i=t.endpoint.merge(n,r);if(/\/login\/(oauth\/access_token|device\/code)$/.test(i.url))return t(i);let{token:a}=await Wr(e,{request:t,auth:{type:`oauth`}});return i.headers.authorization=`token ${a}`,t(i)}var Xr=`0.0.0-development`;function Zr(e){let t=e.request||rn.defaults({headers:{"user-agent":`octokit-auth-oauth-device.js/${Xr} ${nn()}`}}),{request:n=t,...r}=e,i=e.clientType===`github-app`?{...r,clientType:`github-app`,request:n}:{...r,clientType:`oauth-app`,request:n,scopes:e.scopes||[]};if(!e.clientId)throw Error(`[@octokit/auth-oauth-device] "clientId" option must be set (https://github.com/octokit/auth-oauth-device.js#usage)`);if(!e.onVerification)throw Error(`[@octokit/auth-oauth-device] "onVerification" option must be a function (https://github.com/octokit/auth-oauth-device.js#usage)`);return Object.assign(Jr.bind(null,i),{hook:Yr.bind(null,i)})}async function Qr(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=Zr({clientType:`oauth-app`,clientId:t,scopes:n,onVerification:async e=>{await r({verificationUri:e.verification_uri,userCode:e.user_code,expiresIn:e.expires_in,interval:e.interval})},request:a===`https://api.github.com`?void 0:(await import(`./dist-bundle-BT5p_5Yl.mjs`)).request.defaults({baseUrl:a})}),s;try{s=await o({type:`oauth`})}catch(e){if(e instanceof Error){let t=e.message.toLowerCase();throw t.includes(`access_denied`)?Error(`Device-flow authorization was denied.`):t.includes(`expired_token`)||t.includes(`timeout`)||t.includes(`timed out`)?Error(`Device-flow code expired before authorization — please try again.`):Error(`GitHub sign-in failed: ${e.message}`)}throw e}return{token:s.token,tokenType:s.tokenType,scopes:s.scopes??[]}}function $r(){return process.env.OPEN_KNOWLEDGE_GITHUB_CLIENT_ID??`Ov23liqlSd0V1MwR6rhI`}function ei(e){let t=e.toLowerCase().replace(/:\d+$/,``);b.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 ti(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function ni(e,t,n=Qr){let r=$r(),{host:i,json:a}=e;ei(i),a||process.stderr.write(`Logging in to ${i}\n`);let o=await n({clientId:r,host:i===`github.com`?void 0:i,onVerification:e=>{e.userCode,e.verificationUri,a?ti(!0,{type:`verification`,user_code:e.userCode,verification_uri:e.verificationUri,expires_in:e.expiresIn}):process.stderr.write(`Open: ${e.verificationUri}\nEnter code: ${e.userCode}\n`)}}),s=`unknown`,c,l;try{let e=i===`github.com`?`https://api.github.com`:`https://${i}/api/v3`,t=await fetch(`${e}/user`,{headers:{Authorization:`Bearer ${o.token}`,"User-Agent":`open-knowledge-cli`,Accept:`application/vnd.github+json`}});if(t.ok){let e=await t.json();s=e.login??s,c=e.name??void 0,l=e.email??void 0}}catch{}await t.set(i,s,o.token,{gitProtocol:`https`,name:c,email:l}),a?ti(!0,{type:`complete`,host:i,login:s}):process.stderr.write(`✓ Logged in as ${s} on ${i}\n`)}function ri(e){return new P(`login`).description(`Authenticate with GitHub via Device Flow`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname (default: workspace origin host)`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{let n=t.host??D(process.cwd()),r=await e();await ni({...t,host:n},r)})}const ii={style:{maskedText:`[input is masked]`}};var ai=un((e,t)=>{let{validate:n=()=>!0}=e,r=vn(ii,e.theme),[i,a]=ln(`idle`),[o,s]=ln(),[c,l]=ln(``),u=on({status:i,theme:r});Sn(async(e,r)=>{if(i===`idle`)if(_n(e)){let e=c;a(`loading`);let i=await n(e);i===!0?(l(e),a(`done`),t(e)):(r.write(c),s(i||`You must provide a valid value`),a(`idle`))}else l(r.line),s(void 0)});let d=r.style.message(e.message,i),f=``,p;e.mask?f=(typeof e.mask==`string`?e.mask:`*`).repeat(c.length):i!==`done`&&(p=`${r.style.help(r.style.maskedText)}${hn}`),i===`done`&&(f=r.style.answer(f));let m=``;return o&&(m=r.style.error(o)),[[u,d,e.mask?f:p].join(` `),m]});function oi(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>oi.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function si(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function ci(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const li=Function.bind,ui=li.bind(li);function di(e,t,n){let r=ui(ci,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=ui(si,null).apply(null,i)})}function fi(){let e=Symbol(`Singular`),t={registry:{}},n=oi.bind(null,t,e);return di(n,t,e),n}function pi(){let e={registry:{}},t=oi.bind(null,e);return di(t,e),t}var mi={Singular:fi,Collection:pi},hi=`0.0.0-development`;function gi(e){return`Request failed due to following response errors:
5
5
  `+e.errors.map(e=>` - ${e.message}`).join(`
@@ -8,9 +8,9 @@ import{o as e}from"./chunk-DTipWd-i.mjs";import{B as t,Ea as n,Fa as r,Hi as i,J
8
8
  `),n.includes(`file`)&&process.stderr.write(` cleared from ~/.ok/auth.yml
9
9
  `)}function da(){return new P(`signout`).description(`Remove stored credentials`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname (default: workspace origin host)`).action(async e=>{let t=e.host??D(process.cwd());await ua({...e,host:t})})}async function fa(e,t,n=Qt){let r=n(e);if(r.available&&r.token)return{tier:`A`,token:r.token};let i=await t.get(e);return i==null?{tier:`none`}:{tier:i.gitProtocol===`ssh`?`C`:`B`,token:i.token}}function pa(e,t,n){return{type:`status`,host:e,backend:t,...n}}async function ma(e,t){let{host:n,json:r}=e;ei(n);let i=t.backend,a=await fa(n,t);a.tier===`none`&&(r?process.stdout.write(`${JSON.stringify(pa(n,i,{authenticated:!1}))}\n`):process.stderr.write(`Not logged in to ${n}\n`),process.exit(1));let o=n===`github.com`?void 0:`https://${n}/api/v3`,s=new ea({auth:a.token,...o?{baseUrl:o}:{}});try{let{data:e}=await s.users.getAuthenticated();r?process.stdout.write(`${JSON.stringify(pa(n,i,{authenticated:!0,tier:a.tier,login:e.login,name:e.name,email:e.email}))}\n`):process.stderr.write(`✓ Logged in as ${e.login} on ${n}\n`)}catch(e){let t=ra(e,n);r?process.stdout.write(`${JSON.stringify(pa(n,i,{authenticated:!1,error:t.message}))}\n`):process.stderr.write(`✗ ${t.message}\n`),process.exit(1)}}function ha(e){return new P(`status`).description(`Show authentication status`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname (default: workspace origin host)`).option(`--json`,`Output JSON`,!1).action(async t=>{let n=t.host??D(process.cwd());await ma({...t,host:n},await e())})}function ga(e){let t=new P(`auth`);t.description(`GitHub authentication management`);let n=e=>Zt(void 0,e);return t.addCommand(ri(n)),t.addCommand(ha(n)),t.addCommand(la(n)),t.addCommand(da()),t.addCommand(oa(n)),t.addCommand(Rr(n,e)),t}function _a(){return new P(`bug-report`).description(`Generate a diagnostic bundle for bug reporting`).option(`--reveal`,`Reveal the bundle in Finder (default: true)`,!0).option(`--no-reveal`,`Do not reveal the bundle in Finder`).action(async e=>{try{let{zipPath:t,summary:n}=await Bt({level:`standard`,projectDir:process.cwd(),redact:!0,outputPath:Pt(),logger:Tf()});if(process.stdout.write(`${t}\n`),n.redactedLineCount>0&&process.stderr.write(`ok bug-report: ${n.redactedLineCount} line(s) auto-redacted across ${n.redactions.length} file(s)\n`),e.reveal&&or()===`darwin`)try{En(`/usr/bin/open`,[`-R`,t])}catch{}}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`ok bug-report: failed — ${t}\n`),process.exitCode=1}})}function va(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 ya(e){let t=e.inspect??(t=>Yt(e.lockDir,t)),n=e.unlink??(e=>rr(e)),r=e.log??(e=>console.log(e)),i=e.error??(e=>console.error(e)),a=va(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 ba(e){return new P(`clean`).description(`Prune stale / corrupt open-knowledge lock files (never touches live locks)`).action(()=>{e(),ya({lockDir:T(process.cwd())}).failed.length>0&&(process.exitCode=1)})}function xa(e){return`credential.helper=!${e.map(o).join(` `)} auth git-credential`}async function Sa(e,t,n={},r=Qt){let i=[`credential.helper=`,xa(n.selfCliArgs??[`open-knowledge`])];if(!n.skipGhDetect){let t=r(e);if(t.available&&t.token)return{tier:`A`,gitConfig:i,relayToken:{token:t.token,host:e}}}let a=await t.get(e);return a==null?{tier:`none`,gitConfig:[]}:{tier:a.gitProtocol===`ssh`?`C`:`B`,gitConfig:i}}async function Ca(e,t,n=fetch){let r=new AbortController,i=setTimeout(()=>r.abort(),5e3);try{return(await n(`https://api.github.com/repos/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{signal:r.signal,headers:{"User-Agent":`open-knowledge-cli`,Accept:`application/vnd.github+json`}})).status===200}catch{return!1}finally{clearTimeout(i)}}const wa=[[`count`,0,10],[`compress`,10,20],[`receiv`,20,60],[`resolv`,60,100]];function Ta(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 wa)if(n.includes(e))return{stage:t[1],pct:Math.round(i+r/100*(a-i))};return null}function q(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}function Ea(e=process.env){let t={};for(let[n,r]of Object.entries(e))r!==void 0&&(t[n]=r);return t.GIT_TERMINAL_PROMPT=`0`,t.LANG=`C`,t.LC_ALL=`C`,t}function Da(e,t=process.env){let n=Ea(t);return e.relayToken?(n.OK_GH_TOKEN=e.relayToken.token,n.OK_GH_TOKEN_HOST=e.relayToken.host):(delete n.OK_GH_TOKEN,delete n.OK_GH_TOKEN_HOST),n}function Oa(e=process.argv,t=process.execPath){let n=e[1];return n?[t,n]:[t]}function ka(e){return typeof e!=`string`||e.length===0?[`--progress`]:[`--progress`,`-b`,e]}const Aa=u;async function ja(e){try{return await e.clone(ka(e.branch)),{fellBack:!1}}catch(t){if(e.branch!==null&&Aa(t))return e.onFallback(e.branch),await e.clone(ka(null)),{fellBack:!0};throw t}}function Ma(e,t){return{baseDir:e,config:t,unsafe:{allowUnsafeCredentialHelper:!0,allowUnsafePager:!0,allowUnsafeSshCommand:!0,allowUnsafeAskPass:!0,allowUnsafeEditor:!0}}}function Na(e,t,n){return e===`https`&&t===`github.com`&&n}function Pa(e,t){let n=`${t.owner}/${t.name}`;return e===n||e===`${n}.git`?`https://${t.hostname}/${n}`:e}async function Fa(e,t,n,r=process.cwd()){let i=qt(e);if(!i)throw Error(`Invalid git URL: ${e}`);let a=Pa(e,i),o=t.dir?U(r,t.dir):U(r,i.name);if(W(o)&&$n(o).length>0)throw Error(`Target directory is not empty: ${o}`);Ye();let s=$t(),c=i.protocol===`https`&&i.hostname===`github.com`?await Ca(i.owner,i.name):!1,l=Na(i.protocol,i.hostname,c)?{tier:`none`,gitConfig:[]}:await Sa(i.hostname,s,{selfCliArgs:Oa()}),u=Da(l),d=Tt(Ma(r,l.gitConfig)).env(u),f=-1;d.outputHandler((e,n,r)=>{r.on(`data`,e=>{let n=e.toString(`utf-8`);for(let e of n.split(`
10
10
  `)){let n=Ta(e);n&&n.pct!==f&&(f=n.pct,q(t.json,{type:`progress`,pct:n.pct,stage:n.stage}),t.json||process.stderr.write(`\r Cloning ${n.pct}%`))}})}),await ja({branch:typeof t.branch==`string`&&t.branch.length>0?t.branch:null,clone:e=>d.clone(a,o,e),onFallback:e=>{q(t.json,{type:`branch-fallback`,branch:e}),t.json||process.stderr.write(`\n Branch '${e}' not found upstream — cloning default branch instead.\n`)}}),t.json||process.stderr.write(`
11
- `);try{let{runInit:e}=await import(`./init-BG8F8jyV.mjs`),n=await e({cwd:o,mcp:!1});if(n.contentUpdated.length>0){let e=`auto-init: updated ${n.contentUpdated.join(`, `)}`;t.json?q(!0,{type:`warning`,message:e}):process.stderr.write(` ${e}\n`)}}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`auto-init: ${n}`}):process.stderr.write(` auto-init: ${n}\n`)}try{Ia(o)}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`git-exclude: ${n}`}):process.stderr.write(` git-exclude: ${n}\n`)}return o}function Ia(e){let t=pn(e,[`.ok/`]);return t.kind===`no-exclude`?`no-exclude`:t.kind===`refused-tracked`?`already-present`:t.appended.length>0?`appended`:`already-present`}const La=/^[A-Za-z0-9._/:@-]+$/;function Ra(e){return La.test(e)?e:o(e)}function za(e,t){let n=typeof t==`string`&&t.length>0?` -b ${Ra(t)}`:``;return`ok clone ${Ra(e)}${n}`}function Ba(e){let t=i(e.error);if(t.kind!==`auth`)return null;if(d(t)){let t=za(e.url,e.branch);return[`✗ Couldn't clone ${e.url} — authentication is required.`,``,` To fix:`,` 1. Run: ok auth login`,` 2. Then re-run: ${t}`].join(`
11
+ `);try{let{runInit:e}=await import(`./init-BNoSqnre.mjs`),n=await e({cwd:o,mcp:!1});if(n.contentUpdated.length>0){let e=`auto-init: updated ${n.contentUpdated.join(`, `)}`;t.json?q(!0,{type:`warning`,message:e}):process.stderr.write(` ${e}\n`)}}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`auto-init: ${n}`}):process.stderr.write(` auto-init: ${n}\n`)}try{Ia(o)}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`git-exclude: ${n}`}):process.stderr.write(` git-exclude: ${n}\n`)}return o}function Ia(e){let t=pn(e,[`.ok/`]);return t.kind===`no-exclude`?`no-exclude`:t.kind===`refused-tracked`?`already-present`:t.appended.length>0?`appended`:`already-present`}const La=/^[A-Za-z0-9._/:@-]+$/;function Ra(e){return La.test(e)?e:o(e)}function za(e,t){let n=typeof t==`string`&&t.length>0?` -b ${Ra(t)}`:``;return`ok clone ${Ra(e)}${n}`}function Ba(e){let t=i(e.error);if(t.kind!==`auth`)return null;if(d(t)){let t=za(e.url,e.branch);return[`✗ Couldn't clone ${e.url} — authentication is required.`,``,` To fix:`,` 1. Run: ok auth login`,` 2. Then re-run: ${t}`].join(`
12
12
  `)}if(t.subclass===`403`){let t=typeof e.principal==`string`&&e.principal.length>0?` (signed in as @${e.principal} — may lack access)`:``;return`✗ Access denied when cloning ${e.url}${t}. Check that your account has access to the repository.`}return t.subclass===`ssh-auth`?`✗ Couldn't clone ${e.url} over SSH — authentication failed. Check that your SSH key is added to your GitHub account and the host key is trusted, or clone the HTTPS URL instead.`:["✗ Your GitHub token is missing required OAuth scopes — likely the `repo` scope.",``,` To fix:`," 1. Create a token with `repo` scope at https://github.com/settings/tokens",` 2. Run: ok auth pat`,` 3. Then re-run: ${za(e.url,e.branch)}`].join(`
13
- `)}function Va(e){let t=e.error instanceof Error?e.error.message:String(e.error);if(e.json){e.emit({type:`error`,message:t});return}let n=Ba({error:e.error,url:e.url,branch:e.branch,principal:e.principal});e.printStderr(`${n??`✗ ${t}`}\n`)}async function Ha(e,t){let n=(await e.get(t))?.login;return n&&n!==`unknown`?n:null}async function Ua(e){let t=i(e.error),n=null;if(!e.json&&t.kind===`auth`&&t.subclass===`403`){let t=qt(e.url);t&&(n=await(e.resolvePrincipal??(e=>Ha($t(),e)))(t.hostname))}Va({error:e.error,url:e.url,branch:e.branch,json:e.json,principal:n,emit:e.emit,printStderr:e.printStderr})}function Wa(e){return new P(`clone`).description(`Clone a git repository and open it`).argument(`<url>`,`Repository URL or owner/repo shorthand`).argument(`[dir]`,`Target directory (default: ./<repo-name>)`).option(`--json`,`Output JSONL progress events`,!1).option(`-b, --branch <branch>`,`Branch to check out (falls back to default if missing)`).action(async(t,n,r)=>{let i=e();try{let a=await Fa(t,{json:r.json,dir:n,branch:r.branch??null},i);if(r.json)q(!0,{type:`complete`,dir:a});else{process.stderr.write(`✓ Cloned to ${a}\n`),process.chdir(a);let{startCommand:t}=await import(`./start-3HnyNbf6.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){if(e instanceof Ie||e instanceof ge){r.json?q(!0,{type:`error`,message:e.message}):process.stderr.write(`${e.message}\n`),process.exitCode=78;return}await Ua({error:e,url:t,branch:r.branch??null,json:r.json,emit:e=>q(!0,e),printStderr:e=>process.stderr.write(e)}),process.exitCode=1}})}var Ga=st();const Ka=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],[`server`,`port`],...pt.map(e=>e.path)];function qa(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??Mn;try{let{sources:n}=r(e.cwd);return t(`✓ Configuration valid (sources: ${n.length===0?`defaults only`:n.join(`, `)})`),{ok:!0}}catch(e){return n(e instanceof Error?e.message:String(e)),{ok:!1}}}function Ja(e){let t=(0,Ga.parseDocument)(G(e,`utf-8`));if(t.errors.length>0)throw Error(`Could not parse ${e}: ${t.errors.map(e=>e.message).join(`; `)}`);let n=[];for(let e of Ka)t.hasIn(e)&&n.push(e.join(`.`));return n}function Ya(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Xa(e){let t={};for(let n of e){let e=t;for(let t=0;t<n.length-1;t++){let r=n[t],i=e[r],a=Ya(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}async function Za(e={}){let t=e.log??(e=>console.log(e)),n=e.error??(e=>console.error(e)),r=e.scope??`both`,i=e.dryRun??!1,a=e.cwd??process.cwd(),o=e.writeConfigPatchFn??wt,s=[];(r===`project`||r===`both`)&&s.push({scope:`project`,absPath:St(`project`,a,e.homedirOverride)}),(r===`user`||r===`both`)&&s.push({scope:`user`,absPath:St(`user`,a,e.homedirOverride)});let c=[],l=!0;for(let{scope:t,absPath:n}of s){if(!W(n)){c.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=Ja(n)}catch(e){let r=e instanceof Error?e.message:String(e);c.push({path:n,scope:t,found:[],removed:[],error:r}),l=!1;continue}if(r.length===0||i){c.push({path:n,scope:t,found:r,removed:[]});continue}let s=await o({cwd:a,scope:t,patch:Xa(Ka.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!s.ok){c.push({path:n,scope:t,found:r,removed:[],error:gt(s.error)}),l=!1;continue}c.push({path:n,scope:t,found:r,removed:r})}for(let e of c)e.error&&n(`✗ ${e.path}: ${e.error}`);let u=c.some(e=>e.error!==void 0),d=c.reduce((e,t)=>e+t.found.length,0);if(d===0&&!u)t(`No deprecated fields found.`);else if(d>0)for(let e of c)e.error||(e.found.length===0?t(` ${e.path}: no deprecated fields`):t(i?`[dry-run] ${e.path}: would remove ${e.found.length} field(s): ${e.found.join(`, `)}`:`✓ ${e.path}: removed ${e.removed.length} field(s): ${e.removed.join(`, `)}`));return{outcomes:c,ok:l}}function Qa(){let e=new P(`config`).description(`Inspect and maintain OpenKnowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{qa({}).ok||(process.exitCode=1)}),e.command(`migrate`).description(`Remove deprecated config fields from config.yml idempotently (every removed key in the registry — content.*, folders, appearance.editorModeDefault, server.host, etc. — plus the silently-dropped sync.*, persistence.*, server.port)`).option(`--scope <scope>`,`Which scope to migrate: project | user | both`,`both`).option(`--dry-run`,`Preview without writing`,!1).action(async e=>{let t=e.scope;if(t!==`project`&&t!==`user`&&t!==`both`){console.error(`Invalid --scope: ${t}. Expected: project | user | both`),process.exitCode=2;return}(await Za({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}const $a=[` 1. ${B(`Customize`)} (sidebar) → ${B(`Skills`)}`,` 2. Click the ${B(`+`)} button`,` 3. Click ${B(`Create skill`)}`,` 4. Click ${B(`Upload skill`)}`,` 5. Pick ${B(`openknowledge.skill`)} from Downloads`],eo=F(` Open the Claude Desktop App, then: ${B(`Customize → Skills → + → Create skill → Upload skill`)} → pick the file.`);function to(e){let t=[L(`Built ${e.outputPath}`),I(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…`)];return e.handoffError&&t.push(z(` Handoff failed: ${e.handoffError.message}`)),t.push(eo),t.join(`
13
+ `)}function Va(e){let t=e.error instanceof Error?e.error.message:String(e.error);if(e.json){e.emit({type:`error`,message:t});return}let n=Ba({error:e.error,url:e.url,branch:e.branch,principal:e.principal});e.printStderr(`${n??`✗ ${t}`}\n`)}async function Ha(e,t){let n=(await e.get(t))?.login;return n&&n!==`unknown`?n:null}async function Ua(e){let t=i(e.error),n=null;if(!e.json&&t.kind===`auth`&&t.subclass===`403`){let t=qt(e.url);t&&(n=await(e.resolvePrincipal??(e=>Ha($t(),e)))(t.hostname))}Va({error:e.error,url:e.url,branch:e.branch,json:e.json,principal:n,emit:e.emit,printStderr:e.printStderr})}function Wa(e){return new P(`clone`).description(`Clone a git repository and open it`).argument(`<url>`,`Repository URL or owner/repo shorthand`).argument(`[dir]`,`Target directory (default: ./<repo-name>)`).option(`--json`,`Output JSONL progress events`,!1).option(`-b, --branch <branch>`,`Branch to check out (falls back to default if missing)`).action(async(t,n,r)=>{let i=e();try{let a=await Fa(t,{json:r.json,dir:n,branch:r.branch??null},i);if(r.json)q(!0,{type:`complete`,dir:a});else{process.stderr.write(`✓ Cloned to ${a}\n`),process.chdir(a);let{startCommand:t}=await import(`./start-Br97vCln.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){if(e instanceof Ie||e instanceof ge){r.json?q(!0,{type:`error`,message:e.message}):process.stderr.write(`${e.message}\n`),process.exitCode=78;return}await Ua({error:e,url:t,branch:r.branch??null,json:r.json,emit:e=>q(!0,e),printStderr:e=>process.stderr.write(e)}),process.exitCode=1}})}var Ga=st();const Ka=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],[`server`,`port`],...pt.map(e=>e.path)];function qa(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??Mn;try{let{sources:n}=r(e.cwd);return t(`✓ Configuration valid (sources: ${n.length===0?`defaults only`:n.join(`, `)})`),{ok:!0}}catch(e){return n(e instanceof Error?e.message:String(e)),{ok:!1}}}function Ja(e){let t=(0,Ga.parseDocument)(G(e,`utf-8`));if(t.errors.length>0)throw Error(`Could not parse ${e}: ${t.errors.map(e=>e.message).join(`; `)}`);let n=[];for(let e of Ka)t.hasIn(e)&&n.push(e.join(`.`));return n}function Ya(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Xa(e){let t={};for(let n of e){let e=t;for(let t=0;t<n.length-1;t++){let r=n[t],i=e[r],a=Ya(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}async function Za(e={}){let t=e.log??(e=>console.log(e)),n=e.error??(e=>console.error(e)),r=e.scope??`both`,i=e.dryRun??!1,a=e.cwd??process.cwd(),o=e.writeConfigPatchFn??wt,s=[];(r===`project`||r===`both`)&&s.push({scope:`project`,absPath:St(`project`,a,e.homedirOverride)}),(r===`user`||r===`both`)&&s.push({scope:`user`,absPath:St(`user`,a,e.homedirOverride)});let c=[],l=!0;for(let{scope:t,absPath:n}of s){if(!W(n)){c.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=Ja(n)}catch(e){let r=e instanceof Error?e.message:String(e);c.push({path:n,scope:t,found:[],removed:[],error:r}),l=!1;continue}if(r.length===0||i){c.push({path:n,scope:t,found:r,removed:[]});continue}let s=await o({cwd:a,scope:t,patch:Xa(Ka.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!s.ok){c.push({path:n,scope:t,found:r,removed:[],error:gt(s.error)}),l=!1;continue}c.push({path:n,scope:t,found:r,removed:r})}for(let e of c)e.error&&n(`✗ ${e.path}: ${e.error}`);let u=c.some(e=>e.error!==void 0),d=c.reduce((e,t)=>e+t.found.length,0);if(d===0&&!u)t(`No deprecated fields found.`);else if(d>0)for(let e of c)e.error||(e.found.length===0?t(` ${e.path}: no deprecated fields`):t(i?`[dry-run] ${e.path}: would remove ${e.found.length} field(s): ${e.found.join(`, `)}`:`✓ ${e.path}: removed ${e.removed.length} field(s): ${e.removed.join(`, `)}`));return{outcomes:c,ok:l}}function Qa(){let e=new P(`config`).description(`Inspect and maintain OpenKnowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{qa({}).ok||(process.exitCode=1)}),e.command(`migrate`).description(`Remove deprecated config fields from config.yml idempotently (every removed key in the registry — content.*, folders, appearance.editorModeDefault, server.host, etc. — plus the silently-dropped sync.*, persistence.*, server.port)`).option(`--scope <scope>`,`Which scope to migrate: project | user | both`,`both`).option(`--dry-run`,`Preview without writing`,!1).action(async e=>{let t=e.scope;if(t!==`project`&&t!==`user`&&t!==`both`){console.error(`Invalid --scope: ${t}. Expected: project | user | both`),process.exitCode=2;return}(await Za({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}const $a=[` 1. ${B(`Customize`)} (sidebar) → ${B(`Skills`)}`,` 2. Click the ${B(`+`)} button`,` 3. Click ${B(`Create skill`)}`,` 4. Click ${B(`Upload skill`)}`,` 5. Pick ${B(`openknowledge.skill`)} from Downloads`],eo=F(` Open the Claude Desktop App, then: ${B(`Customize → Skills → + → Create skill → Upload skill`)} → pick the file.`);function to(e){let t=[L(`Built ${e.outputPath}`),I(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…`)];return e.handoffError&&t.push(z(` Handoff failed: ${e.handoffError.message}`)),t.push(eo),t.join(`
14
14
  `)}function no(e){let t=e.skillVersion??`unknown`,n=e.recordedAt??`unknown`;return[F(`OpenKnowledge skill ${B(`v${t}`)} already delivered to Claude Desktop.`),I(` Recorded at ${n} in ~/.ok/skill-state.yml`),I(` Use ${B(`--force`)} to rebuild and re-open the install dialog.`)].join(`
15
15
  `)}function ro(e){let t=e.skillVersion?` • Skill v${e.skillVersion}`:``;return[L(`Built ${e.outputPath}`),I(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…${t}`),F(` Claude Desktop App opened. Now upload the file manually:`),...$a,I(` If Claude Desktop didn't open, open it and start at step 1. The file is at ${e.outputPath}`)].join(`
16
16
  `)}function io(e){return`${R(`Error:`)} ${e.buildError??`unknown build failure`}`}async function ao(e={}){let t=await je(e);return t.status===`failed`?{...t,message:io(t),exitCode:1}:t.status===`skip-current`?{...t,message:no(t),exitCode:0}:t.status===`installed`?{...t,message:ro(t),exitCode:0}:{...t,message:to(t),exitCode:0}}function oo(){return new P(`cowork`).description("Build openknowledge.skill and open the Claude Desktop App so you can upload it for Claude Chat & Cowork. (Advanced/rarely needed — `ok init` already wires Claude.)").option(`--out <path>`,`Custom output path (default: ~/Downloads/openknowledge.skill)`).option(`--no-open`,`Build the file but skip the OS file-association handoff`).option(`--force`,`Bypass the install-state gate and rebuild unconditionally`).action(async e=>{let t=await ao({out:e.out,noOpen:!e.open,force:e.force??!1});process.stdout.write(`${t.message}\n`),t.exitCode!==0&&process.exit(t.exitCode)})}async function so(e,t){let n=gr({input:t??process.stdin,output:process.stderr});try{let t=(await n.question(e)).trim().toLowerCase();return t===`y`||t===`yes`}finally{n.close()}}function co(e={}){let t=e.productName??`OpenKnowledge`;return V(Nt(e),t)}function lo(e){if(typeof e!=`object`||!e)return null;let t=e.recentProjects;if(!Array.isArray(t))return null;let n=[];for(let e of t){if(typeof e!=`object`||!e)continue;let t=e;typeof t.path==`string`&&typeof t.name==`string`&&n.push({path:t.path,name:t.name})}return n}function uo(e){let t=V(e,`state.json`);if(!W(t))return[];let n;try{n=JSON.parse(G(t,`utf-8`))}catch{return[]}return lo(n)??[]}function fo(e){let t=V(e,`state.json`);if(!W(t))return!1;try{return lo(JSON.parse(G(t,`utf-8`)))!==null}catch{return!1}}function J(e,t){return e===t?`~`:e.startsWith(`${t}/`)?`~${e.slice(t.length)}`:e}function po(e){return Wn===`/`?e:e.split(Wn).join(`/`)}function mo(e,t,n=`This project`){let r=[];r.push({kind:`stop-server`,group:n,label:`Stop the project server (if running)`,lockDir:T(e)});let i=new Set;for(let a of Mt){let o=kt[a];if(!o.projectConfigPath)continue;let s=o.projectConfigPath(e);i.add(po(H(e,s))),r.push({kind:`mcp-entry`,group:n,label:`Remove OK's MCP entry from ${o.label} (${po(H(e,s))})`,editorId:a,scope:`project`,cwd:e,home:t,configPath:s})}r.push({kind:`launch-entry`,group:n,label:`Remove OK's entry from .claude/launch.json`,projectRoot:e}),r.push({kind:`git-exclude`,group:n,label:`Remove OK paths from .git/info/exclude`,projectRoot:e});let a=new Set([...yn(e),...c]);for(let t of a){let a=t.replace(/\/$/,``);i.has(a)||a!==`.claude/launch.json`&&r.push({kind:`remove-path`,group:n,label:`Remove ${t}`,path:V(e,a),containWithin:e})}try{r.push({kind:`remove-path`,group:n,label:`Remove the OK shadow repo (.git/ok/)`,path:Ge(e)})}catch{}return r}function ho(e,t){return{scope:`deinit`,ops:mo(e,t)}}function go(e){let{home:t,platform:n,host:r,lockDirs:i,marker:a,recentDeinitProjectRoots:o,purgeContent:s}=e,c=[];for(let e of i)c.push({kind:`stop-server`,group:`Running servers`,label:`Stop server at ${J(V(e,`..`,`..`),t)}`,lockDir:e});c.push({kind:`keychain-token`,group:`Credentials`,label:`Remove the GitHub credential (${r}) from the OS keychain + auth.yml`,host:r}),c.push({kind:`embeddings-key`,group:`Credentials`,label:`Remove the embeddings API key (secrets.yml)`}),c.push(...vo(a,t));for(let e of Mt){let n=kt[e],r;try{r=n.configPath(``,t)}catch{continue}c.push({kind:`mcp-entry`,group:`Editor MCP configs`,label:`Remove OK's MCP entry from ${n.label} (${J(r,t)})`,editorId:e,scope:`user`,cwd:t,home:t,configPath:r})}for(let e of jt(t))c.push({kind:`remove-path`,group:`Skill bundles`,label:`Remove ${J(e.path,t)}`,path:e.path});c.push(...yo(t,n,e.env));for(let e of o)c.push(...mo(e,t,`Project: ${Vn(e)}`));return c.push({kind:`remove-path`,group:`Global directory`,label:s?`Remove ~/.ok (including user-authored skills)`:`Remove ~/.ok (keeping ~/.ok/skills)`,path:V(t,`.ok`),preserve:s?void 0:[`skills`]}),{scope:`uninstall`,ops:c}}function _o(e){return[V(e,`.zshrc`),V(e,`.bash_profile`),V(e,`.config`,`fish`,`conf.d`,`open-knowledge.fish`)]}function vo(e,t){let n=[],r=new Set([..._o(t),...e?.rcFiles??[]]);for(let e of r)W(e)&&n.push({kind:`shell-block`,group:`Shell PATH`,label:`Strip the OK block from ${J(e,t)}`,rcFile:e});for(let r of e?.extraSymlinks??[])n.push({kind:`extra-symlink`,group:`Shell PATH`,label:`Remove the ok symlink at ${J(r.path,t)}`,path:r.path,target:r.target});return n}function yo(e,t,n){if(t!==`darwin`)return[];let r={home:e,platformName:t,env:n},i=co(r),a=co({...r,productName:`Open Knowledge`}),o=V(e,`Library`,`Caches`,`OpenKnowledge-updater`);return[{kind:`remove-path`,group:`Application data`,label:`Remove ${J(i,e)}`,path:i},{kind:`remove-path`,group:`Application data`,label:`Remove ${J(a,e)} (only if it is OpenKnowledge's)`,path:a,requireOurState:!0},{kind:`remove-path`,group:`Application data`,label:`Remove ${J(o,e)}`,path:o}]}async function bo(e,t={}){let n=t.clearToken??en,r=t.clearEmbeddingsKey??be,i=t.stopServer??(e=>{let t=Ht({lockDir:e,log:()=>{},error:()=>{}});return{stopped:t.stopped.length,failed:t.failed.map(e=>({pid:e.target.pid,error:e.error}))}}),a=[];for(let t of e.ops)try{a.push(await xo(t,{clearToken:n,clearEmbeddingsKey:r,stopServer:i}))}catch(e){a.push({op:t,status:`failed`,detail:e instanceof Error?e.message:String(e)})}return{results:a,removed:a.filter(e=>e.status===`removed`),failed:a.filter(e=>e.status===`failed`)}}async function xo(e,t){switch(e.kind){case`stop-server`:{let{stopped:n,failed:r}=t.stopServer(e.lockDir);return r.length>0?{op:e,status:`failed`,detail:`could not stop the server (${r.map(e=>`pid ${e.pid}: ${e.error}`).join(`; `)}); a process may still be using files that were removed`}:{op:e,status:n>0?`removed`:`not-present`}}case`keychain-token`:{let{touched:n,keychainError:r}=await t.clearToken(e.host);return r?{op:e,status:`failed`,detail:`keychain unreachable (${r}); remove manually: Keychain Access → service "open-knowledge"`}:{op:e,status:n.length>0?`removed`:`not-present`}}case`embeddings-key`:{let{touched:n}=await t.clearEmbeddingsKey();return{op:e,status:n.length>0?`removed`:`not-present`}}case`shell-block`:{if(!W(e.rcFile))return{op:e,status:`not-present`};let{text:t,changed:n,emptyAfter:r}=Ut(G(e.rcFile,`utf-8`));return n?r?(nr(e.rcFile,{force:!0}),{op:e,status:`removed`,detail:`file removed (was OK-owned)`}):(Ct(e.rcFile,t,{mode:gn(e.rcFile)}),{op:e,status:`removed`}):{op:e,status:`not-present`}}case`extra-symlink`:return Vt(e.path,e.target)?(rr(e.path),{op:e,status:`removed`}):{op:e,status:`not-present`};case`mcp-entry`:{let t=Kt(kt[e.editorId],e.cwd,e.home,e.configPath);switch(t.kind){case`removed`:return{op:e,status:`removed`};case`not-present`:return{op:e,status:`not-present`};case`left-foreign`:return{op:e,status:`skipped`,detail:`left a non-OK server in place`};case`declined`:return{op:e,status:`skipped`,detail:`declined (${t.reason})`};default:throw Error(`unhandled mcp-remove outcome: ${t.kind}`)}}case`launch-entry`:{let t=Pn(e.projectRoot);switch(t.kind){case`removed`:case`removed-file`:return{op:e,status:`removed`};case`not-present`:return{op:e,status:`not-present`};case`declined`:return{op:e,status:`skipped`,detail:`declined (unparseable)`};default:throw Error(`unhandled launch-remove outcome: ${t.kind}`)}}case`git-exclude`:{if(an(e.projectRoot).length===0)return{op:e,status:`not-present`};let t=cn(e.projectRoot,yn(e.projectRoot));return t.kind===`no-exclude`?t.reason===`inaccessible`?{op:e,status:`failed`,detail:`could not write .git/info/exclude (inaccessible)`}:{op:e,status:`not-present`,detail:t.reason}:{op:e,status:t.removed.length>0?`removed`:`not-present`}}case`remove-path`:return So(e)}}function So(e){if(e.requireOurState&&!fo(e.path))return{op:e,status:`skipped`,detail:`not verified as OpenKnowledge — left untouched`};e.containWithin&&At(e.path,e.containWithin);let t;try{t=Yn(e.path)}catch(e){if(e.code!==`ENOENT`)throw e}if(!t)return{op:e,status:`not-present`};if(t.isSymbolicLink())return rr(e.path),{op:e,status:`removed`};if(e.preserve&&e.preserve.length>0){let t=new Set(e.preserve),n=!1;for(let r of $n(e.path))t.has(r)||(nr(V(e.path,r),{recursive:!0,force:!0}),n=!0);return{op:e,status:n?`removed`:`not-present`}}return nr(e.path,{recursive:!0,force:!0}),{op:e,status:`removed`}}function Co(e){let t=new Map;for(let n of e){let e=t.get(n.group)??[];e.push(n),t.set(n.group,e)}return t}function wo(e){if(e.ops.length===0)return I(`Nothing to remove.`);let t=[];for(let[n,r]of Co(e.ops)){t.length>0&&t.push(``),t.push(B(`${n}:`));for(let e of r)t.push(` ${z(`-`)} ${e.label}`)}return t.join(`
@@ -39,7 +39,7 @@ ws.addEventListener('error', () => process.exit(1));
39
39
  setTimeout(() => process.exit(2), ${t+1e4});
40
40
  `),r}async function is(e,t,n,r,i){let a=rs(e,t,V(r,`cpu.cpuprofile`)),o=!1,s=zn(process.execPath,[a],A({stdio:`ignore`})),c=setInterval(()=>{let e=$o(n);e&&i(e)},1e3);await new Promise(e=>{s.once(`close`,t=>{o=t===0,e()}),setTimeout(()=>{s.kill(),e()},t+12e3)}),clearInterval(c);try{nr(V(a,`..`),{recursive:!0,force:!0})}catch{}return o}function as(e){let t;try{t=JSON.parse(e)}catch{return`(could not parse profile)`}let n=new Map(t.nodes.map(e=>[e.id,e])),r=new Map;for(let e of t.nodes)for(let t of e.children??[])r.set(t,e.id);let i=new Map;for(let e of t.samples??[])i.set(e,(i.get(e)??0)+1);let a=t.samples?.length??0,o=t.endTime!=null&&t.startTime!=null?((t.endTime-t.startTime)/1e3).toFixed(2):`?`,s=[...i.entries()].sort((e,t)=>t[1]-e[1]).slice(0,10),c=[`samples ${a} duration_ms ${o}`,``,`Top leaf nodes`];for(let[e,t]of s){let r=n.get(e);if(!r)continue;let i=a>0?(t/a*100).toFixed(1):`0.0`,{functionName:o,url:s,lineNumber:l,columnNumber:u}=r.callFrame;c.push(` ${t} ${i}% id=${e} ${o||`(anonymous)`} ${s}:${l}:${u} hit=${r.hitCount??0}`)}c.push(``,`Top stacks`);let l=e=>{let t=[],i=e;for(;i!=null;){let e=n.get(i);if(!e)break;let{functionName:a,url:o,lineNumber:s,columnNumber:c}=e.callFrame;t.unshift(` ${a||`(anonymous)`} ${o} ${s} ${c}`),i=r.get(i)}return t};for(let[e,t]of s.slice(0,5)){let n=a>0?(t/a*100).toFixed(1):`0.0`;c.push(``,`--- ${t} ${n}%`,...l(e))}return c.join(`
41
41
  `)}async function os(e,t={}){let{pid:n,cpuProfileSecs:r=15,noInspector:i=!1}=e,a=t.log??(e=>console.log(e)),o=t.discover??Ue,s=t.inspect??Yt,c=t.resolveCommand??ve,l=t.resolveUsage??ze,u=t.collectLsofFn??es,d=t.getEndpoints??ns,f=t.profiler??is,p=t.isAlive??(e=>{try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}),m=t.sendSignal??((e,t)=>{process.kill(e,t)}),h=t.sleep??(e=>new Promise(t=>setTimeout(t,e))),g=r*1e3;if(!p(n)){a(Y.default.red(`No process with pid ${n} found.`));return}let _=await o(),v=null,y=null;for(let e of _){let t=s(e,`server`);if(t.status!==`missing`&&t.status!==`corrupt`&&t.lock.pid===n){v=t.lock.worktreeRoot,y={lockDir:e,state:t.status,lockPath:t.lockPath,lock:t.lock};break}}let b=new Date().toISOString().replace(/[:.]/g,`-`),x=e.output?e.output:v?V(v,`.ok`,`local`,`diagnostics`,`process-${n}-${b}`):V(process.cwd(),`ok-diagnose-${n}-${b}`);try{Xn(x,{recursive:!0})}catch(e){a(Y.default.red(`Cannot create output directory ${x}: ${e.message}`));return}a(Y.default.bold(`Diagnosing pid ${n}`)),a(`Output: ${x}`),a(``);let S=(e,t)=>{ir(V(x,e),t),a(` wrote ${e}`)},ee=c(n),C=l(n);S(`metadata.json`,JSON.stringify({capturedAt:new Date().toISOString(),pid:n,command:ee,usage:C,lockInfo:y},null,2)),a(` sampling lsof`);let w=u(n);if(w&&S(`lsof.txt`,w),!i){let e=w?ts(w).find(e=>e>=9229&&e<=9299)??9229:9229,t=d(e);if(!t||t.length===0){a(` no inspector on :${e}, sending SIGUSR1 to pid ${n}`);try{m(n,`SIGUSR1`),await h(2e3),t=d(e)}catch(e){a(Y.default.yellow(` SIGUSR1 delivery failed: ${e.message}`))}}if(t&&t.length>0){S(`inspector-endpoints.json`,JSON.stringify(t,null,2));let e=t[0].webSocketDebuggerUrl;if(e){a(` capturing ${r}s CPU profile`);let t=[];await f(e,g,n,x,e=>t.push(e))?a(` wrote cpu.cpuprofile`):a(Y.default.yellow(` CPU profile capture failed`)),t.length>0&&S(`process-stats.jsonl`,`${t.map(e=>JSON.stringify(e)).join(`
42
- `)}\n`);try{S(`stacks.txt`,as(G(V(x,`cpu.cpuprofile`),`utf-8`)))}catch(e){a(Y.default.yellow(` stacks.txt skipped: ${e.message}`))}}}else a(Y.default.yellow(` Node inspector unavailable — skipping CPU profile`))}a(``),a(Y.default.yellow(`⚠ Before sharing, review what each file contains:`)),a(` metadata.json — content directory paths, lock file locations, CPU/MEM at capture time`),a(` lsof.txt — all open files, network connections, and private paths for this process`),a(` inspector-endpoints.json — Node debugger metadata (titles, URLs)`),a(` cpu.cpuprofile — function names and source file paths from your Node process`),a(` stacks.txt — call stacks derived from cpu.cpuprofile; includes source paths`),a(` process-stats.jsonl — CPU/MEM/RSS numbers only; safe to share`),a(``),a(`Bundle: ${Y.default.bold(x)}`)}async function ss(e){let t=gr({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function cs(e){let t=Zn(V(sr(),`ok-bundle-process-`));return await os({pid:e,output:t}),t}function ls(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MB`:`${(n/1024).toFixed(1)} GB`}function us(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function ds(e,t,n){let{summary:r,manifest:i}=t;e(``),e(Y.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${ls(r.totalBytes)} uncompressed`),e(` doc.name attributes: ${r.docNameCount} occurrence(s) in telemetry${r.redacted?` (values hashed)`:``}`),e(` Content-dir path: ${r.contentDirVisible?`visible (${i.contentDir.absolutePath})`:`not visible`}`),e(` Redacted: ${r.redacted?`yes`:`no`}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function fs(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??ss,i=t.runProcessDiagnose??cs,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=Hn(o);if(!W(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=V(e.contentDir,`.ok`,`local`,`diagnostics`);Xn(n,{recursive:!0}),o=V(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(Y.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await Jt({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(Y.default.yellow(` server not running — live state unavailable`)),ds(n,c,o),e.yes!==!0&&!us(await r(`Write bundle? [y/N]: `))?(n(Y.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await Lt({collected:c,outputPath:o}),n(Y.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{nr(s,{recursive:!0,force:!0})}catch{}}}function ps(){let e=new P(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(Y.default.red(`Invalid pid '${e}': must be a positive integer`)),process.exit(1));let r=Number.parseInt(t.cpuProfile,10);(Number.isNaN(r)||r<=0)&&(console.error(Y.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await os({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(Qo()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--redact`,`Hash doc names and strip the content-dir prefix from the staged bundle`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(Y.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-48vYo7np.mjs`),{resolveContentDir:r}=await import(`./src-DQTDRmqk.mjs`),i=process.cwd(),{config:a}=n(i);await fs({contentDir:r(a,i),projectDir:i,pid:t,out:e.out,yes:e.yes===!0,redact:e.redact===!0})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(Y.default.red(t)),process.exit(1)}}),e}async function ms(){if(!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString(`utf-8`).trim()}return(await ai({message:`Enter embeddings provider API key:`})).trim()}function hs(e){return Re(e)}async function gs(){return(await Ke()).file?{present:!0,source:`file`}:process.env.OK_EMBEDDINGS_API_KEY?{present:!0,source:`env`}:{present:!1,source:null}}async function _s(e){try{let t=Dt(T(e));if(!t||t.port<=0||!Ot(t.pid))return null;let n=await fetch(`http://127.0.0.1:${t.port}/api/semantic-status`,{signal:AbortSignal.timeout(1500)});if(!n.ok)return null;let r=await n.json();return typeof r.embedded!=`number`||typeof r.total!=`number`?null:{embedded:r.embedded,total:r.total}}catch{return null}}function vs(){return new P(`set-key`).description(`Store your embeddings provider API key in ~/.ok/secrets.yml`).action(async()=>{let e=await ms();if(!e){process.stderr.write(`No key provided.
42
+ `)}\n`);try{S(`stacks.txt`,as(G(V(x,`cpu.cpuprofile`),`utf-8`)))}catch(e){a(Y.default.yellow(` stacks.txt skipped: ${e.message}`))}}}else a(Y.default.yellow(` Node inspector unavailable — skipping CPU profile`))}a(``),a(Y.default.yellow(`⚠ Before sharing, review what each file contains:`)),a(` metadata.json — content directory paths, lock file locations, CPU/MEM at capture time`),a(` lsof.txt — all open files, network connections, and private paths for this process`),a(` inspector-endpoints.json — Node debugger metadata (titles, URLs)`),a(` cpu.cpuprofile — function names and source file paths from your Node process`),a(` stacks.txt — call stacks derived from cpu.cpuprofile; includes source paths`),a(` process-stats.jsonl — CPU/MEM/RSS numbers only; safe to share`),a(``),a(`Bundle: ${Y.default.bold(x)}`)}async function ss(e){let t=gr({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function cs(e){let t=Zn(V(sr(),`ok-bundle-process-`));return await os({pid:e,output:t}),t}function ls(e){if(e<1024)return`${e} B`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} KB`;let n=t/1024;return n<1024?`${n.toFixed(1)} MB`:`${(n/1024).toFixed(1)} GB`}function us(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function ds(e,t,n){let{summary:r,manifest:i}=t;e(``),e(Y.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${ls(r.totalBytes)} uncompressed`),e(` doc.name attributes: ${r.docNameCount} occurrence(s) in telemetry${r.redacted?` (values hashed)`:``}`),e(` Content-dir path: ${r.contentDirVisible?`visible (${i.contentDir.absolutePath})`:`not visible`}`),e(` Redacted: ${r.redacted?`yes`:`no`}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function fs(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??ss,i=t.runProcessDiagnose??cs,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=Hn(o);if(!W(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=V(e.contentDir,`.ok`,`local`,`diagnostics`);Xn(n,{recursive:!0}),o=V(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(Y.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await Jt({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(Y.default.yellow(` server not running — live state unavailable`)),ds(n,c,o),e.yes!==!0&&!us(await r(`Write bundle? [y/N]: `))?(n(Y.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await Lt({collected:c,outputPath:o}),n(Y.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{nr(s,{recursive:!0,force:!0})}catch{}}}function ps(){let e=new P(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(Y.default.red(`Invalid pid '${e}': must be a positive integer`)),process.exit(1));let r=Number.parseInt(t.cpuProfile,10);(Number.isNaN(r)||r<=0)&&(console.error(Y.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await os({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(Qo()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--redact`,`Hash doc names and strip the content-dir prefix from the staged bundle`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(Y.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-3kHXROAa.mjs`),{resolveContentDir:r}=await import(`./src-CgblAAT9.mjs`),i=process.cwd(),{config:a}=n(i);await fs({contentDir:r(a,i),projectDir:i,pid:t,out:e.out,yes:e.yes===!0,redact:e.redact===!0})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(Y.default.red(t)),process.exit(1)}}),e}async function ms(){if(!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString(`utf-8`).trim()}return(await ai({message:`Enter embeddings provider API key:`})).trim()}function hs(e){return Re(e)}async function gs(){return(await Ke()).file?{present:!0,source:`file`}:process.env.OK_EMBEDDINGS_API_KEY?{present:!0,source:`env`}:{present:!1,source:null}}async function _s(e){try{let t=Dt(T(e));if(!t||t.port<=0||!Ot(t.pid))return null;let n=await fetch(`http://127.0.0.1:${t.port}/api/semantic-status`,{signal:AbortSignal.timeout(1500)});if(!n.ok)return null;let r=await n.json();return typeof r.embedded!=`number`||typeof r.total!=`number`?null:{embedded:r.embedded,total:r.total}}catch{return null}}function vs(){return new P(`set-key`).description(`Store your embeddings provider API key in ~/.ok/secrets.yml`).action(async()=>{let e=await ms();if(!e){process.stderr.write(`No key provided.
43
43
  `),process.exitCode=1;return}await Te().set(e),process.stderr.write(`✓ Embeddings provider API key stored in ~/.ok/secrets.yml (0600, this machine only).
44
44
  Now enable it per project — the easiest path is OK Desktop → Settings → This
45
45
  project → Search (toggle + endpoint settings), or run
@@ -73,7 +73,7 @@ ${t}`,d++;break;case`id`:l=t.includes(`\0`)?void 0:t;break;case`retry`:/^\d+$/.t
73
73
  `).replace(/\n+$/,``);return e.endsWith(`
74
74
  `)?`${c}\n`:c}function xu(e){return e.replace(/\r\n|\r|\n/g,`<br>`).replace(/\|/g,`\\|`)}function Su(e){return/\s/.test(e)?`<${e}>`:e}function Cu(e,t={}){let{header:n,rows:r}=Kl(e),i=n.length;if(i===0)return{table:``,columns:0,wide:!1};let a=t.wideThreshold??15,o=t.titleColumn??0;return{table:[`| ${n.map(xu).join(` | `)} |`,`| ${n.map(()=>`---`).join(` | `)} |`,...r.map(e=>`| ${n.map((n,r)=>{let i=e[r]??``,a=xu(i);if(r===o&&t.linkForTitle&&i.trim()!==``){let e=t.linkForTitle(i);if(e)return`[${a}](${Su(e)})`}return a}).join(` | `)} |`)].join(`
75
75
  `),columns:i,wide:i>a}}function wu(e,t){let n=e.match(/^#\s+(.+)$/m);return n?n[1].trim():t}function Tu(e,t){return`# ${e}\n\n${t}\n`}const Eu=[`links`,`frontmatter`,`callouts`,`images`,`tables`],Du=/\.mdx?$/i;function Ou(e){return{isNotionExport:e,transforms:{links:0,frontmatter:0,callouts:0,images:0,tables:0},assetsExtracted:0,stubsCreated:0,csvsRemoved:0,wideTables:[],ambiguousTitleLinks:0,unreadable:[],filesChanged:0}}function ku(e,t={}){let n=t.selected??new Set(Eu),r=pu(e);if(!r&&!t.force)return{changes:[],assets:[],deletions:[],report:Ou(!1)};let i=Ou(r),a=uu(e),o=tu(a,{onUnreadable:e=>i.unreadable.push(e)}),s=n.has(`tables`),c=new Map,l=new Set;for(let e of o){e.stubPath&&l.add(e.stubPath);for(let t of e.rowFiles)c.set(t,e)}let u=[],d=[],f=[];for(let e of a){if(!Du.test(e)||s&&l.has(e))continue;let r;try{r=G(e,`utf8`)}catch{i.unreadable.push(e);continue}let a=r,o=(e,t)=>{a!==t&&(i.transforms[e]+=1)};if(n.has(`images`)){let n=a,r=Gl(a,Vn(e),{strip:t.stripBase64});a=r.markdown;for(let t of r.assets)d.push({path:V(Hn(e),t.filename),bytes:t.bytes});i.assetsExtracted+=r.assets.length,o(`images`,n)}if(n.has(`callouts`)){let e=a;a=Vl(a),o(`callouts`,e)}if(n.has(`frontmatter`)){let t=c.get(e);if(t){let e=a;a=bu(a,t.propertyKeys),o(`frontmatter`,e)}}if(n.has(`links`)){let e=a;a=lu(a,{redirectCsv:s}),o(`links`,e)}a!==r&&u.push({path:e,content:a})}if(s)for(let e of o){let r=Cu(e.csvText,{linkForTitle:t=>{let n=Ql(e.folderIndex,t);return n.ambiguous&&(i.ambiguousTitleLinks+=1),n.path?H(Hn(e.stubTargetPath),n.path):null}});if(r.columns===0)continue;let a=e.stubPath??e.stubTargetPath,o=null;if(e.stubPath)try{o=G(e.stubPath,`utf8`)}catch{i.unreadable.push(e.stubPath);continue}let c=Tu(o===null?e.fallbackTitle:wu(o,e.fallbackTitle),r.table);n.has(`links`)&&(c=lu(c,{redirectCsv:s})),r.wide&&i.wideTables.push(a),o===null?(u.push({path:a,content:c}),i.stubsCreated+=1,i.transforms.tables+=1):c!==o&&(u.push({path:a,content:c}),i.transforms.tables+=1),t.removeCsv&&(f.push(e.csvPath),i.csvsRemoved+=1)}return i.filesChanged=new Set(u.map(e=>e.path)).size,{changes:u,assets:d,deletions:f,report:i}}function Au(e){for(let t of e.assets)Xn(Hn(t.path),{recursive:!0}),ir(t.path,t.bytes);for(let t of e.changes)Xn(Hn(t.path),{recursive:!0}),ir(t.path,t.content,`utf8`);for(let t of e.deletions)try{rr(t)}catch(e){if(e.code!==`ENOENT`)throw e}}const ju={images:`Inline base64 images extracted`,callouts:`Notion <aside> callouts converted`,frontmatter:`Row properties lifted to frontmatter`,tables:`Databases rendered as tables`,links:`Internal links decoded`},Mu=[`images`,`callouts`,`frontmatter`,`tables`,`links`];function Nu(e,t){let n=[];n.push(t.applied?`Applied Notion cleanup in ${t.dir}`:`Dry run — no changes written (${t.dir})`);for(let t of Mu)n.push(` ${ju[t]}: ${e.transforms[t]}`);return n.push(` Assets written: ${e.assetsExtracted}`),e.stubsCreated>0&&n.push(` Database pages created (CSVs without a stub): ${e.stubsCreated}`),e.csvsRemoved>0&&n.push(` CSV files removed: ${e.csvsRemoved}`),n.push(` Files changed: ${e.filesChanged}`),e.ambiguousTitleLinks>0&&n.push(` Ambiguous title links left as plain text: ${e.ambiguousTitleLinks}`),e.wideTables.length>0&&n.push(` Wide tables (>15 columns): ${e.wideTables.length}`),e.unreadable.length>0&&n.push(` Skipped unreadable files: ${e.unreadable.length}`),!t.applied&&e.filesChanged+e.assetsExtracted+e.csvsRemoved>0&&(n.push(``),n.push(`Re-run with --apply to write these changes.`)),n.join(`
76
- `)}function Pu(e,t){return JSON.stringify({applied:t.applied,...e},null,2)}function Fu(e){let t=new Set(Eu);return e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0).map(e=>{if(!t.has(e))throw Error(`Unknown transform "${e}". Valid transforms: ${Eu.join(`, `)}`);return e})}function Iu(e,t){let n=new Set(Eu);if(e&&(n=new Set(Fu(e))),t)for(let e of Fu(t))n.delete(e);return n}function Lu(){let e=new P(`migrate`).description(`Migrate content from other tools into Open Knowledge`);return e.command(`notion [dir]`).description(`Clean up a Notion "Markdown & CSV" export in place (dry-run unless --apply)`).option(`--apply`,`write changes to disk (default: dry-run preview)`).option(`--strip-base64`,`delete inline base64 images instead of extracting them to files`).option(`--remove-csv`,`delete each "_all.csv" once its table page exists (destructive)`).option(`--only <transforms>`,`run only these transforms (comma-separated: links,frontmatter,callouts,images,tables)`).option(`--skip <transforms>`,`skip these transforms (comma-separated)`).option(`--force`,`run even if the directory is not detected as a Notion export`).option(`--json`,`print a machine-readable JSON report`).action((e,t)=>{let n=U(e??process.cwd()),r;try{r=Iu(t.only,t.skip)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=2;return}let i=ku(n,{selected:r,stripBase64:t.stripBase64??!1,removeCsv:t.removeCsv??!1,force:t.force??!1}),{report:a}=i;if(!a.isNotionExport&&!t.force){t.json?console.log(JSON.stringify({refused:!0,reason:`not-a-notion-export`,dir:n},null,2)):console.error(`Not a Notion export: ${n}\nNo id-suffixed pages, "_all.csv", or inline base64 images were found. Re-run with --force to override.`),process.exitCode=2;return}if(t.apply)try{Au(i)}catch(e){console.error(`Failed to apply changes: ${e instanceof Error?e.message:String(e)}`),process.exitCode=4;return}console.log(t.json?Pu(a,{applied:t.apply??!1}):Nu(a,{applied:t.apply??!1,dir:n})),a.filesChanged===0&&a.assetsExtracted===0&&i.deletions.length===0?process.exitCode=1:t.apply&&(a.ambiguousTitleLinks>0||a.wideTables.length>0)&&(process.exitCode=3)}),e}function Ru(e=()=>jn(Tn())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>He({lockDir:T(e)}).baseUrl,classifyName:(e,t)=>{let n=V(e,t);try{return K(n).isDirectory()?`folder`:`doc`}catch(e){let t=e?.code;return t!==`ENOENT`&&t!==`ENOTDIR`&&process.stderr.write(`[ok open] statSync failed for ${n} (${t??`unknown`}); treating as a doc\n`),`doc`}},openTarget:e=>{En(`open`,[e])},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function zu(e){return e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).includes(`..`)}function Bu(e){return e.error("No OpenKnowledge desktop app found and no UI is running. Install OK Desktop, or start a UI with `ok ui`, then retry."),1}function Vu(e,t,n,r){let i=`openknowledge://open?project=${encodeURIComponent(e)}&${t}=${encodeURIComponent(n)}`;r.openTarget(i)}function Hu(e,t,n){let i=U(t.project??process.cwd()),a=e.replace(/\/+$/,``);if(!a)return n.error("Nothing to open: pass a doc, folder, or skill name (e.g. `ok open specs/foo/SPEC`)."),1;if(zu(a))return n.error(`Invalid name "${a}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(t.skill===!0){let e=t.scope??`project`;if(!r.includes(e))return n.error(`Invalid --scope "${t.scope}": expected one of ${r.join(`, `)}.`),1;if(n.detectBundlePath())return Vu(i,`doc`,`__skill__/${e}/${a}`,n),n.log(`Opening skill ${a} (${e}) in the OpenKnowledge desktop app.`),0;let o=n.resolveBaseUrl(i);if(o){let t=`${o}/#/${Ze(e,a)}`;return n.openTarget(t),n.log(`Opening skill ${a} (${e}) in your browser: ${t}`),0}return Bu(n)}let o=/\/+$/.test(e)||n.classifyName(i,a)===`folder`,s=n.detectBundlePath();if(o){if(s)return Vu(i,`folder`,a,n),n.log(`Opening folder ${a} in the OpenKnowledge desktop app.`),0;let e=n.resolveBaseUrl(i);if(e){let t=`${e}/#/${Se(a)}`;return n.openTarget(t),n.log(`Opening folder ${a} in your browser: ${t}`),0}return Bu(n)}if(s)return Vu(i,`doc`,a,n),n.log(`Opening ${a} in the OpenKnowledge desktop app.`),0;let c=n.resolveBaseUrl(i);if(c){let e=`${c}/#/${ee(a)}`;return n.openTarget(e),n.log(`Opening ${a} in your browser: ${e}`),0}return Bu(n)}function Uu(){return new P(`open`).description(`Open a doc, folder, or skill in the OK Desktop app (falls back to the browser UI). Docs and folders are auto-detected — no flag needed.`).argument(`<name>`,`Doc path (specs/foo/SPEC), folder path (specs/foo or specs/foo/), or a skill name with --skill`).option(`--skill`,`Open <name> as a skill in the skill editor`).option(`--scope <scope>`,`Skill scope when --skill is set: ${r.join(` | `)}`,`project`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action((e,t)=>{process.exitCode=Hu(e,t,Ru())})}function Wu(e){return new P(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-hDB5CK12.mjs`),r=e(),i=process.cwd(),a=O(r,i),o;try{o=t({projectDir:i,contentDir:a})}catch(e){console.error(`Content preview failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}process.stdout.write(`${n(o,i)}\n`),o.totalCount===0&&o.warnings.length>0&&(process.exitCode=1)})}function Gu(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function Ku(e,t,n=process.cwd()){let r=e.op??`sync`,i=Dt(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`,...a({kind:`cli`,runtimeVersion:Et})},body:JSON.stringify({op:r})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.title??e.error??e.message??`Server responded with ${n.status}`)}Gu(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 o=Tt({baseDir:n});if(r===`sync`||r===`pull`){Gu(e.json,{type:`step`,step:`pull`});let t=await o.pull();Gu(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Gu(e.json,{type:`step`,step:`push`}),await o.push(),Gu(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
76
+ `)}function Pu(e,t){return JSON.stringify({applied:t.applied,...e},null,2)}function Fu(e){let t=new Set(Eu);return e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0).map(e=>{if(!t.has(e))throw Error(`Unknown transform "${e}". Valid transforms: ${Eu.join(`, `)}`);return e})}function Iu(e,t){let n=new Set(Eu);if(e&&(n=new Set(Fu(e))),t)for(let e of Fu(t))n.delete(e);return n}function Lu(){let e=new P(`migrate`).description(`Migrate content from other tools into Open Knowledge`);return e.command(`notion [dir]`).description(`Clean up a Notion "Markdown & CSV" export in place (dry-run unless --apply)`).option(`--apply`,`write changes to disk (default: dry-run preview)`).option(`--strip-base64`,`delete inline base64 images instead of extracting them to files`).option(`--remove-csv`,`delete each "_all.csv" once its table page exists (destructive)`).option(`--only <transforms>`,`run only these transforms (comma-separated: links,frontmatter,callouts,images,tables)`).option(`--skip <transforms>`,`skip these transforms (comma-separated)`).option(`--force`,`run even if the directory is not detected as a Notion export`).option(`--json`,`print a machine-readable JSON report`).action((e,t)=>{let n=U(e??process.cwd()),r;try{r=Iu(t.only,t.skip)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=2;return}let i=ku(n,{selected:r,stripBase64:t.stripBase64??!1,removeCsv:t.removeCsv??!1,force:t.force??!1}),{report:a}=i;if(!a.isNotionExport&&!t.force){t.json?console.log(JSON.stringify({refused:!0,reason:`not-a-notion-export`,dir:n},null,2)):console.error(`Not a Notion export: ${n}\nNo id-suffixed pages, "_all.csv", or inline base64 images were found. Re-run with --force to override.`),process.exitCode=2;return}if(t.apply)try{Au(i)}catch(e){console.error(`Failed to apply changes: ${e instanceof Error?e.message:String(e)}`),process.exitCode=4;return}console.log(t.json?Pu(a,{applied:t.apply??!1}):Nu(a,{applied:t.apply??!1,dir:n})),a.filesChanged===0&&a.assetsExtracted===0&&i.deletions.length===0?process.exitCode=1:t.apply&&(a.ambiguousTitleLinks>0||a.wideTables.length>0)&&(process.exitCode=3)}),e}function Ru(e=()=>jn(Tn())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>He({lockDir:T(e)}).baseUrl,classifyName:(e,t)=>{let n=V(e,t);try{return K(n).isDirectory()?`folder`:`doc`}catch(e){let t=e?.code;return t!==`ENOENT`&&t!==`ENOTDIR`&&process.stderr.write(`[ok open] statSync failed for ${n} (${t??`unknown`}); treating as a doc\n`),`doc`}},openTarget:e=>{En(`open`,[e])},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function zu(e){return e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).includes(`..`)}function Bu(e){return e.error("No OpenKnowledge desktop app found and no UI is running. Install OK Desktop, or start a UI with `ok ui`, then retry."),1}function Vu(e,t,n,r){let i=`openknowledge://open?project=${encodeURIComponent(e)}&${t}=${encodeURIComponent(n)}`;r.openTarget(i)}function Hu(e,t,n){let i=U(t.project??process.cwd()),a=e.replace(/\/+$/,``);if(!a)return n.error("Nothing to open: pass a doc, folder, or skill name (e.g. `ok open specs/foo/SPEC`)."),1;if(zu(a))return n.error(`Invalid name "${a}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(t.skill===!0){let e=t.scope??`project`;if(!r.includes(e))return n.error(`Invalid --scope "${t.scope}": expected one of ${r.join(`, `)}.`),1;if(n.detectBundlePath())return Vu(i,`doc`,`__skill__/${e}/${a}`,n),n.log(`Opening skill ${a} (${e}) in the OpenKnowledge desktop app.`),0;let o=n.resolveBaseUrl(i);if(o){let t=`${o}/#/${Ze(e,a)}`;return n.openTarget(t),n.log(`Opening skill ${a} (${e}) in your browser: ${t}`),0}return Bu(n)}let o=/\/+$/.test(e)||n.classifyName(i,a)===`folder`,s=n.detectBundlePath();if(o){if(s)return Vu(i,`folder`,a,n),n.log(`Opening folder ${a} in the OpenKnowledge desktop app.`),0;let e=n.resolveBaseUrl(i);if(e){let t=`${e}/#/${Se(a)}`;return n.openTarget(t),n.log(`Opening folder ${a} in your browser: ${t}`),0}return Bu(n)}if(s)return Vu(i,`doc`,a,n),n.log(`Opening ${a} in the OpenKnowledge desktop app.`),0;let c=n.resolveBaseUrl(i);if(c){let e=`${c}/#/${ee(a)}`;return n.openTarget(e),n.log(`Opening ${a} in your browser: ${e}`),0}return Bu(n)}function Uu(){return new P(`open`).description(`Open a doc, folder, or skill in the OK Desktop app (falls back to the browser UI). Docs and folders are auto-detected — no flag needed.`).argument(`<name>`,`Doc path (specs/foo/SPEC), folder path (specs/foo or specs/foo/), or a skill name with --skill`).option(`--skill`,`Open <name> as a skill in the skill editor`).option(`--scope <scope>`,`Skill scope when --skill is set: ${r.join(` | `)}`,`project`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action((e,t)=>{process.exitCode=Hu(e,t,Ru())})}function Wu(e){return new P(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-rVAd6E5r.mjs`),r=e(),i=process.cwd(),a=O(r,i),o;try{o=t({projectDir:i,contentDir:a})}catch(e){console.error(`Content preview failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}process.stdout.write(`${n(o,i)}\n`),o.totalCount===0&&o.warnings.length>0&&(process.exitCode=1)})}function Gu(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function Ku(e,t,n=process.cwd()){let r=e.op??`sync`,i=Dt(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`,...a({kind:`cli`,runtimeVersion:Et})},body:JSON.stringify({op:r})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.title??e.error??e.message??`Server responded with ${n.status}`)}Gu(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 o=Tt({baseDir:n});if(r===`sync`||r===`pull`){Gu(e.json,{type:`step`,step:`pull`});let t=await o.pull();Gu(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Gu(e.json,{type:`step`,step:`push`}),await o.push(),Gu(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
77
77
  `)),Gu(e.json,{type:`complete`,op:r}),e.json||process.stderr.write(`✓ ${r} complete\n`)}function qu(e){return new P(`sync`).description(`Commit, pull, and push to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ku({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 Ju(e){return new P(`pull`).description(`Pull changes from the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ku({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 Yu(e){return new P(`push`).description(`Push commits to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ku({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 Xu(e){return typeof e==`string`&&k.includes(e)}async function Zu(e={}){let t=U(e.cwd??process.cwd()),n=e.pack??`knowledge-base`;if(!E[n])return{status:`failed`,message:`${R(`Error:`)} Unknown pack "${n}". Available: ${k.join(`, `)}`,exitCode:1};let r;try{r=await re({projectDir:t,rootDir:e.root,packId:n,skipPrerequisite:e.dryRun===!0})}catch(e){return e instanceof de?{status:`prerequisite-missing`,message:`${R(`Error:`)} ${e.message}`,exitCode:1}:{status:`failed`,message:`${R(`Error:`)} ${e instanceof Error?e.message:String(e)}`,exitCode:1}}if(r.created.length===0){let e=E[n].name;return{status:`no-op`,message:`${L(`Your ${e} pack is already seeded.`)}\n${I(`Nothing to do.`)}`,plan:r,exitCode:0}}if(e.dryRun){let e=ne(E[n]);return{status:`dry-run`,message:`${B(`Reference this pack for inspiration (dry-run — no changes made):`)}\n\n${e}\n\n${B(`Plan:`)}\n\n${$u(r,t)}`,plan:r,exitCode:0}}if(!e.yes&&!await ed(`${B(`Plan:`)}\n\n${$u(r,t)}\n\n${B(`Apply?`)} ${I(`[Y/n] `)}`,e.confirmStream))return{status:`cancelled`,message:I(`Cancelled.`),plan:r,exitCode:0};let i=await ie(r,{projectDir:t,packId:n});if(i.errors.length>0){let e=i.errors.map(e=>` ${R(`✗`)} ${e.path}: ${e.error}`);return{status:`failed`,message:[`${z(`Applied`)} ${i.applied} entries, ${z(String(i.errors.length))} error(s):`,...e].join(`
78
78
  `),plan:r,exitCode:1}}let a=E[n].name,o=i.packSkillsInstalled.length>0?`\n${I(`Installed the ${a} skill for: ${i.packSkillsInstalled.join(`, `)}`)}`:``;return{status:`applied`,message:`${L(`✓ Seeded ${a}`)} ${I(`(${i.applied} entries, ${i.durationMs}ms)`)}${o}`,plan:r,exitCode:0}}function Qu(){let e=[B(`Available packs:`)];for(let t of k){let n=E[t];e.push(` ${L(t)} ${I(`—`)} ${n.name}: ${n.description}`)}return e.join(`
79
79
  `)}function $u(e,t){let n=[],r=e.created.filter(e=>e.kind===`folder`),i=e.created.filter(e=>e.kind===`file`);if(r.length>0){n.push(B(`Folders to create:`));for(let e of r)n.push(` ${L(`+`)} ${F(H(t,U(t,e.path))||e.path)}${I(`/`)}`)}if(i.length>0){n.length>0&&n.push(``),n.push(B(`Files to create:`));for(let e of i)n.push(` ${L(`+`)} ${F(H(t,U(t,e.path))||e.path)}`)}if(e.skipped.length>0){n.length>0&&n.push(``),n.push(I(`Already present (skipped):`));for(let t of e.skipped)n.push(` ${I(`· ${t.path} (${t.reason})`)}`)}if(e.warnings.length>0){n.length>0&&n.push(``),n.push(z(`Warnings:`));for(let t of e.warnings)n.push(` ${z(`!`)} ${t}`)}return n.join(`
@@ -82,9 +82,9 @@ ${t}`,d++;break;case`id`:l=t.includes(`\0`)?void 0:t;break;case`retry`:/^\d+$/.t
82
82
  `);return}if(a){process.stdout.write(`${JSON.stringify({type:`error`,code:c.kind})}\n`);return}process.stderr.write(`✗ share name-check failed: ${c.kind}\n`),process.exit(1)}function id(e){return new P(`name-check`).description(`Check if owner/name is available on GitHub`).requiredOption(`--owner <owner>`,`GitHub owner (user or org)`).requiredOption(`--name <name>`,`Repository name`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{await rd(t,await e())})}async function ad(e){try{let t=[],n=await e.users.getAuthenticated();t.push({login:n.data.login,kind:`user`,avatarUrl:n.data.avatar_url});for await(let n of e.paginate.iterator(e.orgs.listMembershipsForAuthenticatedUser,{state:`active`,per_page:100}))for(let e of n.data)(e.permissions?.can_create_repository===!0||e.role===`admin`)&&t.push({login:e.organization.login,kind:`org`,avatarUrl:e.organization.avatar_url??void 0});return{kind:`ok`,owners:t}}catch(e){return e.status===401?{kind:`auth-required`}:{kind:`network`}}}async function od(e,t){let{host:n,json:r}=e;ei(n);let i=await sa(n,t);if(i==null){if(r){process.stdout.write(`${JSON.stringify({type:`error`,code:`auth-required`})}\n`);return}process.stderr.write(`Not logged in to ${n}\n`),process.exit(1)}let a=n===`github.com`?void 0:`https://${n}/api/v3`,o=await ad(new ea({auth:i,...a?{baseUrl:a}:{}}));if(o.kind===`ok`){if(r)process.stdout.write(`${JSON.stringify({type:`owners`,owners:o.owners})}\n`);else for(let e of o.owners)process.stdout.write(`${e.kind}\t${e.login}\n`);return}if(r){process.stdout.write(`${JSON.stringify({type:`error`,code:o.kind})}\n`);return}process.stderr.write(`✗ share owners failed: ${o.kind}\n`),process.exit(1)}function sd(e){return new P(`owners`).description(`List GitHub owners eligible to host a new repository`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{await od(t,await e())})}function cd(e){let t=e,n=t.status,r=t.response?.data,i=t.response?.headers,a=`${r?.message??r?.errors?.map(e=>e.message??``).join(`
83
83
  `)??``}\n${t.message??``}`.toLowerCase();return n===401?`auth-required`:n===403?i?.[`x-github-sso`]||a.includes(`saml`)||a.includes(`sso`)?`saml-sso`:`network`:n===422&&(r?.errors?.some(e=>e.field===`name`)||a.includes(`already exists`)||a.includes(`name already exists`))?`name-conflict`:`network`}async function ld(e){let{octokit:t,ownerLogin:n,ownerKind:r,name:i,visibility:a,description:o}=e,s=a===`private`;if(r===`user`){let{data:e}=await t.repos.createForAuthenticatedUser({name:i,private:s,...o?{description:o}:{}});return{cloneUrl:e.clone_url,defaultBranch:e.default_branch??`main`}}let{data:c}=await t.repos.createInOrg({org:n,name:i,visibility:a,...o?{description:o}:{}});return{cloneUrl:c.clone_url,defaultBranch:c.default_branch??`main`}}async function ud(e,t,n){try{let{data:r}=await e.repos.get({owner:t,repo:n});return{cloneUrl:r.clone_url,defaultBranch:r.default_branch??`main`}}catch{return null}}async function dd(e,t){return(await e.users.getAuthenticated()).data.login.toLowerCase()===t.toLowerCase()?`user`:`org`}function fd(e){return Tt(Ma(e,[])).env(Ea())}function pd(e,t){if(!e.startsWith(`https://`))return e;try{if(new URL(e).hostname!==`github.com`)return e}catch{return e}return e.replace(`https://`,`https://x-access-token:${t}@`)}const md={ensureOkScaffold:e=>{Ee(e)},gitFactory:fd};async function hd(e){let t={...md,...e.deps},n=U(e.projectDir),r;if(e.ownerKind)r=e.ownerKind;else try{r=await dd(e.octokit,e.body.owner)}catch(e){return{kind:`error`,code:cd(e)}}try{t.ensureOkScaffold(n)}catch{return{kind:`error`,code:`init-failed`}}let i=t.gitFactory(n);if(!W(V(n,`.git`)))try{await i.init()}catch{return{kind:`error`,code:`init-failed`}}let a;try{a=await ld({octokit:e.octokit,ownerLogin:e.body.owner,ownerKind:r,name:e.body.name,visibility:e.body.visibility,description:e.body.description})}catch(t){if(cd(t)===`name-conflict`){let t=await ud(e.octokit,e.body.owner,e.body.name);if(t===null)return{kind:`error`,code:`name-conflict`};a=t}else return{kind:`error`,code:cd(t)}}try{await i.addRemote(`origin`,a.cloneUrl)}catch(e){if(!String(e.message??``).toLowerCase().includes(`remote origin already exists`))return{kind:`error`,code:`push-failed`}}let o=!1;try{await i.raw([`rev-parse`,`--verify`,`HEAD`])}catch{o=!0}if(o)try{await i.add(`.`),await i.raw([`commit`,`--allow-empty`,`-m`,`Initial commit`])}catch{return{kind:`error`,code:`init-failed`}}let s=pd(a.cloneUrl,e.token);try{await i.raw([`push`,s,`HEAD:refs/heads/${a.defaultBranch}`])}catch(e){let t=String(e.message??``).toLowerCase();return t.includes(`saml`)||t.includes(`sso`)?{kind:`error`,code:`saml-sso`}:{kind:`error`,code:`push-failed`}}try{await i.raw([`update-ref`,`refs/remotes/origin/${a.defaultBranch}`,`HEAD`])}catch{}return{kind:`ok`,value:{ownerLogin:e.body.owner,repoName:e.body.name,cloneUrl:a.cloneUrl,defaultBranch:a.defaultBranch}}}function gd(e,t){if(!e){t.kind===`ok`?process.stdout.write(`✓ Published ${t.value.cloneUrl}\n`):(process.stderr.write(`✗ share publish failed: ${t.code}\n`),process.exit(1));return}if(t.kind===`ok`){process.stdout.write(`${JSON.stringify({type:`publish`,...t.value})}\n`);return}process.stdout.write(`${JSON.stringify({type:`error`,code:t.code})}\n`)}async function _d(e,t){let{host:n,owner:r,name:i,visibility:a,description:o,projectDir:s,json:c}=e;ei(n);let l=await sa(n,t);if(l==null){gd(c,{kind:`error`,code:`auth-required`});return}let u=n===`github.com`?void 0:`https://${n}/api/v3`,d=new ea({auth:l,...u?{baseUrl:u}:{}});try{Rn(`git config user.email`,A({cwd:s,stdio:`ignore`}))}catch{process.env.GIT_AUTHOR_NAME??=`OpenKnowledge`,process.env.GIT_AUTHOR_EMAIL??=`noreply@inkeep.com`,process.env.GIT_COMMITTER_NAME??=`OpenKnowledge`,process.env.GIT_COMMITTER_EMAIL??=`noreply@inkeep.com`}gd(c,await hd({octokit:d,token:l,projectDir:s,body:{owner:r,name:i,visibility:a,description:o}}))}function vd(e){return new P(`publish`).description(`Publish a no-remote project to GitHub`).requiredOption(`--owner <owner>`,`GitHub owner (user or org)`).requiredOption(`--name <name>`,`Repository name`).requiredOption(`--visibility <visibility>`,`public or private`).option(`--description <description>`,`Repository description`).requiredOption(`--project-dir <projectDir>`,`Path to the project on disk`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{t.visibility!==`public`&&t.visibility!==`private`&&(process.stderr.write(`✗ visibility must be 'public' or 'private'
84
84
  `),process.exit(1)),await _d(t,await e())})}function yd(){let e=new P(`share`);e.description(`Sharing flow operations (owners, name-check, publish)`);let t=()=>Zt();return e.addCommand(sd(t)),e.addCommand(id(t)),e.addCommand(vd(t)),e}function bd(){return new P(`share`).description(`Switch this project to shared mode (commit OK config alongside content)`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=U(e.project??process.cwd()),n=fn(t),r=cn(t,yn(t));if(r.kind===`no-exclude`){xd(e.json,t,r.reason);return}let i=fn(t);if(e.json){let e={type:`sharing-share`,projectRoot:t,mode:i,removed:r.removed};process.stdout.write(`${JSON.stringify(e)}\n`);return}if(n===`shared`){process.stderr.write(`${F(`Sharing mode is already`)} ${B(`shared`)} ${F(`— nothing to do.`)}\n`);return}process.stderr.write(`${L(`✓`)} ${B(`Sharing mode set to`)} ${L(`shared`)}\n`),process.stderr.write(` Removed OK paths from ${B(`.git/info/exclude`)}; commit the files to share with teammates.\n`)})}function xd(e,t,n){if(e){process.stdout.write(`${JSON.stringify({type:`sharing-share`,projectRoot:t,mode:`no-git`,removed:[],reason:n})}\n`);return}process.stderr.write(`${z({"no-git":`No git repository here — sharing mode does not apply.`,"no-info-dir":`The gitdir's info/ folder is absent; cannot toggle sharing mode.`,"malformed-pointer":"The .git pointer file is malformed (stale worktree). Run `git worktree prune` and try again.",inaccessible:`The .git path is inaccessible (permissions or mount issue).`}[n])}\n`)}function Sd(){return new P(`status`).description(`Print the current sharing mode and the OK paths in .git/info/exclude`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=U(e.project??process.cwd()),n=fn(t),r=mn(t),i=[...an(t)],a=dn(t,yn(t)).tracked;if(e.json){let e={type:`sharing-status`,projectRoot:t,mode:n,skillsShared:r,excluded:i,trackedUpstream:a};process.stdout.write(`${JSON.stringify(e)}\n`);return}let o=[];if(o.push(`OpenKnowledge sharing mode: ${Cd(n)}`),r&&o.push(` ${B(`.ok/skills`)} is committable (carved out); the rest of .ok/ stays local.`),o.push(``),o.push(`Excluded from git via ${B(`.git/info/exclude`)}:`),i.length===0)o.push(` (none)`);else for(let e of i)o.push(` ${e}`);if(o.push(``),o.push(`Other OK paths exist but are tracked upstream:`),a.length===0)o.push(` (none)`);else for(let e of a)o.push(` ${e}`);o.push(``),o.push(`Toggle with: ${F(n===`local-only`?`ok config-sharing share`:`ok config-sharing unshare`)}`),r&&o.push(` (that shares the whole project; to undo only the skills carve-out, use the desktop app: Settings > Config sharing)`),process.stdout.write(`${o.join(`
85
- `)}\n`)})}function Cd(e){switch(e){case`shared`:return L(`shared`);case`local-only`:return L(`local-only`);case`no-git`:return z(`no-git (not a git repository)`)}}function wd(){return new P(`unshare`).description(`Switch this project to local-only mode (add OK artifacts to .git/info/exclude so they stay out of git)`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=U(e.project??process.cwd()),n=pn(t,yn(t));if(n.kind===`refused-tracked`){if(e.json){let e={type:`sharing-unshare`,projectRoot:t,mode:`refused-tracked`,tracked:n.tracked,remediation:n.remediation};process.stdout.write(`${JSON.stringify(e)}\n`)}else process.stderr.write(`${n.remediation}\n`);process.exitCode=1;return}if(n.kind===`no-exclude`){Td(e.json,t,n.reason);return}let r=fn(t);if(e.json){let e={type:`sharing-unshare`,projectRoot:t,mode:r,appended:n.appended,alreadyPresent:n.alreadyPresent};process.stdout.write(`${JSON.stringify(e)}\n`);return}if(n.appended.length===0){process.stderr.write(`${B(`Sharing mode is already`)} ${L(`local-only`)} ${B(`— nothing to do.`)}\n`);return}process.stderr.write(`${L(`✓`)} ${B(`Sharing mode set to`)} ${L(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${B(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function Td(e,t,n){if(e){process.stdout.write(`${JSON.stringify({type:`sharing-unshare`,projectRoot:t,mode:`no-git`,appended:[],alreadyPresent:[],reason:n})}\n`);return}process.stderr.write(`${z({"no-git":`No git repository here — sharing mode does not apply.`,"no-info-dir":`The gitdir's info/ folder is absent; cannot toggle sharing mode.`,"malformed-pointer":"The .git pointer file is malformed (stale worktree). Run `git worktree prune` and try again.",inaccessible:`The .git path is inaccessible (permissions or mount issue).`}[n])}\n`)}function Ed(){let e=new P(`config-sharing`);return e.description(`Manage OpenKnowledge's git-sharing mode (share OK config with the team, or keep local-only on this machine)`),e.addCommand(bd()),e.addCommand(wd()),e.addCommand(Sd()),e}const Dd=new Set([`--cwd`,`--log-level`]);function Od(e){let t=[],n=null,r=!1;for(let i=0;i<e.length;i++){let a=e[i];if(a===`--help`||a===`-h`||a===`--version`||a===`-V`){r=!0;break}if(a===`--cwd`||a===`--log-level`){a===`--cwd`&&(n=e[i+1]??null),i++;continue}if(a.startsWith(`--cwd=`)){n=a.slice(6);continue}if(!a.startsWith(`--log-level=`)&&!(a===`--no-color`||a===`--color`)){if(a.startsWith(`-`)){Dd.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function kd(e,t){if(e.length===0)return null;let n=e[0];return n===`open`&&e[1]!==void 0&&t.isFileish(e[1])?e[1]:t.knownSubcommands.has(n)?null:t.isFileish(n)?n:null}function Ad(e){return/\.(md|mdx)$/i.test(e)}function jd(e,t){if(Ad(t))return!0;try{return K(e).isFile()}catch(t){let n=t?.code;return n!==`ENOENT`&&n!==`ENOTDIR`&&process.stderr.write(`[ok] statSync failed for ${e} (${n??`unknown`}); treating as non-fileish\n`),!1}}function Md(e=()=>jn(Tn())){return{prepare:he,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{En(`open`,[e])},runProjectOpen:(e,t)=>Hu(e,{project:t},Ru()),runBrowserOpen:e=>Fd(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function Nd(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof Ve||e instanceof Xe||e instanceof Je)return t.error(e.message),1;throw e}if(n.mode===`project`)return t.runProjectOpen(n.docName,n.projectRoot);if(t.detectBundlePath()){let e=`openknowledge://open?file=${encodeURIComponent(n.canonicalFilePath)}`;return t.openTarget(e),t.log(`Opening ${n.singleDocRelPath} in the OpenKnowledge desktop app.`),0}return await t.runBrowserOpen(n),0}function Pd(){let e=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[U(e,`public`),U(e,`../../app/dist`),U(e,`../../../app/dist`)].find(e=>W(e))}async function Fd(e){let{createEphemeralProjectDir:t}=await import(`./src-DQTDRmqk.mjs`),{loadConfig:n}=await import(`./index.mjs`),{bootStartServer:r,resolveHost:i}=await import(`./start-3HnyNbf6.mjs`),{openBrowser:a}=await import(`./open-browser-D3OpxES8.mjs`),o=Pd();o||(process.stderr.write("OpenKnowledge UI assets were not found. Reinstall @inkeep/open-knowledge, or build the app (`bun run build`) in a monorepo checkout.\n"),process.exit(1));let s=t(e.contentDir),c=!1,l,u=async()=>{if(!c){c=!0;try{await l?.destroy()}catch{}try{await cr(s,{recursive:!0,force:!0})}catch{}}},d=()=>{u().then(()=>process.exit(0))};process.once(`SIGINT`,d),process.once(`SIGTERM`,d);let{config:f}=n(s),p=i({},process.env);try{l=await r({config:f,cwd:s,host:p,port:0,projectDir:s,singleFile:e.canonicalFilePath,serveContentAssets:!0,reactShellDistDir:o,idleThresholdMs:6e5})}catch(t){await u(),process.stderr.write(`Failed to open ${e.singleDocRelPath}: ${t instanceof Error?t.message:String(t)}\n`),process.exit(1)}let m=`http://${p}:${l.port}/#/${ee(e.docName)}`;process.env.OK_SINGLE_FILE_NO_OPEN===`1`?process.stdout.write(`Serving ${e.singleDocRelPath} (headless) at: ${m}\n`):(process.stdout.write(`Opening ${e.singleDocRelPath} in your browser: ${m}\n`),process.stdout.write(`Press Ctrl-C to close the session.
85
+ `)}\n`)})}function Cd(e){switch(e){case`shared`:return L(`shared`);case`local-only`:return L(`local-only`);case`no-git`:return z(`no-git (not a git repository)`)}}function wd(){return new P(`unshare`).description(`Switch this project to local-only mode (add OK artifacts to .git/info/exclude so they stay out of git)`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=U(e.project??process.cwd()),n=pn(t,yn(t));if(n.kind===`refused-tracked`){if(e.json){let e={type:`sharing-unshare`,projectRoot:t,mode:`refused-tracked`,tracked:n.tracked,remediation:n.remediation};process.stdout.write(`${JSON.stringify(e)}\n`)}else process.stderr.write(`${n.remediation}\n`);process.exitCode=1;return}if(n.kind===`no-exclude`){Td(e.json,t,n.reason);return}let r=fn(t);if(e.json){let e={type:`sharing-unshare`,projectRoot:t,mode:r,appended:n.appended,alreadyPresent:n.alreadyPresent};process.stdout.write(`${JSON.stringify(e)}\n`);return}if(n.appended.length===0){process.stderr.write(`${B(`Sharing mode is already`)} ${L(`local-only`)} ${B(`— nothing to do.`)}\n`);return}process.stderr.write(`${L(`✓`)} ${B(`Sharing mode set to`)} ${L(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${B(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function Td(e,t,n){if(e){process.stdout.write(`${JSON.stringify({type:`sharing-unshare`,projectRoot:t,mode:`no-git`,appended:[],alreadyPresent:[],reason:n})}\n`);return}process.stderr.write(`${z({"no-git":`No git repository here — sharing mode does not apply.`,"no-info-dir":`The gitdir's info/ folder is absent; cannot toggle sharing mode.`,"malformed-pointer":"The .git pointer file is malformed (stale worktree). Run `git worktree prune` and try again.",inaccessible:`The .git path is inaccessible (permissions or mount issue).`}[n])}\n`)}function Ed(){let e=new P(`config-sharing`);return e.description(`Manage OpenKnowledge's git-sharing mode (share OK config with the team, or keep local-only on this machine)`),e.addCommand(bd()),e.addCommand(wd()),e.addCommand(Sd()),e}const Dd=new Set([`--cwd`,`--log-level`]);function Od(e){let t=[],n=null,r=!1;for(let i=0;i<e.length;i++){let a=e[i];if(a===`--help`||a===`-h`||a===`--version`||a===`-V`){r=!0;break}if(a===`--cwd`||a===`--log-level`){a===`--cwd`&&(n=e[i+1]??null),i++;continue}if(a.startsWith(`--cwd=`)){n=a.slice(6);continue}if(!a.startsWith(`--log-level=`)&&!(a===`--no-color`||a===`--color`)){if(a.startsWith(`-`)){Dd.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function kd(e,t){if(e.length===0)return null;let n=e[0];return n===`open`&&e[1]!==void 0&&t.isFileish(e[1])?e[1]:t.knownSubcommands.has(n)?null:t.isFileish(n)?n:null}function Ad(e){return/\.(md|mdx)$/i.test(e)}function jd(e,t){if(Ad(t))return!0;try{return K(e).isFile()}catch(t){let n=t?.code;return n!==`ENOENT`&&n!==`ENOTDIR`&&process.stderr.write(`[ok] statSync failed for ${e} (${n??`unknown`}); treating as non-fileish\n`),!1}}function Md(e=()=>jn(Tn())){return{prepare:he,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{En(`open`,[e])},runProjectOpen:(e,t)=>Hu(e,{project:t},Ru()),runBrowserOpen:e=>Fd(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function Nd(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof Ve||e instanceof Xe||e instanceof Je)return t.error(e.message),1;throw e}if(n.mode===`project`)return t.runProjectOpen(n.docName,n.projectRoot);if(t.detectBundlePath()){let e=`openknowledge://open?file=${encodeURIComponent(n.canonicalFilePath)}`;return t.openTarget(e),t.log(`Opening ${n.singleDocRelPath} in the OpenKnowledge desktop app.`),0}return await t.runBrowserOpen(n),0}function Pd(){let e=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[U(e,`public`),U(e,`../../app/dist`),U(e,`../../../app/dist`)].find(e=>W(e))}async function Fd(e){let{createEphemeralProjectDir:t}=await import(`./src-CgblAAT9.mjs`),{loadConfig:n}=await import(`./index.mjs`),{bootStartServer:r,resolveHost:i}=await import(`./start-Br97vCln.mjs`),{openBrowser:a}=await import(`./open-browser-B_gopYWU.mjs`),o=Pd();o||(process.stderr.write("OpenKnowledge UI assets were not found. Reinstall @inkeep/open-knowledge, or build the app (`bun run build`) in a monorepo checkout.\n"),process.exit(1));let s=t(e.contentDir),c=!1,l,u=async()=>{if(!c){c=!0;try{await l?.destroy()}catch{}try{await cr(s,{recursive:!0,force:!0})}catch{}}},d=()=>{u().then(()=>process.exit(0))};process.once(`SIGINT`,d),process.once(`SIGTERM`,d);let{config:f}=n(s),p=i({},process.env);try{l=await r({config:f,cwd:s,host:p,port:0,projectDir:s,singleFile:e.canonicalFilePath,serveContentAssets:!0,reactShellDistDir:o,idleThresholdMs:6e5})}catch(t){await u(),process.stderr.write(`Failed to open ${e.singleDocRelPath}: ${t instanceof Error?t.message:String(t)}\n`),process.exit(1)}let m=`http://${p}:${l.port}/#/${ee(e.docName)}`;process.env.OK_SINGLE_FILE_NO_OPEN===`1`?process.stdout.write(`Serving ${e.singleDocRelPath} (headless) at: ${m}\n`):(process.stdout.write(`Opening ${e.singleDocRelPath} in your browser: ${m}\n`),process.stdout.write(`Press Ctrl-C to close the session.
86
86
  `),a(m)),await new Promise(()=>{})}function Id(){let e=new P(`skills`).description(`Manage Open Knowledge skills for this project.`);return e.command(`manage`).description(`Control whether OK adopts your editor skills into this project. Default: off — OK only manages skills already under .ok/skills.`).option(`--on`,`Make this project OK-managed: import existing editor skills and adopt new ones.`).option(`--off`,`Stop adopting editor skills (non-destructive — existing .ok/skills + symlinks stay).`).option(`--status`,`Print the current setting.`).action(async e=>{let t=U(process.cwd());if([e.on,e.off,e.status].filter(Boolean).length!==1){process.stderr.write(`${R(`Error:`)} pass exactly one of --on, --off, --status.\n`),process.exitCode=1;return}if(e.status){let e=De(t);process.stdout.write(`Skill management for ${B(t)}: ${e?L(`on`):I(`off (default)`)}\n`);return}let n=!!e.on;try{await Pe(t,{manageEditorSkills:n,surface:`cli`})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`${R(`Error:`)} could not write skill-management marker: ${t}\n`),process.exitCode=1;return}process.stdout.write(n?`${L(`OK now manages skills for this project.`)} Existing editor skills are imported into ${B(`.ok/skills`)} on the next ${B(`ok start`)} / project open, and new ones adopted automatically.\n`:`${F(`OK will no longer adopt editor skills here.`)} Existing ${B(`.ok/skills`)} content + symlinks are left intact.\n`)}),e}function Ld(e,t){return{server:Rd(`server`,e),ui:Rd(`ui`,t)}}function Rd(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 zd(e){return`${Bd(e.server)}\n${Bd(e.ui)}`}function Bd(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 Vd(e){let t=e.inspect??(t=>Yt(e.lockDir,t)),n=e.log??(e=>console.log(e)),r=Ld(t(`server`),t(`ui`));return e.json?n(JSON.stringify(r,null,2)):n(zd(r)),r}function Hd(e){return new P(`status`).description(`Show live state of the server + ui lockfiles for this project`).option(`--json`,`Emit structured JSON instead of formatted text`).action(t=>{e(),Vd({lockDir:T(process.cwd()),json:t.json===!0})})}function Ud(e,t,n,r,i){let a=`urn:uuid:${dr()}`;if(e.headersSent||e.writableEnded||e.destroyed){console.error(`[ok ui] emitProblem called after headers sent — suppressed`,{type:n,status:t,instance:a});return}let o={type:n,title:r,status:t,instance:a,...i===void 0?{}:{detail:i}},s=l.safeParse(o);if(!s.success){console.error(`[ok ui] emitProblem produced an invalid ProblemDetails body:`,{issues:s.error.issues,originalStatus:t,body:o}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-store`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:a}));return}e.writeHead(t,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-store`}),e.end(JSON.stringify(o))}const Wd=1e4;function Gd(e,t){let n=e.socket?.remoteAddress;if(n!==void 0&&!C(n))return Ud(t,403,`urn:ok:error:loopback-required`,`Request must originate from a loopback address.`),!0;if(!ae(e.headers.host))return Ud(t,403,`urn:ok:error:host-not-allowed`,`Host header is not in the loopback allowlist.`),!0;let r=e.headers.origin;return r!==void 0&&!Le(r)?(Ud(t,403,`urn:ok:error:invalid-origin`,`Origin header is not in the loopback allowlist.`),!0):!1}const Kd=3e4;function qd(e,t){let n=e.socket?.remoteAddress;if(n!==void 0&&!C(n)||!ae(e.headers.host))return t.destroy(),!0;let r=e.headers.origin;return typeof r==`string`&&!Le(r)?(t.destroy(),!0):!1}function Jd(e,t,n,r,i,a){a.add(t),t.once(`close`,()=>a.delete(t));let o=_r({host:r,port:i,timeout:Wd});a.add(o),o.once(`close`,()=>a.delete(o));let s=!1,c=n=>{if(!s){if(s=!0,n!==void 0){let t=n.err;console.warn(JSON.stringify({event:n.event,upstreamHost:r,upstreamPort:i,url:e.url,code:t instanceof Error?t.code:void 0,message:t instanceof Error?t.message:void 0}))}try{o.destroy()}catch{}try{t.destroy()}catch{}}};o.once(`connect`,()=>{o.setTimeout(0);let a=[`${e.method??`GET`} ${e.url??`/`} HTTP/1.1`,`host: ${r}:${i}`];for(let[t,n]of Object.entries(e.headers))if(t.toLowerCase()!==`host`&&n!==void 0)if(Array.isArray(n))for(let e of n)a.push(`${t}: ${e}`);else a.push(`${t}: ${n}`);try{o.write(`${a.join(`\r
87
- `)}\r\n\r\n`),n.length>0&&o.write(n)}catch(e){c({event:`proxy-upgrade-handshake-write-failed`,err:e});return}o.on(`data`,e=>{t.writable&&t.write(e)}),t.on(`data`,e=>{o.writable&&o.write(e)})}),o.once(`timeout`,()=>{c({event:`proxy-upgrade-upstream-connect-timeout`})}),o.on(`error`,e=>c({event:`proxy-upgrade-upstream-error`,err:e})),t.on(`error`,e=>c({event:`proxy-upgrade-client-error`,err:e})),o.once(`close`,()=>c()),t.once(`close`,()=>c())}const Yd=[`connection`,`keep-alive`,`proxy-authenticate`,`proxy-authorization`,`te`,`trailer`,`transfer-encoding`,`upgrade`,`cookie`,`set-cookie`];async function Xd(e){let t=e.upstreamTimeoutMs??Wd,n=new Set,r=mr((n,r)=>{Gd(n,r)||Qd(n,r,e.upstreamHost,e.upstreamPort,t)});r.on(`upgrade`,(t,r,i)=>{qd(t,r)||Jd(t,r,i,e.upstreamHost,e.upstreamPort,n)}),await new Promise((t,n)=>{let i=e=>n(e);r.once(`error`,i),r.listen(e.listenPort,e.host,()=>{r.off(`error`,i),t()})});let i=r.address();return{httpServer:r,port:typeof i==`object`&&i?i.port:e.listenPort,close:()=>new Promise(e=>{for(let e of n)try{e.destroy()}catch{}n.clear(),r.close(()=>e()),r.closeIdleConnections()})}}function Zd(e,t,n){Qd(e,t,n.upstreamHost,n.upstreamPort,n.upstreamTimeoutMs??Wd)}function Qd(e,t,n,r,i){let a={...e.headers};delete a.host;for(let e of Yd)delete a[e];e.setTimeout(Kd,()=>{if(t.headersSent)try{t.end()}catch{}else try{Ud(t,408,`urn:ok:error:request-timeout`,`Proxy request exceeded the per-request deadline.`,`Slow-loris-class: client did not finish within ${Kd/1e3}s.`)}catch{}try{e.socket?.destroy()}catch{}});let o=hr({host:n,port:r,method:e.method,path:e.url,headers:{...a,host:`${n}:${r}`}},e=>{let n={...e.headers};for(let e of Yd)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)Ud(t,504,`urn:ok:error:gateway-timeout`,`Upstream did not respond before the gateway deadline.`,`Upstream timeout: ${i/1e3}s elapsed without a response.`);else try{t.end()}catch{}o.destroy()}),o.on(`error`,()=>{if(!t.headersSent)Ud(t,502,`urn:ok:error:collab-server-not-running`,`Collab server is unreachable.`,`Upstream connection failed or dropped before a response was received.`);else try{t.end()}catch{}}),e.on(`error`,()=>{o.destroy()}),e.pipe(o)}const $d=39847;async function ef(e){await Promise.all(e.map(e=>new Promise(t=>{e.close(()=>t())})))}async function tf(e){let{existsSync:n}=await import(`node:fs`),{createServer:r}=await import(`node:http`),{resolve:i}=await import(`node:path`),{acquireUiLock:a,createAssetServeMiddleware:o,createContentFilter:s,readServerLock:c,releaseUiLock:l,updateUiLockPort:u}=await import(`./src-DQTDRmqk.mjs`),{default:d}=await import(`./build-L3kflBeC.mjs`),{resolveContentDir:p,resolveLockDir:m}=await import(`./src-DQTDRmqk.mjs`),h=p(e.config,e.cwd),g=m(e.cwd);a(g,{port:0,worktreeRoot:e.cwd});let _=import.meta.dirname??new URL(`.`,import.meta.url).pathname,v=[i(_,`public`),i(_,`../../app/dist`),i(_,`../../../app/dist`)],y=e.assetDir??v.find(e=>n(e)),b=y?d(y,{single:!0,gzip:!0,etag:!0,dev:!0,extensions:[]}):null,x=n(h)?o({contentFilter:s({projectDir:e.cwd,contentDir:h}),contentSirv:d(h,{dotfiles:!1,dev:!0,extensions:[]}),inlineExtensions:ut,assetExtensions:ct,blocklistExtensions:ot}):null,S=e.port,ee=null,C=(e,t)=>{let n=e.url?.split(`?`)[0];if((n===`/`||n===``)&&(e.url=`/index.html`),!(n?.startsWith(`/api/`)&&Gd(e,t))){if(n===`/api/config`&&(e.method===`GET`||e.method===`HEAD`)){ee?.();let n=c(g),r=e.headers.host??`localhost:${S}`,i=n&&n.port>0?`ws://${r}/collab`:null,a=JSON.stringify({collabUrl:i,previewUrl:null,port:S});t.setHeader(`Content-Type`,`application/json`),t.setHeader(`Cache-Control`,`no-store`),t.setHeader(`X-Content-Type-Options`,`nosniff`),t.statusCode=200,e.method===`HEAD`?t.end():t.end(a);return}if(n?.startsWith(`/api/`)){ee?.();let r=c(g);if(!r||r.port<=0){Ud(t,503,`urn:ok:error:collab-server-not-running`,"Collab server not running. Start `ok start` or run `ok status`.",`Path: ${n}`);return}Zd(e,t,{upstreamHost:f,upstreamPort:r.port});return}if(b&&n?.startsWith(`/assets/`)){b(e,t,()=>{x?x(e,t,()=>nf(t)):nf(t)});return}if(x){x(e,t,()=>{b?b(e,t):nf(t)});return}if(b){b(e,t);return}nf(t)}},w=new Set,te=(e,t,n)=>{if(qd(e,t))return;let r=e.url?.split(`?`)[0]??``;if(r!==`/collab`&&!r.startsWith(`/collab/`)){t.destroy();return}let i=c(g);if(!i||i.port<=0){console.warn(JSON.stringify({event:`ok-ui-upgrade-no-collab-lock`,url:r,reason:"server.lock missing or port unbound — is `ok start` running?"})),t.destroy();return}Jd(e,t,n,f,i.port,w)},T=()=>{for(let e of w)try{e.destroy()}catch{}w.clear()},ne=e.host===void 0?[`::1`,`127.0.0.1`]:[e.host],E=[],D=e.port,re=e=>e instanceof Error&&e.code===`EADDRINUSE`,ie=async()=>{await Promise.all(E.splice(0).map(e=>new Promise(t=>{try{e.close(()=>t())}catch{t()}})))},ae=async e=>{D=e;for(let e of ne){let t=r(C);t.on(`upgrade`,te),E.push(t),await new Promise((n,r)=>{let i=e=>r(e);t.once(`error`,i),t.listen(D,e,()=>{t.off(`error`,i);let e=t.address();typeof e==`object`&&e&&(D=e.port),n()})})}};try{try{await ae(e.port)}catch(t){if(e.fallbackToKernel===!0&&re(t))await ie(),await ae(0);else throw t}}catch(e){await ie();try{l(g)}catch{}throw e}let oe=D;S=oe,u(g,oe);let se=e.scheduler??t,ce=e.safetyNetMs??432e5,O=null,k=!1,le=!1,ue=()=>{k||(k=!0,O!==null&&(se.clearTimeout(O),O=null))},de=()=>{if(ue(),!le){le=!0;try{l(g)}catch{}}},fe=()=>{k||ce<=0||(O!==null&&(se.clearTimeout(O),O=null),O=se.setTimeout(()=>{O=null,console.warn(`[ui] safety-net (${ce}ms) reached — shutting down (D-025 backstop)`);try{e.onSafetyNet?.()}catch{}T();for(let e of E)try{e.close()}catch{}de()},ce))},pe=()=>{k||ce<=0||fe()};return ee=pe,fe(),{httpServers:E,port:oe,release:de,detachSafetyNet:ue,nudgeSafetyNet:pe,drainUpgradeSockets:T}}function nf(e){e.headersSent||e.writableEnded||e.destroyed||(e.setHeader(`X-Content-Type-Options`,`nosniff`),e.setHeader(`Cache-Control`,`no-store`),e.statusCode=404,e.end())}function rf(e,t){if(e!==void 0){let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<0||t>65535)throw Error(`Invalid --port value '${e}'`);return{port:t,fallbackToKernel:!1}}if(t!==void 0&&t!==``){let e=Number.parseInt(t,10);if(Number.isNaN(e)||e<0||e>65535)throw Error(`Invalid PORT env value '${t}'`);return{port:e,fallbackToKernel:!1}}return{port:$d,fallbackToKernel:!0}}async function af(e){let t=e.readLock??(async()=>{let{readUiLock:t}=await import(`./src-DQTDRmqk.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 Xd({listenPort:e.requestedPort,host:e.host,upstreamHost:`localhost`,upstreamPort:r}),upstreamPort:r}}function of(e){return new P(`ui`).description(`Serve the OpenKnowledge React editor UI`).option(`-p, --port <port>`,`UI port (default: $PORT env or ${$d}, kernel-allocated fallback if busy)`).option(`-H, --host <host>`,"UI host. Default: two-socket loopback bind (`[::1]` + `127.0.0.1`) so cross-family collisions fail loud. Pass an explicit host (e.g. `127.0.0.1`, `0.0.0.0`) to bind a single socket on that host.").action(async t=>{let{dim:n}=await import(`./colors-MGDi6UGf.mjs`),{UiLockCollisionError:r}=await import(`./src-DQTDRmqk.mjs`),{resolveLockDir:i}=await import(`./src-DQTDRmqk.mjs`),a=e(),o=t.host,s;try{s=rf(t.port,process.env.PORT)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=1;return}let c=s.port;try{let e=await tf({config:a,cwd:process.cwd(),port:c,fallbackToKernel:s.fallbackToKernel,host:o}),t=o===void 0||o===`::`||o===`0.0.0.0`?`localhost`:o;console.log(`${n(`[ui]`)} listening on http://${t}:${e.port}`);let r=!1,i=t=>{if(r)return;r=!0,console.log(n(`\n[ui] Shutting down (${t})`)),e.detachSafetyNet();let i=()=>{try{e.release()}finally{process.exit(process.exitCode??0)}};e.drainUpgradeSockets(),ef(e.httpServers).then(i,i),setTimeout(i,2e3).unref()};process.once(`SIGINT`,()=>i(`SIGINT`)),process.once(`SIGTERM`,()=>i(`SIGTERM`));return}catch(e){if(!(e instanceof r))throw e;let t=i(process.cwd()),a=o??`localhost`,s;try{s=await af({requestedPort:c,host:a,lockDir:t})}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}if(s.mode===`already-running`){if(console.log(`UI already running at http://${a}:${s.port}`),sf(process)){await new Promise(e=>{let t=t=>{console.log(n(`\n[ui-keepalive] Shutting down (${t})`)),e()};process.once(`SIGINT`,()=>t(`SIGINT`)),process.once(`SIGTERM`,()=>t(`SIGTERM`))});return}process.exit(0)}console.log(`UI running at http://${a}:${s.upstreamPort}; acting as HTTP proxy on port ${s.handle.port}`);let l=!1,u=e=>{l||(l=!0,console.log(n(`\n[ui-proxy] Shutting down (${e})`)),s.handle.close().finally(()=>process.exit(process.exitCode??0)),setTimeout(()=>process.exit(process.exitCode??0),2e3).unref())};process.once(`SIGINT`,()=>u(`SIGINT`)),process.once(`SIGTERM`,()=>u(`SIGTERM`))}})}function sf(e){let t=e.stdout.isTTY===!0,n=typeof e.env.PORT==`string`&&e.env.PORT!==``;return!t||n}function cf(e){if(e.yes===!0||e.json===!0)return!1;let t=e.stdinIsTTY??process.stdin.isTTY,n=e.stdoutIsTTY??process.stdout.isTTY;return t===!0&&n===!0}async function lf(e,t){let n=gr({input:e.input,output:e.output});try{return(await n.question(t)).trim()}finally{n.close()}}async function uf(e={}){let t={input:e.input??process.stdin,output:e.output??process.stderr};t.output.write(I(`
87
+ `)}\r\n\r\n`),n.length>0&&o.write(n)}catch(e){c({event:`proxy-upgrade-handshake-write-failed`,err:e});return}o.on(`data`,e=>{t.writable&&t.write(e)}),t.on(`data`,e=>{o.writable&&o.write(e)})}),o.once(`timeout`,()=>{c({event:`proxy-upgrade-upstream-connect-timeout`})}),o.on(`error`,e=>c({event:`proxy-upgrade-upstream-error`,err:e})),t.on(`error`,e=>c({event:`proxy-upgrade-client-error`,err:e})),o.once(`close`,()=>c()),t.once(`close`,()=>c())}const Yd=[`connection`,`keep-alive`,`proxy-authenticate`,`proxy-authorization`,`te`,`trailer`,`transfer-encoding`,`upgrade`,`cookie`,`set-cookie`];async function Xd(e){let t=e.upstreamTimeoutMs??Wd,n=new Set,r=mr((n,r)=>{Gd(n,r)||Qd(n,r,e.upstreamHost,e.upstreamPort,t)});r.on(`upgrade`,(t,r,i)=>{qd(t,r)||Jd(t,r,i,e.upstreamHost,e.upstreamPort,n)}),await new Promise((t,n)=>{let i=e=>n(e);r.once(`error`,i),r.listen(e.listenPort,e.host,()=>{r.off(`error`,i),t()})});let i=r.address();return{httpServer:r,port:typeof i==`object`&&i?i.port:e.listenPort,close:()=>new Promise(e=>{for(let e of n)try{e.destroy()}catch{}n.clear(),r.close(()=>e()),r.closeIdleConnections()})}}function Zd(e,t,n){Qd(e,t,n.upstreamHost,n.upstreamPort,n.upstreamTimeoutMs??Wd)}function Qd(e,t,n,r,i){let a={...e.headers};delete a.host;for(let e of Yd)delete a[e];e.setTimeout(Kd,()=>{if(t.headersSent)try{t.end()}catch{}else try{Ud(t,408,`urn:ok:error:request-timeout`,`Proxy request exceeded the per-request deadline.`,`Slow-loris-class: client did not finish within ${Kd/1e3}s.`)}catch{}try{e.socket?.destroy()}catch{}});let o=hr({host:n,port:r,method:e.method,path:e.url,headers:{...a,host:`${n}:${r}`}},e=>{let n={...e.headers};for(let e of Yd)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)Ud(t,504,`urn:ok:error:gateway-timeout`,`Upstream did not respond before the gateway deadline.`,`Upstream timeout: ${i/1e3}s elapsed without a response.`);else try{t.end()}catch{}o.destroy()}),o.on(`error`,()=>{if(!t.headersSent)Ud(t,502,`urn:ok:error:collab-server-not-running`,`Collab server is unreachable.`,`Upstream connection failed or dropped before a response was received.`);else try{t.end()}catch{}}),e.on(`error`,()=>{o.destroy()}),e.pipe(o)}const $d=39847;async function ef(e){await Promise.all(e.map(e=>new Promise(t=>{e.close(()=>t())})))}async function tf(e){let{existsSync:n}=await import(`node:fs`),{createServer:r}=await import(`node:http`),{resolve:i}=await import(`node:path`),{acquireUiLock:a,createAssetServeMiddleware:o,createContentFilter:s,readServerLock:c,releaseUiLock:l,updateUiLockPort:u}=await import(`./src-CgblAAT9.mjs`),{default:d}=await import(`./build-L3kflBeC.mjs`),{resolveContentDir:p,resolveLockDir:m}=await import(`./src-CgblAAT9.mjs`),h=p(e.config,e.cwd),g=m(e.cwd);a(g,{port:0,worktreeRoot:e.cwd});let _=import.meta.dirname??new URL(`.`,import.meta.url).pathname,v=[i(_,`public`),i(_,`../../app/dist`),i(_,`../../../app/dist`)],y=e.assetDir??v.find(e=>n(e)),b=y?d(y,{single:!0,gzip:!0,etag:!0,dev:!0,extensions:[]}):null,x=n(h)?o({contentFilter:s({projectDir:e.cwd,contentDir:h}),contentSirv:d(h,{dotfiles:!1,dev:!0,extensions:[]}),inlineExtensions:ut,assetExtensions:ct,blocklistExtensions:ot}):null,S=e.port,ee=null,C=(e,t)=>{let n=e.url?.split(`?`)[0];if((n===`/`||n===``)&&(e.url=`/index.html`),!(n?.startsWith(`/api/`)&&Gd(e,t))){if(n===`/api/config`&&(e.method===`GET`||e.method===`HEAD`)){ee?.();let n=c(g),r=e.headers.host??`localhost:${S}`,i=n&&n.port>0?`ws://${r}/collab`:null,a=JSON.stringify({collabUrl:i,previewUrl:null,port:S});t.setHeader(`Content-Type`,`application/json`),t.setHeader(`Cache-Control`,`no-store`),t.setHeader(`X-Content-Type-Options`,`nosniff`),t.statusCode=200,e.method===`HEAD`?t.end():t.end(a);return}if(n?.startsWith(`/api/`)){ee?.();let r=c(g);if(!r||r.port<=0){Ud(t,503,`urn:ok:error:collab-server-not-running`,"Collab server not running. Start `ok start` or run `ok status`.",`Path: ${n}`);return}Zd(e,t,{upstreamHost:f,upstreamPort:r.port});return}if(b&&n?.startsWith(`/assets/`)){b(e,t,()=>{x?x(e,t,()=>nf(t)):nf(t)});return}if(x){x(e,t,()=>{b?b(e,t):nf(t)});return}if(b){b(e,t);return}nf(t)}},w=new Set,te=(e,t,n)=>{if(qd(e,t))return;let r=e.url?.split(`?`)[0]??``;if(r!==`/collab`&&!r.startsWith(`/collab/`)){t.destroy();return}let i=c(g);if(!i||i.port<=0){console.warn(JSON.stringify({event:`ok-ui-upgrade-no-collab-lock`,url:r,reason:"server.lock missing or port unbound — is `ok start` running?"})),t.destroy();return}Jd(e,t,n,f,i.port,w)},T=()=>{for(let e of w)try{e.destroy()}catch{}w.clear()},ne=e.host===void 0?[`::1`,`127.0.0.1`]:[e.host],E=[],D=e.port,re=e=>e instanceof Error&&e.code===`EADDRINUSE`,ie=async()=>{await Promise.all(E.splice(0).map(e=>new Promise(t=>{try{e.close(()=>t())}catch{t()}})))},ae=async e=>{D=e;for(let e of ne){let t=r(C);t.on(`upgrade`,te),E.push(t),await new Promise((n,r)=>{let i=e=>r(e);t.once(`error`,i),t.listen(D,e,()=>{t.off(`error`,i);let e=t.address();typeof e==`object`&&e&&(D=e.port),n()})})}};try{try{await ae(e.port)}catch(t){if(e.fallbackToKernel===!0&&re(t))await ie(),await ae(0);else throw t}}catch(e){await ie();try{l(g)}catch{}throw e}let oe=D;S=oe,u(g,oe);let se=e.scheduler??t,ce=e.safetyNetMs??432e5,O=null,k=!1,le=!1,ue=()=>{k||(k=!0,O!==null&&(se.clearTimeout(O),O=null))},de=()=>{if(ue(),!le){le=!0;try{l(g)}catch{}}},fe=()=>{k||ce<=0||(O!==null&&(se.clearTimeout(O),O=null),O=se.setTimeout(()=>{O=null,console.warn(`[ui] safety-net (${ce}ms) reached — shutting down (D-025 backstop)`);try{e.onSafetyNet?.()}catch{}T();for(let e of E)try{e.close()}catch{}de()},ce))},pe=()=>{k||ce<=0||fe()};return ee=pe,fe(),{httpServers:E,port:oe,release:de,detachSafetyNet:ue,nudgeSafetyNet:pe,drainUpgradeSockets:T}}function nf(e){e.headersSent||e.writableEnded||e.destroyed||(e.setHeader(`X-Content-Type-Options`,`nosniff`),e.setHeader(`Cache-Control`,`no-store`),e.statusCode=404,e.end())}function rf(e,t){if(e!==void 0){let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<0||t>65535)throw Error(`Invalid --port value '${e}'`);return{port:t,fallbackToKernel:!1}}if(t!==void 0&&t!==``){let e=Number.parseInt(t,10);if(Number.isNaN(e)||e<0||e>65535)throw Error(`Invalid PORT env value '${t}'`);return{port:e,fallbackToKernel:!1}}return{port:$d,fallbackToKernel:!0}}async function af(e){let t=e.readLock??(async()=>{let{readUiLock:t}=await import(`./src-CgblAAT9.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 Xd({listenPort:e.requestedPort,host:e.host,upstreamHost:`localhost`,upstreamPort:r}),upstreamPort:r}}function of(e){return new P(`ui`).description(`Serve the OpenKnowledge React editor UI`).option(`-p, --port <port>`,`UI port (default: $PORT env or ${$d}, kernel-allocated fallback if busy)`).option(`-H, --host <host>`,"UI host. Default: two-socket loopback bind (`[::1]` + `127.0.0.1`) so cross-family collisions fail loud. Pass an explicit host (e.g. `127.0.0.1`, `0.0.0.0`) to bind a single socket on that host.").action(async t=>{let{dim:n}=await import(`./colors-MGDi6UGf.mjs`),{UiLockCollisionError:r}=await import(`./src-CgblAAT9.mjs`),{resolveLockDir:i}=await import(`./src-CgblAAT9.mjs`),a=e(),o=t.host,s;try{s=rf(t.port,process.env.PORT)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=1;return}let c=s.port;try{let e=await tf({config:a,cwd:process.cwd(),port:c,fallbackToKernel:s.fallbackToKernel,host:o}),t=o===void 0||o===`::`||o===`0.0.0.0`?`localhost`:o;console.log(`${n(`[ui]`)} listening on http://${t}:${e.port}`);let r=!1,i=t=>{if(r)return;r=!0,console.log(n(`\n[ui] Shutting down (${t})`)),e.detachSafetyNet();let i=()=>{try{e.release()}finally{process.exit(process.exitCode??0)}};e.drainUpgradeSockets(),ef(e.httpServers).then(i,i),setTimeout(i,2e3).unref()};process.once(`SIGINT`,()=>i(`SIGINT`)),process.once(`SIGTERM`,()=>i(`SIGTERM`));return}catch(e){if(!(e instanceof r))throw e;let t=i(process.cwd()),a=o??`localhost`,s;try{s=await af({requestedPort:c,host:a,lockDir:t})}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}if(s.mode===`already-running`){if(console.log(`UI already running at http://${a}:${s.port}`),sf(process)){await new Promise(e=>{let t=t=>{console.log(n(`\n[ui-keepalive] Shutting down (${t})`)),e()};process.once(`SIGINT`,()=>t(`SIGINT`)),process.once(`SIGTERM`,()=>t(`SIGTERM`))});return}process.exit(0)}console.log(`UI running at http://${a}:${s.upstreamPort}; acting as HTTP proxy on port ${s.handle.port}`);let l=!1,u=e=>{l||(l=!0,console.log(n(`\n[ui-proxy] Shutting down (${e})`)),s.handle.close().finally(()=>process.exit(process.exitCode??0)),setTimeout(()=>process.exit(process.exitCode??0),2e3).unref())};process.once(`SIGINT`,()=>u(`SIGINT`)),process.once(`SIGTERM`,()=>u(`SIGTERM`))}})}function sf(e){let t=e.stdout.isTTY===!0,n=typeof e.env.PORT==`string`&&e.env.PORT!==``;return!t||n}function cf(e){if(e.yes===!0||e.json===!0)return!1;let t=e.stdinIsTTY??process.stdin.isTTY,n=e.stdoutIsTTY??process.stdout.isTTY;return t===!0&&n===!0}async function lf(e,t){let n=gr({input:e.input,output:e.output});try{return(await n.question(t)).trim()}finally{n.close()}}async function uf(e={}){let t={input:e.input??process.stdin,output:e.output??process.stderr};t.output.write(I(`
88
88
  What you share is sent to the OpenKnowledge team.
89
89
  `));let n=await sn({message:`Before you go, mind sharing why? (optional)`,default:null,pageSize:h.length+1,choices:[...h.map(e=>({name:e.label,value:e.value})),{name:`Skip, I'd rather not say`,value:null}]},t);if(n===null)return{};let r=await lf(t,I(`Anything else we should know? (optional) `)),i=await lf(t,I(`Email, if we may follow up (optional) `));return{reason:n,note:r||void 0,email:i||void 0}}async function df(e){if(!cf(e))return`not-prompted`;let t;try{t=await(e.collect??(()=>uf(e)))()}catch{return`failed`}return p(t)?((e.output??process.stderr).write(`\n${B(`Thank you. We read every response.`)}\n\n`),(await(e.submit??v)({...t,source:`cli_uninstall`,appVersion:e.appVersion,platform:e.platform})).ok?`submitted`:`undelivered`):`skipped`}function ff(e,t,n=pf,r=W){let i=[];for(let t of[`/Applications/OpenKnowledge.app`,V(e,`Applications`,`OpenKnowledge.app`)])r(t)&&i.push({method:`app`,label:`OK Desktop (${t})`,instruction:`Move ${t} to the Trash (or: rm -rf "${t}")`});return n([`ls`,`-g`,`--depth=0`,`@inkeep/open-knowledge`])?.includes(`@inkeep/open-knowledge@`)&&i.push({method:`npm-global`,label:`npm global install`,instruction:`npm uninstall -g @inkeep/open-knowledge`}),t&&/[/\\]_npx[/\\]/.test(t)&&i.push({method:`npx`,label:`npx (ephemeral)`,instruction:`Nothing to uninstall — npx runs from a temporary cache. (Optional: npm cache clean --force)`}),i}function pf(e){try{return Ln(`npm`,e,A({encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}))}catch{return null}}const mf=`━`.repeat(64);function hf(e){let t=[z(mf),B(` One more step — remove the OpenKnowledge app itself`),I(` (OpenKnowledge can't delete its own running binary — do this by hand.)`),``];if(e.length===0)t.push(I(` Install method not detected. If you installed it, remove it via:`)),t.push(` ${F(`OK Desktop`)} — move /Applications/OpenKnowledge.app to the Trash`),t.push(` ${F(`npm global`)} — npm uninstall -g @inkeep/open-knowledge`),t.push(` ${F(`npx`)} — nothing to remove (runs from a temporary cache)`);else for(let n of e)t.push(` ${F(n.label)}`),t.push(` ${n.instruction}`);return t.push(z(mf)),t.join(`
90
90
  `)}function gf(e){return U(e,`..`,`..`)}function _f(e){return W(V(e,`.ok`))}async function vf(e){let t=e.findRoot??Ne,n=e.readRecents??uo,r=t(e.cwd)?.rootPath??null,i=co({home:e.home,platformName:e.platform,env:e.env}),a=new Set;for(let e of n(i))a.add(U(e.path));let o=new Set(e.lockDirs.map(gf));for(let e of o)a.add(e);r&&a.delete(r);let s=[];r&&_f(r)&&s.push({path:r,running:o.has(r),current:!0});for(let e of a)_f(e)&&s.push({path:e,running:o.has(e),current:!1});return s.length===0?[]:e.allProjects?s.map(e=>e.path):e.yes||e.dryRun||!(e.isTTY??process.stdout.isTTY)?[]:(e.promptFn??yf)(s)}async function yf(e){return xn({message:`Also remove OpenKnowledge from these projects? (space to toggle; none selected by default)
@@ -0,0 +1,2 @@
1
+ import"./src-IQdx1yfl.mjs";var e=`0.40.0-beta.2`;const t=`config.yml`,n=e;export{n,t};
2
+ //# sourceMappingURL=constants-BJzJKgN0.mjs.map
package/dist/index.d.mts CHANGED
@@ -2355,8 +2355,8 @@ declare const ConfigSchema: ZodObject<{
2355
2355
  }, $loose>>;
2356
2356
  validation: ZodDefault<ZodObject<{
2357
2357
  links: ZodDefault<ZodEnum<{
2358
- error: "error";
2359
2358
  off: "off";
2359
+ error: "error";
2360
2360
  warning: "warning";
2361
2361
  }>>;
2362
2362
  fileTreeIndicators: ZodDefault<ZodBoolean>;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{_ as e,a as t,c as n,g as r,i,l as a,m as o,o as s,r as c,s as l,t as u,u as d}from"./write-project-skill-SrjlunKm.mjs";import{C as f,_ as p,b as m,c as h,f as g,g as _,h as v,i as y,l as b,n as x,r as S,s as C,t as w,u as T,v as E,w as D}from"./src-VT3q7v5V.mjs";import{a as O,i as k,n as A,t as j}from"./acp-harness-probe-CI5eMrtp.mjs";import{A as M,F as N,I as P,M as F,N as I,O as L,P as R,d as z,j as B,k as V,n as H,o as U,s as W,v as G,x as K,y as q}from"./init-DqAj6DLP.mjs";import{n as J}from"./loader-CuzKavqN.mjs";import{n as Y}from"./preview-DNAkJMSB.mjs";import{n as X,t as Z}from"./mcp-migrate-event-CWx0WLdE.mjs";export{l as ALL_EDITOR_IDS,n as EDITOR_LABELS,a as EDITOR_TARGETS,d as HOSTS_WITH_USER_SKILL_DIR,H as LAUNCH_CONFIG_NAME,h as PATH_SHIM_BEGIN,b as PATH_SHIM_BLOCK_RE,T as PATH_SHIM_END,L as addOkPathsToGitExclude,u as assertProjectPathSafe,o as buildManagedServerEntry,S as buildMcpConfigDeclineEvent,Z as buildMcpConfigMigrateEvent,U as classifyExistingMcpEntry,m as collectReportBundle,k as createTokenStore,f as defaultBugReportZipPath,A as detectGh,W as detectInstalledEditors,V as formatTrackedRemediation,M as getExcludedOkPaths,B as getOkArtifactPaths,r as isEntryUpToDate,e as isOwnManagedEntry,J as loadConfig,O as makeLazyProbeTokenStore,v as parseGitHubBlobUrl,_ as parseGitHubShareUrl,p as parseGitHubTreeUrl,E as parseGitUrl,g as pathInstallMarkerPath,Y as previewContent,j as probeOwnManagedEditorMcpEntry,F as probeTrackedOkPaths,z as readExistingMcpEntry,I as readSharingMode,R as readSkillsShared,D as redactContent,N as removeOkPathsFromGitExclude,C as removeOwnMcpEntry,c as removeProjectSkill,t as removeUserGlobalSkillBundle,K as resolveProjectRoot,y as runStop,P as setSkillsShared,X as truncatePriorEntry,s as userGlobalSkillBundleTargets,x as validateLocalFolderForShare,G as writeEditorMcpConfig,w as writeProjectAiIntegrations,i as writeProjectSkill,q as writeUserMcpConfigs};
1
+ import{_ as e,a as t,c as n,g as r,i,l as a,m as o,o as s,r as c,s as l,t as u,u as d}from"./write-project-skill-Cm0CAVv2.mjs";import{C as f,_ as p,b as m,c as h,f as g,g as _,h as v,i as y,l as b,n as x,r as S,s as C,t as w,u as T,v as E,w as D}from"./src-Dj-HA_-C.mjs";import{a as O,i as k,n as A,t as j}from"./acp-harness-probe-DR1ZKGnH.mjs";import{A as M,F as N,I as P,M as F,N as I,O as L,P as R,d as z,j as B,k as V,n as H,o as U,s as W,v as G,x as K,y as q}from"./init-CRqHukN0.mjs";import{n as J}from"./loader-B2FwNLO-.mjs";import{n as Y}from"./preview-2zt9BjS6.mjs";import{n as X,t as Z}from"./mcp-migrate-event-CWx0WLdE.mjs";export{l as ALL_EDITOR_IDS,n as EDITOR_LABELS,a as EDITOR_TARGETS,d as HOSTS_WITH_USER_SKILL_DIR,H as LAUNCH_CONFIG_NAME,h as PATH_SHIM_BEGIN,b as PATH_SHIM_BLOCK_RE,T as PATH_SHIM_END,L as addOkPathsToGitExclude,u as assertProjectPathSafe,o as buildManagedServerEntry,S as buildMcpConfigDeclineEvent,Z as buildMcpConfigMigrateEvent,U as classifyExistingMcpEntry,m as collectReportBundle,k as createTokenStore,f as defaultBugReportZipPath,A as detectGh,W as detectInstalledEditors,V as formatTrackedRemediation,M as getExcludedOkPaths,B as getOkArtifactPaths,r as isEntryUpToDate,e as isOwnManagedEntry,J as loadConfig,O as makeLazyProbeTokenStore,v as parseGitHubBlobUrl,_ as parseGitHubShareUrl,p as parseGitHubTreeUrl,E as parseGitUrl,g as pathInstallMarkerPath,Y as previewContent,j as probeOwnManagedEditorMcpEntry,F as probeTrackedOkPaths,z as readExistingMcpEntry,I as readSharingMode,R as readSkillsShared,D as redactContent,N as removeOkPathsFromGitExclude,C as removeOwnMcpEntry,c as removeProjectSkill,t as removeUserGlobalSkillBundle,K as resolveProjectRoot,y as runStop,P as setSkillsShared,X as truncatePriorEntry,s as userGlobalSkillBundleTargets,x as validateLocalFolderForShare,G as writeEditorMcpConfig,w as writeProjectAiIntegrations,i as writeProjectSkill,q as writeUserMcpConfigs};
@@ -0,0 +1 @@
1
+ import{g as e}from"./init-CRqHukN0.mjs";export{e as runInit};