@inkeep/open-knowledge 0.14.1-beta.0 → 0.14.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/skills/discovery/SKILL.md +1 -1
- package/dist/assets/skills/project/SKILL.md +1 -1
- package/dist/cli.mjs +5 -5
- package/dist/constants-BnrUiISQ.mjs +2 -0
- package/dist/{dist-CfGIZu2A.mjs → dist-DDXOiPkg.mjs} +4 -4
- package/dist/{dist-Dr2mVrNM.mjs → dist-De0GFsdh.mjs} +1 -1
- package/dist/index.mjs +1 -1
- package/dist/init-BXiJM0TD.mjs +1 -0
- package/dist/{init-C_4-o3K2.mjs → init-DLzS-QZM.mjs} +4 -4
- package/dist/loader-BaagpcJC.mjs +1 -0
- package/dist/{loader-Vh9aw3dQ.mjs → loader-CQ-XLDDr.mjs} +2 -2
- package/dist/preview-BGQyMIgQ.mjs +1 -0
- package/dist/{preview-BXjWUBVD.mjs → preview-Dva-Osuc.mjs} +2 -2
- package/dist/public/assets/{ActivityModeContent-D1LV0i9s.js → ActivityModeContent-C25tOL4t.js} +1 -1
- package/dist/public/assets/{DocumentContext-CAteDFxs.js → DocumentContext-BamkFLod.js} +7 -7
- package/dist/public/assets/{OpenInAgentMenuRequestContext-DGTqGF-d.js → OpenInAgentMenuRequestContext-TWudXlcT.js} +3 -3
- package/dist/public/assets/{SettingsDialogBody-CJW_Sq1u.js → SettingsDialogBody-DdlbvMQV.js} +2 -2
- package/dist/public/assets/SourceEditor-D_5MOnNk.js +2 -0
- package/dist/public/assets/config-validation-events-B95fJptt.js +12 -0
- package/dist/public/assets/index-BViRko2u.js +2019 -0
- package/dist/public/assets/index-KVUYtx60.css +1 -0
- package/dist/public/index.html +5 -5
- package/dist/{repair-launch-json-BBmwNfqx.mjs → repair-launch-json-LZl55YXm.mjs} +2 -2
- package/dist/{repair-mcp-configs-DAL7M2L6.mjs → repair-mcp-configs-C02JctcE.mjs} +2 -2
- package/dist/{repair-skills-Mqkiqg_p.mjs → repair-skills-4UqJa14n.mjs} +2 -2
- package/dist/repair-skills-D35qgsTr.mjs +1 -0
- package/dist/{src-0HeDa66x.mjs → src-DyvnIwTS.mjs} +2 -2
- package/dist/start-B9uo1X-i.mjs +1 -0
- package/dist/{start-DvnzD1Qh.mjs → start-DLiZex3g.mjs} +2 -2
- package/dist/{write-project-skill-BXSxpw1L.mjs → write-project-skill-BOMiBSxq.mjs} +2 -2
- package/package.json +1 -1
- package/dist/constants-CVbZs5-3.mjs +0 -2
- package/dist/init-CheOjib4.mjs +0 -1
- package/dist/loader-BIEazULv.mjs +0 -1
- package/dist/preview-p78X8Wu-.mjs +0 -1
- package/dist/public/assets/SourceEditor-Dz9mWVTl.js +0 -2
- package/dist/public/assets/config-validation-events-C_5rJceh.js +0 -12
- package/dist/public/assets/index-4X6bXAZx.css +0 -1
- package/dist/public/assets/index-Cwu5qnV1.js +0 -2019
- package/dist/repair-skills-BAGFBG5W.mjs +0 -1
- package/dist/start-Bj89tp3m.mjs +0 -1
|
@@ -3,7 +3,7 @@ name: open-knowledge-discovery
|
|
|
3
3
|
description: "Read when the user asks what Open Knowledge is, wants to install it on a repository, wants to share an Open Knowledge project with collaborators, or asks how `ok init` / `ok install-skill` / OK Desktop set up a project. Do NOT load to perform Open Knowledge reads/writes — the runtime guidance for editing markdown inside an initialized OK project ships as a separate project-local skill at `.claude/skills/open-knowledge/` whenever `ok init` runs. If the user appears to be editing markdown inside a `.ok/` project and this is the only OK skill loaded, advise them to re-run `ok init` to install the project-local skill."
|
|
4
4
|
compatibility: "Any agent host — no MCP server required. Pure discovery + install guidance."
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.14.1-beta.
|
|
6
|
+
version: "0.14.1-beta.2"
|
|
7
7
|
author: "Inkeep"
|
|
8
8
|
repository: "https://github.com/inkeep/open-knowledge"
|
|
9
9
|
---
|
|
@@ -3,7 +3,7 @@ name: open-knowledge
|
|
|
3
3
|
description: "MUST invoke before reading or editing any `.md` / `.mdx` file, and before any `mcp__open-knowledge__*` tool call (`exec`, `search`, `write`, `edit`, and the rest). This skill is installed into the repository by `ok init`, so its presence alone means this is an Open Knowledge project — its runtime contract governs every markdown file here, with no need to probe for a `.ok/` directory. Authoritative agent-runtime contract; supersedes the overlapping MCP server `instructions` echo."
|
|
4
4
|
compatibility: "Claude Code, Claude Desktop, Claude Cowork, Claude.ai web. Requires Open Knowledge MCP server + code execution."
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.14.1-beta.
|
|
6
|
+
version: "0.14.1-beta.2"
|
|
7
7
|
author: "Inkeep"
|
|
8
8
|
repository: "https://github.com/inkeep/open-knowledge"
|
|
9
9
|
---
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{s as e}from"./chunk-C94x7I9S.mjs";import{t}from"./esm-BLMtE3s6.mjs";import{$i as n,Ai as r,Gi as i,Ki as a,Pi as o,Qi as s,Ta as c,Vi as l,Wr as u,Zi as d,bn as f,ea as p,f as m,ia as h,ki as g,n as _,qi as v,s as y,sa as b,ua as x,wa as S,xr as C}from"./server-lock-BpjJj3OD-Co1tfNQM.mjs";import{a as ee,n as w,r as te,t as ne}from"./gh-detect-CiwGHfLq.mjs";import{r as re}from"./git-handle--dq7Gq14-BpH0pmv5.mjs";import{$n as ie,Br as ae,En as oe,F as se,Fn as ce,Gi as le,Hn as ue,Ht as de,Ji as fe,Jt as pe,Ki as me,Kr as he,Mt as ge,P as _e,Pr as ve,Q as ye,Qi as be,Rn as xe,T as Se,Ur as Ce,Ut as we,Vt as Te,Wi as Ee,Yi as De,Z as Oe,Zt as ke,_ as Ae,_t as je,aa as Me,ai as Ne,at as Pe,bn as Fe,br as Ie,c as Le,dn as Re,ea as ze,fn as Be,it as Ve,mt as He,na as Ue,on as We,qi as Ge,ra as Ke,rt as qe,ta as Je,tt as Ye,v as Xe,w as Ze,wr as Qe,wt as $e,xt as et,yr as tt}from"./dist-
|
|
2
|
+
import{s as e}from"./chunk-C94x7I9S.mjs";import{t}from"./esm-BLMtE3s6.mjs";import{$i as n,Ai as r,Gi as i,Ki as a,Pi as o,Qi as s,Ta as c,Vi as l,Wr as u,Zi as d,bn as f,ea as p,f as m,ia as h,ki as g,n as _,qi as v,s as y,sa as b,ua as x,wa as S,xr as C}from"./server-lock-BpjJj3OD-Co1tfNQM.mjs";import{a as ee,n as w,r as te,t as ne}from"./gh-detect-CiwGHfLq.mjs";import{r as re}from"./git-handle--dq7Gq14-BpH0pmv5.mjs";import{$n as ie,Br as ae,En as oe,F as se,Fn as ce,Gi as le,Hn as ue,Ht as de,Ji as fe,Jt as pe,Ki as me,Kr as he,Mt as ge,P as _e,Pr as ve,Q as ye,Qi as be,Rn as xe,T as Se,Ur as Ce,Ut as we,Vt as Te,Wi as Ee,Yi as De,Z as Oe,Zt as ke,_ as Ae,_t as je,aa as Me,ai as Ne,at as Pe,bn as Fe,br as Ie,c as Le,dn as Re,ea as ze,fn as Be,it as Ve,mt as He,na as Ue,on as We,qi as Ge,ra as Ke,rt as qe,ta as Je,tt as Ye,v as Xe,w as Ze,wr as Qe,wt as $e,xt as et,yr as tt}from"./dist-DDXOiPkg.mjs";import{t as nt}from"./yazl-Docqgl6q.mjs";import{n as rt,r as it,t as T}from"./dist-bundle-D75dREX-.mjs";import{B as at,C as ot,E as st,F as ct,H as lt,I as ut,L as dt,M as ft,N as pt,P as mt,R as ht,S as gt,T as _t,V as vt,b as yt,u as bt,v as xt,w as St,z as Ct}from"./init-DLzS-QZM.mjs";import{a as wt,c as Tt,h as Et,i as Dt,l as Ot,m as kt,o as At,s as jt,u as Mt}from"./src-DyvnIwTS.mjs";import{n as Nt,t as Pt}from"./constants-BnrUiISQ.mjs";import{n as Ft,t as It}from"./loader-CQ-XLDDr.mjs";import{S as Lt,_ as Rt,b as zt,m as Bt,x as Vt,y as Ht}from"./start-DLiZex3g.mjs";import{c as Ut,i as E,n as D,o as O,r as k,s as A,t as j}from"./colors-8SzMRIVy.mjs";import{n as Wt}from"./repair-skills-4UqJa14n.mjs";import{execFile as Gt,execSync as Kt,spawn as M,spawnSync as N}from"node:child_process";import{accessSync as qt,closeSync as Jt,constants as Yt,cpSync as Xt,createWriteStream as Zt,existsSync as P,mkdirSync as F,mkdtempSync as Qt,openSync as $t,readFileSync as I,readdirSync as en,realpathSync as tn,rmSync as nn,statSync as rn,unlinkSync as an,writeFileSync as L}from"node:fs";import on,{basename as R,dirname as sn,join as z,relative as cn,resolve as B,sep as ln}from"node:path";import un from"node:process";import{arch as dn,freemem as fn,homedir as pn,platform as mn,release as hn,tmpdir as gn,totalmem as _n,type as vn,uptime as yn}from"node:os";import{fileURLToPath as bn}from"node:url";import{rm as xn}from"node:fs/promises";import{createHash as Sn,randomUUID as Cn}from"node:crypto";import{setTimeout as wn}from"node:timers/promises";import{promisify as Tn,stripVTControlCharacters as En,styleText as V}from"node:util";import{AsyncLocalStorage as Dn,AsyncResource as On}from"node:async_hooks";import*as kn from"node:readline";import{createInterface as An}from"node:readline/promises";const jn={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 Mn;(function(e){})(Mn||={});function Nn(e){return x(l,e)}async function Pn(e,t,n,r){let i=Fn(await In(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 Fn(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 In(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 Ln(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 Pn(process.stdin,process.stdout,r,{log:t,getDiag:()=>n});await Fe(t),process.exit(i)}catch(e){t?.error({error:e instanceof Error?e.message:String(e)},`[auth] git-credential get: unexpected error`),await Fe(t),process.exit(1)}}),r}function Rn(e){let t=e.endpoint.DEFAULTS;return/^https:\/\/(api\.)?github\.com$/.test(t.baseUrl)?`https://github.com`:t.baseUrl.replace(`/api/v3`,``)}async function zn(e,t,n){let r={baseUrl:Rn(e),headers:{accept:`application/json`},...n},i=await e(t,r);if(`error`in i.data){let n=new rt(`${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 Bn(e){let t=e.request||T,n={client_id:e.clientId};return`scopes`in e&&Array.isArray(e.scopes)&&(n.scope=e.scopes.join(` `)),zn(t,`POST /login/device/code`,n)}async function Vn(e){let t=await zn(e.request||T,`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=Hn(e,t.data.expires_in),n.refreshTokenExpiresAt=Hn(e,t.data.refresh_token_expires_in)}delete n.scopes}return{...t,authentication:n}}function Hn(e,t){return new Date(e+t*1e3).toISOString()}async function Un(e,t){let n=Wn(e,t.auth);if(n)return n;let{data:r}=await Bn({clientType:e.clientType,clientId:e.clientId,request:t.request||e.request,scopes:t.auth.scopes||e.scopes});await e.onVerification(r);let i=await Kn(t.request||e.request,e.clientId,e.clientType,r);return e.authentication=i,i}function Wn(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 Gn(e){await new Promise(t=>setTimeout(t,e*1e3))}async function Kn(e,t,n,r){try{let i={clientId:t,request:e,code:r.device_code},{authentication:a}=n===`oauth-app`?await Vn({...i,clientType:`oauth-app`}):await Vn({...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 Gn(r.interval),Kn(e,t,n,r);if(a===`slow_down`)return await Gn(r.interval+7),Kn(e,t,n,r);throw i}}async function qn(e,t){return Un(e,{auth:t})}async function Jn(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 Un(e,{request:t,auth:{type:`oauth`}});return i.headers.authorization=`token ${a}`,t(i)}var Yn=`0.0.0-development`;function Xn(e){let t=e.request||T.defaults({headers:{"user-agent":`octokit-auth-oauth-device.js/${Yn} ${it()}`}}),{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(qn.bind(null,i),{hook:Jn.bind(null,i)})}async function Zn(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=Xn({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 Qn(){return process.env.OPEN_KNOWLEDGE_GITHUB_CLIENT_ID??`Ov23liqlSd0V1MwR6rhI`}const $n=new Set([`gitlab.com`,`bitbucket.org`,`codeberg.org`,`gitea.com`,`sr.ht`,`sourcehut.org`]);function H(e){let t=e.toLowerCase().replace(/:\d+$/,``);$n.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 er(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function tr(e,t,n=Zn){let r=Qn(),{host:i,json:a}=e;H(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?er(!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?er(!0,{type:`complete`,host:i,login:s}):process.stderr.write(`✓ Logged in as ${s} on ${i}\n`)}function nr(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 tr(t,await e())})}const rr=e=>e.name===`enter`||e.name===`return`;var ir=class extends Error{name=`AbortPromptError`;message=`Prompt was aborted`;constructor(e){super(),this.cause=e?.cause}},ar=class extends Error{name=`CancelPromptError`;message=`Prompt was canceled`},or=class extends Error{name=`ExitPromptError`},sr=class extends Error{name=`HookError`},cr=class extends Error{name=`ValidationError`};const lr=new Dn;function ur(e){return{rl:e,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function dr(e,t){let n=ur(e);return lr.run(n,()=>{function e(e){n.handleChange=()=>{n.index=0,e()},n.handleChange()}return t(e)})}function U(){let e=lr.getStore();if(!e)throw new sr(`[Inquirer] Hook functions can only be called from within a prompt`);return e}function fr(){return U().rl}function pr(e){return On.bind((...t)=>{let n=U(),r=!1,i=n.handleChange;n.handleChange=()=>{r=!0};let a=e(...t);return r&&i(),n.handleChange=i,a})}function mr(e){let t=U(),{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 hr(){U().handleChange()}const gr={queue(e){let t=U(),{index:n}=t;t.hooksEffect.push(()=>{t.hooksCleanup[n]?.();let r=e(fr());if(r!=null&&typeof r!=`function`)throw new cr(`useEffect return value must be a cleanup function or nothing.`);t.hooksCleanup[n]=r})},run(){let e=U();pr(()=>{e.hooksEffect.forEach(e=>{e()}),e.hooksEffect.length=0})()},clearAll(){let e=U();e.hooksCleanup.forEach(e=>{e?.()}),e.hooksEffect.length=0,e.hooksCleanup.length=0}};function _r(e){return typeof e==`function`}function W(e){return mr(t=>{let n=On.bind(function(e){t.get()!==e&&(t.set(e),hr())});if(t.initialized)return[t.get(),n];let r=_r(e)?e():e;return t.set(r),[r,n]})}function vr(e,t){mr(n=>{let r=n.get();(!Array.isArray(r)||t.some((e,t)=>!Object.is(e,r[t])))&&gr.queue(e),n.set(t)})}const yr={prefix:{idle:V(`blue`,`?`),done:V(`green`,lt.tick)},spinner:{interval:80,frames:[`⠋`,`⠙`,`⠹`,`⠸`,`⠼`,`⠴`,`⠦`,`⠧`,`⠇`,`⠏`].map(e=>V(`yellow`,e))},style:{answer:e=>V(`cyan`,e),message:e=>V(`bold`,e),error:e=>V(`red`,`> ${e}`),defaultAnswer:e=>V(`dim`,`(${e})`),help:e=>V(`dim`,e),highlight:e=>V(`cyan`,e),key:e=>V(`cyan`,V(`bold`,`<${e}>`))}};function br(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 xr(...e){let t={};for(let n of e)for(let[e,r]of Object.entries(n)){let n=t[e];t[e]=br(n)&&br(r)?xr(n,r):r}return t}function Sr(...e){return xr(yr,...e.filter(e=>e!=null))}function Cr({status:e=`idle`,theme:t}){let[n,r]=W(!1),[i,a]=W(0),{prefix:o,spinner:s}=Sr(t);return vr(()=>{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 wr(e){return W({current:e})[0]}function Tr(e){let t=wr(e);t.current=e,vr(e=>{let n=!1,r=pr((r,i)=>{n||t.current(i,e)});return e.input.on(`keypress`,r),()=>{n=!0,e.input.removeListener(`keypress`,r)}},[])}var Er=e(vt(),1);function Dr(e,t){return e.split(`
|
|
4
4
|
`).flatMap(e=>at(e,t,{trim:!1,hard:!0}).split(`
|
|
5
5
|
`).map(e=>e.trimEnd())).join(`
|
|
@@ -19,7 +19,7 @@ import{s as e}from"./chunk-C94x7I9S.mjs";import{t}from"./esm-BLMtE3s6.mjs";impor
|
|
|
19
19
|
`),patterns:[...t],lineCount:n}}const qi=z(pn(),`.ok`,`logs`),Ji=z(pn(),`.ok`,`bug-reports`);function Yi(e){let t=z(e,`.ok`,`config.yml`);if(P(t))try{let e=I(t,`utf8`).match(/^\s*name:\s*['"]?(.+?)['"]?\s*$/m);if(e?.[1])return e[1]}catch{}return P(z(e,`.ok`))?Sn(`sha256`).update(B(e)).digest(`hex`).slice(0,12):null}function Xi(){let e={timestamp:new Date().toISOString(),platform:mn(),osType:vn(),osRelease:hn(),hostname:`[redacted]`,uptime:yn(),freeMem:fn(),totalMem:_n(),nodeVersion:process.version,bunVersion:process.versions.bun??null,v8Version:process.versions.v8??null,pid:process.pid};try{e.macosVersion=Kt(`sw_vers -productVersion 2>/dev/null`,{encoding:`utf8`}).trim()}catch{}try{let t=z(__dirname,`..`,`..`,`package.json`);P(t)&&(e.okVersion=JSON.parse(I(t,`utf8`)).version)}catch{}return e}function Zi(e){if(!P(qi))return{files:[],dir:qi};let t=en(qi).filter(e=>e.endsWith(`.log`)||/\.log\.\d+$/.test(e)).map(e=>z(qi,e));if(e&&t.length>0){let n=t.filter(t=>{try{return I(t,`utf8`).includes(`"project":"${e}"`)}catch{return!0}});n.length>0&&(t=n)}return{files:t,dir:qi}}function Qi(e){let t=z(e,`.ok`,`local`);return P(t)?{files:[`server.lock`,`last-spawn-error.log`].map(e=>z(t,e)).filter(e=>P(e)),dir:t}:{files:[],dir:null}}function $i(e){let t=z(e,`.ok`,`local`,`logs`);return P(t)?{files:[`server-current.jsonl`,`server-prev.jsonl`].map(e=>z(t,e)).filter(e=>P(e)),dir:t}:{files:[],dir:null}}async function ea(t){let n=ju();F(Ji,{recursive:!0});let r=z(Ji,`${new Date().toISOString().replace(/[:.]/g,`-`)}-bugreport.zip`);n?.info({projectSlug:t.projectSlug},`gathering diagnostic data`);let i=Xi(),{files:a}=Zi(t.projectSlug),{files:o}=Qi(t.cwd),{files:s}=$i(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}=Ki(I(e,`utf8`)),i=`logs/${R(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}=Ki(I(e,`utf8`)),i=`lockdir/${R(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}=Ki(I(e,`utf8`)),i=`local-logs/${R(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: ${Gi.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=Zt(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&&mn()===`darwin`)try{M(`/usr/bin/open`,[`-R`,r],{detached:!0,stdio:`ignore`}).unref()}catch{}return r}function ta(){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=Yi(t);try{await ea({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 na(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 ra(e){let t=e.inspect??(t=>Et(e.lockDir,t)),n=e.unlink??(e=>an(e)),r=e.log??(e=>console.log(e)),i=e.error??(e=>console.error(e)),a=na(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 ia(e){return new t(`clean`).description(`Prune stale / corrupt open-knowledge lock files (never touches live locks)`).action(()=>{e(),ra({lockDir:Ce(process.cwd())}).failed.length>0&&(process.exitCode=1)})}async function aa(e,t,n={},r=ne){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 oa(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 sa=[[`count`,0,10],[`compress`,10,20],[`receiv`,20,60],[`resolv`,60,100]];function ca(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 sa)if(n.includes(e))return{stage:t[1],pct:Math.round(i+r/100*(a-i))};return null}function q(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}function la(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 ua(e){return typeof e!=`string`||e.length===0?[`--progress`]:[`--progress`,`-b`,e]}const da=u;async function fa(e){try{return await e.clone(ua(e.branch)),{fellBack:!1}}catch(t){if(e.branch!==null&&da(t))return e.onFallback(e.branch),await e.clone(ua(null)),{fellBack:!0};throw t}}function pa(e,t,n){return e===`https`&&t===`github.com`&&n}async function ma(e,t,n,r=process.cwd()){let i=kt(e);if(!i)throw Error(`Invalid git URL: ${e}`);let a=t.dir?B(r,t.dir):B(r,i.name);if(P(a)&&en(a).length>0)throw Error(`Target directory is not empty: ${a}`);let o=ee(),s=i.protocol===`https`&&i.hostname===`github.com`?await oa(i.owner,i.name):!1,c=pa(i.protocol,i.hostname,s)?{tier:`none`,credentialArgs:[]}:await aa(i.hostname,o,{}),l=la(),u=re({baseDir:r,config:c.credentialArgs.length>=2?[c.credentialArgs[1]]:[],unsafe:{allowUnsafeCredentialHelper:!0}}).env(l),d=-1;u.outputHandler((e,n,r)=>{r.on(`data`,e=>{let n=e.toString(`utf-8`);for(let e of n.split(`
|
|
21
21
|
`)){let n=ca(e);n&&n.pct!==d&&(d=n.pct,q(t.json,{type:`progress`,pct:n.pct,stage:n.stage}),t.json||process.stderr.write(`\r Cloning ${n.pct}%`))}})}),await fa({branch:typeof t.branch==`string`&&t.branch.length>0?t.branch:null,clone:t=>u.clone(e,a,t),onFallback:e=>{q(t.json,{type:`branch-fallback`,branch:e}),t.json||process.stderr.write(`\n Branch '${e}' not found upstream — cloning default branch instead.\n`)}}),t.json||process.stderr.write(`
|
|
22
|
-
`);try{let{runInit:e}=await import(`./init-
|
|
22
|
+
`);try{let{runInit:e}=await import(`./init-BXiJM0TD.mjs`),n=await e({cwd:a,mcp:!1});if(n.contentUpdated.length>0){let e=`auto-init: updated ${n.contentUpdated.join(`, `)}`;t.json?q(!0,{type:`warning`,message:e}):process.stderr.write(` ${e}\n`)}}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`auto-init: ${n}`}):process.stderr.write(` auto-init: ${n}\n`)}try{ha(a)}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`git-exclude: ${n}`}):process.stderr.write(` git-exclude: ${n}\n`)}return a}function ha(e){let t=yt(e,[`.ok/`]);return t.kind===`no-exclude`?`no-exclude`:t.kind===`refused-tracked`?`already-present`:t.appended.length>0?`appended`:`already-present`}function ga(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 ma(t,{json:r.json,dir:n,branch:r.branch??null},i);if(r.json)q(!0,{type:`complete`,dir:a});else{process.stderr.write(`✓ Cloned to ${a}\n`),process.chdir(a);let{startCommand:t}=await import(`./start-B9uo1X-i.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){let t=e instanceof Error?e.message:String(e);r.json?q(!0,{type:`error`,message:t}):process.stderr.write(`✗ ${t}\n`),process.exitCode=1}})}var _a=c();const va=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],[`server`,`port`],...r.map(e=>e.path)];function ya(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??Ft;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 ba(e){let t=(0,_a.parseDocument)(I(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 va)t.hasIn(e)&&n.push(e.join(`.`));return n}function xa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Sa(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=xa(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}async function Ca(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(),s=e.writeConfigPatchFn??ze,c=[];(r===`project`||r===`both`)&&c.push({scope:`project`,absPath:be(`project`,a,e.homedirOverride)}),(r===`user`||r===`both`)&&c.push({scope:`user`,absPath:be(`user`,a,e.homedirOverride)});let l=[],u=!0;for(let{scope:t,absPath:n}of c){if(!P(n)){l.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=ba(n)}catch(e){let r=e instanceof Error?e.message:String(e);l.push({path:n,scope:t,found:[],removed:[],error:r}),u=!1;continue}if(r.length===0||i){l.push({path:n,scope:t,found:r,removed:[]});continue}let c=await s({cwd:a,scope:t,patch:Sa(va.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!c.ok){l.push({path:n,scope:t,found:r,removed:[],error:o(c.error)}),u=!1;continue}l.push({path:n,scope:t,found:r,removed:r})}for(let e of l)e.error&&n(`✗ ${e.path}: ${e.error}`);let d=l.some(e=>e.error!==void 0),f=l.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 l)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:l,ok:u}}function wa(){let e=new t(`config`).description(`Inspect and maintain Open Knowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{ya({}).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 Ca({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}var Ta=e(nt(),1),J=e(Ut(),1);const Ea=new Set([`doc.name`]);function Da(e){return`doc:${Sn(`blake2b512`,{outputLength:32}).update(e).digest(`hex`).slice(0,8)}`}function Oa(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 ka(e,t){let n=t.originalToHashed.get(e);if(n!==void 0)return n;let r=Da(e);return t.originalToHashed.set(e,r),Oa(t,e,r),r}function Aa(e,t){return t.length===0||!e.includes(t)?e:e.split(t).join(`<CONTENT_DIR>`)}function ja(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ma(e,t){if(typeof e==`string`)return Aa(e,t.contentDir);if(Array.isArray(e))return e.map(e=>Ma(e,t));if(!ja(e))return e;let n=typeof e.key==`string`&&Ea.has(e.key)&&ja(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`&&ja(a)){let e=ka(n,t);r[i]={...a,stringValue:e}}else Ea.has(i)&&typeof a==`string`?r[i]=ka(a,t):r[i]=Ma(a,t);return r}function Na(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 Pa(e,t){let n=I(e,`utf-8`);if(n.length===0)return;let r=n.endsWith(`
|
|
23
23
|
`),i=n.split(`
|
|
24
24
|
`),a=[];for(let e=0;e<i.length;e++){let n=i[e]??``;if(!(e===i.length-1&&n===``)){if(n.length===0){a.push(``);continue}try{let e=Ma(JSON.parse(n),t);a.push(JSON.stringify(e))}catch{a.push(n)}}}L(e,r?`${a.join(`
|
|
25
25
|
`)}\n`:a.join(`
|
|
@@ -50,7 +50,7 @@ ws.addEventListener('error', () => process.exit(1));
|
|
|
50
50
|
setTimeout(() => process.exit(2), ${t+1e4});
|
|
51
51
|
`),r}async function Ko(e,t,n,r,i){let a=Go(e,t,z(r,`cpu.cpuprofile`)),o=!1,s=M(process.execPath,[a],{stdio:`ignore`}),c=setInterval(()=>{let e=Vo(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{nn(z(a,`..`),{recursive:!0,force:!0})}catch{}return o}function qo(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(`
|
|
52
52
|
`)}async function Jo(e,t={}){let{pid:n,cpuProfileSecs:r=15,noInspector:i=!1}=e,a=t.log??(e=>console.log(e)),o=t.discover??Tt,s=t.inspect??Et,c=t.resolveCommand??Ot,l=t.resolveUsage??Mt,u=t.collectLsofFn??Ho,d=t.getEndpoints??Wo,f=t.profiler??Ko,p=t.isAlive??(e=>{try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}),m=t.sendSignal??((e,t)=>{process.kill(e,t)}),h=t.sleep??(e=>new Promise(t=>setTimeout(t,e))),g=r*1e3;if(!p(n)){a(J.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?z(v,`.ok`,`local`,`diagnostics`,`process-${n}-${b}`):z(process.cwd(),`ok-diagnose-${n}-${b}`);try{F(x,{recursive:!0})}catch(e){a(J.default.red(`Cannot create output directory ${x}: ${e.message}`));return}a(J.default.bold(`Diagnosing pid ${n}`)),a(`Output: ${x}`),a(``);let S=(e,t)=>{L(z(x,e),t),a(` wrote ${e}`)},C=c(n),ee=l(n);S(`metadata.json`,JSON.stringify({capturedAt:new Date().toISOString(),pid:n,command:C,usage:ee,lockInfo:y},null,2)),a(` sampling lsof`);let w=u(n);if(w&&S(`lsof.txt`,w),!i){let e=w?Uo(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(J.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(J.default.yellow(` CPU profile capture failed`)),t.length>0&&S(`process-stats.jsonl`,`${t.map(e=>JSON.stringify(e)).join(`
|
|
53
|
-
`)}\n`);try{S(`stacks.txt`,qo(I(z(x,`cpu.cpuprofile`),`utf-8`)))}catch(e){a(J.default.yellow(` stacks.txt skipped: ${e.message}`))}}}else a(J.default.yellow(` Node inspector unavailable — skipping CPU profile`))}a(``),a(J.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: ${J.default.bold(x)}`)}async function Yo(e){let t=An({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function Xo(e){let t=Qt(z(gn(),`ok-bundle-process-`));return await Jo({pid:e,output:t}),t}function Zo(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 Qo(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function $o(e,t,n){let{summary:r,manifest:i}=t;e(``),e(J.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${Zo(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 es(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??Yo,i=t.runProcessDiagnose??Xo,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=sn(o);if(!P(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=z(e.contentDir,`.ok`,`local`,`diagnostics`);F(n,{recursive:!0}),o=z(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(J.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await go({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(J.default.yellow(` server not running — live state unavailable`)),$o(n,c,o),e.yes!==!0&&!Qo(await r(`Write bundle? [y/N]: `))?(n(J.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await _o({collected:c,outputPath:o}),n(J.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{nn(s,{recursive:!0,force:!0})}catch{}}}function ts(){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(J.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(J.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await Jo({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(Bo()),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(J.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-
|
|
53
|
+
`)}\n`);try{S(`stacks.txt`,qo(I(z(x,`cpu.cpuprofile`),`utf-8`)))}catch(e){a(J.default.yellow(` stacks.txt skipped: ${e.message}`))}}}else a(J.default.yellow(` Node inspector unavailable — skipping CPU profile`))}a(``),a(J.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: ${J.default.bold(x)}`)}async function Yo(e){let t=An({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function Xo(e){let t=Qt(z(gn(),`ok-bundle-process-`));return await Jo({pid:e,output:t}),t}function Zo(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 Qo(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function $o(e,t,n){let{summary:r,manifest:i}=t;e(``),e(J.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${Zo(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 es(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??Yo,i=t.runProcessDiagnose??Xo,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=sn(o);if(!P(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=z(e.contentDir,`.ok`,`local`,`diagnostics`);F(n,{recursive:!0}),o=z(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(J.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await go({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(J.default.yellow(` server not running — live state unavailable`)),$o(n,c,o),e.yes!==!0&&!Qo(await r(`Write bundle? [y/N]: `))?(n(J.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await _o({collected:c,outputPath:o}),n(J.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{nn(s,{recursive:!0,force:!0})}catch{}}}function ts(){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(J.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(J.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await Jo({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(Bo()),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(J.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-BaagpcJC.mjs`),{resolveContentDir:r}=await import(`./dist-De0GFsdh.mjs`),i=process.cwd(),{config:a}=n(i);await es({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(J.default.red(t)),process.exit(1)}}),e}async function ns(){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 Rr({message:`Enter OpenAI embeddings API key:`})).trim()}function rs(e){return Qe(e)}async function is(){return(await We()).file?{present:!0,source:`file`}:process.env.OK_EMBEDDINGS_API_KEY?{present:!0,source:`env`}:{present:!1,source:null}}async function as(e){try{let t=m(Ce(e));if(!t||t.port<=0||!y(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 os(){return new t(`set-key`).description(`Store your OpenAI embeddings API key in ~/.ok/secrets.yml`).action(async()=>{let e=await ns();if(!e){process.stderr.write(`No key provided.
|
|
54
54
|
`),process.exitCode=1;return}await pe().set(e),process.stderr.write(`✓ OpenAI embeddings API key stored in ~/.ok/secrets.yml (0600, this machine only).
|
|
55
55
|
Now enable it per project — the easiest path is OK Desktop → Settings → This
|
|
56
56
|
project → Search (a toggle with an egress-confirmation prompt), or run
|
|
@@ -70,7 +70,7 @@ project → Search (a toggle with an egress-confirmation prompt), or run
|
|
|
70
70
|
`).filter(e=>e.startsWith(`worktree `)).length}catch{return 0}}function Sl(e){let t=B(e);for(;;){if(ie(t))return t;let n=sn(t);if(n===t)throw Error(`No Open Knowledge project found at or above ${e}. Pass an explicit \`cwd\` argument that points inside an OK project (a directory with a \`${g}\`).`);t=n}}function Cl(e){try{let t=new URL(e);return t.protocol===`file:`?bn(t):void 0}catch{return}}async function wl(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=Cl(n[0].uri);return r===void 0&&e.log?.(`single root URI not usable as fs path: ${n[0].uri}`),r}async function Tl(e,t,n,r=Sl){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 El(e){let t=process.stderr,n=e.spawnTimeoutMs??il(process.env.OK_MCP_SPAWN_TIMEOUT_MS),r=e.envAutoStart??process.env.OK_MCP_AUTOSTART,i=It({startupCwd:e.startupCwd,startupConfig:e.startupConfig}),a=new Ee({name:se,version:_},{instructions:$e({dir:`.`})});ue(a);let o=Cn(),s={current:{connectionId:o,displayName:o,colorSeed:o}},c=new Map,l=e=>{if(c.has(e))return;let n=oe(e),r=s.current,i=Ts({connectionId:o,displayName:r.displayName,clientName:r.clientInfo?.name??r.displayName,colorSeed:r.colorSeed,resolveWsUrl:async()=>gl({lockDir:n,contentDir:e},``),log:n=>t.write(`[mcp] keepalive[${e}]: ${n}\n`)});c.set(e,i)},u=()=>wl({getClientCapabilities:()=>a.server.getClientCapabilities(),listRoots:()=>a.server.listRoots(),log:e=>t.write(`[mcp] ${e}\n`)}),d,f=!1,p=async e=>{if(f)return;f=!0;let n=await xl(e);if(n<=1){f=!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{}},m=async e=>{let t=await Tl(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 Open Knowledge project, or have the MCP client advertise a single root.");return t.viaRootGuess&&p(t.projectDir),t.projectDir},h=async e=>{let t=await Tl(e,d,u);if(d=t.nextSticky??d,t.projectDir===void 0)return;t.viaRootGuess&&p(t.projectDir);let a=t.projectDir,o=await i(a),s=await hl({lockDir:oe(a),contentDir:ae(o,a),envAutoStart:r,...n===void 0?{}:{timeoutMs:n}});return l(a),s.replace(/\/mcp$/,``)};a.server.oninitialized=()=>{let e=a.server.getClientVersion(),t=Ne(e?.name,o);s.current={connectionId:o,clientInfo:e?{name:t,version:e.version}:void 0,displayName:t,colorSeed:t}},ve(a,{serverUrl:h,resolveCwd:m,config:i,identityRef:s});let g=new ks,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(),g.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(g),t.write(`[mcp] global stdio server ready (per-call project routing)
|
|
71
71
|
`);let S=!1,C=()=>{S||(S=!0,setTimeout(()=>{t.write(`[mcp] shutdown deadline (5s) reached — forcing exit(1)
|
|
72
72
|
`),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
|
|
73
|
-
`),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=Ns({getPpid:()=>process.ppid,onHostGone:e=>{t.write(`[mcp] ${e} — shutting down\n`),C()}}),Ps({log:e=>t.write(`${e}\n`),transport:g,process,stdin:process.stdin}),process.platform===`darwin`){let e=Ms(yl,{realpathSync:tn,statInoSync:e=>rn(e).ino,log:e=>t.write(`${e}\n`)});if(e!==void 0){t.write(`[mcp] bundle identity anchor=${e.resolvedPath} inode=${e.inode} version=${_}\n`);let{resolvedPath:n,inode:r}=e;y=js({detect:()=>As({bundleAnchorPath:yl,currentInode:r,platform:process.platform,realpath:tn,statInode:e=>rn(e).ino}),onReplaced:e=>{t.write(`[mcp] bundle replaced anchor=${n} bootInode=${e.currentInode} onDiskInode=${e.onDiskInode} version=${_} — exiting for host respawn\n`),C()},log:e=>t.write(`[mcp] ${e}\n`)})}}return{close:x}}function Dl(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=il(process.env.OK_MCP_SPAWN_TIMEOUT_MS);await vl({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=Ss(process.env,i,process.platform);if(a.proxy){let e=xs(process.platform,pn(),{existsSync:P});if(e===null)Cs({stderr:process.stderr,mode:`fallback-absent`,bundlePath:null,reason:`no installed Open Knowledge.app bundle found`});else try{await ws({bundlePath:e,argv:process.argv.slice(2),env:process.env,stderr:process.stderr});return}catch(t){Cs({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`;Cs({stderr:process.stderr,mode:e,bundlePath:null,reason:null})}await El({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 Ol(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function kl(e=()=>Vt(zt())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>he({lockDir:Ce(e)}).baseUrl,openTarget:e=>{M(`open`,[e],{detached:!0,stdio:`ignore`,env:Ol(process.env)}).unref()},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function Al(e,t,n){let r=B(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 Open Knowledge 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 Open Knowledge desktop app.`),0}let o=n.resolveBaseUrl(r);if(o){let e=`${o}/#/${Re(a)}`;return n.openTarget(e),n.log(`Opening ${a} in your browser: ${e}`),0}return n.error("No Open Knowledge desktop app found and no UI is running. Install OK Desktop, or start a UI with `ok ui`, then retry."),1}function jl(){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=Al(e,t,kl())})}function Ml(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-
|
|
73
|
+
`),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=Ns({getPpid:()=>process.ppid,onHostGone:e=>{t.write(`[mcp] ${e} — shutting down\n`),C()}}),Ps({log:e=>t.write(`${e}\n`),transport:g,process,stdin:process.stdin}),process.platform===`darwin`){let e=Ms(yl,{realpathSync:tn,statInoSync:e=>rn(e).ino,log:e=>t.write(`${e}\n`)});if(e!==void 0){t.write(`[mcp] bundle identity anchor=${e.resolvedPath} inode=${e.inode} version=${_}\n`);let{resolvedPath:n,inode:r}=e;y=js({detect:()=>As({bundleAnchorPath:yl,currentInode:r,platform:process.platform,realpath:tn,statInode:e=>rn(e).ino}),onReplaced:e=>{t.write(`[mcp] bundle replaced anchor=${n} bootInode=${e.currentInode} onDiskInode=${e.onDiskInode} version=${_} — exiting for host respawn\n`),C()},log:e=>t.write(`[mcp] ${e}\n`)})}}return{close:x}}function Dl(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=il(process.env.OK_MCP_SPAWN_TIMEOUT_MS);await vl({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=Ss(process.env,i,process.platform);if(a.proxy){let e=xs(process.platform,pn(),{existsSync:P});if(e===null)Cs({stderr:process.stderr,mode:`fallback-absent`,bundlePath:null,reason:`no installed Open Knowledge.app bundle found`});else try{await ws({bundlePath:e,argv:process.argv.slice(2),env:process.env,stderr:process.stderr});return}catch(t){Cs({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`;Cs({stderr:process.stderr,mode:e,bundlePath:null,reason:null})}await El({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 Ol(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function kl(e=()=>Vt(zt())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>he({lockDir:Ce(e)}).baseUrl,openTarget:e=>{M(`open`,[e],{detached:!0,stdio:`ignore`,env:Ol(process.env)}).unref()},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function Al(e,t,n){let r=B(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 Open Knowledge 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 Open Knowledge desktop app.`),0}let o=n.resolveBaseUrl(r);if(o){let e=`${o}/#/${Re(a)}`;return n.openTarget(e),n.log(`Opening ${a} in your browser: ${e}`),0}return n.error("No Open Knowledge desktop app found and no UI is running. Install OK Desktop, or start a UI with `ok ui`, then retry."),1}function jl(){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=Al(e,t,kl())})}function Ml(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-BGQyMIgQ.mjs`),r=e(),i=process.cwd(),a=ae(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 Z(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function Nl(e,t,n=process.cwd()){let r=e.op??`sync`,i=m(Ce(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`,...C({kind:`cli`,runtimeVersion:_})},body:JSON.stringify({op:r})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.title??e.error??e.message??`Server responded with ${n.status}`)}Z(e.json,{type:`triggered`,op:r,port:i.port}),e.json||process.stderr.write(`✓ ${r} triggered\n`);return}catch(t){let n=t instanceof Error?t.message:String(t);e.json||process.stderr.write(`Server trigger failed (${n}), running directly\n`)}}e.json||process.stderr.write(`Running ${r} directly (no live server)\n`);let a=re({baseDir:n});if(r===`sync`||r===`pull`){Z(e.json,{type:`step`,step:`pull`});let t=await a.pull();Z(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Z(e.json,{type:`step`,step:`push`}),await a.push(),Z(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
|
|
74
74
|
`)),Z(e.json,{type:`complete`,op:r}),e.json||process.stderr.write(`✓ ${r} complete\n`)}function Pl(e){return new t(`sync`).description(`Commit, pull, and push to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Nl({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 Fl(e){return new t(`pull`).description(`Pull changes from the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Nl({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 Il(e){return new t(`push`).description(`Push commits to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Nl({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 Ll(e){return typeof e==`string`&&ye.includes(e)}async function Rl(e={}){let t=B(e.cwd??process.cwd()),n=e.pack??`knowledge-base`;if(!Oe[n])return{status:`failed`,message:`${k(`Error:`)} Unknown pack "${n}". Available: ${ye.join(`, `)}`,exitCode:1};let r;try{r=await tt({projectDir:t,rootDir:e.root,packId:n})}catch(e){return e instanceof Ye?{status:`prerequisite-missing`,message:`${k(`Error:`)} ${e.message}`,exitCode:1}:{status:`failed`,message:`${k(`Error:`)} ${e instanceof Error?e.message:String(e)}`,exitCode:1}}if(r.created.length===0){let e=Oe[n].name;return{status:`no-op`,message:`${O(`Your ${e} pack is already seeded.`)}\n${D(`Nothing to do.`)}`,plan:r,exitCode:0}}if(e.dryRun)return{status:`dry-run`,message:`${j(`Plan (dry-run — no changes made):`)}\n\n${Bl(r,t)}`,plan:r,exitCode:0};if(!e.yes&&!await Vl(`${j(`Plan:`)}\n\n${Bl(r,t)}\n\n${j(`Apply?`)} ${D(`[Y/n] `)}`,e.confirmStream))return{status:`cancelled`,message:D(`Cancelled.`),plan:r,exitCode:0};let i=await He(r,{projectDir:t,packId:n});if(i.errors.length>0){let e=i.errors.map(e=>` ${k(`✗`)} ${e.path}: ${e.error}`);return{status:`failed`,message:[`${A(`Applied`)} ${i.applied} entries, ${A(String(i.errors.length))} error(s):`,...e].join(`
|
|
75
75
|
`),plan:r,exitCode:1}}let a=Oe[n].name,o=i.packSkillsInstalled.length>0?`\n${D(`Installed the ${a} skill for: ${i.packSkillsInstalled.join(`, `)}`)}`:``;return{status:`applied`,message:`${O(`✓ Seeded ${a}`)} ${D(`(${i.applied} entries, ${i.durationMs}ms)`)}${o}`,plan:r,exitCode:0}}function zl(){let e=[j(`Available packs:`)];for(let t of ye){let n=Oe[t];e.push(` ${O(t)} ${D(`—`)} ${n.name}: ${n.description}`)}return e.join(`
|
|
76
76
|
`)}function Bl(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(j(`Folders to create:`));for(let e of r)n.push(` ${O(`+`)} ${E(cn(t,B(t,e.path))||e.path)}${D(`/`)}`)}if(i.length>0){n.length>0&&n.push(``),n.push(j(`Files to create:`));for(let e of i)n.push(` ${O(`+`)} ${E(cn(t,B(t,e.path))||e.path)}`)}if(e.skipped.length>0){n.length>0&&n.push(``),n.push(D(`Already present (skipped):`));for(let t of e.skipped)n.push(` ${D(`· ${t.path} (${t.reason})`)}`)}if(e.warnings.length>0){n.length>0&&n.push(``),n.push(A(`Warnings:`));for(let t of e.warnings)n.push(` ${A(`!`)} ${t}`)}return n.join(`
|
|
@@ -79,7 +79,7 @@ project → Search (a toggle with an egress-confirmation prompt), or run
|
|
|
79
79
|
`);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 Gl(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 Wl(t,await e())})}async function Kl(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 ql(e,t){let{host:n,json:r}=e;H(n);let i=await Pi(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 Kl(new K({auth:i,...a?{baseUrl:a}:{}}));if(o.kind===`ok`){if(r)process.stdout.write(`${JSON.stringify({type:`owners`,owners:o.owners})}\n`);else for(let e of o.owners)process.stdout.write(`${e.kind}\t${e.login}\n`);return}if(r){process.stdout.write(`${JSON.stringify({type:`error`,code:o.kind})}\n`);return}process.stderr.write(`✗ share owners failed: ${o.kind}\n`),process.exit(1)}function Jl(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 ql(t,await e())})}function Yl(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(`
|
|
80
80
|
`)??``}\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 Xl(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 Zl(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 Ql(e,t){return(await e.users.getAuthenticated()).data.login.toLowerCase()===t.toLowerCase()?`user`:`org`}function $l(e){return re({baseDir:e,unsafe:{allowUnsafeCredentialHelper:!0}}).env({GIT_TERMINAL_PROMPT:`0`})}function eu(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 tu={ensureOkScaffold:e=>{xe(e)},gitFactory:$l};async function nu(e){let t={...tu,...e.deps},n=B(e.projectDir),r;if(e.ownerKind)r=e.ownerKind;else try{r=await Ql(e.octokit,e.body.owner)}catch(e){return{kind:`error`,code:Yl(e)}}try{t.ensureOkScaffold(n)}catch{return{kind:`error`,code:`init-failed`}}let i=t.gitFactory(n);if(!P(z(n,`.git`)))try{await i.init()}catch{return{kind:`error`,code:`init-failed`}}let a;try{a=await Xl({octokit:e.octokit,ownerLogin:e.body.owner,ownerKind:r,name:e.body.name,visibility:e.body.visibility,description:e.body.description})}catch(t){if(Yl(t)===`name-conflict`){let t=await Zl(e.octokit,e.body.owner,e.body.name);if(t===null)return{kind:`error`,code:`name-conflict`};a=t}else return{kind:`error`,code:Yl(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=eu(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 ru(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 iu(e,t){let{host:n,owner:r,name:i,visibility:a,description:o,projectDir:s,json:c}=e;H(n);let l=await Pi(n,t);if(l==null){ru(c,{kind:`error`,code:`auth-required`});return}let u=n===`github.com`?void 0:`https://${n}/api/v3`,d=new K({auth:l,...u?{baseUrl:u}:{}});try{Kt(`git config user.email`,{cwd:s,stdio:`ignore`})}catch{process.env.GIT_AUTHOR_NAME??=`Open Knowledge`,process.env.GIT_AUTHOR_EMAIL??=`noreply@inkeep.com`,process.env.GIT_COMMITTER_NAME??=`Open Knowledge`,process.env.GIT_COMMITTER_EMAIL??=`noreply@inkeep.com`}ru(c,await nu({octokit:d,token:l,projectDir:s,body:{owner:r,name:i,visibility:a,description:o}}))}function au(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'
|
|
81
81
|
`),process.exit(1)),await iu(t,await e())})}function ou(){let e=new t(`share`);e.description(`Sharing flow operations (owners, name-check, publish)`);let n=()=>te();return e.addCommand(Jl(n)),e.addCommand(Gl(n)),e.addCommand(au(n)),e}function su(){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=B(e.project??process.cwd()),n=_t(t),r=st(t,ot(t));if(r.kind===`no-exclude`){cu(e.json,t,r.reason);return}let i=_t(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(`${E(`Sharing mode is already`)} ${j(`shared`)} ${E(`— nothing to do.`)}\n`);return}process.stderr.write(`${O(`✓`)} ${j(`Sharing mode set to`)} ${O(`shared`)}\n`),process.stderr.write(` Removed OK paths from ${j(`.git/info/exclude`)}; commit the files to share with teammates.\n`)})}function cu(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(`${A({"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 lu(){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=B(e.project??process.cwd()),n=_t(t),r=[...gt(t)],i=St(t,ot(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(`Open Knowledge sharing mode: ${uu(n)}`),a.push(``),a.push(`Excluded from git via ${j(`.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: ${E(n===`local-only`?`ok config-sharing share`:`ok config-sharing unshare`)}`),process.stdout.write(`${a.join(`
|
|
82
|
-
`)}\n`)})}function uu(e){switch(e){case`shared`:return O(`shared`);case`local-only`:return O(`local-only`);case`no-git`:return A(`no-git (not a git repository)`)}}function du(){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=B(e.project??process.cwd()),n=yt(t,ot(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`){fu(e.json,t,n.reason);return}let r=_t(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(`${j(`Sharing mode is already`)} ${O(`local-only`)} ${j(`— nothing to do.`)}\n`);return}process.stderr.write(`${O(`✓`)} ${j(`Sharing mode set to`)} ${O(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${j(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function fu(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(`${A({"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 pu(){let e=new t(`config-sharing`);return e.description(`Manage Open Knowledge's git-sharing mode (share OK config with the team, or keep local-only on this machine)`),e.addCommand(su()),e.addCommand(du()),e.addCommand(lu()),e}const mu=new Set([`--cwd`,`--log-level`]);function hu(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(`-`)){mu.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function gu(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 _u(e){return/\.(md|mdx)$/i.test(e)}function vu(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function yu(e=()=>Vt(zt())){return{prepare:Ie,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{M(`open`,[e],{detached:!0,stdio:`ignore`,env:vu(process.env)}).unref()},runProjectOpen:(e,t)=>Al(e,{project:t},kl()),runBrowserOpen:e=>Su(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function bu(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof Ve||e instanceof qe||e instanceof Pe)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 Open Knowledge desktop app.`),0}return await t.runBrowserOpen(n),0}function xu(){let e=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[B(e,`public`),B(e,`../../app/dist`),B(e,`../../../app/dist`)].find(e=>P(e))}async function Su(e){let{createEphemeralProjectDir:t}=await import(`./dist-
|
|
82
|
+
`)}\n`)})}function uu(e){switch(e){case`shared`:return O(`shared`);case`local-only`:return O(`local-only`);case`no-git`:return A(`no-git (not a git repository)`)}}function du(){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=B(e.project??process.cwd()),n=yt(t,ot(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`){fu(e.json,t,n.reason);return}let r=_t(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(`${j(`Sharing mode is already`)} ${O(`local-only`)} ${j(`— nothing to do.`)}\n`);return}process.stderr.write(`${O(`✓`)} ${j(`Sharing mode set to`)} ${O(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${j(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function fu(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(`${A({"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 pu(){let e=new t(`config-sharing`);return e.description(`Manage Open Knowledge's git-sharing mode (share OK config with the team, or keep local-only on this machine)`),e.addCommand(su()),e.addCommand(du()),e.addCommand(lu()),e}const mu=new Set([`--cwd`,`--log-level`]);function hu(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(`-`)){mu.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function gu(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 _u(e){return/\.(md|mdx)$/i.test(e)}function vu(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function yu(e=()=>Vt(zt())){return{prepare:Ie,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{M(`open`,[e],{detached:!0,stdio:`ignore`,env:vu(process.env)}).unref()},runProjectOpen:(e,t)=>Al(e,{project:t},kl()),runBrowserOpen:e=>Su(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function bu(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof Ve||e instanceof qe||e instanceof Pe)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 Open Knowledge desktop app.`),0}return await t.runBrowserOpen(n),0}function xu(){let e=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[B(e,`public`),B(e,`../../app/dist`),B(e,`../../../app/dist`)].find(e=>P(e))}async function Su(e){let{createEphemeralProjectDir:t}=await import(`./dist-De0GFsdh.mjs`),{loadConfig:n}=await import(`./index.mjs`),{bootStartServer:r,resolveHost:i}=await import(`./start-B9uo1X-i.mjs`),{openBrowser:a}=await import(`./open-browser-DHTbHSqx.mjs`),o=xu();o||(process.stderr.write("Open Knowledge 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 xn(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}/#/${Re(e.docName)}`;process.stdout.write(`Opening ${e.singleDocRelPath} in your browser: ${m}\n`),process.stdout.write(`Press Ctrl-C to close the session.
|
|
83
83
|
`),a(m),await new Promise(()=>{})}function Cu(e,t){return{server:wu(`server`,e),ui:wu(`ui`,t)}}function wu(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 Tu(e){return`${Eu(e.server)}\n${Eu(e.ui)}`}function Eu(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 Du(e){let t=e.inspect??(t=>Et(e.lockDir,t)),n=e.log??(e=>console.log(e)),r=Cu(t(`server`),t(`ui`));return e.json?n(JSON.stringify(r,null,2)):n(Tu(r)),r}function Ou(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(),Du({lockDir:Ce(process.cwd()),json:t.json===!0})})}function ku(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(`
|
|
84
84
|
`)}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 $,Au;function ju(){return Au}Q.name(`open-knowledge`).description(`Local-first knowledge base with CRDT collaboration`).usage(`[options] [file | command]`).version(ku(Nt)).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=At(n,process.cwd());r!==null&&(wt(process.cwd()),process.chdir(r),console.error(`[ok] Using Open Knowledge project at ${r}`));let{config:i}=Ft(r??t);$=i;let a=e.args?.[0]??e.name()??`cli`;Au=ke({name:`cli`,project:i.project?.name??void 0}),Au.info({command:a,cwd:process.cwd()},`cli command started`)}),Q.action(async()=>{if(Vt(zt()).available){Lt({spawn:M});return}await Bt($,{})});const Mu=Rt(()=>$);Q.addCommand(Mu);const Nu=Dl(()=>$);Q.addCommand(Nu),Q.addCommand(bt()),Q.addCommand(Hl()),Q.addCommand(vs()),Q.addCommand(Wt());const Pu=Ml(()=>$);Q.addCommand(Pu);const Fu=xt(()=>$);Q.addCommand(Fu),Q.addCommand(jl()),Q.addCommand(Dt(()=>$)),Q.addCommand(ia(()=>$)),Q.addCommand(Ou(()=>$)),Q.addCommand(jt()),Q.addCommand(ts()),Q.addCommand(ta()),Q.addCommand(wa()),Q.addCommand(Ui(ju)),Q.addCommand(us()),Q.addCommand(ga(()=>$)),Q.addCommand(Pl(()=>$)),Q.addCommand(Il(()=>$)),Q.addCommand(Fl(()=>$)),Q.addCommand(ou()),Q.addCommand(pu()),Q.addHelpText(`after`,`
|
|
85
85
|
Examples:
|