@inkeep/open-knowledge 0.20.0-beta.3 → 0.20.0-beta.4

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 (30) hide show
  1. package/dist/assets/skills/discovery/SKILL.md +1 -1
  2. package/dist/assets/skills/project/SKILL.md +4 -2
  3. package/dist/cli.mjs +6 -6
  4. package/dist/constants-CccigS7Z.mjs +2 -0
  5. package/dist/{dist-CcBhqiSK.mjs → dist-DG18qmsf.mjs} +6 -6
  6. package/dist/{dist-DVWyQ2rE.mjs → dist-lMD2xM96.mjs} +1 -1
  7. package/dist/index.mjs +1 -1
  8. package/dist/{init-CXgKbGqU.mjs → init-BEl-oLte.mjs} +4 -4
  9. package/dist/init-C7uBoTEn.mjs +1 -0
  10. package/dist/loader-Br4O9l2c.mjs +1 -0
  11. package/dist/{loader-P-wIqwQJ.mjs → loader-CAzv0pqx.mjs} +2 -2
  12. package/dist/{preview-C6u_HSrM.mjs → preview-BQFuOGx7.mjs} +2 -2
  13. package/dist/preview-DgLc6gDO.mjs +1 -0
  14. package/dist/public/assets/{index-PKtmMZD3.js → index-B8O97Pkv.js} +2 -2
  15. package/dist/public/index.html +1 -1
  16. package/dist/{repair-launch-json-DhC6fFqf.mjs → repair-launch-json-BTrUFJZp.mjs} +2 -2
  17. package/dist/{repair-mcp-configs-Mu9q2KP8.mjs → repair-mcp-configs-_6UImgDH.mjs} +2 -2
  18. package/dist/{repair-skills-aa6PY9M2.mjs → repair-skills-B54Iho-y.mjs} +2 -2
  19. package/dist/repair-skills-CypPUSjG.mjs +1 -0
  20. package/dist/{src-DPSnkoZ_.mjs → src-AOM5DOYm.mjs} +2 -2
  21. package/dist/start-C0Mpznab.mjs +1 -0
  22. package/dist/{start-Bz1Xy2ov.mjs → start-CPnfm53U.mjs} +2 -2
  23. package/dist/{write-project-skill-DF8Mypd7.mjs → write-project-skill-CD-qC1w3.mjs} +2 -2
  24. package/package.json +1 -1
  25. package/dist/constants-8TbZTxy2.mjs +0 -2
  26. package/dist/init-B8ThmEDv.mjs +0 -1
  27. package/dist/loader-B4XVtshT.mjs +0 -1
  28. package/dist/preview-CiozYdtg.mjs +0 -1
  29. package/dist/repair-skills-CUAuz35w.mjs +0 -1
  30. package/dist/start-BrzdwifC.mjs +0 -1
@@ -3,7 +3,7 @@ name: open-knowledge-discovery
3
3
  description: "Read when the user asks what OpenKnowledge is, wants to install it on a repository, wants to share an OpenKnowledge project with collaborators, or asks how `ok init` / `ok cowork` / OK Desktop set up a project. Do NOT load to perform OpenKnowledge reads/writes — the runtime guidance for editing markdown inside an initialized OK project ships as a separate project-local skill at `.claude/skills/open-knowledge/` whenever `ok init` runs. If the user appears to be editing markdown inside a `.ok/` project and this is the only OK skill loaded, advise them to re-run `ok init` to install the project-local skill."
4
4
  compatibility: "Any agent host — no MCP server required. Pure discovery + install guidance."
5
5
  metadata:
6
- version: "0.20.0-beta.3"
6
+ version: "0.20.0-beta.4"
7
7
  author: "Inkeep"
8
8
  repository: "https://github.com/inkeep/open-knowledge"
9
9
  ---
@@ -3,7 +3,7 @@ name: open-knowledge
3
3
  description: "Authoritative agent-runtime contract for working inside an OpenKnowledge project — a markdown-CRDT knowledge base exposed over MCP. Use whenever reading, listing, searching, or editing any `.md` or `.mdx` file in the project, and before any `mcp__open-knowledge__*` tool call (`exec`, `search`, `write`, `edit`, and the rest). Installed by `ok init`, so its presence means this is an OpenKnowledge project and it governs every markdown file here. Covers the read/write tool surface, grounding and linking rules, folder/template conventions, the live browser preview, and the rule that OK's MCP tools — never native file tools — handle in-scope markdown."
4
4
  compatibility: "Claude Code, Claude Desktop, Claude Cowork, Claude.ai web. Requires OpenKnowledge MCP server + code execution."
5
5
  metadata:
6
- version: "0.20.0-beta.3"
6
+ version: "0.20.0-beta.4"
7
7
  author: "Inkeep"
8
8
  repository: "https://github.com/inkeep/open-knowledge"
9
9
  ---
@@ -48,7 +48,9 @@ Tools NOT in OK MCP (your host's): `preview_start`, `preview_screenshot`, `WebFe
48
48
 
49
49
  **MCP tool visibility — not seeing `exec` is NOT the escape hatch.** MCP wiring varies by client (Claude Code, Cursor, Codex, Windsurf, VS Code). Server labels are user-defined; tools may not appear as top-level symbols named `exec`. If OpenKnowledge is registered as an MCP server here, route markdown reads through its `exec` / `search` via your client's documented MCP invocation (including any generic "call MCP tool" flow). Registration is the test, not top-level-symbol visibility.
50
50
 
51
- **Escape hatch.** Native `Read` / `Grep` / `Glob` on `.md` / `.mdx` is allowed **only** when no OpenKnowledge MCP server is registered for this project, **or** immediately after you tried an MCP call and it failed then begin a user-visible sentence with `OpenKnowledge MCP unavailable:`. Never use the hatch because you skipped your client's MCP path, didn't see `exec` as a top-level tool, or rationalized the skill wasn't necessary.
51
+ **Your initial tool list is NOT exhaustive — run tool discovery before concluding the MCP is missing.** Some clients (notably Codex) defer MCP tools behind a lazy `tool_search` / tool-discovery step, so `mcp__open-knowledge__*` is absent from the upfront tool set and only appears after you search for it. Absence from the visible list means "I have not discovered it yet," NOT "it is not registered." If you don't see the tools, your first move is to run your client's tool-discovery / `tool_search` for `open-knowledge` (or `exec` / `search` / `write`) do not infer unavailability from the initial list.
52
+
53
+ **Escape hatch.** Native `Read` / `Grep` / `Glob` on `.md` / `.mdx` is allowed **only** when, after running tool discovery (above), no OpenKnowledge MCP server is registered for this project, **or** immediately after you actually invoked an MCP call and it failed — then begin a user-visible sentence with `OpenKnowledge MCP unavailable:`. "Not registered" is a conclusion you may only reach after tool discovery turned it up empty — never from the initial tool list alone. Never use the hatch because you skipped your client's MCP path, didn't see `exec` as a top-level tool, didn't run tool discovery, or rationalized the skill wasn't necessary.
52
54
 
53
55
  **Source code and non-markdown files** (`.ts`, `.py`, `package.json`, …): native `Read` / `Grep` / `Glob` always.
54
56
 
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{s as e}from"./chunk-C94x7I9S.mjs";import{t}from"./esm-BLMtE3s6.mjs";import{$a as n,Ia as r,Ii as i,Ja as a,La as o,Mo as s,Nn as c,Qa as l,Va as u,_o as d,an as f,ao as p,do as m,eo as h,f as g,ha as _,io as v,jo as y,li as b,mo as x,n as S,oi as ee,oo as C,s as w,so as T,zi as te}from"./server-lock-CN2YHwpP-CemdeDui.mjs";import{a as ne,n as re,r as ie,t as ae}from"./gh-detect-DsccWGZs.mjs";import{i as oe}from"./git-handle-DY9lXoT3-Cmzgvwd8.mjs";import{$ as se,An as ce,Cn as le,D as ue,Dn as de,Dr as fe,Ft as pe,Gt as me,Hn as he,Kn as ge,Kt as _e,L as ve,Mr as ye,O as be,Or as xe,Qr as Se,Ur as Ce,Wt as we,Yr as Te,Zi as Ee,Zt as De,_t as Oe,aa as ke,ar as Ae,at as je,b as Me,bt as Ne,c as Pe,da as Fe,en as Ie,et as Le,fa as Re,ga as ze,hn as Be,ia as Ve,la as He,ln as Ue,ma as We,mi as Ge,mn as Ke,na as qe,oa as Je,or as Ye,ot as Xe,pa as Ze,ra as Qe,rt as $e,st as et,ta as tt,ti as nt,wt as rt,x as it,zn as at}from"./dist-CcBhqiSK.mjs";import{t as ot}from"./yazl-Docqgl6q.mjs";import{n as st,r as ct,t as E}from"./dist-bundle-D75dREX-.mjs";import{A as lt,C as ut,D as dt,E as ft,F as pt,I as mt,L as ht,M as gt,N as _t,O as vt,P as yt,S as bt,T as xt,b as St,j as Ct,k as wt,u as Tt,v as Et,w as Dt}from"./init-CXgKbGqU.mjs";import{a as Ot,c as kt,h as At,i as jt,l as Mt,m as Nt,o as Pt,s as Ft,u as It}from"./src-DPSnkoZ_.mjs";import{n as Lt,t as Rt}from"./constants-8TbZTxy2.mjs";import{n as zt,t as Bt}from"./loader-P-wIqwQJ.mjs";import{c as Vt,i as D,n as O,o as k,r as A,s as j,t as M}from"./colors-8SzMRIVy.mjs";import{S as Ht,_ as Ut,b as Wt,m as Gt,x as Kt,y as qt}from"./start-Bz1Xy2ov.mjs";import{n as Jt}from"./repair-skills-aa6PY9M2.mjs";import{execFile as Yt,execSync as Xt,spawn as N,spawnSync as P}from"node:child_process";import{accessSync as Zt,closeSync as Qt,constants as $t,cpSync as en,createWriteStream as tn,existsSync as F,mkdirSync as I,mkdtempSync as nn,openSync as rn,readFileSync as L,readdirSync as an,realpathSync as on,rmSync as sn,statSync as cn,unlinkSync as ln,writeFileSync as R}from"node:fs";import un,{basename as z,dirname as dn,join as B,relative as fn,resolve as V,sep as pn}from"node:path";import mn from"node:process";import{arch as hn,freemem as gn,homedir as _n,platform as vn,release as yn,tmpdir as bn,totalmem as xn,type as Sn,uptime as Cn}from"node:os";import{fileURLToPath as wn}from"node:url";import{rm as Tn}from"node:fs/promises";import{createHash as En,randomUUID as Dn}from"node:crypto";import{setTimeout as On}from"node:timers/promises";import{promisify as kn,stripVTControlCharacters as An,styleText as H}from"node:util";import{AsyncLocalStorage as jn,AsyncResource as Mn}from"node:async_hooks";import*as Nn from"node:readline";import{createInterface as Pn}from"node:readline/promises";const Fn={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 In;(function(e){})(In||={});function Ln(e){return d(a,e)}async function Rn(e,t,n,r){let i=zn(await Bn(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 zn(e){let t={};for(let n of e.split(`
2
+ import{s as e}from"./chunk-C94x7I9S.mjs";import{t}from"./esm-BLMtE3s6.mjs";import{$a as n,Ia as r,Ii as i,Ja as a,La as o,Mo as s,Nn as c,Qa as l,Va as u,_o as d,an as f,ao as p,do as m,eo as h,f as g,ha as _,io as v,jo as y,li as b,mo as x,n as S,oi as ee,oo as C,s as w,so as T,zi as te}from"./server-lock-CN2YHwpP-CemdeDui.mjs";import{a as ne,n as re,r as ie,t as ae}from"./gh-detect-DsccWGZs.mjs";import{i as oe}from"./git-handle-DY9lXoT3-Cmzgvwd8.mjs";import{$ as se,An as ce,Cn as le,D as ue,Dn as de,Dr as fe,Ft as pe,Gt as me,Hn as he,Kn as ge,Kt as _e,L as ve,Mr as ye,O as be,Or as xe,Qr as Se,Ur as Ce,Wt as we,Yr as Te,Zi as Ee,Zt as De,_t as Oe,aa as ke,ar as Ae,at as je,b as Me,bt as Ne,c as Pe,da as Fe,en as Ie,et as Le,fa as Re,ga as ze,hn as Be,ia as Ve,la as He,ln as Ue,ma as We,mi as Ge,mn as Ke,na as qe,oa as Je,or as Ye,ot as Xe,pa as Ze,ra as Qe,rt as $e,st as et,ta as tt,ti as nt,wt as rt,x as it,zn as at}from"./dist-DG18qmsf.mjs";import{t as ot}from"./yazl-Docqgl6q.mjs";import{n as st,r as ct,t as E}from"./dist-bundle-D75dREX-.mjs";import{A as lt,C as ut,D as dt,E as ft,F as pt,I as mt,L as ht,M as gt,N as _t,O as vt,P as yt,S as bt,T as xt,b as St,j as Ct,k as wt,u as Tt,v as Et,w as Dt}from"./init-BEl-oLte.mjs";import{a as Ot,c as kt,h as At,i as jt,l as Mt,m as Nt,o as Pt,s as Ft,u as It}from"./src-AOM5DOYm.mjs";import{n as Lt,t as Rt}from"./constants-CccigS7Z.mjs";import{n as zt,t as Bt}from"./loader-CAzv0pqx.mjs";import{c as Vt,i as D,n as O,o as k,r as A,s as j,t as M}from"./colors-8SzMRIVy.mjs";import{S as Ht,_ as Ut,b as Wt,m as Gt,x as Kt,y as qt}from"./start-CPnfm53U.mjs";import{n as Jt}from"./repair-skills-B54Iho-y.mjs";import{execFile as Yt,execSync as Xt,spawn as N,spawnSync as P}from"node:child_process";import{accessSync as Zt,closeSync as Qt,constants as $t,cpSync as en,createWriteStream as tn,existsSync as F,mkdirSync as I,mkdtempSync as nn,openSync as rn,readFileSync as L,readdirSync as an,realpathSync as on,rmSync as sn,statSync as cn,unlinkSync as ln,writeFileSync as R}from"node:fs";import un,{basename as z,dirname as dn,join as B,relative as fn,resolve as V,sep as pn}from"node:path";import mn from"node:process";import{arch as hn,freemem as gn,homedir as _n,platform as vn,release as yn,tmpdir as bn,totalmem as xn,type as Sn,uptime as Cn}from"node:os";import{fileURLToPath as wn}from"node:url";import{rm as Tn}from"node:fs/promises";import{createHash as En,randomUUID as Dn}from"node:crypto";import{setTimeout as On}from"node:timers/promises";import{promisify as kn,stripVTControlCharacters as An,styleText as H}from"node:util";import{AsyncLocalStorage as jn,AsyncResource as Mn}from"node:async_hooks";import*as Nn from"node:readline";import{createInterface as Pn}from"node:readline/promises";const Fn={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 In;(function(e){})(In||={});function Ln(e){return d(a,e)}async function Rn(e,t,n,r){let i=zn(await Bn(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 zn(e){let t={};for(let n of e.split(`
3
3
  `)){let e=n.trim();if(e===``)continue;let r=e.indexOf(`=`);r!==-1&&(t[e.slice(0,r)]=e.slice(r+1))}return t}function Bn(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 Vn(e,n){let r=new t(`git-credential`);return r.description(`Git credential helper (git credential-helper protocol)`),r.command(`get`).description(`Lookup credentials from TokenStore (called by git)`).action(async()=>{let t=n?.();try{let n,r=await e({onKeychainRead:e=>{n=e},onBackendSelected:e=>{e.backend===`file`&&e.reason&&t?.warn({backend:`file`,reason:e.reason},`[auth] token storage fallback`)}}),i=await Rn(process.stdin,process.stdout,r,{log:t,getDiag:()=>n});await le(t),process.exit(i)}catch(e){t?.error({error:e instanceof Error?e.message:String(e)},`[auth] git-credential get: unexpected error`),await le(t),process.exit(1)}}),r}function Hn(e){let t=e.endpoint.DEFAULTS;return/^https:\/\/(api\.)?github\.com$/.test(t.baseUrl)?`https://github.com`:t.baseUrl.replace(`/api/v3`,``)}async function Un(e,t,n){let r={baseUrl:Hn(e),headers:{accept:`application/json`},...n},i=await e(t,r);if(`error`in i.data){let n=new st(`${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 Wn(e){let t=e.request||E,n={client_id:e.clientId};return`scopes`in e&&Array.isArray(e.scopes)&&(n.scope=e.scopes.join(` `)),Un(t,`POST /login/device/code`,n)}async function Gn(e){let t=await Un(e.request||E,`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=Kn(e,t.data.expires_in),n.refreshTokenExpiresAt=Kn(e,t.data.refresh_token_expires_in)}delete n.scopes}return{...t,authentication:n}}function Kn(e,t){return new Date(e+t*1e3).toISOString()}async function qn(e,t){let n=Jn(e,t.auth);if(n)return n;let{data:r}=await Wn({clientType:e.clientType,clientId:e.clientId,request:t.request||e.request,scopes:t.auth.scopes||e.scopes});await e.onVerification(r);let i=await Xn(t.request||e.request,e.clientId,e.clientType,r);return e.authentication=i,i}function Jn(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 Yn(e){await new Promise(t=>setTimeout(t,e*1e3))}async function Xn(e,t,n,r){try{let i={clientId:t,request:e,code:r.device_code},{authentication:a}=n===`oauth-app`?await Gn({...i,clientType:`oauth-app`}):await Gn({...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 Yn(r.interval),Xn(e,t,n,r);if(a===`slow_down`)return await Yn(r.interval+7),Xn(e,t,n,r);throw i}}async function Zn(e,t){return qn(e,{auth:t})}async function Qn(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 qn(e,{request:t,auth:{type:`oauth`}});return i.headers.authorization=`token ${a}`,t(i)}var $n=`0.0.0-development`;function er(e){let t=e.request||E.defaults({headers:{"user-agent":`octokit-auth-oauth-device.js/${$n} ${ct()}`}}),{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(Zn.bind(null,i),{hook:Qn.bind(null,i)})}async function tr(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=er({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-BnlRWriT.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 nr(){return process.env.OPEN_KNOWLEDGE_GITHUB_CLIENT_ID??`Ov23liqlSd0V1MwR6rhI`}const rr=new Set([`gitlab.com`,`bitbucket.org`,`codeberg.org`,`gitea.com`,`sr.ht`,`sourcehut.org`]);function U(e){let t=e.toLowerCase().replace(/:\d+$/,``);rr.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 ir(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function ar(e,t,n=tr){let r=nr(),{host:i,json:a}=e;U(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?ir(!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?ir(!0,{type:`complete`,host:i,login:s}):process.stderr.write(`✓ Logged in as ${s} on ${i}\n`)}function or(e){return new t(`login`).description(`Authenticate with GitHub via Device Flow`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{await ar(t,await e())})}const sr=e=>e.name===`enter`||e.name===`return`;var cr=class extends Error{name=`AbortPromptError`;message=`Prompt was aborted`;constructor(e){super(),this.cause=e?.cause}},lr=class extends Error{name=`CancelPromptError`;message=`Prompt was canceled`},ur=class extends Error{name=`ExitPromptError`},dr=class extends Error{name=`HookError`},fr=class extends Error{name=`ValidationError`};const pr=new jn;function mr(e){return{rl:e,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function hr(e,t){let n=mr(e);return pr.run(n,()=>{function e(e){n.handleChange=()=>{n.index=0,e()},n.handleChange()}return t(e)})}function W(){let e=pr.getStore();if(!e)throw new dr(`[Inquirer] Hook functions can only be called from within a prompt`);return e}function gr(){return W().rl}function _r(e){return Mn.bind((...t)=>{let n=W(),r=!1,i=n.handleChange;n.handleChange=()=>{r=!0};let a=e(...t);return r&&i(),n.handleChange=i,a})}function vr(e){let t=W(),{index:n}=t,r=e({get(){return t.hooks[n]},set(e){t.hooks[n]=e},initialized:n in t.hooks});return t.index++,r}function yr(){W().handleChange()}const br={queue(e){let t=W(),{index:n}=t;t.hooksEffect.push(()=>{t.hooksCleanup[n]?.();let r=e(gr());if(r!=null&&typeof r!=`function`)throw new fr(`useEffect return value must be a cleanup function or nothing.`);t.hooksCleanup[n]=r})},run(){let e=W();_r(()=>{e.hooksEffect.forEach(e=>{e()}),e.hooksEffect.length=0})()},clearAll(){let e=W();e.hooksCleanup.forEach(e=>{e?.()}),e.hooksEffect.length=0,e.hooksCleanup.length=0}};function xr(e){return typeof e==`function`}function G(e){return vr(t=>{let n=Mn.bind(function(e){t.get()!==e&&(t.set(e),yr())});if(t.initialized)return[t.get(),n];let r=xr(e)?e():e;return t.set(r),[r,n]})}function Sr(e,t){vr(n=>{let r=n.get();(!Array.isArray(r)||t.some((e,t)=>!Object.is(e,r[t])))&&br.queue(e),n.set(t)})}const Cr={prefix:{idle:H(`blue`,`?`),done:H(`green`,ht.tick)},spinner:{interval:80,frames:[`⠋`,`⠙`,`⠹`,`⠸`,`⠼`,`⠴`,`⠦`,`⠧`,`⠇`,`⠏`].map(e=>H(`yellow`,e))},style:{answer:e=>H(`cyan`,e),message:e=>H(`bold`,e),error:e=>H(`red`,`> ${e}`),defaultAnswer:e=>H(`dim`,`(${e})`),help:e=>H(`dim`,e),highlight:e=>H(`cyan`,e),key:e=>H(`cyan`,H(`bold`,`<${e}>`))}};function wr(e){if(typeof e!=`object`||!e)return!1;let t=e;for(;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function Tr(...e){let t={};for(let n of e)for(let[e,r]of Object.entries(n)){let n=t[e];t[e]=wr(n)&&wr(r)?Tr(n,r):r}return t}function Er(...e){return Tr(Cr,...e.filter(e=>e!=null))}function Dr({status:e=`idle`,theme:t}){let[n,r]=G(!1),[i,a]=G(0),{prefix:o,spinner:s}=Er(t);return Sr(()=>{if(e===`loading`){let e,t=-1,n=setTimeout(()=>{r(!0),e=setInterval(()=>{t+=1,a(t%s.frames.length)},s.interval)},300);return()=>{clearTimeout(n),clearInterval(e)}}else r(!1)},[e]),n?s.frames[i]:typeof o==`string`?o:o[e===`loading`?`idle`:e]??o.idle}function Or(e){return G({current:e})[0]}function kr(e){let t=Or(e);t.current=e,Sr(e=>{let n=!1,r=_r((r,i)=>{n||t.current(i,e)});return e.input.on(`keypress`,r),()=>{n=!0,e.input.removeListener(`keypress`,r)}},[])}var Ar=e(mt(),1);function jr(e,t){return e.split(`
4
4
  `).flatMap(e=>pt(e,t,{trim:!1,hard:!0}).split(`
5
5
  `).map(e=>e.trimEnd())).join(`
@@ -19,9 +19,9 @@ import{s as e}from"./chunk-C94x7I9S.mjs";import{t}from"./esm-BLMtE3s6.mjs";impor
19
19
  `),patterns:[...t],lineCount:n}}const Zi=B(_n(),`.ok`,`logs`),Qi=B(_n(),`.ok`,`bug-reports`);function $i(e){let t=B(e,`.ok`,`config.yml`);if(F(t))try{let e=L(t,`utf8`).match(/^\s*name:\s*['"]?(.+?)['"]?\s*$/m);if(e?.[1])return e[1]}catch{}return F(B(e,`.ok`))?En(`sha256`).update(V(e)).digest(`hex`).slice(0,12):null}function ea(){let e={timestamp:new Date().toISOString(),platform:vn(),osType:Sn(),osRelease:yn(),hostname:`[redacted]`,uptime:Cn(),freeMem:gn(),totalMem:xn(),nodeVersion:process.version,bunVersion:process.versions.bun??null,v8Version:process.versions.v8??null,pid:process.pid};try{e.macosVersion=Xt(`sw_vers -productVersion 2>/dev/null`,{encoding:`utf8`}).trim()}catch{}try{let t=B(__dirname,`..`,`..`,`package.json`);F(t)&&(e.okVersion=JSON.parse(L(t,`utf8`)).version)}catch{}return e}function ta(e){if(!F(Zi))return{files:[],dir:Zi};let t=an(Zi).filter(e=>e.endsWith(`.log`)||/\.log\.\d+$/.test(e)).map(e=>B(Zi,e));if(e&&t.length>0){let n=t.filter(t=>{try{return L(t,`utf8`).includes(`"project":"${e}"`)}catch{return!0}});n.length>0&&(t=n)}return{files:t,dir:Zi}}function na(e){let t=B(e,`.ok`,`local`);return F(t)?{files:[`server.lock`,`last-spawn-error.log`].map(e=>B(t,e)).filter(e=>F(e)),dir:t}:{files:[],dir:null}}function ra(e){let t=B(e,`.ok`,`local`,`logs`);return F(t)?{files:[`server-current.jsonl`,`server-prev.jsonl`].map(e=>B(t,e)).filter(e=>F(e)),dir:t}:{files:[],dir:null}}async function ia(t){let n=Ku();I(Qi,{recursive:!0});let r=B(Qi,`${new Date().toISOString().replace(/[:.]/g,`-`)}-bugreport.zip`);n?.info({projectSlug:t.projectSlug},`gathering diagnostic data`);let i=ea(),{files:a}=ta(t.projectSlug),{files:o}=na(t.cwd),{files:s}=ra(t.cwd);n?.info({logFileCount:a.length,lockFileCount:o.length,localSinkFileCount:s.length},`files collected`);let c=[],l=[],{ZipFile:u}=await import(`./yazl-CQSNnbvt.mjs`).then(t=>e(t.default,1)),d=new u;for(let e of a)try{let{redacted:t,patterns:n,lineCount:r}=Xi(L(e,`utf8`)),i=`logs/${z(e)}`;d.addBuffer(Buffer.from(t,`utf8`),i),l.push(i),n.length>0&&c.push({file:i,lineCount:r,patterns:n})}catch{}for(let e of o)try{let{redacted:t,patterns:n,lineCount:r}=Xi(L(e,`utf8`)),i=`lockdir/${z(e)}`;d.addBuffer(Buffer.from(t,`utf8`),i),l.push(i),n.length>0&&c.push({file:i,lineCount:r,patterns:n})}catch{}for(let e of s)try{let{redacted:t,patterns:n,lineCount:r}=Xi(L(e,`utf8`)),i=`local-logs/${z(e)}`;d.addBuffer(Buffer.from(t,`utf8`),i),l.push(i),n.length>0&&c.push({file:i,lineCount:r,patterns:n})}catch{}let f=JSON.stringify(i,null,2);d.addBuffer(Buffer.from(f,`utf8`),`sysinfo.json`),l.push(`sysinfo.json`);let p={generatedAt:new Date().toISOString(),disciplineVersion:`1.0.0`,projectSlug:t.projectSlug,files:l,redactions:c,sysinfo:i};d.addBuffer(Buffer.from(JSON.stringify(p,null,2),`utf8`),`MANIFEST.json`);let m=c.reduce((e,t)=>e+t.lineCount,0),h=[`# Bug Report Bundle`,``,`Generated: ${p.generatedAt}`,`Project: ${t.projectSlug??`(unscoped)`}`,`Discipline version: ${p.disciplineVersion}`,``,`## Contents`,``,...l.map(e=>`- ${e}`),``,`## Privacy`,``,`This bundle was auto-redacted before packaging.`,`Patterns checked: ${Yi.join(`, `)}`,m>0?`${m} line(s) were scrubbed across ${c.length} file(s).`:`No redactions were needed.`,`See MANIFEST.json for the full redaction audit report.`,``,`This bundle is safe to attach to a GitHub issue.`].join(`
20
20
  `);d.addBuffer(Buffer.from(h,`utf8`),`README.md`),d.end();let g=tn(r);if(d.outputStream.pipe(g),await new Promise((e,t)=>{g.on(`close`,e),g.on(`error`,t)}),n?.info({bundlePath:r,fileCount:l.length,redactionCount:m},`bundle written`),process.stdout.write(`${r}\n`),m>0&&process.stderr.write(`ok bug-report: ${m} line(s) auto-redacted across ${c.length} file(s)\n`),!t.noReveal&&vn()===`darwin`)try{N(`/usr/bin/open`,[`-R`,r],{detached:!0,stdio:`ignore`}).unref()}catch{}return r}function aa(){return new t(`bug-report`).description(`Generate a diagnostic bundle for bug reporting`).option(`--reveal`,`Reveal the bundle in Finder (default: true)`,!0).option(`--no-reveal`,`Do not reveal the bundle in Finder`).action(async e=>{let t=process.cwd(),n=$i(t);try{await ia({projectSlug:n,cwd:t,noReveal:!e.reveal})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`ok bug-report: failed — ${t}\n`),process.exitCode=1}})}function oa(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 sa(e){let t=e.inspect??(t=>At(e.lockDir,t)),n=e.unlink??(e=>ln(e)),r=e.log??(e=>console.log(e)),i=e.error??(e=>console.error(e)),a=oa(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 ca(e){return new t(`clean`).description(`Prune stale / corrupt open-knowledge lock files (never touches live locks)`).action(()=>{e(),sa({lockDir:Se(process.cwd())}).failed.length>0&&(process.exitCode=1)})}async function la(e,t,n={},r=ae){if(!n.skipGhDetect&&r().available)return{tier:`A`,credentialArgs:[`-c`,`credential.helper=!gh auth git-credential`]};let i=await t.get(e);return i==null?{tier:`none`,credentialArgs:[]}:{tier:i.gitProtocol===`ssh`?`C`:`B`,credentialArgs:[`-c`,`credential.helper=!open-knowledge auth git-credential`]}}async function ua(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 da=[[`count`,0,10],[`compress`,10,20],[`receiv`,20,60],[`resolv`,60,100]];function fa(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 da)if(n.includes(e))return{stage:t[1],pct:Math.round(i+r/100*(a-i))};return null}function J(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}function pa(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 ma(e){return typeof e!=`string`||e.length===0?[`--progress`]:[`--progress`,`-b`,e]}const ha=i;async function ga(e){try{return await e.clone(ma(e.branch)),{fellBack:!1}}catch(t){if(e.branch!==null&&ha(t))return e.onFallback(e.branch),await e.clone(ma(null)),{fellBack:!0};throw t}}function _a(e,t){return{baseDir:e,config:t,unsafe:{allowUnsafeCredentialHelper:!0,allowUnsafePager:!0,allowUnsafeSshCommand:!0,allowUnsafeAskPass:!0}}}function va(e,t,n){return e===`https`&&t===`github.com`&&n}function ya(e,t){let n=`${t.owner}/${t.name}`;return e===n||e===`${n}.git`?`https://${t.hostname}/${n}`:e}async function ba(e,t,n,r=process.cwd()){let i=Nt(e);if(!i)throw Error(`Invalid git URL: ${e}`);let a=ya(e,i),o=t.dir?V(r,t.dir):V(r,i.name);if(F(o)&&an(o).length>0)throw Error(`Target directory is not empty: ${o}`);let s=ne(),c=i.protocol===`https`&&i.hostname===`github.com`?await ua(i.owner,i.name):!1,l=va(i.protocol,i.hostname,c)?{tier:`none`,credentialArgs:[]}:await la(i.hostname,s,{}),u=pa(),d=oe(_a(r,l.credentialArgs.length>=2?[l.credentialArgs[1]]:[])).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(`
21
21
  `)){let n=fa(e);n&&n.pct!==f&&(f=n.pct,J(t.json,{type:`progress`,pct:n.pct,stage:n.stage}),t.json||process.stderr.write(`\r Cloning ${n.pct}%`))}})}),await ga({branch:typeof t.branch==`string`&&t.branch.length>0?t.branch:null,clone:e=>d.clone(a,o,e),onFallback:e=>{J(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(`
22
- `);try{let{runInit:e}=await import(`./init-B8ThmEDv.mjs`),n=await e({cwd:o,mcp:!1});if(n.contentUpdated.length>0){let e=`auto-init: updated ${n.contentUpdated.join(`, `)}`;t.json?J(!0,{type:`warning`,message:e}):process.stderr.write(` ${e}\n`)}}catch(e){let n=e instanceof Error?e.message:String(e);t.json?J(!0,{type:`warning`,message:`auto-init: ${n}`}):process.stderr.write(` auto-init: ${n}\n`)}try{xa(o)}catch(e){let n=e instanceof Error?e.message:String(e);t.json?J(!0,{type:`warning`,message:`git-exclude: ${n}`}):process.stderr.write(` git-exclude: ${n}\n`)}return o}function xa(e){let t=St(e,[`.ok/`]);return t.kind===`no-exclude`?`no-exclude`:t.kind===`refused-tracked`?`already-present`:t.appended.length>0?`appended`:`already-present`}const Sa=/^[A-Za-z0-9._/:@-]+$/;function Ca(e){return Sa.test(e)?e:_(e)}function wa(e,t){let n=typeof t==`string`&&t.length>0?` -b ${Ca(t)}`:``;return`ok clone ${Ca(e)}${n}`}function Ta(e){let t=ee(e.error);if(t.kind!==`auth`)return null;if(te(t)){let t=wa(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(`
22
+ `);try{let{runInit:e}=await import(`./init-C7uBoTEn.mjs`),n=await e({cwd:o,mcp:!1});if(n.contentUpdated.length>0){let e=`auto-init: updated ${n.contentUpdated.join(`, `)}`;t.json?J(!0,{type:`warning`,message:e}):process.stderr.write(` ${e}\n`)}}catch(e){let n=e instanceof Error?e.message:String(e);t.json?J(!0,{type:`warning`,message:`auto-init: ${n}`}):process.stderr.write(` auto-init: ${n}\n`)}try{xa(o)}catch(e){let n=e instanceof Error?e.message:String(e);t.json?J(!0,{type:`warning`,message:`git-exclude: ${n}`}):process.stderr.write(` git-exclude: ${n}\n`)}return o}function xa(e){let t=St(e,[`.ok/`]);return t.kind===`no-exclude`?`no-exclude`:t.kind===`refused-tracked`?`already-present`:t.appended.length>0?`appended`:`already-present`}const Sa=/^[A-Za-z0-9._/:@-]+$/;function Ca(e){return Sa.test(e)?e:_(e)}function wa(e,t){let n=typeof t==`string`&&t.length>0?` -b ${Ca(t)}`:``;return`ok clone ${Ca(e)}${n}`}function Ta(e){let t=ee(e.error);if(t.kind!==`auth`)return null;if(te(t)){let t=wa(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(`
23
23
  `)}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: ${wa(e.url,e.branch)}`].join(`
24
- `)}function Ea(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=Ta({error:e.error,url:e.url,branch:e.branch,principal:e.principal});e.printStderr(`${n??`✗ ${t}`}\n`)}async function Da(e,t){let n=(await e.get(t))?.login;return n&&n!==`unknown`?n:null}async function Oa(e){let t=ee(e.error),n=null;if(!e.json&&t.kind===`auth`&&t.subclass===`403`){let t=Nt(e.url);t&&(n=await(e.resolvePrincipal??(e=>Da(ne(),e)))(t.hostname))}Ea({error:e.error,url:e.url,branch:e.branch,json:e.json,principal:n,emit:e.emit,printStderr:e.printStderr})}function ka(e){return new t(`clone`).description(`Clone a git repository and open it`).argument(`<url>`,`Repository URL or owner/repo shorthand`).argument(`[dir]`,`Target directory (default: ./<repo-name>)`).option(`--json`,`Output JSONL progress events`,!1).option(`-b, --branch <branch>`,`Branch to check out (falls back to default if missing)`).action(async(t,n,r)=>{let i=e();try{let a=await ba(t,{json:r.json,dir:n,branch:r.branch??null},i);if(r.json)J(!0,{type:`complete`,dir:a});else{process.stderr.write(`✓ Cloned to ${a}\n`),process.chdir(a);let{startCommand:t}=await import(`./start-BrzdwifC.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){await Oa({error:e,url:t,branch:r.branch??null,json:r.json,emit:e=>J(!0,e),printStderr:e=>process.stderr.write(e)}),process.exitCode=1}})}var Aa=s();const ja=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],[`server`,`port`],...o.map(e=>e.path)];function Ma(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??zt;try{let{sources:n}=r(e.cwd);return t(`✓ Configuration valid (sources: ${n.length===0?`defaults only`:n.join(`, `)})`),{ok:!0}}catch(e){return n(e instanceof Error?e.message:String(e)),{ok:!1}}}function Na(e){let t=(0,Aa.parseDocument)(L(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 ja)t.hasIn(e)&&n.push(e.join(`.`));return n}function Pa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Fa(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=Pa(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}async function Ia(e={}){let t=e.log??(e=>console.log(e)),n=e.error??(e=>console.error(e)),r=e.scope??`both`,i=e.dryRun??!1,a=e.cwd??process.cwd(),o=e.writeConfigPatchFn??Fe,s=[];(r===`project`||r===`both`)&&s.push({scope:`project`,absPath:He(`project`,a,e.homedirOverride)}),(r===`user`||r===`both`)&&s.push({scope:`user`,absPath:He(`user`,a,e.homedirOverride)});let c=[],l=!0;for(let{scope:t,absPath:n}of s){if(!F(n)){c.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=Na(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:Fa(ja.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!s.ok){c.push({path:n,scope:t,found:r,removed:[],error:u(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 d=c.some(e=>e.error!==void 0),f=c.reduce((e,t)=>e+t.found.length,0);if(f===0&&!d)t(`No deprecated fields found.`);else if(f>0)for(let e of c)e.error||(e.found.length===0?t(` ${e.path}: no deprecated fields`):t(i?`[dry-run] ${e.path}: would remove ${e.found.length} field(s): ${e.found.join(`, `)}`:`✓ ${e.path}: removed ${e.removed.length} field(s): ${e.removed.join(`, `)}`));return{outcomes:c,ok:l}}function La(){let e=new t(`config`).description(`Inspect and maintain OpenKnowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{Ma({}).ok||(process.exitCode=1)}),e.command(`migrate`).description(`Remove deprecated config fields from config.yml idempotently (every removed key in the registry — content.*, folders, appearance.editorModeDefault, server.host, etc. — plus the silently-dropped sync.*, persistence.*, server.port)`).option(`--scope <scope>`,`Which scope to migrate: project | user | both`,`both`).option(`--dry-run`,`Preview without writing`,!1).action(async e=>{let t=e.scope;if(t!==`project`&&t!==`user`&&t!==`both`){console.error(`Invalid --scope: ${t}. Expected: project | user | both`),process.exitCode=2;return}(await Ia({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}const Ra=[` 1. ${M(`Customize`)} (sidebar) → ${M(`Skills`)}`,` 2. Click the ${M(`+`)} button`,` 3. Click ${M(`Create skill`)}`,` 4. Click ${M(`Upload skill`)}`,` 5. Pick ${M(`openknowledge.skill`)} from Downloads`],za=D(` Open the Claude Desktop App, then: ${M(`Customize → Skills → + → Create skill → Upload skill`)} → pick the file.`);function Ba(e){let t=[k(`Built ${e.outputPath}`),O(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…`)];return e.handoffError&&t.push(j(` Handoff failed: ${e.handoffError.message}`)),t.push(za),t.join(`
24
+ `)}function Ea(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=Ta({error:e.error,url:e.url,branch:e.branch,principal:e.principal});e.printStderr(`${n??`✗ ${t}`}\n`)}async function Da(e,t){let n=(await e.get(t))?.login;return n&&n!==`unknown`?n:null}async function Oa(e){let t=ee(e.error),n=null;if(!e.json&&t.kind===`auth`&&t.subclass===`403`){let t=Nt(e.url);t&&(n=await(e.resolvePrincipal??(e=>Da(ne(),e)))(t.hostname))}Ea({error:e.error,url:e.url,branch:e.branch,json:e.json,principal:n,emit:e.emit,printStderr:e.printStderr})}function ka(e){return new t(`clone`).description(`Clone a git repository and open it`).argument(`<url>`,`Repository URL or owner/repo shorthand`).argument(`[dir]`,`Target directory (default: ./<repo-name>)`).option(`--json`,`Output JSONL progress events`,!1).option(`-b, --branch <branch>`,`Branch to check out (falls back to default if missing)`).action(async(t,n,r)=>{let i=e();try{let a=await ba(t,{json:r.json,dir:n,branch:r.branch??null},i);if(r.json)J(!0,{type:`complete`,dir:a});else{process.stderr.write(`✓ Cloned to ${a}\n`),process.chdir(a);let{startCommand:t}=await import(`./start-C0Mpznab.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){await Oa({error:e,url:t,branch:r.branch??null,json:r.json,emit:e=>J(!0,e),printStderr:e=>process.stderr.write(e)}),process.exitCode=1}})}var Aa=s();const ja=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],[`server`,`port`],...o.map(e=>e.path)];function Ma(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??zt;try{let{sources:n}=r(e.cwd);return t(`✓ Configuration valid (sources: ${n.length===0?`defaults only`:n.join(`, `)})`),{ok:!0}}catch(e){return n(e instanceof Error?e.message:String(e)),{ok:!1}}}function Na(e){let t=(0,Aa.parseDocument)(L(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 ja)t.hasIn(e)&&n.push(e.join(`.`));return n}function Pa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Fa(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=Pa(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}async function Ia(e={}){let t=e.log??(e=>console.log(e)),n=e.error??(e=>console.error(e)),r=e.scope??`both`,i=e.dryRun??!1,a=e.cwd??process.cwd(),o=e.writeConfigPatchFn??Fe,s=[];(r===`project`||r===`both`)&&s.push({scope:`project`,absPath:He(`project`,a,e.homedirOverride)}),(r===`user`||r===`both`)&&s.push({scope:`user`,absPath:He(`user`,a,e.homedirOverride)});let c=[],l=!0;for(let{scope:t,absPath:n}of s){if(!F(n)){c.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=Na(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:Fa(ja.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!s.ok){c.push({path:n,scope:t,found:r,removed:[],error:u(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 d=c.some(e=>e.error!==void 0),f=c.reduce((e,t)=>e+t.found.length,0);if(f===0&&!d)t(`No deprecated fields found.`);else if(f>0)for(let e of c)e.error||(e.found.length===0?t(` ${e.path}: no deprecated fields`):t(i?`[dry-run] ${e.path}: would remove ${e.found.length} field(s): ${e.found.join(`, `)}`:`✓ ${e.path}: removed ${e.removed.length} field(s): ${e.removed.join(`, `)}`));return{outcomes:c,ok:l}}function La(){let e=new t(`config`).description(`Inspect and maintain OpenKnowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{Ma({}).ok||(process.exitCode=1)}),e.command(`migrate`).description(`Remove deprecated config fields from config.yml idempotently (every removed key in the registry — content.*, folders, appearance.editorModeDefault, server.host, etc. — plus the silently-dropped sync.*, persistence.*, server.port)`).option(`--scope <scope>`,`Which scope to migrate: project | user | both`,`both`).option(`--dry-run`,`Preview without writing`,!1).action(async e=>{let t=e.scope;if(t!==`project`&&t!==`user`&&t!==`both`){console.error(`Invalid --scope: ${t}. Expected: project | user | both`),process.exitCode=2;return}(await Ia({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}const Ra=[` 1. ${M(`Customize`)} (sidebar) → ${M(`Skills`)}`,` 2. Click the ${M(`+`)} button`,` 3. Click ${M(`Create skill`)}`,` 4. Click ${M(`Upload skill`)}`,` 5. Pick ${M(`openknowledge.skill`)} from Downloads`],za=D(` Open the Claude Desktop App, then: ${M(`Customize → Skills → + → Create skill → Upload skill`)} → pick the file.`);function Ba(e){let t=[k(`Built ${e.outputPath}`),O(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…`)];return e.handoffError&&t.push(j(` Handoff failed: ${e.handoffError.message}`)),t.push(za),t.join(`
25
25
  `)}function Va(e){let t=e.skillVersion??`unknown`,n=e.recordedAt??`unknown`;return[D(`OpenKnowledge skill ${M(`v${t}`)} already delivered to Claude Desktop.`),O(` Recorded at ${n} in ~/.ok/skill-state.yml`),O(` Use ${M(`--force`)} to rebuild and re-open the install dialog.`)].join(`
26
26
  `)}function Ha(e){let t=e.skillVersion?` • Skill v${e.skillVersion}`:``;return[k(`Built ${e.outputPath}`),O(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…${t}`),D(` Claude Desktop App opened. Now upload the file manually:`),...Ra,O(` If Claude Desktop didn't open, open it and start at step 1. The file is at ${e.outputPath}`)].join(`
27
27
  `)}function Ua(e){return`${A(`Error:`)} ${e.buildError??`unknown build failure`}`}async function Wa(e={}){let t=await rt(e);return t.status===`failed`?{...t,message:Ua(t),exitCode:1}:t.status===`skip-current`?{...t,message:Va(t),exitCode:0}:t.status===`installed`?{...t,message:Ha(t),exitCode:0}:{...t,message:Ba(t),exitCode:0}}function Ga(){return new t(`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 Wa({out:e.out,noOpen:!e.open,force:e.force??!1});process.stdout.write(`${t.message}\n`),t.exitCode!==0&&process.exit(t.exitCode)})}var Ka=e(ot(),1),Y=e(Vt(),1);const qa=new Set([`doc.name`]);function Ja(e){return`doc:${En(`blake2b512`,{outputLength:32}).update(e).digest(`hex`).slice(0,8)}`}function Ya(e,t,n){let r=e.docNameMap[n];if(r===void 0){e.docNameMap[n]=t;return}if(r===t)return;let i=e.docNameCollisions[n];i?i.includes(t)||i.push(t):e.docNameCollisions[n]=[t]}function Xa(e,t){let n=t.originalToHashed.get(e);if(n!==void 0)return n;let r=Ja(e);return t.originalToHashed.set(e,r),Ya(t,e,r),r}function Za(e,t){return t.length===0||!e.includes(t)?e:e.split(t).join(`<CONTENT_DIR>`)}function Qa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function $a(e,t){if(typeof e==`string`)return Za(e,t.contentDir);if(Array.isArray(e))return e.map(e=>$a(e,t));if(!Qa(e))return e;let n=typeof e.key==`string`&&qa.has(e.key)&&Qa(e.value)&&typeof e.value.stringValue==`string`?e.value.stringValue:null,r={};for(let[i,a]of Object.entries(e))if(n!==null&&i===`value`&&Qa(a)){let e=Xa(n,t);r[i]={...a,stringValue:e}}else qa.has(i)&&typeof a==`string`?r[i]=Xa(a,t):r[i]=$a(a,t);return r}function eo(e,t){if(t.originalToHashed.size===0)return e;let n=Array.from(t.originalToHashed.entries()).sort(([e],[t])=>t.length-e.length),r=e;for(let[e,t]of n)e.length!==0&&r.includes(e)&&(r=r.split(e).join(t));return r}function to(e,t){let n=L(e,`utf-8`);if(n.length===0)return;let r=n.endsWith(`
@@ -55,7 +55,7 @@ ws.addEventListener('error', () => process.exit(1));
55
55
  setTimeout(() => process.exit(2), ${t+1e4});
56
56
  `),r}async function ps(e,t,n,r,i){let a=fs(e,t,B(r,`cpu.cpuprofile`)),o=!1,s=N(process.execPath,[a],{stdio:`ignore`}),c=setInterval(()=>{let e=cs(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{sn(B(a,`..`),{recursive:!0,force:!0})}catch{}return o}function ms(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(`
57
57
  `)}async function hs(e,t={}){let{pid:n,cpuProfileSecs:r=15,noInspector:i=!1}=e,a=t.log??(e=>console.log(e)),o=t.discover??kt,s=t.inspect??At,c=t.resolveCommand??Mt,l=t.resolveUsage??It,u=t.collectLsofFn??ls,d=t.getEndpoints??ds,f=t.profiler??ps,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?B(v,`.ok`,`local`,`diagnostics`,`process-${n}-${b}`):B(process.cwd(),`ok-diagnose-${n}-${b}`);try{I(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)=>{R(B(x,e),t),a(` wrote ${e}`)},ee=c(n),C=l(n);S(`metadata.json`,JSON.stringify({capturedAt:new Date().toISOString(),pid:n,command:ee,usage:C,lockInfo:y},null,2)),a(` sampling lsof`);let w=u(n);if(w&&S(`lsof.txt`,w),!i){let e=w?us(w).find(e=>e>=9229&&e<=9299)??9229:9229,t=d(e);if(!t||t.length===0){a(` no inspector on :${e}, sending SIGUSR1 to pid ${n}`);try{m(n,`SIGUSR1`),await h(2e3),t=d(e)}catch(e){a(Y.default.yellow(` SIGUSR1 delivery failed: ${e.message}`))}}if(t&&t.length>0){S(`inspector-endpoints.json`,JSON.stringify(t,null,2));let e=t[0].webSocketDebuggerUrl;if(e){a(` capturing ${r}s CPU profile`);let t=[];await f(e,g,n,x,e=>t.push(e))?a(` wrote cpu.cpuprofile`):a(Y.default.yellow(` CPU profile capture failed`)),t.length>0&&S(`process-stats.jsonl`,`${t.map(e=>JSON.stringify(e)).join(`
58
- `)}\n`);try{S(`stacks.txt`,ms(L(B(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 gs(e){let t=Pn({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function _s(e){let t=nn(B(bn(),`ok-bundle-process-`));return await hs({pid:e,output:t}),t}function vs(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 ys(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function bs(e,t,n){let{summary:r,manifest:i}=t;e(``),e(Y.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${vs(r.totalBytes)} uncompressed`),e(` doc.name attributes: ${r.docNameCount} occurrence(s) in telemetry${r.redacted?` (values hashed)`:``}`),e(` Content-dir path: ${r.contentDirVisible?`visible (${i.contentDir.absolutePath})`:`not visible`}`),e(` Redacted: ${r.redacted?`yes`:`no`}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function xs(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??gs,i=t.runProcessDiagnose??_s,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=dn(o);if(!F(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=B(e.contentDir,`.ok`,`local`,`diagnostics`);I(n,{recursive:!0}),o=B(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(Y.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await Lo({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(Y.default.yellow(` server not running — live state unavailable`)),bs(n,c,o),e.yes!==!0&&!ys(await r(`Write bundle? [y/N]: `))?(n(Y.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await Ro({collected:c,outputPath:o}),n(Y.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{sn(s,{recursive:!0,force:!0})}catch{}}}function Ss(){let e=new t(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(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 hs({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(ss()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--redact`,`Hash doc names and strip the content-dir prefix from the staged bundle`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(Y.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-B4XVtshT.mjs`),{resolveContentDir:r}=await import(`./dist-DVWyQ2rE.mjs`),i=process.cwd(),{config:a}=n(i);await xs({contentDir:r(a,i),projectDir:i,pid:t,out:e.out,yes:e.yes===!0,redact:e.redact===!0})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(Y.default.red(t)),process.exit(1)}}),e}async function Cs(){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 Hr({message:`Enter OpenAI embeddings API key:`})).trim()}function ws(e){return ye(e)}async function Ts(){return(await Ue()).file?{present:!0,source:`file`}:process.env.OK_EMBEDDINGS_API_KEY?{present:!0,source:`env`}:{present:!1,source:null}}async function Es(e){try{let t=g(Se(e));if(!t||t.port<=0||!w(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 Ds(){return new t(`set-key`).description(`Store your OpenAI embeddings API key in ~/.ok/secrets.yml`).action(async()=>{let e=await Cs();if(!e){process.stderr.write(`No key provided.
58
+ `)}\n`);try{S(`stacks.txt`,ms(L(B(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 gs(e){let t=Pn({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function _s(e){let t=nn(B(bn(),`ok-bundle-process-`));return await hs({pid:e,output:t}),t}function vs(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 ys(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function bs(e,t,n){let{summary:r,manifest:i}=t;e(``),e(Y.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${vs(r.totalBytes)} uncompressed`),e(` doc.name attributes: ${r.docNameCount} occurrence(s) in telemetry${r.redacted?` (values hashed)`:``}`),e(` Content-dir path: ${r.contentDirVisible?`visible (${i.contentDir.absolutePath})`:`not visible`}`),e(` Redacted: ${r.redacted?`yes`:`no`}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function xs(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??gs,i=t.runProcessDiagnose??_s,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=dn(o);if(!F(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=B(e.contentDir,`.ok`,`local`,`diagnostics`);I(n,{recursive:!0}),o=B(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(Y.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await Lo({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(Y.default.yellow(` server not running — live state unavailable`)),bs(n,c,o),e.yes!==!0&&!ys(await r(`Write bundle? [y/N]: `))?(n(Y.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await Ro({collected:c,outputPath:o}),n(Y.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{sn(s,{recursive:!0,force:!0})}catch{}}}function Ss(){let e=new t(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(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 hs({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(ss()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--redact`,`Hash doc names and strip the content-dir prefix from the staged bundle`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(Y.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-Br4O9l2c.mjs`),{resolveContentDir:r}=await import(`./dist-lMD2xM96.mjs`),i=process.cwd(),{config:a}=n(i);await xs({contentDir:r(a,i),projectDir:i,pid:t,out:e.out,yes:e.yes===!0,redact:e.redact===!0})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(Y.default.red(t)),process.exit(1)}}),e}async function Cs(){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 Hr({message:`Enter OpenAI embeddings API key:`})).trim()}function ws(e){return ye(e)}async function Ts(){return(await Ue()).file?{present:!0,source:`file`}:process.env.OK_EMBEDDINGS_API_KEY?{present:!0,source:`env`}:{present:!1,source:null}}async function Es(e){try{let t=g(Se(e));if(!t||t.port<=0||!w(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 Ds(){return new t(`set-key`).description(`Store your OpenAI embeddings API key in ~/.ok/secrets.yml`).action(async()=>{let e=await Cs();if(!e){process.stderr.write(`No key provided.
59
59
  `),process.exitCode=1;return}await De().set(e),process.stderr.write(`✓ OpenAI embeddings API key stored in ~/.ok/secrets.yml (0600, this machine only).
60
60
  Now enable it per project — the easiest path is OK Desktop → Settings → This
61
61
  project → Search (a toggle with an egress-confirmation prompt), or run
@@ -72,7 +72,7 @@ project → Search (a toggle with an egress-confirmation prompt), or run
72
72
  `).filter(e=>e.startsWith(`worktree `)).length}catch{return 0}}function Fl(e){let t=V(e);for(;;){if(Ae(t))return t;let n=dn(t);if(n===t)throw Error(`No OpenKnowledge project found at or above ${e}. Pass an explicit \`cwd\` argument that points inside an OK project (a directory with a \`${r}\`).`);t=n}}function Il(e){try{let t=new URL(e);return t.protocol===`file:`?wn(t):void 0}catch{return}}async function Ll(e){if(!e.getClientCapabilities()?.roots)return;let t;try{t=await e.listRoots()}catch(t){e.log?.(`listRoots fallback failed: ${t instanceof Error?t.message:String(t)}`);return}let n=t.roots??[];if(n.length!==1)return;let r=Il(n[0].uri);return r===void 0&&e.log?.(`single root URI not usable as fs path: ${n[0].uri}`),r}async function Rl(e,t,n,r=Fl){if(e!==void 0){let t=r(e);return{projectDir:t,viaRootGuess:!1,nextSticky:t}}if(t!==void 0){let e=r(t);return{projectDir:e,viaRootGuess:!1,nextSticky:e}}let i=await n();return i===void 0?{projectDir:void 0,viaRootGuess:!1,nextSticky:void 0}:{projectDir:r(i),viaRootGuess:!0,nextSticky:void 0}}async function zl(e){let t=process.stderr,n=e.spawnTimeoutMs??_l(process.env.OK_MCP_SPAWN_TIMEOUT_MS),r=e.envAutoStart??process.env.OK_MCP_AUTOSTART,i=Bt({startupCwd:e.startupCwd,startupConfig:e.startupConfig}),a=new tt({name:f,version:S});ge(a);let o=Dn(),s={current:{connectionId:o,displayName:o,colorSeed:o}},c=new Map,l=e=>{if(c.has(e))return;let n=ce(e),r=s.current,i=Rs({connectionId:o,displayName:r.displayName,clientName:r.clientInfo?.name??r.displayName,colorSeed:r.colorSeed,resolveWsUrl:async()=>kl({lockDir:n,contentDir:e},``),log:n=>t.write(`[mcp] keepalive[${e}]: ${n}\n`)});c.set(e,i)},u=()=>Ll({getClientCapabilities:()=>a.server.getClientCapabilities(),listRoots:()=>a.server.listRoots(),log:e=>t.write(`[mcp] ${e}\n`)}),d,p=!1,m=async e=>{if(p)return;p=!0;let n=await Pl(e);if(n<=1){p=!1;return}let r=`Routed to ${e} from the MCP client's single advertised root, but this repo has ${n} git worktrees. If you are working in a worktree, pass its path as \`cwd\` on OK tool calls once — it sticks for the session, so reads, writes, and the preview all target that worktree instead of this checkout.`;try{t.write(`[mcp] ${r}\n`),await a.server.sendLoggingMessage({level:`warning`,data:r})}catch{}},h=async e=>{let t=await Rl(e,d,u);if(d=t.nextSticky??d,t.projectDir===void 0)throw Error("`cwd` is required for tool calls against the global MCP server. Pass an absolute path inside an OpenKnowledge project, or have the MCP client advertise a single root.");return t.viaRootGuess&&m(t.projectDir),t.projectDir},g=async e=>{let t=await Rl(e,d,u);if(d=t.nextSticky??d,t.projectDir===void 0)return;t.viaRootGuess&&m(t.projectDir);let a=t.projectDir,o=await i(a),s=await Ol({lockDir:ce(a),contentDir:Te(o,a),envAutoStart:r,...n===void 0?{}:{timeoutMs:n}});return l(a),s.replace(/\/mcp$/,``)};a.server.oninitialized=()=>{let e=a.server.getClientVersion(),t=Ge(e?.name,o);s.current={connectionId:o,clientInfo:e?{name:t,version:e.version}:void 0,displayName:t,colorSeed:t}},Ce(a,{serverUrl:g,resolveCwd:h,config:i,identityRef:s});let _=new Hs,v=!1,y,b,x=async()=>{if(v)return;v=!0,y?.stop(),b?.stop();for(let e of c.values())try{e.close()}catch(e){t.write(`[mcp] keepalive close error: ${e instanceof Error?e.message:String(e)}\n`)}c.clear();let e=await Promise.allSettled([a.close(),_.close()]);for(let n of e)if(n.status===`rejected`){let e=n.reason;t.write(`[mcp] shutdown close error: ${e instanceof Error?e.message:String(e)}\n`)}};await a.connect(_),t.write(`[mcp] global stdio server ready (per-call project routing)
73
73
  `);let ee=!1,C=()=>{ee||(ee=!0,setTimeout(()=>{t.write(`[mcp] shutdown deadline (5s) reached — forcing exit(1)
74
74
  `),process.exit(1)},5e3).unref(),x().finally(()=>{process.exit(0)}))};if(process.once(`SIGINT`,C),process.once(`SIGTERM`,C),process.stdin.on(`end`,()=>{t.write(`[mcp] stdin end — host disconnected, shutting down
75
- `),C()}),process.stdin.on(`error`,e=>{t.write(`[mcp] stdin error (${e instanceof Error?e.message:String(e)}) — host disconnected, shutting down\n`),C()}),b=Ks({getPpid:()=>process.ppid,onHostGone:e=>{t.write(`[mcp] ${e} — shutting down\n`),C()}}),qs({log:e=>t.write(`${e}\n`),transport:_,process,stdin:process.stdin}),process.platform===`darwin`){let e=Gs(Ml,{realpathSync:on,statInoSync:e=>cn(e).ino,log:e=>t.write(`${e}\n`)});if(e!==void 0){t.write(`[mcp] bundle identity anchor=${e.resolvedPath} inode=${e.inode} version=${S}\n`);let{resolvedPath:n,inode:r}=e;y=Ws({detect:()=>Us({bundleAnchorPath:Ml,currentInode:r,platform:process.platform,realpath:on,statInode:e=>cn(e).ino}),onReplaced:e=>{t.write(`[mcp] bundle replaced anchor=${n} bootInode=${e.currentInode} onDiskInode=${e.onDiskInode} version=${S} — exiting for host respawn\n`),C()},log:e=>t.write(`[mcp] ${e}\n`)})}}return{close:x}}function Bl(e){return new t(`mcp`).description(`Start MCP stdio server for project knowledge base`).option(`-p, --port <port>`,`Override per-call routing and proxy stdio to this HTTP MCP port (skips bundle proxy)`,void 0).option(`--no-bundle-proxy`,`Run the npm-fetched MCP server in-process instead of proxying to the macOS Desktop bundle (equivalent: OK_BUNDLE_PROXY=0)`).action(async t=>{try{let n=e(),r=process.cwd();if(t.port!==void 0){let e=_l(process.env.OK_MCP_SPAWN_TIMEOUT_MS);await jl({lockDir:``,contentDir:``,portOverride:t.port,envAutoStart:process.env.OK_MCP_AUTOSTART,timeoutMs:e});return}let i=t.bundleProxy===!1?[...process.argv,`--no-bundle-proxy`]:process.argv,a=Fs(process.env,i,process.platform);if(a.proxy){let e=Ps(process.platform,_n(),{existsSync:F});if(e===null)Is({stderr:process.stderr,mode:`fallback-absent`,bundlePath:null,reason:`no installed OpenKnowledge.app bundle found`});else try{await Ls({bundlePath:e,argv:process.argv.slice(2),env:process.env,stderr:process.stderr});return}catch(t){Is({stderr:process.stderr,mode:`fallback-exec-failed`,bundlePath:e,reason:t instanceof Error?t.message:String(t)})}}else{let e=a.suppressedBy===`env`?`suppressed-env`:a.suppressedBy===`flag`?`suppressed-flag`:a.suppressedBy===`self`?`suppressed-self`:`suppressed-platform`;Is({stderr:process.stderr,mode:e,bundlePath:null,reason:null})}await zl({startupCwd:r,startupConfig:n})}catch(e){process.stderr.write(`MCP server failed to start: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}})}function Vl(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function Hl(e=()=>Kt(Wt())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>nt({lockDir:Se(e)}).baseUrl,openTarget:e=>{N(`open`,[e],{detached:!0,stdio:`ignore`,env:Vl(process.env)}).unref()},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function Ul(e,t,n){let r=V(t.project??process.cwd()),i=t.folder===!0||/\/+$/.test(e),a=e.replace(/\/+$/,``);if(!a)return n.error("Nothing to open: pass a doc path (e.g. `ok open specs/foo/SPEC`)."),1;if(a.startsWith(`/`)||a.includes(`\\`)||a.split(`/`).includes(`..`))return n.error(`Invalid name "${a}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(i){let e=n.resolveBaseUrl(r);if(!e)return n.error(`No OpenKnowledge UI is running for ${r}. Folder preview requires a running UI — start one with \`ok ui\`, then retry.`),1;let t=`${e}/#/${Be(a)}`;return n.openTarget(t),n.log(`Opening folder ${a} in your browser: ${t}`),0}if(n.detectBundlePath()){let e=`openknowledge://open?project=${encodeURIComponent(r)}&doc=${encodeURIComponent(a)}`;return n.openTarget(e),n.log(`Opening ${a} in the OpenKnowledge desktop app.`),0}let o=n.resolveBaseUrl(r);if(o){let e=`${o}/#/${Ke(a)}`;return n.openTarget(e),n.log(`Opening ${a} in your browser: ${e}`),0}return n.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 Wl(){return new t(`open`).description(`Open a doc in the OK Desktop app (folders open in the browser)`).argument(`<doc>`,`Extension-less doc path (e.g. specs/foo/SPEC), or a folder path with --folder`).option(`--folder`,`Treat <doc> as a folder and open the folder route in the browser`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action((e,t)=>{process.exitCode=Ul(e,t,Hl())})}function Gl(e){return new t(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-CiozYdtg.mjs`),r=e(),i=process.cwd(),a=Te(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 Kl(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function ql(e,t,n=process.cwd()){let r=e.op??`sync`,i=g(Se(n));if(i&&i.port>0){let t=`http://127.0.0.1:${i.port}/api/sync/trigger`;e.json||process.stderr.write(`Triggering ${r} via running server (port ${i.port})\n`);try{let n=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,...b({kind:`cli`,runtimeVersion:S})},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}`)}Kl(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=oe({baseDir:n});if(r===`sync`||r===`pull`){Kl(e.json,{type:`step`,step:`pull`});let t=await a.pull();Kl(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Kl(e.json,{type:`step`,step:`push`}),await a.push(),Kl(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
75
+ `),C()}),process.stdin.on(`error`,e=>{t.write(`[mcp] stdin error (${e instanceof Error?e.message:String(e)}) — host disconnected, shutting down\n`),C()}),b=Ks({getPpid:()=>process.ppid,onHostGone:e=>{t.write(`[mcp] ${e} — shutting down\n`),C()}}),qs({log:e=>t.write(`${e}\n`),transport:_,process,stdin:process.stdin}),process.platform===`darwin`){let e=Gs(Ml,{realpathSync:on,statInoSync:e=>cn(e).ino,log:e=>t.write(`${e}\n`)});if(e!==void 0){t.write(`[mcp] bundle identity anchor=${e.resolvedPath} inode=${e.inode} version=${S}\n`);let{resolvedPath:n,inode:r}=e;y=Ws({detect:()=>Us({bundleAnchorPath:Ml,currentInode:r,platform:process.platform,realpath:on,statInode:e=>cn(e).ino}),onReplaced:e=>{t.write(`[mcp] bundle replaced anchor=${n} bootInode=${e.currentInode} onDiskInode=${e.onDiskInode} version=${S} — exiting for host respawn\n`),C()},log:e=>t.write(`[mcp] ${e}\n`)})}}return{close:x}}function Bl(e){return new t(`mcp`).description(`Start MCP stdio server for project knowledge base`).option(`-p, --port <port>`,`Override per-call routing and proxy stdio to this HTTP MCP port (skips bundle proxy)`,void 0).option(`--no-bundle-proxy`,`Run the npm-fetched MCP server in-process instead of proxying to the macOS Desktop bundle (equivalent: OK_BUNDLE_PROXY=0)`).action(async t=>{try{let n=e(),r=process.cwd();if(t.port!==void 0){let e=_l(process.env.OK_MCP_SPAWN_TIMEOUT_MS);await jl({lockDir:``,contentDir:``,portOverride:t.port,envAutoStart:process.env.OK_MCP_AUTOSTART,timeoutMs:e});return}let i=t.bundleProxy===!1?[...process.argv,`--no-bundle-proxy`]:process.argv,a=Fs(process.env,i,process.platform);if(a.proxy){let e=Ps(process.platform,_n(),{existsSync:F});if(e===null)Is({stderr:process.stderr,mode:`fallback-absent`,bundlePath:null,reason:`no installed OpenKnowledge.app bundle found`});else try{await Ls({bundlePath:e,argv:process.argv.slice(2),env:process.env,stderr:process.stderr});return}catch(t){Is({stderr:process.stderr,mode:`fallback-exec-failed`,bundlePath:e,reason:t instanceof Error?t.message:String(t)})}}else{let e=a.suppressedBy===`env`?`suppressed-env`:a.suppressedBy===`flag`?`suppressed-flag`:a.suppressedBy===`self`?`suppressed-self`:`suppressed-platform`;Is({stderr:process.stderr,mode:e,bundlePath:null,reason:null})}await zl({startupCwd:r,startupConfig:n})}catch(e){process.stderr.write(`MCP server failed to start: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}})}function Vl(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function Hl(e=()=>Kt(Wt())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>nt({lockDir:Se(e)}).baseUrl,openTarget:e=>{N(`open`,[e],{detached:!0,stdio:`ignore`,env:Vl(process.env)}).unref()},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function Ul(e,t,n){let r=V(t.project??process.cwd()),i=t.folder===!0||/\/+$/.test(e),a=e.replace(/\/+$/,``);if(!a)return n.error("Nothing to open: pass a doc path (e.g. `ok open specs/foo/SPEC`)."),1;if(a.startsWith(`/`)||a.includes(`\\`)||a.split(`/`).includes(`..`))return n.error(`Invalid name "${a}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(i){let e=n.resolveBaseUrl(r);if(!e)return n.error(`No OpenKnowledge UI is running for ${r}. Folder preview requires a running UI — start one with \`ok ui\`, then retry.`),1;let t=`${e}/#/${Be(a)}`;return n.openTarget(t),n.log(`Opening folder ${a} in your browser: ${t}`),0}if(n.detectBundlePath()){let e=`openknowledge://open?project=${encodeURIComponent(r)}&doc=${encodeURIComponent(a)}`;return n.openTarget(e),n.log(`Opening ${a} in the OpenKnowledge desktop app.`),0}let o=n.resolveBaseUrl(r);if(o){let e=`${o}/#/${Ke(a)}`;return n.openTarget(e),n.log(`Opening ${a} in your browser: ${e}`),0}return n.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 Wl(){return new t(`open`).description(`Open a doc in the OK Desktop app (folders open in the browser)`).argument(`<doc>`,`Extension-less doc path (e.g. specs/foo/SPEC), or a folder path with --folder`).option(`--folder`,`Treat <doc> as a folder and open the folder route in the browser`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action((e,t)=>{process.exitCode=Ul(e,t,Hl())})}function Gl(e){return new t(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-DgLc6gDO.mjs`),r=e(),i=process.cwd(),a=Te(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 Kl(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function ql(e,t,n=process.cwd()){let r=e.op??`sync`,i=g(Se(n));if(i&&i.port>0){let t=`http://127.0.0.1:${i.port}/api/sync/trigger`;e.json||process.stderr.write(`Triggering ${r} via running server (port ${i.port})\n`);try{let n=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,...b({kind:`cli`,runtimeVersion:S})},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}`)}Kl(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=oe({baseDir:n});if(r===`sync`||r===`pull`){Kl(e.json,{type:`step`,step:`pull`});let t=await a.pull();Kl(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Kl(e.json,{type:`step`,step:`push`}),await a.push(),Kl(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
76
76
  `)),Kl(e.json,{type:`complete`,op:r}),e.json||process.stderr.write(`✓ ${r} complete\n`)}function Jl(e){return new t(`sync`).description(`Commit, pull, and push to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await ql({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 Yl(e){return new t(`pull`).description(`Pull changes from the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await ql({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 Xl(e){return new t(`push`).description(`Push commits to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await ql({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 Zl(e){return typeof e==`string`&&Le.includes(e)}async function Ql(e={}){let t=V(e.cwd??process.cwd()),n=e.pack??`knowledge-base`;if(!se[n])return{status:`failed`,message:`${A(`Error:`)} Unknown pack "${n}". Available: ${Le.join(`, `)}`,exitCode:1};let r;try{r=await fe({projectDir:t,rootDir:e.root,packId:n})}catch(e){return e instanceof $e?{status:`prerequisite-missing`,message:`${A(`Error:`)} ${e.message}`,exitCode:1}:{status:`failed`,message:`${A(`Error:`)} ${e instanceof Error?e.message:String(e)}`,exitCode:1}}if(r.created.length===0){let e=se[n].name;return{status:`no-op`,message:`${k(`Your ${e} pack is already seeded.`)}\n${O(`Nothing to do.`)}`,plan:r,exitCode:0}}if(e.dryRun){let e=de(se[n]);return{status:`dry-run`,message:`${M(`Reference this pack for inspiration (dry-run — no changes made):`)}\n\n${e}\n\n${M(`Plan:`)}\n\n${eu(r,t)}`,plan:r,exitCode:0}}if(!e.yes&&!await tu(`${M(`Plan:`)}\n\n${eu(r,t)}\n\n${M(`Apply?`)} ${O(`[Y/n] `)}`,e.confirmStream))return{status:`cancelled`,message:O(`Cancelled.`),plan:r,exitCode:0};let i=await Oe(r,{projectDir:t,packId:n});if(i.errors.length>0){let e=i.errors.map(e=>` ${A(`✗`)} ${e.path}: ${e.error}`);return{status:`failed`,message:[`${j(`Applied`)} ${i.applied} entries, ${j(String(i.errors.length))} error(s):`,...e].join(`
77
77
  `),plan:r,exitCode:1}}let a=se[n].name,o=i.packSkillsInstalled.length>0?`\n${O(`Installed the ${a} skill for: ${i.packSkillsInstalled.join(`, `)}`)}`:``;return{status:`applied`,message:`${k(`✓ Seeded ${a}`)} ${O(`(${i.applied} entries, ${i.durationMs}ms)`)}${o}`,plan:r,exitCode:0}}function $l(){let e=[M(`Available packs:`)];for(let t of Le){let n=se[t];e.push(` ${k(t)} ${O(`—`)} ${n.name}: ${n.description}`)}return e.join(`
78
78
  `)}function eu(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(M(`Folders to create:`));for(let e of r)n.push(` ${k(`+`)} ${D(fn(t,V(t,e.path))||e.path)}${O(`/`)}`)}if(i.length>0){n.length>0&&n.push(``),n.push(M(`Files to create:`));for(let e of i)n.push(` ${k(`+`)} ${D(fn(t,V(t,e.path))||e.path)}`)}if(e.skipped.length>0){n.length>0&&n.push(``),n.push(O(`Already present (skipped):`));for(let t of e.skipped)n.push(` ${O(`· ${t.path} (${t.reason})`)}`)}if(e.warnings.length>0){n.length>0&&n.push(``),n.push(j(`Warnings:`));for(let t of e.warnings)n.push(` ${j(`!`)} ${t}`)}return n.join(`
@@ -81,7 +81,7 @@ project → Search (a toggle with an egress-confirmation prompt), or run
81
81
  `);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 au(e){return new t(`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 iu(t,await e())})}async function ou(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 su(e,t){let{host:n,json:r}=e;U(n);let i=await Ri(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 ou(new q({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 cu(e){return new t(`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 su(t,await e())})}function lu(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(`
82
82
  `)??``}\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 uu(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 du(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 fu(e,t){return(await e.users.getAuthenticated()).data.login.toLowerCase()===t.toLowerCase()?`user`:`org`}function pu(e){return oe({baseDir:e,unsafe:{allowUnsafeCredentialHelper:!0}}).env({GIT_TERMINAL_PROMPT:`0`})}function mu(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 hu={ensureOkScaffold:e=>{he(e)},gitFactory:pu};async function gu(e){let t={...hu,...e.deps},n=V(e.projectDir),r;if(e.ownerKind)r=e.ownerKind;else try{r=await fu(e.octokit,e.body.owner)}catch(e){return{kind:`error`,code:lu(e)}}try{t.ensureOkScaffold(n)}catch{return{kind:`error`,code:`init-failed`}}let i=t.gitFactory(n);if(!F(B(n,`.git`)))try{await i.init()}catch{return{kind:`error`,code:`init-failed`}}let a;try{a=await uu({octokit:e.octokit,ownerLogin:e.body.owner,ownerKind:r,name:e.body.name,visibility:e.body.visibility,description:e.body.description})}catch(t){if(lu(t)===`name-conflict`){let t=await du(e.octokit,e.body.owner,e.body.name);if(t===null)return{kind:`error`,code:`name-conflict`};a=t}else return{kind:`error`,code:lu(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=mu(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 _u(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 vu(e,t){let{host:n,owner:r,name:i,visibility:a,description:o,projectDir:s,json:c}=e;U(n);let l=await Ri(n,t);if(l==null){_u(c,{kind:`error`,code:`auth-required`});return}let u=n===`github.com`?void 0:`https://${n}/api/v3`,d=new q({auth:l,...u?{baseUrl:u}:{}});try{Xt(`git config user.email`,{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`}_u(c,await gu({octokit:d,token:l,projectDir:s,body:{owner:r,name:i,visibility:a,description:o}}))}function yu(e){return new t(`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'
83
83
  `),process.exit(1)),await vu(t,await e())})}function bu(){let e=new t(`share`);e.description(`Sharing flow operations (owners, name-check, publish)`);let n=()=>ie();return e.addCommand(cu(n)),e.addCommand(au(n)),e.addCommand(yu(n)),e}function xu(){return new t(`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=V(e.project??process.cwd()),n=xt(t),r=ft(t,ut(t));if(r.kind===`no-exclude`){Su(e.json,t,r.reason);return}let i=xt(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(`${D(`Sharing mode is already`)} ${M(`shared`)} ${D(`— nothing to do.`)}\n`);return}process.stderr.write(`${k(`✓`)} ${M(`Sharing mode set to`)} ${k(`shared`)}\n`),process.stderr.write(` Removed OK paths from ${M(`.git/info/exclude`)}; commit the files to share with teammates.\n`)})}function Su(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(`${j({"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 Cu(){return new t(`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=V(e.project??process.cwd()),n=xt(t),r=[...bt(t)],i=Dt(t,ut(t)).tracked;if(e.json){let e={type:`sharing-status`,projectRoot:t,mode:n,excluded:r,trackedUpstream:i};process.stdout.write(`${JSON.stringify(e)}\n`);return}let a=[];if(a.push(`OpenKnowledge sharing mode: ${wu(n)}`),a.push(``),a.push(`Excluded from git via ${M(`.git/info/exclude`)}:`),r.length===0)a.push(` (none)`);else for(let e of r)a.push(` ${e}`);if(a.push(``),a.push(`Other OK paths exist but are tracked upstream:`),i.length===0)a.push(` (none)`);else for(let e of i)a.push(` ${e}`);a.push(``),a.push(`Toggle with: ${D(n===`local-only`?`ok config-sharing share`:`ok config-sharing unshare`)}`),process.stdout.write(`${a.join(`
84
- `)}\n`)})}function wu(e){switch(e){case`shared`:return k(`shared`);case`local-only`:return k(`local-only`);case`no-git`:return j(`no-git (not a git repository)`)}}function Tu(){return new t(`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=V(e.project??process.cwd()),n=St(t,ut(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`){Eu(e.json,t,n.reason);return}let r=xt(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(`${M(`Sharing mode is already`)} ${k(`local-only`)} ${M(`— nothing to do.`)}\n`);return}process.stderr.write(`${k(`✓`)} ${M(`Sharing mode set to`)} ${k(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${M(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function Eu(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(`${j({"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 Du(){let e=new t(`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(xu()),e.addCommand(Tu()),e.addCommand(Cu()),e}const Ou=new Set([`--cwd`,`--log-level`]);function ku(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(`-`)){Ou.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function Au(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 ju(e){return/\.(md|mdx)$/i.test(e)}function Mu(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function Nu(e=()=>Kt(Wt())){return{prepare:xe,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{N(`open`,[e],{detached:!0,stdio:`ignore`,env:Mu(process.env)}).unref()},runProjectOpen:(e,t)=>Ul(e,{project:t},Hl()),runBrowserOpen:e=>Iu(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function Pu(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof Xe||e instanceof je||e instanceof et)return t.error(e.message),1;throw e}if(n.mode===`project`)return t.runProjectOpen(n.docName,n.projectRoot);if(t.detectBundlePath()){let e=`openknowledge://open?file=${encodeURIComponent(n.canonicalFilePath)}`;return t.openTarget(e),t.log(`Opening ${n.singleDocRelPath} in the OpenKnowledge desktop app.`),0}return await t.runBrowserOpen(n),0}function Fu(){let e=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[V(e,`public`),V(e,`../../app/dist`),V(e,`../../../app/dist`)].find(e=>F(e))}async function Iu(e){let{createEphemeralProjectDir:t}=await import(`./dist-DVWyQ2rE.mjs`),{loadConfig:n}=await import(`./index.mjs`),{bootStartServer:r,resolveHost:i}=await import(`./start-BrzdwifC.mjs`),{openBrowser:a}=await import(`./open-browser-DHTbHSqx.mjs`),o=Fu();o||(process.stderr.write("OpenKnowledge UI assets were not found. Reinstall @inkeep/open-knowledge, or build the app (`bun run build`) in a monorepo checkout.\n"),process.exit(1));let s=t(e.contentDir),c=!1,l,u=async()=>{if(!c){c=!0;try{await l?.destroy()}catch{}try{await Tn(s,{recursive:!0,force:!0})}catch{}}},d=()=>{u().then(()=>process.exit(0))};process.once(`SIGINT`,d),process.once(`SIGTERM`,d);let{config:f}=n(s),p=i({},process.env);try{l=await r({config:f,cwd:s,host:p,port:0,projectDir:s,singleFile:e.canonicalFilePath,serveContentAssets:!0,reactShellDistDir:o})}catch(t){await u(),process.stderr.write(`Failed to open ${e.singleDocRelPath}: ${t instanceof Error?t.message:String(t)}\n`),process.exit(1)}let m=`http://${p}:${l.port}/#/${Ke(e.docName)}`;process.stdout.write(`Opening ${e.singleDocRelPath} in your browser: ${m}\n`),process.stdout.write(`Press Ctrl-C to close the session.
84
+ `)}\n`)})}function wu(e){switch(e){case`shared`:return k(`shared`);case`local-only`:return k(`local-only`);case`no-git`:return j(`no-git (not a git repository)`)}}function Tu(){return new t(`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=V(e.project??process.cwd()),n=St(t,ut(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`){Eu(e.json,t,n.reason);return}let r=xt(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(`${M(`Sharing mode is already`)} ${k(`local-only`)} ${M(`— nothing to do.`)}\n`);return}process.stderr.write(`${k(`✓`)} ${M(`Sharing mode set to`)} ${k(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${M(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function Eu(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(`${j({"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 Du(){let e=new t(`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(xu()),e.addCommand(Tu()),e.addCommand(Cu()),e}const Ou=new Set([`--cwd`,`--log-level`]);function ku(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(`-`)){Ou.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function Au(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 ju(e){return/\.(md|mdx)$/i.test(e)}function Mu(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function Nu(e=()=>Kt(Wt())){return{prepare:xe,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{N(`open`,[e],{detached:!0,stdio:`ignore`,env:Mu(process.env)}).unref()},runProjectOpen:(e,t)=>Ul(e,{project:t},Hl()),runBrowserOpen:e=>Iu(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function Pu(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof Xe||e instanceof je||e instanceof et)return t.error(e.message),1;throw e}if(n.mode===`project`)return t.runProjectOpen(n.docName,n.projectRoot);if(t.detectBundlePath()){let e=`openknowledge://open?file=${encodeURIComponent(n.canonicalFilePath)}`;return t.openTarget(e),t.log(`Opening ${n.singleDocRelPath} in the OpenKnowledge desktop app.`),0}return await t.runBrowserOpen(n),0}function Fu(){let e=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[V(e,`public`),V(e,`../../app/dist`),V(e,`../../../app/dist`)].find(e=>F(e))}async function Iu(e){let{createEphemeralProjectDir:t}=await import(`./dist-lMD2xM96.mjs`),{loadConfig:n}=await import(`./index.mjs`),{bootStartServer:r,resolveHost:i}=await import(`./start-C0Mpznab.mjs`),{openBrowser:a}=await import(`./open-browser-DHTbHSqx.mjs`),o=Fu();o||(process.stderr.write("OpenKnowledge UI assets were not found. Reinstall @inkeep/open-knowledge, or build the app (`bun run build`) in a monorepo checkout.\n"),process.exit(1));let s=t(e.contentDir),c=!1,l,u=async()=>{if(!c){c=!0;try{await l?.destroy()}catch{}try{await Tn(s,{recursive:!0,force:!0})}catch{}}},d=()=>{u().then(()=>process.exit(0))};process.once(`SIGINT`,d),process.once(`SIGTERM`,d);let{config:f}=n(s),p=i({},process.env);try{l=await r({config:f,cwd:s,host:p,port:0,projectDir:s,singleFile:e.canonicalFilePath,serveContentAssets:!0,reactShellDistDir:o})}catch(t){await u(),process.stderr.write(`Failed to open ${e.singleDocRelPath}: ${t instanceof Error?t.message:String(t)}\n`),process.exit(1)}let m=`http://${p}:${l.port}/#/${Ke(e.docName)}`;process.stdout.write(`Opening ${e.singleDocRelPath} in your browser: ${m}\n`),process.stdout.write(`Press Ctrl-C to close the session.
85
85
  `),a(m),await new Promise(()=>{})}function Lu(){let e=new t(`skills`).description(`Manage Open Knowledge skills for this project.`);return e.command(`manage`).description(`Control whether OK adopts your editor skills into this project. Default: off — OK only manages skills already under .ok/skills.`).option(`--on`,`Make this project OK-managed: import existing editor skills and adopt new ones.`).option(`--off`,`Stop adopting editor skills (non-destructive — existing .ok/skills + symlinks stay).`).option(`--status`,`Print the current setting.`).action(async e=>{let t=V(process.cwd());if([e.on,e.off,e.status].filter(Boolean).length!==1){process.stderr.write(`${A(`Error:`)} pass exactly one of --on, --off, --status.\n`),process.exitCode=1;return}if(e.status){let e=Ye(t);process.stdout.write(`Skill management for ${M(t)}: ${e?k(`on`):O(`off (default)`)}\n`);return}let n=!!e.on;try{await Ee(t,{manageEditorSkills:n,surface:`cli`})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`${A(`Error:`)} could not write skill-management marker: ${t}\n`),process.exitCode=1;return}process.stdout.write(n?`${k(`OK now manages skills for this project.`)} Existing editor skills are imported into ${M(`.ok/skills`)} on the next ${M(`ok start`)} / project open, and new ones adopted automatically.\n`:`${D(`OK will no longer adopt editor skills here.`)} Existing ${M(`.ok/skills`)} content + symlinks are left intact.\n`)}),e}function Ru(e,t){return{server:zu(`server`,e),ui:zu(`ui`,t)}}function zu(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 Bu(e){return`${Vu(e.server)}\n${Vu(e.ui)}`}function Vu(e){let t=e.name===`server`?`server`:`ui `;return e.state===`missing`?`${t} not running`:e.state===`corrupt`?`${t} lock file corrupt — run \`ok clean\``:e.state===`foreign-host`?`${t} foreign host (${e.host}) pid=${e.pid} port=${e.port}`:e.state===`dead-pid`?`${t} stale (dead pid=${e.pid}) — run \`ok clean\``:`${t} alive pid=${e.pid} port=${e.port} started=${e.startedAt}`}function Hu(e){let t=e.inspect??(t=>At(e.lockDir,t)),n=e.log??(e=>console.log(e)),r=Ru(t(`server`),t(`ui`));return e.json?n(JSON.stringify(r,null,2)):n(Bu(r)),r}function Uu(e){return new t(`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(),Hu({lockDir:Se(process.cwd()),json:t.json===!0})})}function Wu(e){return[e,`Copyright (C) 2026 Inkeep, Inc.`,`License GPL-3.0-or-later: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.`,`This is free software: you are free to change and redistribute it.`,`There is NO WARRANTY, to the extent permitted by law.`].join(`
86
86
  `)}process.argv.includes(`--no-color`)?(process.env.NO_COLOR=`1`,delete process.env.FORCE_COLOR):process.argv.includes(`--color`)&&(process.env.FORCE_COLOR=`1`,delete process.env.NO_COLOR);const Q=new t;let $,Gu;function Ku(){return Gu}Q.name(`open-knowledge`).description(`Local-first knowledge base with CRDT collaboration`).usage(`[options] [file | command]`).version(Wu(Lt)).option(`--cwd <path>`,`Working directory`).option(`--log-level <level>`,`Log level: silent, error, warn, info (default), debug, trace`,`info`).option(`--no-color`,`Disable color output`).option(`--color`,`Force color output`).hook(`preAction`,e=>{let t=e.opts().cwd;if(t!==void 0&&process.chdir(t),Q.getOptionValueSource(`logLevel`)===`cli`){let e=String(Q.opts().logLevel);process.env.LOG_LEVEL=e,process.env.OK_CONSOLE_LEVEL=e}let n=e.args?.[0],r=Pt(n,process.cwd());r!==null&&(Ot(process.cwd()),process.chdir(r),console.error(`[ok] Using OpenKnowledge project at ${r}`));let{config:i}=zt(r??t);$=i;let a=e.args?.[0]??e.name()??`cli`;Gu=Ie({name:`cli`,project:i.project?.name??void 0}),Gu.info({command:a,cwd:process.cwd()},`cli command started`)}),Q.action(async()=>{if(Kt(Wt()).available){Ht({spawn:N});return}await Gt($,{})});const qu=Ut(()=>$);Q.addCommand(qu);const Ju=Bl(()=>$);Q.addCommand(Ju),Q.addCommand(Tt()),Q.addCommand(nu()),Q.addCommand(Ga(),{hidden:!0}),Q.addCommand(Jt()),Q.addCommand(Lu());const Yu=Gl(()=>$);Q.addCommand(Yu);const Xu=Et(()=>$);Q.addCommand(Xu),Q.addCommand(Wl()),Q.addCommand(jt(()=>$)),Q.addCommand(ca(()=>$)),Q.addCommand(Uu(()=>$)),Q.addCommand(Ft()),Q.addCommand(Ss()),Q.addCommand(aa()),Q.addCommand(La()),Q.addCommand(qi(Ku)),Q.addCommand(js()),Q.addCommand(ka(()=>$)),Q.addCommand(Jl(()=>$)),Q.addCommand(Xl(()=>$)),Q.addCommand(Yl(()=>$)),Q.addCommand(bu()),Q.addCommand(Du()),Q.addHelpText(`after`,`
87
87
  Examples:
@@ -0,0 +1,2 @@
1
+ import"./server-lock-CN2YHwpP-CemdeDui.mjs";var e=`0.20.0-beta.4`;const t=`config.yml`,n=e;export{n,t};
2
+ //# sourceMappingURL=constants-CccigS7Z.mjs.map