@inkeep/open-knowledge 0.15.1-beta.8 → 0.16.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/skills/discovery/SKILL.md +1 -1
- package/dist/assets/skills/packs/okf/SKILL.md +52 -0
- package/dist/assets/skills/project/SKILL.md +1 -1
- package/dist/cli.mjs +5 -5
- package/dist/constants-zR9K6MQx.mjs +2 -0
- package/dist/{dist-By70vg0t.mjs → dist-6j4x3nmy.mjs} +1 -1
- package/dist/{dist-CTSVLMDV.mjs → dist-Dcg4smYg.mjs} +89 -2
- package/dist/index.mjs +1 -1
- package/dist/init-5s5Urhtt.mjs +1 -0
- package/dist/{init-aYL9jcNv.mjs → init-Dx1FSwm_.mjs} +4 -4
- package/dist/{loader-CWI8ks9W.mjs → loader-Bi8VVUuv.mjs} +2 -2
- package/dist/loader-N9LzTn4Q.mjs +1 -0
- package/dist/preview-BvKJzJeL.mjs +1 -0
- package/dist/{preview-D8NePS8S.mjs → preview-CNJw1WeR.mjs} +2 -2
- package/dist/public/assets/index-CIPatjw4.css +1 -0
- package/dist/public/assets/{index-COE4tg_p.js → index-DIPWIhIx.js} +96 -96
- package/dist/public/index.html +2 -2
- package/dist/{repair-launch-json-DXLiy3_c.mjs → repair-launch-json-Bm5zcxnt.mjs} +2 -2
- package/dist/{repair-mcp-configs-DB8b3UTm.mjs → repair-mcp-configs-B6-IzQ47.mjs} +2 -2
- package/dist/repair-skills-DrcVDbk1.mjs +1 -0
- package/dist/{repair-skills-M719vrZS.mjs → repair-skills-DsHqeRKO.mjs} +2 -2
- package/dist/{src-S9W6ORmK.mjs → src-DmdJFypb.mjs} +2 -2
- package/dist/start-LI_wE7gV.mjs +1 -0
- package/dist/{start-8EN9Ekcs.mjs → start-mHeHaykC.mjs} +2 -2
- package/dist/{write-project-skill-CD8uXqFq.mjs → write-project-skill-C5HoLkCk.mjs} +2 -2
- package/package.json +1 -1
- package/dist/constants-BVR2lBMG.mjs +0 -2
- package/dist/init-CouVGATa.mjs +0 -1
- package/dist/loader-m_58dShD.mjs +0 -1
- package/dist/preview-D3Z-uBc0.mjs +0 -1
- package/dist/public/assets/index-5V9bJ3LG.css +0 -1
- package/dist/repair-skills-BQnVB088.mjs +0 -1
- package/dist/start-_FVQvoNg.mjs +0 -1
|
@@ -3,7 +3,7 @@ name: open-knowledge-discovery
|
|
|
3
3
|
description: "Read when the user asks what Open Knowledge is, wants to install it on a repository, wants to share an Open Knowledge project with collaborators, or asks how `ok init` / `ok install-skill` / OK Desktop set up a project. Do NOT load to perform Open Knowledge reads/writes — the runtime guidance for editing markdown inside an initialized OK project ships as a separate project-local skill at `.claude/skills/open-knowledge/` whenever `ok init` runs. If the user appears to be editing markdown inside a `.ok/` project and this is the only OK skill loaded, advise them to re-run `ok init` to install the project-local skill."
|
|
4
4
|
compatibility: "Any agent host — no MCP server required. Pure discovery + install guidance."
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.
|
|
6
|
+
version: "0.16.0-beta.0"
|
|
7
7
|
author: "Inkeep"
|
|
8
8
|
repository: "https://github.com/inkeep/open-knowledge"
|
|
9
9
|
---
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: open-knowledge-pack-okf
|
|
3
|
+
description: "How to work in an OKF starter project (the `okf` starter pack): a knowledge base that is conformant with Google's Open Knowledge Format (OKF) from commit one — `concepts/`, `references/`, `notes/`, a reserved `index.md` navigation hub, and a reserved `log.md` change history. Read when the project has these folders + reserved files. Carries the OKF conventions (non-empty `type` on every non-reserved doc; reserved files carry no frontmatter) as guidance, not enforcement. Complements the platform `open-knowledge` skill; does not replace it."
|
|
4
|
+
compatibility: "Claude Code, Claude Desktop, Claude Cowork, Claude.ai web. Requires Open Knowledge MCP server. Installed project-local by `ok seed --pack okf`."
|
|
5
|
+
# `type` keeps this skill doc OKF-conformant: it installs as project-local
|
|
6
|
+
# markdown under `.claude`/`.cursor`/`.agents` skills dirs, which OK admits into
|
|
7
|
+
# the content corpus — so without a non-empty `type` it would be a non-reserved
|
|
8
|
+
# doc that violates the pack's own "every non-reserved doc has a `type`" contract.
|
|
9
|
+
type: Document
|
|
10
|
+
metadata:
|
|
11
|
+
pack: "okf"
|
|
12
|
+
author: "Inkeep"
|
|
13
|
+
repository: "https://github.com/inkeep/open-knowledge"
|
|
14
|
+
---
|
|
15
|
+
# OKF starter pack — how to work here
|
|
16
|
+
|
|
17
|
+
This project was scaffolded to be conformant with **Google's Open Knowledge Format (OKF) v0.1** from the first commit — markdown + YAML frontmatter, a standard-markdown link graph, and two reserved files. Conformance here is pre-populated, **not enforced**: Open Knowledge's native frontmatter schema stays open-shaped, nothing is linted, and you are free to author however you like. This skill explains the conventions so the kit stays OKF-portable as it grows.
|
|
18
|
+
|
|
19
|
+
> This skill is pack guidance. The platform `open-knowledge` skill (read/write/preview/grounding rules) still governs every markdown operation — this layers OKF conventions on top.
|
|
20
|
+
|
|
21
|
+
## The one rule (keep the kit conformant)
|
|
22
|
+
|
|
23
|
+
OKF requires exactly one thing of every **non-reserved** document: a **non-empty `type`** in its frontmatter. That is the whole conformance contract for your content.
|
|
24
|
+
|
|
25
|
+
- The value is **yours to choose** — `concept`, `reference`, `note`, `person`, `event`, anything that fits. There is no blessed taxonomy.
|
|
26
|
+
- `Document` is a fine **generic fallback** when nothing more specific fits (it is just a non-empty value, not a special keyword).
|
|
27
|
+
- The folder templates already set a sensible `type` per section — create docs with `write({ document: { path, template: "<name>" } })` and you inherit it.
|
|
28
|
+
|
|
29
|
+
## Folders
|
|
30
|
+
|
|
31
|
+
- **`concepts/`** — durable ideas and definitions, one file per concept (`type: concept`).
|
|
32
|
+
- **`references/`** — external sources and citations you rely on (`type: reference`).
|
|
33
|
+
- **`notes/`** — working notes and observations (`type: note`).
|
|
34
|
+
|
|
35
|
+
Link liberally with **standard markdown links** (`[text](./path.md)`) — the value is the graph that emerges from the links between typed docs, and standard links keep that graph portable to any OKF consumer. (Open Knowledge also accepts `[[wiki-link]]` shorthand as a native superset, and the OKF export normalizes it to standard links — but seeded content uses standard links so the bundle is conformant as-is.)
|
|
36
|
+
|
|
37
|
+
## Reserved files (keep them frontmatter-free)
|
|
38
|
+
|
|
39
|
+
OKF reserves two lowercase files at the project root. **Neither carries frontmatter** — adding any frontmatter to a reserved file breaks OKF conformance.
|
|
40
|
+
|
|
41
|
+
- **`index.md`** (OKF §6) — the navigation hub: a link-list to the key docs and sections. Keep it current as you add important docs; it is how a reader (or a strict OKF consumer) finds their way in.
|
|
42
|
+
- **`log.md`** (OKF §7) — the change history: newest-first dated entries shaped `## YYYY-MM-DD: <summary>`. Add an entry whenever you create, edit, or restructure content. The seed ships a prose instruction documenting this format — add your first dated entry on your first edit.
|
|
43
|
+
|
|
44
|
+
The tool does not keep these live for you (that would be enforcement) — maintaining them is part of authoring here.
|
|
45
|
+
|
|
46
|
+
## What stays OKF-portable
|
|
47
|
+
|
|
48
|
+
- Every non-reserved doc has a non-empty `type`. ✅
|
|
49
|
+
- `index.md` / `log.md` stay lowercase and frontmatter-free. ✅
|
|
50
|
+
- Links use standard markdown / wiki-link syntax. ✅
|
|
51
|
+
|
|
52
|
+
If you ever want to hand this knowledge base to a strict OKF consumer, those three habits are all it takes.
|
|
@@ -3,7 +3,7 @@ name: open-knowledge
|
|
|
3
3
|
description: "MUST invoke before reading or editing any `.md` / `.mdx` file, and before any `mcp__open-knowledge__*` tool call (`exec`, `search`, `write`, `edit`, and the rest). This skill is installed into the repository by `ok init`, so its presence alone means this is an Open Knowledge project — its runtime contract governs every markdown file here, with no need to probe for a `.ok/` directory. Authoritative agent-runtime contract for working inside this Open Knowledge project."
|
|
4
4
|
compatibility: "Claude Code, Claude Desktop, Claude Cowork, Claude.ai web. Requires Open Knowledge MCP server + code execution."
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.
|
|
6
|
+
version: "0.16.0-beta.0"
|
|
7
7
|
author: "Inkeep"
|
|
8
8
|
repository: "https://github.com/inkeep/open-knowledge"
|
|
9
9
|
---
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{s as e}from"./chunk-C94x7I9S.mjs";import{t}from"./esm-BLMtE3s6.mjs";import{Da as n,Gr as r,Ji as i,Li as a,Mi as o,Ni as s,Oa as c,Sr as l,Wi as u,Xi as d,Yi as f,bn as p,ea as m,f as h,n as g,na as _,pa as v,ra as y,s as b,sa as x,ta as S,ua as C}from"./server-lock-BpjJj3OD-DlYx_Xz-.mjs";import{a as ee,n as w,r as te,t as ne}from"./gh-detect-wbzQ2Z5B.mjs";import{r as T}from"./git-handle--dq7Gq14-BpH0pmv5.mjs";import{$i as re,Bt as ie,Cr as ae,F as oe,Gi as se,Gr as ce,Hr as le,Ht as ue,Ji as de,Ki as fe,Ln as pe,Nr as me,P as he,Pn as ge,Q as _e,Qn as ve,T as ye,Tn as be,Ui as xe,Vn as Se,Vt as Ce,Wi as we,Xt as Te,Z as Ee,Zi as De,_ as Oe,_t as ke,an as Ae,at as je,c as Me,dn as Ne,ea as Pe,ia as Fe,ii as Ie,it as Le,jt as Re,mt as ze,na as Be,qi as Ve,qt as He,rt as Ue,ta as We,tt as Ge,un as Ke,v as qe,vr as Je,w as Ye,xt as Xe,yn as Ze,yr as Qe,zr as $e}from"./dist-
|
|
2
|
+
import{s as e}from"./chunk-C94x7I9S.mjs";import{t}from"./esm-BLMtE3s6.mjs";import{Da as n,Gr as r,Ji as i,Li as a,Mi as o,Ni as s,Oa as c,Sr as l,Wi as u,Xi as d,Yi as f,bn as p,ea as m,f as h,n as g,na as _,pa as v,ra as y,s as b,sa as x,ta as S,ua as C}from"./server-lock-BpjJj3OD-DlYx_Xz-.mjs";import{a as ee,n as w,r as te,t as ne}from"./gh-detect-wbzQ2Z5B.mjs";import{r as T}from"./git-handle--dq7Gq14-BpH0pmv5.mjs";import{$i as re,Bt as ie,Cr as ae,F as oe,Gi as se,Gr as ce,Hr as le,Ht as ue,Ji as de,Ki as fe,Ln as pe,Nr as me,P as he,Pn as ge,Q as _e,Qn as ve,T as ye,Tn as be,Ui as xe,Vn as Se,Vt as Ce,Wi as we,Xt as Te,Z as Ee,Zi as De,_ as Oe,_t as ke,an as Ae,at as je,c as Me,dn as Ne,ea as Pe,ia as Fe,ii as Ie,it as Le,jt as Re,mt as ze,na as Be,qi as Ve,qt as He,rt as Ue,ta as We,tt as Ge,un as Ke,v as qe,vr as Je,w as Ye,xt as Xe,yn as Ze,yr as Qe,zr as $e}from"./dist-Dcg4smYg.mjs";import{t as et}from"./yazl-Docqgl6q.mjs";import{n as tt,r as nt,t as rt}from"./dist-bundle-D75dREX-.mjs";import{B as it,C as at,E as ot,F as st,H as ct,I as lt,L as ut,M as dt,N as ft,P as pt,R as mt,S as ht,T as gt,V as _t,b as vt,u as yt,v as bt,w as xt,z as St}from"./init-Dx1FSwm_.mjs";import{a as Ct,c as wt,h as Tt,i as Et,l as Dt,m as Ot,o as kt,s as At,u as jt}from"./src-DmdJFypb.mjs";import{n as Mt,t as Nt}from"./constants-zR9K6MQx.mjs";import{n as Pt,t as Ft}from"./loader-Bi8VVUuv.mjs";import{S as It,_ as Lt,b as Rt,m as zt,x as Bt,y as Vt}from"./start-mHeHaykC.mjs";import{c as Ht,i as E,n as D,o as O,r as k,s as A,t as j}from"./colors-8SzMRIVy.mjs";import{n as Ut}from"./repair-skills-DsHqeRKO.mjs";import{execFile as Wt,execSync as Gt,spawn as M,spawnSync as N}from"node:child_process";import{accessSync as Kt,closeSync as qt,constants as Jt,cpSync as Yt,createWriteStream as Xt,existsSync as P,mkdirSync as F,mkdtempSync as Zt,openSync as Qt,readFileSync as I,readdirSync as $t,realpathSync as en,rmSync as tn,statSync as nn,unlinkSync as rn,writeFileSync as L}from"node:fs";import an,{basename as R,dirname as on,join as z,relative as sn,resolve as B,sep as cn}from"node:path";import ln from"node:process";import{arch as un,freemem as dn,homedir as fn,platform as pn,release as mn,tmpdir as hn,totalmem as gn,type as _n,uptime as vn}from"node:os";import{fileURLToPath as yn}from"node:url";import{rm as bn}from"node:fs/promises";import{createHash as xn,randomUUID as Sn}from"node:crypto";import{setTimeout as Cn}from"node:timers/promises";import{promisify as wn,stripVTControlCharacters as Tn,styleText as V}from"node:util";import{AsyncLocalStorage as En,AsyncResource as Dn}from"node:async_hooks";import*as On from"node:readline";import{createInterface as kn}from"node:readline/promises";const An={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 jn;(function(e){})(jn||={});function Mn(e){return v(u,e)}async function Nn(e,t,n,r){let i=Pn(await Fn(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 Pn(e){let t={};for(let n of e.split(`
|
|
3
3
|
`)){let e=n.trim();if(e===``)continue;let r=e.indexOf(`=`);r!==-1&&(t[e.slice(0,r)]=e.slice(r+1))}return t}function Fn(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 In(e,n){let r=new t(`git-credential`);return r.description(`Git credential helper (git credential-helper protocol)`),r.command(`get`).description(`Lookup credentials from TokenStore (called by git)`).action(async()=>{let t=n?.();try{let n,r=await e({onKeychainRead:e=>{n=e},onBackendSelected:e=>{e.backend===`file`&&e.reason&&t?.warn({backend:`file`,reason:e.reason},`[auth] token storage fallback`)}}),i=await Nn(process.stdin,process.stdout,r,{log:t,getDiag:()=>n});await Ze(t),process.exit(i)}catch(e){t?.error({error:e instanceof Error?e.message:String(e)},`[auth] git-credential get: unexpected error`),await Ze(t),process.exit(1)}}),r}function Ln(e){let t=e.endpoint.DEFAULTS;return/^https:\/\/(api\.)?github\.com$/.test(t.baseUrl)?`https://github.com`:t.baseUrl.replace(`/api/v3`,``)}async function Rn(e,t,n){let r={baseUrl:Ln(e),headers:{accept:`application/json`},...n},i=await e(t,r);if(`error`in i.data){let n=new tt(`${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 zn(e){let t=e.request||rt,n={client_id:e.clientId};return`scopes`in e&&Array.isArray(e.scopes)&&(n.scope=e.scopes.join(` `)),Rn(t,`POST /login/device/code`,n)}async function Bn(e){let t=await Rn(e.request||rt,`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=Vn(e,t.data.expires_in),n.refreshTokenExpiresAt=Vn(e,t.data.refresh_token_expires_in)}delete n.scopes}return{...t,authentication:n}}function Vn(e,t){return new Date(e+t*1e3).toISOString()}async function Hn(e,t){let n=Un(e,t.auth);if(n)return n;let{data:r}=await zn({clientType:e.clientType,clientId:e.clientId,request:t.request||e.request,scopes:t.auth.scopes||e.scopes});await e.onVerification(r);let i=await Gn(t.request||e.request,e.clientId,e.clientType,r);return e.authentication=i,i}function Un(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 Wn(e){await new Promise(t=>setTimeout(t,e*1e3))}async function Gn(e,t,n,r){try{let i={clientId:t,request:e,code:r.device_code},{authentication:a}=n===`oauth-app`?await Bn({...i,clientType:`oauth-app`}):await Bn({...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 Wn(r.interval),Gn(e,t,n,r);if(a===`slow_down`)return await Wn(r.interval+7),Gn(e,t,n,r);throw i}}async function Kn(e,t){return Hn(e,{auth:t})}async function qn(e,t,n,r){let i=t.endpoint.merge(n,r);if(/\/login\/(oauth\/access_token|device\/code)$/.test(i.url))return t(i);let{token:a}=await Hn(e,{request:t,auth:{type:`oauth`}});return i.headers.authorization=`token ${a}`,t(i)}var Jn=`0.0.0-development`;function Yn(e){let t=e.request||rt.defaults({headers:{"user-agent":`octokit-auth-oauth-device.js/${Jn} ${nt()}`}}),{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(Kn.bind(null,i),{hook:qn.bind(null,i)})}async function Xn(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=Yn({clientType:`oauth-app`,clientId:t,scopes:n,onVerification:async e=>{await r({verificationUri:e.verification_uri,userCode:e.user_code,expiresIn:e.expires_in,interval:e.interval})},request:a===`https://api.github.com`?void 0:(await import(`./dist-bundle-BnlRWriT.mjs`)).request.defaults({baseUrl:a})}),s;try{s=await o({type:`oauth`})}catch(e){if(e instanceof Error){let t=e.message.toLowerCase();throw t.includes(`access_denied`)?Error(`Device-flow authorization was denied.`):t.includes(`expired_token`)||t.includes(`timeout`)||t.includes(`timed out`)?Error(`Device-flow code expired before authorization — please try again.`):Error(`GitHub sign-in failed: ${e.message}`)}throw e}return{token:s.token,tokenType:s.tokenType,scopes:s.scopes??[]}}function Zn(){return process.env.OPEN_KNOWLEDGE_GITHUB_CLIENT_ID??`Ov23liqlSd0V1MwR6rhI`}const Qn=new Set([`gitlab.com`,`bitbucket.org`,`codeberg.org`,`gitea.com`,`sr.ht`,`sourcehut.org`]);function H(e){let t=e.toLowerCase().replace(/:\d+$/,``);Qn.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 $n(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function er(e,t,n=Xn){let r=Zn(),{host:i,json:a}=e;H(i),a||process.stderr.write(`Logging in to ${i}\n`);let o=await n({clientId:r,host:i===`github.com`?void 0:i,onVerification:e=>{e.userCode,e.verificationUri,a?$n(!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?$n(!0,{type:`complete`,host:i,login:s}):process.stderr.write(`✓ Logged in as ${s} on ${i}\n`)}function tr(e){return new t(`login`).description(`Authenticate with GitHub via Device Flow`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{await er(t,await e())})}const nr=e=>e.name===`enter`||e.name===`return`;var rr=class extends Error{name=`AbortPromptError`;message=`Prompt was aborted`;constructor(e){super(),this.cause=e?.cause}},ir=class extends Error{name=`CancelPromptError`;message=`Prompt was canceled`},ar=class extends Error{name=`ExitPromptError`},or=class extends Error{name=`HookError`},sr=class extends Error{name=`ValidationError`};const cr=new En;function lr(e){return{rl:e,hooks:[],hooksCleanup:[],hooksEffect:[],index:0,handleChange(){}}}function ur(e,t){let n=lr(e);return cr.run(n,()=>{function e(e){n.handleChange=()=>{n.index=0,e()},n.handleChange()}return t(e)})}function U(){let e=cr.getStore();if(!e)throw new or(`[Inquirer] Hook functions can only be called from within a prompt`);return e}function dr(){return U().rl}function fr(e){return Dn.bind((...t)=>{let n=U(),r=!1,i=n.handleChange;n.handleChange=()=>{r=!0};let a=e(...t);return r&&i(),n.handleChange=i,a})}function pr(e){let t=U(),{index:n}=t,r=e({get(){return t.hooks[n]},set(e){t.hooks[n]=e},initialized:n in t.hooks});return t.index++,r}function mr(){U().handleChange()}const hr={queue(e){let t=U(),{index:n}=t;t.hooksEffect.push(()=>{t.hooksCleanup[n]?.();let r=e(dr());if(r!=null&&typeof r!=`function`)throw new sr(`useEffect return value must be a cleanup function or nothing.`);t.hooksCleanup[n]=r})},run(){let e=U();fr(()=>{e.hooksEffect.forEach(e=>{e()}),e.hooksEffect.length=0})()},clearAll(){let e=U();e.hooksCleanup.forEach(e=>{e?.()}),e.hooksEffect.length=0,e.hooksCleanup.length=0}};function gr(e){return typeof e==`function`}function W(e){return pr(t=>{let n=Dn.bind(function(e){t.get()!==e&&(t.set(e),mr())});if(t.initialized)return[t.get(),n];let r=gr(e)?e():e;return t.set(r),[r,n]})}function _r(e,t){pr(n=>{let r=n.get();(!Array.isArray(r)||t.some((e,t)=>!Object.is(e,r[t])))&&hr.queue(e),n.set(t)})}const vr={prefix:{idle:V(`blue`,`?`),done:V(`green`,ct.tick)},spinner:{interval:80,frames:[`⠋`,`⠙`,`⠹`,`⠸`,`⠼`,`⠴`,`⠦`,`⠧`,`⠇`,`⠏`].map(e=>V(`yellow`,e))},style:{answer:e=>V(`cyan`,e),message:e=>V(`bold`,e),error:e=>V(`red`,`> ${e}`),defaultAnswer:e=>V(`dim`,`(${e})`),help:e=>V(`dim`,e),highlight:e=>V(`cyan`,e),key:e=>V(`cyan`,V(`bold`,`<${e}>`))}};function yr(e){if(typeof e!=`object`||!e)return!1;let t=e;for(;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function br(...e){let t={};for(let n of e)for(let[e,r]of Object.entries(n)){let n=t[e];t[e]=yr(n)&&yr(r)?br(n,r):r}return t}function xr(...e){return br(vr,...e.filter(e=>e!=null))}function Sr({status:e=`idle`,theme:t}){let[n,r]=W(!1),[i,a]=W(0),{prefix:o,spinner:s}=xr(t);return _r(()=>{if(e===`loading`){let e,t=-1,n=setTimeout(()=>{r(!0),e=setInterval(()=>{t+=1,a(t%s.frames.length)},s.interval)},300);return()=>{clearTimeout(n),clearInterval(e)}}else r(!1)},[e]),n?s.frames[i]:typeof o==`string`?o:o[e===`loading`?`idle`:e]??o.idle}function Cr(e){return W({current:e})[0]}function wr(e){let t=Cr(e);t.current=e,_r(e=>{let n=!1,r=fr((r,i)=>{n||t.current(i,e)});return e.input.on(`keypress`,r),()=>{n=!0,e.input.removeListener(`keypress`,r)}},[])}var Tr=e(_t(),1);function Er(e,t){return e.split(`
|
|
4
4
|
`).flatMap(e=>it(e,t,{trim:!1,hard:!0}).split(`
|
|
5
5
|
`).map(e=>e.trimEnd())).join(`
|
|
@@ -19,7 +19,7 @@ import{s as e}from"./chunk-C94x7I9S.mjs";import{t}from"./esm-BLMtE3s6.mjs";impor
|
|
|
19
19
|
`),patterns:[...t],lineCount:n}}const Ki=z(fn(),`.ok`,`logs`),qi=z(fn(),`.ok`,`bug-reports`);function Ji(e){let t=z(e,`.ok`,`config.yml`);if(P(t))try{let e=I(t,`utf8`).match(/^\s*name:\s*['"]?(.+?)['"]?\s*$/m);if(e?.[1])return e[1]}catch{}return P(z(e,`.ok`))?xn(`sha256`).update(B(e)).digest(`hex`).slice(0,12):null}function Yi(){let e={timestamp:new Date().toISOString(),platform:pn(),osType:_n(),osRelease:mn(),hostname:`[redacted]`,uptime:vn(),freeMem:dn(),totalMem:gn(),nodeVersion:process.version,bunVersion:process.versions.bun??null,v8Version:process.versions.v8??null,pid:process.pid};try{e.macosVersion=Gt(`sw_vers -productVersion 2>/dev/null`,{encoding:`utf8`}).trim()}catch{}try{let t=z(__dirname,`..`,`..`,`package.json`);P(t)&&(e.okVersion=JSON.parse(I(t,`utf8`)).version)}catch{}return e}function Xi(e){if(!P(Ki))return{files:[],dir:Ki};let t=$t(Ki).filter(e=>e.endsWith(`.log`)||/\.log\.\d+$/.test(e)).map(e=>z(Ki,e));if(e&&t.length>0){let n=t.filter(t=>{try{return I(t,`utf8`).includes(`"project":"${e}"`)}catch{return!0}});n.length>0&&(t=n)}return{files:t,dir:Ki}}function Zi(e){let t=z(e,`.ok`,`local`);return P(t)?{files:[`server.lock`,`last-spawn-error.log`].map(e=>z(t,e)).filter(e=>P(e)),dir:t}:{files:[],dir:null}}function Qi(e){let t=z(e,`.ok`,`local`,`logs`);return P(t)?{files:[`server-current.jsonl`,`server-prev.jsonl`].map(e=>z(t,e)).filter(e=>P(e)),dir:t}:{files:[],dir:null}}async function $i(t){let n=Au();F(qi,{recursive:!0});let r=z(qi,`${new Date().toISOString().replace(/[:.]/g,`-`)}-bugreport.zip`);n?.info({projectSlug:t.projectSlug},`gathering diagnostic data`);let i=Yi(),{files:a}=Xi(t.projectSlug),{files:o}=Zi(t.cwd),{files:s}=Qi(t.cwd);n?.info({logFileCount:a.length,lockFileCount:o.length,localSinkFileCount:s.length},`files collected`);let c=[],l=[],{ZipFile:u}=await import(`./yazl-CQSNnbvt.mjs`).then(t=>e(t.default,1)),d=new u;for(let e of a)try{let{redacted:t,patterns:n,lineCount:r}=Gi(I(e,`utf8`)),i=`logs/${R(e)}`;d.addBuffer(Buffer.from(t,`utf8`),i),l.push(i),n.length>0&&c.push({file:i,lineCount:r,patterns:n})}catch{}for(let e of o)try{let{redacted:t,patterns:n,lineCount:r}=Gi(I(e,`utf8`)),i=`lockdir/${R(e)}`;d.addBuffer(Buffer.from(t,`utf8`),i),l.push(i),n.length>0&&c.push({file:i,lineCount:r,patterns:n})}catch{}for(let e of s)try{let{redacted:t,patterns:n,lineCount:r}=Gi(I(e,`utf8`)),i=`local-logs/${R(e)}`;d.addBuffer(Buffer.from(t,`utf8`),i),l.push(i),n.length>0&&c.push({file:i,lineCount:r,patterns:n})}catch{}let f=JSON.stringify(i,null,2);d.addBuffer(Buffer.from(f,`utf8`),`sysinfo.json`),l.push(`sysinfo.json`);let p={generatedAt:new Date().toISOString(),disciplineVersion:`1.0.0`,projectSlug:t.projectSlug,files:l,redactions:c,sysinfo:i};d.addBuffer(Buffer.from(JSON.stringify(p,null,2),`utf8`),`MANIFEST.json`);let m=c.reduce((e,t)=>e+t.lineCount,0),h=[`# Bug Report Bundle`,``,`Generated: ${p.generatedAt}`,`Project: ${t.projectSlug??`(unscoped)`}`,`Discipline version: ${p.disciplineVersion}`,``,`## Contents`,``,...l.map(e=>`- ${e}`),``,`## Privacy`,``,`This bundle was auto-redacted before packaging.`,`Patterns checked: ${Wi.join(`, `)}`,m>0?`${m} line(s) were scrubbed across ${c.length} file(s).`:`No redactions were needed.`,`See MANIFEST.json for the full redaction audit report.`,``,`This bundle is safe to attach to a GitHub issue.`].join(`
|
|
20
20
|
`);d.addBuffer(Buffer.from(h,`utf8`),`README.md`),d.end();let g=Xt(r);if(d.outputStream.pipe(g),await new Promise((e,t)=>{g.on(`close`,e),g.on(`error`,t)}),n?.info({bundlePath:r,fileCount:l.length,redactionCount:m},`bundle written`),process.stdout.write(`${r}\n`),m>0&&process.stderr.write(`ok bug-report: ${m} line(s) auto-redacted across ${c.length} file(s)\n`),!t.noReveal&&pn()===`darwin`)try{M(`/usr/bin/open`,[`-R`,r],{detached:!0,stdio:`ignore`}).unref()}catch{}return r}function ea(){return new t(`bug-report`).description(`Generate a diagnostic bundle for bug reporting`).option(`--reveal`,`Reveal the bundle in Finder (default: true)`,!0).option(`--no-reveal`,`Do not reveal the bundle in Finder`).action(async e=>{let t=process.cwd(),n=Ji(t);try{await $i({projectSlug:n,cwd:t,noReveal:!e.reveal})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`ok bug-report: failed — ${t}\n`),process.exitCode=1}})}function 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 na(e){let t=e.inspect??(t=>Tt(e.lockDir,t)),n=e.unlink??(e=>rn(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 ra(e){return new t(`clean`).description(`Prune stale / corrupt open-knowledge lock files (never touches live locks)`).action(()=>{e(),na({lockDir:le(process.cwd())}).failed.length>0&&(process.exitCode=1)})}async function ia(e,t,n={},r=ne){if(!n.skipGhDetect&&r().available)return{tier:`A`,credentialArgs:[`-c`,`credential.helper=!gh auth git-credential`]};let i=await t.get(e);return i==null?{tier:`none`,credentialArgs:[]}:{tier:i.gitProtocol===`ssh`?`C`:`B`,credentialArgs:[`-c`,`credential.helper=!open-knowledge auth git-credential`]}}async function 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 oa=[[`count`,0,10],[`compress`,10,20],[`receiv`,20,60],[`resolv`,60,100]];function sa(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 oa)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 ca(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 la(e){return typeof e!=`string`||e.length===0?[`--progress`]:[`--progress`,`-b`,e]}const ua=r;async function da(e){try{return await e.clone(la(e.branch)),{fellBack:!1}}catch(t){if(e.branch!==null&&ua(t))return e.onFallback(e.branch),await e.clone(la(null)),{fellBack:!0};throw t}}function fa(e,t,n){return e===`https`&&t===`github.com`&&n}async function pa(e,t,n,r=process.cwd()){let i=Ot(e);if(!i)throw Error(`Invalid git URL: ${e}`);let a=t.dir?B(r,t.dir):B(r,i.name);if(P(a)&&$t(a).length>0)throw Error(`Target directory is not empty: ${a}`);let o=ee(),s=i.protocol===`https`&&i.hostname===`github.com`?await aa(i.owner,i.name):!1,c=fa(i.protocol,i.hostname,s)?{tier:`none`,credentialArgs:[]}:await ia(i.hostname,o,{}),l=ca(),u=T({baseDir:r,config:c.credentialArgs.length>=2?[c.credentialArgs[1]]:[],unsafe:{allowUnsafeCredentialHelper:!0}}).env(l),d=-1;u.outputHandler((e,n,r)=>{r.on(`data`,e=>{let n=e.toString(`utf-8`);for(let e of n.split(`
|
|
21
21
|
`)){let n=sa(e);n&&n.pct!==d&&(d=n.pct,q(t.json,{type:`progress`,pct:n.pct,stage:n.stage}),t.json||process.stderr.write(`\r Cloning ${n.pct}%`))}})}),await da({branch:typeof t.branch==`string`&&t.branch.length>0?t.branch:null,clone:t=>u.clone(e,a,t),onFallback:e=>{q(t.json,{type:`branch-fallback`,branch:e}),t.json||process.stderr.write(`\n Branch '${e}' not found upstream — cloning default branch instead.\n`)}}),t.json||process.stderr.write(`
|
|
22
|
-
`);try{let{runInit:e}=await import(`./init-
|
|
22
|
+
`);try{let{runInit:e}=await import(`./init-5s5Urhtt.mjs`),n=await e({cwd:a,mcp:!1});if(n.contentUpdated.length>0){let e=`auto-init: updated ${n.contentUpdated.join(`, `)}`;t.json?q(!0,{type:`warning`,message:e}):process.stderr.write(` ${e}\n`)}}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`auto-init: ${n}`}):process.stderr.write(` auto-init: ${n}\n`)}try{ma(a)}catch(e){let n=e instanceof Error?e.message:String(e);t.json?q(!0,{type:`warning`,message:`git-exclude: ${n}`}):process.stderr.write(` git-exclude: ${n}\n`)}return a}function ma(e){let t=vt(e,[`.ok/`]);return t.kind===`no-exclude`?`no-exclude`:t.kind===`refused-tracked`?`already-present`:t.appended.length>0?`appended`:`already-present`}function ha(e){return new t(`clone`).description(`Clone a git repository and open it`).argument(`<url>`,`Repository URL or owner/repo shorthand`).argument(`[dir]`,`Target directory (default: ./<repo-name>)`).option(`--json`,`Output JSONL progress events`,!1).option(`-b, --branch <branch>`,`Branch to check out (falls back to default if missing)`).action(async(t,n,r)=>{let i=e();try{let a=await pa(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-LI_wE7gV.mjs`);await t(e).parseAsync([],{from:`user`})}}catch(e){let t=e instanceof Error?e.message:String(e);r.json?q(!0,{type:`error`,message:t}):process.stderr.write(`✗ ${t}\n`),process.exitCode=1}})}var ga=c();const _a=[[`sync`],[`persistence`,`debounceMs`],[`persistence`,`maxDebounceMs`],[`server`,`port`],...s.map(e=>e.path)];function va(e={}){let t=e.log??(e=>console.error(e)),n=e.error??(e=>console.error(e)),r=e.loadConfigFn??Pt;try{let{sources:n}=r(e.cwd);return t(`✓ Configuration valid (sources: ${n.length===0?`defaults only`:n.join(`, `)})`),{ok:!0}}catch(e){return n(e instanceof Error?e.message:String(e)),{ok:!1}}}function ya(e){let t=(0,ga.parseDocument)(I(e,`utf-8`));if(t.errors.length>0)throw Error(`Could not parse ${e}: ${t.errors.map(e=>e.message).join(`; `)}`);let n=[];for(let e of _a)t.hasIn(e)&&n.push(e.join(`.`));return n}function ba(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function xa(e){let t={};for(let n of e){let e=t;for(let t=0;t<n.length-1;t++){let r=n[t],i=e[r],a=ba(i)?i:{};e[r]=a,e=a}e[n[n.length-1]]=null}return t}async function Sa(e={}){let t=e.log??(e=>console.log(e)),n=e.error??(e=>console.error(e)),r=e.scope??`both`,i=e.dryRun??!1,o=e.cwd??process.cwd(),s=e.writeConfigPatchFn??re,c=[];(r===`project`||r===`both`)&&c.push({scope:`project`,absPath:De(`project`,o,e.homedirOverride)}),(r===`user`||r===`both`)&&c.push({scope:`user`,absPath:De(`user`,o,e.homedirOverride)});let l=[],u=!0;for(let{scope:t,absPath:n}of c){if(!P(n)){l.push({path:n,scope:t,found:[],removed:[]});continue}let r;try{r=ya(n)}catch(e){let r=e instanceof Error?e.message:String(e);l.push({path:n,scope:t,found:[],removed:[],error:r}),u=!1;continue}if(r.length===0||i){l.push({path:n,scope:t,found:r,removed:[]});continue}let c=await s({cwd:o,scope:t,patch:xa(_a.filter(e=>r.includes(e.join(`.`)))),homedirOverride:e.homedirOverride});if(!c.ok){l.push({path:n,scope:t,found:r,removed:[],error:a(c.error)}),u=!1;continue}l.push({path:n,scope:t,found:r,removed:r})}for(let e of l)e.error&&n(`✗ ${e.path}: ${e.error}`);let d=l.some(e=>e.error!==void 0),f=l.reduce((e,t)=>e+t.found.length,0);if(f===0&&!d)t(`No deprecated fields found.`);else if(f>0)for(let e of l)e.error||(e.found.length===0?t(` ${e.path}: no deprecated fields`):t(i?`[dry-run] ${e.path}: would remove ${e.found.length} field(s): ${e.found.join(`, `)}`:`✓ ${e.path}: removed ${e.removed.length} field(s): ${e.removed.join(`, `)}`));return{outcomes:l,ok:u}}function Ca(){let e=new t(`config`).description(`Inspect and maintain Open Knowledge configuration files`);return e.command(`validate`).description(`Validate the merged config (defaults → user → project)`).action(()=>{va({}).ok||(process.exitCode=1)}),e.command(`migrate`).description(`Remove deprecated config fields from config.yml idempotently (every removed key in the registry — content.*, folders, appearance.editorModeDefault, server.host, etc. — plus the silently-dropped sync.*, persistence.*, server.port)`).option(`--scope <scope>`,`Which scope to migrate: project | user | both`,`both`).option(`--dry-run`,`Preview without writing`,!1).action(async e=>{let t=e.scope;if(t!==`project`&&t!==`user`&&t!==`both`){console.error(`Invalid --scope: ${t}. Expected: project | user | both`),process.exitCode=2;return}(await Sa({scope:t,dryRun:e.dryRun})).ok||(process.exitCode=1)}),e}var wa=e(et(),1),J=e(Ht(),1);const Ta=new Set([`doc.name`]);function Ea(e){return`doc:${xn(`blake2b512`,{outputLength:32}).update(e).digest(`hex`).slice(0,8)}`}function Da(e,t,n){let r=e.docNameMap[n];if(r===void 0){e.docNameMap[n]=t;return}if(r===t)return;let i=e.docNameCollisions[n];i?i.includes(t)||i.push(t):e.docNameCollisions[n]=[t]}function Oa(e,t){let n=t.originalToHashed.get(e);if(n!==void 0)return n;let r=Ea(e);return t.originalToHashed.set(e,r),Da(t,e,r),r}function ka(e,t){return t.length===0||!e.includes(t)?e:e.split(t).join(`<CONTENT_DIR>`)}function Aa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ja(e,t){if(typeof e==`string`)return ka(e,t.contentDir);if(Array.isArray(e))return e.map(e=>ja(e,t));if(!Aa(e))return e;let n=typeof e.key==`string`&&Ta.has(e.key)&&Aa(e.value)&&typeof e.value.stringValue==`string`?e.value.stringValue:null,r={};for(let[i,a]of Object.entries(e))if(n!==null&&i===`value`&&Aa(a)){let e=Oa(n,t);r[i]={...a,stringValue:e}}else Ta.has(i)&&typeof a==`string`?r[i]=Oa(a,t):r[i]=ja(a,t);return r}function Ma(e,t){if(t.originalToHashed.size===0)return e;let n=Array.from(t.originalToHashed.entries()).sort(([e],[t])=>t.length-e.length),r=e;for(let[e,t]of n)e.length!==0&&r.includes(e)&&(r=r.split(e).join(t));return r}function Na(e,t){let n=I(e,`utf-8`);if(n.length===0)return;let r=n.endsWith(`
|
|
23
23
|
`),i=n.split(`
|
|
24
24
|
`),a=[];for(let e=0;e<i.length;e++){let n=i[e]??``;if(!(e===i.length-1&&n===``)){if(n.length===0){a.push(``);continue}try{let e=ja(JSON.parse(n),t);a.push(JSON.stringify(e))}catch{a.push(n)}}}L(e,r?`${a.join(`
|
|
25
25
|
`)}\n`:a.join(`
|
|
@@ -50,7 +50,7 @@ ws.addEventListener('error', () => process.exit(1));
|
|
|
50
50
|
setTimeout(() => process.exit(2), ${t+1e4});
|
|
51
51
|
`),r}async function Go(e,t,n,r,i){let a=Wo(e,t,z(r,`cpu.cpuprofile`)),o=!1,s=M(process.execPath,[a],{stdio:`ignore`}),c=setInterval(()=>{let e=Bo(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{tn(z(a,`..`),{recursive:!0,force:!0})}catch{}return o}function Ko(e){let t;try{t=JSON.parse(e)}catch{return`(could not parse profile)`}let n=new Map(t.nodes.map(e=>[e.id,e])),r=new Map;for(let e of t.nodes)for(let t of e.children??[])r.set(t,e.id);let i=new Map;for(let e of t.samples??[])i.set(e,(i.get(e)??0)+1);let a=t.samples?.length??0,o=t.endTime!=null&&t.startTime!=null?((t.endTime-t.startTime)/1e3).toFixed(2):`?`,s=[...i.entries()].sort((e,t)=>t[1]-e[1]).slice(0,10),c=[`samples ${a} duration_ms ${o}`,``,`Top leaf nodes`];for(let[e,t]of s){let r=n.get(e);if(!r)continue;let i=a>0?(t/a*100).toFixed(1):`0.0`,{functionName:o,url:s,lineNumber:l,columnNumber:u}=r.callFrame;c.push(` ${t} ${i}% id=${e} ${o||`(anonymous)`} ${s}:${l}:${u} hit=${r.hitCount??0}`)}c.push(``,`Top stacks`);let l=e=>{let t=[],i=e;for(;i!=null;){let e=n.get(i);if(!e)break;let{functionName:a,url:o,lineNumber:s,columnNumber:c}=e.callFrame;t.unshift(` ${a||`(anonymous)`} ${o} ${s} ${c}`),i=r.get(i)}return t};for(let[e,t]of s.slice(0,5)){let n=a>0?(t/a*100).toFixed(1):`0.0`;c.push(``,`--- ${t} ${n}%`,...l(e))}return c.join(`
|
|
52
52
|
`)}async function qo(e,t={}){let{pid:n,cpuProfileSecs:r=15,noInspector:i=!1}=e,a=t.log??(e=>console.log(e)),o=t.discover??wt,s=t.inspect??Tt,c=t.resolveCommand??Dt,l=t.resolveUsage??jt,u=t.collectLsofFn??Vo,d=t.getEndpoints??Uo,f=t.profiler??Go,p=t.isAlive??(e=>{try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}),m=t.sendSignal??((e,t)=>{process.kill(e,t)}),h=t.sleep??(e=>new Promise(t=>setTimeout(t,e))),g=r*1e3;if(!p(n)){a(J.default.red(`No process with pid ${n} found.`));return}let _=await o(),v=null,y=null;for(let e of _){let t=s(e,`server`);if(t.status!==`missing`&&t.status!==`corrupt`&&t.lock.pid===n){v=t.lock.worktreeRoot,y={lockDir:e,state:t.status,lockPath:t.lockPath,lock:t.lock};break}}let b=new Date().toISOString().replace(/[:.]/g,`-`),x=e.output?e.output:v?z(v,`.ok`,`local`,`diagnostics`,`process-${n}-${b}`):z(process.cwd(),`ok-diagnose-${n}-${b}`);try{F(x,{recursive:!0})}catch(e){a(J.default.red(`Cannot create output directory ${x}: ${e.message}`));return}a(J.default.bold(`Diagnosing pid ${n}`)),a(`Output: ${x}`),a(``);let S=(e,t)=>{L(z(x,e),t),a(` wrote ${e}`)},C=c(n),ee=l(n);S(`metadata.json`,JSON.stringify({capturedAt:new Date().toISOString(),pid:n,command:C,usage:ee,lockInfo:y},null,2)),a(` sampling lsof`);let w=u(n);if(w&&S(`lsof.txt`,w),!i){let e=w?Ho(w).find(e=>e>=9229&&e<=9299)??9229:9229,t=d(e);if(!t||t.length===0){a(` no inspector on :${e}, sending SIGUSR1 to pid ${n}`);try{m(n,`SIGUSR1`),await h(2e3),t=d(e)}catch(e){a(J.default.yellow(` SIGUSR1 delivery failed: ${e.message}`))}}if(t&&t.length>0){S(`inspector-endpoints.json`,JSON.stringify(t,null,2));let e=t[0].webSocketDebuggerUrl;if(e){a(` capturing ${r}s CPU profile`);let t=[];await f(e,g,n,x,e=>t.push(e))?a(` wrote cpu.cpuprofile`):a(J.default.yellow(` CPU profile capture failed`)),t.length>0&&S(`process-stats.jsonl`,`${t.map(e=>JSON.stringify(e)).join(`
|
|
53
|
-
`)}\n`);try{S(`stacks.txt`,Ko(I(z(x,`cpu.cpuprofile`),`utf-8`)))}catch(e){a(J.default.yellow(` stacks.txt skipped: ${e.message}`))}}}else a(J.default.yellow(` Node inspector unavailable — skipping CPU profile`))}a(``),a(J.default.yellow(`⚠ Before sharing, review what each file contains:`)),a(` metadata.json — content directory paths, lock file locations, CPU/MEM at capture time`),a(` lsof.txt — all open files, network connections, and private paths for this process`),a(` inspector-endpoints.json — Node debugger metadata (titles, URLs)`),a(` cpu.cpuprofile — function names and source file paths from your Node process`),a(` stacks.txt — call stacks derived from cpu.cpuprofile; includes source paths`),a(` process-stats.jsonl — CPU/MEM/RSS numbers only; safe to share`),a(``),a(`Bundle: ${J.default.bold(x)}`)}async function Jo(e){let t=kn({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function Yo(e){let t=Zt(z(hn(),`ok-bundle-process-`));return await qo({pid:e,output:t}),t}function Xo(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 Zo(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function Qo(e,t,n){let{summary:r,manifest:i}=t;e(``),e(J.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${Xo(r.totalBytes)} uncompressed`),e(` doc.name attributes: ${r.docNameCount} occurrence(s) in telemetry${r.redacted?` (values hashed)`:``}`),e(` Content-dir path: ${r.contentDirVisible?`visible (${i.contentDir.absolutePath})`:`not visible`}`),e(` Redacted: ${r.redacted?`yes`:`no`}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function $o(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??Jo,i=t.runProcessDiagnose??Yo,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=on(o);if(!P(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=z(e.contentDir,`.ok`,`local`,`diagnostics`);F(n,{recursive:!0}),o=z(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(J.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await ho({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(J.default.yellow(` server not running — live state unavailable`)),Qo(n,c,o),e.yes!==!0&&!Zo(await r(`Write bundle? [y/N]: `))?(n(J.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await go({collected:c,outputPath:o}),n(J.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{tn(s,{recursive:!0,force:!0})}catch{}}}function es(){let e=new t(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(J.default.red(`Invalid pid '${e}': must be a positive integer`)),process.exit(1));let r=Number.parseInt(t.cpuProfile,10);(Number.isNaN(r)||r<=0)&&(console.error(J.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await qo({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(zo()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--redact`,`Hash doc names and strip the content-dir prefix from the staged bundle`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(J.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-
|
|
53
|
+
`)}\n`);try{S(`stacks.txt`,Ko(I(z(x,`cpu.cpuprofile`),`utf-8`)))}catch(e){a(J.default.yellow(` stacks.txt skipped: ${e.message}`))}}}else a(J.default.yellow(` Node inspector unavailable — skipping CPU profile`))}a(``),a(J.default.yellow(`⚠ Before sharing, review what each file contains:`)),a(` metadata.json — content directory paths, lock file locations, CPU/MEM at capture time`),a(` lsof.txt — all open files, network connections, and private paths for this process`),a(` inspector-endpoints.json — Node debugger metadata (titles, URLs)`),a(` cpu.cpuprofile — function names and source file paths from your Node process`),a(` stacks.txt — call stacks derived from cpu.cpuprofile; includes source paths`),a(` process-stats.jsonl — CPU/MEM/RSS numbers only; safe to share`),a(``),a(`Bundle: ${J.default.bold(x)}`)}async function Jo(e){let t=kn({input:process.stdin,output:process.stdout});try{return(await t.question(e)).trim()}finally{t.close()}}async function Yo(e){let t=Zt(z(hn(),`ok-bundle-process-`));return await qo({pid:e,output:t}),t}function Xo(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 Zo(e){let t=e.trim().toLowerCase();return t===`y`||t===`yes`}function Qo(e,t,n){let{summary:r,manifest:i}=t;e(``),e(J.default.bold(`ok diagnose bundle — content summary`)),e(``),e(` Files: ${r.fileCount}`),e(` Total size: ${Xo(r.totalBytes)} uncompressed`),e(` doc.name attributes: ${r.docNameCount} occurrence(s) in telemetry${r.redacted?` (values hashed)`:``}`),e(` Content-dir path: ${r.contentDirVisible?`visible (${i.contentDir.absolutePath})`:`not visible`}`),e(` Redacted: ${r.redacted?`yes`:`no`}`),e(` Server status: ${i.serverStatus}`),e(` Output: ${n}`),e(``)}async function $o(e,t={}){let n=t.log??(e=>console.log(e)),r=t.prompt??Jo,i=t.runProcessDiagnose??Yo,a=t.now??(()=>new Date),o;if(e.out!==void 0){o=e.out;let t=on(o);if(!P(t))throw Error(`ok diagnose bundle: --out parent directory does not exist: ${t}. Create it first.`)}else{let t=a().toISOString().replace(/[:.]/g,`-`),n=z(e.contentDir,`.ok`,`local`,`diagnostics`);F(n,{recursive:!0}),o=z(n,`bundle-${t}.zip`)}let s;e.pid!==void 0&&(n(J.default.dim(`Running ok diagnose process ${e.pid} into a temp dir`)),s=await i(e.pid));let c=await ho({contentDir:e.contentDir,projectDir:e.projectDir,processDir:s,redact:e.redact===!0,deps:t.collectDeps});try{return c.manifest.serverStatus===`not-running`&&n(J.default.yellow(` server not running — live state unavailable`)),Qo(n,c,o),e.yes!==!0&&!Zo(await r(`Write bundle? [y/N]: `))?(n(J.default.dim(`Aborted; no bundle written.`)),{outputPath:null,declined:!0}):(await go({collected:c,outputPath:o}),n(J.default.bold(`Bundle: ${o}`)),{outputPath:o,declined:!1})}finally{if(c.cleanup(),s!==void 0)try{tn(s,{recursive:!0,force:!0})}catch{}}}function es(){let e=new t(`diagnose`).description(`Diagnostic utilities for open-knowledge processes`);return e.command(`process`).description(`Capture a diagnostic bundle (metadata, lsof, CPU profile) for a running process`).argument(`<pid>`,`Process ID to diagnose`).option(`--cpu-profile <seconds>`,`CPU profile duration (default: 15)`,`15`).option(`--output <dir>`,`Output directory`).option(`--no-inspector`,`Collect metadata only; skip Node inspector and CPU profile`).action(async(e,t)=>{let n=Number.parseInt(e,10);(Number.isNaN(n)||n<=0)&&(console.error(J.default.red(`Invalid pid '${e}': must be a positive integer`)),process.exit(1));let r=Number.parseInt(t.cpuProfile,10);(Number.isNaN(r)||r<=0)&&(console.error(J.default.red(`--cpu-profile must be a positive integer`)),process.exit(1)),await qo({pid:n,cpuProfileSecs:r,output:t.output,noInspector:!t.inspector})}),e.addCommand(zo()),e.command(`bundle`).description(`Capture a support bundle (telemetry + logs + server state) into a zip suitable for bug reports`).option(`--pid <pid>`,"Include `ok diagnose process <pid>` output under process/ in the bundle").option(`--out <path>`,`Write the zip to this path instead of the default location`).option(`--yes`,`Skip the y/N prompt`).option(`--redact`,`Hash doc names and strip the content-dir prefix from the staged bundle`).action(async e=>{let t;e.pid!==void 0&&(t=Number.parseInt(e.pid,10),(Number.isNaN(t)||t<=0)&&(console.error(J.default.red(`Invalid --pid '${e.pid}': must be a positive integer`)),process.exit(1)));try{let{loadConfig:n}=await import(`./loader-N9LzTn4Q.mjs`),{resolveContentDir:r}=await import(`./dist-6j4x3nmy.mjs`),i=process.cwd(),{config:a}=n(i);await $o({contentDir:r(a,i),projectDir:i,pid:t,out:e.out,yes:e.yes===!0,redact:e.redact===!0})}catch(e){let t=e instanceof Error?e.message:String(e);console.error(J.default.red(t)),process.exit(1)}}),e}async function ts(){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 Lr({message:`Enter OpenAI embeddings API key:`})).trim()}function ns(e){return ae(e)}async function rs(){return(await Ae()).file?{present:!0,source:`file`}:process.env.OK_EMBEDDINGS_API_KEY?{present:!0,source:`env`}:{present:!1,source:null}}async function is(e){try{let t=h(le(e));if(!t||t.port<=0||!b(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 as(){return new t(`set-key`).description(`Store your OpenAI embeddings API key in ~/.ok/secrets.yml`).action(async()=>{let e=await ts();if(!e){process.stderr.write(`No key provided.
|
|
54
54
|
`),process.exitCode=1;return}await He().set(e),process.stderr.write(`✓ OpenAI embeddings API key stored in ~/.ok/secrets.yml (0600, this machine only).
|
|
55
55
|
Now enable it per project — the easiest path is OK Desktop → Settings → This
|
|
56
56
|
project → Search (a toggle with an egress-confirmation prompt), or run
|
|
@@ -70,7 +70,7 @@ project → Search (a toggle with an egress-confirmation prompt), or run
|
|
|
70
70
|
`).filter(e=>e.startsWith(`worktree `)).length}catch{return 0}}function xl(e){let t=B(e);for(;;){if(ve(t))return t;let n=on(t);if(n===t)throw Error(`No Open Knowledge project found at or above ${e}. Pass an explicit \`cwd\` argument that points inside an OK project (a directory with a \`${o}\`).`);t=n}}function Sl(e){try{let t=new URL(e);return t.protocol===`file:`?yn(t):void 0}catch{return}}async function Cl(e){if(!e.getClientCapabilities()?.roots)return;let t;try{t=await e.listRoots()}catch(t){e.log?.(`listRoots fallback failed: ${t instanceof Error?t.message:String(t)}`);return}let n=t.roots??[];if(n.length!==1)return;let r=Sl(n[0].uri);return r===void 0&&e.log?.(`single root URI not usable as fs path: ${n[0].uri}`),r}async function wl(e,t,n,r=xl){if(e!==void 0){let t=r(e);return{projectDir:t,viaRootGuess:!1,nextSticky:t}}if(t!==void 0){let e=r(t);return{projectDir:e,viaRootGuess:!1,nextSticky:e}}let i=await n();return i===void 0?{projectDir:void 0,viaRootGuess:!1,nextSticky:void 0}:{projectDir:r(i),viaRootGuess:!0,nextSticky:void 0}}async function Tl(e){let t=process.stderr,n=e.spawnTimeoutMs??rl(process.env.OK_MCP_SPAWN_TIMEOUT_MS),r=e.envAutoStart??process.env.OK_MCP_AUTOSTART,i=Ft({startupCwd:e.startupCwd,startupConfig:e.startupConfig}),a=new xe({name:oe,version:g});Se(a);let o=Sn(),s={current:{connectionId:o,displayName:o,colorSeed:o}},c=new Map,l=e=>{if(c.has(e))return;let n=be(e),r=s.current,i=ws({connectionId:o,displayName:r.displayName,clientName:r.clientInfo?.name??r.displayName,colorSeed:r.colorSeed,resolveWsUrl:async()=>hl({lockDir:n,contentDir:e},``),log:n=>t.write(`[mcp] keepalive[${e}]: ${n}\n`)});c.set(e,i)},u=()=>Cl({getClientCapabilities:()=>a.server.getClientCapabilities(),listRoots:()=>a.server.listRoots(),log:e=>t.write(`[mcp] ${e}\n`)}),d,f=!1,p=async e=>{if(f)return;f=!0;let n=await bl(e);if(n<=1){f=!1;return}let r=`Routed to ${e} from the MCP client's single advertised root, but this repo has ${n} git worktrees. If you are working in a worktree, pass its path as \`cwd\` on OK tool calls once — it sticks for the session, so reads, writes, and the preview all target that worktree instead of this checkout.`;try{t.write(`[mcp] ${r}\n`),await a.server.sendLoggingMessage({level:`warning`,data:r})}catch{}},m=async e=>{let t=await wl(e,d,u);if(d=t.nextSticky??d,t.projectDir===void 0)throw Error("`cwd` is required for tool calls against the global MCP server. Pass an absolute path inside an Open Knowledge project, or have the MCP client advertise a single root.");return t.viaRootGuess&&p(t.projectDir),t.projectDir},h=async e=>{let t=await wl(e,d,u);if(d=t.nextSticky??d,t.projectDir===void 0)return;t.viaRootGuess&&p(t.projectDir);let a=t.projectDir,o=await i(a),s=await ml({lockDir:be(a),contentDir:$e(o,a),envAutoStart:r,...n===void 0?{}:{timeoutMs:n}});return l(a),s.replace(/\/mcp$/,``)};a.server.oninitialized=()=>{let e=a.server.getClientVersion(),t=Ie(e?.name,o);s.current={connectionId:o,clientInfo:e?{name:t,version:e.version}:void 0,displayName:t,colorSeed:t}},me(a,{serverUrl:h,resolveCwd:m,config:i,identityRef:s});let _=new Os,v=!1,y,b,x=async()=>{if(v)return;v=!0,y?.stop(),b?.stop();for(let e of c.values())try{e.close()}catch(e){t.write(`[mcp] keepalive close error: ${e instanceof Error?e.message:String(e)}\n`)}c.clear();let e=await Promise.allSettled([a.close(),_.close()]);for(let n of e)if(n.status===`rejected`){let e=n.reason;t.write(`[mcp] shutdown close error: ${e instanceof Error?e.message:String(e)}\n`)}};await a.connect(_),t.write(`[mcp] global stdio server ready (per-call project routing)
|
|
71
71
|
`);let S=!1,C=()=>{S||(S=!0,setTimeout(()=>{t.write(`[mcp] shutdown deadline (5s) reached — forcing exit(1)
|
|
72
72
|
`),process.exit(1)},5e3).unref(),x().finally(()=>{process.exit(0)}))};if(process.once(`SIGINT`,C),process.once(`SIGTERM`,C),process.stdin.on(`end`,()=>{t.write(`[mcp] stdin end — host disconnected, shutting down
|
|
73
|
-
`),C()}),process.stdin.on(`error`,e=>{t.write(`[mcp] stdin error (${e instanceof Error?e.message:String(e)}) — host disconnected, shutting down\n`),C()}),b=Ms({getPpid:()=>process.ppid,onHostGone:e=>{t.write(`[mcp] ${e} — shutting down\n`),C()}}),Ns({log:e=>t.write(`${e}\n`),transport:_,process,stdin:process.stdin}),process.platform===`darwin`){let e=js(vl,{realpathSync:en,statInoSync:e=>nn(e).ino,log:e=>t.write(`${e}\n`)});if(e!==void 0){t.write(`[mcp] bundle identity anchor=${e.resolvedPath} inode=${e.inode} version=${g}\n`);let{resolvedPath:n,inode:r}=e;y=As({detect:()=>ks({bundleAnchorPath:vl,currentInode:r,platform:process.platform,realpath:en,statInode:e=>nn(e).ino}),onReplaced:e=>{t.write(`[mcp] bundle replaced anchor=${n} bootInode=${e.currentInode} onDiskInode=${e.onDiskInode} version=${g} — exiting for host respawn\n`),C()},log:e=>t.write(`[mcp] ${e}\n`)})}}return{close:x}}function El(e){return new t(`mcp`).description(`Start MCP stdio server for project knowledge base`).option(`-p, --port <port>`,`Override per-call routing and proxy stdio to this HTTP MCP port (skips bundle proxy)`,void 0).option(`--no-bundle-proxy`,`Run the npm-fetched MCP server in-process instead of proxying to the macOS Desktop bundle (equivalent: OK_BUNDLE_PROXY=0)`).action(async t=>{try{let n=e(),r=process.cwd();if(t.port!==void 0){let e=rl(process.env.OK_MCP_SPAWN_TIMEOUT_MS);await _l({lockDir:``,contentDir:``,portOverride:t.port,envAutoStart:process.env.OK_MCP_AUTOSTART,timeoutMs:e});return}let i=t.bundleProxy===!1?[...process.argv,`--no-bundle-proxy`]:process.argv,a=xs(process.env,i,process.platform);if(a.proxy){let e=bs(process.platform,fn(),{existsSync:P});if(e===null)Ss({stderr:process.stderr,mode:`fallback-absent`,bundlePath:null,reason:`no installed Open Knowledge.app bundle found`});else try{await Cs({bundlePath:e,argv:process.argv.slice(2),env:process.env,stderr:process.stderr});return}catch(t){Ss({stderr:process.stderr,mode:`fallback-exec-failed`,bundlePath:e,reason:t instanceof Error?t.message:String(t)})}}else{let e=a.suppressedBy===`env`?`suppressed-env`:a.suppressedBy===`flag`?`suppressed-flag`:a.suppressedBy===`self`?`suppressed-self`:`suppressed-platform`;Ss({stderr:process.stderr,mode:e,bundlePath:null,reason:null})}await Tl({startupCwd:r,startupConfig:n})}catch(e){process.stderr.write(`MCP server failed to start: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}})}function Dl(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function Ol(e=()=>Bt(Rt())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>ce({lockDir:le(e)}).baseUrl,openTarget:e=>{M(`open`,[e],{detached:!0,stdio:`ignore`,env:Dl(process.env)}).unref()},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function kl(e,t,n){let r=B(t.project??process.cwd()),i=t.folder===!0||/\/+$/.test(e),a=e.replace(/\/+$/,``);if(!a)return n.error("Nothing to open: pass a doc path (e.g. `ok open specs/foo/SPEC`)."),1;if(a.startsWith(`/`)||a.includes(`\\`)||a.split(`/`).includes(`..`))return n.error(`Invalid name "${a}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(i){let e=n.resolveBaseUrl(r);if(!e)return n.error(`No Open Knowledge UI is running for ${r}. Folder preview requires a running UI — start one with \`ok ui\`, then retry.`),1;let t=`${e}/#/${Ne(a)}`;return n.openTarget(t),n.log(`Opening folder ${a} in your browser: ${t}`),0}if(n.detectBundlePath()){let e=`openknowledge://open?project=${encodeURIComponent(r)}&doc=${encodeURIComponent(a)}`;return n.openTarget(e),n.log(`Opening ${a} in the Open Knowledge desktop app.`),0}let o=n.resolveBaseUrl(r);if(o){let e=`${o}/#/${Ke(a)}`;return n.openTarget(e),n.log(`Opening ${a} in your browser: ${e}`),0}return n.error("No Open Knowledge desktop app found and no UI is running. Install OK Desktop, or start a UI with `ok ui`, then retry."),1}function Al(){return new t(`open`).description(`Open a doc in the OK Desktop app (folders open in the browser)`).argument(`<doc>`,`Extension-less doc path (e.g. specs/foo/SPEC), or a folder path with --folder`).option(`--folder`,`Treat <doc> as a folder and open the folder route in the browser`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action((e,t)=>{process.exitCode=kl(e,t,Ol())})}function jl(e){return new t(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-
|
|
73
|
+
`),C()}),process.stdin.on(`error`,e=>{t.write(`[mcp] stdin error (${e instanceof Error?e.message:String(e)}) — host disconnected, shutting down\n`),C()}),b=Ms({getPpid:()=>process.ppid,onHostGone:e=>{t.write(`[mcp] ${e} — shutting down\n`),C()}}),Ns({log:e=>t.write(`${e}\n`),transport:_,process,stdin:process.stdin}),process.platform===`darwin`){let e=js(vl,{realpathSync:en,statInoSync:e=>nn(e).ino,log:e=>t.write(`${e}\n`)});if(e!==void 0){t.write(`[mcp] bundle identity anchor=${e.resolvedPath} inode=${e.inode} version=${g}\n`);let{resolvedPath:n,inode:r}=e;y=As({detect:()=>ks({bundleAnchorPath:vl,currentInode:r,platform:process.platform,realpath:en,statInode:e=>nn(e).ino}),onReplaced:e=>{t.write(`[mcp] bundle replaced anchor=${n} bootInode=${e.currentInode} onDiskInode=${e.onDiskInode} version=${g} — exiting for host respawn\n`),C()},log:e=>t.write(`[mcp] ${e}\n`)})}}return{close:x}}function El(e){return new t(`mcp`).description(`Start MCP stdio server for project knowledge base`).option(`-p, --port <port>`,`Override per-call routing and proxy stdio to this HTTP MCP port (skips bundle proxy)`,void 0).option(`--no-bundle-proxy`,`Run the npm-fetched MCP server in-process instead of proxying to the macOS Desktop bundle (equivalent: OK_BUNDLE_PROXY=0)`).action(async t=>{try{let n=e(),r=process.cwd();if(t.port!==void 0){let e=rl(process.env.OK_MCP_SPAWN_TIMEOUT_MS);await _l({lockDir:``,contentDir:``,portOverride:t.port,envAutoStart:process.env.OK_MCP_AUTOSTART,timeoutMs:e});return}let i=t.bundleProxy===!1?[...process.argv,`--no-bundle-proxy`]:process.argv,a=xs(process.env,i,process.platform);if(a.proxy){let e=bs(process.platform,fn(),{existsSync:P});if(e===null)Ss({stderr:process.stderr,mode:`fallback-absent`,bundlePath:null,reason:`no installed Open Knowledge.app bundle found`});else try{await Cs({bundlePath:e,argv:process.argv.slice(2),env:process.env,stderr:process.stderr});return}catch(t){Ss({stderr:process.stderr,mode:`fallback-exec-failed`,bundlePath:e,reason:t instanceof Error?t.message:String(t)})}}else{let e=a.suppressedBy===`env`?`suppressed-env`:a.suppressedBy===`flag`?`suppressed-flag`:a.suppressedBy===`self`?`suppressed-self`:`suppressed-platform`;Ss({stderr:process.stderr,mode:e,bundlePath:null,reason:null})}await Tl({startupCwd:r,startupConfig:n})}catch(e){process.stderr.write(`MCP server failed to start: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1}})}function Dl(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function Ol(e=()=>Bt(Rt())){return{detectBundlePath:()=>e().bundlePath??null,resolveBaseUrl:e=>ce({lockDir:le(e)}).baseUrl,openTarget:e=>{M(`open`,[e],{detached:!0,stdio:`ignore`,env:Dl(process.env)}).unref()},log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}function kl(e,t,n){let r=B(t.project??process.cwd()),i=t.folder===!0||/\/+$/.test(e),a=e.replace(/\/+$/,``);if(!a)return n.error("Nothing to open: pass a doc path (e.g. `ok open specs/foo/SPEC`)."),1;if(a.startsWith(`/`)||a.includes(`\\`)||a.split(`/`).includes(`..`))return n.error(`Invalid name "${a}": must be a relative path with no '..' segments, leading '/', or backslashes.`),1;if(i){let e=n.resolveBaseUrl(r);if(!e)return n.error(`No Open Knowledge UI is running for ${r}. Folder preview requires a running UI — start one with \`ok ui\`, then retry.`),1;let t=`${e}/#/${Ne(a)}`;return n.openTarget(t),n.log(`Opening folder ${a} in your browser: ${t}`),0}if(n.detectBundlePath()){let e=`openknowledge://open?project=${encodeURIComponent(r)}&doc=${encodeURIComponent(a)}`;return n.openTarget(e),n.log(`Opening ${a} in the Open Knowledge desktop app.`),0}let o=n.resolveBaseUrl(r);if(o){let e=`${o}/#/${Ke(a)}`;return n.openTarget(e),n.log(`Opening ${a} in your browser: ${e}`),0}return n.error("No Open Knowledge desktop app found and no UI is running. Install OK Desktop, or start a UI with `ok ui`, then retry."),1}function Al(){return new t(`open`).description(`Open a doc in the OK Desktop app (folders open in the browser)`).argument(`<doc>`,`Extension-less doc path (e.g. specs/foo/SPEC), or a folder path with --folder`).option(`--folder`,`Treat <doc> as a folder and open the folder route in the browser`).option(`--project <dir>`,`Project root (defaults to the current directory)`).action((e,t)=>{process.exitCode=kl(e,t,Ol())})}function jl(e){return new t(`preview`).description(`Show what content the watcher will track (read-only)`).action(async()=>{let{previewContent:t,formatPreviewBlock:n}=await import(`./preview-BvKJzJeL.mjs`),r=e(),i=process.cwd(),a=$e(r,i),o;try{o=t({projectDir:i,contentDir:a})}catch(e){console.error(`Content preview failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}process.stdout.write(`${n(o,i)}\n`),o.totalCount===0&&o.warnings.length>0&&(process.exitCode=1)})}function Z(e,t){e&&process.stdout.write(`${JSON.stringify(t)}\n`)}async function Ml(e,t,n=process.cwd()){let r=e.op??`sync`,i=h(le(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`,...l({kind:`cli`,runtimeVersion:g})},body:JSON.stringify({op:r})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.title??e.error??e.message??`Server responded with ${n.status}`)}Z(e.json,{type:`triggered`,op:r,port:i.port}),e.json||process.stderr.write(`✓ ${r} triggered\n`);return}catch(t){let n=t instanceof Error?t.message:String(t);e.json||process.stderr.write(`Server trigger failed (${n}), running directly\n`)}}e.json||process.stderr.write(`Running ${r} directly (no live server)\n`);let a=T({baseDir:n});if(r===`sync`||r===`pull`){Z(e.json,{type:`step`,step:`pull`});let t=await a.pull();Z(e.json,{type:`pull`,summary:t.summary}),e.json||process.stderr.write(` pull: ${t.summary.changes} changes\n`)}(r===`sync`||r===`push`)&&(Z(e.json,{type:`step`,step:`push`}),await a.push(),Z(e.json,{type:`push`,ok:!0}),e.json||process.stderr.write(` push: ok
|
|
74
74
|
`)),Z(e.json,{type:`complete`,op:r}),e.json||process.stderr.write(`✓ ${r} complete\n`)}function Nl(e){return new t(`sync`).description(`Commit, pull, and push to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ml({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 Pl(e){return new t(`pull`).description(`Pull changes from the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ml({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 Fl(e){return new t(`push`).description(`Push commits to the remote`).option(`--json`,`Output JSONL progress events`,!1).action(async t=>{try{await Ml({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 Il(e){return typeof e==`string`&&_e.includes(e)}async function Ll(e={}){let t=B(e.cwd??process.cwd()),n=e.pack??`knowledge-base`;if(!Ee[n])return{status:`failed`,message:`${k(`Error:`)} Unknown pack "${n}". Available: ${_e.join(`, `)}`,exitCode:1};let r;try{r=await Je({projectDir:t,rootDir:e.root,packId:n})}catch(e){return e instanceof Ge?{status:`prerequisite-missing`,message:`${k(`Error:`)} ${e.message}`,exitCode:1}:{status:`failed`,message:`${k(`Error:`)} ${e instanceof Error?e.message:String(e)}`,exitCode:1}}if(r.created.length===0){let e=Ee[n].name;return{status:`no-op`,message:`${O(`Your ${e} pack is already seeded.`)}\n${D(`Nothing to do.`)}`,plan:r,exitCode:0}}if(e.dryRun)return{status:`dry-run`,message:`${j(`Plan (dry-run — no changes made):`)}\n\n${zl(r,t)}`,plan:r,exitCode:0};if(!e.yes&&!await Bl(`${j(`Plan:`)}\n\n${zl(r,t)}\n\n${j(`Apply?`)} ${D(`[Y/n] `)}`,e.confirmStream))return{status:`cancelled`,message:D(`Cancelled.`),plan:r,exitCode:0};let i=await ze(r,{projectDir:t,packId:n});if(i.errors.length>0){let e=i.errors.map(e=>` ${k(`✗`)} ${e.path}: ${e.error}`);return{status:`failed`,message:[`${A(`Applied`)} ${i.applied} entries, ${A(String(i.errors.length))} error(s):`,...e].join(`
|
|
75
75
|
`),plan:r,exitCode:1}}let a=Ee[n].name,o=i.packSkillsInstalled.length>0?`\n${D(`Installed the ${a} skill for: ${i.packSkillsInstalled.join(`, `)}`)}`:``;return{status:`applied`,message:`${O(`✓ Seeded ${a}`)} ${D(`(${i.applied} entries, ${i.durationMs}ms)`)}${o}`,plan:r,exitCode:0}}function Rl(){let e=[j(`Available packs:`)];for(let t of _e){let n=Ee[t];e.push(` ${O(t)} ${D(`—`)} ${n.name}: ${n.description}`)}return e.join(`
|
|
76
76
|
`)}function zl(e,t){let n=[],r=e.created.filter(e=>e.kind===`folder`),i=e.created.filter(e=>e.kind===`file`);if(r.length>0){n.push(j(`Folders to create:`));for(let e of r)n.push(` ${O(`+`)} ${E(sn(t,B(t,e.path))||e.path)}${D(`/`)}`)}if(i.length>0){n.length>0&&n.push(``),n.push(j(`Files to create:`));for(let e of i)n.push(` ${O(`+`)} ${E(sn(t,B(t,e.path))||e.path)}`)}if(e.skipped.length>0){n.length>0&&n.push(``),n.push(D(`Already present (skipped):`));for(let t of e.skipped)n.push(` ${D(`· ${t.path} (${t.reason})`)}`)}if(e.warnings.length>0){n.length>0&&n.push(``),n.push(A(`Warnings:`));for(let t of e.warnings)n.push(` ${A(`!`)} ${t}`)}return n.join(`
|
|
@@ -79,7 +79,7 @@ project → Search (a toggle with an egress-confirmation prompt), or run
|
|
|
79
79
|
`);return}if(a){process.stdout.write(`${JSON.stringify({type:`error`,code:c.kind})}\n`);return}process.stderr.write(`✗ share name-check failed: ${c.kind}\n`),process.exit(1)}function Wl(e){return new t(`name-check`).description(`Check if owner/name is available on GitHub`).requiredOption(`--owner <owner>`,`GitHub owner (user or org)`).requiredOption(`--name <name>`,`Repository name`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{await Ul(t,await e())})}async function Gl(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 Kl(e,t){let{host:n,json:r}=e;H(n);let i=await Ni(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 Gl(new K({auth:i,...a?{baseUrl:a}:{}}));if(o.kind===`ok`){if(r)process.stdout.write(`${JSON.stringify({type:`owners`,owners:o.owners})}\n`);else for(let e of o.owners)process.stdout.write(`${e.kind}\t${e.login}\n`);return}if(r){process.stdout.write(`${JSON.stringify({type:`error`,code:o.kind})}\n`);return}process.stderr.write(`✗ share owners failed: ${o.kind}\n`),process.exit(1)}function ql(e){return new t(`owners`).description(`List GitHub owners eligible to host a new repository`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{await Kl(t,await e())})}function Jl(e){let t=e,n=t.status,r=t.response?.data,i=t.response?.headers,a=`${r?.message??r?.errors?.map(e=>e.message??``).join(`
|
|
80
80
|
`)??``}\n${t.message??``}`.toLowerCase();return n===401?`auth-required`:n===403?i?.[`x-github-sso`]||a.includes(`saml`)||a.includes(`sso`)?`saml-sso`:`network`:n===422&&(r?.errors?.some(e=>e.field===`name`)||a.includes(`already exists`)||a.includes(`name already exists`))?`name-conflict`:`network`}async function Yl(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 Xl(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 Zl(e,t){return(await e.users.getAuthenticated()).data.login.toLowerCase()===t.toLowerCase()?`user`:`org`}function Ql(e){return T({baseDir:e,unsafe:{allowUnsafeCredentialHelper:!0}}).env({GIT_TERMINAL_PROMPT:`0`})}function $l(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 eu={ensureOkScaffold:e=>{pe(e)},gitFactory:Ql};async function tu(e){let t={...eu,...e.deps},n=B(e.projectDir),r;if(e.ownerKind)r=e.ownerKind;else try{r=await Zl(e.octokit,e.body.owner)}catch(e){return{kind:`error`,code:Jl(e)}}try{t.ensureOkScaffold(n)}catch{return{kind:`error`,code:`init-failed`}}let i=t.gitFactory(n);if(!P(z(n,`.git`)))try{await i.init()}catch{return{kind:`error`,code:`init-failed`}}let a;try{a=await Yl({octokit:e.octokit,ownerLogin:e.body.owner,ownerKind:r,name:e.body.name,visibility:e.body.visibility,description:e.body.description})}catch(t){if(Jl(t)===`name-conflict`){let t=await Xl(e.octokit,e.body.owner,e.body.name);if(t===null)return{kind:`error`,code:`name-conflict`};a=t}else return{kind:`error`,code:Jl(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=$l(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 nu(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 ru(e,t){let{host:n,owner:r,name:i,visibility:a,description:o,projectDir:s,json:c}=e;H(n);let l=await Ni(n,t);if(l==null){nu(c,{kind:`error`,code:`auth-required`});return}let u=n===`github.com`?void 0:`https://${n}/api/v3`,d=new K({auth:l,...u?{baseUrl:u}:{}});try{Gt(`git config user.email`,{cwd:s,stdio:`ignore`})}catch{process.env.GIT_AUTHOR_NAME??=`Open Knowledge`,process.env.GIT_AUTHOR_EMAIL??=`noreply@inkeep.com`,process.env.GIT_COMMITTER_NAME??=`Open Knowledge`,process.env.GIT_COMMITTER_EMAIL??=`noreply@inkeep.com`}nu(c,await tu({octokit:d,token:l,projectDir:s,body:{owner:r,name:i,visibility:a,description:o}}))}function iu(e){return new t(`publish`).description(`Publish a no-remote project to GitHub`).requiredOption(`--owner <owner>`,`GitHub owner (user or org)`).requiredOption(`--name <name>`,`Repository name`).requiredOption(`--visibility <visibility>`,`public or private`).option(`--description <description>`,`Repository description`).requiredOption(`--project-dir <projectDir>`,`Path to the project on disk`).option(`--host <host>`,`GitHub or GitHub Enterprise hostname`,`github.com`).option(`--json`,`Output JSON`,!1).action(async t=>{t.visibility!==`public`&&t.visibility!==`private`&&(process.stderr.write(`✗ visibility must be 'public' or 'private'
|
|
81
81
|
`),process.exit(1)),await ru(t,await e())})}function au(){let e=new t(`share`);e.description(`Sharing flow operations (owners, name-check, publish)`);let n=()=>te();return e.addCommand(ql(n)),e.addCommand(Wl(n)),e.addCommand(iu(n)),e}function ou(){return new t(`share`).description(`Switch this project to shared mode (commit OK config alongside content)`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=B(e.project??process.cwd()),n=gt(t),r=ot(t,at(t));if(r.kind===`no-exclude`){su(e.json,t,r.reason);return}let i=gt(t);if(e.json){let e={type:`sharing-share`,projectRoot:t,mode:i,removed:r.removed};process.stdout.write(`${JSON.stringify(e)}\n`);return}if(n===`shared`){process.stderr.write(`${E(`Sharing mode is already`)} ${j(`shared`)} ${E(`— nothing to do.`)}\n`);return}process.stderr.write(`${O(`✓`)} ${j(`Sharing mode set to`)} ${O(`shared`)}\n`),process.stderr.write(` Removed OK paths from ${j(`.git/info/exclude`)}; commit the files to share with teammates.\n`)})}function su(e,t,n){if(e){process.stdout.write(`${JSON.stringify({type:`sharing-share`,projectRoot:t,mode:`no-git`,removed:[],reason:n})}\n`);return}process.stderr.write(`${A({"no-git":`No git repository here — sharing mode does not apply.`,"no-info-dir":`The gitdir's info/ folder is absent; cannot toggle sharing mode.`,"malformed-pointer":"The .git pointer file is malformed (stale worktree). Run `git worktree prune` and try again.",inaccessible:`The .git path is inaccessible (permissions or mount issue).`}[n])}\n`)}function cu(){return new t(`status`).description(`Print the current sharing mode and the OK paths in .git/info/exclude`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=B(e.project??process.cwd()),n=gt(t),r=[...ht(t)],i=xt(t,at(t)).tracked;if(e.json){let e={type:`sharing-status`,projectRoot:t,mode:n,excluded:r,trackedUpstream:i};process.stdout.write(`${JSON.stringify(e)}\n`);return}let a=[];if(a.push(`Open Knowledge sharing mode: ${lu(n)}`),a.push(``),a.push(`Excluded from git via ${j(`.git/info/exclude`)}:`),r.length===0)a.push(` (none)`);else for(let e of r)a.push(` ${e}`);if(a.push(``),a.push(`Other OK paths exist but are tracked upstream:`),i.length===0)a.push(` (none)`);else for(let e of i)a.push(` ${e}`);a.push(``),a.push(`Toggle with: ${E(n===`local-only`?`ok config-sharing share`:`ok config-sharing unshare`)}`),process.stdout.write(`${a.join(`
|
|
82
|
-
`)}\n`)})}function lu(e){switch(e){case`shared`:return O(`shared`);case`local-only`:return O(`local-only`);case`no-git`:return A(`no-git (not a git repository)`)}}function uu(){return new t(`unshare`).description(`Switch this project to local-only mode (add OK artifacts to .git/info/exclude so they stay out of git)`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=B(e.project??process.cwd()),n=vt(t,at(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`){du(e.json,t,n.reason);return}let r=gt(t);if(e.json){let e={type:`sharing-unshare`,projectRoot:t,mode:r,appended:n.appended,alreadyPresent:n.alreadyPresent};process.stdout.write(`${JSON.stringify(e)}\n`);return}if(n.appended.length===0){process.stderr.write(`${j(`Sharing mode is already`)} ${O(`local-only`)} ${j(`— nothing to do.`)}\n`);return}process.stderr.write(`${O(`✓`)} ${j(`Sharing mode set to`)} ${O(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${j(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function du(e,t,n){if(e){process.stdout.write(`${JSON.stringify({type:`sharing-unshare`,projectRoot:t,mode:`no-git`,appended:[],alreadyPresent:[],reason:n})}\n`);return}process.stderr.write(`${A({"no-git":`No git repository here — sharing mode does not apply.`,"no-info-dir":`The gitdir's info/ folder is absent; cannot toggle sharing mode.`,"malformed-pointer":"The .git pointer file is malformed (stale worktree). Run `git worktree prune` and try again.",inaccessible:`The .git path is inaccessible (permissions or mount issue).`}[n])}\n`)}function fu(){let e=new t(`config-sharing`);return e.description(`Manage Open Knowledge's git-sharing mode (share OK config with the team, or keep local-only on this machine)`),e.addCommand(ou()),e.addCommand(uu()),e.addCommand(cu()),e}const pu=new Set([`--cwd`,`--log-level`]);function mu(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(`-`)){pu.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function hu(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 gu(e){return/\.(md|mdx)$/i.test(e)}function _u(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function vu(e=()=>Bt(Rt())){return{prepare:Qe,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{M(`open`,[e],{detached:!0,stdio:`ignore`,env:_u(process.env)}).unref()},runProjectOpen:(e,t)=>kl(e,{project:t},Ol()),runBrowserOpen:e=>xu(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function yu(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof Le||e instanceof Ue||e instanceof je)return t.error(e.message),1;throw e}if(n.mode===`project`)return t.runProjectOpen(n.docName,n.projectRoot);if(t.detectBundlePath()){let e=`openknowledge://open?file=${encodeURIComponent(n.canonicalFilePath)}`;return t.openTarget(e),t.log(`Opening ${n.singleDocRelPath} in the Open Knowledge desktop app.`),0}return await t.runBrowserOpen(n),0}function bu(){let e=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[B(e,`public`),B(e,`../../app/dist`),B(e,`../../../app/dist`)].find(e=>P(e))}async function xu(e){let{createEphemeralProjectDir:t}=await import(`./dist-
|
|
82
|
+
`)}\n`)})}function lu(e){switch(e){case`shared`:return O(`shared`);case`local-only`:return O(`local-only`);case`no-git`:return A(`no-git (not a git repository)`)}}function uu(){return new t(`unshare`).description(`Switch this project to local-only mode (add OK artifacts to .git/info/exclude so they stay out of git)`).option(`--project <dir>`,`Project root (defaults to cwd)`).option(`--json`,`Output JSON`,!1).action(async e=>{let t=B(e.project??process.cwd()),n=vt(t,at(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`){du(e.json,t,n.reason);return}let r=gt(t);if(e.json){let e={type:`sharing-unshare`,projectRoot:t,mode:r,appended:n.appended,alreadyPresent:n.alreadyPresent};process.stdout.write(`${JSON.stringify(e)}\n`);return}if(n.appended.length===0){process.stderr.write(`${j(`Sharing mode is already`)} ${O(`local-only`)} ${j(`— nothing to do.`)}\n`);return}process.stderr.write(`${O(`✓`)} ${j(`Sharing mode set to`)} ${O(`local-only`)}\n`),process.stderr.write(` Added ${n.appended.length} path(s) to ${j(`.git/info/exclude`)} (per-clone, not committed).\n`)})}function du(e,t,n){if(e){process.stdout.write(`${JSON.stringify({type:`sharing-unshare`,projectRoot:t,mode:`no-git`,appended:[],alreadyPresent:[],reason:n})}\n`);return}process.stderr.write(`${A({"no-git":`No git repository here — sharing mode does not apply.`,"no-info-dir":`The gitdir's info/ folder is absent; cannot toggle sharing mode.`,"malformed-pointer":"The .git pointer file is malformed (stale worktree). Run `git worktree prune` and try again.",inaccessible:`The .git path is inaccessible (permissions or mount issue).`}[n])}\n`)}function fu(){let e=new t(`config-sharing`);return e.description(`Manage Open Knowledge's git-sharing mode (share OK config with the team, or keep local-only on this machine)`),e.addCommand(ou()),e.addCommand(uu()),e.addCommand(cu()),e}const pu=new Set([`--cwd`,`--log-level`]);function mu(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(`-`)){pu.has(a)&&i++;continue}t.push(a)}}return{operands:t,cwd:n,sawTerminalFlag:r}}function hu(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 gu(e){return/\.(md|mdx)$/i.test(e)}function _u(e){let t={...e};return delete t.ELECTRON_RUN_AS_NODE,t}function vu(e=()=>Bt(Rt())){return{prepare:Qe,detectBundlePath:()=>e().bundlePath??null,openTarget:e=>{M(`open`,[e],{detached:!0,stdio:`ignore`,env:_u(process.env)}).unref()},runProjectOpen:(e,t)=>kl(e,{project:t},Ol()),runBrowserOpen:e=>xu(e),log:e=>process.stdout.write(`${e}\n`),error:e=>process.stderr.write(`${e}\n`)}}async function yu(e,t){let n;try{n=t.prepare(e)}catch(e){if(e instanceof Le||e instanceof Ue||e instanceof je)return t.error(e.message),1;throw e}if(n.mode===`project`)return t.runProjectOpen(n.docName,n.projectRoot);if(t.detectBundlePath()){let e=`openknowledge://open?file=${encodeURIComponent(n.canonicalFilePath)}`;return t.openTarget(e),t.log(`Opening ${n.singleDocRelPath} in the Open Knowledge desktop app.`),0}return await t.runBrowserOpen(n),0}function bu(){let e=import.meta.dirname??new URL(`.`,import.meta.url).pathname;return[B(e,`public`),B(e,`../../app/dist`),B(e,`../../../app/dist`)].find(e=>P(e))}async function xu(e){let{createEphemeralProjectDir:t}=await import(`./dist-6j4x3nmy.mjs`),{loadConfig:n}=await import(`./index.mjs`),{bootStartServer:r,resolveHost:i}=await import(`./start-LI_wE7gV.mjs`),{openBrowser:a}=await import(`./open-browser-DHTbHSqx.mjs`),o=bu();o||(process.stderr.write("Open Knowledge UI assets were not found. Reinstall @inkeep/open-knowledge, or build the app (`bun run build`) in a monorepo checkout.\n"),process.exit(1));let s=t(e.contentDir),c=!1,l,u=async()=>{if(!c){c=!0;try{await l?.destroy()}catch{}try{await bn(s,{recursive:!0,force:!0})}catch{}}},d=()=>{u().then(()=>process.exit(0))};process.once(`SIGINT`,d),process.once(`SIGTERM`,d);let{config:f}=n(s),p=i({},process.env);try{l=await r({config:f,cwd:s,host:p,port:0,projectDir:s,singleFile:e.canonicalFilePath,serveContentAssets:!0,reactShellDistDir:o})}catch(t){await u(),process.stderr.write(`Failed to open ${e.singleDocRelPath}: ${t instanceof Error?t.message:String(t)}\n`),process.exit(1)}let m=`http://${p}:${l.port}/#/${Ke(e.docName)}`;process.stdout.write(`Opening ${e.singleDocRelPath} in your browser: ${m}\n`),process.stdout.write(`Press Ctrl-C to close the session.
|
|
83
83
|
`),a(m),await new Promise(()=>{})}function Su(e,t){return{server:Cu(`server`,e),ui:Cu(`ui`,t)}}function Cu(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 wu(e){return`${Tu(e.server)}\n${Tu(e.ui)}`}function Tu(e){let t=e.name===`server`?`server`:`ui `;return e.state===`missing`?`${t} not running`:e.state===`corrupt`?`${t} lock file corrupt — run \`ok clean\``:e.state===`foreign-host`?`${t} foreign host (${e.host}) pid=${e.pid} port=${e.port}`:e.state===`dead-pid`?`${t} stale (dead pid=${e.pid}) — run \`ok clean\``:`${t} alive pid=${e.pid} port=${e.port} started=${e.startedAt}`}function Eu(e){let t=e.inspect??(t=>Tt(e.lockDir,t)),n=e.log??(e=>console.log(e)),r=Su(t(`server`),t(`ui`));return e.json?n(JSON.stringify(r,null,2)):n(wu(r)),r}function Du(e){return new t(`status`).description(`Show live state of the server + ui lockfiles for this project`).option(`--json`,`Emit structured JSON instead of formatted text`).action(t=>{e(),Eu({lockDir:le(process.cwd()),json:t.json===!0})})}function Ou(e){return[e,`Copyright (C) 2026 Inkeep, Inc.`,`License GPL-3.0-or-later: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.`,`This is free software: you are free to change and redistribute it.`,`There is NO WARRANTY, to the extent permitted by law.`].join(`
|
|
84
84
|
`)}process.argv.includes(`--no-color`)?(process.env.NO_COLOR=`1`,delete process.env.FORCE_COLOR):process.argv.includes(`--color`)&&(process.env.FORCE_COLOR=`1`,delete process.env.NO_COLOR);const Q=new t;let $,ku;function Au(){return ku}Q.name(`open-knowledge`).description(`Local-first knowledge base with CRDT collaboration`).usage(`[options] [file | command]`).version(Ou(Mt)).option(`--cwd <path>`,`Working directory`).option(`--log-level <level>`,`Log level: silent, error, warn, info (default), debug, trace`,`info`).option(`--no-color`,`Disable color output`).option(`--color`,`Force color output`).hook(`preAction`,e=>{let t=e.opts().cwd;if(t!==void 0&&process.chdir(t),Q.getOptionValueSource(`logLevel`)===`cli`){let e=String(Q.opts().logLevel);process.env.LOG_LEVEL=e,process.env.OK_CONSOLE_LEVEL=e}let n=e.args?.[0],r=kt(n,process.cwd());r!==null&&(Ct(process.cwd()),process.chdir(r),console.error(`[ok] Using Open Knowledge project at ${r}`));let{config:i}=Pt(r??t);$=i;let a=e.args?.[0]??e.name()??`cli`;ku=Te({name:`cli`,project:i.project?.name??void 0}),ku.info({command:a,cwd:process.cwd()},`cli command started`)}),Q.action(async()=>{if(Bt(Rt()).available){It({spawn:M});return}await zt($,{})});const ju=Lt(()=>$);Q.addCommand(ju);const Mu=El(()=>$);Q.addCommand(Mu),Q.addCommand(yt()),Q.addCommand(Vl()),Q.addCommand(_s()),Q.addCommand(Ut());const Nu=jl(()=>$);Q.addCommand(Nu);const Pu=bt(()=>$);Q.addCommand(Pu),Q.addCommand(Al()),Q.addCommand(Et(()=>$)),Q.addCommand(ra(()=>$)),Q.addCommand(Du(()=>$)),Q.addCommand(At()),Q.addCommand(es()),Q.addCommand(ea()),Q.addCommand(Ca()),Q.addCommand(Hi(Au)),Q.addCommand(ls()),Q.addCommand(ha(()=>$)),Q.addCommand(Nl(()=>$)),Q.addCommand(Fl(()=>$)),Q.addCommand(Pl(()=>$)),Q.addCommand(au()),Q.addCommand(fu()),Q.addHelpText(`after`,`
|
|
85
85
|
Examples:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Cr as e,J as t,Jr as n,Sn as r,Wr as i,a,an as o,c as s,d as c,f as l,g as u,h as d,i as f,l as p,m,n as h,o as g,p as _,r as v,s as y,t as b,tn as x,u as S,vn as C,zt as w}from"./server-lock-BpjJj3OD-DlYx_Xz-.mjs";import{$ as T,$n as E,$r as D,$t as O,A as k,Ai as A,An as j,Ar as M,At as N,B as P,Bi as F,Bn as I,Br as L,Bt as R,C as z,Ci as B,Cn as V,Cr as H,Ct as U,D as W,Di as G,Dn as K,Dr as q,Dt as J,E as Y,Ei as X,En as Z,Er as Q,Et as $,F as ee,Fi as te,Fn as ne,Fr as re,Ft as ie,G as ae,Gn as oe,Gr as se,Gt as ce,H as le,Hi as ue,Hn as de,Hr as fe,Ht as pe,I as me,Ii as he,In as ge,Ir as _e,It as ve,J as ye,Jn as be,Jr as xe,Jt as Se,K as Ce,Kn as we,Kr as Te,Kt as Ee,L as De,Li as Oe,Ln as ke,Lr as Ae,Lt as je,M as Me,Mi as Ne,Mn as Pe,Mr as Fe,Mt as Ie,N as Le,Ni as Re,Nn as ze,Nr as Be,Nt as Ve,O as He,Oi as Ue,On as We,Or as Ge,Ot as Ke,P as qe,Pi as Je,Pn as Ye,Pr as Xe,Pt as Ze,Q as Qe,Qn as $e,Qr as et,Qt as tt,R as nt,Ri as rt,Rn as it,Rr as at,Rt as ot,S as st,Si as ct,Sn as lt,Sr as ut,St as dt,T as ft,Ti as pt,Tn as mt,Tr as ht,Tt as gt,U as _t,Un as vt,Ur as yt,Ut as bt,V as xt,Vi as St,Vn as Ct,Vr as wt,Vt as Tt,W as Et,Wn as Dt,Wr as Ot,Wt as kt,X as At,Xn as jt,Xr as Mt,Xt as Nt,Y as Pt,Yn as Ft,Yr as It,Yt as Lt,Z as Rt,Zn as zt,Zr as Bt,Zt as Vt,_ as Ht,_i as Ut,_n as Wt,_r as Gt,_t as Kt,a as qt,ai as Jt,an as Yt,ar as Xt,at as Zt,b as Qt,bi as $t,bn as en,br as tn,bt as nn,c as rn,ci as an,cn as on,cr as sn,ct as cn,d as ln,di as un,dn,dr as fn,dt as pn,ea as mn,ei as hn,en as gn,er as _n,et as vn,f as yn,fi as bn,fn as xn,fr as Sn,ft as Cn,g as wn,gi as Tn,gn as En,gr as Dn,gt as On,h as kn,hi as An,hn as jn,hr as Mn,ht as Nn,i as Pn,ii as Fn,in as In,ir as Ln,it as Rn,j as zn,ji as Bn,jn as Vn,jr as Hn,jt as Un,k as Wn,ki as Gn,kn as Kn,kr as qn,kt as Jn,l as Yn,li as Xn,ln as Zn,lr as Qn,lt as $n,m as er,mi as tr,mn as nr,mr as rr,mt as ir,n as ar,ni as or,nn as sr,nr as cr,nt as lr,o as ur,oi as dr,on as fr,or as pr,ot as mr,p as hr,pi as gr,pn as _r,pr as vr,pt as yr,q as br,qn as xr,qr as Sr,qt as Cr,r as wr,ri as Tr,rn as Er,rr as Dr,rt as Or,s as kr,si as Ar,sn as jr,sr as Mr,st as Nr,t as Pr,ta as Fr,ti as Ir,tn as Lr,tr as Rr,tt as zr,u as Br,ui as Vr,un as Hr,ur as Ur,ut as Wr,v as Gr,vi as Kr,vn as qr,vr as Jr,vt as Yr,w as Xr,wi as Zr,wn as Qr,wr as $r,wt as ei,x as ti,xi as ni,xn as ri,xr as ii,xt as ai,y as oi,yi as si,yn as ci,yr as li,yt as ui,z as di,zi as fi,zn as pi,zr as mi,zt as hi}from"./dist-
|
|
1
|
+
import{Cr as e,J as t,Jr as n,Sn as r,Wr as i,a,an as o,c as s,d as c,f as l,g as u,h as d,i as f,l as p,m,n as h,o as g,p as _,r as v,s as y,t as b,tn as x,u as S,vn as C,zt as w}from"./server-lock-BpjJj3OD-DlYx_Xz-.mjs";import{$ as T,$n as E,$r as D,$t as O,A as k,Ai as A,An as j,Ar as M,At as N,B as P,Bi as F,Bn as I,Br as L,Bt as R,C as z,Ci as B,Cn as V,Cr as H,Ct as U,D as W,Di as G,Dn as K,Dr as q,Dt as J,E as Y,Ei as X,En as Z,Er as Q,Et as $,F as ee,Fi as te,Fn as ne,Fr as re,Ft as ie,G as ae,Gn as oe,Gr as se,Gt as ce,H as le,Hi as ue,Hn as de,Hr as fe,Ht as pe,I as me,Ii as he,In as ge,Ir as _e,It as ve,J as ye,Jn as be,Jr as xe,Jt as Se,K as Ce,Kn as we,Kr as Te,Kt as Ee,L as De,Li as Oe,Ln as ke,Lr as Ae,Lt as je,M as Me,Mi as Ne,Mn as Pe,Mr as Fe,Mt as Ie,N as Le,Ni as Re,Nn as ze,Nr as Be,Nt as Ve,O as He,Oi as Ue,On as We,Or as Ge,Ot as Ke,P as qe,Pi as Je,Pn as Ye,Pr as Xe,Pt as Ze,Q as Qe,Qn as $e,Qr as et,Qt as tt,R as nt,Ri as rt,Rn as it,Rr as at,Rt as ot,S as st,Si as ct,Sn as lt,Sr as ut,St as dt,T as ft,Ti as pt,Tn as mt,Tr as ht,Tt as gt,U as _t,Un as vt,Ur as yt,Ut as bt,V as xt,Vi as St,Vn as Ct,Vr as wt,Vt as Tt,W as Et,Wn as Dt,Wr as Ot,Wt as kt,X as At,Xn as jt,Xr as Mt,Xt as Nt,Y as Pt,Yn as Ft,Yr as It,Yt as Lt,Z as Rt,Zn as zt,Zr as Bt,Zt as Vt,_ as Ht,_i as Ut,_n as Wt,_r as Gt,_t as Kt,a as qt,ai as Jt,an as Yt,ar as Xt,at as Zt,b as Qt,bi as $t,bn as en,br as tn,bt as nn,c as rn,ci as an,cn as on,cr as sn,ct as cn,d as ln,di as un,dn,dr as fn,dt as pn,ea as mn,ei as hn,en as gn,er as _n,et as vn,f as yn,fi as bn,fn as xn,fr as Sn,ft as Cn,g as wn,gi as Tn,gn as En,gr as Dn,gt as On,h as kn,hi as An,hn as jn,hr as Mn,ht as Nn,i as Pn,ii as Fn,in as In,ir as Ln,it as Rn,j as zn,ji as Bn,jn as Vn,jr as Hn,jt as Un,k as Wn,ki as Gn,kn as Kn,kr as qn,kt as Jn,l as Yn,li as Xn,ln as Zn,lr as Qn,lt as $n,m as er,mi as tr,mn as nr,mr as rr,mt as ir,n as ar,ni as or,nn as sr,nr as cr,nt as lr,o as ur,oi as dr,on as fr,or as pr,ot as mr,p as hr,pi as gr,pn as _r,pr as vr,pt as yr,q as br,qn as xr,qr as Sr,qt as Cr,r as wr,ri as Tr,rn as Er,rr as Dr,rt as Or,s as kr,si as Ar,sn as jr,sr as Mr,st as Nr,t as Pr,ta as Fr,ti as Ir,tn as Lr,tr as Rr,tt as zr,u as Br,ui as Vr,un as Hr,ur as Ur,ut as Wr,v as Gr,vi as Kr,vn as qr,vr as Jr,vt as Yr,w as Xr,wi as Zr,wn as Qr,wr as $r,wt as ei,x as ti,xi as ni,xn as ri,xr as ii,xt as ai,y as oi,yi as si,yn as ci,yr as li,yt as ui,z as di,zi as fi,zn as pi,zr as mi,zt as hi}from"./dist-Dcg4smYg.mjs";export{Pr as AGENT_ID_MAX_LEN,ar as AGENT_ID_RE,wr as AGENT_WRITE_ORIGIN,Pn as AgentFocusBroadcaster,qt as AgentPresenceBroadcaster,ur as AgentSessionCapacityError,kr as AgentSessionManager,rn as AutoStartDisabledError,Yn as BacklinkIndex,Br as CC1Broadcaster,t as CC1_CONTRACT_VERSION,ln as CONFIG_FILENAME,yn as CONFLICT_MARKER_RE,hr as CURSOR_BUNDLE_PATHS_BY_PLATFORM,er as ConfigSchema,kn as DEFAULT_CHECKPOINT_RETENTION,wn as DEFAULT_EMBEDDINGS_DIMENSIONS,Ht as DEFAULT_PACK_ID,Gr as EMBEDDINGS_API_KEY_ENV,oi as FILE_SYSTEM_WRITER,Qt as FILE_WATCHER_ORIGIN,ti as FileEmbeddingsBackend,st as GIT_PREFLIGHT_FAIL_SPAN_NAME,z as GIT_UPSTREAM_WRITER,mn as GitDirAccessError,Xr as GitNotAvailableError,ft as GitTooOldError,Y as HOCUSPOCUS_AUTH_REJECTION_REASONS,W as HocuspocusAuthRejection,He as HocuspocusAuthTokenSchema,Wn as INSTALLED_AGENTS_SCHEMES,w as LINEAGE_EPOCH_KEY,k as LIVE_DERIVED_INDEX_DEBOUNCE_MS,zn as LOG_MD_TEMPLATE,Me as MANAGED_RENAME_ORIGIN,Le as MAX_AGENT_SESSIONS,qe as MCP_CONNECTION_ID_HEADER,ee as MCP_SERVER_NAME,me as MIN_GIT_VERSION,De as MISSING_OK_CONFIG_MESSAGE,Fr as MalformedGitPointerError,nt as McpLogger,di as MissingOkConfigError,P as OBSERVER_SYNC_ORIGIN,xt as OK_OKIGNORE_TEMPLATE,x as ORPHAN_MODES,le as PANE_TARGET_TTL_MS,o as PROTOCOL_VERSION,_t as PinoLogger,b as ProcessLockCollisionError,Et as ProjectGitInitError,ae as ROLLBACK_ORIGIN,Ce as ROOT_GITIGNORE_TEMPLATE,h as RUNTIME_VERSION,br as SERVICE_WRITER,ye as SKILL_INSTALL_EVENTS_FILE_REL,C as SKILL_STATE_TARGETS,Pt as STARTER_FOLDERS,At as STARTER_FOLDER_FRONTMATTER_FILENAME,Rt as STARTER_PACKS,Qe as STARTER_PACK_IDS,T as STARTER_TEMPLATES,vn as STATE_MANIFEST_FILENAME,v as STATE_SCHEMA_VERSION,r as SYSTEM_DOC_NAME,zr as SeedPrerequisiteError,lr as SeedRootDirError,f as ServerLockCollisionError,Or as SingleFileNotAFileError,Rn as SingleFileNotFoundError,Zt as SingleFileNotMarkdownError,mr as StateManifestError,Nr as TagIndex,cn as UiLockCollisionError,$n as __getShowAllWalkStatsForTesting,Wr as __resetShowAllWalkStatsForTesting,a as acquireProcessLock,g as acquireServerLock,pn as acquireUiLock,Cn as applyAgentMarkdownWrite,yr as applyExternalChange,ir as applySeed,Nn as armPaneTarget,On as assertCompatibleStateManifest,Kt as assertGitAvailable,Yr as assertNeverDiskEvent,ui as attachIdleShutdown,nn as bootServer,ai as buildAndOpenSkill,dt as buildConfigYmlContent,U as buildExecResult,ei as buildSkillZip,gt as buildStarterFolderFrontmatterYaml,$ as buildWipTree,J as classifyEvents,Ke as classifyFsPath,Jn as clearArmedPaneTarget,N as clearContributors,Un as clearEmbeddingsKeyFromAllBackends,Ie as coercePackId,e as colorFromSeed,Ve as commitUpstreamImport,Ze as commitWip,ie as commitWipFromTree,ve as compareSemver,je as containsConflictMarkers,ot as contentHash,hi as contributorCount,R as countShadowObjects,Tt as countStaleAgentWipRefs,pe as countWipRefs,bt as createApiExtension,kt as createAssetServeMiddleware,ce as createContentFilter,Ee as createContentFilterAsync,Cr as createEmbeddingsSecretStore,Se as createEphemeralProjectDir,Lt as createExternalChangeHandler,Nt as createFileLogger,Vt as createLiveDerivedIndexExtension,tt as createMcpHttpHandler,O as createOsProbe,gn as createPersistenceExtension,Lr as createServer,sr as createServerObserverExtension,Er as createStreamingErrorWriter,In as createTestLogger,Yt as describeStoredEmbeddingsKey,fr as detectClaudeDesktopPresence,jr as detectGit,on as detectProjectShape,Zn as emitPreflightFailureSpan,Hr as encodeDocName,dn as encodeFolderRoute,xn as ensureProjectGit,_r as errorResponse,nr as evictStaleTrackerEntries,jn as extractWikiLinksFromMarkdown,En as fallbackPaths,Wt as findEnclosingGitRoot,qr as findEnclosingProjectRoot,ci as flushFileLogger,en as formatAuthRejectionWire,ri as formatContributors,lt as formatContributorsFrom,V as gcCheckpointRefs,Qr as getCurrentMcpLogger,mt as getLocalDir,Z as getLogFilePath,K as getLogger,We as getLogsDir,Kn as getMeter,j as getMetrics,Vn as getTracer,Pe as handleCollabSocketError,ze as handleSpawnCursor,Ye as hasGcLogLatch,i as iconFromClientName,ne as incrementCollabSocketFilteredError,ge as incrementServerObserverFire,ke as initContent,it as initShadowRepo,pi as initTelemetry,I as initToleranceTelemetryWriter,Ct as installPrettyZodErrors,de as installTestLoggers,vt as installUserSkill,Dt as isAllowedApiOrigin,oe as isAllowedWorkspaceHostHeader,we as isConfigDoc,xr as isHocuspocusAuthRejectionReason,be as isKnownPackId,Ft as isLoopbackAddress,n as isOrphanMode,jt as isPairedWriteOrigin,zt as isPathWithinDir,y as isProcessAlive,$e as isProjectRoot,E as isSelfWrite,_n as isSystemDoc,Rr as isToleranceTelemetryEnabled,s as isValidLockPid,cr as lastKnownHash,Dr as listRescueCheckpoints,Ln as listStarterPacks,Xt as loadPrincipal,p as lockFilePath,pr as loggerFactory,Mr as logsCurrentPath,sn as logsPreviousPath,Qn as makeLazyEmbeddingsKeyStore,Ur as mountMcpAndApi,fn as normalizeFsPath,Sn as packageVersionMajorMinor,vr as parseAuthRejectionWire,rr as parseGitVersion,Mn as parseHocuspocusAuthToken,Dn as parseKeepaliveConnectionId,Gt as pathToDocName,Jr as planSeed,li as prepareSingleFileOpen,tn as readAllTargets,ii as readArmedPaneTarget,ut as readBranchFromHead,S as readProcessLock,c as readProcessLockDetailed,H as readProjectLocalSemanticConfig,l as readServerLock,$r as readServerPackageVersion,ht as readSkillInstallStateSnapshot,Q as readStateManifest,q as readTargetRecordedAt,Ge as readTargetVersion,qn as readUiLock,M as reconcile,Hn as recordContributor,Fe as recordSkillInstallEvent,Be as registerAllTools,Xe as registerWrite,_ as releaseProcessLock,m as releaseServerLock,re as releaseUiLock,_e as removeLastKnownHash,Ae as resetMetrics,at as resolveBundledSkillDir,mi as resolveContentDir,L as resolveCursorBinaryDefault,wt as resolveCursorSpawnInvocation,fe as resolveLockDir,yt as resolvePack,Ot as resolvePackageVersion,se as resolveUiInfo,Te as restoreContributors,Sr as restoreLifecycleFromConflictsJson,xe as rewriteMarkdownLinksForDocumentRename,It as rewriteWikiLinksForDocumentRename,Mt as runAuthReposSubprocess,Bt as runAuthStatusSubprocess,et as runCloneSubprocess,D as runDeviceFlowSubprocess,hn as runWithMcpLogger,Ir as safeContentPath,or as safeSubdir,Tr as safetyCheckpoint,Fn as sanitizeClientName,Jt as saveInMemoryCheckpoint,dr as saveVersion,Ar as seedBasenameIndex,an as serializeError,Xn as setActiveSpanAttributes,Vr as shadowGit,un as shutdownTelemetry,bn as spansCurrentPath,gr as spansPreviousPath,tr as spawnDetached,An as splitMarkdownBlocks,Tn as startWatcher,Ut as streamingProblemEvent,Kr as swapContributors,si as teardownToleranceTelemetryWriter,$t as toBroadcasterKey,ni as tracedAppendFileSync,ct as tracedLinkSync,B as tracedMkdir,Zr as tracedMkdirSync,pt as tracedRename,X as tracedRenameSync,G as tracedRmSync,Ue as tracedRmdirSync,Gn as tracedUnlinkSync,A as tracedWriteFile,Bn as tracedWriteFileSync,Ne as updateLastKnownHash,d as updateProcessLockPort,u as updateServerLockPort,Re as updateUiLockPort,Je as validateAgentId,te as validateCloneInputs,he as validateSkillZip,Oe as withSpan,rt as withSpanSync,fi as writeRootGitignoreForNewRepo,F as writeStateManifest,St as writeTargetVersion,ue as writeTracker};
|
|
@@ -1685,7 +1685,94 @@ description: When the agent does scheduled work: daily briefings, end-of-day dos
|
|
|
1685
1685
|
|
|
1686
1686
|
- Run OK's \`links({ kind: "dead" })\` across the vault. Triage redlinks into new entities (agents create dossiers through OK), typo fixes (OK edits in place), or removal (drop the link; a tracked task captures any future-doc intent).
|
|
1687
1687
|
|
|
1688
|
-
`,
|
|
1688
|
+
`,OKF_FOLDERS=[{path:`concepts`,title:`Concepts`,description:"Durable ideas and definitions, one file per concept. Each doc carries `type: concept` in its frontmatter. Link related concepts so the graph builds itself.",tags:[`concept`,`okf`],starterTemplate:`concept`},{path:`references`,title:`References`,description:"External sources and citations you rely on, one file per source. Each doc carries `type: reference`. Link the docs that cite a reference so the evidence trail stays navigable.",tags:[`reference`,`okf`],starterTemplate:`reference`},{path:`notes`,title:`Notes`,description:"Working notes and observations, one file per note. Each doc carries `type: note`. The lightest section — capture first, link as ideas connect.",tags:[`note`,`okf`],starterTemplate:`note`}],OKF_TEMPLATES={concept:`---
|
|
1689
|
+
title: Concept Name
|
|
1690
|
+
description: One-line definition of the concept.
|
|
1691
|
+
---
|
|
1692
|
+
---
|
|
1693
|
+
type: concept
|
|
1694
|
+
created: {{date}}
|
|
1695
|
+
author: {{user}}
|
|
1696
|
+
tags: [concept]
|
|
1697
|
+
---
|
|
1698
|
+
|
|
1699
|
+
## Definition
|
|
1700
|
+
|
|
1701
|
+
## Why it matters
|
|
1702
|
+
|
|
1703
|
+
## Related
|
|
1704
|
+
|
|
1705
|
+
- Link a related idea, e.g. [another concept](./another-concept.md).
|
|
1706
|
+
`,reference:`---
|
|
1707
|
+
title: Reference Title
|
|
1708
|
+
description: One-line summary of the source.
|
|
1709
|
+
---
|
|
1710
|
+
---
|
|
1711
|
+
type: reference
|
|
1712
|
+
created: {{date}}
|
|
1713
|
+
author: {{user}}
|
|
1714
|
+
tags: [reference]
|
|
1715
|
+
---
|
|
1716
|
+
|
|
1717
|
+
## Summary
|
|
1718
|
+
|
|
1719
|
+
## Key points
|
|
1720
|
+
|
|
1721
|
+
## Where this is used
|
|
1722
|
+
|
|
1723
|
+
- Link the docs that cite this reference.
|
|
1724
|
+
`,note:`---
|
|
1725
|
+
title: Note Title
|
|
1726
|
+
description: One-line summary of the note.
|
|
1727
|
+
---
|
|
1728
|
+
---
|
|
1729
|
+
type: note
|
|
1730
|
+
created: {{date}}
|
|
1731
|
+
author: {{user}}
|
|
1732
|
+
tags: [note]
|
|
1733
|
+
---
|
|
1734
|
+
|
|
1735
|
+
## Note
|
|
1736
|
+
|
|
1737
|
+
## Links
|
|
1738
|
+
`},OKF_WELCOME_MD=`---
|
|
1739
|
+
title: Welcome
|
|
1740
|
+
description: Start here — what this knowledge base is and how it is organized.
|
|
1741
|
+
type: Document
|
|
1742
|
+
tags: [welcome]
|
|
1743
|
+
---
|
|
1744
|
+
|
|
1745
|
+
# Welcome
|
|
1746
|
+
|
|
1747
|
+
This knowledge base was scaffolded with the **OKF starter pack**, so it is conformant with the Open Knowledge Format (OKF) from the first commit.
|
|
1748
|
+
|
|
1749
|
+
## How it is organized
|
|
1750
|
+
|
|
1751
|
+
- [index](./index.md) — the navigation hub (a reserved OKF file; carries no frontmatter).
|
|
1752
|
+
- [log](./log.md) — the change history (a reserved OKF file; carries no frontmatter).
|
|
1753
|
+
- [concepts/](./concepts/), [references/](./references/), [notes/](./notes/) — your content. Every document here carries a non-empty \`type\` in its frontmatter.
|
|
1754
|
+
|
|
1755
|
+
## The one rule
|
|
1756
|
+
|
|
1757
|
+
OKF requires exactly one thing of every non-reserved document: a non-empty \`type\`. The value is yours to choose — \`concept\`, \`reference\`, \`note\`, or anything that fits. \`Document\` is a fine generic fallback.
|
|
1758
|
+
|
|
1759
|
+
See the project skill for the full set of conventions.
|
|
1760
|
+
`,OKF_INDEX_MD=`# Index
|
|
1761
|
+
|
|
1762
|
+
The navigation hub for this knowledge base. Start with [welcome](./welcome.md), then explore by section.
|
|
1763
|
+
|
|
1764
|
+
## Sections
|
|
1765
|
+
|
|
1766
|
+
- [welcome](./welcome.md) — what this knowledge base is and how it is organized
|
|
1767
|
+
- [concepts/](./concepts/) — durable ideas and definitions, one file per concept (\`type: concept\`)
|
|
1768
|
+
- [references/](./references/) — sources and citations you rely on (\`type: reference\`)
|
|
1769
|
+
- [notes/](./notes/) — working notes and observations (\`type: note\`)
|
|
1770
|
+
|
|
1771
|
+
Every document outside this file and \`log.md\` carries a non-empty \`type\` in its frontmatter — that is all OKF requires.
|
|
1772
|
+
`,OKF_LOG_MD=`# Log
|
|
1773
|
+
|
|
1774
|
+
Change history for this knowledge base, newest entry first. Add a dated entry (\`## YYYY-MM-DD: <summary>\`) whenever you create, edit, or restructure content — one entry per working session, not per file.
|
|
1775
|
+
`,STARTER_PACKS={"knowledge-base":{id:`knowledge-base`,name:`Knowledge base`,description:`Trusted articles from your sources.`,defaultSubfolder:`brain`,folders:KNOWLEDGE_BASE_FOLDERS,templates:KNOWLEDGE_BASE_TEMPLATES,rootFiles:{"log.md":KNOWLEDGE_BASE_LOG_MD}},"software-lifecycle":{id:`software-lifecycle`,name:`Software lifecycle`,description:`Proposals, decisions, and specs.`,defaultSubfolder:`project-docs`,folders:SOFTWARE_LIFECYCLE_FOLDERS,templates:SOFTWARE_LIFECYCLE_TEMPLATES},"plain-notes":{id:`plain-notes`,name:`Plain notes`,description:`Notes and daily entries.`,defaultSubfolder:void 0,folders:PLAIN_NOTES_FOLDERS,templates:PLAIN_NOTES_TEMPLATES},worldbuilding:{id:`worldbuilding`,name:`Worldbuilding`,description:`A wiki for your story world.`,defaultSubfolder:`world`,folders:WORLDBUILDING_FOLDERS,templates:WORLDBUILDING_TEMPLATES},"writing-pipeline":{id:`writing-pipeline`,name:`Writing pipeline`,description:`From first draft to finished piece.`,defaultSubfolder:`writing`,folders:WRITING_PIPELINE_FOLDERS,templates:WRITING_PIPELINE_TEMPLATES},"entity-vault":{id:`entity-vault`,name:`Personal CRM`,description:`Track the people, companies, and meetings.`,defaultSubfolder:`vault`,folders:ENTITY_VAULT_FOLDERS,templates:ENTITY_VAULT_TEMPLATES,rootFiles:{"log.md":ENTITY_VAULT_LOG_MD,"USER.md":ENTITY_VAULT_USER_MD,"SOUL.md":ENTITY_VAULT_SOUL_MD,"ACCESS_POLICY.md":ENTITY_VAULT_ACCESS_POLICY_MD,"HEARTBEAT.md":ENTITY_VAULT_HEARTBEAT_MD}},okf:{id:`okf`,name:`OKF starter`,description:`An Open Knowledge Format–conformant knowledge base.`,defaultSubfolder:void 0,folders:OKF_FOLDERS,templates:OKF_TEMPLATES,rootFiles:{"welcome.md":OKF_WELCOME_MD,"index.md":OKF_INDEX_MD,"log.md":OKF_LOG_MD}}},STARTER_PACK_IDS=Object.keys(STARTER_PACKS);function resolvePack(e){return e&&STARTER_PACKS[e]||STARTER_PACKS[DEFAULT_PACK_ID]}function isKnownPackId(e){return typeof e==`string`&&STARTER_PACK_IDS.includes(e)}function coercePackId(e){return isKnownPackId(e)?e:void 0}function deriveFolderSummary(e){let t=e.trim(),s=(/^([^.!?]+[.!?])/.exec(t)?.[1]??t).trim();return s.length<=140?s:`${s.slice(0,137)}…`}function listStarterPacks(){return STARTER_PACK_IDS.map(e=>{let t=STARTER_PACKS[e];return{id:t.id,name:t.name,description:t.description,defaultSubfolder:t.defaultSubfolder,folders:t.folders.map(e=>({path:e.path,summary:deriveFolderSummary(e.description)})),entryCounts:computePackEntryCounts(t)}})}function computePackEntryCounts(e){let t=e.folders.length,s=0;for(let t of e.folders)s+=1+(t.extraTemplates?.length??0);return s+=e.rootFiles?Object.keys(e.rootFiles).length:0,{files:s,folders:t}}const STARTER_FOLDERS=KNOWLEDGE_BASE_FOLDERS,STARTER_TEMPLATES=KNOWLEDGE_BASE_TEMPLATES,LOG_MD_TEMPLATE=KNOWLEDGE_BASE_LOG_MD,STARTER_FOLDER_FRONTMATTER_FILENAME=`frontmatter.yml`;function buildStarterFolderFrontmatterYaml(e){let t=[];t.push(`title: ${yamlScalar(e.title)}`),t.push(`description: ${yamlScalar(e.description)}`),t.push(`tags:`);for(let s of e.tags)t.push(` - ${yamlScalar(s)}`);return`${t.join(`
|
|
1689
1776
|
`)}\n`}function yamlScalar(e){return e===``?`""`:/[:#\n"'\\]|^\s|\s$/.test(e)?`"${e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`:e}function resolveFileContent(e,t){let s=/^([^/]+)\/\.ok\/frontmatter\.yml$/.exec(e);if(s){let e=t.folders.find(e=>e.path===s[1]);return e?buildStarterFolderFrontmatterYaml(e):void 0}let g=/^([^/]+)\/\.ok\/templates\/([^/]+)\.md$/.exec(e);if(g){let e=g[2]??``;return t.templates[e]}if(!e.includes(`/`)&&t.rootFiles?.[e]!==void 0)return t.rootFiles[e]}async function applySeed(e,t={}){let s=Date.now(),g=resolve(t.projectDir??process.cwd()),S=resolvePack(t.packId??`knowledge-base`),w=0,E=[],D=[];for(let t of e.created)try{let e=assertEntryPathInProject(g,t.path);D.push({entry:t,absPath:e})}catch(e){E.push({path:typeof t.path==`string`?t.path:String(t.path),error:e instanceof SeedRootDirError||e instanceof Error?e.message:String(e)})}for(let{entry:e,absPath:t}of D.filter(e=>e.entry.kind===`folder`))try{mkdirSync(t,{recursive:!0}),w+=1}catch(t){E.push({path:e.path,error:t instanceof Error?t.message:String(t)})}for(let{entry:e,absPath:t}of D.filter(e=>e.entry.kind===`file`)){let s=e.template??e.path,g=resolveFileContent(s,S);if(g===void 0){E.push({path:e.path,error:`No content template registered for template id "${s}" in pack "${S.id}"`});continue}if(!existsSync(t))try{writeFileSync(t,g,`utf-8`),w+=1}catch(t){E.push({path:e.path,error:t instanceof Error?t.message:String(t)})}}let O=installPackSkill(g,S.id);return{applied:w,errors:E,durationMs:Date.now()-s,packSkillsInstalled:O}}function frontmatterTemplateId(e){return`${e}/.ok/frontmatter.yml`}function templateFileTemplateId(e,t){return`${e}/.ok/templates/${t}.md`}function normalizeRootDir(e,t){if(!e)return``;let s=e.trim();if(s===``||s===`.`||s===`./`)return``;if(s.startsWith(`/`))throw new SeedRootDirError(`rootDir must be relative to the project directory, got: ${e}`);let g=s.replace(/\\/g,`/`).replace(/^\.\//,``).replace(/\/+$/,``);if(g.split(`/`).some(e=>e===`..`))throw new SeedRootDirError(`rootDir must not contain '..' segments, got: ${e}`);return assertEntryPathInProject(t,g),g}function joinRelative(e,t){return e===``?t:`${e}/${t}`}async function planSeed(e={}){let t=resolve(e.projectDir??process.cwd());if(!isProjectRoot(t))throw new SeedPrerequisiteError(`No ${OK_PROJECT_MARKER} found at ${t}. Run \`ok init\` first to scaffold the tool config.`);let s=normalizeRootDir(e.rootDir,t),g=resolvePack(e.packId??`knowledge-base`),S=[],w=[],E=[];s!==``&&(existsSync(join(t,s))?w.push({path:s,reason:`already-exists`}):S.push({path:s,kind:`folder`}));for(let e of g.folders){let D=joinRelative(s,e.path);existsSync(join(t,D))?w.push({path:D,reason:`already-exists`}):S.push({path:D,kind:`folder`});let O=`${D}/.ok`;existsSync(join(t,O))?w.push({path:O,reason:`already-exists`}):S.push({path:O,kind:`folder`});let k=`${O}/${STARTER_FOLDER_FRONTMATTER_FILENAME}`;existsSync(join(t,k))?w.push({path:k,reason:`already-exists`}):S.push({path:k,kind:`file`,template:frontmatterTemplateId(e.path)});let j=`${O}/templates`;existsSync(join(t,j))?w.push({path:j,reason:`already-exists`}):S.push({path:j,kind:`folder`});let F=[e.starterTemplate,...e.extraTemplates??[]];for(let s of F){let D=`${j}/${s}.md`;if(existsSync(join(t,D))){w.push({path:D,reason:`already-exists`});continue}if(g.templates[s]===void 0){let t=s===e.starterTemplate;E.push(t?`No starter template body registered for "${s}" in pack "${g.id}". The folder will land without a pre-selected template.`:`No body registered for extra template "${s}" in pack "${g.id}". The folder will land without that optional variant.`);continue}S.push({path:D,kind:`file`,template:templateFileTemplateId(e.path,s)})}}if(g.rootFiles)for(let e of Object.keys(g.rootFiles)){let g=joinRelative(s,e);existsSync(join(t,g))?w.push({path:g,reason:`already-exists`}):S.push({path:g,kind:`file`,template:e})}return{created:S,skipped:w,warnings:E}}function createSingleFlight(){let e=new Map;return{run(t,s){let g=e.get(t);if(g)return{promise:g,coalesced:!0};let S=s();e.set(t,S);let w=()=>{e.get(t)===S&&e.delete(t)};return S.then(w,w),{promise:S,coalesced:!1}},get size(){return e.size}}}const log$7=getLogger(`suggest-links`),WORD_CHAR_RE=/[\p{L}\p{N}]/u,WIKI_LINK_RE=/\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/y,MD_LINK_RE=/\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y,MD_IMAGE_RE=/!\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y;var SuggestLinksTargetNotFoundError=class extends Error{constructor(e){super(`Document not found: ${e}`),this.name=`SuggestLinksTargetNotFoundError`}};function normalizeSnippet(e){return e.replace(/\s+/g,` `).trim()}function snippetAround(e,t,s){if(!normalizeSnippet(e))return null;let g=Math.max(e.lastIndexOf(`.`,t-1),e.lastIndexOf(`?`,t-1),e.lastIndexOf(`!`,t-1),e.lastIndexOf(`
|
|
1690
1777
|
`,t-1)),S=[e.indexOf(`.`,s),e.indexOf(`?`,s),e.indexOf(`!`,s),e.indexOf(`
|
|
1691
1778
|
`,s)].filter(e=>e>=0),w=g>=0?g+1:Math.max(0,t-60),E=S.length>0?Math.min(...S)+1:Math.min(e.length,s+60),D=w>0?`…`:``,O=E<e.length?`…`:``,k=normalizeSnippet(e.slice(w,E));return k?`${D}${k}${O}`:null}function matchFence(e){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(!t)return null;let s=t[1],g=s[0];return g!=="`"&&g!==`~`?null:{char:g,length:s.length}}function isFenceClose(e,t){let s=e.trimStart();if(e.length-s.length>3)return!1;let g=0;for(;s[g]===t.char;)g+=1;return g<t.length?!1:s.slice(g).trim().length===0}function leadingMarkdownPrefixLength(e){let t=/^\s{0,3}(?:#{1,6}\s+|>\s+|(?:[-+*]|\d+[.)])\s+)/.exec(e);return t?t[0].length:0}function readInlineCode(e,t){let s=0;for(;e[t+s]==="`";)s++;if(s===0)return null;let g=t+s,S=g;for(;S<e.length;){if(e[S]!=="`"){S+=1;continue}let t=0;for(;e[S+t]==="`";)t+=1;if(t===s)return{text:e.slice(g,S),nextIndex:S+s};S+=t}return{text:e.slice(t,g),nextIndex:g}}function readWikiLink(e,t){WIKI_LINK_RE.lastIndex=t;let s=WIKI_LINK_RE.exec(e);if(!s)return null;let g=s[1]??``,S=g.trim(),w=s[2]?.trim()||null,E=s[3]??null,D=E?.trim()||null;if(!S)return null;let O=D??S,k=D?E:g,j=D?s[0].lastIndexOf(E??``):2,F=k?.indexOf(O)??0;return{target:S,alias:D,anchor:w,label:O,labelStart:t+j+Math.max(F,0),nextIndex:t+s[0].length}}function normalizeMarkdownHref(e){return e.startsWith(`<`)&&e.endsWith(`>`)?e.slice(1,-1):e}function readMarkdownLink(e,t){MD_LINK_RE.lastIndex=t;let s=MD_LINK_RE.exec(e);return s?{text:s[1]??``,href:normalizeMarkdownHref(s[2]??``),nextIndex:t+s[0].length}:null}function readMarkdownImage(e,t){MD_IMAGE_RE.lastIndex=t;let s=MD_IMAGE_RE.exec(e);return s?{alt:s[1]??``,nextIndex:t+s[0].length}:null}function isWordBoundaryChar(e){return!e||!WORD_CHAR_RE.test(e)}function hasWholeWordBoundaries(e,t,s){return isWordBoundaryChar(e[t-1])&&isWordBoundaryChar(e[s])}function prepareSearchLabels(e){let t=[],s=new Set;for(let g of e.matchLabels){let e=g.trim();if(!e)continue;let S=e.toLocaleLowerCase();s.has(S)||(s.add(S),t.push({raw:e,lower:S,length:e.length}))}return t.sort((e,t)=>t.length===e.length?e.raw.localeCompare(t.raw):t.length-e.length)}function findSegmentMatches(e,t){let s=e.toLocaleLowerCase(),g=[];for(let S of t){let t=0;for(;t<=s.length-S.length;){let w=s.indexOf(S.lower,t);if(w===-1)break;let E=w+S.length;hasWholeWordBoundaries(e,w,E)&&g.push({start:w,end:E}),t=w+1}}g.sort((e,t)=>{if(e.start!==t.start)return e.start-t.start;let s=e.end-e.start,g=t.end-t.start;return g===s?e.end-t.end:g-s});let S=[],w=null;for(let e of g)w&&e.start<w.end||(S.push(e),w=e);return S}function contiguousOffsets(e,t){let s=[];for(let g=0;g<t.length;g+=1)s.push(e+g);return s}function wikiLinkResolvesToTarget(e,t){let s=e.trim();return s?s===t||toWikiLinkSlug(s)===t:!1}function scanLineForMentions(e,t,s,g,S){let w=``,E=[],D=``,O=[];function k(){D&&(E.push({flatStart:w.length,text:D,sourceOffsets:O}),w+=D,D=``,O=[])}function j(e,t){D+=e,O.push(t)}function F(e){k(),w+=e}function L(e,t){k(),e&&(E.push({flatStart:w.length,text:e,sourceOffsets:t}),w+=e)}let B=leadingMarkdownPrefixLength(e);for(;B<e.length;){if(e[B]===`\\`&&B+1<e.length){j(e[B+1]??``,t+B+1),B+=2;continue}if(e[B]==="`"){let t=readInlineCode(e,B);if(t){F(t.text),B=t.nextIndex;continue}}if(e[B]===`!`&&e[B+1]===`[`){let t=readMarkdownImage(e,B);if(t){F(t.alt),B=t.nextIndex;continue}}if(e[B]===`[`&&e[B+1]===`[`){let s=readWikiLink(e,B);if(s){let e=s.label;wikiLinkResolvesToTarget(s.target,g)?F(e):L(e,contiguousOffsets(t+s.labelStart,e)),B=s.nextIndex;continue}}if(e[B]===`[`&&e[B-1]!==`!`){let S=readMarkdownLink(e,B);if(S){resolveInternalHref(S.href,s)?.docName===g?F(S.text):L(S.text,contiguousOffsets(t+B+1,S.text)),B=S.nextIndex;continue}}j(e[B]??``,t+B),B+=1}k();let H=[];for(let e of E){let t=findSegmentMatches(e.text,S);for(let s of t){let t=e.flatStart+s.start,g=e.flatStart+s.end,S=snippetAround(w,t,g)??e.text.slice(s.start,s.end),E=e.sourceOffsets[s.start];typeof E==`number`&&H.push({excerpt:S,offset:E})}}return H}function scanMarkdownForMentions(e,t,s,g){let{frontmatter:S,body:w}=stripFrontmatter(e),E=S.length,D=[],O=null,k=0,j=0;for(;j<=w.length;){let e=w[j];if(!(j===w.length||e===`
|
|
@@ -2846,4 +2933,4 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
2846
2933
|
`))e&&await t.raw(`update-ref`,`-d`,e);Y.info({context:e.oldBranch},`[branch-switch] cleaned up detached context ${e.oldBranch}`)}}catch(e){Y.error({err:e},`[branch-switch] detached cleanup failed`)}setBatchInProgress(!1),await ye.flushDeferredStores(`discard-stale`),Te?.emitBranchSwitched(g)}if(e.headMoved&&e.newHead&&_e.current&&s>0){let t=L??`.`;try{let s=await commitUpstreamImport(_e.current,t,e.oldHead,e.newHead,g);incrementUpstreamImport(),Y.info({oldHead:e.oldHead?.slice(0,8)??`null`,newHead:e.newHead.slice(0,8),sha:s.slice(0,8)},`[history] upstream-import from ${e.oldHead?.slice(0,8)??`null`}..${e.newHead.slice(0,8)} → ${s.slice(0,8)}`)}catch(e){Y.error({err:e},`[shadow] upstream-import failed`)}}})}catch(e){Y.error({err:e},`[server] HEAD watcher failed to start`),Fr.push(`head-watcher`)}function D(e){for(let g of e)try{let e=relative(t,join(s,g));if(e.startsWith(`..`))continue;let S=stripDocExtension(e),w=Ce.documents.get(S);if(!w)continue;let E=jt(S);E===null?Y.warn({docName:S,file:g},`[sync] content conflict: serializeDoc returned null; reconciledBase snapshot skipped`):setReconciledBase(S,E);let D=w.getMap(`lifecycle`);D.set(`status`,`conflict`),D.set(`reason`,`sync-merge-conflict`),Y.info({docName:S,file:g},`[sync] marked loaded content conflict`)}catch(e){Y.warn({err:e,file:g},`[sync] failed to mark loaded content conflict`)}}let O=buildSyncCredentialArgs(H);try{$t=new SyncEngine({projectDir:s,contentDir:t,contentFilter:fe,contentRoot:L,syncEnabled:te(),credentialArgs:O,cc1Broadcaster:Te,detectGh:e.detectGh,tokenStore:e.tokenStore,checkPushPermissionFn:e.checkPushPermissionFn,setBatchInProgress:e=>{setBatchInProgress(e),e||ye.flushDeferredStores(`within-branch`).catch(e=>{Y.error({err:e},`[persistence] deferred store drain failed after sync batch`)})},onStateChange:e=>{Y.info({state:e},`[sync] state → ${e}`)},onContentConflictsDetected:D,onAutoDisable:async e=>{Y.warn({reason:e},`[sync] auto-disabled — persisting to project-local config`);let t=await writeConfigPatch({cwd:s,scope:`project-local`,patch:{autoSync:{enabled:!1}}});t.ok||Y.error({result:t,reason:e,humanError:humanFormat(t.error),configPath:resolveConfigPath(`project-local`,s)},`[sync] failed to persist auto-disable — next restart WILL re-enable sync and re-trigger the same failure. Check permissions on the config path.`)}}),await $t.start()}catch(e){Y.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),$t=null}Ke(`files`),Ke(`backlinks`),Ke(`graph`),Ke(`tags`)}return Ir().then(Ue,We),{hocuspocus:Ce,sessionManager:we,cc1Broadcaster:Te,agentFocusBroadcaster:De,agentPresenceBroadcaster:je,maintenanceCoordinator:ve,contentFilter:fe,basenameIndex:ce,serverInstanceId:oe,destroy:Mr,ready:Ge,degraded:Fr,lockDir:se,get syncEngine(){return $t}}}const SERVER_MEMORY_SCHEMA_VERSION=1,BYTES_PER_MB=1024*1024;function toMb(e){return e/BYTES_PER_MB}function captureServerMemorySnapshot(){let e=process.memoryUsage();return{schemaVersion:SERVER_MEMORY_SCHEMA_VERSION,capturedAt:new Date().toISOString(),snapshot:{rssMb:toMb(e.rss),heapTotalMb:toMb(e.heapTotal),heapUsedMb:toMb(e.heapUsed),externalMb:toMb(e.external),arrayBuffersMb:toMb(e.arrayBuffers)}}}let cachedGauge=null;onTelemetryShutdown(()=>{cachedGauge=null});function installServerMemoryGauge(){if(cachedGauge)return;let e=getMeter().createObservableGauge(`ok.server.memory.usage_megabytes`,{description:`Server process memory by section. Bounded labels: section ∈ {heap_used, heap_total, rss}.`,unit:`MB`});e.addCallback(e=>{let{snapshot:t}=captureServerMemorySnapshot();e.observe(t.heapUsedMb,{section:`heap_used`}),e.observe(t.heapTotalMb,{section:`heap_total`}),e.observe(t.rssMb,{section:`rss`})}),cachedGauge=e}const TELEMETRY_FILENAME=`tolerance-telemetry.jsonl`,TELEMETRY_PREV_FILENAME=`tolerance-telemetry.prev.jsonl`,TELEMETRY_MAX_BYTES=8*1024*1024;let appender=null,appendFailureWarned=!1;function isToleranceTelemetryEnabled(e=process.env){return e.OK_BRIDGE_TOLERANCE_TELEMETRY===`1`}function initToleranceTelemetryWriter(e){if(!isToleranceTelemetryEnabled())return;let t=getLocalDir(e);appender=new RotatingAppender({currentPath:resolve(t,TELEMETRY_FILENAME),previousPath:resolve(t,TELEMETRY_PREV_FILENAME),maxBytes:TELEMETRY_MAX_BYTES}),setToleranceTelemetryHook(e=>{let t={event:`bridge-tolerance-fire`,timestamp:e.timestamp,class:e.className,document:e.documentName??null,codeUnitPosition:e.codeUnitPosition,severity:e.severity};appender?.append(`${JSON.stringify(t)}\n`).catch(e=>{appendFailureWarned||(appendFailureWarned=!0,console.warn(`[tolerance-telemetry] append failed; further failures are silent:`,e instanceof Error?e.message:String(e)))})})}async function teardownToleranceTelemetryWriter(){setToleranceTelemetryHook(null),await appender?.drain(),appender=null,appendFailureWarned=!1}const LEGACY_RUNTIME_FILENAMES=[`server.lock`,`ui.lock`,`state.json`,`principal.json`,`sync-state.json`,`conflicts.json`,`last-spawn-error.log`],LEGACY_RUNTIME_DIRNAMES=[`cache`,`tmp`];function findLegacyRuntimeFiles(e){let t=resolve(e,LOCAL_DIR);if(!(()=>{if(!existsSync(t))return!0;try{return readdirSync(t).length===0}catch{return!0}})())return[];let s=[];for(let t of LEGACY_RUNTIME_FILENAMES)existsSync(resolve(e,t))&&s.push(t);for(let t of LEGACY_RUNTIME_DIRNAMES){let g=resolve(e,t);try{existsSync(g)&&statSync(g).isDirectory()&&s.push(`${t}/`)}catch{}}return s}function computeWorktreeAttributes(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return{kind:`main`,gitdir:t.path};case`linked`:return{kind:`linked`,gitdir:t.path};case`malformed-pointer`:return{kind:`linked`,gitdir:null};case`inaccessible`:case`absent`:return{kind:`main`,gitdir:null}}}const DEFAULT_IDLE_THRESHOLD_MS=1800*1e3,DESTROY_STEP_TIMEOUT_MS=5e3,PINO_REDACT_MAX_DEPTH=5;async function bootServer(e){let t=e.projectDir??e.contentDir,s=resolveLocalSinkConfig({projectDir:t});if(s){let e=s.telemetry.attributeDenylist,t=[];for(let s of e){t.push(s);for(let e=1;e<=PINO_REDACT_MAX_DEPTH;e++)t.push(`${`*.`.repeat(e)}${s}`)}loggerFactory.configure({pinoConfig:{fileSink:s.logs,redactPaths:t}})}initTelemetry({localSink:s?.telemetry}),initToleranceTelemetryWriter(t),installServerMemoryGauge();let{kind:g,gitdir:S}=computeWorktreeAttributes(e.projectDir??e.contentDir),w={"ok.worktree.kind":g};return S!==null&&(w[`ok.worktree.gitdir`]=normalizeFsPath(S)),withSpan(`ok.boot`,{attributes:w},async()=>bootServerInner(e))}async function bootServerInner(e){let t=e.skipAutoInit??!1,s=e.attachUiSibling??!0,g=e.idleShutdownMs,S=e.log??getLogger(`boot`),w=process.env.OK_LOCK_KIND===`mcp-spawned`||process.env.OK_LOCK_KIND===`interactive`?process.env.OK_LOCK_KIND:void 0,E=e.lockKind??w??`interactive`,{createServer:D}=await import(`node:http`),{updateServerLockPort:O}=await import(`./server-lock-CyhBidkz-DUTkjNDG.mjs`),k=!1;if(!t&&e.autoInitFn)try{k=!!await e.autoInitFn()}catch(e){S.warn({err:e},`autoInitFn failed`)}let j=e.projectDir??e.contentDir,F=resolve(j,`.ok`);if(!existsSync(resolve(F,`config.yml`)))throw new MissingOkConfigError(existsSync(F)?`config`:`okdir`,j);existsSync(resolve(F,`.gitignore`))||console.warn("[boot] Note: .ok/.gitignore is missing — per-machine state files in .ok/ may show up as untracked changes. Run `ok init` to add the recommended ignore entries.");let L=e.gitPreflight??assertGitAvailable;try{e.gitEnabled!==!1&&L()}catch(e){if(e instanceof GitNotAvailableError||e instanceof GitTooOldError){let t=e instanceof GitTooOldError?e.detected:``,s=e instanceof GitTooOldError?`too_old`:`not_available`;emitPreflightFailureSpan(e),S.warn({event:`git_preflight_fail`,platform:e.platform,reason:s,detectedVersion:t},s===`not_available`?`git binary not found`:`git binary too old`),process.stderr.write(`${e.message}\n`)}throw await shutdownTelemetry(),await Promise.race([teardownToleranceTelemetryWriter(),new Promise(e=>setTimeout(e,DESTROY_STEP_TIMEOUT_MS))]),e}let B=findLegacyRuntimeFiles(F);B.length>0&&console.warn(`[boot] Found legacy runtime files at .ok/${B.join(`, `)}. Delete .ok/ and re-init — these files moved to .ok/${LOCAL_DIR}/.`);let H=createServer$1({contentDir:e.contentDir,projectDir:e.projectDir,contentRoot:e.contentRoot,port:e.port,host:e.host,quiet:e.quiet??!1,debounce:e.debounce,maxDebounce:e.maxDebounce,gitEnabled:e.gitEnabled,commitDebounceMs:e.commitDebounceMs,wipRef:e.wipRef,enableTestRoutes:e.enableTestRoutes,shadowRepo:e.shadowRepo,destroyTimeoutMs:e.destroyTimeoutMs,localOpCliArgs:e.localOpCliArgs,onAgentWrite:e.onAgentWrite,lockKind:E,skipStateManifestCheck:e.skipStateManifestCheck,detectGh:e.detectGh,tokenStore:e.tokenStore,embeddingsKeyStore:e.embeddingsKeyStore,singleDocRelPath:e.singleDocRelPath,ephemeral:e.ephemeral}),{hocuspocus:q,destroy:ee,ready:J,degraded:Y,lockDir:te,sessionManager:ne,agentFocusBroadcaster:ae,agentPresenceBroadcaster:oe,maintenanceCoordinator:se}=H,ce=(()=>{let t=e.host??`localhost`;return t===`0.0.0.0`||t===`::`?`localhost`:t.includes(`:`)&&!t.startsWith(`[`)?`[${t}]`:t})(),ue=e.port??0,de=e.ephemeral?void 0:createMcpHttpHandler({contentDir:e.contentDir,projectDir:e.projectDir??e.contentDir,config:e.config,getServerUrl:()=>`http://${ce}:${ue}`,log:S}),fe=D();fe.headersTimeout=3e4,fe.requestTimeout=6e4;let me=e.serveContentAssets?createAssetServeMiddleware({contentFilter:H.contentFilter,contentSirv:build_default(e.contentDir,{dev:!0,dotfiles:!1}),inlineExtensions:INLINE_RENDERABLE_EXTENSIONS,assetExtensions:ASSET_EXTENSIONS,blocklistExtensions:EXECUTABLE_BLOCKLIST_EXTENSIONS}):void 0,ge=!1;if(e.reactShellDistDir)try{acquireUiLock(te,{port:0,worktreeRoot:e.projectDir??e.contentDir}),ge=!0}catch(e){if(e instanceof UiLockCollisionError)S.info({event:`ui-lock-yielded-to-live-holder`,pid:process.pid,existingPid:e.existing.pid,existingPort:e.existing.port,lockDir:te},`ui.lock already held by a live process — yielding (advertisement is fulfilled)`);else throw await ee().catch(()=>{}),e}let _e=e.reactShellDistDir?build_default(e.reactShellDistDir,{single:!0,gzip:!0,immutable:!0}):void 0,ve=mountMcpAndApi({httpServer:fe,hocuspocus:q,mcpHttpHandler:de,log:S,sessionManager:ne,agentFocusBroadcaster:ae,agentPresenceBroadcaster:oe,maintenanceCoordinator:se,keepaliveGraceMs:e.keepaliveGraceMs,contentAssetMiddleware:me,reactShellMiddleware:_e,ephemeral:e.ephemeral}),ye=async()=>{throw Error(`bootServer: destroy() invoked before initialization — boot did not complete`)},Ce=null;g!==null&&(Ce=attachIdleShutdown({httpServer:fe,thresholdMs:g??DEFAULT_IDLE_THRESHOLD_MS,log:S,onShutdown:(e.idleShutdownHandler??(e=>async()=>{await e()}))(async()=>{await ye()})})),await restoreLifecycleFromConflictsJson({hocuspocus:q,projectDir:e.projectDir??e.contentDir,log:S});try{await new Promise((t,s)=>{let g=e=>s(e);fe.once(`error`,g),fe.listen(e.port,e.host,()=>{fe.removeListener(`error`,g),t()})})}catch(e){if(ge)try{releaseUiLock(te)}catch(e){S.warn({err:e},`releaseUiLock failed during listen-error cleanup`)}throw await ee().catch(()=>{}),e}let we=fe.address(),Te=typeof we==`object`&&we?we.port:e.port??0;if(ue=Te,O(te,Te),ge&&updateUiLockPort(te,Te),s&&e.spawnUiSiblingFn)try{await e.spawnUiSiblingFn({lockDir:te,log:S})}catch(e){S.warn({err:e},`spawnUiSiblingFn failed`)}let De=!1,je=async(e,t)=>{let s;try{await Promise.race([t(),new Promise((t,g)=>{s=setTimeout(()=>{g(Error(`${e} timed out after ${DESTROY_STEP_TIMEOUT_MS}ms`))},DESTROY_STEP_TIMEOUT_MS),s.unref?.()})])}finally{s!==void 0&&clearTimeout(s)}};return ye=async()=>{if(De)return;De=!0;let e=[],t=async(t,s)=>{try{await je(t,s)}catch(s){e.push(s),S.warn({err:s,step:t},`bootServer destroy step failed`)}};try{Ce?.detach()}catch(t){e.push(t),S.warn({err:t,step:`idleHandle.detach`},`bootServer destroy step failed`)}if(await t(`mount.shutdown`,()=>ve.shutdown()),de!==void 0&&await t(`mcpHttpHandler.close`,()=>de.close()),await t(`mount.wss.close`,()=>new Promise((e,t)=>{ve.wss.close(s=>s?t(s):e())})),await t(`httpServer.closeAllConnections`,async()=>{fe.closeAllConnections?.()}),await t(`httpServer.close`,()=>new Promise((e,t)=>{fe.close(s=>s&&s.code!==`ERR_SERVER_NOT_RUNNING`?t(s):e())})),await t(`destroyHocuspocus`,()=>ee()),ge&&await t(`releaseUiLock`,async()=>releaseUiLock(te)),await t(`shutdownTelemetry`,()=>shutdownTelemetry()),await t(`teardownToleranceTelemetry`,()=>teardownToleranceTelemetryWriter()),await t(`flushLogFileSinks`,()=>loggerFactory.flushAllFileSinks()),e.length>0)throw AggregateError(e,`bootServer destroy completed with errors`)},{httpServer:fe,destroy:ye,lockDir:te,contentDir:e.contentDir,port:Te,ready:J,degraded:Y,didAutoInit:k,serverInstance:H}}async function restoreLifecycleFromConflictsJson(e){let{hocuspocus:t,projectDir:s,log:g}=e,S,w;try{S=new ConflictStore(s),w=S.list()}catch(e){g.warn({err:e,projectDir:s},`[boot] lifecycle restore: failed to read conflicts.json — skipping`);return}if(w.length===0)return;let E=null;try{let e=resolveGitDir(s),t=e?join(e,`MERGE_HEAD`):null;if(!t||!existsSync(t)){S.clear(),console.warn(JSON.stringify({event:`lifecycle-restore-cleared-stale-conflicts`,reason:`no-merge-head`,count:w.length}));return}let g=(await simpleGit({baseDir:s,timeout:{block:5e3}}).raw([`diff`,`--name-only`,`--diff-filter=U`])).trim();E=new Set(g?g.split(`
|
|
2847
2934
|
`).map(e=>e.trim()).filter(Boolean):[])}catch(e){g.warn({err:e,projectDir:s},`[boot] lifecycle restore: git unmerged probe failed — restoring all entries`)}if(E!==null){let e=0;for(let t of w)E.has(t.file)||(S.removeConflict(t.file),e++);if(e>0&&console.warn(JSON.stringify({event:`lifecycle-restore-pruned-resolved-entries`,pruned:e,remaining:w.length-e})),w=w.filter(e=>E?.has(e.file)),w.length===0)return}for(let e of w){let s=stripDocExtension(e.file),S=null,w=!1;try{S=await t.openDirectConnection(s);let e=S.document;if(!e)continue;let g=e.getMap(`lifecycle`);g.set(`status`,`conflict`),g.set(`reason`,`conflict-markers`),w=!0,console.warn(JSON.stringify({event:`lifecycle-restored-from-conflicts-json`,"doc.name":s}))}catch(e){g.warn({err:e,docName:s},`[boot] lifecycle restore: failed to set lifecycle for doc — skipping`)}finally{if(S)try{await S.disconnect()}catch(e){g.warn({err:e,docName:s,restored:w},`[boot] lifecycle restore: disconnect failed after lifecycle write`)}}}}const ConfigSchema=ConfigSchema$1;function detectClaudeDesktopPresence(e={}){let t=e.home??homedir(),s=e.platformName??process.platform,g=e.env??process.env;return s===`darwin`?existsSync(join(t,`Library`,`Application Support`,`Claude`)):s===`win32`?existsSync(join(g.APPDATA??join(t,`AppData`,`Roaming`),`Claude`)):!1}const OK_LOGS_DIR=join(homedir(),`.ok`,`logs`),MAX_ROTATED_FILES=2,MAX_AGE_DAYS=7,MAX_DIR_SIZE_BYTES=45*1024*1024,REDACT_PATHS=[`authorization`,`password`,`token`,`apiKey`,`secret`,`*.authorization`,`*.password`,`*.token`,`*.apiKey`,`*.secret`];function resolveLogLevel(){let e=process.env.OK_LOG_LEVEL??process.env.LOG_LEVEL;if(e){let t=[`fatal`,`error`,`warn`,`info`,`debug`],s=e.toLowerCase();if(t.includes(s))return s}return process.env.NODE_ENV===`test`?`silent`:`info`}function ensureDir(e){mkdirSync(e,{recursive:!0})}function todayDateString(){return new Date().toISOString().slice(0,10)}function rotateIfNeeded(e){try{if(statSync(e).size<5242880)return}catch{return}for(let t=MAX_ROTATED_FILES;t>=1;t--){let s=t===1?e:`${e}.${t-1}`,g=`${e}.${t}`;try{renameSync(s,g)}catch{}}try{unlinkSync(`${e}.${MAX_ROTATED_FILES+1}`)}catch{}}function pruneLogsDir(e){try{let t=Date.now(),s=MAX_AGE_DAYS*24*60*60*1e3,g=readdirSync(e).filter(e=>e.endsWith(`.log`)||/\.log\.\d+$/.test(e)).map(t=>{try{let s=statSync(join(e,t));return{name:t,mtime:s.mtimeMs,size:s.size}}catch{return null}}).filter(Boolean);for(let S of g)if(t-S.mtime>s)try{unlinkSync(join(e,S.name))}catch{}let S=g.filter(e=>t-e.mtime<=s).sort((e,t)=>e.mtime-t.mtime),w=S.reduce((e,t)=>e+t.size,0);for(let t of S){if(w<=MAX_DIR_SIZE_BYTES)break;try{unlinkSync(join(e,t.name)),w-=t.size}catch{}}}catch{}}function createFileLogger(e){ensureDir(OK_LOGS_DIR);let t=todayDateString(),s=e.filePath??join(OK_LOGS_DIR,`${e.name}.${t}.log`);rotateIfNeeded(s),(e._setTimeout??setTimeout)(()=>pruneLogsDir(OK_LOGS_DIR),5e3).unref();let g=import_pino.default.destination({dest:s,append:!0,sync:!0});return(0,import_pino.default)({level:resolveLogLevel(),name:e.name,redact:{paths:REDACT_PATHS,censor:`[REDACTED]`},base:{pid:process.pid,hostname:void 0,runtime:`cli`,project:e.project??`<no-project>`},timestamp:import_pino.default.stdTimeFunctions.isoTime,...e.additionalOptions},g)}function flushFileLogger(e,t=250){return new Promise(s=>{if(!e){s();return}let g=e[import_pino.default.symbols.streamSym],S=!1,w=()=>{S||(S=!0,s())};if(!g||typeof g.flushSync!=`function`){w();return}let E=()=>{try{g.flushSync?.()}catch{}w()},D=setTimeout(w,t);typeof D.unref==`function`&&D.unref(),typeof g.fd==`number`&&g.fd>=0?(clearTimeout(D),E()):typeof g.once==`function`?g.once(`ready`,()=>{clearTimeout(D),E()}):(clearTimeout(D),E())})}function getLogFilePath(e){return join(OK_LOGS_DIR,`${e}.${todayDateString()}.log`)}function getLogsDir(){return OK_LOGS_DIR}const ANCESTOR_WALK_DEPTH_LIMIT=30,GIT_MARKER=`.git`;function findEnclosingGitRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT;){let e=!1;try{e=existsSync(resolve(t,GIT_MARKER))}catch{e=!1}if(e)return{gitRoot:t,distance:s};let g=dirname(t);if(g===t)return null;t=g,s+=1}return null}const execFileAsync=promisify(execFile),log=getLogger(`project-git`);var ProjectGitInitError=class extends Error{stderr;constructor(e,t=``,s){super(e,s),this.name=`ProjectGitInitError`,this.stderr=t}};async function isInsideExistingWorkTree(e){try{let{stdout:t}=await execFileAsync(`git`,[`rev-parse`,`--is-inside-work-tree`],{cwd:e});return t.trim()===`true`}catch{return!1}}async function ensureProjectGit(e){let t=resolve(e),s=resolve(t,`.git`),g=resolve(s,`HEAD`),S=!1;if(existsSync(s)){if(!statSync(s).isDirectory()||existsSync(g))return{didInit:!1};log.info({},`detected partial .git/ — running git init to repair`),S=!0}else if(await isInsideExistingWorkTree(t))return{didInit:!1};let w=``;try{w=(await execFileAsync(`git`,[`init`,`--initial-branch=main`,t])).stderr??``}catch(e){let s=typeof e==`object`&&e&&`stderr`in e?String(e.stderr??``):``;throw new ProjectGitInitError(`git init failed at ${t}: ${e instanceof Error?e.message:String(e)}`,s,{cause:e})}if(!existsSync(g))throw new ProjectGitInitError(`git init reported success but ${s}/HEAD is missing (partial init detected)`,w);return S?(log.info({path:t},`backfilled missing .git/HEAD`),{didInit:!0,repaired:!0}):(log.info({path:t,branch:`main`},`initialized .git/`),{didInit:!0})}async function resolvePackageVersion(e,t){let s;try{s=createRequire(t).resolve(e)}catch(e){if(e?.code===`MODULE_NOT_FOUND`)return;throw e}for(let t=dirname(s),g=0;g<32;g+=1){let s=join(t,`package.json`);if(existsSync(s))try{let t=JSON.parse(await readFile$1(s,`utf-8`));if(t.name===e&&typeof t.version==`string`)return t.version}catch{}let g=dirname(t);if(g===t)return;t=g}}const MAX_CAUSE_DEPTH=5,HOME_PATH_PATTERNS=[{regex:/\/Users\/[^/]+\//g,replacement:`~/`},{regex:/\/home\/[^/]+\//g,replacement:`~/`},{regex:/C:\\\\Users\\\\[^\\\\]+\\\\/g,replacement:`~\\`},{regex:/C:\\Users\\[^\\]+\\/g,replacement:`~\\`}];function scrubPaths(e){if(e===void 0)return;let t=e;for(let{regex:e,replacement:s}of HOME_PATH_PATTERNS)t=t.replace(e,s);return t}function serializeError(e,t=0,s=new WeakSet){if(t>=MAX_CAUSE_DEPTH)return{name:`SerializedError.CauseDepthExceeded`,message:`cause chain depth > ${MAX_CAUSE_DEPTH}; truncated`};if(typeof e==`object`&&e){if(s.has(e))return{name:`SerializedError.CauseCycle`,message:`cyclic cause; truncated`};s.add(e)}if(e instanceof Error)return{name:e.name,message:scrubPaths(e.message)??``,stack:scrubPaths(e.stack),code:e.code,cause:e.cause===void 0?void 0:serializeError(e.cause,t+1,s)};if(e==null)return{name:`UnknownError`,message:String(e)};if(typeof e==`string`)return{name:`StringError`,message:scrubPaths(e)??e};if(typeof e==`object`){let g=e;return{name:String(g.name??`ObjectError`),message:scrubPaths(String(g.message??``))??``,stack:scrubPaths(g.stack),code:g.code,cause:g.cause===void 0?void 0:serializeError(g.cause,t+1,s)}}return{name:`UnknownError`,message:String(e)}}var SingleFileNotFoundError=class extends Error{constructor(e){super(`File not found: ${e}`),this.filePath=e,this.name=`SingleFileNotFoundError`}},SingleFileNotAFileError=class extends Error{constructor(e){super(`Not a file: ${e}. \`ok <file>\` opens a single markdown file.`),this.filePath=e,this.name=`SingleFileNotAFileError`}},SingleFileNotMarkdownError=class extends Error{constructor(e){super(`Open Knowledge edits markdown files (.md / .mdx): ${e}`),this.filePath=e,this.name=`SingleFileNotMarkdownError`}};function prepareSingleFileOpen(e){if(!isSupportedDocFile(e))throw new SingleFileNotMarkdownError(e);let t;try{t=realpathSync(resolve(e))}catch(t){throw t.code===`ENOENT`?new SingleFileNotFoundError(e):t}if(!statSync(t).isFile())throw new SingleFileNotAFileError(e);let s=dirname(t),g=findEnclosingProjectRoot(s);if(g){let e=g.rootPath;return{mode:`project`,projectRoot:e,docName:stripDocExtension(relative(resolveProjectContentDir(e),t).split(sep).join(`/`)),canonicalFilePath:t}}let S=basename(t);return{mode:`ephemeral`,canonicalFilePath:t,contentDir:s,singleDocRelPath:S,docName:stripDocExtension(S)}}function resolveProjectContentDir(e){return resolve(e,readConfigSafely({absPath:resolveConfigPath(`project`,e),sideline:!1,warn:()=>{}}).value.content?.dir??`.`)}function createEphemeralProjectDir(e){let t=mkdtempSync(resolve(tmpdir(),`ok-ephemeral-`)),s=resolve(t,`.ok`);return mkdirSync(s,{recursive:!0}),writeFileSync(resolve(s,`config.yml`),`# Ephemeral single-file session (\`ok <file>\`). Throwaway — safe to delete.\ncontent:\n dir: ${JSON.stringify(e)}\n`,`utf-8`),writeFileSync(resolve(s,`.gitignore`),`local/
|
|
2848
2935
|
`,`utf-8`),t}export{STARTER_TEMPLATES as $,writeConfigPatch as $i,isSelfWrite as $n,runDeviceFlowSubprocess as $r,createOsProbe as $t,LIVE_DERIVED_INDEX_DEBOUNCE_MS as A,tracedWriteFile as Ai,getMetrics as An,reconcile as Ar,clearContributors as At,OBSERVER_SYNC_ORIGIN as B,writeStateManifest as Bi,initToleranceTelemetryWriter as Bn,resolveCursorBinaryDefault as Br,countShadowObjects as Bt,GIT_UPSTREAM_WRITER as C,tracedMkdir as Ci,gcCheckpointRefs as Cn,readProjectLocalSemanticConfig as Cr,buildExecResult as Ct,HocuspocusAuthRejection as D,tracedRmSync as Di,getLogger as Dn,readTargetRecordedAt as Dr,classifyEvents as Dt,HOCUSPOCUS_AUTH_REJECTION_REASONS as E,tracedRenameSync as Ei,getLogFilePath as En,readStateManifest as Er,buildWipTree as Et,MCP_SERVER_NAME as F,validateCloneInputs as Fi,incrementCollabSocketFilteredError as Fn,releaseUiLock as Fr,commitWipFromTree as Ft,ROLLBACK_ORIGIN as G,LATEST_PROTOCOL_VERSION as Gi,isAllowedWorkspaceHostHeader as Gn,resolveUiInfo as Gr,createContentFilter as Gt,PANE_TARGET_TTL_MS as H,writeTracker as Hi,installTestLoggers as Hn,resolveLockDir as Hr,countWipRefs as Ht,MIN_GIT_VERSION as I,validateSkillZip as Ii,incrementServerObserverFire as In,removeLastKnownHash as Ir,compareSemver as It,SKILL_INSTALL_EVENTS_FILE_REL as J,isJSONRPCResultResponse as Ji,isKnownPackId as Jn,rewriteMarkdownLinksForDocumentRename as Jr,createEphemeralProjectDir as Jt,ROOT_GITIGNORE_TEMPLATE as K,isInitializedNotification as Ki,isConfigDoc as Kn,restoreContributors as Kr,createContentFilterAsync as Kt,MISSING_OK_CONFIG_MESSAGE as L,withSpan as Li,initContent as Ln,resetMetrics as Lr,containsConflictMarkers as Lt,MANAGED_RENAME_ORIGIN as M,updateLastKnownHash as Mi,handleCollabSocketError as Mn,recordSkillInstallEvent as Mr,coercePackId as Mt,MAX_AGENT_SESSIONS as N,updateUiLockPort as Ni,handleSpawnCursor as Nn,registerAllTools as Nr,commitUpstreamImport as Nt,HocuspocusAuthTokenSchema as O,tracedRmdirSync as Oi,getLogsDir as On,readTargetVersion as Or,classifyFsPath as Ot,MCP_CONNECTION_ID_HEADER as P,validateAgentId as Pi,hasGcLogLatch as Pn,registerWrite as Pr,commitWip as Pt,STARTER_PACK_IDS as Q,withFileLockSync as Qi,isProjectRoot as Qn,runCloneSubprocess as Qr,createMcpHttpHandler as Qt,McpLogger as R,withSpanSync as Ri,initShadowRepo as Rn,resolveBundledSkillDir as Rr,contentHash as Rt,GIT_PREFLIGHT_FAIL_SPAN_NAME as S,tracedLinkSync as Si,formatContributorsFrom as Sn,readBranchFromHead as Sr,buildConfigYmlContent as St,GitTooOldError as T,tracedRename as Ti,getLocalDir as Tn,readSkillInstallStateSnapshot as Tr,buildStarterFolderFrontmatterYaml as Tt,PinoLogger as U,McpServer as Ui,installUserSkill as Un,resolvePack as Ur,createApiExtension as Ut,OK_OKIGNORE_TEMPLATE as V,writeTargetVersion as Vi,installPrettyZodErrors as Vn,resolveCursorSpawnInvocation as Vr,countStaleAgentWipRefs as Vt,ProjectGitInitError as W,JSONRPCMessageSchema as Wi,isAllowedApiOrigin as Wn,resolvePackageVersion as Wr,createAssetServeMiddleware as Wt,STARTER_FOLDER_FRONTMATTER_FILENAME as X,readConfigSafely as Xi,isPairedWriteOrigin as Xn,runAuthReposSubprocess as Xr,createFileLogger as Xt,STARTER_FOLDERS as Y,atomicWriteFileSync as Yi,isLoopbackAddress as Yn,rewriteWikiLinksForDocumentRename as Yr,createExternalChangeHandler as Yt,STARTER_PACKS as Z,resolveConfigPath as Zi,isPathWithinDir as Zn,runAuthStatusSubprocess as Zr,createLiveDerivedIndexExtension as Zt,DEFAULT_PACK_ID as _,streamingProblemEvent as _i,findEnclosingGitRoot as _n,pathToDocName as _r,assertGitAvailable as _t,AgentPresenceBroadcaster as a,saveInMemoryCheckpoint as ai,describeStoredEmbeddingsKey as an,loadPrincipal as ar,SingleFileNotMarkdownError as at,FILE_WATCHER_ORIGIN as b,toBroadcasterKey as bi,formatAuthRejectionWire as bn,readAllTargets as br,bootServer as bt,AutoStartDisabledError as c,serializeError as ci,detectProjectShape as cn,logsPreviousPath as cr,UiLockCollisionError as ct,CONFIG_FILENAME as d,shutdownTelemetry as di,encodeFolderRoute as dn,normalizeFsPath as dr,acquireUiLock as dt,GitDirAccessError as ea,runWithMcpLogger as ei,createPersistenceExtension as en,isSystemDoc as er,STATE_MANIFEST_FILENAME as et,CONFLICT_MARKER_RE as f,spansCurrentPath as fi,ensureProjectGit as fn,packageVersionMajorMinor as fr,applyAgentMarkdownWrite as ft,DEFAULT_EMBEDDINGS_DIMENSIONS as g,startWatcher as gi,fallbackPaths as gn,parseKeepaliveConnectionId as gr,assertCompatibleStateManifest as gt,DEFAULT_CHECKPOINT_RETENTION as h,splitMarkdownBlocks as hi,extractWikiLinksFromMarkdown as hn,parseHocuspocusAuthToken as hr,armPaneTarget as ht,AgentFocusBroadcaster as i,resolveShadowDir as ia,sanitizeClientName as ii,createTestLogger as in,listStarterPacks as ir,SingleFileNotFoundError as it,LOG_MD_TEMPLATE as j,tracedWriteFileSync as ji,getTracer as jn,recordContributor as jr,clearEmbeddingsKeyFromAllBackends as jt,INSTALLED_AGENTS_SCHEMES as k,tracedUnlinkSync as ki,getMeter as kn,readUiLock as kr,clearArmedPaneTarget as kt,BacklinkIndex as l,setActiveSpanAttributes as li,emitPreflightFailureSpan as ln,makeLazyEmbeddingsKeyStore as lr,__getShowAllWalkStatsForTesting as lt,ConfigSchema as m,spawnDetached as mi,evictStaleTrackerEntries as mn,parseGitVersion as mr,applySeed as mt,AGENT_ID_RE as n,parseCheckpoint as na,safeSubdir as ni,createServerObserverExtension as nn,lastKnownHash as nr,SeedRootDirError as nt,AgentSessionCapacityError as o,saveVersion as oi,detectClaudeDesktopPresence as on,loggerFactory as or,StateManifestError as ot,CURSOR_BUNDLE_PATHS_BY_PLATFORM as p,spansPreviousPath as pi,errorResponse as pn,parseAuthRejectionWire as pr,applyExternalChange as pt,SERVICE_WRITER as q,isJSONRPCRequest as qi,isHocuspocusAuthRejectionReason as qn,restoreLifecycleFromConflictsJson as qr,createEmbeddingsSecretStore as qt,AGENT_WRITE_ORIGIN as r,resolveGitDirDetailed as ra,safetyCheckpoint as ri,createStreamingErrorWriter as rn,listRescueCheckpoints as rr,SingleFileNotAFileError as rt,AgentSessionManager as s,seedBasenameIndex as si,detectGit as sn,logsCurrentPath as sr,TagIndex as st,AGENT_ID_MAX_LEN as t,MalformedGitPointerError as ta,safeContentPath as ti,createServer$1 as tn,isToleranceTelemetryEnabled as tr,SeedPrerequisiteError as tt,CC1Broadcaster as u,shadowGit as ui,encodeDocName as un,mountMcpAndApi as ur,__resetShowAllWalkStatsForTesting as ut,EMBEDDINGS_API_KEY_ENV as v,swapContributors as vi,findEnclosingProjectRoot as vn,planSeed as vr,assertNeverDiskEvent as vt,GitNotAvailableError as w,tracedMkdirSync as wi,getCurrentMcpLogger as wn,readServerPackageVersion as wr,buildSkillZip as wt,FileEmbeddingsBackend as x,tracedAppendFileSync as xi,formatContributors as xn,readArmedPaneTarget as xr,buildAndOpenSkill as xt,FILE_SYSTEM_WRITER as y,teardownToleranceTelemetryWriter as yi,flushFileLogger as yn,prepareSingleFileOpen as yr,attachIdleShutdown as yt,MissingOkConfigError as z,writeRootGitignoreForNewRepo as zi,initTelemetry as zn,resolveContentDir as zr,contributorCount as zt};
|
|
2849
|
-
//# sourceMappingURL=dist-
|
|
2936
|
+
//# sourceMappingURL=dist-Dcg4smYg.mjs.map
|