@inkeep/open-knowledge 0.58.7 → 0.58.8
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/{acp-harness-probe-B6b6chsm.mjs → acp-harness-probe-C2IHuVgy.mjs} +2 -2
- package/dist/cli.mjs +6 -6
- package/dist/constants-CaZ6pf_w.mjs +2 -0
- package/dist/fs-traced-C1nHpvFb.mjs +1 -0
- package/dist/{fs-traced-CJ0NSnI0.mjs → fs-traced-Dy67FR5_.mjs} +2 -2
- package/dist/git-handle-BPPRdjZZ.mjs +1 -0
- package/dist/{git-handle-DDFppGcc.mjs → git-handle-KDk0khh5.mjs} +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{init-3RLwbQaj.mjs → init-097BT-JV.mjs} +3 -3
- package/dist/init-wif6tBNp.mjs +1 -0
- package/dist/{launch-json-removal-CTPT8xSE.mjs → launch-json-removal-CmteoVKJ.mjs} +2 -2
- package/dist/{loader-CIbOOQlE.mjs → loader-C7KxwdAY.mjs} +2 -2
- package/dist/loader-CihrsBwk.mjs +1 -0
- package/dist/md-manager-CdRw_aqi.mjs +2 -0
- package/dist/{open-browser-CHSsUL5t.mjs → open-browser-BklPlV75.mjs} +2 -2
- package/dist/parse-worker.mjs +1 -1
- package/dist/{preview-7Dq6jlVC.mjs → preview-ByTvhfy1.mjs} +2 -2
- package/dist/preview-CbPgjt4U.mjs +1 -0
- package/dist/public/assets/{ActivityModeContent-7I3FAqNa.js → ActivityModeContent-BIn008__.js} +1 -1
- package/dist/public/assets/{AgentDiffPane-BQC85Rn1.js → AgentDiffPane-3GMOCb2c.js} +1 -1
- package/dist/public/assets/{AgentThreadClientBinder-q7HjbS_V.js → AgentThreadClientBinder-Di2dPu4h.js} +1 -1
- package/dist/public/assets/{CodeMirrorPropInput-Bf5PV704.js → CodeMirrorPropInput-BKSuOOVi.js} +1 -1
- package/dist/public/assets/{DocumentContext-YI07j2yc.js → DocumentContext-C-X4T4d9.js} +1 -1
- package/dist/public/assets/{EditorModeToggle-B3XSSPCP.js → EditorModeToggle-CPKSIpqP.js} +1 -1
- package/dist/public/assets/{EnableSyncConfirmDialog-DrBUTfFU.js → EnableSyncConfirmDialog-B9GQfDxa.js} +1 -1
- package/dist/public/assets/{ExcalidrawDocEditor-T3TL3VQu.js → ExcalidrawDocEditor-CiuG3mW7.js} +1 -1
- package/dist/public/assets/FeedbackForm-DYjADexF.js +1 -0
- package/dist/public/assets/{GraphPanel-B_Mg9p1O.js → GraphPanel-DT-1F3b4.js} +1 -1
- package/dist/public/assets/{ImportSkillDialog-B5zHicwe.js → ImportSkillDialog-d6lkfU9h.js} +1 -1
- package/dist/public/assets/{LintConfigEditor-D5Dg5HLZ.js → LintConfigEditor-BEaCP-Xa.js} +1 -1
- package/dist/public/assets/{ManagedArtifactProperties-WOaAexG2.js → ManagedArtifactProperties-CI77JvTy.js} +1 -1
- package/dist/public/assets/ManagedArtifactProperties-RawOG82I.js +1 -0
- package/dist/public/assets/{MermaidDocEditor-CwD8mOHB.js → MermaidDocEditor-3Qy_xxrY.js} +1 -1
- package/dist/public/assets/{PropertyDisplayRow-CKXJ3p74.js → PropertyDisplayRow-jv0QSvvc.js} +1 -1
- package/dist/public/assets/{ReportBugDialogBody-CVQgnZSP.js → ReportBugDialogBody-CD42zSIE.js} +1 -1
- package/dist/public/assets/{SchemaConfigEditor-kvdPUUAX.js → SchemaConfigEditor-DRPb60r3.js} +1 -1
- package/dist/public/assets/{SessionsHost-x_FfXVKL.js → SessionsHost-0wztntvc.js} +2 -2
- package/dist/public/assets/{SettingsDialogBody-CgHSjRrN.js → SettingsDialogBody-CguEJilL.js} +2 -2
- package/dist/public/assets/{ShareBranchSwitchDialog-DIQmuIkz.js → ShareBranchSwitchDialog-DD3l5H06.js} +1 -1
- package/dist/public/assets/{ShareReceiveDialog-BWuqWxsw.js → ShareReceiveDialog-D5BGQzdA.js} +1 -1
- package/dist/public/assets/{ShareReceiveMissDialog-DBLKwZ22.js → ShareReceiveMissDialog-QiuppiTF.js} +1 -1
- package/dist/public/assets/{SkillCostValue-6xiHOBnl.js → SkillCostValue-D8ebP6Zc.js} +1 -1
- package/dist/public/assets/{SkillEditBanner-BqzwArWv.js → SkillEditBanner-BkzopHHR.js} +1 -1
- package/dist/public/assets/{SkillInstallMenu-BXOomxqv.js → SkillInstallMenu-B7luagyu.js} +1 -1
- package/dist/public/assets/{SkillOriginInline-B1B3kTSz.js → SkillOriginInline-BvpULx0r.js} +1 -1
- package/dist/public/assets/{SkillToolbarControls-NUcxAczC.js → SkillToolbarControls-Dzsdm7PA.js} +1 -1
- package/dist/public/assets/{SlidesToolbarControls-BZvu5Syj.js → SlidesToolbarControls-CoX9pn5-.js} +1 -1
- package/dist/public/assets/{SourceEditor-DYdjbyzp.js → SourceEditor-QZM8qnoP.js} +1 -1
- package/dist/public/assets/{TerminalPanel-DkxYnA6s.js → TerminalPanel-gvD8j_Io.js} +1 -1
- package/dist/public/assets/{TerminalWindowApp-CEKKfG52.js → TerminalWindowApp-CAceqDR9.js} +1 -1
- package/dist/public/assets/{TextDocEditor-CaNNKmLz.js → TextDocEditor-tkRGKEq5.js} +1 -1
- package/dist/public/assets/ThreadView-BMvSxzC4.js +14 -0
- package/dist/public/assets/{TimelineDiffPane-yi7kMXSo.js → TimelineDiffPane-DDkbig_i.js} +1 -1
- package/dist/public/assets/{agent-diff-store-SkFUI7rS.js → agent-diff-store-kz-Y8I6f.js} +1 -1
- package/dist/public/assets/{auth-state-cache-DbD6wjBD.js → auth-state-cache-CXBlrCdD.js} +2 -2
- package/dist/public/assets/client-version-B1ECEFiM.js +1 -0
- package/dist/public/assets/{comment-chips-DiZPWTPl.js → comment-chips-ZBz8P1qB.js} +1 -1
- package/dist/public/assets/{config-provider-USxiO_wH.js → config-provider-j9ER9l4W.js} +3 -3
- package/dist/public/assets/{dist-DGemBD_J.js → dist-7P3QNiAv.js} +2 -2
- package/dist/public/assets/{doc-paths-BkpejoFL.js → doc-paths-DPQCXAM6.js} +1 -1
- package/dist/public/assets/{documents-events-B2g_1xMi.js → documents-events-DSYMSbrh.js} +1 -1
- package/dist/public/assets/{file-tree-adapter-Bo3rGytc.js → file-tree-adapter-DWQqMzJU.js} +1 -1
- package/dist/public/assets/{file-tree-utils-CzXn1zjH.js → file-tree-utils-CCGJg4dv.js} +1 -1
- package/dist/public/assets/{folder-config-api-DPWmRi8a.js → folder-config-api-BFcRWayL.js} +1 -1
- package/dist/public/assets/{follow-file-DWqYp0pE.js → follow-file-DInAFQK_.js} +2 -2
- package/dist/public/assets/globals-DZLrtRra.css +1 -0
- package/dist/public/assets/i18n-8WVAXtMP.js +1 -0
- package/dist/public/assets/{index-C6Xk875v.js → index-CW5V3fEN.js} +8 -8
- package/dist/public/assets/{lint-config-client-sK38eqbj.js → lint-config-client-D0R0SOyp.js} +1 -1
- package/dist/public/assets/{markdownlint-rule-browser-T68WxSIo.js → markdownlint-rule-browser-C-ng_hpW.js} +1 -1
- package/dist/public/assets/{messages-D2-S61MT.js → messages-B1AtMu4g.js} +1 -1
- package/dist/public/assets/{messages-CgyRKo5g.js → messages-BOin2R2m.js} +1 -1
- package/dist/public/assets/{messages-Cdv9hd10.js → messages-BSAPNWhz.js} +1 -1
- package/dist/public/assets/{messages-Fy0K5qZm.js → messages-CHMN5vzg.js} +1 -1
- package/dist/public/assets/{messages-BFlTGREq.js → messages-CVdYp7oq.js} +1 -1
- package/dist/public/assets/{messages-Daexf5KZ.js → messages-CrhnZzfX.js} +1 -1
- package/dist/public/assets/{messages-D_5Iek_V.js → messages-D1a_S47U.js} +1 -1
- package/dist/public/assets/{messages-BP5GGrRC.js → messages-D7G9yvga.js} +1 -1
- package/dist/public/assets/{messages-BN7zDSVo.js → messages-DFzggSxO.js} +1 -1
- package/dist/public/assets/{messages-DQkd1f5c.js → messages-DQUtt-5a.js} +1 -1
- package/dist/public/assets/{messages-D13EOsYw.js → messages-QRz1xKWv.js} +1 -1
- package/dist/public/assets/{messages-DvC9XHhc.js → messages-ugbFvlbF.js} +1 -1
- package/dist/public/assets/{navigation-targets-D6rHX3Pq.js → navigation-targets-BI4fIUSN.js} +1 -1
- package/dist/public/assets/{open-managed-artifact-tab-ENQgQOde.js → open-managed-artifact-tab-DUwaeWfA.js} +1 -1
- package/dist/public/assets/{pending-receive-nav-store-BaBTyiLf.js → pending-receive-nav-store-Crc_XCGA.js} +1 -1
- package/dist/public/assets/{prop-types-CizsurD0.js → prop-types-tU6-fOmD.js} +1 -1
- package/dist/public/assets/{receive-store-DHalgzeU.js → receive-store-BzLz5gZK.js} +1 -1
- package/dist/public/assets/{selection-context-DV36ssJQ.js → selection-context-CnpF-Ed9.js} +1 -1
- package/dist/public/assets/{skill-actions-ayyLVAw5.js → skill-actions-BdLNV2ET.js} +1 -1
- package/dist/public/assets/{skill-scope-gUkJkFRO.js → skill-scope-CRZYtnmj.js} +1 -1
- package/dist/public/assets/{skills-api-DO54o34O.js → skills-api-DT1cIHsu.js} +1 -1
- package/dist/public/assets/{src-B3OD2BqU.js → src-BHnBKao9.js} +1 -1
- package/dist/public/assets/{tag-pill-input-D2qVy9HA.js → tag-pill-input-Bcant_jp.js} +1 -1
- package/dist/public/assets/{target-navigation-intent-BqElNT05.js → target-navigation-intent-Bd_1P8q5.js} +1 -1
- package/dist/public/assets/{telemetry-impl-DhefnhPq.js → telemetry-impl-u08eIZFn.js} +1 -1
- package/dist/public/assets/{telemetry-startup--1E51CEj.js → telemetry-startup-PYGQzY-J.js} +1 -1
- package/dist/public/assets/{terminal-cli-display-BTQdEy1j.js → terminal-cli-display-Dcm1esjR.js} +1 -1
- package/dist/public/assets/{terminal-launch-events-DNmxO4ft.js → terminal-launch-events-D8ytCf2E.js} +1 -1
- package/dist/public/assets/{terminal-telemetry-BC3JNC05.js → terminal-telemetry-LPAWl6sJ.js} +1 -1
- package/dist/public/assets/{typing-burst-detector-cZASYUag.js → typing-burst-detector-MvNJwskd.js} +1 -1
- package/dist/public/assets/{uninstall-D9_hPyyW.js → uninstall-ACcONsCi.js} +1 -1
- package/dist/public/assets/{use-activity-panel-Drw3hRT0.js → use-activity-panel-DO4-UumZ.js} +1 -1
- package/dist/public/assets/{use-apply-config-color-theme-DZRctrdg.js → use-apply-config-color-theme-DpUYtbRe.js} +1 -1
- package/dist/public/assets/{use-collab-url-B7oEo69p.js → use-collab-url-B1V6TiLU.js} +1 -1
- package/dist/public/assets/{use-live-xterm-theme-C1EtEd_i.js → use-live-xterm-theme-DYp4WjiU.js} +1 -1
- package/dist/public/assets/{use-open-skill-C-OW-Q9z.js → use-open-skill-8o6IZoY2.js} +1 -1
- package/dist/public/assets/{use-popular-skills-BIvBkMNA.js → use-popular-skills-CC2urVQ6.js} +1 -1
- package/dist/public/assets/{use-settings-route-BrzzIll2.js → use-settings-route-DYSuZnve.js} +1 -1
- package/dist/public/assets/{use-skill-origin-FTbTIS5Y.js → use-skill-origin-Cd9ipAH-.js} +1 -1
- package/dist/public/assets/{use-terminal-enabled-CSNDVdz8.js → use-terminal-enabled-pw2WV2qk.js} +1 -1
- package/dist/public/assets/{use-timeline-entry-diff-DGCq_9Hl.js → use-timeline-entry-diff-B3StRSt9.js} +1 -1
- package/dist/public/assets/{use-workspace-8Sxb8Z6Q.js → use-workspace-BP0fuu9O.js} +1 -1
- package/dist/public/index.html +48 -48
- package/dist/public/uninstall.html +6 -6
- package/dist/{repair-launch-json-DwX_p44c.mjs → repair-launch-json-BSlvdEhG.mjs} +2 -2
- package/dist/{repair-mcp-configs-B97Hde8v.mjs → repair-mcp-configs-MWY28hax.mjs} +2 -2
- package/dist/{repair-skills-9uic_lvC.mjs → repair-skills-BoMh5uOr.mjs} +2 -2
- package/dist/repair-skills-D3qrrU25.mjs +1 -0
- package/dist/{resolve-project-root-DxuF_Wkh.mjs → resolve-project-root-DpSmoodv.mjs} +2 -2
- package/dist/{server-lock-BmwIVWMl.mjs → server-lock-CSO3K0Ok.mjs} +2 -2
- package/dist/server-lock-D_MF6GOb.mjs +1 -0
- package/dist/{skill-teardown-BAqBOmoz.mjs → skill-teardown-D66Xjjil.mjs} +2 -2
- package/dist/{sleep-B416PNUo.mjs → sleep-CEs13Om_.mjs} +2 -2
- package/dist/{src-BjgAn2Yr.mjs → src-8LdfqLwC.mjs} +6 -6
- package/dist/{src-Cx5SESaf.mjs → src-BZ35NJ2E.mjs} +2 -2
- package/dist/{src-BxdlvOrw.mjs → src-BimG4LM6.mjs} +3 -3
- package/dist/src-D_5cigYC.mjs +1 -0
- package/dist/{src-CUYD9VhP.mjs → src-DorV8gmN.mjs} +1 -1
- package/dist/{start-DbzSO0Vm.mjs → start-BCpGrVds.mjs} +4 -4
- package/dist/start-C7xEQnkW.mjs +1 -0
- package/dist/{ui-Z7Q_cw-H.mjs → ui-DRrmB9yI.mjs} +3 -3
- package/package.json +4 -4
- package/dist/constants-Da740t6h.mjs +0 -2
- package/dist/fs-traced-Bmqe7SqT.mjs +0 -1
- package/dist/git-handle-CDxQW_H0.mjs +0 -1
- package/dist/init-DtdLKAVm.mjs +0 -1
- package/dist/loader-B_hH6wym.mjs +0 -1
- package/dist/md-manager-30E0O9b-.mjs +0 -2
- package/dist/preview-BUhx_VX6.mjs +0 -1
- package/dist/public/assets/FeedbackForm-bekuqqT1.js +0 -1
- package/dist/public/assets/ManagedArtifactProperties-DXXsE5wd.js +0 -1
- package/dist/public/assets/ThreadView-Bt_MQTAE.js +0 -14
- package/dist/public/assets/client-version-p4OJ2Mf5.js +0 -1
- package/dist/public/assets/globals-CStTfhCT.css +0 -1
- package/dist/public/assets/i18n-DLbGfWG4.js +0 -1
- package/dist/repair-skills-DFvLHpTw.mjs +0 -1
- package/dist/server-lock-e6dYuoeq.mjs +0 -1
- package/dist/src-Bq4zes2H.mjs +0 -1
- package/dist/start-BVuhLPC4.mjs +0 -1
- /package/dist/public/assets/{globals-tNjN0wSq.js → globals-CQk8qCgW.js} +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{pt as e}from"./sleep-
|
|
1
|
+
import{pt as e}from"./sleep-CEs13Om_.mjs";import{ai as t}from"./src-8LdfqLwC.mjs";import{g as n,p as r,s as i}from"./resolve-project-root-DpSmoodv.mjs";import{d as a}from"./init-097BT-JV.mjs";import{execFileSync as o,spawn as s}from"node:child_process";import{dirname as c,join as l,win32 as u}from"node:path";import{existsSync as d,mkdirSync as f,readFileSync as p,statSync as m,writeFileSync as h}from"node:fs";import{homedir as g}from"node:os";var _=e();const v=`open-knowledge`;function y(e){try{e()}catch{}}var b=class{backend=`keyring`;constructor(e){this.onKeychainRead=e}async get(e){let{Entry:t}=await import(`@napi-rs/keyring`),n;try{n=new t(v,e).getPassword()}catch(t){return y(()=>this.onKeychainRead?.({kind:`read-error`,host:e,error:t instanceof Error?t.name:`unknown`})),null}if(n==null)return y(()=>this.onKeychainRead?.({kind:`absent`,host:e})),null;try{return JSON.parse(n)}catch{return y(()=>this.onKeychainRead?.({kind:`corrupt-entry`,host:e,error:`corrupt-entry`})),null}}async set(e,t,n,r){let{Entry:i}=await import(`@napi-rs/keyring`),a=new i(v,e),o={login:t,token:n,...r};a.setPassword(JSON.stringify(o))}async clear(e){let{Entry:t}=await import(`@napi-rs/keyring`);try{new t(v,e).deletePassword()}catch{}}},x=class{backend=`file`;authFile;constructor(e){this.authFile=e??l(g(),`.ok`,`auth.yml`)}read(){if(!d(this.authFile))return{};try{return(0,_.parse)(p(this.authFile,`utf-8`))??{}}catch(e){let t=e instanceof Error?e.message:`unknown error`;return process.stderr.write(`[auth] Failed to parse ${this.authFile}: ${t}. Starting with empty credentials.\n`),{}}}write(e){let t=c(this.authFile);d(t)||f(t,{recursive:!0,mode:448}),h(this.authFile,(0,_.stringify)(e),{mode:384})}async get(e){return this.read()[e]??null}async set(e,t,n,r){let i=this.read();i[e]={login:t,token:n,...r},this.write(i)}async clear(e){let t=this.read();delete t[e],this.write(t)}},S=class{backend=`keyring`;constructor(e,t){this.keychain=e,this.file=t}async get(e){let t=await this.keychain.get(e);if(t!=null)return t;let n=await this.file.get(e);if(n==null)return null;try{await this.keychain.set(e,n.login,n.token,{gitProtocol:n.gitProtocol,name:n.name,email:n.email}),await this.file.clear(e),process.stderr.write(`[auth] migrated ${e} credential from ~/.ok/auth.yml to the OS keychain\n`)}catch{}return n}set(e,t,n,r){return this.keychain.set(e,t,n,r)}async clear(e){await this.keychain.clear(e),await this.file.get(e)!=null&&await this.file.clear(e)}};async function C(e,t){try{let{Entry:n}=await import(`@napi-rs/keyring`);return new n(v,`__probe__`),process.stderr.write(`[auth] token storage: OS keychain
|
|
2
2
|
`),y(()=>t?.onBackendSelected?.({backend:`keyring`})),new S(new b(t?.onKeychainRead),new x(e))}catch(n){let r=n instanceof Error?`${n.name}: ${n.message}`:String(n);return process.stderr.write(`[auth] token storage: file (~/.ok/auth.yml) — OS keychain unavailable: ${r}\n`),y(()=>t?.onBackendSelected?.({backend:`file`,reason:r})),new x(e)}}function w(e){let t=null;return function(){if(t)return t;let n=2e3;return t=(async()=>{let t=null,r=new Promise(r=>{t=setTimeout(()=>{process.stderr.write(`[auth] token storage: keyring init exceeded ${n}ms; falling back to file (~/.ok/auth.yml)\n`),r(new x(e))},n)});try{return await Promise.race([C(e),r])}catch{return new x(e)}finally{t!==null&&clearTimeout(t)}})(),t}}function T(e){let t=w(e);return{async get(e){let n=await(await t()).get(e);return n===null?null:{token:n.token}}}}function E(e){let t=w(e);return{backend:`file`,async get(e){return(await t()).get(e)},async set(e,n,r,i){return(await t()).set(e,n,r,i)},async clear(e){return(await t()).clear(e)}}}async function D(e,t){let n=[],r=new x(t);await r.get(e)!=null&&(await r.clear(e),n.push(`file`));let i;try{let{Entry:t}=await import(`@napi-rs/keyring`);new t(v,`__probe__`);let r,a=await new b(e=>{e.kind===`read-error`&&(r=e.error??`read-error`)}).get(e);if(r!==void 0)i=r;else if(a!=null)try{new t(v,e).deletePassword(),n.push(`keychain`)}catch(e){i=e instanceof Error?e.name:`delete-error`}}catch{}return{touched:n,keychainError:i}}const O=[`/opt/homebrew/bin/gh`,`/usr/local/bin/gh`,`/opt/local/bin/gh`,`/snap/bin/gh`,`/usr/bin/gh`],k={encoding:`utf-8`,stdio:[`ignore`,`pipe`,`pipe`],timeout:5e3,windowsHide:!0};function A(e,t={}){let n=t._exec??o,r=t._fileExists??d,i=[`auth`,`token`,...e?[`--hostname`,e]:[]],a=[`gh`,...O.filter(r)];for(let e of a)try{let t=n(e,i,k).toString().trim();if(t.length>0)return{available:!0,token:t}}catch{}return{available:!1}}function j(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function M(e){let t=e?.code;return t===`ENOENT`||t===`EACCES`||t===`EPERM`?{ok:!1,reason:`not-installed`}:{ok:!1,reason:`spawn-error`}}function N(e){return t({detached:!0,stdio:`ignore`,shell:!1,env:j(e)})}function P(e,t,n={}){let r=(n.spawn??s)(e,[...t],N(n.env??process.env));return r.unref(),r}function F(e,t,n={}){let r=n.spawn??s,i=n.timeoutMs??2e3;return new Promise(a=>{let o=!1,s=e=>{o||(o=!0,a(e))},c=setTimeout(()=>s({ok:!1,reason:`timeout`}),i);try{let i=r(e,[...t],N(n.env??process.env));i.once(`error`,e=>{clearTimeout(c),s(M(e))}),i.once(`spawn`,()=>{clearTimeout(c),s({ok:!0})});try{i.unref()}catch{}}catch(e){clearTimeout(c),s(M(e))}})}const I=`com.inkeep.open-knowledge`,L=`OpenKnowledge.app`,R=`/Applications/${L}`;function z(){return{platform:process.platform,env:process.env,execPath:process.execPath,isTTY:process.stdout.isTTY,statSync:e=>{try{return m(e,{throwIfNoEntry:!1})??null}catch{return null}}}}function B(e){if(e.env.ELECTRON_RUN_AS_NODE===`1`){let t=/(.+?\.app)\/Contents\/MacOS\//.exec(e.execPath);if(t?.[1])return t[1]}if(V(e,R))return R;let t=l(e.homeDir??g(),`Applications`,L);return V(e,t)?t:null}function V(e,t){return H(e,l(t,`Contents`,`MacOS`,`OpenKnowledge`))}function H(e,t){try{let n=e.statSync(t);return n&&typeof n.isFile==`function`?n.isFile():!1}catch{return!1}}const U=[`@inkeepopen-knowledge-desktop`,`OpenKnowledge`];function W(e){if(e.env.ELECTRON_RUN_AS_NODE===`1`&&/\\OpenKnowledge\.exe$/i.test(e.execPath))return e.execPath;let t=e.env.LOCALAPPDATA;if(t)for(let n of U){let r=u.join(t,`Programs`,n,`OpenKnowledge.exe`);if(H(e,r))return r}return null}function G(e){if(e.env.ELECTRON_RUN_AS_NODE===`1`&&e.execPath.endsWith(`/openknowledge`))return e.execPath;let t=`/opt/OpenKnowledge/openknowledge`;return H(e,t)?t:null}function K(e){if(e.env.OK_FORCE_BROWSER===`1`)return{available:!1,reason:`force-browser`};if(e.platform!==`darwin`&&e.platform!==`win32`&&e.platform!==`linux`)return{available:!1,reason:`unsupported-platform`};let t;try{t=e.platform===`darwin`?B(e):e.platform===`win32`?W(e):G(e)}catch{return{available:!1,reason:`stat-error`}}return t?e.env.OK_FORCE_DESKTOP===`1`?{available:!0,reason:`available`,bundlePath:t}:!(e.isTTY===!0||e.platform===`win32`&&e.isTTY===void 0&&!e.env.CI)||e.env.SSH_CONNECTION||e.env.SSH_TTY||e.platform===`linux`&&!e.env.DISPLAY&&!e.env.WAYLAND_DISPLAY?{available:!1,reason:`headless`,bundlePath:t}:{available:!0,reason:`available`,bundlePath:t}:{available:!1,reason:`no-bundle`}}function q(e,t){let n=e.log??(e=>console.error(e)),r=e.platform??process.platform;if(n("Launching OpenKnowledge desktop (use `ok start` for the browser server, or `OK_FORCE_BROWSER=1` to always skip)"),r===`darwin`){P(`open`,[`-b`,I],{spawn:e.spawn});return}let i=t?.bundlePath;if(!i){n(`Desktop launch skipped: no resolved desktop executable (caller bug).`);return}P(i,[],{spawn:e.spawn})}function J(e=`no-bundle`){switch(e){case`no-bundle`:return`Desktop app not found (checked the standard install locations for this OS). Install it from https://openknowledge.ai/download, or omit --mode for browser mode.`;case`darwin-only`:case`unsupported-platform`:return`Desktop app is not available on this platform. Use --mode=browser, or omit --mode for the server fallback.`;case`headless`:return`Desktop launch is gated in headless contexts (CI, SSH, non-TTY stdout). Set OK_FORCE_DESKTOP=1 to override, or use --mode=browser.`;case`force-browser`:return`OK_FORCE_BROWSER=1 is set — desktop dispatch is disabled. Unset it to use --mode=app.`;case`stat-error`:return`Failed to inspect the desktop install (filesystem error). Check permissions or use --mode=browser.`;case`available`:return`Desktop app appears available but launch dispatch did not fire (caller bug).`}}function Y(e,t,o){let s=i[e],c=e===`opencode`?n:r,l=[],u=s.projectConfigPath?.(t);u!==void 0&&l.push({scope:`project`,configPath:u});try{l.push({scope:`user`,configPath:s.configPath(t,o)})}catch{}for(let n of l){let r=a(s,t,o,n.configPath);if(r!==null&&c(r))return{editorId:e,scope:n.scope,configPath:n.configPath}}return null}export{q as a,F as c,C as d,T as f,K as i,A as l,I as n,J as o,E as p,z as r,P as s,Y as t,D as u};
|
|
3
|
-
//# sourceMappingURL=acp-harness-probe-
|
|
3
|
+
//# sourceMappingURL=acp-harness-probe-C2IHuVgy.mjs.map
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{o as e}from"./chunk-DTipWd-i.mjs";import{At as t,Ct as n,E as r,It as i,Mt as a,N as o,St as s,T as c,Ut as l,_t as u,a as d,c as f,jt as p,kt as m,nn as h,p as g,pt as _,xt as v,zt as y}from"./sleep-
|
|
2
|
+
import{o as e}from"./chunk-DTipWd-i.mjs";import{At as t,Ct as n,E as r,It as i,Mt as a,N as o,St as s,T as c,Ut as l,_t as u,a as d,c as f,jt as p,kt as m,nn as h,p as g,pt as _,xt as v,zt as y}from"./sleep-CEs13Om_.mjs";import{Da as ee,Ga as b,Is as x,K as S,Ks as te,Lo as C,Ns as ne,Oa as re,Os as ie,Ro as ae,Rt as oe,Sc as se,Ts as ce,Uo as le,aa as ue,at as de,bs as fe,dc as pe,dt as me,es as he,gs as ge,k as _e,ks as ve,ls as ye,ms as be,oa as xe,ts as Se,zo as Ce,zt as we}from"./src-BimG4LM6.mjs";import{$ as Te,Aa as Ee,Bn as De,Bt as Oe,Di as ke,Ei as Ae,F as je,Ht as Me,I as Ne,Ii as Pe,Ir as Fe,J as Ie,Kt as Le,L as Re,Li as ze,Lr as Be,Ma as Ve,Na as He,Oi as w,On as Ue,P as We,Pr as Ge,Q as Ke,Sn as qe,Tn as Je,Vt as Ye,X as Xe,Yr as Ze,Z as Qe,_ as $e,_i as et,_t as tt,a as nt,ai as T,at as rt,dt as it,en as at,f as ot,fi as st,ft as ct,ht as lt,ja as ut,ki as dt,li as ft,ln as pt,lr as mt,lt as ht,mt as gt,n as _t,on as vt,ot as yt,p as bt,pi as xt,pt as St,qt as Ct,r as wt,rt as Tt,sn as Et,st as Dt,t as Ot,ut as kt,vi as At,w as jt,zn as Mt,zr as Nt,zt as Pt}from"./src-8LdfqLwC.mjs";import{A as E,F as Ft,I as It,k as Lt}from"./fs-traced-Dy67FR5_.mjs";import{s as Rt}from"./git-handle-KDk0khh5.mjs";import{S as zt,b as D,i as Bt,u as Vt}from"./server-lock-CSO3K0Ok.mjs";import{_ as Ht,a as Ut,b as O,r as Wt,s as Gt,v as Kt}from"./resolve-project-root-DpSmoodv.mjs";import{_ as qt,c as Jt,d as Yt,f as Xt,h as Zt,i as Qt,l as $t,m as en,n as tn,o as nn,p as rn,r as an,t as on,u as sn,v as cn,y as ln}from"./src-BZ35NJ2E.mjs";import{c as un,i as k,n as A,o as j,r as M,s as N,t as P}from"./colors-BsmVIwfM.mjs";import{a as dn,c as fn,d as pn,i as mn,l as hn,p as gn,r as _n,s as vn,u as yn}from"./acp-harness-probe-C2IHuVgy.mjs";import{n as bn,r as xn,t as F}from"./dist-bundle-CFfKBclM.mjs";import{A as Sn,B as Cn,C as wn,D as Tn,F as En,I as Dn,L as On,M as kn,N as An,P as jn,R as Mn,S as Nn,V as Pn,j as Fn,k as In,u as Ln,w as Rn,z as zn}from"./init-097BT-JV.mjs";import{n as Bn,t as Vn}from"./constants-CaZ6pf_w.mjs";import{n as Hn,t as Un}from"./loader-C7KxwdAY.mjs";import{T as Wn,x as Gn}from"./start-BCpGrVds.mjs";import{i as Kn}from"./skill-teardown-D66Xjjil.mjs";import{t as qn}from"./launch-json-removal-CmteoVKJ.mjs";import{n as Jn}from"./repair-skills-BoMh5uOr.mjs";import{execFile as Yn,execFileSync as Xn,execSync as Zn,spawn as Qn,spawnSync as $n}from"node:child_process";import{basename as er,dirname as I,isAbsolute as tr,join as L,posix as nr,relative as R,resolve as z,sep as rr}from"node:path";import ir from"node:process";import{fileURLToPath as ar}from"node:url";import{accessSync as or,appendFileSync as sr,closeSync as cr,constants as lr,existsSync as B,lstatSync as ur,mkdirSync as V,mkdtempSync as dr,openSync as fr,readFileSync as H,readdirSync as pr,realpathSync as mr,renameSync as hr,rmSync as gr,statSync as U,unlinkSync as W,writeFileSync as _r}from"node:fs";import{homedir as vr,platform as yr,tmpdir as br}from"node:os";import{rm as xr}from"node:fs/promises";import{randomUUID as Sr}from"node:crypto";import{setTimeout as Cr}from"node:timers/promises";import{promisify as wr}from"node:util";import{createInterface as Tr}from"node:readline/promises";const Er={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 Dr;(function(e){})(Dr||={});function Or(e){return l(u,e)}async function kr(e){let{projectDir:t,contentDir:n,baseConfig:r,targetPath:i,fix:a=!1}=e,o=[],s=Ze({projectDir:t,contentDir:n}),c=new Set,l=e=>{c.has(e)||(c.add(e),o.push(e))},u=Be(t,r,l),d=new Map,f=e=>{let t=I(e),r=d.get(t);if(r)return r;let i=Fe(u,Nt(n,e,l));return d.set(t,i),i},p=[],m=Ar(i,n);m.kind===`file`?p.push(R(n,m.path)):h(m.path);function h(e){let t;try{t=pr(e,{withFileTypes:!0})}catch(t){o.push(`could not read directory ${R(n,e)||`.`}: ${Mr(t)}`);return}for(let r of t){if(r.name.startsWith(`.`))continue;let t=L(e,r.name),i=R(n,t);if(r.isDirectory()){if(s.isDirExcluded(i))continue;h(t)}else if(r.isFile()){if(!jr(r.name)||s.isExcluded(i))continue;p.push(i)}}}p.sort();let g=[],_=0,v=0,y=0;for(let e of p){let t=L(n,e),r;try{r=H(t,`utf-8`)}catch(t){o.push(`could not read ${e}: ${Mr(t)}`);continue}let i=f(e),s=!1;if(a&&i.enabled){let n=ue(r,i);if(n!==r){let i=`${t}.tmp.${process.pid}.${Date.now()}`;try{_r(i,n,`utf-8`),hr(i,t),r=n,s=!0,y++}catch(t){try{W(i)}catch{}o.push(`could not write fix to ${e}: ${Mr(t)}`)}}}let c=await xe(r,i,e);for(let e of c)e.severity===`error`?_++:v++;g.push({file:e,diagnostics:c,fixed:s})}return{contentDir:n,files:g,warnings:o,fileCount:p.length,errorCount:_,warningCount:v,fixedCount:y}}function Ar(e,t){if(e===void 0||e===``)return{kind:`dir`,path:t};let n=tr(e)?e:z(t,e);try{if(U(n).isFile())return{kind:`file`,path:n}}catch{}return{kind:`dir`,path:n}}function jr(e){let t=e.toLowerCase();return x.some(e=>t.endsWith(e))}function Mr(e){return e instanceof Error?e.message:String(e)}function Nr(e){return new O(`lint`).description(`Lint markdown content (headless) — whole project, a folder, or a single file`).argument(`[path]`,`Folder or file to lint, relative to where you run the command`).option(`--json`,`Emit structured JSON instead of formatted text`).option(`--fix`,`Auto-fix fixable issues in place (markdownlint rules only)`).option(`--errors-only`,`Exit non-zero only on error-severity problems (findings are warning-severity unless your .markdownlint.* assigns a rule "error")`).action(async(t,n)=>{let r=e(),i=process.cwd(),a=ke(r,i),o=t===void 0?void 0:Pr(t,qt()),s=r.contentRules,c=await kr({projectDir:i,contentDir:a,baseConfig:s?re(s):b,targetPath:o,fix:n.fix===!0});n.json===!0?process.stdout.write(`${JSON.stringify(c,null,2)}\n`):process.stdout.write(`${Lr(c)}\n`),(n.errorsOnly===!0?c.errorCount>0:Fr(c))&&(process.exitCode=1)})}function Pr(e,t){return z(t,e)}function Fr(e){return e.errorCount>0||e.warningCount>0}function Ir(e){let t=[P(e.file)+(e.fixed?A(` (fixed)`):``)];for(let n of e.diagnostics){let e=A(`${n.range.start.line+1}:${n.range.start.character+1}`.padEnd(7)),r=n.severity===`error`?M(`error `):N(`warning`);t.push(` ${e} ${r} ${n.message} ${A(`${n.source}/${n.code}`)}`)}return t.push(``),t}function Lr(e){let t=[];for(let n of e.files)n.diagnostics.length>0&&t.push(...Ir(n));for(let n of e.warnings)t.push(N(`! ${n}`));e.warnings.length>0&&t.push(``);let n=e.errorCount+e.warningCount;if(n===0)t.push(j(`✓ No problems in ${e.fileCount} file${e.fileCount===1?``:`s`}.`));else{let r=[`${n} problem${n===1?``:`s`}`];r.push(`${e.errorCount} error${e.errorCount===1?``:`s`}`),r.push(`${e.warningCount} warning${e.warningCount===1?``:`s`}`),t.push(`${M(r[0]??``)} (${r[1]}, ${r[2]}) across ${e.fileCount} file${e.fileCount===1?``:`s`}.`)}return e.fixedCount>0&&t.push(A(`Fixed ${e.fixedCount} file${e.fixedCount===1?``:`s`}.`)),t.join(`
|
|
3
3
|
`)}const Rr={out:e=>process.stdout.write(`${e}\n`),err:e=>process.stderr.write(`${e}\n`)};function zr(e){return new O(`audit`).description(`Unified validation audit (markdown lint + broken internal links) via the running project server`).argument(`[path]`,`Folder or file to audit, relative to where you run the command`).option(`--json`,`Emit the full structured JSON response instead of formatted text`).option(`--errors-only`,`Exit non-zero only on error-severity problems (broken links default to warnings; the project's validation.links setting can raise them to errors)`).action(async(t,n)=>{let r=await Br(t,n,e(),process.cwd(),qt());r!==0&&(process.exitCode=r)})}async function Br(e,t,n,r,i,a=Rr){let o=ke(n,r),s;if(e!==void 0){let t=Vr(e,i,o);if(t===null)return a.err(`Path is outside the content directory (${o}): ${e}`),1;s=t===``?void 0:t}let c=Bt(w(r));if(!c||c.port<=0)return a.err("OpenKnowledge server is not running — the links validator needs the live backlink index. Start it with `ok start` (or open OK Desktop) and re-run. For headless lint-only checks, use `ok lint`."),1;let l=s===void 0?``:`?path=${encodeURIComponent(s)}`,u;try{u=await fetch(`http://127.0.0.1:${c.port}/api/audit${l}`,{headers:se({kind:`cli`,runtimeVersion:D})})}catch(e){return a.err(`Could not reach the OpenKnowledge server on port ${c.port}: ${String(e)}`),1}if(!u.ok){let e=await u.json().catch(()=>({}));return a.err(`Audit failed: ${e.title??e.error??e.message??`server responded with ${u.status}`}`),1}let d=ee.safeParse(await u.json().catch(()=>null));if(!d.success){let e=d.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `);return a.err(`Audit failed: unexpected response shape from the server. Schema issues: ${e}`),1}let f=d.data;return t.json===!0?a.out(JSON.stringify(f,null,2)):a.out(Lr(Hr(f))),+(t.errorsOnly===!0?f.errorCount>0:f.errorCount+f.warningCount>0)}function Vr(e,t,n){let r=R(n,z(t,e));return r===``?``:r.startsWith(`..`)||tr(r)?null:r.split(rr).join(`/`)}function Hr(e){return{files:e.files.map(e=>({file:e.file,fixed:!1,diagnostics:e.diagnostics})),warnings:e.warnings,fileCount:e.fileCount,errorCount:e.errorCount,warningCount:e.warningCount,fixedCount:0}}async function Ur(e,t,n,r){let i=Wr(await Gr(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 Wr(e){let t={};for(let n of e.split(`
|
|
4
4
|
`)){let e=n.trim();if(e===``)continue;let r=e.indexOf(`=`);r!==-1&&(t[e.slice(0,r)]=e.slice(r+1))}return t}function Gr(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 Kr(e,t){let n=new O(`git-credential`);return n.description(`Git credential helper (git credential-helper protocol)`),n.command(`get`).description(`Lookup credentials from TokenStore (called by git)`).action(async()=>{let n=t?.();try{let t,r=await e({onKeychainRead:e=>{t=e},onBackendSelected:e=>{e.backend===`file`&&e.reason&&n?.warn({backend:`file`,reason:e.reason},`[auth] token storage fallback`)}}),i=await Ur(process.stdin,process.stdout,r,{log:n,getDiag:()=>t});await bt(n),process.exit(i)}catch(e){n?.error({err:e},`[auth] git-credential get: unexpected error`),await bt(n),process.exit(1)}}),n}function qr(e){let t=e.endpoint.DEFAULTS;return/^https:\/\/(api\.)?github\.com$/.test(t.baseUrl)?`https://github.com`:t.baseUrl.replace(`/api/v3`,``)}async function Jr(e,t,n){let r={baseUrl:qr(e),headers:{accept:`application/json`},...n},i=await e(t,r);if(`error`in i.data){let n=new bn(`${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 Yr(e){let t=e.request||F,n={client_id:e.clientId};return`scopes`in e&&Array.isArray(e.scopes)&&(n.scope=e.scopes.join(` `)),Jr(t,`POST /login/device/code`,n)}async function Xr(e){let t=await Jr(e.request||F,`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=Zr(e,t.data.expires_in),n.refreshTokenExpiresAt=Zr(e,t.data.refresh_token_expires_in)}delete n.scopes}return{...t,authentication:n}}function Zr(e,t){return new Date(e+t*1e3).toISOString()}async function Qr(e,t){let n=$r(e,t.auth);if(n)return n;let{data:r}=await Yr({clientType:e.clientType,clientId:e.clientId,request:t.request||e.request,scopes:t.auth.scopes||e.scopes});await e.onVerification(r);let i=await ti(t.request||e.request,e.clientId,e.clientType,r);return e.authentication=i,i}function $r(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 ei(e){await new Promise(t=>setTimeout(t,e*1e3))}async function ti(e,t,n,r){try{let i={clientId:t,request:e,code:r.device_code},{authentication:a}=n===`oauth-app`?await Xr({...i,clientType:`oauth-app`}):await Xr({...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 ei(r.interval),ti(e,t,n,r);if(a===`slow_down`)return await ei(r.interval+7),ti(e,t,n,r);throw i}}async function ni(e,t){return Qr(e,{auth:t})}async function ri(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 Qr(e,{request:t,auth:{type:`oauth`}});return i.headers.authorization=`token ${a}`,t(i)}var ii=`0.0.0-development`;function ai(e){let t=e.request||F.defaults({headers:{"user-agent":`octokit-auth-oauth-device.js/${ii} ${xn()}`}}),{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(ni.bind(null,i),{hook:ri.bind(null,i)})}async function oi(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=ai({clientType:`oauth-app`,clientId:t,scopes:n,onVerification:async e=>{await r({verificationUri:e.verification_uri,userCode:e.user_code,expiresIn:e.expires_in,interval:e.interval})},request:a===`https://api.github.com`?void 0:(await import(`./dist-bundle-BT5p_5Yl.mjs`)).request.defaults({baseUrl:a})}),s;try{s=await o({type:`oauth`})}catch(e){if(e instanceof Error){let t=e.message.toLowerCase();throw t.includes(`access_denied`)?Error(`Device-flow authorization was denied.`):t.includes(`expired_token`)||t.includes(`timeout`)||t.includes(`timed out`)?Error(`Device-flow code expired before authorization — please try again.`):Error(`GitHub sign-in failed: ${e.message}`)}throw e}return{token:s.token,tokenType:s.tokenType,scopes:s.scopes??[]}}function si(){return process.env.OPEN_KNOWLEDGE_GITHUB_CLIENT_ID??`Ov23liqlSd0V1MwR6rhI`}function G(e){let t=e.toLowerCase().replace(/:\d+$/,``);fe.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 ci(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function li(e,t,n=oi){let r=si(),{host:i,json:a}=e;G(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?ci(!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?ci(!0,{type:`complete`,host:i,login:s}):process.stderr.write(`✓ Logged in as ${s} on ${i}\n`)}function ui(e){return new O(`login`).description(`Authenticate with GitHub via Device Flow`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname (default: workspace origin host)`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{let n=t.host??Ge(process.cwd()),r=await e();await li({...t,host:n},r)})}const di={style:{maskedText:`[input is masked]`}};var fi=En((e,t)=>{let{validate:n=()=>!0}=e,r=zn(di,e.theme),[i,a]=Cn(`idle`),[o,s]=Cn(),[c,l]=Cn(``),u=Mn({status:i,theme:r});On(async(e,r)=>{if(i===`idle`)if(Pn(e)){let e=c;a(`loading`);let i=await n(e);i===!0?(l(e),a(`done`),t(e)):(r.write(c),s(i||`You must provide a valid value`),a(`idle`))}else l(r.line),s(void 0)});let d=r.style.message(e.message,i),f=``,p;e.mask?f=(typeof e.mask==`string`?e.mask:`*`).repeat(c.length):i!==`done`&&(p=`${r.style.help(r.style.maskedText)}${Dn}`),i===`done`&&(f=r.style.answer(f));let m=``;return o&&(m=r.style.error(o)),[[u,d,e.mask?f:p].join(` `),m]});function pi(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>pi.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function mi(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function hi(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const gi=Function.bind,_i=gi.bind(gi);function vi(e,t,n){let r=_i(hi,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=_i(mi,null).apply(null,i)})}function yi(){let e=Symbol(`Singular`),t={registry:{}},n=pi.bind(null,t,e);return vi(n,t,e),n}function bi(){let e={registry:{}},t=pi.bind(null,e);return vi(t,e),t}var xi={Singular:yi,Collection:bi},Si=`0.0.0-development`;function Ci(e){return`Request failed due to following response errors:
|
|
5
5
|
`+e.errors.map(e=>` - ${e.message}`).join(`
|
|
@@ -8,9 +8,9 @@ import{o as e}from"./chunk-DTipWd-i.mjs";import{At as t,Ct as n,E as r,It as i,M
|
|
|
8
8
|
`),n.includes(`file`)&&process.stderr.write(` cleared from ~/.ok/auth.yml
|
|
9
9
|
`)}function _a(){return new O(`signout`).description(`Remove stored credentials`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname (default: workspace origin host)`).action(async e=>{let t=e.host??Ge(process.cwd());await ga({...e,host:t})})}async function va(e,t,n=hn){let r=n(e);if(r.available&&r.token)return{tier:`A`,token:r.token};let i=await t.get(e);return i==null?{tier:`none`}:{tier:i.gitProtocol===`ssh`?`C`:`B`,token:i.token}}function ya(e,t,n){return{type:`status`,host:e,backend:t,...n}}async function ba(e,t){let{host:n,json:r}=e;G(n);let i=t.backend,a=await va(n,t);a.tier===`none`&&(r?process.stdout.write(`${JSON.stringify(ya(n,i,{authenticated:!1}))}\n`):process.stderr.write(`Not logged in to ${n}\n`),process.exit(1));let o=n===`github.com`?void 0:`https://${n}/api/v3`,s=new oa({auth:a.token,...o?{baseUrl:o}:{}});try{let{data:e}=await s.users.getAuthenticated();r?process.stdout.write(`${JSON.stringify(ya(n,i,{authenticated:!0,tier:a.tier,login:e.login,name:e.name,email:e.email}))}\n`):process.stderr.write(`✓ Logged in as ${e.login} on ${n}\n`)}catch(e){let t=la(e,n);r?process.stdout.write(`${JSON.stringify(ya(n,i,{authenticated:!1,error:t.message}))}\n`):process.stderr.write(`✗ ${t.message}\n`),process.exit(1)}}function xa(e){return new O(`status`).description(`Show authentication status`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname (default: workspace origin host)`).option(`--json`,`Output JSON`,!1).action(async t=>{let n=t.host??Ge(process.cwd());await ba({...t,host:n},await e())})}function Sa(e){let t=new O(`auth`);t.description(`GitHub authentication management`);let n=e=>pn(void 0,e);return t.addCommand(ui(n)),t.addCommand(xa(n)),t.addCommand(ha(n)),t.addCommand(_a()),t.addCommand(fa(n)),t.addCommand(Kr(n,e)),t}function Ca(e,t=yr(),n=vn){try{t===`darwin`?n(`/usr/bin/open`,[`-R`,e]):n(t===`win32`?`explorer.exe`:`xdg-open`,[I(e)])}catch{}}function wa(){return new O(`bug-report`).description(`Generate a diagnostic bundle for bug reporting`).option(`--reveal`,`Reveal the bundle in your file manager (default: true)`,!0).option(`--no-reveal`,`Do not reveal the bundle in your file manager`).action(async e=>{try{let{zipPath:t,summary:n}=await Xt({level:`standard`,projectDir:process.cwd(),redact:!0,outputPath:Zt(),logger:Nf()});process.stdout.write(`${t}\n`),n.redactedLineCount>0&&process.stderr.write(`ok bug-report: ${n.redactedLineCount} line(s) auto-redacted across ${n.redactions.length} file(s)\n`),e.reveal&&Ca(t)}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`ok bug-report: failed — ${t}\n`),process.exitCode=1}})}function Ta(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 Ea(e){let t=e.inspect??(t=>Yt(e.lockDir,t)),n=e.unlink??(e=>W(e)),r=e.log??(e=>console.log(e)),i=e.error??(e=>console.error(e)),a=Ta(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 Da(e){return new O(`clean`).description(`Prune stale / corrupt open-knowledge lock files (never touches live locks)`).action(()=>{e(),Ea({lockDir:w(process.cwd())}).failed.length>0&&(process.exitCode=1)})}function Oa(e){return`credential.helper=!${e.map(le).join(` `)} auth git-credential`}async function ka(e,t,n={},r=hn){let i=[`credential.helper=`,Oa(n.selfCliArgs??[`open-knowledge`])];if(!n.skipGhDetect){let t=r(e);if(t.available&&t.token)return{tier:`A`,gitConfig:i,relayToken:{token:t.token,host:e}}}let a=await t.get(e);return a==null?{tier:`none`,gitConfig:[]}:{tier:a.gitProtocol===`ssh`?`C`:`B`,gitConfig:i}}async function Aa(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 ja=[[`count`,0,10],[`compress`,10,20],[`receiv`,20,60],[`resolv`,60,100]];function Ma(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 ja)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 Na(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 Pa(e,t=process.env){let n=Na(t);return e.relayToken?(n.OK_GH_TOKEN=e.relayToken.token,n.OK_GH_TOKEN_HOST=e.relayToken.host):(delete n.OK_GH_TOKEN,delete n.OK_GH_TOKEN_HOST),n}function Fa(e=process.argv,t=process.execPath){let n=e[1];return n?[t,n]:[t]}function Ia(e){return typeof e!=`string`||e.length===0?[`--progress`]:[`--progress`,`-b`,e]}const La=ae;async function Ra(e){try{return await e.clone(Ia(e.branch)),{fellBack:!1}}catch(t){if(e.branch!==null&&La(t))return e.onFallback(e.branch),await e.clone(Ia(null)),{fellBack:!0};throw t}}function za(e,t){return{baseDir:e,config:t,unsafe:{allowUnsafeCredentialHelper:!0,allowUnsafePager:!0,allowUnsafeSshCommand:!0,allowUnsafeAskPass:!0,allowUnsafeEditor:!0}}}function Ba(e,t,n){return e===`https`&&t===`github.com`&&n}function Va(e,t){let n=`${t.owner}/${t.name}`;return e===n||e===`${n}.git`?`https://${t.hostname}/${n}`:e}async function Ha(e,t,n,r=process.cwd()){let i=sn(e);if(!i)throw Error(`Invalid git URL: ${e}`);let a=Va(e,i),o=t.dir?z(r,t.dir):z(r,i.name);if(B(o)&&pr(o).length>0)throw Error(`Target directory is not empty: ${o}`);pt();let s=gn(),c=i.protocol===`https`&&i.hostname===`github.com`?await Aa(i.owner,i.name):!1,l=Ba(i.protocol,i.hostname,c)?{tier:`none`,gitConfig:[]}:await ka(i.hostname,s,{selfCliArgs:Fa()}),u=Pa(l),d=Rt(za(r,l.gitConfig)).env(u),f=-1;d.outputHandler((e,n,r)=>{r.on(`data`,e=>{let n=e.toString(`utf-8`);for(let e of n.split(`
|
|
10
10
|
`)){let n=Ma(e);n&&n.pct!==f&&(f=n.pct,q(t.json,{type:`progress`,pct:n.pct,stage:n.stage}),t.json||process.stderr.write(`\r Cloning ${n.pct}%`))}})}),await Ra({branch:typeof t.branch==`string`&&t.branch.length>0?t.branch:null,clone:e=>d.clone(a,o,e),onFallback:e=>{q(t.json,{type:`branch-fallback`,branch:e}),t.json||process.stderr.write(`\n Branch '${e}' not found upstream — cloning default branch instead.\n`)}}),t.json||process.stderr.write(`
|
|
11
|
-
`);try{let{runInit:e}=await import(`./init-
|
|
11
|
+
`);try{let{runInit:e}=await import(`./init-wif6tBNp.mjs`),n=await e({cwd:o,mcp:!1});if(n.contentUpdated.length>0){let e=`auto-init: updated ${n.contentUpdated.join(`, `)}`;t.json?q(!0,{type:`warning`,message:e}):process.stderr.write(` ${e}\n`)}}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`auto-init: ${n}`}):process.stderr.write(` auto-init: ${n}\n`)}try{Ua(o)}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`git-exclude: ${n}`}):process.stderr.write(` git-exclude: ${n}\n`)}return o}function Ua(e){let t=Tn(e,[`.ok/`]);return t.kind===`no-exclude`?`no-exclude`:t.kind===`refused-tracked`?`already-present`:t.appended.length>0?`appended`:`already-present`}const Wa=/^[A-Za-z0-9._/:@-]+$/;function Ga(e){return Wa.test(e)?e:le(e)}function Ka(e,t){let n=typeof t==`string`&&t.length>0?` -b ${Ga(t)}`:``;return`ok clone ${Ga(e)}${n}`}function qa(e){let t=C(e.error);if(t.kind!==`auth`)return null;if(Ce(t)){let t=Ka(e.url,e.branch);return[`✗ Couldn't clone ${e.url} — authentication is required.`,``,` To fix:`,` 1. Run: ok auth login`,` 2. Then re-run: ${t}`].join(`
|
|
12
12
|
`)}if(t.subclass===`403`){let t=typeof e.principal==`string`&&e.principal.length>0?` (signed in as @${e.principal} — may lack access)`:``;return`✗ Access denied when cloning ${e.url}${t}. Check that your account has access to the repository.`}return t.subclass===`ssh-auth`?`✗ Couldn't clone ${e.url} over SSH — authentication failed. Check that your SSH key is added to your GitHub account and the host key is trusted, or clone the HTTPS URL instead.`:["✗ Your GitHub token is missing required OAuth scopes — likely the `repo` scope.",``,` To fix:`," 1. Create a token with `repo` scope at https://github.com/settings/tokens",` 2. Run: ok auth pat`,` 3. Then re-run: ${Ka(e.url,e.branch)}`].join(`
|
|
13
|
-
`)}function Ja(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=qa({error:e.error,url:e.url,branch:e.branch,principal:e.principal});e.printStderr(`${n??`✗ ${t}`}\n`)}async function Ya(e,t){let n=(await e.get(t))?.login;return n&&n!==`unknown`?n:null}async function Xa(e){let t=C(e.error),n=null;if(!e.json&&t.kind===`auth`&&t.subclass===`403`){let t=sn(e.url);t&&(n=await(e.resolvePrincipal??(e=>Ya(gn(),e)))(t.hostname))}Ja({error:e.error,url:e.url,branch:e.branch,json:e.json,principal:n,emit:e.emit,printStderr:e.printStderr})}function Za(e){return new O(`clone`).description(`Clone a git repository and open it`).argument(`<url>`,`Repository URL or owner/repo shorthand`).argument(`[dir]`,`Target directory (default: ./<repo-name>)`).option(`--json`,`Output JSONL progress events`,!1).option(`-b, --branch <branch>`,`Branch to check out (falls back to default if missing)`).action(async(t,n,r)=>{let i=e();try{let a=await Ha(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-
|
|
13
|
+
`)}function Ja(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=qa({error:e.error,url:e.url,branch:e.branch,principal:e.principal});e.printStderr(`${n??`✗ ${t}`}\n`)}async function Ya(e,t){let n=(await e.get(t))?.login;return n&&n!==`unknown`?n:null}async function Xa(e){let t=C(e.error),n=null;if(!e.json&&t.kind===`auth`&&t.subclass===`403`){let t=sn(e.url);t&&(n=await(e.resolvePrincipal??(e=>Ya(gn(),e)))(t.hostname))}Ja({error:e.error,url:e.url,branch:e.branch,json:e.json,principal:n,emit:e.emit,printStderr:e.printStderr})}function Za(e){return new O(`clone`).description(`Clone a git repository and open it`).argument(`<url>`,`Repository URL or owner/repo shorthand`).argument(`[dir]`,`Target directory (default: ./<repo-name>)`).option(`--json`,`Output JSONL progress events`,!1).option(`-b, --branch <branch>`,`Branch to check out (falls back to default if missing)`).action(async(t,n,r)=>{let i=e();try{let a=await Ha(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-C7xEQnkW.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){if(e instanceof vt||e instanceof Et){r.json?q(!0,{type:`error`,message:e.message}):process.stderr.write(`${e.message}\n`),process.exitCode=78;return}await Xa({error:e,url:t,branch:r.branch??null,json:r.json,emit:e=>q(!0,e),printStderr:e=>process.stderr.write(e)}),process.exitCode=1}})}var Qa=_();const $a=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],...f.map(e=>e.path)];function eo(e){return It({absPath:Lt(`project-local`,e),sideline:!1}).diagnostics}function to(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??Hn;try{let{sources:n,diagnostics:i,sidelined:a}=r(e.cwd),o=(e.readProjectLocalFn??eo)(e.cwd??process.cwd()),s=[...i,...o],c=n.length===0?`defaults only`:n.join(`, `),l=s.filter(e=>e.code!==`REMOVED_KEY`);l.length===0?t(`✓ Configuration valid (sources: ${c})`):t(`! Configuration loaded, but ${l.length} config layer(s) had issues (sources: ${c})`);for(let e of s)t(``),t(g(e));for(let{from:e,to:n}of a)t(``),t(`Moved ${e} aside to ${n} so defaults could be used. Restore it once fixed.`);return{ok:!0}}catch(e){return n(e instanceof Error?e.message:String(e)),{ok:!1}}}function no(e){let t=(0,Qa.parseDocument)(H(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 $a)t.hasIn(e)&&n.push(e.join(`.`));return n}function ro(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function io(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=ro(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}function ao(e){switch(e){case`project`:return[`project`];case`project-local`:return[`project-local`];case`user`:return[`user`];case`both`:return[`project`,`user`];case`all`:return[`project`,`project-local`,`user`]}}async function oo(e={}){let t=e.log??(e=>console.log(e)),n=e.error??(e=>console.error(e)),r=e.scope??`all`,i=e.dryRun??!1,a=e.cwd??process.cwd(),o=e.writeConfigPatchFn??E,s=ao(r).map(t=>({scope:t,absPath:Lt(t,a,e.homedirOverride)})),c=[],l=!0;for(let{scope:t,absPath:n}of s){if(!B(n)){c.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=no(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:io($a.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!s.ok){c.push({path:n,scope:t,found:r,removed:[],error:g(s.error)}),l=!1;continue}c.push({path:n,scope:t,found:r,removed:r})}for(let e of c)e.error&&n(`✗ ${e.path}: ${e.error}`);let u=c.some(e=>e.error!==void 0),d=c.reduce((e,t)=>e+t.found.length,0);if(d===0&&!u)t(`No deprecated fields found.`);else if(d>0)for(let e of c)e.error||(e.found.length===0?t(` ${e.path}: no deprecated fields`):t(i?`[dry-run] ${e.path}: would remove ${e.found.length} field(s): ${e.found.join(`, `)}`:`✓ ${e.path}: removed ${e.removed.length} field(s): ${e.removed.join(`, `)}`));return{outcomes:c,ok:l}}const so=`project | project-local | user | all`,co=new Set(Object.keys({project:!0,"project-local":!0,user:!0,both:!0,all:!0}));function lo(e){return e!==`config`}function uo(){let e=new O(`config`).description(`Inspect and maintain OpenKnowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{to({}).ok||(process.exitCode=1)}),e.command(`migrate`).description(`Remove deprecated config fields from config.yml idempotently (every removed key in the registry — content.*, folders, appearance.editorModeDefault, server.host, etc. — plus the silently-dropped sync.*, persistence.*)`).option(`--scope <scope>`,`Which scope to migrate: ${so}`,`all`).option(`--dry-run`,`Preview without writing`,!1).action(async e=>{let t=String(e.scope);if(!co.has(t)){console.error(`Invalid --scope: ${t}. Expected: ${so}`),process.exitCode=2;return}(await oo({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}const fo=[` 1. ${P(`Customize`)} (sidebar) → ${P(`Skills`)}`,` 2. Click the ${P(`+`)} button`,` 3. Click ${P(`Create skill`)}`,` 4. Click ${P(`Upload skill`)}`,` 5. Pick ${P(`openknowledge.skill`)} from Downloads`],po=k(` Open the Claude Desktop App, then: ${P(`Customize → Skills → + → Create skill → Upload skill`)} → pick the file.`);function mo(e){let t=[j(`Built ${e.outputPath}`),A(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…`)];return e.handoffError&&t.push(N(` Handoff failed: ${e.handoffError.message}`)),t.push(po),t.join(`
|
|
14
14
|
`)}function ho(e){let t=e.skillVersion??`unknown`,n=e.recordedAt??`unknown`;return[k(`OpenKnowledge skill ${P(`v${t}`)} already delivered to Claude Desktop.`),A(` Recorded at ${n} in ~/.ok/skill-state.yml`),A(` Use ${P(`--force`)} to rebuild and re-open the install dialog.`)].join(`
|
|
15
15
|
`)}function go(e){let t=e.skillVersion?` • Skill v${e.skillVersion}`:``;return[j(`Built ${e.outputPath}`),A(` ${e.size} bytes • sha256 ${e.sha256?.slice(0,12)}…${t}`),k(` Claude Desktop App opened. Now upload the file manually:`),...fo,A(` If Claude Desktop didn't open, open it and start at step 1. The file is at ${e.outputPath}`)].join(`
|
|
16
16
|
`)}function _o(e){return`${M(`Error:`)} ${e.buildError??`unknown build failure`}`}async function vo(e={}){let t=await mt(e);return t.status===`failed`?{...t,message:_o(t),exitCode:1}:t.status===`skip-current`?{...t,message:ho(t),exitCode:0}:t.status===`installed`?{...t,message:go(t),exitCode:0}:{...t,message:mo(t),exitCode:0}}function yo(){return new O(`cowork`).description("Build openknowledge.skill and open the Claude Desktop App so you can upload it for Claude Chat & Cowork. (Advanced/rarely needed — `ok init` already wires Claude.)").option(`--out <path>`,`Custom output path (default: ~/Downloads/openknowledge.skill)`).option(`--no-open`,`Build the file but skip the OS file-association handoff`).option(`--force`,`Bypass the install-state gate and rebuild unconditionally`).action(async e=>{let t=await vo({out:e.out,noOpen:!e.open,force:e.force??!1});process.stdout.write(`${t.message}\n`),t.exitCode!==0&&process.exit(t.exitCode)})}async function bo(e,t){let n=Tr({input:t??process.stdin,output:process.stderr});try{let t=(await n.question(e)).trim().toLowerCase();return t===`y`||t===`yes`}finally{n.close()}}function xo(e={}){let t=e.platformName??process.platform,n=e.productName??`OpenKnowledge`;return Ht(t).join(Kt({...e,platformName:t}),n)}function So(e={}){let t=e.platformName??process.platform,n=e.home??vr(),r=e.env??process.env,i=Ht(t),a;return a=t===`win32`?r.LOCALAPPDATA||i.join(n,`AppData`,`Local`):t===`darwin`?i.join(n,`Library`,`Caches`):r.XDG_CACHE_HOME||i.join(n,`.cache`),i.join(a,`@inkeepopen-knowledge-desktop-updater`)}function Co(e){if(typeof e!=`object`||!e)return null;let t=e.recentProjects;if(!Array.isArray(t))return null;let n=[];for(let e of t){if(typeof e!=`object`||!e)continue;let t=e;typeof t.path==`string`&&typeof t.name==`string`&&n.push({path:t.path,name:t.name})}return n}function wo(e){let t=L(e,`state.json`);if(!B(t))return[];let n;try{n=JSON.parse(H(t,`utf-8`))}catch{return[]}return Co(n)??[]}function To(e){let t=L(e,`state.json`);if(!B(t))return!1;try{return Co(JSON.parse(H(t,`utf-8`)))!==null}catch{return!1}}function J(e,t){return e===t?`~`:e.startsWith(`${t}/`)?`~${e.slice(t.length)}`:e}function Eo(e){return rr===`/`?e:e.split(rr).join(`/`)}function Do(e,t,n=`This project`){let r=[];r.push({kind:`stop-server`,group:n,label:`Stop the project server (if running)`,lockDir:w(e)});let i=new Set;for(let a of Ut){let o=Gt[a];if(!o.projectConfigPath)continue;let s=o.projectConfigPath(e);i.add(Eo(R(e,s))),r.push({kind:`mcp-entry`,group:n,label:`Remove OK's MCP entry from ${o.label} (${Eo(R(e,s))})`,editorId:a,scope:`project`,cwd:e,home:t,configPath:s})}r.push({kind:`launch-entry`,group:n,label:`Remove OK's entry from .claude/launch.json`,projectRoot:e}),r.push({kind:`git-exclude`,group:n,label:`Remove OK paths from .git/info/exclude`,projectRoot:e});let a=new Set([...Sn(e),...ve]);for(let t of a){let a=t.replace(/\/$/,``);i.has(a)||a!==`.claude/launch.json`&&r.push({kind:`remove-path`,group:n,label:`Remove ${t}`,path:L(e,a),containWithin:e})}try{r.push({kind:`remove-path`,group:n,label:`Remove the OK shadow repo (.git/ok/)`,path:He(e)})}catch{}return r}function Oo(e,t){return{scope:`deinit`,ops:Do(e,t)}}function ko(e){let{home:t,platform:n,host:r,lockDirs:i,marker:a,recentDeinitProjectRoots:o,purgeContent:s}=e,c=[];for(let e of i)c.push({kind:`stop-server`,group:`Running servers`,label:`Stop server at ${J(L(e,`..`,`..`),t)}`,lockDir:e});c.push({kind:`keychain-token`,group:`Credentials`,label:`Remove the GitHub credential (${r}) from the OS keychain + auth.yml`,host:r}),c.push({kind:`embeddings-key`,group:`Credentials`,label:`Remove all embeddings API keys (secrets.yml)`}),c.push(...jo(a,t));for(let e of Ut){let n=Gt[e],r;try{r=n.configPath(``,t)}catch{continue}c.push({kind:`mcp-entry`,group:`Editor MCP configs`,label:`Remove OK's MCP entry from ${n.label} (${J(r,t)})`,editorId:e,scope:`user`,cwd:t,home:t,configPath:r})}for(let e of Kn(t))c.push({kind:`remove-path`,group:`Skill bundles`,label:`Remove ${J(e.path,t)}`,path:e.path});c.push(...Mo(t,n,e.env));for(let e of o)c.push(...Do(e,t,`Project: ${er(e)}`));return c.push({kind:`remove-path`,group:`Global directory`,label:s?`Remove ~/.ok (including user-authored skills)`:`Remove ~/.ok (keeping ~/.ok/skills)`,path:L(t,`.ok`),preserve:s?void 0:[`skills`]}),{scope:`uninstall`,ops:c}}function Ao(e){return[L(e,`.zshrc`),L(e,`.bash_profile`),L(e,`.config`,`fish`,`conf.d`,`open-knowledge.fish`)]}function jo(e,t){let n=[],r=new Set([...Ao(t),...e?.rcFiles??[]]);for(let e of r)B(e)&&n.push({kind:`shell-block`,group:`Shell PATH`,label:`Strip the OK block from ${J(e,t)}`,rcFile:e});for(let r of e?.extraSymlinks??[])n.push({kind:`extra-symlink`,group:`Shell PATH`,label:`Remove the ok symlink at ${J(r.path,t)}`,path:r.path,target:r.target});return n}function Mo(e,t,n){let r={home:e,platformName:t,env:n},i=xo(r),a=So(r),o=[{kind:`remove-path`,group:`Application data`,label:`Remove ${J(i,e)}`,path:i}];if(t===`darwin`){let t=xo({...r,productName:`Open Knowledge`});o.push({kind:`remove-path`,group:`Application data`,label:`Remove ${J(t,e)} (only if it is OpenKnowledge's)`,path:t,requireOurState:!0})}return o.push({kind:`remove-path`,group:`Application data`,label:`Remove ${J(a,e)}`,path:a}),o}async function No(e,t={}){let n=t.clearToken??yn,r=t.clearEmbeddingsKey??st,i=t.stopServer??(e=>{let t=on({lockDir:e,log:()=>{},error:()=>{}});return{stopped:t.stopped.length,failed:t.failed.map(e=>({pid:e.target.pid,error:e.error}))}}),a=[];for(let t of e.ops)try{a.push(await Po(t,{clearToken:n,clearEmbeddingsKey:r,stopServer:i}))}catch(e){a.push({op:t,status:`failed`,detail:e instanceof Error?e.message:String(e)})}return{results:a,removed:a.filter(e=>e.status===`removed`),failed:a.filter(e=>e.status===`failed`)}}async function Po(e,t){switch(e.kind){case`stop-server`:{let{stopped:n,failed:r}=t.stopServer(e.lockDir);return r.length>0?{op:e,status:`failed`,detail:`could not stop the server (${r.map(e=>`pid ${e.pid}: ${e.error}`).join(`; `)}); a process may still be using files that were removed`}:{op:e,status:n>0?`removed`:`not-present`}}case`keychain-token`:{let{touched:n,keychainError:r}=await t.clearToken(e.host);return r?{op:e,status:`failed`,detail:`keychain unreachable (${r}); remove manually: Keychain Access → service "open-knowledge"`}:{op:e,status:n.length>0?`removed`:`not-present`}}case`embeddings-key`:{let{touched:n}=await t.clearEmbeddingsKey();return{op:e,status:n.length>0?`removed`:`not-present`}}case`shell-block`:{if(!B(e.rcFile))return{op:e,status:`not-present`};let{text:t,changed:n,emptyAfter:r}=$t(H(e.rcFile,`utf-8`));return n?r?(gr(e.rcFile,{force:!0}),{op:e,status:`removed`,detail:`file removed (was OK-owned)`}):(Ft(e.rcFile,t,{mode:Rn(e.rcFile)}),{op:e,status:`removed`}):{op:e,status:`not-present`}}case`extra-symlink`:return nn(e.path,e.target)?(W(e.path),{op:e,status:`removed`}):{op:e,status:`not-present`};case`mcp-entry`:{let t=Qt(Gt[e.editorId],e.cwd,e.home,e.configPath);switch(t.kind){case`removed`:return{op:e,status:`removed`};case`not-present`:return{op:e,status:`not-present`};case`left-foreign`:return{op:e,status:`skipped`,detail:`left a non-OK server in place`};case`declined`:return{op:e,status:`skipped`,detail:`declined (${t.reason})`};default:throw Error(`unhandled mcp-remove outcome: ${t.kind}`)}}case`launch-entry`:{let t=qn(e.projectRoot);switch(t.kind){case`removed`:return{op:e,status:`removed`};case`not-present`:return{op:e,status:`not-present`};case`declined`:return{op:e,status:`skipped`,detail:`declined (unparseable)`};default:throw Error(`unhandled launch-remove outcome: ${t.kind}`)}}case`git-exclude`:{if(In(e.projectRoot).length===0)return{op:e,status:`not-present`};let t=jn(e.projectRoot,Sn(e.projectRoot));return t.kind===`no-exclude`?t.reason===`inaccessible`?{op:e,status:`failed`,detail:`could not write .git/info/exclude (inaccessible)`}:{op:e,status:`not-present`,detail:t.reason}:{op:e,status:t.removed.length>0?`removed`:`not-present`}}case`remove-path`:return Fo(e)}}function Fo(e){if(e.requireOurState&&!To(e.path))return{op:e,status:`skipped`,detail:`not verified as OpenKnowledge — left untouched`};e.containWithin&&Wt(e.path,e.containWithin);let t;try{t=ur(e.path)}catch(e){if(e.code!==`ENOENT`)throw e}if(!t)return{op:e,status:`not-present`};if(t.isSymbolicLink())return W(e.path),{op:e,status:`removed`};if(e.preserve&&e.preserve.length>0){let t=new Set(e.preserve),n=!1;for(let r of pr(e.path))t.has(r)||(gr(L(e.path,r),{recursive:!0,force:!0}),n=!0);return{op:e,status:n?`removed`:`not-present`}}return gr(e.path,{recursive:!0,force:!0}),{op:e,status:`removed`}}function Io(e){let t=new Map;for(let n of e){let e=t.get(n.group)??[];e.push(n),t.set(n.group,e)}return t}function Lo(e){if(e.ops.length===0)return A(`Nothing to remove.`);let t=[];for(let[n,r]of Io(e.ops)){t.length>0&&t.push(``),t.push(P(`${n}:`));for(let e of r)t.push(` ${N(`-`)} ${e.label}`)}return t.join(`
|
|
@@ -39,7 +39,7 @@ ws.addEventListener('error', () => process.exit(1));
|
|
|
39
39
|
setTimeout(() => process.exit(2), ${t+1e4});
|
|
40
40
|
`),r}async function _s(e,t,n,r,i){let a=gs(e,t,L(r,`cpu.cpuprofile`)),o=!1,s=Qn(process.execPath,[a],T({stdio:`ignore`})),c=setInterval(()=>{let e=fs(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{gr(L(a,`..`),{recursive:!0,force:!0})}catch{}return o}function vs(e){let t;try{t=JSON.parse(e)}catch{return`(could not parse profile)`}let n=new Map(t.nodes.map(e=>[e.id,e])),r=new Map;for(let e of t.nodes)for(let t of e.children??[])r.set(t,e.id);let i=new Map;for(let e of t.samples??[])i.set(e,(i.get(e)??0)+1);let a=t.samples?.length??0,o=t.endTime!=null&&t.startTime!=null?((t.endTime-t.startTime)/1e3).toFixed(2):`?`,s=[...i.entries()].sort((e,t)=>t[1]-e[1]).slice(0,10),c=[`samples ${a} duration_ms ${o}`,``,`Top leaf nodes`];for(let[e,t]of s){let r=n.get(e);if(!r)continue;let i=a>0?(t/a*100).toFixed(1):`0.0`,{functionName:o,url:s,lineNumber:l,columnNumber:u}=r.callFrame;c.push(` ${t} ${i}% id=${e} ${o||`(anonymous)`} ${s}:${l}:${u} hit=${r.hitCount??0}`)}c.push(``,`Top stacks`);let l=e=>{let t=[],i=e;for(;i!=null;){let e=n.get(i);if(!e)break;let{functionName:a,url:o,lineNumber:s,columnNumber:c}=e.callFrame;t.unshift(` ${a||`(anonymous)`} ${o} ${s} ${c}`),i=r.get(i)}return t};for(let[e,t]of s.slice(0,5)){let n=a>0?(t/a*100).toFixed(1):`0.0`;c.push(``,`--- ${t} ${n}%`,...l(e))}return c.join(`
|
|
41
41
|
`)}async function ys(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??Yt,c=t.resolveCommand??rt,l=t.resolveUsage??yt,u=t.collectLsofFn??ps,d=t.getEndpoints??hs,f=t.profiler??_s,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 ee=new Date().toISOString().replace(/[:.]/g,`-`),b=e.output?e.output:v?L(v,`.ok`,`local`,`diagnostics`,`process-${n}-${ee}`):L(process.cwd(),`ok-diagnose-${n}-${ee}`);try{V(b,{recursive:!0})}catch(e){a(Y.default.red(`Cannot create output directory ${b}: ${e.message}`));return}a(Y.default.bold(`Diagnosing pid ${n}`)),a(`Output: ${b}`),a(``);let x=(e,t)=>{_r(L(b,e),t),a(` wrote ${e}`)},S=c(n),te=l(n);x(`metadata.json`,JSON.stringify({capturedAt:new Date().toISOString(),pid:n,command:S,usage:te,lockInfo:y},null,2)),a(` sampling lsof`);let C=u(n);if(C&&x(`lsof.txt`,C),!i){let e=C?ms(C).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){x(`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,b,e=>t.push(e))?a(` wrote cpu.cpuprofile`):a(Y.default.yellow(` CPU profile capture failed`)),t.length>0&&x(`process-stats.jsonl`,`${t.map(e=>JSON.stringify(e)).join(`
|
|
42
|
-
`)}\n`);try{x(`stacks.txt`,vs(H(L(b,`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(b)}`)}async function bs(e){let t=Tr({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function xs(e){let t=dr(L(br(),`ok-bundle-process-`));return await ys({pid:e,output:t}),t}function Ss(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 Cs(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function ws(e){let{summary:t,manifest:n}=e;return t.redacted?t.contentDirVisible?`masked as <CONTENT_DIR>, but still present in some files`:`masked as <CONTENT_DIR>`:t.contentDirVisible?`visible (${n.contentDir.absolutePath})`:`not present`}function Ts(e){let t=e.manifest.redaction.secretScrub;return t===void 0?Y.default.yellow(`NOT scrubbed (--no-redact): tokens and keys ship verbatim`):`scrubbed known credential formats (${t.redactedLineCount} line(s) across ${t.redactions.length} file(s))`}function Es(e,t,n){let{summary:r,manifest:i}=t;e(``),e(Y.default.bold(`ok diagnose bundle — what leaves this machine`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${Ss(r.totalBytes)} uncompressed`),e(` Document names: included in cleartext (${r.docNameCount} doc.name occurrence(s) in telemetry)`),e(` Content-dir path: ${ws(t)}`),e(` Credentials: ${Ts(t)}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function Ds(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??bs,i=t.runProcessDiagnose??xs,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=I(o);if(!B(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=L(e.contentDir,`.ok`,`local`,`diagnostics`);V(n,{recursive:!0}),o=L(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(Y.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=e.redact!==!1,l=await rn({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:c,scrubSecrets:c,deps:t.collectDeps});try{return l.manifest.serverStatus===`not-running`&&n(Y.default.yellow(` server not running — live state unavailable`)),Es(n,l,o),e.yes!==!0&&!Cs(await r(`Write bundle? [y/N]: `))?(n(Y.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await en({collected:l,outputPath:o}),n(Y.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(l.cleanup(),s!==void 0)try{gr(s,{recursive:!0,force:!0})}catch{}}}function Os(){let e=new O(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(Y.default.red(`Invalid pid '${e}': must be a positive integer`)),process.exit(1));let r=Number.parseInt(t.cpuProfile,10);(Number.isNaN(r)||r<=0)&&(console.error(Y.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await ys({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(ds()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--no-redact`,`Write a raw bundle: skip credential scrubbing and content-dir path masking`).option(`--redact`,`Scrub credentials and mask the content-dir path (the default)`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(Y.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-
|
|
42
|
+
`)}\n`);try{x(`stacks.txt`,vs(H(L(b,`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(b)}`)}async function bs(e){let t=Tr({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function xs(e){let t=dr(L(br(),`ok-bundle-process-`));return await ys({pid:e,output:t}),t}function Ss(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 Cs(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function ws(e){let{summary:t,manifest:n}=e;return t.redacted?t.contentDirVisible?`masked as <CONTENT_DIR>, but still present in some files`:`masked as <CONTENT_DIR>`:t.contentDirVisible?`visible (${n.contentDir.absolutePath})`:`not present`}function Ts(e){let t=e.manifest.redaction.secretScrub;return t===void 0?Y.default.yellow(`NOT scrubbed (--no-redact): tokens and keys ship verbatim`):`scrubbed known credential formats (${t.redactedLineCount} line(s) across ${t.redactions.length} file(s))`}function Es(e,t,n){let{summary:r,manifest:i}=t;e(``),e(Y.default.bold(`ok diagnose bundle — what leaves this machine`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${Ss(r.totalBytes)} uncompressed`),e(` Document names: included in cleartext (${r.docNameCount} doc.name occurrence(s) in telemetry)`),e(` Content-dir path: ${ws(t)}`),e(` Credentials: ${Ts(t)}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function Ds(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??bs,i=t.runProcessDiagnose??xs,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=I(o);if(!B(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=L(e.contentDir,`.ok`,`local`,`diagnostics`);V(n,{recursive:!0}),o=L(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(Y.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=e.redact!==!1,l=await rn({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:c,scrubSecrets:c,deps:t.collectDeps});try{return l.manifest.serverStatus===`not-running`&&n(Y.default.yellow(` server not running — live state unavailable`)),Es(n,l,o),e.yes!==!0&&!Cs(await r(`Write bundle? [y/N]: `))?(n(Y.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await en({collected:l,outputPath:o}),n(Y.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(l.cleanup(),s!==void 0)try{gr(s,{recursive:!0,force:!0})}catch{}}}function Os(){let e=new O(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(Y.default.red(`Invalid pid '${e}': must be a positive integer`)),process.exit(1));let r=Number.parseInt(t.cpuProfile,10);(Number.isNaN(r)||r<=0)&&(console.error(Y.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await ys({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(ds()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--no-redact`,`Write a raw bundle: skip credential scrubbing and content-dir path masking`).option(`--redact`,`Scrub credentials and mask the content-dir path (the default)`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(Y.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-CihrsBwk.mjs`),{resolveContentDir:r}=await import(`./src-DorV8gmN.mjs`),i=process.cwd(),{config:a}=n(i);await Ds({contentDir:r(a,i),projectDir:i,pid:t,out:e.out,yes:e.yes===!0,redact:e.redact})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(Y.default.red(t)),process.exit(1)}}),e}async function ks(){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 fi({message:`Enter embeddings provider API key:`})).trim()}function As(e){return ft(e)}async function js(e,t){let n=await At(xt(),e,t);return n.apiKey?{present:!0,notRequired:!1,source:n.source}:{present:!1,notRequired:n.keyless,source:null}}async function Ms(e){try{let t=Bt(w(e));if(!t||t.port<=0||!zt(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 Ns(){return new O(`set-key`).description(`Store the embeddings API key for THIS project's configured endpoint`).option(`--cwd <path>`,`Project directory (defaults to the current directory)`).action(async e=>{let t=await ks();if(!t){process.stderr.write(`No key provided.
|
|
43
43
|
`),process.exitCode=1;return}let n=z(e.cwd??process.cwd()),{baseUrl:r}=As(n);try{await xt().setForProject(n,r,t)}catch(e){process.stderr.write(`Failed to store the embeddings key: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1;return}process.stderr.write(`✓ Embeddings API key stored for ${r}\n (kept in ~/.ok/secrets.yml, 0600, this machine only — never in the project).
|
|
44
44
|
Enable semantic search with \`ok embeddings enable\`, or in
|
|
45
45
|
OK Desktop → Settings → This project → Search.
|
|
@@ -74,7 +74,7 @@ ${t}`,d++;break;case`id`:l=t.includes(`\0`)?void 0:t;break;case`retry`:/^\d+$/.t
|
|
|
74
74
|
`).replace(/\n+$/,``);return e.endsWith(`
|
|
75
75
|
`)?`${c}\n`:c}function Wu(e){return e.replace(/\r\n|\r|\n/g,`<br>`).replace(/\|/g,`\\|`)}function Gu(e){return/\s/.test(e)?`<${e}>`:e}function Ku(e,t={}){let{header:n,rows:r}=hu(e),i=n.length;if(i===0)return{table:``,columns:0,wide:!1};let a=t.wideThreshold??15,o=t.titleColumn??0;return{table:[`| ${n.map(Wu).join(` | `)} |`,`| ${n.map(()=>`---`).join(` | `)} |`,...r.map(e=>`| ${n.map((n,r)=>{let i=e[r]??``,a=Wu(i);if(r===o&&t.linkForTitle&&i.trim()!==``){let e=t.linkForTitle(i);if(e)return`[${a}](${Gu(e)})`}return a}).join(` | `)} |`)].join(`
|
|
76
76
|
`),columns:i,wide:i>a}}function qu(e,t){let n=e.match(/^#\s+(.+)$/m);return n?n[1].trim():t}function Ju(e,t){return`# ${e}\n\n${t}\n`}const Yu=[`links`,`frontmatter`,`callouts`,`images`,`tables`],Xu=/\.mdx?$/i;function Zu(e){return{isNotionExport:e,transforms:{links:0,frontmatter:0,callouts:0,images:0,tables:0},assetsExtracted:0,stubsCreated:0,csvsRemoved:0,wideTables:[],ambiguousTitleLinks:0,unreadable:[],filesChanged:0}}function Qu(e,t={}){let n=t.selected??new Set(Yu),r=Iu(e);if(!r&&!t.force)return{changes:[],assets:[],deletions:[],report:Zu(!1)};let i=Zu(r),a=Nu(e),o=wu(a,{onUnreadable:e=>i.unreadable.push(e)}),s=n.has(`tables`),c=new Map,l=new Set;for(let e of o){e.stubPath&&l.add(e.stubPath);for(let t of e.rowFiles)c.set(t,e)}let u=[],d=[],f=[];for(let e of a){if(!Xu.test(e)||s&&l.has(e))continue;let r;try{r=H(e,`utf8`)}catch{i.unreadable.push(e);continue}let a=r,o=(e,t)=>{a!==t&&(i.transforms[e]+=1)};if(n.has(`images`)){let n=a,r=mu(a,er(e),{strip:t.stripBase64});a=r.markdown;for(let t of r.assets)d.push({path:L(I(e),t.filename),bytes:t.bytes});i.assetsExtracted+=r.assets.length,o(`images`,n)}if(n.has(`callouts`)){let e=a;a=uu(a),o(`callouts`,e)}if(n.has(`frontmatter`)){let t=c.get(e);if(t){let e=a;a=Uu(a,t.propertyKeys),o(`frontmatter`,e)}}if(n.has(`links`)){let e=a;a=Mu(a,{redirectCsv:s}),o(`links`,e)}a!==r&&u.push({path:e,content:a})}if(s)for(let e of o){let r=Ku(e.csvText,{linkForTitle:t=>{let n=xu(e.folderIndex,t);return n.ambiguous&&(i.ambiguousTitleLinks+=1),n.path?R(I(e.stubTargetPath),n.path):null}});if(r.columns===0)continue;let a=e.stubPath??e.stubTargetPath,o=null;if(e.stubPath)try{o=H(e.stubPath,`utf8`)}catch{i.unreadable.push(e.stubPath);continue}let c=Ju(o===null?e.fallbackTitle:qu(o,e.fallbackTitle),r.table);n.has(`links`)&&(c=Mu(c,{redirectCsv:s})),r.wide&&i.wideTables.push(a),o===null?(u.push({path:a,content:c}),i.stubsCreated+=1,i.transforms.tables+=1):c!==o&&(u.push({path:a,content:c}),i.transforms.tables+=1),t.removeCsv&&(f.push(e.csvPath),i.csvsRemoved+=1)}return i.filesChanged=new Set(u.map(e=>e.path)).size,{changes:u,assets:d,deletions:f,report:i}}function $u(e){for(let t of e.assets)V(I(t.path),{recursive:!0}),_r(t.path,t.bytes);for(let t of e.changes)V(I(t.path),{recursive:!0}),_r(t.path,t.content,`utf8`);for(let t of e.deletions)try{W(t)}catch(e){if(e.code!==`ENOENT`)throw e}}const ed={images:`Inline base64 images extracted`,callouts:`Notion <aside> callouts converted`,frontmatter:`Row properties lifted to frontmatter`,tables:`Databases rendered as tables`,links:`Internal links decoded`},td=[`images`,`callouts`,`frontmatter`,`tables`,`links`];function nd(e,t){let n=[];n.push(t.applied?`Applied Notion cleanup in ${t.dir}`:`Dry run — no changes written (${t.dir})`);for(let t of td)n.push(` ${ed[t]}: ${e.transforms[t]}`);return n.push(` Assets written: ${e.assetsExtracted}`),e.stubsCreated>0&&n.push(` Database pages created (CSVs without a stub): ${e.stubsCreated}`),e.csvsRemoved>0&&n.push(` CSV files removed: ${e.csvsRemoved}`),n.push(` Files changed: ${e.filesChanged}`),e.ambiguousTitleLinks>0&&n.push(` Ambiguous title links left as plain text: ${e.ambiguousTitleLinks}`),e.wideTables.length>0&&n.push(` Wide tables (>15 columns): ${e.wideTables.length}`),e.unreadable.length>0&&n.push(` Skipped unreadable files: ${e.unreadable.length}`),!t.applied&&e.filesChanged+e.assetsExtracted+e.csvsRemoved>0&&(n.push(``),n.push(`Re-run with --apply to write these changes.`)),n.join(`
|
|
77
|
-
`)}function rd(e,t){return JSON.stringify({applied:t.applied,...e},null,2)}function id(e){let t=new Set(Yu);return e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0).map(e=>{if(!t.has(e))throw Error(`Unknown transform "${e}". Valid transforms: ${Yu.join(`, `)}`);return e})}function ad(e,t){let n=new Set(Yu);if(e&&(n=new Set(id(e))),t)for(let e of id(t))n.delete(e);return n}function od(){let e=new O(`migrate`).description(`Migrate content from other tools into Open Knowledge`);return e.command(`notion [dir]`).description(`Clean up a Notion "Markdown & CSV" export in place (dry-run unless --apply)`).option(`--apply`,`write changes to disk (default: dry-run preview)`).option(`--strip-base64`,`delete inline base64 images instead of extracting them to files`).option(`--remove-csv`,`delete each "_all.csv" once its table page exists (destructive)`).option(`--only <transforms>`,`run only these transforms (comma-separated: links,frontmatter,callouts,images,tables)`).option(`--skip <transforms>`,`skip these transforms (comma-separated)`).option(`--force`,`run even if the directory is not detected as a Notion export`).option(`--json`,`print a machine-readable JSON report`).action((e,t)=>{let n=z(e??process.cwd()),r;try{r=ad(t.only,t.skip)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=2;return}let i=Qu(n,{selected:r,stripBase64:t.stripBase64??!1,removeCsv:t.removeCsv??!1,force:t.force??!1}),{report:a}=i;if(!a.isNotionExport&&!t.force){t.json?console.log(JSON.stringify({refused:!0,reason:`not-a-notion-export`,dir:n},null,2)):console.error(`Not a Notion export: ${n}\nNo id-suffixed pages, "_all.csv", or inline base64 images were found. Re-run with --force to override.`),process.exitCode=2;return}if(t.apply)try{$u(i)}catch(e){console.error(`Failed to apply changes: ${e instanceof Error?e.message:String(e)}`),process.exitCode=4;return}console.log(t.json?rd(a,{applied:t.apply??!1}):nd(a,{applied:t.apply??!1,dir:n})),a.filesChanged===0&&a.assetsExtracted===0&&i.deletions.length===0?process.exitCode=1:t.apply&&(a.ambiguousTitleLinks>0||a.wideTables.length>0)&&(process.exitCode=3)}),e}function sd(e,t){return t===`darwin`?{command:`/usr/bin/open`,args:[e]}:t===`win32`?e.startsWith(`http://`)||e.startsWith(`https://`)?{command:`explorer.exe`,args:[e]}:{command:`rundll32.exe`,args:[`url.dll,FileProtocolHandler`,e]}:{command:`xdg-open`,args:[e]}}function cd(e,t={}){let n=sd(e,t.platform??process.platform);return fn(n.command,n.args,{spawn:t.spawn,env:t.env,timeoutMs:t.timeoutMs})}function ld(e,t,n=process.platform){let r=sd(t,n).command;switch(e){case`not-installed`:return`${r} is not installed or cannot be executed`;case`timeout`:return`${r} did not start in time`;case`spawn-error`:return`${r} could not be started`}}function ud(e=()=>mn(_n())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>Te({lockDir:w(e)}).baseUrl,classifyName:(e,t)=>{let n=L(e,t);try{return U(n).isDirectory()?`folder`:`doc`}catch(e){let t=e?.code;return t!==`ENOENT`&&t!==`ENOTDIR`&&process.stderr.write(`[ok open] statSync failed for ${n} (${t??`unknown`}); treating as a doc\n`),`doc`}},openTarget:cd,log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function dd(e){return e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).includes(`..`)}function fd(e){return e.error("No OpenKnowledge desktop app found and no UI is running. Install it from https://openknowledge.ai/download, or run `ok start` to serve the editor, then retry."),1}async function pd(e,t,n){let r=await n.openTarget(e);return r.ok?(n.log(t),0):(n.error(`Could not open ${e}: ${ld(r.reason,e)}.`),1)}async function md(e,t,n){let r=z(t.project??process.cwd()),i=e.replace(/\/+$/,``);if(!i)return n.error("Nothing to open: pass a doc, folder, or skill name (e.g. `ok open specs/foo/SPEC`)."),1;if(dd(i))return n.error(`Invalid name "${i}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(t.skill===!0){let e=t.scope??`project`;if(!te.includes(e))return n.error(`Invalid --scope "${t.scope}": expected one of ${te.join(`, `)}.`),1;if(n.detectBundlePath())return pd(`openknowledge://open?project=${encodeURIComponent(r)}&doc=${encodeURIComponent(`__skill__/${e}/${i}`)}`,`Opening skill ${i} (${e}) in the OpenKnowledge desktop app.`,n);let a=n.resolveBaseUrl(r);if(a){let t=`${a}/#/${Ke(e,i)}`;return pd(t,`Opening skill ${i} (${e}) in your browser: ${t}`,n)}return fd(n)}let a=/\/+$/.test(e)||n.classifyName(r,i)===`folder`,o=n.detectBundlePath();if(a){if(o)return pd(`openknowledge://open?project=${encodeURIComponent(r)}&folder=${encodeURIComponent(i)}`,`Opening folder ${i} in the OpenKnowledge desktop app.`,n);let e=n.resolveBaseUrl(r);if(e){let t=`${e}/#/${Qe(i)}`;return pd(t,`Opening folder ${i} in your browser: ${t}`,n)}return fd(n)}if(o)return pd(`openknowledge://open?project=${encodeURIComponent(r)}&doc=${encodeURIComponent(i)}`,`Opening ${i} in the OpenKnowledge desktop app.`,n);let s=n.resolveBaseUrl(r);if(s){let e=`${s}/#/${Xe(i)}`;return pd(e,`Opening ${i} in your browser: ${e}`,n)}return fd(n)}function hd(){return new O(`open`).description(`Open a doc, folder, or skill in the OK Desktop app (falls back to the browser UI). Docs and folders are auto-detected — no flag needed.`).argument(`<name>`,`Doc path (specs/foo/SPEC), folder path (specs/foo or specs/foo/), or a skill name with --skill`).option(`--skill`,`Open <name> as a skill in the skill editor`).option(`--scope <scope>`,`Skill scope when --skill is set: ${te.join(` | `)}`,`project`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action(async(e,t)=>{process.exitCode=await md(e,t,ud())})}function gd(e){return new O(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-
|
|
77
|
+
`)}function rd(e,t){return JSON.stringify({applied:t.applied,...e},null,2)}function id(e){let t=new Set(Yu);return e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0).map(e=>{if(!t.has(e))throw Error(`Unknown transform "${e}". Valid transforms: ${Yu.join(`, `)}`);return e})}function ad(e,t){let n=new Set(Yu);if(e&&(n=new Set(id(e))),t)for(let e of id(t))n.delete(e);return n}function od(){let e=new O(`migrate`).description(`Migrate content from other tools into Open Knowledge`);return e.command(`notion [dir]`).description(`Clean up a Notion "Markdown & CSV" export in place (dry-run unless --apply)`).option(`--apply`,`write changes to disk (default: dry-run preview)`).option(`--strip-base64`,`delete inline base64 images instead of extracting them to files`).option(`--remove-csv`,`delete each "_all.csv" once its table page exists (destructive)`).option(`--only <transforms>`,`run only these transforms (comma-separated: links,frontmatter,callouts,images,tables)`).option(`--skip <transforms>`,`skip these transforms (comma-separated)`).option(`--force`,`run even if the directory is not detected as a Notion export`).option(`--json`,`print a machine-readable JSON report`).action((e,t)=>{let n=z(e??process.cwd()),r;try{r=ad(t.only,t.skip)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=2;return}let i=Qu(n,{selected:r,stripBase64:t.stripBase64??!1,removeCsv:t.removeCsv??!1,force:t.force??!1}),{report:a}=i;if(!a.isNotionExport&&!t.force){t.json?console.log(JSON.stringify({refused:!0,reason:`not-a-notion-export`,dir:n},null,2)):console.error(`Not a Notion export: ${n}\nNo id-suffixed pages, "_all.csv", or inline base64 images were found. Re-run with --force to override.`),process.exitCode=2;return}if(t.apply)try{$u(i)}catch(e){console.error(`Failed to apply changes: ${e instanceof Error?e.message:String(e)}`),process.exitCode=4;return}console.log(t.json?rd(a,{applied:t.apply??!1}):nd(a,{applied:t.apply??!1,dir:n})),a.filesChanged===0&&a.assetsExtracted===0&&i.deletions.length===0?process.exitCode=1:t.apply&&(a.ambiguousTitleLinks>0||a.wideTables.length>0)&&(process.exitCode=3)}),e}function sd(e,t){return t===`darwin`?{command:`/usr/bin/open`,args:[e]}:t===`win32`?e.startsWith(`http://`)||e.startsWith(`https://`)?{command:`explorer.exe`,args:[e]}:{command:`rundll32.exe`,args:[`url.dll,FileProtocolHandler`,e]}:{command:`xdg-open`,args:[e]}}function cd(e,t={}){let n=sd(e,t.platform??process.platform);return fn(n.command,n.args,{spawn:t.spawn,env:t.env,timeoutMs:t.timeoutMs})}function ld(e,t,n=process.platform){let r=sd(t,n).command;switch(e){case`not-installed`:return`${r} is not installed or cannot be executed`;case`timeout`:return`${r} did not start in time`;case`spawn-error`:return`${r} could not be started`}}function ud(e=()=>mn(_n())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>Te({lockDir:w(e)}).baseUrl,classifyName:(e,t)=>{let n=L(e,t);try{return U(n).isDirectory()?`folder`:`doc`}catch(e){let t=e?.code;return t!==`ENOENT`&&t!==`ENOTDIR`&&process.stderr.write(`[ok open] statSync failed for ${n} (${t??`unknown`}); treating as a doc\n`),`doc`}},openTarget:cd,log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function dd(e){return e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).includes(`..`)}function fd(e){return e.error("No OpenKnowledge desktop app found and no UI is running. Install it from https://openknowledge.ai/download, or run `ok start` to serve the editor, then retry."),1}async function pd(e,t,n){let r=await n.openTarget(e);return r.ok?(n.log(t),0):(n.error(`Could not open ${e}: ${ld(r.reason,e)}.`),1)}async function md(e,t,n){let r=z(t.project??process.cwd()),i=e.replace(/\/+$/,``);if(!i)return n.error("Nothing to open: pass a doc, folder, or skill name (e.g. `ok open specs/foo/SPEC`)."),1;if(dd(i))return n.error(`Invalid name "${i}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(t.skill===!0){let e=t.scope??`project`;if(!te.includes(e))return n.error(`Invalid --scope "${t.scope}": expected one of ${te.join(`, `)}.`),1;if(n.detectBundlePath())return pd(`openknowledge://open?project=${encodeURIComponent(r)}&doc=${encodeURIComponent(`__skill__/${e}/${i}`)}`,`Opening skill ${i} (${e}) in the OpenKnowledge desktop app.`,n);let a=n.resolveBaseUrl(r);if(a){let t=`${a}/#/${Ke(e,i)}`;return pd(t,`Opening skill ${i} (${e}) in your browser: ${t}`,n)}return fd(n)}let a=/\/+$/.test(e)||n.classifyName(r,i)===`folder`,o=n.detectBundlePath();if(a){if(o)return pd(`openknowledge://open?project=${encodeURIComponent(r)}&folder=${encodeURIComponent(i)}`,`Opening folder ${i} in the OpenKnowledge desktop app.`,n);let e=n.resolveBaseUrl(r);if(e){let t=`${e}/#/${Qe(i)}`;return pd(t,`Opening folder ${i} in your browser: ${t}`,n)}return fd(n)}if(o)return pd(`openknowledge://open?project=${encodeURIComponent(r)}&doc=${encodeURIComponent(i)}`,`Opening ${i} in the OpenKnowledge desktop app.`,n);let s=n.resolveBaseUrl(r);if(s){let e=`${s}/#/${Xe(i)}`;return pd(e,`Opening ${i} in your browser: ${e}`,n)}return fd(n)}function hd(){return new O(`open`).description(`Open a doc, folder, or skill in the OK Desktop app (falls back to the browser UI). Docs and folders are auto-detected — no flag needed.`).argument(`<name>`,`Doc path (specs/foo/SPEC), folder path (specs/foo or specs/foo/), or a skill name with --skill`).option(`--skill`,`Open <name> as a skill in the skill editor`).option(`--scope <scope>`,`Skill scope when --skill is set: ${te.join(` | `)}`,`project`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action(async(e,t)=>{process.exitCode=await md(e,t,ud())})}function gd(e){return new O(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-CbPgjt4U.mjs`),r=e(),i=process.cwd(),a=ke(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 _d(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function vd(e,t,n=process.cwd()){let r=e.op??`sync`,i=Bt(w(n));if(i&&i.port>0){let t=`http://127.0.0.1:${i.port}/api/sync/trigger`;e.json||process.stderr.write(`Triggering ${r} via running server (port ${i.port})\n`);try{let n=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,...se({kind:`cli`,runtimeVersion:D})},body:JSON.stringify({op:r})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.title??e.error??e.message??`Server responded with ${n.status}`)}_d(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=Rt({baseDir:n});if(r===`sync`||r===`pull`){_d(e.json,{type:`step`,step:`pull`});let t=await a.pull();_d(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(_d(e.json,{type:`step`,step:`push`}),await a.push(),_d(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
|
|
78
78
|
`)),_d(e.json,{type:`complete`,op:r}),e.json||process.stderr.write(`✓ ${r} complete\n`)}function yd(e){return new O(`sync`).description(`Commit, pull, and push to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await vd({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 bd(e){return new O(`pull`).description(`Pull changes from the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await vd({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 xd(e){return new O(`push`).description(`Push commits to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await vd({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 Sd(e,t){if(e.packSkillHomeRefusal===void 0)return``;if(e.packSkillHomeRefusal===`home-escapes-project`)return`\n${N(`!`)} The ${t} skills were not installed: this project's skill folder is a symlink pointing outside the project, and Open Knowledge will not write through it. Replace it with a real directory inside the project, then run \`ok seed\` again.`;let n=[...new Set([Se,...ie.map(e=>ce[e])].filter(e=>e!==null).map(ne))].map(e=>`${e}/`);return`\n${N(`!`)} The ${t} skills were not installed: this project has no agent folder for them. Open Knowledge only writes skills into a folder that already exists (${n.join(`, `)}) and never creates one for you. Create the folder your agent uses, then run \`ok seed\` again to install them.`}function Cd(e){return typeof e==`string`&&Ct.includes(e)}async function wd(e={}){let t=z(e.cwd??process.cwd()),n=e.pack??`knowledge-base`;if(!Le[n])return{status:`failed`,message:`${M(`Error:`)} Unknown pack "${n}". Available: ${Ct.join(`, `)}`,exitCode:1};let r;try{r=await Oe({projectDir:t,rootDir:e.root,packId:n,skipPrerequisite:e.dryRun===!0})}catch(e){return e instanceof at?{status:`prerequisite-missing`,message:`${M(`Error:`)} ${e.message}`,exitCode:1}:{status:`failed`,message:`${M(`Error:`)} ${e instanceof Error?e.message:String(e)}`,exitCode:1}}if(!S(r)){let e=Le[n].name,t=(r.packSkills??[]).filter(e=>e.conflict).map(e=>`\n${N(`!`)} Skill "${e.name}" is your own — the pack's version is not installed. Rename yours to install the pack's version.`).join(``),i=Sd(r,e);return{status:`no-op`,message:`${j(`Your ${e} pack is already seeded.`)}${i}${t}${i===``?`\n${A(`Nothing to do.`)}`:``}`,plan:r,exitCode:0}}if(e.dryRun){let e=Pt(Le[n]);return{status:`dry-run`,message:`${P(`Reference this pack for inspiration (dry-run — no changes made):`)}\n\n${e}\n\n${P(`Plan:`)}\n\n${Ed(r,t)}`,plan:r,exitCode:0}}if(!e.yes&&!await Dd(`${P(`Plan:`)}\n\n${Ed(r,t)}\n\n${P(`Apply?`)} ${A(`[Y/n] `)}`,e.confirmStream))return{status:`cancelled`,message:A(`Cancelled.`),plan:r,exitCode:0};let i=await Ye(r,{projectDir:t,packId:n});if(i.errors.length>0){let e=i.errors.map(e=>` ${M(`✗`)} ${e.path}: ${e.error}`);return{status:`failed`,message:[`${N(`Applied`)} ${i.applied} entries, ${N(String(i.errors.length))} error(s):`,...e].join(`
|
|
79
79
|
`),plan:r,exitCode:1}}let a=Le[n].name,o=i.packSkillsInstalled.length>0?`\n${A(`Installed the ${a} skills for: ${i.packSkillsInstalled.join(`, `)}`)}`:``,s=i.pluginsEnabled.length>0?`\n${A(`Enabled plugin(s) included with this pack: ${i.pluginsEnabled.join(`, `)} — turn off any time in Settings.`)}`:``,c=(i.packSkillConflicts??[]).map(e=>e.hosts===void 0||e.hosts.length===0?`\n${N(`!`)} Skill "${e.name}" was not installed — you already have your own skill with that name. Rename yours if you want the pack's version.`:`\n${N(`!`)} Skill "${e.name}" was not installed for ${e.hosts.join(`, `)} — you already have your own skill with that name there. Rename yours if you want the pack's version.`).join(``);return{status:`applied`,message:`${j(`✓ Seeded ${a}`)} ${A(`(${i.applied} entries, ${i.durationMs}ms)`)}${o}${s}${Sd(r,a)}${c}`,plan:r,exitCode:0}}function Td(){let e=[P(`Available packs:`)];for(let t of Ct){let n=Le[t];e.push(` ${j(t)} ${A(`—`)} ${n.name}: ${n.description}`)}return e.join(`
|
|
80
80
|
`)}function Ed(e,t){let n=[],r=e.created.filter(e=>e.kind===`folder`),i=e.created.filter(e=>e.kind===`file`);if(r.length>0){n.push(P(`Folders to create:`));for(let e of r)n.push(` ${j(`+`)} ${k(R(t,z(t,e.path))||e.path)}${A(`/`)}`)}if(i.length>0){n.length>0&&n.push(``),n.push(P(`Files to create:`));for(let e of i)n.push(` ${j(`+`)} ${k(R(t,z(t,e.path))||e.path)}`)}if(e.skipped.length>0){n.length>0&&n.push(``),n.push(A(`Already present (skipped):`));for(let t of e.skipped)n.push(` ${A(`· ${t.path} (${t.reason})`)}`)}if(e.warnings.length>0){n.length>0&&n.push(``),n.push(N(`Warnings:`));for(let t of e.warnings)n.push(` ${N(`!`)} ${t}`)}let a=(e.packSkills??[]).filter(e=>e.conflict);if(a.length>0){n.length>0&&n.push(``),n.push(N(`Name collisions:`));for(let e of a)n.push(` ${N(`!`)} Skill "${e.name}" is your own — the pack's version will not be installed. Rename yours to install the pack's version.`)}return n.join(`
|
|
@@ -83,7 +83,7 @@ ${t}`,d++;break;case`id`:l=t.includes(`\0`)?void 0:t;break;case`retry`:/^\d+$/.t
|
|
|
83
83
|
`);return}if(a){process.stdout.write(`${JSON.stringify({type:`error`,code:c.kind})}\n`);return}process.stderr.write(`✗ share name-check failed: ${c.kind}\n`),process.exit(1)}function jd(e){return new O(`name-check`).description(`Check if owner/name is available on GitHub`).requiredOption(`--owner <owner>`,`GitHub owner (user or org)`).requiredOption(`--name <name>`,`Repository name`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{await Ad(t,await e())})}async function Md(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 Nd(e,t){let{host:n,json:r}=e;G(n);let i=await pa(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 Md(new oa({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 Pd(e){return new O(`owners`).description(`List GitHub owners eligible to host a new repository`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{await Nd(t,await e())})}function Fd(e){let t=e,n=t.status,r=t.response?.data,i=t.response?.headers,a=`${r?.message??r?.errors?.map(e=>e.message??``).join(`
|
|
84
84
|
`)??``}\n${t.message??``}`.toLowerCase();return n===401?`auth-required`:n===403?i?.[`x-github-sso`]||a.includes(`saml`)||a.includes(`sso`)?`saml-sso`:`network`:n===422&&(r?.errors?.some(e=>e.field===`name`)||a.includes(`already exists`)||a.includes(`name already exists`))?`name-conflict`:`network`}async function Id(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 Ld(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 Rd(e,t){return(await e.users.getAuthenticated()).data.login.toLowerCase()===t.toLowerCase()?`user`:`org`}function zd(e){return Rt(za(e,[])).env(Na())}function Bd(e,t){if(!e.startsWith(`https://`))return e;try{if(new URL(e).hostname!==`github.com`)return e}catch{return e}return e.replace(`https://`,`https://x-access-token:${t}@`)}const Vd={ensureOkScaffold:e=>{qe(e)},gitFactory:zd};async function Hd(e){let t={...Vd,...e.deps},n=z(e.projectDir),r;if(e.ownerKind)r=e.ownerKind;else try{r=await Rd(e.octokit,e.body.owner)}catch(e){return{kind:`error`,code:Fd(e)}}try{t.ensureOkScaffold(n)}catch{return{kind:`error`,code:`init-failed`}}let i=t.gitFactory(n);if(!B(L(n,`.git`)))try{await i.init()}catch{return{kind:`error`,code:`init-failed`}}let a;try{a=await Id({octokit:e.octokit,ownerLogin:e.body.owner,ownerKind:r,name:e.body.name,visibility:e.body.visibility,description:e.body.description})}catch(t){if(Fd(t)===`name-conflict`){let t=await Ld(e.octokit,e.body.owner,e.body.name);if(t===null)return{kind:`error`,code:`name-conflict`};a=t}else return{kind:`error`,code:Fd(t)}}try{await i.addRemote(`origin`,a.cloneUrl)}catch(e){if(!String(e.message??``).toLowerCase().includes(`remote origin already exists`))return{kind:`error`,code:`push-failed`}}let o=!1;try{await i.raw([`rev-parse`,`--verify`,`HEAD`])}catch{o=!0}if(o)try{await i.add(`.`),await i.raw([`commit`,`--allow-empty`,`-m`,`Initial commit`])}catch{return{kind:`error`,code:`init-failed`}}let s=Bd(a.cloneUrl,e.token);try{await i.raw([`push`,s,`HEAD:refs/heads/${a.defaultBranch}`])}catch(e){let t=String(e.message??``).toLowerCase();return t.includes(`saml`)||t.includes(`sso`)?{kind:`error`,code:`saml-sso`}:{kind:`error`,code:`push-failed`}}try{await i.raw([`update-ref`,`refs/remotes/origin/${a.defaultBranch}`,`HEAD`])}catch{}return{kind:`ok`,value:{ownerLogin:e.body.owner,repoName:e.body.name,cloneUrl:a.cloneUrl,defaultBranch:a.defaultBranch}}}function Ud(e,t){if(!e){t.kind===`ok`?process.stdout.write(`✓ Published ${t.value.cloneUrl}\n`):(process.stderr.write(`✗ share publish failed: ${t.code}\n`),process.exit(1));return}if(t.kind===`ok`){process.stdout.write(`${JSON.stringify({type:`publish`,...t.value})}\n`);return}process.stdout.write(`${JSON.stringify({type:`error`,code:t.code})}\n`)}async function Wd(e,t){let{host:n,owner:r,name:i,visibility:a,description:o,projectDir:s,json:c}=e;if(G(n),Ue(s)){process.stderr.write(`${new Je(z(s)).message}\n`),process.exitCode=64;return}let l=await pa(n,t);if(l==null){Ud(c,{kind:`error`,code:`auth-required`});return}let u=n===`github.com`?void 0:`https://${n}/api/v3`,d=new oa({auth:l,...u?{baseUrl:u}:{}});try{Zn(`git config user.email`,T({cwd:s,stdio:`ignore`}))}catch{process.env.GIT_AUTHOR_NAME??=`OpenKnowledge`,process.env.GIT_AUTHOR_EMAIL??=`noreply@inkeep.com`,process.env.GIT_COMMITTER_NAME??=`OpenKnowledge`,process.env.GIT_COMMITTER_EMAIL??=`noreply@inkeep.com`}Ud(c,await Hd({octokit:d,token:l,projectDir:s,body:{owner:r,name:i,visibility:a,description:o}}))}function Gd(e){return new O(`publish`).description(`Publish a no-remote project to GitHub`).requiredOption(`--owner <owner>`,`GitHub owner (user or org)`).requiredOption(`--name <name>`,`Repository name`).requiredOption(`--visibility <visibility>`,`public or private`).option(`--description <description>`,`Repository description`).requiredOption(`--project-dir <projectDir>`,`Path to the project on disk`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{t.visibility!==`public`&&t.visibility!==`private`&&(process.stderr.write(`✗ visibility must be 'public' or 'private'
|
|
85
85
|
`),process.exit(1)),await Wd(t,await e())})}function Kd(){let e=new O(`share`);e.description(`Sharing flow operations (owners, name-check, publish)`);let t=()=>pn();return e.addCommand(Pd(t)),e.addCommand(jd(t)),e.addCommand(Gd(t)),e}function qd(){return new O(`share`).description(`Switch this project to shared mode (commit OK config alongside content)`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=z(e.project??process.cwd()),n=kn(t),r=jn(t,Sn(t));if(r.kind===`no-exclude`){Jd(e.json,t,r.reason);return}let i=kn(t);if(e.json){let e={type:`sharing-share`,projectRoot:t,mode:i,removed:r.removed};process.stdout.write(`${JSON.stringify(e)}\n`);return}if(n===`shared`){process.stderr.write(`${k(`Sharing mode is already`)} ${P(`shared`)} ${k(`— nothing to do.`)}\n`);return}process.stderr.write(`${j(`✓`)} ${P(`Sharing mode set to`)} ${j(`shared`)}\n`),process.stderr.write(` Removed OK paths from ${P(`.git/info/exclude`)}; commit the files to share with teammates.\n`)})}function Jd(e,t,n){if(e){process.stdout.write(`${JSON.stringify({type:`sharing-share`,projectRoot:t,mode:`no-git`,removed:[],reason:n})}\n`);return}process.stderr.write(`${N({"no-git":`No git repository here — sharing mode does not apply.`,"no-info-dir":`The gitdir's info/ folder is absent; cannot toggle sharing mode.`,"malformed-pointer":"The .git pointer file is malformed (stale worktree). Run `git worktree prune` and try again.",inaccessible:`The .git path is inaccessible (permissions or mount issue).`}[n])}\n`)}function Yd(){return new O(`status`).description(`Print the current sharing mode and the OK paths in .git/info/exclude`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=z(e.project??process.cwd()),n=kn(t),r=An(t),i=[...In(t)],a=Fn(t,Sn(t)).tracked;if(e.json){let e={type:`sharing-status`,projectRoot:t,mode:n,skillsShared:r,excluded:i,trackedUpstream:a};process.stdout.write(`${JSON.stringify(e)}\n`);return}let o=[];if(o.push(`OpenKnowledge sharing mode: ${Xd(n)}`),r&&o.push(` ${P(`.ok/skills`)} is committable (carved out); the rest of .ok/ stays local.`),o.push(``),o.push(`Excluded from git via ${P(`.git/info/exclude`)}:`),i.length===0)o.push(` (none)`);else for(let e of i)o.push(` ${e}`);if(o.push(``),o.push(`Other OK paths exist but are tracked upstream:`),a.length===0)o.push(` (none)`);else for(let e of a)o.push(` ${e}`);o.push(``),o.push(`Toggle with: ${k(n===`local-only`?`ok config-sharing share`:`ok config-sharing unshare`)}`),r&&o.push(` (that shares the whole project; to undo only the skills carve-out, use the desktop app: Settings > Sync & sharing)`),process.stdout.write(`${o.join(`
|
|
86
|
-
`)}\n`)})}function Xd(e){switch(e){case`shared`:return j(`shared`);case`local-only`:return j(`local-only`);case`no-git`:return N(`no-git (not a git repository)`)}}function Zd(){return new O(`unshare`).description(`Switch this project to local-only mode (add OK artifacts to .git/info/exclude so they stay out of git)`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=z(e.project??process.cwd()),n=Tn(t,Sn(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`){Qd(e.json,t,n.reason);return}let r=kn(t);if(e.json){let e={type:`sharing-unshare`,projectRoot:t,mode:r,appended:n.appended,alreadyPresent:n.alreadyPresent};process.stdout.write(`${JSON.stringify(e)}\n`);return}if(n.appended.length===0){process.stderr.write(`${P(`Sharing mode is already`)} ${j(`local-only`)} ${P(`— nothing to do.`)}\n`);return}process.stderr.write(`${j(`✓`)} ${P(`Sharing mode set to`)} ${j(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${P(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function Qd(e,t,n){if(e){process.stdout.write(`${JSON.stringify({type:`sharing-unshare`,projectRoot:t,mode:`no-git`,appended:[],alreadyPresent:[],reason:n})}\n`);return}process.stderr.write(`${N({"no-git":`No git repository here — sharing mode does not apply.`,"no-info-dir":`The gitdir's info/ folder is absent; cannot toggle sharing mode.`,"malformed-pointer":"The .git pointer file is malformed (stale worktree). Run `git worktree prune` and try again.",inaccessible:`The .git path is inaccessible (permissions or mount issue).`}[n])}\n`)}function $d(){let e=new O(`config-sharing`);return e.description(`Manage OpenKnowledge's git-sharing mode (share OK config with the team, or keep local-only on this machine)`),e.addCommand(qd()),e.addCommand(Zd()),e.addCommand(Yd()),e}const ef=new Set([`--cwd`,`--log-level`]);function tf(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(`-`)){ef.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function nf(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 rf(e){return/\.(md|mdx)$/i.test(e)}function af(e,t){if(rf(t))return!0;try{return U(e).isFile()}catch(t){let n=t?.code;return n!==`ENOENT`&&n!==`ENOTDIR`&&process.stderr.write(`[ok] statSync failed for ${e} (${n??`unknown`}); treating as non-fileish\n`),!1}}function of(e=()=>mn(_n())){return{prepare:nt,detectBundlePath:()=>e().bundlePath??null,openTarget:cd,runProjectOpen:(e,t)=>md(e,{project:t},ud()),runBrowserOpen:e=>cf(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function sf(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof _t||e instanceof Ot||e instanceof wt)return t.error(e.message),1;throw e}if(n.mode===`project`)return await t.runProjectOpen(n.docName,n.projectRoot);if(t.detectBundlePath()){let e=`openknowledge://open?file=${encodeURIComponent(n.canonicalFilePath)}`,r=await t.openTarget(e);return r.ok?(t.log(`Opening ${n.singleDocRelPath} in the OpenKnowledge desktop app.`),0):(t.error(`Could not open the OpenKnowledge desktop app: ${ld(r.reason,e)}.`),1)}return await t.runBrowserOpen(n),0}async function cf(e){let{createEphemeralProjectDir:t}=await import(`./src-
|
|
86
|
+
`)}\n`)})}function Xd(e){switch(e){case`shared`:return j(`shared`);case`local-only`:return j(`local-only`);case`no-git`:return N(`no-git (not a git repository)`)}}function Zd(){return new O(`unshare`).description(`Switch this project to local-only mode (add OK artifacts to .git/info/exclude so they stay out of git)`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=z(e.project??process.cwd()),n=Tn(t,Sn(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`){Qd(e.json,t,n.reason);return}let r=kn(t);if(e.json){let e={type:`sharing-unshare`,projectRoot:t,mode:r,appended:n.appended,alreadyPresent:n.alreadyPresent};process.stdout.write(`${JSON.stringify(e)}\n`);return}if(n.appended.length===0){process.stderr.write(`${P(`Sharing mode is already`)} ${j(`local-only`)} ${P(`— nothing to do.`)}\n`);return}process.stderr.write(`${j(`✓`)} ${P(`Sharing mode set to`)} ${j(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${P(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function Qd(e,t,n){if(e){process.stdout.write(`${JSON.stringify({type:`sharing-unshare`,projectRoot:t,mode:`no-git`,appended:[],alreadyPresent:[],reason:n})}\n`);return}process.stderr.write(`${N({"no-git":`No git repository here — sharing mode does not apply.`,"no-info-dir":`The gitdir's info/ folder is absent; cannot toggle sharing mode.`,"malformed-pointer":"The .git pointer file is malformed (stale worktree). Run `git worktree prune` and try again.",inaccessible:`The .git path is inaccessible (permissions or mount issue).`}[n])}\n`)}function $d(){let e=new O(`config-sharing`);return e.description(`Manage OpenKnowledge's git-sharing mode (share OK config with the team, or keep local-only on this machine)`),e.addCommand(qd()),e.addCommand(Zd()),e.addCommand(Yd()),e}const ef=new Set([`--cwd`,`--log-level`]);function tf(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(`-`)){ef.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function nf(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 rf(e){return/\.(md|mdx)$/i.test(e)}function af(e,t){if(rf(t))return!0;try{return U(e).isFile()}catch(t){let n=t?.code;return n!==`ENOENT`&&n!==`ENOTDIR`&&process.stderr.write(`[ok] statSync failed for ${e} (${n??`unknown`}); treating as non-fileish\n`),!1}}function of(e=()=>mn(_n())){return{prepare:nt,detectBundlePath:()=>e().bundlePath??null,openTarget:cd,runProjectOpen:(e,t)=>md(e,{project:t},ud()),runBrowserOpen:e=>cf(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function sf(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof _t||e instanceof Ot||e instanceof wt)return t.error(e.message),1;throw e}if(n.mode===`project`)return await t.runProjectOpen(n.docName,n.projectRoot);if(t.detectBundlePath()){let e=`openknowledge://open?file=${encodeURIComponent(n.canonicalFilePath)}`,r=await t.openTarget(e);return r.ok?(t.log(`Opening ${n.singleDocRelPath} in the OpenKnowledge desktop app.`),0):(t.error(`Could not open the OpenKnowledge desktop app: ${ld(r.reason,e)}.`),1)}return await t.runBrowserOpen(n),0}async function cf(e){let{createEphemeralProjectDir:t}=await import(`./src-DorV8gmN.mjs`),{loadConfig:n}=await import(`./src-D_5cigYC.mjs`),{bootStartServer:r,resolveBundledReactShellDir:i,resolveHost:a}=await import(`./start-C7xEQnkW.mjs`),{openBrowser:o}=await import(`./open-browser-BklPlV75.mjs`),s=i();s||(process.stderr.write("OpenKnowledge UI assets were not found. Reinstall @inkeep/open-knowledge, or build the app (`bun run build`) in a monorepo checkout.\n"),process.exit(1));let c=t(e.contentDir),l=!1,u,d=async()=>{if(!l){l=!0;try{await u?.destroy()}catch{}try{await xr(c,{recursive:!0,force:!0})}catch{}}},f=()=>{d().then(()=>process.exit(0))};process.once(`SIGINT`,f),process.once(`SIGTERM`,f);let{config:p}=n(c),m=a({},process.env);try{u=await r({config:p,cwd:c,host:m,port:0,projectDir:c,singleFile:e.canonicalFilePath,serveContentAssets:!0,reactShellDistDir:s,idleThresholdMs:6e5})}catch(t){await d(),process.stderr.write(`Failed to open ${e.singleDocRelPath}: ${t instanceof Error?t.message:String(t)}\n`),process.exit(1)}let h=`http://${m}:${u.port}/#/${Xe(e.docName)}`;process.env.OK_SINGLE_FILE_NO_OPEN===`1`?process.stdout.write(`Serving ${e.singleDocRelPath} (headless) at: ${h}\n`):(process.stdout.write(`Opening ${e.singleDocRelPath} in your browser: ${h}\n`),process.stdout.write(`Press Ctrl-C to close the session.
|
|
87
87
|
`),o(h)),await new Promise(()=>{})}function lf(){let e=new O(`skills`).description(`Manage Open Knowledge skills for this project.`);return e.command(`installed`).description(`List every skill installed across all your agents (read-only).`).option(`--json`,`Emit the raw enumeration as JSON.`).action(e=>{let t=z(process.cwd()),n=Ve(Mt(t)?.rootPath??t),r=dt({projectDir:n}),i={...r,skills:r.skills.filter(e=>_e(e.provenance,n))};if(e.json){process.stdout.write(`${JSON.stringify(i,null,2)}\n`);return}if(i.skills.length===0){process.stdout.write(`${A(`No installed skills found across any agent.`)}\n`);return}process.stdout.write(`${P(`${i.skills.length} installed skill(s):`)}\n`);for(let e of i.skills){let t=e.provenance.version?A(` v${e.provenance.version}`):``,n=[e.inert.commands&&`commands`,e.inert.hooks&&`hooks`,e.inert.mcp&&`mcp`].filter(Boolean),r=n.length>0?A(` [${n.join(`, `)}]`):``;process.stdout.write(` ${j(e.name)}${t} ${A(e.sourceHarnesses.join(`, `))}${r}\n`)}process.stdout.write(`\n${P(`${i.packs.length} pack(s):`)}\n`);for(let e of i.packs)process.stdout.write(` ${k(e.name)} ${A(`v${e.version}`)} — ${e.skills.length} skill(s)\n`)}),e.command(`import <source>`).description(`Import a skill into this project as versioned content (github owner/repo, a git URL, or a local path).`).option(`--skill <name>`,`Pick one skill from a multi-skill source.`).option(`--scope <scope>`,`project (default) or global.`,`project`).action(async(e,t)=>{let n=Yt(w(process.cwd()),`server`);if(n.status!==`alive`){process.stderr.write(`${M(`Error:`)} no running Open Knowledge server for this project. Start it with ${P(`ok start`)} and retry.\n`),process.exitCode=1;return}let r;try{r=await fetch(`http://127.0.0.1:${n.lock.port}/api/skill/import`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({source:e,...t.skill?{skill:t.skill}:{},scope:t.scope===`global`?`global`:`project`})})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`${M(`Error:`)} could not reach the server: ${t}\n`),process.exitCode=1;return}let i=await r.json().catch(()=>({}));if(!r.ok){let e=i.detail??i.title??`HTTP ${r.status}`;process.stderr.write(`${M(`Import failed:`)} ${e}\n`),process.exitCode=1;return}let a=i.name;if(i.alreadyImported){process.stdout.write(`${k(`Already imported:`)} ${P(a)} (identical content).\n`);return}let o=i.provenance??{},s=i.collisionRenamedFrom;process.stdout.write(`${j(`Imported`)} ${P(a)}${s?A(` (renamed from ${s} — name was taken)`):``} from ${A(o.source??e)}${o.publisher?A(` · ${o.publisher}`):``}.\n${A(`Saved as versioned content in this project's skill home. Scripts shown, never run. Use the skill's install menu (or the install MCP verb) to add it to your other editors.`)}\n`);for(let e of i.warnings??[])process.stdout.write(` ${A(`! ${e}`)}\n`)}),e}function uf(e,t){let n=df(`server`,e),r=df(`ui`,t);return r.state===`missing`&&e.status===`alive`&&e.lock.capabilities?.includes(`ui`)===!0&&(r={name:`ui`,state:`alive`,pid:e.lock.pid,port:e.lock.port,startedAt:e.lock.startedAt,host:e.lock.hostname,alive:!0,servedByServer:!0}),{server:n,ui:r}}function df(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 ff(e){return`${pf(e.server)}\n${pf(e.ui)}`}function pf(e){let t=e.name===`server`?`server`:`ui `;return e.state===`missing`?`${t} not running`:e.state===`corrupt`?`${t} lock file corrupt — run \`ok clean\``:e.state===`foreign-host`?`${t} foreign host (${e.host}) pid=${e.pid} port=${e.port}`:e.state===`dead-pid`?`${t} stale (dead pid=${e.pid}) — run \`ok clean\``:e.servedByServer===!0?`${t} served by server pid=${e.pid} port=${e.port}`:`${t} alive pid=${e.pid} port=${e.port} started=${e.startedAt}`}function mf(e){let t=e.inspect??(t=>Yt(e.lockDir,t)),n=e.log??(e=>console.log(e)),r=uf(t(`server`),t(`ui`));return e.json?n(JSON.stringify(r,null,2)):n(ff(r)),r}function hf(e){return new O(`status`).description(`Show live state of the server + ui lockfiles for this project`).option(`--json`,`Emit structured JSON instead of formatted text`).action(t=>{e(),mf({lockDir:w(process.cwd()),json:t.json===!0})})}function gf(e){if(e.yes===!0||e.json===!0)return!1;let t=e.stdinIsTTY??process.stdin.isTTY,n=e.stdoutIsTTY??process.stdout.isTTY;return t===!0&&n===!0}async function _f(e,t){let n=Tr({input:e.input,output:e.output});try{return(await n.question(t)).trim()}finally{n.close()}}async function vf(e={}){let t={input:e.input??process.stdin,output:e.output??process.stderr};t.output.write(A(`
|
|
88
88
|
What you share is sent to the OpenKnowledge team.
|
|
89
89
|
`));let n=await Nn({message:`Before you go, mind sharing why? (optional)`,default:null,pageSize:he.length+1,choices:[...he.map(e=>({name:e.label,value:e.value})),{name:`Skip, I'd rather not say`,value:null}]},t);if(n===null)return{};let r=await _f(t,A(`Anything else we should know? (optional) `)),i=await _f(t,A(`Email, if we may follow up (optional) `));return{reason:n,note:r||void 0,email:i||void 0}}async function yf(e){if(!gf(e))return`not-prompted`;let t;try{t=await(e.collect??(()=>vf(e)))()}catch{return`failed`}return oe(t)?((e.output??process.stderr).write(`\n${P(`Thank you. We read every response.`)}\n\n`),(await(e.submit??we)({...t,source:`cli_uninstall`,appVersion:e.appVersion,platform:e.platform})).ok?`submitted`:`undelivered`):`skipped`}function bf(e,t,n=xf,r=B,i={}){let a=[],o=i.platform??process.platform,s=i.env??process.env;if(o===`darwin`)for(let t of[`/Applications/OpenKnowledge.app`,L(e,`Applications`,`OpenKnowledge.app`)])r(t)&&a.push({method:`app`,label:`OK Desktop (${t})`,instruction:`Move ${t} to the Trash (or: rm -rf "${t}")`});else if(o===`win32`){let e=s.LOCALAPPDATA;if(e)for(let t of[`@inkeepopen-knowledge-desktop`,`OpenKnowledge`]){let n=L(e,`Programs`,t,`OpenKnowledge.exe`);if(r(n)){a.push({method:`app`,label:`OK Desktop (${n})`,instruction:`Uninstall from Windows Settings → Apps → Installed apps → OpenKnowledge`});break}}}else o===`linux`&&r(`/opt/OpenKnowledge/openknowledge`)&&a.push({method:`app`,label:`OK Desktop (/opt/OpenKnowledge)`,instruction:`Remove with your package manager: sudo apt remove openknowledge (Debian/Ubuntu) or sudo dnf remove OpenKnowledge (Fedora/RHEL)`});return n([`ls`,`-g`,`--depth=0`,`@inkeep/open-knowledge`])?.includes(`@inkeep/open-knowledge@`)&&a.push({method:`npm-global`,label:`npm global install`,instruction:`npm uninstall -g @inkeep/open-knowledge`}),t&&/[/\\]_npx[/\\]/.test(t)&&a.push({method:`npx`,label:`npx (ephemeral)`,instruction:`Nothing to uninstall — npx runs from a temporary cache. (Optional: npm cache clean --force)`}),a}function xf(e){try{return Xn(`npm`,e,T({encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}))}catch{return null}}const Sf=`━`.repeat(64);function Cf(e,t=process.platform){let n=[N(Sf),P(` One more step — remove the OpenKnowledge app itself`),A(` (OpenKnowledge can't delete its own running binary — do this by hand.)`),``];if(e.length===0){let e=t===`win32`?`uninstall from Settings → Apps → Installed apps → OpenKnowledge`:t===`linux`?`remove the openknowledge package with your package manager (apt / dnf)`:`move /Applications/OpenKnowledge.app to the Trash`;n.push(A(` Install method not detected. If you installed it, remove it via:`)),n.push(` ${k(`OK Desktop`)} — ${e}`),n.push(` ${k(`npm global`)} — npm uninstall -g @inkeep/open-knowledge`),n.push(` ${k(`npx`)} — nothing to remove (runs from a temporary cache)`)}else for(let t of e)n.push(` ${k(t.label)}`),n.push(` ${t.instruction}`);return n.push(N(Sf)),n.join(`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e,c as t}from"./fs-traced-Dy67FR5_.mjs";export{t as tracedMkdir,e as tracedWriteFile};
|