@inkeep/open-knowledge 0.51.0-beta.0 → 0.51.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/{acp-harness-probe-BzTMCs3I.mjs → acp-harness-probe-5Bd7W9lp.mjs} +2 -2
  2. package/dist/cli.mjs +6 -6
  3. package/dist/constants-QeQKosNT.mjs +2 -0
  4. package/dist/index.d.mts +17 -17
  5. package/dist/index.mjs +1 -1
  6. package/dist/{init-BY2_9jaf.mjs → init-DGihqAzs.mjs} +3 -3
  7. package/dist/init-DpRNnzFn.mjs +1 -0
  8. package/dist/{launch-json-removal-DJZIawj4.mjs → launch-json-removal-BVPFVWm2.mjs} +2 -2
  9. package/dist/loader-BAOw2Vq0.mjs +1 -0
  10. package/dist/{loader-DEyEB0pl.mjs → loader-B_nowTX3.mjs} +2 -2
  11. package/dist/{preview-COKlGckl.mjs → preview-B88pOGOc.mjs} +2 -2
  12. package/dist/preview-CJAgM4pS.mjs +1 -0
  13. package/dist/public/assets/FeedbackForm-jU5fMAff.js +1 -0
  14. package/dist/public/assets/{globals-Bq7QmnDv.css → globals-Ba8eSnNC.css} +1 -1
  15. package/dist/public/assets/{index-CEkDqwbq.js → index-DbydDmJw.js} +2 -2
  16. package/dist/public/assets/{uninstall-Bh5dzTYb.js → uninstall-e3XxU518.js} +1 -1
  17. package/dist/public/index.html +3 -3
  18. package/dist/public/uninstall.html +3 -3
  19. package/dist/{repair-launch-json-fD5l_Dkv.mjs → repair-launch-json-DXPSD0ub.mjs} +2 -2
  20. package/dist/{repair-mcp-configs-DqrMkSEg.mjs → repair-mcp-configs-Do4zIXkE.mjs} +2 -2
  21. package/dist/{src-CyXVAtz1.mjs → src-BabT8t0g.mjs} +2 -2
  22. package/dist/src-CMD64NyP.mjs +1 -0
  23. package/dist/start-C2dEkRx7.mjs +1 -0
  24. package/dist/{start-CcF7z41U.mjs → start-hkzQEInB.mjs} +2 -2
  25. package/package.json +5 -5
  26. package/dist/constants-CFMkNBqi.mjs +0 -2
  27. package/dist/init-BV5qgdEO.mjs +0 -1
  28. package/dist/loader-BcOjgjSS.mjs +0 -1
  29. package/dist/preview-CpGDxOmo.mjs +0 -1
  30. package/dist/public/assets/FeedbackForm-CHJMhyv8.js +0 -1
  31. package/dist/src-BhdDn5db.mjs +0 -1
  32. package/dist/start-BiJWiuVi.mjs +0 -1
  33. /package/dist/public/assets/{globals-B8Za6o5Q.js → globals-BSqcs0wt.js} +0 -0
@@ -1,3 +1,3 @@
1
- import{ft as e}from"./sleep-ChZE9826.mjs";import{ei as t}from"./src-CwuSSZyu.mjs";import{d as n}from"./init-BY2_9jaf.mjs";import{f as r,h as i,o as a}from"./write-project-skill-DHsuRyv9.mjs";import{execFileSync as o,spawn as s}from"node:child_process";import{dirname as c,join as l,win32 as u}from"node:path";import{existsSync as d,mkdirSync as f,readFileSync as p,statSync as m,writeFileSync as h}from"node:fs";import{homedir as g}from"node:os";var _=e();const v=`open-knowledge`;function y(e){try{e()}catch{}}var b=class{backend=`keyring`;constructor(e){this.onKeychainRead=e}async get(e){let{Entry:t}=await import(`@napi-rs/keyring`),n;try{n=new t(v,e).getPassword()}catch(t){return y(()=>this.onKeychainRead?.({kind:`read-error`,host:e,error:t instanceof Error?t.name:`unknown`})),null}if(n==null)return y(()=>this.onKeychainRead?.({kind:`absent`,host:e})),null;try{return JSON.parse(n)}catch{return y(()=>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(v,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(v,e).deletePassword()}catch{}}},x=class{backend=`file`;authFile;constructor(e){this.authFile=e??l(g(),`.ok`,`auth.yml`)}read(){if(!d(this.authFile))return{};try{return(0,_.parse)(p(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=c(this.authFile);d(t)||f(t,{recursive:!0,mode:448}),h(this.authFile,(0,_.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)}},S=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 C(e,t){try{let{Entry:n}=await import(`@napi-rs/keyring`);return new n(v,`__probe__`),process.stderr.write(`[auth] token storage: OS keychain
1
+ import{ft as e}from"./sleep-ChZE9826.mjs";import{ei as t}from"./src-CwuSSZyu.mjs";import{d as n}from"./init-DGihqAzs.mjs";import{f as r,h as i,o as a}from"./write-project-skill-DHsuRyv9.mjs";import{execFileSync as o,spawn as s}from"node:child_process";import{dirname as c,join as l,win32 as u}from"node:path";import{existsSync as d,mkdirSync as f,readFileSync as p,statSync as m,writeFileSync as h}from"node:fs";import{homedir as g}from"node:os";var _=e();const v=`open-knowledge`;function y(e){try{e()}catch{}}var b=class{backend=`keyring`;constructor(e){this.onKeychainRead=e}async get(e){let{Entry:t}=await import(`@napi-rs/keyring`),n;try{n=new t(v,e).getPassword()}catch(t){return y(()=>this.onKeychainRead?.({kind:`read-error`,host:e,error:t instanceof Error?t.name:`unknown`})),null}if(n==null)return y(()=>this.onKeychainRead?.({kind:`absent`,host:e})),null;try{return JSON.parse(n)}catch{return y(()=>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(v,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(v,e).deletePassword()}catch{}}},x=class{backend=`file`;authFile;constructor(e){this.authFile=e??l(g(),`.ok`,`auth.yml`)}read(){if(!d(this.authFile))return{};try{return(0,_.parse)(p(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=c(this.authFile);d(t)||f(t,{recursive:!0,mode:448}),h(this.authFile,(0,_.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)}},S=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 C(e,t){try{let{Entry:n}=await import(`@napi-rs/keyring`);return new n(v,`__probe__`),process.stderr.write(`[auth] token storage: OS keychain
2
2
  `),y(()=>t?.onBackendSelected?.({backend:`keyring`})),new S(new b(t?.onKeychainRead),new x(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`),y(()=>t?.onBackendSelected?.({backend:`file`,reason:r})),new x(e)}}function w(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 x(e))},n)});try{return await Promise.race([C(e),r])}catch{return new x(e)}finally{t!==null&&clearTimeout(t)}})(),t}}function T(e){let t=w(e);return{async get(e){let n=await(await t()).get(e);return n===null?null:{token:n.token}}}}function E(e){let t=w(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 D(e,t){let n=[],r=new x(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(v,`__probe__`);let r,a=await new b(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(v,e).deletePassword(),n.push(`keychain`)}catch(e){i=e instanceof Error?e.name:`delete-error`}}catch{}return{touched:n,keychainError:i}}const O=[`/opt/homebrew/bin/gh`,`/usr/local/bin/gh`,`/opt/local/bin/gh`,`/snap/bin/gh`,`/usr/bin/gh`],k={encoding:`utf-8`,stdio:[`ignore`,`pipe`,`pipe`],timeout:5e3,windowsHide:!0};function A(e,t={}){let n=t._exec??o,r=t._fileExists??d,i=[`auth`,`token`,...e?[`--hostname`,e]:[]],a=[`gh`,...O.filter(r)];for(let e of a)try{let t=n(e,i,k).toString().trim();if(t.length>0)return{available:!0,token:t}}catch{}return{available:!1}}function j(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function M(e,n,r={}){let i=(r.spawn??s)(e,[...n],t({detached:!0,stdio:`ignore`,env:j(r.env??process.env)}));return i.unref(),i}const N=`com.inkeep.open-knowledge`,P=`OpenKnowledge.app`,F=`/Applications/${P}`;function I(){return{platform:process.platform,env:process.env,execPath:process.execPath,isTTY:process.stdout.isTTY,statSync:e=>{try{return m(e,{throwIfNoEntry:!1})??null}catch{return null}}}}function L(e){if(e.env.ELECTRON_RUN_AS_NODE===`1`){let t=/(.+?\.app)\/Contents\/MacOS\//.exec(e.execPath);if(t?.[1])return t[1]}if(R(e,F))return F;let t=l(e.homeDir??g(),`Applications`,P);return R(e,t)?t:null}function R(e,t){return z(e,l(t,`Contents`,`MacOS`,`OpenKnowledge`))}function z(e,t){try{let n=e.statSync(t);return n&&typeof n.isFile==`function`?n.isFile():!1}catch{return!1}}const B=[`@inkeepopen-knowledge-desktop`,`OpenKnowledge`];function V(e){if(e.env.ELECTRON_RUN_AS_NODE===`1`&&/\\OpenKnowledge\.exe$/i.test(e.execPath))return e.execPath;let t=e.env.LOCALAPPDATA;if(t)for(let n of B){let r=u.join(t,`Programs`,n,`OpenKnowledge.exe`);if(z(e,r))return r}return null}function H(e){if(e.env.ELECTRON_RUN_AS_NODE===`1`&&e.execPath.endsWith(`/openknowledge`))return e.execPath;let t=`/opt/OpenKnowledge/openknowledge`;return z(e,t)?t:null}function U(e){if(e.env.OK_FORCE_BROWSER===`1`)return{available:!1,reason:`force-browser`};if(e.platform!==`darwin`&&e.platform!==`win32`&&e.platform!==`linux`)return{available:!1,reason:`unsupported-platform`};let t;try{t=e.platform===`darwin`?L(e):e.platform===`win32`?V(e):H(e)}catch{return{available:!1,reason:`stat-error`}}return t?e.env.OK_FORCE_DESKTOP===`1`?{available:!0,reason:`available`,bundlePath:t}:!(e.isTTY===!0||e.platform===`win32`&&e.isTTY===void 0&&!e.env.CI)||e.env.SSH_CONNECTION||e.env.SSH_TTY||e.platform===`linux`&&!e.env.DISPLAY&&!e.env.WAYLAND_DISPLAY?{available:!1,reason:`headless`,bundlePath:t}:{available:!0,reason:`available`,bundlePath:t}:{available:!1,reason:`no-bundle`}}function W(e,t){let n=e.log??(e=>console.error(e)),r=e.platform??process.platform;if(n("Launching OpenKnowledge desktop (use `ok start` for the browser server, or `OK_FORCE_BROWSER=1` to always skip)"),r===`darwin`){M(`open`,[`-b`,N],{spawn:e.spawn});return}let i=t?.bundlePath;if(!i){n(`Desktop launch skipped: no resolved desktop executable (caller bug).`);return}M(i,[],{spawn:e.spawn})}function G(e=`no-bundle`){switch(e){case`no-bundle`:return`Desktop app not found (checked the standard install locations for this OS). Install it, or omit --mode for browser mode.`;case`darwin-only`:case`unsupported-platform`:return`Desktop app is not available on this platform. Use --mode=browser, or omit --mode for the server fallback.`;case`headless`:return`Desktop launch is gated in headless contexts (CI, SSH, non-TTY stdout). Set OK_FORCE_DESKTOP=1 to override, or use --mode=browser.`;case`force-browser`:return`OK_FORCE_BROWSER=1 is set — desktop dispatch is disabled. Unset it to use --mode=app.`;case`stat-error`:return`Failed to inspect the desktop install (filesystem error). Check permissions or use --mode=browser.`;case`available`:return`Desktop app appears available but launch dispatch did not fire (caller bug).`}}function K(e,t,o){let s=a[e],c=e===`opencode`?i:r,l=[],u=s.projectConfigPath?.(t);u!==void 0&&l.push({scope:`project`,configPath:u});try{l.push({scope:`user`,configPath:s.configPath(t,o)})}catch{}for(let r of l){let i=n(s,t,o,r.configPath);if(i!==null&&c(i))return{editorId:e,scope:r.scope,configPath:r.configPath}}return null}export{W as a,A as c,T as d,E as f,U as i,D as l,N as n,G as o,I as r,M as s,K as t,C as u};
3
- //# sourceMappingURL=acp-harness-probe-BzTMCs3I.mjs.map
3
+ //# sourceMappingURL=acp-harness-probe-5Bd7W9lp.mjs.map
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{At as t,E as n,Ft as r,Ht as i,N as a,Ot as o,Rt as s,St as c,T as l,a as u,bt as d,c as f,ft as p,gt as m,jt as h,kt as g,m as _,tn as v,xt as y}from"./sleep-ChZE9826.mjs";import{Ao as b,C as x,Da as S,Ho as ee,It as C,Jo as te,Lt as ne,Oa as re,Q as ie,Ro as ae,Wo as oe,Ws as se,_s as ce,ca as le,ho as ue,it as de,ka as fe,mo as pe,po as me,rs as he,sa as ge,ss as _e,yo as ve}from"./src-DMpGVIiQ.mjs";import{$ as ye,$t as be,Bt as xe,Ci as w,Da as Se,Ea as Ce,F as we,Ft as Te,I as Ee,J as De,L as Oe,Mi as ke,Mn as Ae,Mr as je,Mt as Me,Nt as Ne,Oa as Pe,P as Fe,Pr as Ie,Pt as Le,Q as Re,Si as ze,Ta as Be,Wr as Ve,X as He,Z as Ue,_ as We,a as Ge,at as Ke,ci as qe,ct as Je,dt as Ye,ei as T,en as Xe,f as Ze,fi as Qe,ft as $e,hn as et,ht as tt,ii as nt,ji as rt,jn as it,jr as at,kr as ot,lt as st,n as ct,nn as lt,or as ut,ot as dt,p as ft,pi as pt,pt as mt,qt as ht,r as gt,rt as _t,si as vt,st as yt,t as bt,ut as xt,w as St,wi as Ct,xi as wt,zt as Tt}from"./src-CwuSSZyu.mjs";import{A as E,F as Et,I as Dt,k as Ot}from"./fs-traced-RPXwxrA5.mjs";import{a as kt}from"./git-handle-KAEFG2Xp.mjs";import{S as At,_ as D,i as jt,u as Mt}from"./server-lock-BV0Ktccm.mjs";import{t as O}from"./esm-DmX1RzAi.mjs";import{_ as Nt,c as Pt,d as Ft,f as It,h as Lt,i as Rt,l as zt,m as Bt,n as Vt,o as Ht,p as Ut,r as Wt,t as Gt,u as Kt,v as qt,y as Jt}from"./src-CyXVAtz1.mjs";import{c as Yt,i as k,n as A,o as j,r as M,s as N,t as P}from"./colors-BsmVIwfM.mjs";import{a as Xt,c as Zt,f as Qt,i as $t,l as en,r as tn,s as nn,u as rn}from"./acp-harness-probe-BzTMCs3I.mjs";import{n as an,r as on,t as sn}from"./dist-bundle-CFfKBclM.mjs";import{A as cn,B as ln,C as un,D as dn,F as fn,I as pn,L as mn,M as hn,N as gn,P as _n,R as vn,S as yn,V as bn,j as xn,k as Sn,u as Cn,w as wn,z as Tn}from"./init-BY2_9jaf.mjs";import{n as En,t as Dn}from"./constants-CFMkNBqi.mjs";import{g as On,i as kn,n as An,o as jn}from"./write-project-skill-DHsuRyv9.mjs";import{n as Mn,t as Nn}from"./loader-DEyEB0pl.mjs";import{D as Pn,M as Fn,S as In}from"./start-CcF7z41U.mjs";import{i as Ln}from"./skill-teardown-BppNXkpR.mjs";import{t as Rn}from"./launch-json-removal-DJZIawj4.mjs";import{n as zn}from"./repair-skills-BFfQjF9F.mjs";import{u as Bn}from"./ui-CNA2d6cp.mjs";import{execFile as Vn,execFileSync as Hn,execSync as Un,spawn as Wn,spawnSync as Gn}from"node:child_process";import{basename as Kn,dirname as F,isAbsolute as qn,join as I,relative as L,resolve as R,sep as Jn}from"node:path";import Yn from"node:process";import{fileURLToPath as Xn}from"node:url";import{accessSync as Zn,appendFileSync as Qn,closeSync as $n,constants as er,existsSync as z,lstatSync as tr,mkdirSync as B,mkdtempSync as nr,openSync as rr,readFileSync as V,readdirSync as ir,realpathSync as ar,renameSync as or,rmSync as sr,statSync as H,unlinkSync as U,writeFileSync as cr}from"node:fs";import{homedir as lr,platform as ur,tmpdir as dr}from"node:os";import{rm as fr}from"node:fs/promises";import{randomUUID as pr}from"node:crypto";import{setTimeout as mr}from"node:timers/promises";import{promisify as hr}from"node:util";import{createInterface as gr}from"node:readline/promises";const _r={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 vr;(function(e){})(vr||={});function yr(e){return i(m,e)}async function br(e){let{projectDir:t,contentDir:n,baseConfig:r,targetPath:i,fix:a=!1}=e,o=[],s=Ve({projectDir:t,contentDir:n}),c=new Set,l=e=>{c.has(e)||(c.add(e),o.push(e))},u=je(t,r,l),d=new Map,f=e=>{let t=F(e),r=d.get(t);if(r)return r;let i=at(u,Ie(n,e,l));return d.set(t,i),i},p=[],m=xr(i,n);m.kind===`file`?p.push(L(n,m.path)):h(m.path);function h(e){let t;try{t=ir(e,{withFileTypes:!0})}catch(t){o.push(`could not read directory ${L(n,e)||`.`}: ${Cr(t)}`);return}for(let r of t){if(r.name.startsWith(`.`))continue;let t=I(e,r.name),i=L(n,t);if(r.isDirectory()){if(s.isDirExcluded(i))continue;h(t)}else if(r.isFile()){if(!Sr(r.name)||s.isExcluded(i))continue;p.push(i)}}}p.sort();let g=[],_=0,v=0,y=0;for(let e of p){let t=I(n,e),r;try{r=V(t,`utf-8`)}catch(t){o.push(`could not read ${e}: ${Cr(t)}`);continue}let i=f(e),s=!1;if(a&&i.enabled){let n=ge(r,i);if(n!==r){let i=`${t}.tmp.${process.pid}.${Date.now()}`;try{cr(i,n,`utf-8`),or(i,t),r=n,s=!0,y++}catch(t){try{U(i)}catch{}o.push(`could not write fix to ${e}: ${Cr(t)}`)}}}let c=await le(r,i,e);for(let e of c)e.severity===`error`?_++:v++;g.push({file:e,diagnostics:c,fixed:s})}return{contentDir:n,files:g,warnings:o,fileCount:p.length,errorCount:_,warningCount:v,fixedCount:y}}function xr(e,t){if(e===void 0||e===``)return{kind:`dir`,path:t};let n=qn(e)?e:R(t,e);try{if(H(n).isFile())return{kind:`file`,path:n}}catch{}return{kind:`dir`,path:n}}function Sr(e){let t=e.toLowerCase();return _e.some(e=>t.endsWith(e))}function Cr(e){return e instanceof Error?e.message:String(e)}function wr(e){return new O(`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=ze(r,i),o=t===void 0?void 0:Tr(t,Nt()),s=r.contentRules,c=await br({projectDir:i,contentDir:a,baseConfig:s?re(s):fe,targetPath:o,fix:n.fix===!0});n.json===!0?process.stdout.write(`${JSON.stringify(c,null,2)}\n`):process.stdout.write(`${Or(c)}\n`),(n.errorsOnly===!0?c.errorCount>0:Er(c))&&(process.exitCode=1)})}function Tr(e,t){return R(t,e)}function Er(e){return e.errorCount>0||e.warningCount>0}function Dr(e){let t=[P(e.file)+(e.fixed?A(` (fixed)`):``)];for(let n of e.diagnostics){let e=A(`${n.range.start.line+1}:${n.range.start.character+1}`.padEnd(7)),r=n.severity===`error`?M(`error `):N(`warning`);t.push(` ${e} ${r} ${n.message} ${A(`${n.source}/${n.code}`)}`)}return t.push(``),t}function Or(e){let t=[];for(let n of e.files)n.diagnostics.length>0&&t.push(...Dr(n));for(let n of e.warnings)t.push(N(`! ${n}`));e.warnings.length>0&&t.push(``);let n=e.errorCount+e.warningCount;if(n===0)t.push(j(`✓ 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(`${M(r[0]??``)} (${r[1]}, ${r[2]}) across ${e.fileCount} file${e.fileCount===1?``:`s`}.`)}return e.fixedCount>0&&t.push(A(`Fixed ${e.fixedCount} file${e.fixedCount===1?``:`s`}.`)),t.join(`
2
+ import{o as e}from"./chunk-DTipWd-i.mjs";import{At as t,E as n,Ft as r,Ht as i,N as a,Ot as o,Rt as s,St as c,T as l,a as u,bt as d,c as f,ft as p,gt as m,jt as h,kt as g,m as _,tn as v,xt as y}from"./sleep-ChZE9826.mjs";import{Ao as b,C as x,Da as S,Ho as ee,It as C,Jo as te,Lt as ne,Oa as re,Q as ie,Ro as ae,Wo as oe,Ws as se,_s as ce,ca as le,ho as ue,it as de,ka as fe,mo as pe,po as me,rs as he,sa as ge,ss as _e,yo as ve}from"./src-DMpGVIiQ.mjs";import{$ as ye,$t as be,Bt as xe,Ci as w,Da as Se,Ea as Ce,F as we,Ft as Te,I as Ee,J as De,L as Oe,Mi as ke,Mn as Ae,Mr as je,Mt as Me,Nt as Ne,Oa as Pe,P as Fe,Pr as Ie,Pt as Le,Q as Re,Si as ze,Ta as Be,Wr as Ve,X as He,Z as Ue,_ as We,a as Ge,at as Ke,ci as qe,ct as Je,dt as Ye,ei as T,en as Xe,f as Ze,fi as Qe,ft as $e,hn as et,ht as tt,ii as nt,ji as rt,jn as it,jr as at,kr as ot,lt as st,n as ct,nn as lt,or as ut,ot as dt,p as ft,pi as pt,pt as mt,qt as ht,r as gt,rt as _t,si as vt,st as yt,t as bt,ut as xt,w as St,wi as Ct,xi as wt,zt as Tt}from"./src-CwuSSZyu.mjs";import{A as E,F as Et,I as Dt,k as Ot}from"./fs-traced-RPXwxrA5.mjs";import{a as kt}from"./git-handle-KAEFG2Xp.mjs";import{S as At,_ as D,i as jt,u as Mt}from"./server-lock-BV0Ktccm.mjs";import{t as O}from"./esm-DmX1RzAi.mjs";import{_ as Nt,c as Pt,d as Ft,f as It,h as Lt,i as Rt,l as zt,m as Bt,n as Vt,o as Ht,p as Ut,r as Wt,t as Gt,u as Kt,v as qt,y as Jt}from"./src-BabT8t0g.mjs";import{c as Yt,i as k,n as A,o as j,r as M,s as N,t as P}from"./colors-BsmVIwfM.mjs";import{a as Xt,c as Zt,f as Qt,i as $t,l as en,r as tn,s as nn,u as rn}from"./acp-harness-probe-5Bd7W9lp.mjs";import{n as an,r as on,t as sn}from"./dist-bundle-CFfKBclM.mjs";import{A as cn,B as ln,C as un,D as dn,F as fn,I as pn,L as mn,M as hn,N as gn,P as _n,R as vn,S as yn,V as bn,j as xn,k as Sn,u as Cn,w as wn,z as Tn}from"./init-DGihqAzs.mjs";import{n as En,t as Dn}from"./constants-QeQKosNT.mjs";import{g as On,i as kn,n as An,o as jn}from"./write-project-skill-DHsuRyv9.mjs";import{n as Mn,t as Nn}from"./loader-B_nowTX3.mjs";import{D as Pn,M as Fn,S as In}from"./start-hkzQEInB.mjs";import{i as Ln}from"./skill-teardown-BppNXkpR.mjs";import{t as Rn}from"./launch-json-removal-BVPFVWm2.mjs";import{n as zn}from"./repair-skills-BFfQjF9F.mjs";import{u as Bn}from"./ui-CNA2d6cp.mjs";import{execFile as Vn,execFileSync as Hn,execSync as Un,spawn as Wn,spawnSync as Gn}from"node:child_process";import{basename as Kn,dirname as F,isAbsolute as qn,join as I,relative as L,resolve as R,sep as Jn}from"node:path";import Yn from"node:process";import{fileURLToPath as Xn}from"node:url";import{accessSync as Zn,appendFileSync as Qn,closeSync as $n,constants as er,existsSync as z,lstatSync as tr,mkdirSync as B,mkdtempSync as nr,openSync as rr,readFileSync as V,readdirSync as ir,realpathSync as ar,renameSync as or,rmSync as sr,statSync as H,unlinkSync as U,writeFileSync as cr}from"node:fs";import{homedir as lr,platform as ur,tmpdir as dr}from"node:os";import{rm as fr}from"node:fs/promises";import{randomUUID as pr}from"node:crypto";import{setTimeout as mr}from"node:timers/promises";import{promisify as hr}from"node:util";import{createInterface as gr}from"node:readline/promises";const _r={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 vr;(function(e){})(vr||={});function yr(e){return i(m,e)}async function br(e){let{projectDir:t,contentDir:n,baseConfig:r,targetPath:i,fix:a=!1}=e,o=[],s=Ve({projectDir:t,contentDir:n}),c=new Set,l=e=>{c.has(e)||(c.add(e),o.push(e))},u=je(t,r,l),d=new Map,f=e=>{let t=F(e),r=d.get(t);if(r)return r;let i=at(u,Ie(n,e,l));return d.set(t,i),i},p=[],m=xr(i,n);m.kind===`file`?p.push(L(n,m.path)):h(m.path);function h(e){let t;try{t=ir(e,{withFileTypes:!0})}catch(t){o.push(`could not read directory ${L(n,e)||`.`}: ${Cr(t)}`);return}for(let r of t){if(r.name.startsWith(`.`))continue;let t=I(e,r.name),i=L(n,t);if(r.isDirectory()){if(s.isDirExcluded(i))continue;h(t)}else if(r.isFile()){if(!Sr(r.name)||s.isExcluded(i))continue;p.push(i)}}}p.sort();let g=[],_=0,v=0,y=0;for(let e of p){let t=I(n,e),r;try{r=V(t,`utf-8`)}catch(t){o.push(`could not read ${e}: ${Cr(t)}`);continue}let i=f(e),s=!1;if(a&&i.enabled){let n=ge(r,i);if(n!==r){let i=`${t}.tmp.${process.pid}.${Date.now()}`;try{cr(i,n,`utf-8`),or(i,t),r=n,s=!0,y++}catch(t){try{U(i)}catch{}o.push(`could not write fix to ${e}: ${Cr(t)}`)}}}let c=await le(r,i,e);for(let e of c)e.severity===`error`?_++:v++;g.push({file:e,diagnostics:c,fixed:s})}return{contentDir:n,files:g,warnings:o,fileCount:p.length,errorCount:_,warningCount:v,fixedCount:y}}function xr(e,t){if(e===void 0||e===``)return{kind:`dir`,path:t};let n=qn(e)?e:R(t,e);try{if(H(n).isFile())return{kind:`file`,path:n}}catch{}return{kind:`dir`,path:n}}function Sr(e){let t=e.toLowerCase();return _e.some(e=>t.endsWith(e))}function Cr(e){return e instanceof Error?e.message:String(e)}function wr(e){return new O(`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=ze(r,i),o=t===void 0?void 0:Tr(t,Nt()),s=r.contentRules,c=await br({projectDir:i,contentDir:a,baseConfig:s?re(s):fe,targetPath:o,fix:n.fix===!0});n.json===!0?process.stdout.write(`${JSON.stringify(c,null,2)}\n`):process.stdout.write(`${Or(c)}\n`),(n.errorsOnly===!0?c.errorCount>0:Er(c))&&(process.exitCode=1)})}function Tr(e,t){return R(t,e)}function Er(e){return e.errorCount>0||e.warningCount>0}function Dr(e){let t=[P(e.file)+(e.fixed?A(` (fixed)`):``)];for(let n of e.diagnostics){let e=A(`${n.range.start.line+1}:${n.range.start.character+1}`.padEnd(7)),r=n.severity===`error`?M(`error `):N(`warning`);t.push(` ${e} ${r} ${n.message} ${A(`${n.source}/${n.code}`)}`)}return t.push(``),t}function Or(e){let t=[];for(let n of e.files)n.diagnostics.length>0&&t.push(...Dr(n));for(let n of e.warnings)t.push(N(`! ${n}`));e.warnings.length>0&&t.push(``);let n=e.errorCount+e.warningCount;if(n===0)t.push(j(`✓ 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(`${M(r[0]??``)} (${r[1]}, ${r[2]}) across ${e.fileCount} file${e.fileCount===1?``:`s`}.`)}return e.fixedCount>0&&t.push(A(`Fixed ${e.fixedCount} file${e.fixedCount===1?``:`s`}.`)),t.join(`
3
3
  `)}const kr={out:e=>process.stdout.write(`${e}\n`),err:e=>process.stderr.write(`${e}\n`)};function Ar(e){return new O(`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 jr(t,n,e(),process.cwd(),Nt());r!==0&&(process.exitCode=r)})}async function jr(e,t,n,r,i,a=kr){let o=ze(n,r),s;if(e!==void 0){let t=Mr(e,i,o);if(t===null)return a.err(`Path is outside the content directory (${o}): ${e}`),1;s=t===``?void 0:t}let c=jt(w(r));if(!c||c.port<=0)return a.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 l=s===void 0?``:`?path=${encodeURIComponent(s)}`,u;try{u=await fetch(`http://127.0.0.1:${c.port}/api/audit${l}`,{headers:se({kind:`cli`,runtimeVersion:D})})}catch(e){return a.err(`Could not reach the OpenKnowledge server on port ${c.port}: ${String(e)}`),1}if(!u.ok){let e=await u.json().catch(()=>({}));return a.err(`Audit failed: ${e.title??e.error??e.message??`server responded with ${u.status}`}`),1}let d=S.safeParse(await u.json().catch(()=>null));if(!d.success){let e=d.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `);return a.err(`Audit failed: unexpected response shape from the server. Schema issues: ${e}`),1}let f=d.data;return t.json===!0?a.out(JSON.stringify(f,null,2)):a.out(Or(Nr(f))),+(t.errorsOnly===!0?f.errorCount>0:f.errorCount+f.warningCount>0)}function Mr(e,t,n){let r=L(n,R(t,e));return r===``?``:r.startsWith(`..`)||qn(r)?null:r.split(Jn).join(`/`)}function Nr(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 Pr(e,t,n,r){let i=Fr(await Ir(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 Fr(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 Ir(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 Lr(e,t){let n=new O(`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 Pr(process.stdin,process.stdout,r,{log:n,getDiag:()=>t});await ft(n),process.exit(i)}catch(e){n?.error({err:e},`[auth] git-credential get: unexpected error`),await ft(n),process.exit(1)}}),n}function Rr(e){let t=e.endpoint.DEFAULTS;return/^https:\/\/(api\.)?github\.com$/.test(t.baseUrl)?`https://github.com`:t.baseUrl.replace(`/api/v3`,``)}async function zr(e,t,n){let r={baseUrl:Rr(e),headers:{accept:`application/json`},...n},i=await e(t,r);if(`error`in i.data){let n=new an(`${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 Br(e){let t=e.request||sn,n={client_id:e.clientId};return`scopes`in e&&Array.isArray(e.scopes)&&(n.scope=e.scopes.join(` `)),zr(t,`POST /login/device/code`,n)}async function Vr(e){let t=await zr(e.request||sn,`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=Hr(e,t.data.expires_in),n.refreshTokenExpiresAt=Hr(e,t.data.refresh_token_expires_in)}delete n.scopes}return{...t,authentication:n}}function Hr(e,t){return new Date(e+t*1e3).toISOString()}async function Ur(e,t){let n=Wr(e,t.auth);if(n)return n;let{data:r}=await Br({clientType:e.clientType,clientId:e.clientId,request:t.request||e.request,scopes:t.auth.scopes||e.scopes});await e.onVerification(r);let i=await Kr(t.request||e.request,e.clientId,e.clientType,r);return e.authentication=i,i}function Wr(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 Gr(e){await new Promise(t=>setTimeout(t,e*1e3))}async function Kr(e,t,n,r){try{let i={clientId:t,request:e,code:r.device_code},{authentication:a}=n===`oauth-app`?await Vr({...i,clientType:`oauth-app`}):await Vr({...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 Gr(r.interval),Kr(e,t,n,r);if(a===`slow_down`)return await Gr(r.interval+7),Kr(e,t,n,r);throw i}}async function qr(e,t){return Ur(e,{auth:t})}async function Jr(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 Ur(e,{request:t,auth:{type:`oauth`}});return i.headers.authorization=`token ${a}`,t(i)}var Yr=`0.0.0-development`;function Xr(e){let t=e.request||sn.defaults({headers:{"user-agent":`octokit-auth-oauth-device.js/${Yr} ${on()}`}}),{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(qr.bind(null,i),{hook:Jr.bind(null,i)})}async function Zr(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=Xr({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 Qr(){return process.env.OPEN_KNOWLEDGE_GITHUB_CLIENT_ID??`Ov23liqlSd0V1MwR6rhI`}function W(e){let t=e.toLowerCase().replace(/:\d+$/,``);te.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 $r(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function ei(e,t,n=Zr){let r=Qr(),{host:i,json:a}=e;W(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?$r(!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?$r(!0,{type:`complete`,host:i,login:s}):process.stderr.write(`✓ Logged in as ${s} on ${i}\n`)}function ti(e){return new O(`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??ot(process.cwd()),r=await e();await ei({...t,host:n},r)})}const ni={style:{maskedText:`[input is masked]`}};var ri=fn((e,t)=>{let{validate:n=()=>!0}=e,r=Tn(ni,e.theme),[i,a]=ln(`idle`),[o,s]=ln(),[c,l]=ln(``),u=vn({status:i,theme:r});mn(async(e,r)=>{if(i===`idle`)if(bn(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)}${pn}`),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 ii(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)=>ii.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 ai(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 oi(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 si=Function.bind,ci=si.bind(si);function li(e,t,n){let r=ci(oi,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]=ci(ai,null).apply(null,i)})}function ui(){let e=Symbol(`Singular`),t={registry:{}},n=ii.bind(null,t,e);return li(n,t,e),n}function di(){let e={registry:{}},t=ii.bind(null,e);return li(t,e),t}var fi={Singular:ui,Collection:di},pi=`0.0.0-development`;function mi(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{At as t,E as n,Ft as r,Ht as i,N
8
8
  `),n.includes(`file`)&&process.stderr.write(` cleared from ~/.ok/auth.yml
9
9
  `)}function sa(){return new O(`signout`).description(`Remove stored credentials`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname (default: workspace origin host)`).action(async e=>{let t=e.host??ot(process.cwd());await oa({...e,host:t})})}async function ca(e,t,n=Zt){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 la(e,t,n){return{type:`status`,host:e,backend:t,...n}}async function ua(e,t){let{host:n,json:r}=e;W(n);let i=t.backend,a=await ca(n,t);a.tier===`none`&&(r?process.stdout.write(`${JSON.stringify(la(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 K({auth:a.token,...o?{baseUrl:o}:{}});try{let{data:e}=await s.users.getAuthenticated();r?process.stdout.write(`${JSON.stringify(la(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=$i(e,n);r?process.stdout.write(`${JSON.stringify(la(n,i,{authenticated:!1,error:t.message}))}\n`):process.stderr.write(`✗ ${t.message}\n`),process.exit(1)}}function da(e){return new O(`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??ot(process.cwd());await ua({...t,host:n},await e())})}function fa(e){let t=new O(`auth`);t.description(`GitHub authentication management`);let n=e=>rn(void 0,e);return t.addCommand(ti(n)),t.addCommand(da(n)),t.addCommand(aa(n)),t.addCommand(sa()),t.addCommand(na(n)),t.addCommand(Lr(n,e)),t}function pa(){return new O(`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 It({level:`standard`,projectDir:process.cwd(),redact:!0,outputPath:Lt(),logger:pf()});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&&ur()===`darwin`)try{nn(`/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 ma(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 ha(e){let t=e.inspect??(t=>Ft(e.lockDir,t)),n=e.unlink??(e=>U(e)),r=e.log??(e=>console.log(e)),i=e.error??(e=>console.error(e)),a=ma(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 ga(e){return new O(`clean`).description(`Prune stale / corrupt open-knowledge lock files (never touches live locks)`).action(()=>{e(),ha({lockDir:w(process.cwd())}).failed.length>0&&(process.exitCode=1)})}function _a(e){return`credential.helper=!${e.map(ve).join(` `)} auth git-credential`}async function va(e,t,n={},r=Zt){let i=[`credential.helper=`,_a(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 ya(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 ba=[[`count`,0,10],[`compress`,10,20],[`receiv`,20,60],[`resolv`,60,100]];function xa(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 ba)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 Sa(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 Ca(e,t=process.env){let n=Sa(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 wa(e=process.argv,t=process.execPath){let n=e[1];return n?[t,n]:[t]}function Ta(e){return typeof e!=`string`||e.length===0?[`--progress`]:[`--progress`,`-b`,e]}const Ea=pe;async function Da(e){try{return await e.clone(Ta(e.branch)),{fellBack:!1}}catch(t){if(e.branch!==null&&Ea(t))return e.onFallback(e.branch),await e.clone(Ta(null)),{fellBack:!0};throw t}}function Oa(e,t){return{baseDir:e,config:t,unsafe:{allowUnsafeCredentialHelper:!0,allowUnsafePager:!0,allowUnsafeSshCommand:!0,allowUnsafeAskPass:!0,allowUnsafeEditor:!0}}}function ka(e,t,n){return e===`https`&&t===`github.com`&&n}function Aa(e,t){let n=`${t.owner}/${t.name}`;return e===n||e===`${n}.git`?`https://${t.hostname}/${n}`:e}async function ja(e,t,n,r=process.cwd()){let i=Kt(e);if(!i)throw Error(`Invalid git URL: ${e}`);let a=Aa(e,i),o=t.dir?R(r,t.dir):R(r,i.name);if(z(o)&&ir(o).length>0)throw Error(`Target directory is not empty: ${o}`);lt();let s=Qt(),c=i.protocol===`https`&&i.hostname===`github.com`?await ya(i.owner,i.name):!1,l=ka(i.protocol,i.hostname,c)?{tier:`none`,gitConfig:[]}:await va(i.hostname,s,{selfCliArgs:wa()}),u=Ca(l),d=kt(Oa(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=xa(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 Da({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-BV5qgdEO.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{Ma(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 Ma(e){let t=dn(e,[`.ok/`]);return t.kind===`no-exclude`?`no-exclude`:t.kind===`refused-tracked`?`already-present`:t.appended.length>0?`appended`:`already-present`}const Na=/^[A-Za-z0-9._/:@-]+$/;function Pa(e){return Na.test(e)?e:ve(e)}function Fa(e,t){let n=typeof t==`string`&&t.length>0?` -b ${Pa(t)}`:``;return`ok clone ${Pa(e)}${n}`}function Ia(e){let t=me(e.error);if(t.kind!==`auth`)return null;if(ue(t)){let t=Fa(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-DpRNnzFn.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{Ma(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 Ma(e){let t=dn(e,[`.ok/`]);return t.kind===`no-exclude`?`no-exclude`:t.kind===`refused-tracked`?`already-present`:t.appended.length>0?`appended`:`already-present`}const Na=/^[A-Za-z0-9._/:@-]+$/;function Pa(e){return Na.test(e)?e:ve(e)}function Fa(e,t){let n=typeof t==`string`&&t.length>0?` -b ${Pa(t)}`:``;return`ok clone ${Pa(e)}${n}`}function Ia(e){let t=me(e.error);if(t.kind!==`auth`)return null;if(ue(t)){let t=Fa(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: ${Fa(e.url,e.branch)}`].join(`
13
- `)}function La(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=Ia({error:e.error,url:e.url,branch:e.branch,principal:e.principal});e.printStderr(`${n??`✗ ${t}`}\n`)}async function Ra(e,t){let n=(await e.get(t))?.login;return n&&n!==`unknown`?n:null}async function za(e){let t=me(e.error),n=null;if(!e.json&&t.kind===`auth`&&t.subclass===`403`){let t=Kt(e.url);t&&(n=await(e.resolvePrincipal??(e=>Ra(Qt(),e)))(t.hostname))}La({error:e.error,url:e.url,branch:e.branch,json:e.json,principal:n,emit:e.emit,printStderr:e.printStderr})}function Ba(e){return new O(`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 ja(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-BiJWiuVi.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){if(e instanceof be||e instanceof Xe){r.json?q(!0,{type:`error`,message:e.message}):process.stderr.write(`${e.message}\n`),process.exitCode=78;return}await za({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 Va=p();const Ha=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],...f.map(e=>e.path)];function Ua(e){return Dt({absPath:Ot(`project-local`,e),sideline:!1}).diagnostics}function Wa(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??Mn;try{let{sources:n,diagnostics:i,sidelined:a}=r(e.cwd),o=(e.readProjectLocalFn??Ua)(e.cwd??process.cwd()),s=[...i,...o],c=n.length===0?`defaults only`:n.join(`, `),l=s.filter(e=>e.code!==`REMOVED_KEY`);l.length===0?t(`✓ Configuration valid (sources: ${c})`):t(`! Configuration loaded, but ${l.length} config layer(s) had issues (sources: ${c})`);for(let e of s)t(``),t(_(e));for(let{from:e,to:n}of a)t(``),t(`Moved ${e} aside to ${n} so defaults could be used. Restore it once fixed.`);return{ok:!0}}catch(e){return n(e instanceof Error?e.message:String(e)),{ok:!1}}}function Ga(e){let t=(0,Va.parseDocument)(V(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 Ha)t.hasIn(e)&&n.push(e.join(`.`));return n}function Ka(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function qa(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=Ka(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}function Ja(e){switch(e){case`project`:return[`project`];case`project-local`:return[`project-local`];case`user`:return[`user`];case`both`:return[`project`,`user`];case`all`:return[`project`,`project-local`,`user`]}}async function Ya(e={}){let t=e.log??(e=>console.log(e)),n=e.error??(e=>console.error(e)),r=e.scope??`all`,i=e.dryRun??!1,a=e.cwd??process.cwd(),o=e.writeConfigPatchFn??E,s=Ja(r).map(t=>({scope:t,absPath:Ot(t,a,e.homedirOverride)})),c=[],l=!0;for(let{scope:t,absPath:n}of s){if(!z(n)){c.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=Ga(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:qa(Ha.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!s.ok){c.push({path:n,scope:t,found:r,removed:[],error:_(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}}const Xa=`project | project-local | user | all`,Za=new Set(Object.keys({project:!0,"project-local":!0,user:!0,both:!0,all:!0}));function Qa(e){return e!==`config`}function $a(){let e=new O(`config`).description(`Inspect and maintain OpenKnowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{Wa({}).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.*)`).option(`--scope <scope>`,`Which scope to migrate: ${Xa}`,`all`).option(`--dry-run`,`Preview without writing`,!1).action(async e=>{let t=String(e.scope);if(!Za.has(t)){console.error(`Invalid --scope: ${t}. Expected: ${Xa}`),process.exitCode=2;return}(await Ya({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}const eo=[` 1. ${P(`Customize`)} (sidebar) → ${P(`Skills`)}`,` 2. Click the ${P(`+`)} button`,` 3. Click ${P(`Create skill`)}`,` 4. Click ${P(`Upload skill`)}`,` 5. Pick ${P(`openknowledge.skill`)} from Downloads`],to=k(` Open the Claude Desktop App, then: ${P(`Customize → Skills → + → Create skill → Upload skill`)} → pick the file.`);function no(e){let t=[j(`Built ${e.outputPath}`),A(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…`)];return e.handoffError&&t.push(N(` Handoff failed: ${e.handoffError.message}`)),t.push(to),t.join(`
13
+ `)}function La(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=Ia({error:e.error,url:e.url,branch:e.branch,principal:e.principal});e.printStderr(`${n??`✗ ${t}`}\n`)}async function Ra(e,t){let n=(await e.get(t))?.login;return n&&n!==`unknown`?n:null}async function za(e){let t=me(e.error),n=null;if(!e.json&&t.kind===`auth`&&t.subclass===`403`){let t=Kt(e.url);t&&(n=await(e.resolvePrincipal??(e=>Ra(Qt(),e)))(t.hostname))}La({error:e.error,url:e.url,branch:e.branch,json:e.json,principal:n,emit:e.emit,printStderr:e.printStderr})}function Ba(e){return new O(`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 ja(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-C2dEkRx7.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){if(e instanceof be||e instanceof Xe){r.json?q(!0,{type:`error`,message:e.message}):process.stderr.write(`${e.message}\n`),process.exitCode=78;return}await za({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 Va=p();const Ha=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],...f.map(e=>e.path)];function Ua(e){return Dt({absPath:Ot(`project-local`,e),sideline:!1}).diagnostics}function Wa(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??Mn;try{let{sources:n,diagnostics:i,sidelined:a}=r(e.cwd),o=(e.readProjectLocalFn??Ua)(e.cwd??process.cwd()),s=[...i,...o],c=n.length===0?`defaults only`:n.join(`, `),l=s.filter(e=>e.code!==`REMOVED_KEY`);l.length===0?t(`✓ Configuration valid (sources: ${c})`):t(`! Configuration loaded, but ${l.length} config layer(s) had issues (sources: ${c})`);for(let e of s)t(``),t(_(e));for(let{from:e,to:n}of a)t(``),t(`Moved ${e} aside to ${n} so defaults could be used. Restore it once fixed.`);return{ok:!0}}catch(e){return n(e instanceof Error?e.message:String(e)),{ok:!1}}}function Ga(e){let t=(0,Va.parseDocument)(V(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 Ha)t.hasIn(e)&&n.push(e.join(`.`));return n}function Ka(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function qa(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=Ka(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}function Ja(e){switch(e){case`project`:return[`project`];case`project-local`:return[`project-local`];case`user`:return[`user`];case`both`:return[`project`,`user`];case`all`:return[`project`,`project-local`,`user`]}}async function Ya(e={}){let t=e.log??(e=>console.log(e)),n=e.error??(e=>console.error(e)),r=e.scope??`all`,i=e.dryRun??!1,a=e.cwd??process.cwd(),o=e.writeConfigPatchFn??E,s=Ja(r).map(t=>({scope:t,absPath:Ot(t,a,e.homedirOverride)})),c=[],l=!0;for(let{scope:t,absPath:n}of s){if(!z(n)){c.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=Ga(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:qa(Ha.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!s.ok){c.push({path:n,scope:t,found:r,removed:[],error:_(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}}const Xa=`project | project-local | user | all`,Za=new Set(Object.keys({project:!0,"project-local":!0,user:!0,both:!0,all:!0}));function Qa(e){return e!==`config`}function $a(){let e=new O(`config`).description(`Inspect and maintain OpenKnowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{Wa({}).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.*)`).option(`--scope <scope>`,`Which scope to migrate: ${Xa}`,`all`).option(`--dry-run`,`Preview without writing`,!1).action(async e=>{let t=String(e.scope);if(!Za.has(t)){console.error(`Invalid --scope: ${t}. Expected: ${Xa}`),process.exitCode=2;return}(await Ya({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}const eo=[` 1. ${P(`Customize`)} (sidebar) → ${P(`Skills`)}`,` 2. Click the ${P(`+`)} button`,` 3. Click ${P(`Create skill`)}`,` 4. Click ${P(`Upload skill`)}`,` 5. Pick ${P(`openknowledge.skill`)} from Downloads`],to=k(` Open the Claude Desktop App, then: ${P(`Customize → Skills → + → Create skill → Upload skill`)} → pick the file.`);function no(e){let t=[j(`Built ${e.outputPath}`),A(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…`)];return e.handoffError&&t.push(N(` Handoff failed: ${e.handoffError.message}`)),t.push(to),t.join(`
14
14
  `)}function ro(e){let t=e.skillVersion??`unknown`,n=e.recordedAt??`unknown`;return[k(`OpenKnowledge skill ${P(`v${t}`)} already delivered to Claude Desktop.`),A(` Recorded at ${n} in ~/.ok/skill-state.yml`),A(` Use ${P(`--force`)} to rebuild and re-open the install dialog.`)].join(`
15
15
  `)}function io(e){let t=e.skillVersion?` • Skill v${e.skillVersion}`:``;return[j(`Built ${e.outputPath}`),A(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…${t}`),k(` Claude Desktop App opened. Now upload the file manually:`),...eo,A(` If Claude Desktop didn't open, open it and start at step 1. The file is at ${e.outputPath}`)].join(`
16
16
  `)}function ao(e){return`${M(`Error:`)} ${e.buildError??`unknown build failure`}`}async function oo(e={}){let t=await ut(e);return t.status===`failed`?{...t,message:ao(t),exitCode:1}:t.status===`skip-current`?{...t,message:ro(t),exitCode:0}:t.status===`installed`?{...t,message:io(t),exitCode:0}:{...t,message:no(t),exitCode:0}}function so(){return new O(`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 oo({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 co(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 lo(e={}){let t=e.productName??`OpenKnowledge`;return I(On(e),t)}function uo(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 fo(e){let t=I(e,`state.json`);if(!z(t))return[];let n;try{n=JSON.parse(V(t,`utf-8`))}catch{return[]}return uo(n)??[]}function po(e){let t=I(e,`state.json`);if(!z(t))return!1;try{return uo(JSON.parse(V(t,`utf-8`)))!==null}catch{return!1}}function J(e,t){return e===t?`~`:e.startsWith(`${t}/`)?`~${e.slice(t.length)}`:e}function mo(e){return Jn===`/`?e:e.split(Jn).join(`/`)}function ho(e,t,n=`This project`){let r=[];r.push({kind:`stop-server`,group:n,label:`Stop the project server (if running)`,lockDir:w(e)});let i=new Set;for(let a of kn){let o=jn[a];if(!o.projectConfigPath)continue;let s=o.projectConfigPath(e);i.add(mo(L(e,s))),r.push({kind:`mcp-entry`,group:n,label:`Remove OK's MCP entry from ${o.label} (${mo(L(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([...cn(e),...he]);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:I(e,a),containWithin:e})}try{r.push({kind:`remove-path`,group:n,label:`Remove the OK shadow repo (.git/ok/)`,path:Pe(e)})}catch{}return r}function go(e,t){return{scope:`deinit`,ops:ho(e,t)}}function _o(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(I(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 all embeddings API keys (secrets.yml)`}),c.push(...yo(a,t));for(let e of kn){let n=jn[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 Ln(t))c.push({kind:`remove-path`,group:`Skill bundles`,label:`Remove ${J(e.path,t)}`,path:e.path});c.push(...bo(t,n,e.env));for(let e of o)c.push(...ho(e,t,`Project: ${Kn(e)}`));return c.push({kind:`remove-path`,group:`Global directory`,label:s?`Remove ~/.ok (including user-authored skills)`:`Remove ~/.ok (keeping ~/.ok/skills)`,path:I(t,`.ok`),preserve:s?void 0:[`skills`]}),{scope:`uninstall`,ops:c}}function vo(e){return[I(e,`.zshrc`),I(e,`.bash_profile`),I(e,`.config`,`fish`,`conf.d`,`open-knowledge.fish`)]}function yo(e,t){let n=[],r=new Set([...vo(t),...e?.rcFiles??[]]);for(let e of r)z(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 bo(e,t,n){if(t!==`darwin`)return[];let r={home:e,platformName:t,env:n},i=lo(r),a=lo({...r,productName:`Open Knowledge`}),o=I(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 xo(e,t={}){let n=t.clearToken??en,r=t.clearEmbeddingsKey??vt,i=t.stopServer??(e=>{let t=Gt({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 So(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 So(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(!z(e.rcFile))return{op:e,status:`not-present`};let{text:t,changed:n,emptyAfter:r}=zt(V(e.rcFile,`utf-8`));return n?r?(sr(e.rcFile,{force:!0}),{op:e,status:`removed`,detail:`file removed (was OK-owned)`}):(Et(e.rcFile,t,{mode:wn(e.rcFile)}),{op:e,status:`removed`}):{op:e,status:`not-present`}}case`extra-symlink`:return Ht(e.path,e.target)?(U(e.path),{op:e,status:`removed`}):{op:e,status:`not-present`};case`mcp-entry`:{let t=Rt(jn[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=Rn(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(Sn(e.projectRoot).length===0)return{op:e,status:`not-present`};let t=_n(e.projectRoot,cn(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 Co(e)}}function Co(e){if(e.requireOurState&&!po(e.path))return{op:e,status:`skipped`,detail:`not verified as OpenKnowledge — left untouched`};e.containWithin&&An(e.path,e.containWithin);let t;try{t=tr(e.path)}catch(e){if(e.code!==`ENOENT`)throw e}if(!t)return{op:e,status:`not-present`};if(t.isSymbolicLink())return U(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 ir(e.path))t.has(r)||(sr(I(e.path,r),{recursive:!0,force:!0}),n=!0);return{op:e,status:n?`removed`:`not-present`}}return sr(e.path,{recursive:!0,force:!0}),{op:e,status:`removed`}}function wo(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 To(e){if(e.ops.length===0)return A(`Nothing to remove.`);let t=[];for(let[n,r]of wo(e.ops)){t.length>0&&t.push(``),t.push(P(`${n}:`));for(let e of r)t.push(` ${N(`-`)} ${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 as(e,t,n,r,i){let a=is(e,t,I(r,`cpu.cpuprofile`)),o=!1,s=Wn(process.execPath,[a],T({stdio:`ignore`})),c=setInterval(()=>{let e=es(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{sr(I(a,`..`),{recursive:!0,force:!0})}catch{}return o}function os(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 ss(e,t={}){let{pid:n,cpuProfileSecs:r=15,noInspector:i=!1}=e,a=t.log??(e=>console.log(e)),o=t.discover??_t,s=t.inspect??Ft,c=t.resolveCommand??Ke,l=t.resolveUsage??dt,u=t.collectLsofFn??ts,d=t.getEndpoints??rs,f=t.profiler??as,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?I(v,`.ok`,`local`,`diagnostics`,`process-${n}-${b}`):I(process.cwd(),`ok-diagnose-${n}-${b}`);try{B(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)=>{cr(I(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 te=u(n);if(te&&S(`lsof.txt`,te),!i){let e=te?ns(te).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`,os(V(I(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 cs(e){let t=gr({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function ls(e){let t=nr(I(dr(),`ok-bundle-process-`));return await ss({pid:e,output:t}),t}function us(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 ds(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function fs(e){let{summary:t,manifest:n}=e;return t.redacted?t.contentDirVisible?`masked as <CONTENT_DIR>, but still present in some files`:`masked as <CONTENT_DIR>`:t.contentDirVisible?`visible (${n.contentDir.absolutePath})`:`not present`}function ps(e){let t=e.manifest.redaction.secretScrub;return t===void 0?Y.default.yellow(`NOT scrubbed (--no-redact): tokens and keys ship verbatim`):`scrubbed known credential formats (${t.redactedLineCount} line(s) across ${t.redactions.length} file(s))`}function ms(e,t,n){let{summary:r,manifest:i}=t;e(``),e(Y.default.bold(`ok diagnose bundle — what leaves this machine`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${us(r.totalBytes)} uncompressed`),e(` Document names: included in cleartext (${r.docNameCount} doc.name occurrence(s) in telemetry)`),e(` Content-dir path: ${fs(t)}`),e(` Credentials: ${ps(t)}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function hs(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??cs,i=t.runProcessDiagnose??ls,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=F(o);if(!z(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=I(e.contentDir,`.ok`,`local`,`diagnostics`);B(n,{recursive:!0}),o=I(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=e.redact!==!1,l=await Ut({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:c,scrubSecrets:c,deps:t.collectDeps});try{return l.manifest.serverStatus===`not-running`&&n(Y.default.yellow(` server not running — live state unavailable`)),ms(n,l,o),e.yes!==!0&&!ds(await r(`Write bundle? [y/N]: `))?(n(Y.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await Bt({collected:l,outputPath:o}),n(Y.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(l.cleanup(),s!==void 0)try{sr(s,{recursive:!0,force:!0})}catch{}}}function gs(){let e=new O(`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 ss({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand($o()),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(`--no-redact`,`Write a raw bundle: skip credential scrubbing and content-dir path masking`).option(`--redact`,`Scrub credentials and mask the content-dir path (the default)`).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-BcOjgjSS.mjs`),{resolveContentDir:r}=await import(`./src-DR51i3QD.mjs`),i=process.cwd(),{config:a}=n(i);await hs({contentDir:r(a,i),projectDir:i,pid:t,out:e.out,yes:e.yes===!0,redact:e.redact})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(Y.default.red(t)),process.exit(1)}}),e}async function _s(){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 ri({message:`Enter embeddings provider API key:`})).trim()}function vs(e){return nt(e)}async function ys(e,t){let n=await pt(qe(),e,t);return n.apiKey?{present:!0,notRequired:!1,source:n.source}:{present:!1,notRequired:n.keyless,source:null}}async function bs(e){try{let t=jt(w(e));if(!t||t.port<=0||!At(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 xs(){return new O(`set-key`).description(`Store the embeddings API key for THIS project's configured endpoint`).option(`--cwd <path>`,`Project directory (defaults to the current directory)`).action(async e=>{let t=await _s();if(!t){process.stderr.write(`No key provided.
42
+ `)}\n`);try{S(`stacks.txt`,os(V(I(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 cs(e){let t=gr({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function ls(e){let t=nr(I(dr(),`ok-bundle-process-`));return await ss({pid:e,output:t}),t}function us(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 ds(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function fs(e){let{summary:t,manifest:n}=e;return t.redacted?t.contentDirVisible?`masked as <CONTENT_DIR>, but still present in some files`:`masked as <CONTENT_DIR>`:t.contentDirVisible?`visible (${n.contentDir.absolutePath})`:`not present`}function ps(e){let t=e.manifest.redaction.secretScrub;return t===void 0?Y.default.yellow(`NOT scrubbed (--no-redact): tokens and keys ship verbatim`):`scrubbed known credential formats (${t.redactedLineCount} line(s) across ${t.redactions.length} file(s))`}function ms(e,t,n){let{summary:r,manifest:i}=t;e(``),e(Y.default.bold(`ok diagnose bundle — what leaves this machine`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${us(r.totalBytes)} uncompressed`),e(` Document names: included in cleartext (${r.docNameCount} doc.name occurrence(s) in telemetry)`),e(` Content-dir path: ${fs(t)}`),e(` Credentials: ${ps(t)}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function hs(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??cs,i=t.runProcessDiagnose??ls,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=F(o);if(!z(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=I(e.contentDir,`.ok`,`local`,`diagnostics`);B(n,{recursive:!0}),o=I(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=e.redact!==!1,l=await Ut({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:c,scrubSecrets:c,deps:t.collectDeps});try{return l.manifest.serverStatus===`not-running`&&n(Y.default.yellow(` server not running — live state unavailable`)),ms(n,l,o),e.yes!==!0&&!ds(await r(`Write bundle? [y/N]: `))?(n(Y.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await Bt({collected:l,outputPath:o}),n(Y.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(l.cleanup(),s!==void 0)try{sr(s,{recursive:!0,force:!0})}catch{}}}function gs(){let e=new O(`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 ss({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand($o()),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(`--no-redact`,`Write a raw bundle: skip credential scrubbing and content-dir path masking`).option(`--redact`,`Scrub credentials and mask the content-dir path (the default)`).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-BAOw2Vq0.mjs`),{resolveContentDir:r}=await import(`./src-DR51i3QD.mjs`),i=process.cwd(),{config:a}=n(i);await hs({contentDir:r(a,i),projectDir:i,pid:t,out:e.out,yes:e.yes===!0,redact:e.redact})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(Y.default.red(t)),process.exit(1)}}),e}async function _s(){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 ri({message:`Enter embeddings provider API key:`})).trim()}function vs(e){return nt(e)}async function ys(e,t){let n=await pt(qe(),e,t);return n.apiKey?{present:!0,notRequired:!1,source:n.source}:{present:!1,notRequired:n.keyless,source:null}}async function bs(e){try{let t=jt(w(e));if(!t||t.port<=0||!At(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 xs(){return new O(`set-key`).description(`Store the embeddings API key for THIS project's configured endpoint`).option(`--cwd <path>`,`Project directory (defaults to the current directory)`).action(async e=>{let t=await _s();if(!t){process.stderr.write(`No key provided.
43
43
  `),process.exitCode=1;return}let n=R(e.cwd??process.cwd()),{baseUrl:r}=vs(n);try{await qe().setForProject(n,r,t)}catch(e){process.stderr.write(`Failed to store the embeddings key: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1;return}process.stderr.write(`✓ Embeddings API key stored for ${r}\n (kept in ~/.ok/secrets.yml, 0600, this machine only — never in the project).
44
44
  Enable semantic search with \`ok embeddings enable\`, or in
45
45
  OK Desktop → Settings → This project → Search.
@@ -74,7 +74,7 @@ ${t}`,d++;break;case`id`:l=t.includes(`\0`)?void 0:t;break;case`retry`:/^\d+$/.t
74
74
  `).replace(/\n+$/,``);return e.endsWith(`
75
75
  `)?`${c}\n`:c}function Ou(e){return e.replace(/\r\n|\r|\n/g,`<br>`).replace(/\|/g,`\\|`)}function ku(e){return/\s/.test(e)?`<${e}>`:e}function Au(e,t={}){let{header:n,rows:r}=$l(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(Ou).join(` | `)} |`,`| ${n.map(()=>`---`).join(` | `)} |`,...r.map(e=>`| ${n.map((n,r)=>{let i=e[r]??``,a=Ou(i);if(r===o&&t.linkForTitle&&i.trim()!==``){let e=t.linkForTitle(i);if(e)return`[${a}](${ku(e)})`}return a}).join(` | `)} |`)].join(`
76
76
  `),columns:i,wide:i>a}}function ju(e,t){let n=e.match(/^#\s+(.+)$/m);return n?n[1].trim():t}function Mu(e,t){return`# ${e}\n\n${t}\n`}const Nu=[`links`,`frontmatter`,`callouts`,`images`,`tables`],Pu=/\.mdx?$/i;function Fu(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 Iu(e,t={}){let n=t.selected??new Set(Nu),r=bu(e);if(!r&&!t.force)return{changes:[],assets:[],deletions:[],report:Fu(!1)};let i=Fu(r),a=_u(e),o=cu(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(!Pu.test(e)||s&&l.has(e))continue;let r;try{r=V(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=Ql(a,Kn(e),{strip:t.stripBase64});a=r.markdown;for(let t of r.assets)d.push({path:I(F(e),t.filename),bytes:t.bytes});i.assetsExtracted+=r.assets.length,o(`images`,n)}if(n.has(`callouts`)){let e=a;a=Jl(a),o(`callouts`,e)}if(n.has(`frontmatter`)){let t=c.get(e);if(t){let e=a;a=Du(a,t.propertyKeys),o(`frontmatter`,e)}}if(n.has(`links`)){let e=a;a=gu(a,{redirectCsv:s}),o(`links`,e)}a!==r&&u.push({path:e,content:a})}if(s)for(let e of o){let r=Au(e.csvText,{linkForTitle:t=>{let n=au(e.folderIndex,t);return n.ambiguous&&(i.ambiguousTitleLinks+=1),n.path?L(F(e.stubTargetPath),n.path):null}});if(r.columns===0)continue;let a=e.stubPath??e.stubTargetPath,o=null;if(e.stubPath)try{o=V(e.stubPath,`utf8`)}catch{i.unreadable.push(e.stubPath);continue}let c=Mu(o===null?e.fallbackTitle:ju(o,e.fallbackTitle),r.table);n.has(`links`)&&(c=gu(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 Lu(e){for(let t of e.assets)B(F(t.path),{recursive:!0}),cr(t.path,t.bytes);for(let t of e.changes)B(F(t.path),{recursive:!0}),cr(t.path,t.content,`utf8`);for(let t of e.deletions)try{U(t)}catch(e){if(e.code!==`ENOENT`)throw e}}const Ru={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`},zu=[`images`,`callouts`,`frontmatter`,`tables`,`links`];function Bu(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 zu)n.push(` ${Ru[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(`
77
- `)}function Vu(e,t){return JSON.stringify({applied:t.applied,...e},null,2)}function Hu(e){let t=new Set(Nu);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: ${Nu.join(`, `)}`);return e})}function Uu(e,t){let n=new Set(Nu);if(e&&(n=new Set(Hu(e))),t)for(let e of Hu(t))n.delete(e);return n}function Wu(){let e=new O(`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=R(e??process.cwd()),r;try{r=Uu(t.only,t.skip)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=2;return}let i=Iu(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{Lu(i)}catch(e){console.error(`Failed to apply changes: ${e instanceof Error?e.message:String(e)}`),process.exitCode=4;return}console.log(t.json?Vu(a,{applied:t.apply??!1}):Bu(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 Gu(e=()=>$t(tn())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>ye({lockDir:w(e)}).baseUrl,classifyName:(e,t)=>{let n=I(e,t);try{return H(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=>{nn(`open`,[e])},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function Ku(e){return e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).includes(`..`)}function qu(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 Ju(e,t,n,r){let i=`openknowledge://open?project=${encodeURIComponent(e)}&${t}=${encodeURIComponent(n)}`;r.openTarget(i)}function Yu(e,t,n){let r=R(t.project??process.cwd()),i=e.replace(/\/+$/,``);if(!i)return n.error("Nothing to open: pass a doc, folder, or skill name (e.g. `ok open specs/foo/SPEC`)."),1;if(Ku(i))return n.error(`Invalid name "${i}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(t.skill===!0){let e=t.scope??`project`;if(!ce.includes(e))return n.error(`Invalid --scope "${t.scope}": expected one of ${ce.join(`, `)}.`),1;if(n.detectBundlePath())return Ju(r,`doc`,`__skill__/${e}/${i}`,n),n.log(`Opening skill ${i} (${e}) in the OpenKnowledge desktop app.`),0;let a=n.resolveBaseUrl(r);if(a){let t=`${a}/#/${Re(e,i)}`;return n.openTarget(t),n.log(`Opening skill ${i} (${e}) in your browser: ${t}`),0}return qu(n)}let a=/\/+$/.test(e)||n.classifyName(r,i)===`folder`,o=n.detectBundlePath();if(a){if(o)return Ju(r,`folder`,i,n),n.log(`Opening folder ${i} in the OpenKnowledge desktop app.`),0;let e=n.resolveBaseUrl(r);if(e){let t=`${e}/#/${Ue(i)}`;return n.openTarget(t),n.log(`Opening folder ${i} in your browser: ${t}`),0}return qu(n)}if(o)return Ju(r,`doc`,i,n),n.log(`Opening ${i} in the OpenKnowledge desktop app.`),0;let s=n.resolveBaseUrl(r);if(s){let e=`${s}/#/${He(i)}`;return n.openTarget(e),n.log(`Opening ${i} in your browser: ${e}`),0}return qu(n)}function Xu(){return new O(`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: ${ce.join(` | `)}`,`project`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action((e,t)=>{process.exitCode=Yu(e,t,Gu())})}function Zu(e){return new O(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-CpGDxOmo.mjs`),r=e(),i=process.cwd(),a=ze(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 Qu(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function $u(e,t,n=process.cwd()){let r=e.op??`sync`,i=jt(w(n));if(i&&i.port>0){let t=`http://127.0.0.1:${i.port}/api/sync/trigger`;e.json||process.stderr.write(`Triggering ${r} via running server (port ${i.port})\n`);try{let n=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,...se({kind:`cli`,runtimeVersion:D})},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}`)}Qu(e.json,{type:`triggered`,op:r,port:i.port}),e.json||process.stderr.write(`✓ ${r} triggered\n`);return}catch(t){let n=t instanceof Error?t.message:String(t);e.json||process.stderr.write(`Server trigger failed (${n}), running directly\n`)}}e.json||process.stderr.write(`Running ${r} directly (no live server)\n`);let a=kt({baseDir:n});if(r===`sync`||r===`pull`){Qu(e.json,{type:`step`,step:`pull`});let t=await a.pull();Qu(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Qu(e.json,{type:`step`,step:`push`}),await a.push(),Qu(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
77
+ `)}function Vu(e,t){return JSON.stringify({applied:t.applied,...e},null,2)}function Hu(e){let t=new Set(Nu);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: ${Nu.join(`, `)}`);return e})}function Uu(e,t){let n=new Set(Nu);if(e&&(n=new Set(Hu(e))),t)for(let e of Hu(t))n.delete(e);return n}function Wu(){let e=new O(`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=R(e??process.cwd()),r;try{r=Uu(t.only,t.skip)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=2;return}let i=Iu(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{Lu(i)}catch(e){console.error(`Failed to apply changes: ${e instanceof Error?e.message:String(e)}`),process.exitCode=4;return}console.log(t.json?Vu(a,{applied:t.apply??!1}):Bu(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 Gu(e=()=>$t(tn())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>ye({lockDir:w(e)}).baseUrl,classifyName:(e,t)=>{let n=I(e,t);try{return H(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=>{nn(`open`,[e])},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function Ku(e){return e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).includes(`..`)}function qu(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 Ju(e,t,n,r){let i=`openknowledge://open?project=${encodeURIComponent(e)}&${t}=${encodeURIComponent(n)}`;r.openTarget(i)}function Yu(e,t,n){let r=R(t.project??process.cwd()),i=e.replace(/\/+$/,``);if(!i)return n.error("Nothing to open: pass a doc, folder, or skill name (e.g. `ok open specs/foo/SPEC`)."),1;if(Ku(i))return n.error(`Invalid name "${i}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(t.skill===!0){let e=t.scope??`project`;if(!ce.includes(e))return n.error(`Invalid --scope "${t.scope}": expected one of ${ce.join(`, `)}.`),1;if(n.detectBundlePath())return Ju(r,`doc`,`__skill__/${e}/${i}`,n),n.log(`Opening skill ${i} (${e}) in the OpenKnowledge desktop app.`),0;let a=n.resolveBaseUrl(r);if(a){let t=`${a}/#/${Re(e,i)}`;return n.openTarget(t),n.log(`Opening skill ${i} (${e}) in your browser: ${t}`),0}return qu(n)}let a=/\/+$/.test(e)||n.classifyName(r,i)===`folder`,o=n.detectBundlePath();if(a){if(o)return Ju(r,`folder`,i,n),n.log(`Opening folder ${i} in the OpenKnowledge desktop app.`),0;let e=n.resolveBaseUrl(r);if(e){let t=`${e}/#/${Ue(i)}`;return n.openTarget(t),n.log(`Opening folder ${i} in your browser: ${t}`),0}return qu(n)}if(o)return Ju(r,`doc`,i,n),n.log(`Opening ${i} in the OpenKnowledge desktop app.`),0;let s=n.resolveBaseUrl(r);if(s){let e=`${s}/#/${He(i)}`;return n.openTarget(e),n.log(`Opening ${i} in your browser: ${e}`),0}return qu(n)}function Xu(){return new O(`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: ${ce.join(` | `)}`,`project`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action((e,t)=>{process.exitCode=Yu(e,t,Gu())})}function Zu(e){return new O(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-CJAgM4pS.mjs`),r=e(),i=process.cwd(),a=ze(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 Qu(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function $u(e,t,n=process.cwd()){let r=e.op??`sync`,i=jt(w(n));if(i&&i.port>0){let t=`http://127.0.0.1:${i.port}/api/sync/trigger`;e.json||process.stderr.write(`Triggering ${r} via running server (port ${i.port})\n`);try{let n=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,...se({kind:`cli`,runtimeVersion:D})},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}`)}Qu(e.json,{type:`triggered`,op:r,port:i.port}),e.json||process.stderr.write(`✓ ${r} triggered\n`);return}catch(t){let n=t instanceof Error?t.message:String(t);e.json||process.stderr.write(`Server trigger failed (${n}), running directly\n`)}}e.json||process.stderr.write(`Running ${r} directly (no live server)\n`);let a=kt({baseDir:n});if(r===`sync`||r===`pull`){Qu(e.json,{type:`step`,step:`pull`});let t=await a.pull();Qu(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Qu(e.json,{type:`step`,step:`push`}),await a.push(),Qu(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
78
78
  `)),Qu(e.json,{type:`complete`,op:r}),e.json||process.stderr.write(`✓ ${r} complete\n`)}function ed(e){return new O(`sync`).description(`Commit, pull, and push to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await $u({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 td(e){return new O(`pull`).description(`Pull changes from the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await $u({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 nd(e){return new O(`push`).description(`Push commits to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await $u({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 rd(e){return typeof e==`string`&&xe.includes(e)}async function id(e={}){let t=R(e.cwd??process.cwd()),n=e.pack??`knowledge-base`;if(!Tt[n])return{status:`failed`,message:`${M(`Error:`)} Unknown pack "${n}". Available: ${xe.join(`, `)}`,exitCode:1};let r;try{r=await Ne({projectDir:t,rootDir:e.root,packId:n,skipPrerequisite:e.dryRun===!0})}catch(e){return e instanceof ht?{status:`prerequisite-missing`,message:`${M(`Error:`)} ${e.message}`,exitCode:1}:{status:`failed`,message:`${M(`Error:`)} ${e instanceof Error?e.message:String(e)}`,exitCode:1}}if(r.created.length===0&&!r.packSkills?.some(e=>e.pending)){let e=Tt[n].name,t=(r.packSkills??[]).filter(e=>e.conflict).map(e=>`\n${N(`!`)} Skill "${e.name}" is your own — the pack's version is not installed. Rename yours to install the pack's version.`).join(``);return{status:`no-op`,message:`${j(`Your ${e} pack is already seeded.`)}${t}\n${A(`Nothing to do.`)}`,plan:r,exitCode:0}}if(e.dryRun){let e=Me(Tt[n]);return{status:`dry-run`,message:`${P(`Reference this pack for inspiration (dry-run — no changes made):`)}\n\n${e}\n\n${P(`Plan:`)}\n\n${od(r,t)}`,plan:r,exitCode:0}}if(!e.yes&&!await sd(`${P(`Plan:`)}\n\n${od(r,t)}\n\n${P(`Apply?`)} ${A(`[Y/n] `)}`,e.confirmStream))return{status:`cancelled`,message:A(`Cancelled.`),plan:r,exitCode:0};let i=await Le(r,{projectDir:t,packId:n});if(i.errors.length>0){let e=i.errors.map(e=>` ${M(`✗`)} ${e.path}: ${e.error}`);return{status:`failed`,message:[`${N(`Applied`)} ${i.applied} entries, ${N(String(i.errors.length))} error(s):`,...e].join(`
79
79
  `),plan:r,exitCode:1}}let a=Tt[n].name,o=i.packSkillsInstalled.length>0?`\n${A(`Installed the ${a} skills for: ${i.packSkillsInstalled.join(`, `)}`)}`:``,s=(i.packSkillConflicts??[]).map(e=>e.hosts===void 0||e.hosts.length===0?`\n${N(`!`)} Skill "${e.name}" was not installed — you already have your own skill with that name. Rename yours if you want the pack's version.`:`\n${N(`!`)} Skill "${e.name}" was not installed for ${e.hosts.join(`, `)} — you already have your own skill with that name there. Rename yours if you want the pack's version.`).join(``);return{status:`applied`,message:`${j(`✓ Seeded ${a}`)} ${A(`(${i.applied} entries, ${i.durationMs}ms)`)}${o}${s}`,plan:r,exitCode:0}}function ad(){let e=[P(`Available packs:`)];for(let t of xe){let n=Tt[t];e.push(` ${j(t)} ${A(`—`)} ${n.name}: ${n.description}`)}return e.join(`
80
80
  `)}function od(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(P(`Folders to create:`));for(let e of r)n.push(` ${j(`+`)} ${k(L(t,R(t,e.path))||e.path)}${A(`/`)}`)}if(i.length>0){n.length>0&&n.push(``),n.push(P(`Files to create:`));for(let e of i)n.push(` ${j(`+`)} ${k(L(t,R(t,e.path))||e.path)}`)}if(e.skipped.length>0){n.length>0&&n.push(``),n.push(A(`Already present (skipped):`));for(let t of e.skipped)n.push(` ${A(`· ${t.path} (${t.reason})`)}`)}if(e.warnings.length>0){n.length>0&&n.push(``),n.push(N(`Warnings:`));for(let t of e.warnings)n.push(` ${N(`!`)} ${t}`)}let a=(e.packSkills??[]).filter(e=>e.conflict);if(a.length>0){n.length>0&&n.push(``),n.push(N(`Name collisions:`));for(let e of a)n.push(` ${N(`!`)} Skill "${e.name}" is your own — the pack's version will not be installed. Rename yours to install the pack's version.`)}return n.join(`
@@ -83,7 +83,7 @@ ${t}`,d++;break;case`id`:l=t.includes(`\0`)?void 0:t;break;case`retry`:/^\d+$/.t
83
83
  `);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 dd(e){return new O(`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 ud(t,await e())})}async function fd(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 pd(e,t){let{host:n,json:r}=e;W(n);let i=await ra(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 fd(new K({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 md(e){return new O(`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 pd(t,await e())})}function hd(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(`
84
84
  `)??``}\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 gd(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 _d(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 vd(e,t){return(await e.users.getAuthenticated()).data.login.toLowerCase()===t.toLowerCase()?`user`:`org`}function yd(e){return kt(Oa(e,[])).env(Sa())}function bd(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 xd={ensureOkScaffold:e=>{et(e)},gitFactory:yd};async function Sd(e){let t={...xd,...e.deps},n=R(e.projectDir),r;if(e.ownerKind)r=e.ownerKind;else try{r=await vd(e.octokit,e.body.owner)}catch(e){return{kind:`error`,code:hd(e)}}try{t.ensureOkScaffold(n)}catch{return{kind:`error`,code:`init-failed`}}let i=t.gitFactory(n);if(!z(I(n,`.git`)))try{await i.init()}catch{return{kind:`error`,code:`init-failed`}}let a;try{a=await gd({octokit:e.octokit,ownerLogin:e.body.owner,ownerKind:r,name:e.body.name,visibility:e.body.visibility,description:e.body.description})}catch(t){if(hd(t)===`name-conflict`){let t=await _d(e.octokit,e.body.owner,e.body.name);if(t===null)return{kind:`error`,code:`name-conflict`};a=t}else return{kind:`error`,code:hd(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=bd(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 Cd(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 wd(e,t){let{host:n,owner:r,name:i,visibility:a,description:o,projectDir:s,json:c}=e;W(n);let l=await ra(n,t);if(l==null){Cd(c,{kind:`error`,code:`auth-required`});return}let u=n===`github.com`?void 0:`https://${n}/api/v3`,d=new K({auth:l,...u?{baseUrl:u}:{}});try{Un(`git config user.email`,T({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`}Cd(c,await Sd({octokit:d,token:l,projectDir:s,body:{owner:r,name:i,visibility:a,description:o}}))}function Td(e){return new O(`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'
85
85
  `),process.exit(1)),await wd(t,await e())})}function Ed(){let e=new O(`share`);e.description(`Sharing flow operations (owners, name-check, publish)`);let t=()=>rn();return e.addCommand(md(t)),e.addCommand(dd(t)),e.addCommand(Td(t)),e}function Dd(){return new O(`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=R(e.project??process.cwd()),n=hn(t),r=_n(t,cn(t));if(r.kind===`no-exclude`){Od(e.json,t,r.reason);return}let i=hn(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(`${k(`Sharing mode is already`)} ${P(`shared`)} ${k(`— nothing to do.`)}\n`);return}process.stderr.write(`${j(`✓`)} ${P(`Sharing mode set to`)} ${j(`shared`)}\n`),process.stderr.write(` Removed OK paths from ${P(`.git/info/exclude`)}; commit the files to share with teammates.\n`)})}function Od(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(`${N({"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 kd(){return new O(`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=R(e.project??process.cwd()),n=hn(t),r=gn(t),i=[...Sn(t)],a=xn(t,cn(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: ${Ad(n)}`),r&&o.push(` ${P(`.ok/skills`)} is committable (carved out); the rest of .ok/ stays local.`),o.push(``),o.push(`Excluded from git via ${P(`.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: ${k(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(`
86
- `)}\n`)})}function Ad(e){switch(e){case`shared`:return j(`shared`);case`local-only`:return j(`local-only`);case`no-git`:return N(`no-git (not a git repository)`)}}function jd(){return new O(`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=R(e.project??process.cwd()),n=dn(t,cn(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`){Md(e.json,t,n.reason);return}let r=hn(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(`${P(`Sharing mode is already`)} ${j(`local-only`)} ${P(`— nothing to do.`)}\n`);return}process.stderr.write(`${j(`✓`)} ${P(`Sharing mode set to`)} ${j(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${P(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function Md(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(`${N({"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 Nd(){let e=new O(`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(Dd()),e.addCommand(jd()),e.addCommand(kd()),e}const Pd=new Set([`--cwd`,`--log-level`]);function Fd(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(`-`)){Pd.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function Id(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 Ld(e){return/\.(md|mdx)$/i.test(e)}function Rd(e,t){if(Ld(t))return!0;try{return H(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 zd(e=()=>$t(tn())){return{prepare:Ge,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{nn(`open`,[e])},runProjectOpen:(e,t)=>Yu(e,{project:t},Gu()),runBrowserOpen:e=>Vd(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function Bd(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof ct||e instanceof bt||e instanceof gt)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}async function Vd(e){let{createEphemeralProjectDir:t}=await import(`./src-DR51i3QD.mjs`),{loadConfig:n}=await import(`./src-BhdDn5db.mjs`),{bootStartServer:r,resolveBundledReactShellDir:i,resolveHost:a}=await import(`./start-BiJWiuVi.mjs`),{openBrowser:o}=await import(`./open-browser-De70N-tU.mjs`),s=i();s||(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 c=t(e.contentDir),l=!1,u,d=async()=>{if(!l){l=!0;try{await u?.destroy()}catch{}try{await fr(c,{recursive:!0,force:!0})}catch{}}},f=()=>{d().then(()=>process.exit(0))};process.once(`SIGINT`,f),process.once(`SIGTERM`,f);let{config:p}=n(c),m=a({},process.env);try{u=await r({config:p,cwd:c,host:m,port:0,projectDir:c,singleFile:e.canonicalFilePath,serveContentAssets:!0,reactShellDistDir:s,idleThresholdMs:6e5})}catch(t){await d(),process.stderr.write(`Failed to open ${e.singleDocRelPath}: ${t instanceof Error?t.message:String(t)}\n`),process.exit(1)}let h=`http://${m}:${u.port}/#/${He(e.docName)}`;process.env.OK_SINGLE_FILE_NO_OPEN===`1`?process.stdout.write(`Serving ${e.singleDocRelPath} (headless) at: ${h}\n`):(process.stdout.write(`Opening ${e.singleDocRelPath} in your browser: ${h}\n`),process.stdout.write(`Press Ctrl-C to close the session.
86
+ `)}\n`)})}function Ad(e){switch(e){case`shared`:return j(`shared`);case`local-only`:return j(`local-only`);case`no-git`:return N(`no-git (not a git repository)`)}}function jd(){return new O(`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=R(e.project??process.cwd()),n=dn(t,cn(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`){Md(e.json,t,n.reason);return}let r=hn(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(`${P(`Sharing mode is already`)} ${j(`local-only`)} ${P(`— nothing to do.`)}\n`);return}process.stderr.write(`${j(`✓`)} ${P(`Sharing mode set to`)} ${j(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${P(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function Md(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(`${N({"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 Nd(){let e=new O(`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(Dd()),e.addCommand(jd()),e.addCommand(kd()),e}const Pd=new Set([`--cwd`,`--log-level`]);function Fd(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(`-`)){Pd.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function Id(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 Ld(e){return/\.(md|mdx)$/i.test(e)}function Rd(e,t){if(Ld(t))return!0;try{return H(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 zd(e=()=>$t(tn())){return{prepare:Ge,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{nn(`open`,[e])},runProjectOpen:(e,t)=>Yu(e,{project:t},Gu()),runBrowserOpen:e=>Vd(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function Bd(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof ct||e instanceof bt||e instanceof gt)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}async function Vd(e){let{createEphemeralProjectDir:t}=await import(`./src-DR51i3QD.mjs`),{loadConfig:n}=await import(`./src-CMD64NyP.mjs`),{bootStartServer:r,resolveBundledReactShellDir:i,resolveHost:a}=await import(`./start-C2dEkRx7.mjs`),{openBrowser:o}=await import(`./open-browser-De70N-tU.mjs`),s=i();s||(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 c=t(e.contentDir),l=!1,u,d=async()=>{if(!l){l=!0;try{await u?.destroy()}catch{}try{await fr(c,{recursive:!0,force:!0})}catch{}}},f=()=>{d().then(()=>process.exit(0))};process.once(`SIGINT`,f),process.once(`SIGTERM`,f);let{config:p}=n(c),m=a({},process.env);try{u=await r({config:p,cwd:c,host:m,port:0,projectDir:c,singleFile:e.canonicalFilePath,serveContentAssets:!0,reactShellDistDir:s,idleThresholdMs:6e5})}catch(t){await d(),process.stderr.write(`Failed to open ${e.singleDocRelPath}: ${t instanceof Error?t.message:String(t)}\n`),process.exit(1)}let h=`http://${m}:${u.port}/#/${He(e.docName)}`;process.env.OK_SINGLE_FILE_NO_OPEN===`1`?process.stdout.write(`Serving ${e.singleDocRelPath} (headless) at: ${h}\n`):(process.stdout.write(`Opening ${e.singleDocRelPath} in your browser: ${h}\n`),process.stdout.write(`Press Ctrl-C to close the session.
87
87
  `),o(h)),await new Promise(()=>{})}function Hd(){let e=new O(`skills`).description(`Manage Open Knowledge skills for this project.`);return e.command(`installed`).description(`List every skill installed across all your agents (read-only).`).option(`--json`,`Emit the raw enumeration as JSON.`).action(e=>{let t=R(process.cwd()),n=Se(it(t)?.rootPath??t),r=Ct({projectDir:n}),i={...r,skills:r.skills.filter(e=>x(e.provenance,n))};if(e.json){process.stdout.write(`${JSON.stringify(i,null,2)}\n`);return}if(i.skills.length===0){process.stdout.write(`${A(`No installed skills found across any agent.`)}\n`);return}process.stdout.write(`${P(`${i.skills.length} installed skill(s):`)}\n`);for(let e of i.skills){let t=e.provenance.version?A(` v${e.provenance.version}`):``,n=[e.inert.commands&&`commands`,e.inert.hooks&&`hooks`,e.inert.mcp&&`mcp`].filter(Boolean),r=n.length>0?A(` [${n.join(`, `)}]`):``;process.stdout.write(` ${j(e.name)}${t} ${A(e.sourceHarnesses.join(`, `))}${r}\n`)}process.stdout.write(`\n${P(`${i.packs.length} pack(s):`)}\n`);for(let e of i.packs)process.stdout.write(` ${k(e.name)} ${A(`v${e.version}`)} — ${e.skills.length} skill(s)\n`)}),e.command(`import <source>`).description(`Import a skill into this project as versioned content (github owner/repo, a git URL, or a local path).`).option(`--skill <name>`,`Pick one skill from a multi-skill source.`).option(`--scope <scope>`,`project (default) or global.`,`project`).action(async(e,t)=>{let n=Ft(w(process.cwd()),`server`);if(n.status!==`alive`){process.stderr.write(`${M(`Error:`)} no running Open Knowledge server for this project. Start it with ${P(`ok start`)} and retry.\n`),process.exitCode=1;return}let r;try{r=await fetch(`http://127.0.0.1:${n.lock.port}/api/skill/import`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({source:e,...t.skill?{skill:t.skill}:{},scope:t.scope===`global`?`global`:`project`})})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`${M(`Error:`)} could not reach the server: ${t}\n`),process.exitCode=1;return}let i=await r.json().catch(()=>({}));if(!r.ok){let e=i.detail??i.title??`HTTP ${r.status}`;process.stderr.write(`${M(`Import failed:`)} ${e}\n`),process.exitCode=1;return}let a=i.name;if(i.alreadyImported){process.stdout.write(`${k(`Already imported:`)} ${P(a)} (identical content).\n`);return}let o=i.provenance??{},s=i.collisionRenamedFrom;process.stdout.write(`${j(`Imported`)} ${P(a)}${s?A(` (renamed from ${s} — name was taken)`):``} from ${A(o.source??e)}${o.publisher?A(` · ${o.publisher}`):``}.\n${A(`Saved as versioned content in this project's skill home. Scripts shown, never run. Use the skill's install menu (or the install MCP verb) to add it to your other editors.`)}\n`);for(let e of i.warnings??[])process.stdout.write(` ${A(`! ${e}`)}\n`)}),e}function Ud(e,t){let n=Wd(`server`,e),r=Wd(`ui`,t);return r.state===`missing`&&e.status===`alive`&&e.lock.capabilities?.includes(`ui`)===!0&&(r={name:`ui`,state:`alive`,pid:e.lock.pid,port:e.lock.port,startedAt:e.lock.startedAt,host:e.lock.hostname,alive:!0,servedByServer:!0}),{server:n,ui:r}}function Wd(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 Gd(e){return`${Kd(e.server)}\n${Kd(e.ui)}`}function Kd(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\``:e.servedByServer===!0?`${t} served by server pid=${e.pid} port=${e.port}`:`${t} alive pid=${e.pid} port=${e.port} started=${e.startedAt}`}function qd(e){let t=e.inspect??(t=>Ft(e.lockDir,t)),n=e.log??(e=>console.log(e)),r=Ud(t(`server`),t(`ui`));return e.json?n(JSON.stringify(r,null,2)):n(Gd(r)),r}function Jd(e){return new O(`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(),qd({lockDir:w(process.cwd()),json:t.json===!0})})}function Yd(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 Xd(e,t){let n=gr({input:e.input,output:e.output});try{return(await n.question(t)).trim()}finally{n.close()}}async function Zd(e={}){let t={input:e.input??process.stdin,output:e.output??process.stderr};t.output.write(A(`
88
88
  What you share is sent to the OpenKnowledge team.
89
89
  `));let n=await yn({message:`Before you go, mind sharing why? (optional)`,default:null,pageSize:b.length+1,choices:[...b.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 Xd(t,A(`Anything else we should know? (optional) `)),i=await Xd(t,A(`Email, if we may follow up (optional) `));return{reason:n,note:r||void 0,email:i||void 0}}async function Qd(e){if(!Yd(e))return`not-prompted`;let t;try{t=await(e.collect??(()=>Zd(e)))()}catch{return`failed`}return C(t)?((e.output??process.stderr).write(`\n${P(`Thank you. We read every response.`)}\n\n`),(await(e.submit??ne)({...t,source:`cli_uninstall`,appVersion:e.appVersion,platform:e.platform})).ok?`submitted`:`undelivered`):`skipped`}function $d(e,t,n=ef,r=z){let i=[];for(let t of[`/Applications/OpenKnowledge.app`,I(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 ef(e){try{return Hn(`npm`,e,T({encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}))}catch{return null}}const tf=`━`.repeat(64);function nf(e){let t=[N(tf),P(` One more step — remove the OpenKnowledge app itself`),A(` (OpenKnowledge can't delete its own running binary — do this by hand.)`),``];if(e.length===0)t.push(A(` Install method not detected. If you installed it, remove it via:`)),t.push(` ${k(`OK Desktop`)} — move /Applications/OpenKnowledge.app to the Trash`),t.push(` ${k(`npm global`)} — npm uninstall -g @inkeep/open-knowledge`),t.push(` ${k(`npx`)} — nothing to remove (runs from a temporary cache)`);else for(let n of e)t.push(` ${k(n.label)}`),t.push(` ${n.instruction}`);return t.push(N(tf)),t.join(`
@@ -0,0 +1,2 @@
1
+ import"./src-DMpGVIiQ.mjs";var e=`0.51.0-beta.1`;const t=`config.yml`,n=e;export{n,t};
2
+ //# sourceMappingURL=constants-QeQKosNT.mjs.map
package/dist/index.d.mts CHANGED
@@ -9455,6 +9455,23 @@ declare module '@tiptap/core' {
9455
9455
  * special-case in the mdxJsxTextElement handler.
9456
9456
  */
9457
9457
  //#endregion
9458
+ //#region ../../node_modules/.pnpm/@tiptap+extension-horizontal-rule@3.22.3_@tiptap+core@3.22.3_@tiptap+pm@3.22.4__@tiptap+pm@3.22.4/node_modules/@tiptap/extension-horizontal-rule/dist/index.d.ts
9459
+ declare module '@tiptap/core' {
9460
+ interface Commands<ReturnType> {
9461
+ horizontalRule: {
9462
+ /**
9463
+ * Add a horizontal rule
9464
+ * @example editor.commands.setHorizontalRule()
9465
+ */
9466
+ setHorizontalRule: () => ReturnType;
9467
+ };
9468
+ }
9469
+ }
9470
+ /**
9471
+ * This extension allows you to insert horizontal rules.
9472
+ * @see https://www.tiptap.dev/api/nodes/horizontal-rule
9473
+ */
9474
+ //#endregion
9458
9475
  //#region ../../node_modules/.pnpm/@tiptap+extension-blockquote@3.22.3_@tiptap+core@3.22.3_@tiptap+pm@3.22.4_/node_modules/@tiptap/extension-blockquote/dist/index.d.ts
9459
9476
  declare module '@tiptap/core' {
9460
9477
  interface Commands<ReturnType> {
@@ -9478,23 +9495,6 @@ declare module '@tiptap/core' {
9478
9495
  * Matches a blockquote to a `>` as input.
9479
9496
  */
9480
9497
  //#endregion
9481
- //#region ../../node_modules/.pnpm/@tiptap+extension-horizontal-rule@3.22.3_@tiptap+core@3.22.3_@tiptap+pm@3.22.4__@tiptap+pm@3.22.4/node_modules/@tiptap/extension-horizontal-rule/dist/index.d.ts
9482
- declare module '@tiptap/core' {
9483
- interface Commands<ReturnType> {
9484
- horizontalRule: {
9485
- /**
9486
- * Add a horizontal rule
9487
- * @example editor.commands.setHorizontalRule()
9488
- */
9489
- setHorizontalRule: () => ReturnType;
9490
- };
9491
- }
9492
- }
9493
- /**
9494
- * This extension allows you to insert horizontal rules.
9495
- * @see https://www.tiptap.dev/api/nodes/horizontal-rule
9496
- */
9497
- //#endregion
9498
9498
  //#region ../../node_modules/.pnpm/@tiptap+extension-code@3.22.3_@tiptap+core@3.22.3_@tiptap+pm@3.22.4_/node_modules/@tiptap/extension-code/dist/index.d.ts
9499
9499
  declare module '@tiptap/core' {
9500
9500
  interface Commands<ReturnType> {
package/dist/index.mjs CHANGED
@@ -1516,6 +1516,6 @@ export default function okBridge(pi: {
1516
1516
  `))}function j9(e,t){let n=S(e,`utf-8`);if(n.trim().length!==0)try{let r=k9(JSON.parse(n),t),i=n.endsWith(`
1517
1517
  `)?`
1518
1518
  `:``;ne(e,`${JSON.stringify(r,null,2)}${i}`)}catch{let r=O9(n,t.contentDir);r!==n&&ne(e,r)}}function M9(e,t){let n=S(e,`utf-8`),r=O9(n,t.contentDir);r!==n&&ne(e,r)}function N9(e){try{return C(e,{withFileTypes:!0}).filter(e=>e.isFile()).map(t=>N(e,t.name))}catch{return[]}}const YSe=new Set([`agent-presence.json`,`agent-effects.json`,`runtime.json`]);function P9(e){return/\.log\.\d+$/.test(e)}function XSe(e){return e.endsWith(`.jsonl`)||e.endsWith(`.log`)||P9(e)}function ZSe(e){let t={contentDir:e.contentDir};for(let n of[`telemetry`,`logs`,`process`])for(let r of N9(N(e.stagingDir,n)))XSe(r)?A9(r,t):r.endsWith(`.json`)?j9(r,t):M9(r,t);for(let n of N9(N(e.stagingDir,`state`))){let e=fe(n);n.endsWith(`.jsonl`)?A9(n,t):YSe.has(e)?j9(n,t):M9(n,t)}}const F9=[`.ok`,`local`,`telemetry`],I9=[`.ok`,`local`,`logs`],L9=[`.ok`,`local`,`loss-capture`],R9=`spans-current.jsonl`,z9=`spans-prev.jsonl`,B9=`server-current.jsonl`,V9=`server-prev.jsonl`,H9=`loss-current.jsonl`,U9=`loss-prev.jsonl`;function QSe(e){return N(e,...F9,R9)}function $Se(e){return N(e,...F9,z9)}function eCe(e){return N(e,...I9,B9)}function tCe(e){return N(e,...I9,V9)}function nCe(e){return N(e,...L9,H9)}function rCe(e){return N(e,...L9,U9)}const W9=1e3;async function iCe(e){try{let t=await fetch(`http://127.0.0.1:${e}/api/metrics/agent-presence`,{signal:AbortSignal.timeout(W9)});return t.ok?await t.text():null}catch{return null}}async function aCe(e){try{let t=await fetch(`http://127.0.0.1:${e}/api/metrics/agent-effects`,{signal:AbortSignal.timeout(W9)});return t.ok?await t.text():null}catch{return null}}async function oCe(e){try{let t=await fetch(`http://127.0.0.1:${e}/api/metrics/watcher-recent`,{signal:AbortSignal.timeout(W9)});return t.ok?await t.text():null}catch{return null}}function sCe(e){try{let t=JSON.parse(e);if(typeof t!=`object`||!t)return null;let n=t.decisions;return Array.isArray(n)?n.length===0?``:`${n.map(e=>JSON.stringify(e)).join(`
1519
- `)}\n`:null}catch{return null}}function cCe(e){let t=N(e,`.git`,`ok`);if(!g(t))return null;let n=u(`git`,[`-C`,t,`log`,`--oneline`,`-50`],I3({encoding:`utf-8`,timeout:2e3}));return n.error||n.status!==0?null:n.stdout??``}function lCe(e){let t=N(e,`.git`,`ok`);if(!g(t))return null;let n=u(`git`,[`-C`,t,`for-each-ref`,`--sort=-creatordate`,`--count=50`,`--format=%(refname)%09%(creatordate:iso-strict)%09%(contents:subject)`,`refs/checkpoints/`],I3({encoding:`utf-8`,timeout:2e3}));return n.error||n.status!==0?null:n.stdout??``}function G9(){let e=process.env.OK_DESKTOP_VERSION,t=process.env.OK_DESKTOP_PACKAGED,n=process.env.OK_DESKTOP_CHANNEL;return e===void 0||t===void 0||n===void 0?null:{electronVersion:e,packaged:t===`1`||t.toLowerCase()===`true`,channel:n}}function uCe(){return{nodeVersion:process.version,platform:k(),arch:ie()}}function dCe(){return process.env.OTEL_SDK_DISABLED===`false`}function K9(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function q9(e){if(!g(e))return{};let t;try{t=(0,Zt.parse)(S(e,`utf-8`))}catch(t){return console.warn(`[ok diagnose bundle] failed to parse ${e} for manifest config; manifest will report schema defaults. Reason: ${t instanceof Error?t.message:String(t)}`),{}}if(!K9(t))return{};let n=t.telemetry;if(!K9(n))return{};let r=n.localSink;return K9(r)?r:{}}function J9(e){return typeof e==`boolean`?e:void 0}function fCe(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?e:void 0}function Y9(e){if(K9(e))return fCe(e.maxBytes)}function pCe(e){let t=q9(d$(`project`,e)),n=q9(d$(`project-local`,e));return{enabled:J9(n.enabled)??J9(t.enabled)??!0,spansMaxBytes:Y9(n.spans)??Y9(t.spans)??52428800,logsMaxBytes:Y9(n.logs)??Y9(t.logs)??26214400}}function mCe(e){return Ae(`sha256`).update(e).digest(`hex`)}function hCe(e){let t=S(e),n=0;for(let e=0;e<t.length;e++)t[e]===10&&n++;return n}function gCe(e){let t=S(e,`utf-8`),n=`"doc.name"`,r=0,i=t.indexOf(n);for(;i!==-1;)r++,i=t.indexOf(n,i+10);return r}function X9(e,t){if(!g(e))return!1;try{return v(pe(t),{recursive:!0}),m(e,t),!0}catch{return!1}}function Z9(e){let t=[],n=e=>{let r=C(e,{withFileTypes:!0});for(let i of r){let r=N(e,i.name);i.isDirectory()?n(r):i.isFile()&&t.push(r)}};return n(e),t.sort()}const _Ce=new Set([`.jsonl`]);function Q9(e){let t=e.lastIndexOf(`.`);return t===-1?!1:_Ce.has(e.slice(t))}const vCe=new Set([`.jsonl`,`.json`,`.txt`,`.log`,`.lock`]);function yCe(e){if(P9(e))return!0;let t=e.lastIndexOf(`.`);return t===-1?!1:vCe.has(e.slice(t))}function bCe(e){let t=[];for(let n of Z9(e)){let r=$9(e,n);if(!yCe(r))continue;let{redacted:i,patterns:a,lineCount:o}=No(S(n,`utf-8`));a.length!==0&&(ne(n,i),t.push({file:r,lineCount:o,patterns:a}))}return{redactions:t,redactedLineCount:t.reduce((e,t)=>e+t.lineCount,0)}}function $9(e,t){return _e(e,t).split(ye).join(`/`)}async function xCe(e){let t=ve(e.contentDir),n=ve(e.projectDir??e.contentDir),r=e.deps??{},i=r.fetchAgentPresence??iCe,a=r.fetchAgentEffects??aCe,o=r.fetchWatcherRecent??oCe,s=r.readShadowHead??cCe,c=r.readCheckpointRefs??lCe,l=r.now??(()=>new Date),u=r.okVersion??(()=>`0.51.0-beta.0`),d=r.readDesktopEnv??G9,f=r.readLanguage??D9,p=r.readRuntime??uCe,h=r.isOtlpPushEnabled??dCe,_=y(N(le(),`ok-bundle-`));try{v(N(_,`telemetry`),{recursive:!0}),v(N(_,`logs`),{recursive:!0}),v(N(_,`state`),{recursive:!0}),X9(QSe(n),N(_,`telemetry`,R9)),X9($Se(n),N(_,`telemetry`,z9)),X9(eCe(n),N(_,`logs`,B9)),X9(tCe(n),N(_,`logs`,V9));for(let t of e.userLogFiles??[])X9(t,N(_,`logs`,fe(t)));let y=N(n,`.ok`,`local`),b=N(y,`server.lock`),x=`not-running`,C=`no server.lock`,w=null;if(g(b)){X9(b,N(_,`state`,`server.lock`));try{let e=S(b,`utf-8`),t=JSON.parse(e);typeof t.port==`number`?w=t.port:C=`lock present but no port`}catch{C=`lock present but unparseable`}}if(w!==null){let e=await i(w);e===null?C=`agent-presence endpoint at :${w} unreachable`:(ne(N(_,`state`,`agent-presence.json`),e),x=`running`,C=``);let t=await a(w);t!==null&&ne(N(_,`state`,`agent-effects.json`),t);let n=await o(w);if(n!==null){let e=sCe(n);e!==null&&ne(N(_,`state`,`watcher-recent.jsonl`),e)}}let T=s(t);T!==null&&ne(N(_,`state`,`shadow-head.txt`),T);let E=c(t);E!==null&&ne(N(_,`state`,`checkpoint-refs.txt`),E),X9(nCe(n),N(_,`state`,H9)),X9(rCe(n),N(_,`state`,U9)),X9(N(y,`last-spawn-error.log`),N(_,`state`,`last-spawn-error.log`)),X9(N(y,bY),N(_,`state`,bY)),X9(N(y,xY),N(_,`state`,xY));let te=p(),re=d(),ie=f(),ae={ok:{version:u(),nodeVersion:te.nodeVersion,platform:te.platform,arch:te.arch},host:{desktop:re,language:ie}};ne(N(_,`state`,`runtime.json`),`${JSON.stringify(ae,null,2)}\n`);let oe=x===`running`?`running
1519
+ `)}\n`:null}catch{return null}}function cCe(e){let t=N(e,`.git`,`ok`);if(!g(t))return null;let n=u(`git`,[`-C`,t,`log`,`--oneline`,`-50`],I3({encoding:`utf-8`,timeout:2e3}));return n.error||n.status!==0?null:n.stdout??``}function lCe(e){let t=N(e,`.git`,`ok`);if(!g(t))return null;let n=u(`git`,[`-C`,t,`for-each-ref`,`--sort=-creatordate`,`--count=50`,`--format=%(refname)%09%(creatordate:iso-strict)%09%(contents:subject)`,`refs/checkpoints/`],I3({encoding:`utf-8`,timeout:2e3}));return n.error||n.status!==0?null:n.stdout??``}function G9(){let e=process.env.OK_DESKTOP_VERSION,t=process.env.OK_DESKTOP_PACKAGED,n=process.env.OK_DESKTOP_CHANNEL;return e===void 0||t===void 0||n===void 0?null:{electronVersion:e,packaged:t===`1`||t.toLowerCase()===`true`,channel:n}}function uCe(){return{nodeVersion:process.version,platform:k(),arch:ie()}}function dCe(){return process.env.OTEL_SDK_DISABLED===`false`}function K9(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function q9(e){if(!g(e))return{};let t;try{t=(0,Zt.parse)(S(e,`utf-8`))}catch(t){return console.warn(`[ok diagnose bundle] failed to parse ${e} for manifest config; manifest will report schema defaults. Reason: ${t instanceof Error?t.message:String(t)}`),{}}if(!K9(t))return{};let n=t.telemetry;if(!K9(n))return{};let r=n.localSink;return K9(r)?r:{}}function J9(e){return typeof e==`boolean`?e:void 0}function fCe(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?e:void 0}function Y9(e){if(K9(e))return fCe(e.maxBytes)}function pCe(e){let t=q9(d$(`project`,e)),n=q9(d$(`project-local`,e));return{enabled:J9(n.enabled)??J9(t.enabled)??!0,spansMaxBytes:Y9(n.spans)??Y9(t.spans)??52428800,logsMaxBytes:Y9(n.logs)??Y9(t.logs)??26214400}}function mCe(e){return Ae(`sha256`).update(e).digest(`hex`)}function hCe(e){let t=S(e),n=0;for(let e=0;e<t.length;e++)t[e]===10&&n++;return n}function gCe(e){let t=S(e,`utf-8`),n=`"doc.name"`,r=0,i=t.indexOf(n);for(;i!==-1;)r++,i=t.indexOf(n,i+10);return r}function X9(e,t){if(!g(e))return!1;try{return v(pe(t),{recursive:!0}),m(e,t),!0}catch{return!1}}function Z9(e){let t=[],n=e=>{let r=C(e,{withFileTypes:!0});for(let i of r){let r=N(e,i.name);i.isDirectory()?n(r):i.isFile()&&t.push(r)}};return n(e),t.sort()}const _Ce=new Set([`.jsonl`]);function Q9(e){let t=e.lastIndexOf(`.`);return t===-1?!1:_Ce.has(e.slice(t))}const vCe=new Set([`.jsonl`,`.json`,`.txt`,`.log`,`.lock`]);function yCe(e){if(P9(e))return!0;let t=e.lastIndexOf(`.`);return t===-1?!1:vCe.has(e.slice(t))}function bCe(e){let t=[];for(let n of Z9(e)){let r=$9(e,n);if(!yCe(r))continue;let{redacted:i,patterns:a,lineCount:o}=No(S(n,`utf-8`));a.length!==0&&(ne(n,i),t.push({file:r,lineCount:o,patterns:a}))}return{redactions:t,redactedLineCount:t.reduce((e,t)=>e+t.lineCount,0)}}function $9(e,t){return _e(e,t).split(ye).join(`/`)}async function xCe(e){let t=ve(e.contentDir),n=ve(e.projectDir??e.contentDir),r=e.deps??{},i=r.fetchAgentPresence??iCe,a=r.fetchAgentEffects??aCe,o=r.fetchWatcherRecent??oCe,s=r.readShadowHead??cCe,c=r.readCheckpointRefs??lCe,l=r.now??(()=>new Date),u=r.okVersion??(()=>`0.51.0-beta.1`),d=r.readDesktopEnv??G9,f=r.readLanguage??D9,p=r.readRuntime??uCe,h=r.isOtlpPushEnabled??dCe,_=y(N(le(),`ok-bundle-`));try{v(N(_,`telemetry`),{recursive:!0}),v(N(_,`logs`),{recursive:!0}),v(N(_,`state`),{recursive:!0}),X9(QSe(n),N(_,`telemetry`,R9)),X9($Se(n),N(_,`telemetry`,z9)),X9(eCe(n),N(_,`logs`,B9)),X9(tCe(n),N(_,`logs`,V9));for(let t of e.userLogFiles??[])X9(t,N(_,`logs`,fe(t)));let y=N(n,`.ok`,`local`),b=N(y,`server.lock`),x=`not-running`,C=`no server.lock`,w=null;if(g(b)){X9(b,N(_,`state`,`server.lock`));try{let e=S(b,`utf-8`),t=JSON.parse(e);typeof t.port==`number`?w=t.port:C=`lock present but no port`}catch{C=`lock present but unparseable`}}if(w!==null){let e=await i(w);e===null?C=`agent-presence endpoint at :${w} unreachable`:(ne(N(_,`state`,`agent-presence.json`),e),x=`running`,C=``);let t=await a(w);t!==null&&ne(N(_,`state`,`agent-effects.json`),t);let n=await o(w);if(n!==null){let e=sCe(n);e!==null&&ne(N(_,`state`,`watcher-recent.jsonl`),e)}}let T=s(t);T!==null&&ne(N(_,`state`,`shadow-head.txt`),T);let E=c(t);E!==null&&ne(N(_,`state`,`checkpoint-refs.txt`),E),X9(nCe(n),N(_,`state`,H9)),X9(rCe(n),N(_,`state`,U9)),X9(N(y,`last-spawn-error.log`),N(_,`state`,`last-spawn-error.log`)),X9(N(y,bY),N(_,`state`,bY)),X9(N(y,xY),N(_,`state`,xY));let te=p(),re=d(),ie=f(),ae={ok:{version:u(),nodeVersion:te.nodeVersion,platform:te.platform,arch:te.arch},host:{desktop:re,language:ie}};ne(N(_,`state`,`runtime.json`),`${JSON.stringify(ae,null,2)}\n`);let oe=x===`running`?`running
1520
1520
  `:`not-running (${C})\n`;if(ne(N(_,`state`,`server-status.txt`),oe),e.processDir&&g(e.processDir)){let t=N(_,`process`);v(t,{recursive:!0}),m(e.processDir,t,{recursive:!0})}let O=e.redact===!0;O&&ZSe({stagingDir:_,contentDir:t}),e.note&&ne(N(_,`note.txt`),e.note);let se=null;e.scrubSecrets===!0&&(se=bCe(_));for(let t of e.extraFiles??[])X9(t.sourcePath,N(_,`extra`,t.zipName??fe(t.sourcePath)))||r.logger?.warn({sourcePath:t.sourcePath},`extra file missing; omitted from bundle`);let k=pCe(n),ce=Z9(_),le=[],ue=0,A=0;for(let e of ce){let t=$9(_,e),n=ee(e).size,r=Q9(t)?hCe(e):0;le.push({path:t,bytes:n,lines:r}),ue+=n,t.startsWith(`telemetry/`)&&Q9(t)&&(A+=gCe(e))}let j={applied:O};se!==null&&(j.secretScrub=se);let de={schemaVersion:2,createdAt:l().toISOString(),ok:{version:u(),nodeVersion:te.nodeVersion,platform:te.platform,arch:te.arch},host:{desktop:re,language:ie},contentDir:{pathSha256:mCe(t),absolutePath:O?`<CONTENT_DIR>`:t},telemetry:{localSink:k,otlpPushEnabled:h()},redaction:j,serverStatus:x,files:le};ne(N(_,`manifest.json`),`${JSON.stringify(de,null,2)}\n`);let pe=ce.some(e=>{try{return S(e,`utf-8`).includes(t)}catch{return!1}}),me={totalBytes:ue,fileCount:le.length,docNameCount:A,contentDirVisible:pe,redacted:O},M=!1;return{stagingDir:_,manifest:de,summary:me,cleanup:()=>{M||(M=!0,D(_,{recursive:!0,force:!0}))}}}catch(e){throw D(_,{recursive:!0,force:!0}),e}}async function SCe(e){let{collected:t,outputPath:n}=e,r=pe(n);if(!g(r))throw Error(`ok diagnose bundle: parent directory does not exist: ${r}. Create it or pass --out with an existing parent.`);let i=new ive.ZipFile,a=Z9(t.stagingDir);for(let e of a){let n=$9(t.stagingDir,e);i.addFile(e,n)}i.end();let o=h(n);return i.outputStream.pipe(o),await new Promise((e,t)=>{o.on(`close`,e),o.on(`error`,t),i.outputStream.on(`error`,t)}),n}function CCe(e,t){let n=N(e,`.ok`,`config.yml`);if(g(n))try{let t=(0,Zt.parse)(S(n,`utf-8`)),r=I7(t)?t.content:void 0,i=I7(r)?r.dir:void 0;if(typeof i==`string`&&i.length>0)return ve(e,i)}catch(e){t?.warn({configPath:n,err:e},`bug-report: failed to read .ok/config.yml; falling back to project root as content dir`)}return ve(e)}async function wCe(e,t,n,r){let i=f9(t,e.logger),a=await xCe({contentDir:CCe(t,e.logger),projectDir:t,redact:e.redact,scrubSecrets:e.redact,note:e.note,extraFiles:e.extraFiles,userLogFiles:[...ySe(i,e.userLogsDir??N(O(),`.ok`,`logs`)),...m9(e.cachesDir??N(O(),`Library`,`Caches`))],deps:{readDesktopEnv:n,readLanguage:r,logger:e.logger}});try{v(pe(e.outputPath),{recursive:!0}),await SCe({collected:a,outputPath:e.outputPath});let t=a.manifest.redaction.secretScrub;return{zipPath:e.outputPath,summary:{level:`full`,systemWide:!1,projectSlug:i,files:a.manifest.files.map(e=>e.path),redactions:t?.redactions??[],redactedLineCount:t?.redactedLineCount??0,generatedAt:a.manifest.createdAt}}}finally{a.cleanup()}}async function TCe(e){let{projectDir:t}=e,n=e.readDesktopEnv??G9,r=e.readLanguage??D9;if(e.level===`full`&&t!==void 0)return wCe(e,t,n,r);let{zipPath:i,summary:a}=await CSe({projectDir:t,redact:e.redact,outputPath:e.outputPath,userLogsDir:e.userLogsDir,shipItLogFiles:m9(e.cachesDir??N(O(),`Library`,`Caches`)),logger:e.logger,note:e.note,extraFiles:e.extraFiles,desktop:n(),language:r()});return{zipPath:i,summary:{level:e.level,systemWide:t===void 0,projectSlug:a.projectSlug,files:a.files,redactions:a.redactions,redactedLineCount:a.redactedLineCount,generatedAt:a.generatedAt}}}export{V5 as ALL_EDITOR_IDS,H5 as EDITOR_LABELS,l7 as EDITOR_TARGETS,U5 as HOSTS_WITH_USER_SKILL_DIR,uSe as LAUNCH_CONFIG_NAME,RSe as PATH_SHIM_BEGIN,BSe as PATH_SHIM_BLOCK_RE,zSe as PATH_SHIM_END,Kxe as addOkPathsToGitExclude,O7 as assertProjectPathSafe,Q5 as buildManagedServerEntry,kSe as buildMcpConfigDeclineEvent,ASe as buildMcpConfigMigrateEvent,u9 as classifyExistingMcpEntry,TCe as collectReportBundle,tn as createTokenStore,gSe as defaultBugReportZipPath,Be as detectGh,mSe as detectInstalledEditors,Ube as editorConfigPathDisplay,Hbe as editorEntryLocator,G7 as formatTrackedRemediation,Yxe as getExcludedOkPaths,U7 as getOkArtifactPaths,X5 as isEntryUpToDate,$5 as isOwnManagedEntry,FSe as loadConfig,uee as makeLazyProbeTokenStore,d9 as okBugReportsDir,C9 as parseGitHubBlobUrl,ISe as parseGitHubShareUrl,w9 as parseGitHubTreeUrl,S9 as parseGitUrl,VSe as pathInstallMarkerPath,Cxe as previewContent,hSe as probeOwnManagedEditorMcpEntry,W7 as probeTrackedOkPaths,c9 as readExistingMcpEntry,Jxe as readSharingMode,Xxe as readSkillsShared,No as redactContent,qxe as removeOkPathsFromGitExclude,TSe as removeOwnMcpEntry,Fxe as removeProjectSkill,USe as removeUserGlobalSkillBundle,jxe as resolveProjectRoot,NSe as runStop,Zxe as setSkillsShared,y9 as truncatePriorEntry,E9 as userGlobalSkillBundleTargets,LSe as validateLocalFolderForShare,s9 as writeEditorMcpConfig,KSe as writeProjectAiIntegrations,j7 as writeProjectSkill,pSe as writeUserMcpConfigs};
1521
1521
  //# sourceMappingURL=index.mjs.map