@inkeep/open-knowledge 0.4.0-beta.31 → 0.4.0-beta.32
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/open-knowledge/SKILL.md +1 -1
- package/dist/cli.mjs +5 -5
- package/dist/config-schema.json +0 -13
- package/dist/config.project.schema.json +0 -13
- package/dist/constants-BVG2ymMz.mjs +2 -0
- package/dist/{dist-DOIb_FW2.mjs → dist-Bfw3oOGm.mjs} +12 -12
- package/dist/{dist-YAZrJ15a.mjs → dist-BjlSvO5w.mjs} +1 -1
- package/dist/{dist-D3xMMmYf.mjs → dist-k62w-4-v.mjs} +2 -2
- package/dist/index.mjs +1 -1
- package/dist/init-CcjfJ0-a.mjs +1 -0
- package/dist/{init-3-63uZzL.mjs → init-DsLc7vc7.mjs} +3 -3
- package/dist/loader-BLwabAxT.mjs +1 -0
- package/dist/{loader-BohnSRzb.mjs → loader-DmKx1Dxe.mjs} +3 -3
- package/dist/{preview-KUL_V2fF.mjs → preview-CuLb6srO.mjs} +2 -2
- package/dist/preview-GtCa8ObI.mjs +1 -0
- package/dist/public/assets/{ActivityModeContent-DbLaeHZ0.js → ActivityModeContent-PLMlj69Z.js} +1 -1
- package/dist/public/assets/{DocumentContext-BoqbPYlX.js → DocumentContext-DyDoN3zw.js} +1 -1
- package/dist/public/assets/{GraphPanel-D3k9jF0Q.js → GraphPanel-CSCNVbH4.js} +1 -1
- package/dist/public/assets/{SettingsDialog-UrpLReCS.js → SettingsDialog-BZIR95bl.js} +3 -3
- package/dist/public/assets/{SourceEditor-HTGqnC5W.js → SourceEditor-BSNx4vgo.js} +1 -1
- package/dist/public/assets/{config-validation-events--Lmna0va.js → config-validation-events-CQdOhgu4.js} +1 -1
- package/dist/public/assets/doc-hash-D_cCMufM.js +422 -0
- package/dist/public/assets/{index-CwEThoQY.js → index-DplFbAir.js} +4 -4
- package/dist/public/assets/{target-navigation-intent-7etGAyzg.js → target-navigation-intent-D3oiWq7j.js} +1 -1
- package/dist/public/assets/{toggle-group-MmUCNd9k.js → toggle-group-CnwuxlqO.js} +1 -1
- package/dist/public/assets/{tooltip-D8vJ720z.js → tooltip-DZMJlHWf.js} +1 -1
- package/dist/public/assets/{typing-burst-detector-CvAtpmP1.js → typing-burst-detector-2N-LtlIn.js} +1 -1
- package/dist/public/index.html +8 -8
- package/dist/schemas/v0/config.project.schema.json +0 -13
- package/dist/{src-DWeGFSri.mjs → src-CPSJr8lr.mjs} +2 -2
- package/dist/start-BoXsjqPU.mjs +1 -0
- package/dist/{start-BIWsMLqV.mjs → start-DUBJCx0O.mjs} +2 -2
- package/package.json +1 -1
- package/dist/constants-BHNW8Zq_.mjs +0 -2
- package/dist/init-6drSK50y.mjs +0 -1
- package/dist/loader-DY3uDuFe.mjs +0 -1
- package/dist/preview-BIFV91lQ.mjs +0 -1
- package/dist/public/assets/doc-hash-B4Tnobw5.js +0 -422
- package/dist/start-Cfbbhayh.mjs +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as __toCommonJS,i as __require$1,n as __esmMin,o as __toESM$1,r as __exportAll,t as __commonJSMin$1}from"./chunk-FK9Q3tQk.mjs";import{$ as FolderConfigPutSuccessSchema,$n as toWikiLinkSlug,$t as SyncConflictContentSuccessSchema,A as CONFIG_DOC_NAMES,An as emptySkillState,Ar as record,At as RenamePathSuccessSchema,Bn as isOrphanMode,Br as $ZodObject,Bt as SearchRequestSchema,C as CC1ServerInfoPayloadSchema,Cn as createBasenameIndex,Cr as intersection,Ct as ORPHAN_MODES,D as CC1_CHANNEL_DISK_ACK,Dn as createWorkspaceSearchDocument,Dr as object$1,Dt as PrincipalSuccessSchema,E as CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,En as createWorkspaceSearchCorpus,Er as number,Et as PagesSuccessSchema,F as CreateFolderRequestSchema,Fn as getParseHealth,Fr as datetime,Ft as SKILL_STATE_TARGETS,G as DiffSuccessSchema,Gn as readFmMap,Gr as safeParseAsync$1,Gt as SeedPlanSuccessSchema,H as DeadLinksSuccessSchema,Hn as mergeThreeWay,Hr as parse$1,Ht as SeedApplyRequestSchema,I as CreateFolderSuccessSchema,In as getWikiLinkText,Ir as toJSONSchema,It as SKILL_STATE_VERSION_RE,Jn as searchWorkspaceCorpus,Jr as normalizeParams,Jt as SkillStateSchema,K as DocumentListSuccessSchema,Kn as resolveAssetProjectPath,Kr as clone,Kt as ServerInfoSuccessSchema,L as CreatePageRequestSchema,Ln as humanFormat,Lt as SYSTEM_DOC_NAME,M as CONFIG_DOC_NAME_PROJECT,Mn as extractFrontmatterTags,Mr as union,Mt as RollbackRequestSchema,N as CONFIG_DOC_NAME_PROJECT_LOCAL,Nn as fnv1aDigest,Nr as unknown,Nt as RollbackSuccessSchema,O as CC1_CHANNEL_SERVER_INFO,On as defaultScheduler,Or as optional,Ot as ProblemDetailsSchema,P as CONFIG_DOC_NAME_USER,Pn as getHeadingSlug,Pt as SKILL_STATE_REL,Q as FolderConfigPutRequestSchema,Qn as toBridgeInvariantLog,Qt as SyncAbortMergeSuccessSchema,R as CreatePageSuccessSchema,Rn as iconFromClientName,Rr as describe$1,Rt as SaveVersionRequestSchema,S as CC1DiskAckPayloadSchema,Sn as colorFromSeed,Sr as discriminatedUnion,St as MetricsReconciliationSuccessSchema,T as CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,Tn as createTagInTextRegex,Tr as looseObject,Tt as PageHeadingsSuccessSchema,U as DeletePathRequestSchema,Un as normalizeBridge,Ur as parseAsync,Ut as SeedApplySuccessSchema,Vn as mediaKindForSidebarAssetExtension,Vr as $ZodType,Vt as SearchSuccessSchema,W as DeletePathSuccessSchema,Wn as prependFrontmatter,Wr as safeParse$1,Wt as SeedListPacksSuccessSchema,X as EmptyRequestSchema,Xn as stripFrontmatter,Xt as StreamingProblemEventSchema,Y as EXECUTABLE_BLOCKLIST_EXTENSIONS,Yn as sharedExtensions,Yr as $constructor,Yt as SpawnCursorSuccessSchema,Z as FolderConfigGetSuccessSchema,Zn as tagsMatchingPrefix,Zr as require_dist$2,Zt as SuggestLinksSuccessSchema,_ as BridgeMergeContentLossError,_n as applyFastDiff,_r as _null,_t as LocalOpOpenRequestSchema,a as AgentBurstDiffSuccessSchema,an as SyncTriggerSuccessSchema,ar as ConfigSchema$1,at as InstallSkillRequestSchema,b as CC1ConfigValidationRejectedPayloadSchema,bn as classifyMarkdownHref,br as boolean,bt as MetricsAgentPresenceSuccessSchema,c as AgentUndoRequestSchema,cn as TemplateDeleteSuccessSchema,cr as applyPatchToDocument,ct as LinkGraphSuccessSchema,d as AgentWriteMdSuccessSchema,dn as TemplatePutSuccessSchema,dr as validatePatchScopes,dt as LocalOpAuthIdentitySuccessSchema,en as SyncConflictsSuccessSchema,er as unwrapFrontmatterFences,et as ForwardLinksSuccessSchema,f as AgentWriteRequestSchema,fn as TestRescanBacklinksSuccessSchema,fr as withConfigSpan,ft as LocalOpAuthPatRequestSchema,g as BridgeInvariantViolationError,gn as WorkspaceSuccessSchema,gr as _enum,gt as LocalOpCloneRequestSchema,h as BacklinksSuccessSchema,hn as UploadRequestSchema,hr as ZodOptional$1,ht as LocalOpAuthStatusSuccessSchema,i as AgentActivitySuccessSchema,in as SyncTriggerRequestSchema,ir as CONFIG_SCHEMA_MAJOR_PATH,it as INLINE_RENDERABLE_EXTENSIONS,j as CONFIG_DOC_NAME_OKIGNORE,jn as expandTagToHierarchy,jr as string,jt as RescueListSuccessSchema,k as CC1_CONTRACT_VERSION,kn as detectAppliedToleranceClasses,kr as preprocess,kt as RenamePathRequestSchema,l as AgentUndoSuccessSchema,ln as TemplateGetSuccessSchema,lr as locateIssue,lt as LocalOpAuthEmptySuccessSchema,m as BacklinkCountsSuccessSchema,mn as UploadAssetSuccessSchema,mt as LocalOpAuthSetIdentityRequestSchema,nn as SyncResolveConflictSuccessSchema,nr as PluginKey,nt as HistoryVersionSuccessSchema,o as AgentPatchRequestSchema,on as TagsForNameSuccessSchema,or as LOCAL_DIR,ot as InstallSkillSuccessSchema,p as AgentWriteSuccessSchema,pn as TestResetSuccessSchema,pr as withConfigSpanSync,pt as LocalOpAuthPatSuccessSchema,q as DocumentReadSuccessSchema,qn as resolveInternalHref,qr as defineLazy,qt as SkillInstallStateSuccessSchema,r as ASSET_EXTENSIONS,rn as SyncStatusSchema,rr as Fragment,rt as HubsSuccessSchema,s as AgentPatchSuccessSchema,sn as TagsListSuccessSchema,sr as addConfigSpanEvent,st as InstalledAgentsSuccessSchema,t as AGENT_ICON_COLORS,tn as SyncResolveConflictRequestSchema,tr as getSchema,tt as HistorySuccessSchema,u as AgentWriteMdRequestSchema,un as TemplatePutRequestSchema,ur as toConfigIssue,ut as LocalOpAuthHostRequestSchema,v as CC1BranchSwitchedPayloadSchema,vn as applyIncrementalDiff,vt as LocalOpOpenSuccessSchema,w as CC1_CHANNEL_BRANCH_SWITCHED,wn as createCodeFenceTracker,wr as literal,wt as OrphansSuccessSchema,x as CC1DerivedViewPayloadSchema,xn as classifyWikiLinkTarget,xr as custom,xt as MetricsParseHealthSuccessSchema,y as CC1ConfigIgnoreNestedErrorPayloadSchema,yn as assertNeverProblemType,yr as array,yt as MarkdownManager,z as DEFAULT_DEDUP_MODE,zn as isKnownConfigError,zr as meta$1,zt as SaveVersionSuccessSchema}from"./dist-D3xMMmYf.mjs";import{a as metrics,c as SpanStatusCode,i as propagation,l as SpanKind,n as init_esm$2,o as diag,r as trace,s as context,t as esm_exports$2}from"./esm-BbkJd7ro.mjs";import{a as acquireProcessLock,c as isValidLockPid,f as readServerLock,g as updateProcessLockPort,m as releaseServerLock,n as RUNTIME_VERSION,o as acquireServerLock,p as releaseProcessLock,s as isProcessAlive,t as ProcessLockCollisionError,u as readProcessLock}from"./server-lock-D7DXNVql-BRVVzA6T.mjs";import{a as require_src$15,i as esm_default,r as withParentLock,t as createGitInstance}from"./git-handle-DwfYp_z--CfyPz4Dz.mjs";import{r as diffLines,t as createPatch}from"./libesm-YL3Bqolr.mjs";import{n as mimes,t as build_default}from"./build-fAc55Z_L.mjs";import{t as b1}from"./chunk-YNYSPYQ5-Dq-BWW-f.mjs";import{a as c,c as h,d as m,f as p,h as x,i as b,l as i,m as v,n as C,o as d,p as u,r as a,s as f,t as $$1,u as l}from"./chunk-GFQRA5P5-CkMj9l7f.mjs";import{A as gt,B as wt,C as _i$1,D as da$1,E as bt,F as pe,H as zi$1,I as qi,L as us$1,M as ma$1,N as mt$1,O as di$1,P as pa$1,S as X$1,T as bl,V as xi$1,_ as Ti$1,a as Fi$1,b as W$1,c as M,d as P,f as Pt$1,g as T,h as Sl,i as En$1,j as he,k as ga$1,l as Nl,m as Se,n as Bi$1,o as Fs$1,p as R,r as Ci$1,s as G$1,t as Al,u as Oi$1,v as V,w as be,x as Wi$1,y as Vi$1,z as wl}from"./chunk-FEIOJCZD-Vm1q1kLH.mjs";import{a as d$1,c as m$1,d as y,i as c$1,l as p$1,n as N,o as f$1,r as P$1,s as h$1,t as $$2,u as v$1}from"./chunk-XHM67O4N-Cd7Fiqsb.mjs";import{n as l$1,r as o,t as h$2}from"./chunk-R6VWJ2ZL-DSqbA7Rj.mjs";import{r as o$1}from"./chunk-CWQS3NFK-BQ5SUtd7.mjs";import"./chunk-DXB73IDG-DfmyzFzL.mjs";import{n as d$2,t as _$1}from"./chunk-5QMZ5MUS-SLhNX8t9.mjs";import{n as u$1,t as b$1}from"./chunk-A5O5YHGN-DQP-O5US.mjs";import{n,r,t as c$2}from"./chunk-OJDRYQWQ-D4lSWh0K.mjs";import{r as x$1,t as a$1}from"./chunk-24IMIIXA-_PX4ITYZ.mjs";import{n as n$1}from"./chunk-3THT3N7L-DrzOuTpA.mjs";import{t as n$2}from"./chunk-44UOCSGV-BbZqjKvt.mjs";import{createRequire}from"node:module";import{execFile,spawn,spawnSync}from"node:child_process";import*as U from"node:path";import{basename,dirname,extname,isAbsolute,join,normalize,posix,relative,resolve,sep,win32}from"node:path";import*as I from"node:fs";import{appendFileSync,closeSync,createReadStream,createWriteStream,existsSync,linkSync,lstatSync,mkdirSync,openSync,readFile,readFileSync,readSync,readdirSync,realpathSync,renameSync,rmSync,rmdirSync,statSync,unlinkSync,writeFileSync}from"node:fs";import{homedir,hostname,platform,tmpdir}from"node:os";import{URLSearchParams as URLSearchParams$1,fileURLToPath}from"node:url";import{AsyncLocalStorage}from"node:async_hooks";import{promisify}from"node:util";import{Readable}from"stream";import{Transform}from"node:stream";import crypto$1,{createHash,randomUUID,webcrypto}from"node:crypto";import crypto$2 from"crypto";import*as zlib$2 from"zlib";import{access,constants,mkdir,readFile as readFile$1,readdir,realpath,rename,stat as stat$1,writeFile}from"node:fs/promises";import{pipeline}from"node:stream/promises";import{setTimeout as setTimeout$1}from"node:timers/promises";import{Http2ServerRequest,constants as constants$1}from"http2";import{lookup}from"node:dns";import{createServer}from"node:http";const WRITER_ID_RE=/^(agent-[^/]+|principal-[^/]+|file-system|git-upstream|openknowledge-service)$/;function classifyGitEntry(e,t,s){let g;try{g=statSync(e)}catch(t){let s=t.code;return s===`ENOENT`||s===`ENOTDIR`?{kind:`absent`}:{kind:`inaccessible`,gitPath:e,cause:t}}let S=computeProjectSubPath(t,s);if(g.isDirectory())return{kind:`directory`,path:e,projectSubPath:S};if(g.isFile()){let s;try{s=readFileSync(e,`utf-8`).trim()}catch(t){return{kind:`malformed-pointer`,gitPath:e,target:``,cause:t}}let g=s.match(/^gitdir:\s*(.+)$/);return g?{kind:`linked`,path:resolve(t,g[1]),gitPath:e,projectSubPath:S}:{kind:`malformed-pointer`,gitPath:e,target:``}}return{kind:`absent`}}function computeProjectSubPath(e,t){let s=relative(e,t);return s===``||s===`.`||s.startsWith(`..`)||isAbsolute(s)?``:s}function findAncestorGitEntry(e){let t=homedir(),s=resolve(e),g=64;for(let e=0;e<64;e++){if(s===t)return null;let e=dirname(s);if(e===s||e===t)return null;let g=resolve(e,`.git`);try{let t=statSync(g);if(t.isDirectory()||t.isFile())return{gitPath:g,workTreeRoot:e}}catch(e){let t=e.code;t!==`ENOENT`&&t!==`ENOTDIR`&&console.warn(`[shadow-repo-layout] Cannot stat ${g} (${t??`unknown`}); skipping ancestor`)}s=e}return null}function resolveGitDirDetailed(e){let t=resolve(e),s=classifyGitEntry(resolve(t,`.git`),t,t);if(s.kind!==`absent`)return s;let g=findAncestorGitEntry(t);return g===null?{kind:`absent`}:classifyGitEntry(g.gitPath,g.workTreeRoot,t)}function resolveGitDir(e){let t=resolveGitDirDetailed(e);return t.kind===`directory`||t.kind===`linked`?t.path:null}function resolveShadowDir(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return resolve(t.path,shadowSubdirName(t.projectSubPath));case`linked`:if(!existsSync(t.path))throw new MalformedGitPointerError(t.gitPath,t.path);return resolve(t.path,shadowSubdirName(t.projectSubPath));case`malformed-pointer`:throw new MalformedGitPointerError(t.gitPath,t.target,{cause:t.cause});case`inaccessible`:throw new GitDirAccessError(t.gitPath,{cause:t.cause});case`absent`:return resolve(e,`.git/ok`)}}function shadowSubdirName(e){return e===``?`ok`:`ok-${slugifyShadowSubPath(e)}`}function slugifyShadowSubPath(e){let t=e.split(sep).join(`-`).replace(/\/+/g,`-`).replace(/[^A-Za-z0-9._-]/g,`_`).replace(/^\.+/,`_`),s=64;if(t.length<=64)return t||`sub`;let g=djb2(e).toString(16).padStart(8,`0`);return`${t.slice(0,55)}-${g}`}function djb2(e){let t=5381;for(let s=0;s<e.length;s++)t=t*33+e.charCodeAt(s)>>>0;return t}var MalformedGitPointerError=class extends Error{gitPointerPath;resolvedTarget;constructor(e,t,s){let g=t?`references a missing or unreadable gitdir at ${t}`:`is unreadable or has no valid gitdir: pointer`;super(`\`.git\` pointer at ${e} ${g}. Run \`git worktree prune\` from the source repo and try again.`,s),this.name=`MalformedGitPointerError`,this.gitPointerPath=e,this.resolvedTarget=t}},GitDirAccessError=class extends Error{gitPath;constructor(e,t){let s=t?.cause!==void 0&&t.cause!==null&&typeof t.cause==`object`&&`code`in t.cause&&typeof t.cause.code==`string`?` (${t.cause.code})`:``;super(`Cannot access \`.git\` at ${e}${s}. Check filesystem permissions and that the volume is mounted.`,t),this.name=`GitDirAccessError`,this.gitPath=e}};function getShadowRepoPath(e){let t;try{t=resolveShadowDir(e)}catch(e){if(e instanceof MalformedGitPointerError||e instanceof GitDirAccessError)return null;throw e}return existsSync(resolve(t,`HEAD`))?t:null}function getWipRefPattern(e){return`refs/wip/${e}/`}const OK_CONTRIBUTORS_PREFIX=`ok-contributors: `;function parseContributors(e){if(!e)return[];let t=[];for(let s of e.split(`
|
|
1
|
+
import{a as __toCommonJS,i as __require$1,n as __esmMin,o as __toESM$1,r as __exportAll,t as __commonJSMin$1}from"./chunk-FK9Q3tQk.mjs";import{$ as FolderConfigPutSuccessSchema,$n as toWikiLinkSlug,$t as SyncConflictContentSuccessSchema,A as CONFIG_DOC_NAMES,An as emptySkillState,Ar as record,At as RenamePathSuccessSchema,Bn as isOrphanMode,Br as $ZodObject,Bt as SearchRequestSchema,C as CC1ServerInfoPayloadSchema,Cn as createBasenameIndex,Cr as intersection,Ct as ORPHAN_MODES,D as CC1_CHANNEL_DISK_ACK,Dn as createWorkspaceSearchDocument,Dr as object$1,Dt as PrincipalSuccessSchema,E as CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,En as createWorkspaceSearchCorpus,Er as number,Et as PagesSuccessSchema,F as CreateFolderRequestSchema,Fn as getParseHealth,Fr as datetime,Ft as SKILL_STATE_TARGETS,G as DiffSuccessSchema,Gn as readFmMap,Gr as safeParseAsync$1,Gt as SeedPlanSuccessSchema,H as DeadLinksSuccessSchema,Hn as mergeThreeWay,Hr as parse$1,Ht as SeedApplyRequestSchema,I as CreateFolderSuccessSchema,In as getWikiLinkText,Ir as toJSONSchema,It as SKILL_STATE_VERSION_RE,Jn as searchWorkspaceCorpus,Jr as normalizeParams,Jt as SkillStateSchema,K as DocumentListSuccessSchema,Kn as resolveAssetProjectPath,Kr as clone,Kt as ServerInfoSuccessSchema,L as CreatePageRequestSchema,Ln as humanFormat,Lt as SYSTEM_DOC_NAME,M as CONFIG_DOC_NAME_PROJECT,Mn as extractFrontmatterTags,Mr as union,Mt as RollbackRequestSchema,N as CONFIG_DOC_NAME_PROJECT_LOCAL,Nn as fnv1aDigest,Nr as unknown,Nt as RollbackSuccessSchema,O as CC1_CHANNEL_SERVER_INFO,On as defaultScheduler,Or as optional,Ot as ProblemDetailsSchema,P as CONFIG_DOC_NAME_USER,Pn as getHeadingSlug,Pt as SKILL_STATE_REL,Q as FolderConfigPutRequestSchema,Qn as toBridgeInvariantLog,Qt as SyncAbortMergeSuccessSchema,R as CreatePageSuccessSchema,Rn as iconFromClientName,Rr as describe$1,Rt as SaveVersionRequestSchema,S as CC1DiskAckPayloadSchema,Sn as colorFromSeed,Sr as discriminatedUnion,St as MetricsReconciliationSuccessSchema,T as CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,Tn as createTagInTextRegex,Tr as looseObject,Tt as PageHeadingsSuccessSchema,U as DeletePathRequestSchema,Un as normalizeBridge,Ur as parseAsync,Ut as SeedApplySuccessSchema,Vn as mediaKindForSidebarAssetExtension,Vr as $ZodType,Vt as SearchSuccessSchema,W as DeletePathSuccessSchema,Wn as prependFrontmatter,Wr as safeParse$1,Wt as SeedListPacksSuccessSchema,X as EmptyRequestSchema,Xn as stripFrontmatter,Xt as StreamingProblemEventSchema,Y as EXECUTABLE_BLOCKLIST_EXTENSIONS,Yn as sharedExtensions,Yr as $constructor,Yt as SpawnCursorSuccessSchema,Z as FolderConfigGetSuccessSchema,Zn as tagsMatchingPrefix,Zr as require_dist$2,Zt as SuggestLinksSuccessSchema,_ as BridgeMergeContentLossError,_n as applyFastDiff,_r as _null,_t as LocalOpOpenRequestSchema,a as AgentBurstDiffSuccessSchema,an as SyncTriggerSuccessSchema,ar as ConfigSchema$1,at as InstallSkillRequestSchema,b as CC1ConfigValidationRejectedPayloadSchema,bn as classifyMarkdownHref,br as boolean,bt as MetricsAgentPresenceSuccessSchema,c as AgentUndoRequestSchema,cn as TemplateDeleteSuccessSchema,cr as applyPatchToDocument,ct as LinkGraphSuccessSchema,d as AgentWriteMdSuccessSchema,dn as TemplatePutSuccessSchema,dr as validatePatchScopes,dt as LocalOpAuthIdentitySuccessSchema,en as SyncConflictsSuccessSchema,er as unwrapFrontmatterFences,et as ForwardLinksSuccessSchema,f as AgentWriteRequestSchema,fn as TestRescanBacklinksSuccessSchema,fr as withConfigSpan,ft as LocalOpAuthPatRequestSchema,g as BridgeInvariantViolationError,gn as WorkspaceSuccessSchema,gr as _enum,gt as LocalOpCloneRequestSchema,h as BacklinksSuccessSchema,hn as UploadRequestSchema,hr as ZodOptional$1,ht as LocalOpAuthStatusSuccessSchema,i as AgentActivitySuccessSchema,in as SyncTriggerRequestSchema,ir as CONFIG_SCHEMA_MAJOR_PATH,it as INLINE_RENDERABLE_EXTENSIONS,j as CONFIG_DOC_NAME_OKIGNORE,jn as expandTagToHierarchy,jr as string,jt as RescueListSuccessSchema,k as CC1_CONTRACT_VERSION,kn as detectAppliedToleranceClasses,kr as preprocess,kt as RenamePathRequestSchema,l as AgentUndoSuccessSchema,ln as TemplateGetSuccessSchema,lr as locateIssue,lt as LocalOpAuthEmptySuccessSchema,m as BacklinkCountsSuccessSchema,mn as UploadAssetSuccessSchema,mt as LocalOpAuthSetIdentityRequestSchema,nn as SyncResolveConflictSuccessSchema,nr as PluginKey,nt as HistoryVersionSuccessSchema,o as AgentPatchRequestSchema,on as TagsForNameSuccessSchema,or as LOCAL_DIR,ot as InstallSkillSuccessSchema,p as AgentWriteSuccessSchema,pn as TestResetSuccessSchema,pr as withConfigSpanSync,pt as LocalOpAuthPatSuccessSchema,q as DocumentReadSuccessSchema,qn as resolveInternalHref,qr as defineLazy,qt as SkillInstallStateSuccessSchema,r as ASSET_EXTENSIONS,rn as SyncStatusSchema,rr as Fragment,rt as HubsSuccessSchema,s as AgentPatchSuccessSchema,sn as TagsListSuccessSchema,sr as addConfigSpanEvent,st as InstalledAgentsSuccessSchema,t as AGENT_ICON_COLORS,tn as SyncResolveConflictRequestSchema,tr as getSchema,tt as HistorySuccessSchema,u as AgentWriteMdRequestSchema,un as TemplatePutRequestSchema,ur as toConfigIssue,ut as LocalOpAuthHostRequestSchema,v as CC1BranchSwitchedPayloadSchema,vn as applyIncrementalDiff,vt as LocalOpOpenSuccessSchema,w as CC1_CHANNEL_BRANCH_SWITCHED,wn as createCodeFenceTracker,wr as literal,wt as OrphansSuccessSchema,x as CC1DerivedViewPayloadSchema,xn as classifyWikiLinkTarget,xr as custom,xt as MetricsParseHealthSuccessSchema,y as CC1ConfigIgnoreNestedErrorPayloadSchema,yn as assertNeverProblemType,yr as array,yt as MarkdownManager,z as DEFAULT_DEDUP_MODE,zn as isKnownConfigError,zr as meta$1,zt as SaveVersionSuccessSchema}from"./dist-k62w-4-v.mjs";import{a as metrics,c as SpanStatusCode,i as propagation,l as SpanKind,n as init_esm$2,o as diag,r as trace,s as context,t as esm_exports$2}from"./esm-BbkJd7ro.mjs";import{a as acquireProcessLock,c as isValidLockPid,f as readServerLock,g as updateProcessLockPort,m as releaseServerLock,n as RUNTIME_VERSION,o as acquireServerLock,p as releaseProcessLock,s as isProcessAlive,t as ProcessLockCollisionError,u as readProcessLock}from"./server-lock-D7DXNVql-BRVVzA6T.mjs";import{a as require_src$15,i as esm_default,r as withParentLock,t as createGitInstance}from"./git-handle-DwfYp_z--CfyPz4Dz.mjs";import{r as diffLines,t as createPatch}from"./libesm-YL3Bqolr.mjs";import{n as mimes,t as build_default}from"./build-fAc55Z_L.mjs";import{t as b1}from"./chunk-YNYSPYQ5-Dq-BWW-f.mjs";import{a as c,c as h,d as m,f as p,h as x,i as b,l as i,m as v,n as C,o as d,p as u,r as a,s as f,t as $$1,u as l}from"./chunk-GFQRA5P5-CkMj9l7f.mjs";import{A as gt,B as wt,C as _i$1,D as da$1,E as bt,F as pe,H as zi$1,I as qi,L as us$1,M as ma$1,N as mt$1,O as di$1,P as pa$1,S as X$1,T as bl,V as xi$1,_ as Ti$1,a as Fi$1,b as W$1,c as M,d as P,f as Pt$1,g as T,h as Sl,i as En$1,j as he,k as ga$1,l as Nl,m as Se,n as Bi$1,o as Fs$1,p as R,r as Ci$1,s as G$1,t as Al,u as Oi$1,v as V,w as be,x as Wi$1,y as Vi$1,z as wl}from"./chunk-FEIOJCZD-Vm1q1kLH.mjs";import{a as d$1,c as m$1,d as y,i as c$1,l as p$1,n as N,o as f$1,r as P$1,s as h$1,t as $$2,u as v$1}from"./chunk-XHM67O4N-Cd7Fiqsb.mjs";import{n as l$1,r as o,t as h$2}from"./chunk-R6VWJ2ZL-DSqbA7Rj.mjs";import{r as o$1}from"./chunk-CWQS3NFK-BQ5SUtd7.mjs";import"./chunk-DXB73IDG-DfmyzFzL.mjs";import{n as d$2,t as _$1}from"./chunk-5QMZ5MUS-SLhNX8t9.mjs";import{n as u$1,t as b$1}from"./chunk-A5O5YHGN-DQP-O5US.mjs";import{n,r,t as c$2}from"./chunk-OJDRYQWQ-D4lSWh0K.mjs";import{r as x$1,t as a$1}from"./chunk-24IMIIXA-_PX4ITYZ.mjs";import{n as n$1}from"./chunk-3THT3N7L-DrzOuTpA.mjs";import{t as n$2}from"./chunk-44UOCSGV-BbZqjKvt.mjs";import{createRequire}from"node:module";import{execFile,spawn,spawnSync}from"node:child_process";import*as U from"node:path";import{basename,dirname,extname,isAbsolute,join,normalize,posix,relative,resolve,sep,win32}from"node:path";import*as I from"node:fs";import{appendFileSync,closeSync,createReadStream,createWriteStream,existsSync,linkSync,lstatSync,mkdirSync,openSync,readFile,readFileSync,readSync,readdirSync,realpathSync,renameSync,rmSync,rmdirSync,statSync,unlinkSync,writeFileSync}from"node:fs";import{homedir,hostname,platform,tmpdir}from"node:os";import{URLSearchParams as URLSearchParams$1,fileURLToPath}from"node:url";import{AsyncLocalStorage}from"node:async_hooks";import{promisify}from"node:util";import{Readable}from"stream";import{Transform}from"node:stream";import crypto$1,{createHash,randomUUID,webcrypto}from"node:crypto";import crypto$2 from"crypto";import*as zlib$2 from"zlib";import{access,constants,mkdir,readFile as readFile$1,readdir,realpath,rename,stat as stat$1,writeFile}from"node:fs/promises";import{pipeline}from"node:stream/promises";import{setTimeout as setTimeout$1}from"node:timers/promises";import{Http2ServerRequest,constants as constants$1}from"http2";import{lookup}from"node:dns";import{createServer}from"node:http";const WRITER_ID_RE=/^(agent-[^/]+|principal-[^/]+|file-system|git-upstream|openknowledge-service)$/;function classifyGitEntry(e,t,s){let g;try{g=statSync(e)}catch(t){let s=t.code;return s===`ENOENT`||s===`ENOTDIR`?{kind:`absent`}:{kind:`inaccessible`,gitPath:e,cause:t}}let S=computeProjectSubPath(t,s);if(g.isDirectory())return{kind:`directory`,path:e,projectSubPath:S};if(g.isFile()){let s;try{s=readFileSync(e,`utf-8`).trim()}catch(t){return{kind:`malformed-pointer`,gitPath:e,target:``,cause:t}}let g=s.match(/^gitdir:\s*(.+)$/);return g?{kind:`linked`,path:resolve(t,g[1]),gitPath:e,projectSubPath:S}:{kind:`malformed-pointer`,gitPath:e,target:``}}return{kind:`absent`}}function computeProjectSubPath(e,t){let s=relative(e,t);return s===``||s===`.`||s.startsWith(`..`)||isAbsolute(s)?``:s}function findAncestorGitEntry(e){let t=homedir(),s=resolve(e),g=64;for(let e=0;e<64;e++){if(s===t)return null;let e=dirname(s);if(e===s||e===t)return null;let g=resolve(e,`.git`);try{let t=statSync(g);if(t.isDirectory()||t.isFile())return{gitPath:g,workTreeRoot:e}}catch(e){let t=e.code;t!==`ENOENT`&&t!==`ENOTDIR`&&console.warn(`[shadow-repo-layout] Cannot stat ${g} (${t??`unknown`}); skipping ancestor`)}s=e}return null}function resolveGitDirDetailed(e){let t=resolve(e),s=classifyGitEntry(resolve(t,`.git`),t,t);if(s.kind!==`absent`)return s;let g=findAncestorGitEntry(t);return g===null?{kind:`absent`}:classifyGitEntry(g.gitPath,g.workTreeRoot,t)}function resolveGitDir(e){let t=resolveGitDirDetailed(e);return t.kind===`directory`||t.kind===`linked`?t.path:null}function resolveShadowDir(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return resolve(t.path,shadowSubdirName(t.projectSubPath));case`linked`:if(!existsSync(t.path))throw new MalformedGitPointerError(t.gitPath,t.path);return resolve(t.path,shadowSubdirName(t.projectSubPath));case`malformed-pointer`:throw new MalformedGitPointerError(t.gitPath,t.target,{cause:t.cause});case`inaccessible`:throw new GitDirAccessError(t.gitPath,{cause:t.cause});case`absent`:return resolve(e,`.git/ok`)}}function shadowSubdirName(e){return e===``?`ok`:`ok-${slugifyShadowSubPath(e)}`}function slugifyShadowSubPath(e){let t=e.split(sep).join(`-`).replace(/\/+/g,`-`).replace(/[^A-Za-z0-9._-]/g,`_`).replace(/^\.+/,`_`),s=64;if(t.length<=64)return t||`sub`;let g=djb2(e).toString(16).padStart(8,`0`);return`${t.slice(0,55)}-${g}`}function djb2(e){let t=5381;for(let s=0;s<e.length;s++)t=t*33+e.charCodeAt(s)>>>0;return t}var MalformedGitPointerError=class extends Error{gitPointerPath;resolvedTarget;constructor(e,t,s){let g=t?`references a missing or unreadable gitdir at ${t}`:`is unreadable or has no valid gitdir: pointer`;super(`\`.git\` pointer at ${e} ${g}. Run \`git worktree prune\` from the source repo and try again.`,s),this.name=`MalformedGitPointerError`,this.gitPointerPath=e,this.resolvedTarget=t}},GitDirAccessError=class extends Error{gitPath;constructor(e,t){let s=t?.cause!==void 0&&t.cause!==null&&typeof t.cause==`object`&&`code`in t.cause&&typeof t.cause.code==`string`?` (${t.cause.code})`:``;super(`Cannot access \`.git\` at ${e}${s}. Check filesystem permissions and that the volume is mounted.`,t),this.name=`GitDirAccessError`,this.gitPath=e}};function getShadowRepoPath(e){let t;try{t=resolveShadowDir(e)}catch(e){if(e instanceof MalformedGitPointerError||e instanceof GitDirAccessError)return null;throw e}return existsSync(resolve(t,`HEAD`))?t:null}function getWipRefPattern(e){return`refs/wip/${e}/`}const OK_CONTRIBUTORS_PREFIX=`ok-contributors: `;function parseContributors(e){if(!e)return[];let t=[];for(let s of e.split(`
|
|
2
2
|
`)){let e=s.trim();if(e.startsWith(OK_CONTRIBUTORS_PREFIX))try{let s=JSON.parse(e.slice(17));if(typeof s==`object`&&s&&`id`in s&&typeof s.id==`string`&&`name`in s&&typeof s.name==`string`&&`docs`in s&&Array.isArray(s.docs)&&s.docs.every(e=>typeof e==`string`)&&(!(`colorSeed`in s)||typeof s.colorSeed==`string`)){let e=s;if(`summaries`in e){let t=e.summaries;(!Array.isArray(t)||!t.every(e=>typeof e==`string`))&&delete e.summaries}t.push(s)}}catch{}}return t}const OK_CHECKPOINT_PREFIX=`ok-checkpoint-v1: `;function parseCheckpoint(e){if(!e)return null;for(let t of e.split(`
|
|
3
3
|
`)){let e=t.trim();if(!e.startsWith(OK_CHECKPOINT_PREFIX))continue;let s;try{s=JSON.parse(e.slice(18))}catch{return null}if(typeof s!=`object`||!s)return null;let g=s,S=g.kind,w=g.metadata;if(typeof w!=`object`||!w)return null;let E=typeof g.docName==`string`?g.docName:null,D=typeof g.size==`number`&&Number.isFinite(g.size)?g.size:null;if(S===`bridge-merge-loss`){let e=w;return Array.isArray(e.lostSubstrings)&&e.lostSubstrings.every(e=>typeof e==`string`)?{kind:`bridge-merge-loss`,docName:E,size:D,metadata:{lostSubstrings:e.lostSubstrings}}:null}if(S===`external-change-rescue`){let e=w;return typeof e.incomingDiskSha==`string`?{kind:`external-change-rescue`,docName:E,size:D,metadata:{incomingDiskSha:e.incomingDiskSha}}:null}return null}return null}function formatCheckpointBodyLine(e){let t={kind:e.kind,metadata:e.metadata};return e.docName!==null&&(t.docName=e.docName),e.size!==null&&(t.size=e.size),`${OK_CHECKPOINT_PREFIX}${JSON.stringify(t)}`}const OK_ACTOR_PREFIX=`ok-actor: `;function formatOkActor(e){let{summaries:t,previous_paths:s,...g}=e,S={...g};return t&&t.length>0&&(S.summaries=t),s&&s.length>0&&(S.previous_paths=s),`${OK_ACTOR_PREFIX}${JSON.stringify(S)}`}function parseOkActorObject(e){if(e.v!==1||!(`display_name`in e)||typeof e.display_name!=`string`||!(`docs`in e)||!Array.isArray(e.docs))return null;let t=typeof e.principal==`string`?e.principal:null,s=typeof e.agent_session==`string`?e.agent_session:null,g;if(typeof e.writer_id==`string`&&e.writer_id.length>0)g=e.writer_id;else if(s)g=`agent-${s}`;else if(t)g=t;else switch(e.display_name){case`File System`:g=`file-system`;break;case`Git (upstream)`:g=`git-upstream`;break;default:g=`openknowledge-service`}let S=`summaries`in e&&Array.isArray(e.summaries)&&e.summaries.every(e=>typeof e==`string`)?e.summaries:void 0,w=parsePreviousPaths(e);return{v:1,writer_id:g,principal:t,agent_session:s,agent_type:typeof e.agent_type==`string`?e.agent_type:null,client_name:typeof e.client_name==`string`?e.client_name:null,client_version:typeof e.client_version==`string`?e.client_version:null,label:typeof e.label==`string`?e.label:null,display_name:e.display_name,color_seed:typeof e.color_seed==`string`?e.color_seed:`unknown`,docs:e.docs.filter(e=>typeof e==`string`),...S&&S.length>0?{summaries:S}:{},...w&&w.length>0?{previous_paths:w}:{}}}function parsePreviousPaths(e){if(!(`previous_paths`in e)||!Array.isArray(e.previous_paths))return;let t=[];for(let s of e.previous_paths){if(typeof s!=`object`||!s)continue;let e=s;typeof e.from!=`string`||typeof e.to!=`string`||t.push({from:e.from,to:e.to})}return t}function parseOkActors(e){if(!e)return[];let t=[];for(let s of e.split(`
|
|
4
4
|
`)){let e=s.trim();if(!e.startsWith(OK_ACTOR_PREFIX))continue;let g;try{g=JSON.parse(e.slice(10))}catch{continue}if(typeof g!=`object`||!g)continue;let S=parseOkActorObject(g);S&&t.push(S)}return t}function okActorToShadowContributor(e){let t={v:1,id:e.writer_id,name:e.display_name,colorSeed:e.color_seed,docs:e.docs};return e.summaries&&e.summaries.length>0&&(t.summaries=e.summaries),t}function readContributors(e){let t=parseOkActors(e);return t.length>0?t.map(okActorToShadowContributor):parseContributors(e)}function formatWipSubject(e){return e.length===0?`wip: auto-save`:e.length===1?`wip: ${e[0]}`:`wip: ${e.length} docs`}function formatReconcileSubject(e){return`reconcile: ${e}`}function formatRollbackSubject(e,t){return`rollback: ${e} to ${t.slice(0,7)}`}function formatParkSubject(e,t){return`park: ${e} -> ${t}`}function formatRenameSubject(e,t){return`rename: ${e} -> ${t}`}function formatCheckpointSubject(e){return`checkpoint: ${e}`}function formatImportSubject(e,t){return e?`import: from ${e.slice(0,8)}..${t.slice(0,8)}`:`import: initial at ${t.slice(0,8)}`}const SUBJECT_LINE_BREAK_RE=RegExp(`[\\r\\n\\v\\f\\u0085\\u2028\\u2029]`,`g`);function stripLineBreaks(e){return e.replace(SUBJECT_LINE_BREAK_RE,` `)}function composeCommitSubject(e,t){let s=stripLineBreaks(e);if(t.length===0)return s;if(t.length>=2)return`${s} (${t.length} edits)`;let[g]=t;if(g===void 0)return s;let S=stripLineBreaks(g),w=`${s} — ${S}`;if(w.length<=72)return w;let E=`${s} — `,D=72-E.length-1;return D<=0?w.slice(0,72):`${E}${S.slice(0,D)}…`}function parseWriterId(e){return WRITER_ID_RE.test(e)?e.startsWith(`agent-`)?{id:e,classification:`agent`,isAgent:!0}:e.startsWith(`principal-`)?{id:e,classification:`principal`,isAgent:!1}:e===`file-system`?{id:e,classification:`classified-file-system`,isAgent:null}:e===`git-upstream`?{id:e,classification:`classified-git-upstream`,isAgent:null}:e===`openknowledge-service`?{id:e,classification:`classified-openknowledge-service`,isAgent:null}:{id:e,classification:`unknown`,isAgent:null}:{id:e,classification:`unknown`,isAgent:null}}var require_err_helpers=__commonJSMin$1(((e,t)=>{let s=e=>e&&typeof e.message==`string`,g=e=>{if(!e)return;let t=e.cause;if(typeof t==`function`){let t=e.cause();return s(t)?t:void 0}else return s(t)?t:void 0},S=(e,t)=>{if(!s(e))return``;let w=e.stack||``;if(t.has(e))return w+`
|
|
@@ -799,7 +799,7 @@ ${e.terminator}`}function Qa(e){return`(${Ee(e.body)})${ke(e.redirections)}`}fun
|
|
|
799
799
|
`,`
|
|
800
800
|
`).replaceAll(`\r`,`
|
|
801
801
|
`).split(`
|
|
802
|
-
`))s(S)||collectHrefsFromLine(stripHtmlComments(S,g).replace(/`[^`]*`/g,``),t);return[...t]}function resolveReferencedAssetWithinContentDir(e){let t=decodeHrefPath(e.href);if(!t||isRemoteOrOpaqueHref(t))return null;let s=extname(t).slice(1).toLowerCase();if(!ASSET_EXTENSIONS.has(s))return null;let g=resolveAssetProjectPath(t,e.fromDocName);if(!g)return null;let S=resolve(e.contentDir,g),w,E;try{if(w=normalize(realpathSync(S)),!isWithinContentDir(w,e.contentDir))return null;E=statSync(w)}catch(t){let s=errnoCode$1(t);return s!==`ENOENT`&&s!==`ENOTDIR`&&console.warn(`[asset-references] unexpected error resolving asset:`,e.href,t),null}return E.isFile()?{absolutePath:w,relativePath:toContentRelativePath(e.contentDir,w),stat:E}:null}function toContentRelativePath(e,t){let s=normalize(realpathSync(e));return normalize(t).slice(s.length+(s.endsWith(sep)?0:1)).split(sep).join(`/`)}function collectReferencedAssets(e){let t;try{t=normalize(realpathSync(e.contentDir))}catch(e){return console.warn(`[asset-references] could not resolve content directory:`,e),[]}let s=new Map;for(let[g,S]of e.fileIndex){let w=e.readMarkdown(S.canonicalPath);if(w!==null)for(let S of extractLocalAssetHrefs(w)){let w=resolveReferencedAssetWithinContentDir({contentDir:t,fromDocName:g,href:S});if(!w||e.isExcluded?.(w.relativePath))continue;let E=mediaKindForAssetPath(w.absolutePath),D=s.get(w.relativePath);if(D){D.referencedBy.includes(g)||D.referencedBy.push(g);continue}s.set(w.relativePath,{kind:`asset`,path:w.relativePath,assetExt:extname(w.relativePath).toLowerCase(),mediaKind:E,size:w.stat.size,modified:w.stat.mtime.toISOString(),referencedBy:[g]})}}return[...s.values()].sort((e,t)=>e.path.localeCompare(t.path))}Object.assign(mimes,{m4v:`video/mp4`,mkv:`video/x-matroska`,flac:`audio/flac`});function assetContentTypeForPath(e){return mimes[extname(e).slice(1).toLowerCase()]??null}function createAssetServeMiddleware(e){let{contentFilter:t,contentSirv:s,inlineExtensions:g,assetExtensions:S,blocklistExtensions:w}=e;return(e,E,D)=>{let O;try{O=decodeURIComponent(e.url?.split(`?`)[0]?.replace(/^\//,``)??``)}catch{return D()}if(!O||t.
|
|
802
|
+
`))s(S)||collectHrefsFromLine(stripHtmlComments(S,g).replace(/`[^`]*`/g,``),t);return[...t]}function resolveReferencedAssetWithinContentDir(e){let t=decodeHrefPath(e.href);if(!t||isRemoteOrOpaqueHref(t))return null;let s=extname(t).slice(1).toLowerCase();if(!ASSET_EXTENSIONS.has(s))return null;let g=resolveAssetProjectPath(t,e.fromDocName);if(!g)return null;let S=resolve(e.contentDir,g),w,E;try{if(w=normalize(realpathSync(S)),!isWithinContentDir(w,e.contentDir))return null;E=statSync(w)}catch(t){let s=errnoCode$1(t);return s!==`ENOENT`&&s!==`ENOTDIR`&&console.warn(`[asset-references] unexpected error resolving asset:`,e.href,t),null}return E.isFile()?{absolutePath:w,relativePath:toContentRelativePath(e.contentDir,w),stat:E}:null}function toContentRelativePath(e,t){let s=normalize(realpathSync(e));return normalize(t).slice(s.length+(s.endsWith(sep)?0:1)).split(sep).join(`/`)}function collectReferencedAssets(e){let t;try{t=normalize(realpathSync(e.contentDir))}catch(e){return console.warn(`[asset-references] could not resolve content directory:`,e),[]}let s=new Map;for(let[g,S]of e.fileIndex){let w=e.readMarkdown(S.canonicalPath);if(w!==null)for(let S of extractLocalAssetHrefs(w)){let w=resolveReferencedAssetWithinContentDir({contentDir:t,fromDocName:g,href:S});if(!w||e.isExcluded?.(w.relativePath))continue;let E=mediaKindForAssetPath(w.absolutePath),D=s.get(w.relativePath);if(D){D.referencedBy.includes(g)||D.referencedBy.push(g);continue}s.set(w.relativePath,{kind:`asset`,path:w.relativePath,assetExt:extname(w.relativePath).toLowerCase(),mediaKind:E,size:w.stat.size,modified:w.stat.mtime.toISOString(),referencedBy:[g]})}}return[...s.values()].sort((e,t)=>e.path.localeCompare(t.path))}Object.assign(mimes,{m4v:`video/mp4`,mkv:`video/x-matroska`,flac:`audio/flac`});function assetContentTypeForPath(e){return mimes[extname(e).slice(1).toLowerCase()]??null}function createAssetServeMiddleware(e){let{contentFilter:t,contentSirv:s,inlineExtensions:g,assetExtensions:S,blocklistExtensions:w}=e;return(e,E,D)=>{let O;try{O=decodeURIComponent(e.url?.split(`?`)[0]?.replace(/^\//,``)??``)}catch{return D()}let k=extname(O).slice(1).toLowerCase(),j=k===`md`||k===`mdx`;if(!O||t.isPathIgnored(O)||!j&&!S.has(k))return D();E.setHeader(`X-Content-Type-Options`,`nosniff`),j||(g.has(k)?E.setHeader(`Content-Disposition`,`inline`):E.setHeader(`Content-Disposition`,`attachment`)),k===`svg`&&E.setHeader(`Content-Security-Policy`,`sandbox; default-src 'none'; style-src 'unsafe-inline'`),s(e,E,()=>{if(!E.headersSent){if(S.has(k)||w.has(k)){E.statusCode=404,E.end();return}D()}})}}function resolveContentDir(e,t){return resolve(t,e.content.dir)}function getLocalDir(e){return resolve(e,`.ok`,LOCAL_DIR)}function resolveLockDir(e){return getLocalDir(e)}function resolveWithinRoot(e,t){if(typeof e!=`string`||!isAbsolute(e))return{ok:!1,reason:`root path is not absolute: ${String(e)}`};if(typeof t!=`string`)return{ok:!1,reason:`path must be a string`};if(t.includes(`\0`))return{ok:!1,reason:`path contains a NUL byte`};let s=resolve(e),g=resolve(s,t),S=relative(s,g);return S===``?{ok:!0,abs:g,rel:``}:S===`..`||S.startsWith(`../`)||isAbsolute(S)?{ok:!1,reason:`path "${t}" escapes the configured root`}:{ok:!0,abs:g,rel:S}}const ROUTED_CWD_DESCRIPTION="Absolute host path inside the target Open Knowledge project. Required when the MCP server is registered globally (e.g. `npx @inkeep/open-knowledge mcp` once at the host level, routing per call), unless the MCP client advertises exactly one root via the `roots` capability — that single root is then used as the implicit `cwd`. Optional when the server is anchored to a single project (the per-project HTTP MCP server defaults to its configured project root).",summaryArgSchema=string().max(200).optional().describe(`Optional one-line user-outcome description (≤80 chars). Appears as a bullet in the timeline.`);function textResult(e,t){return{content:[{type:`text`,text:e}],...t?{isError:!0}:{}}}function textPlusStructured(e,t,s){return{content:[{type:`text`,text:e}],structuredContent:t,...s?{isError:!0}:{}}}const HOCUSPOCUS_NOT_RUNNING_ERROR="Error: Hocuspocus server is not running. Start it with `open-knowledge start`, then retry.\nFor disk-only writes without real-time sync, use your native Edit tool directly.",ROLE_LABEL={ingest:`raw-sources layer (preserve external material, no analysis)`,research:`wiki layer, provisional (synthesize findings that can still change)`,consolidate:`wiki layer, canonical (promote stabilized research to source-of-truth)`},ROLE_BEFORE={ingest:"user shares a URL or file they want preserved, or `research` needs raw sources",research:"`ingest` has captured the relevant sources (or the user points at one)",consolidate:"`research` has produced a provisional article AND a decision has actually been made"},ROLE_AFTER={ingest:"often `research` on the same topic — or just stop; raw preservation is frequently enough on its own",research:"usually stop (research lives as provisional indefinitely) or `consolidate` once a decision lands",consolidate:"update 2–3 neighbor docs to link the new canonical article; research articles it supersedes gain a `superseded_by` pointer"};function buildWorkflowFrame(e){return`## Where this fits
|
|
803
803
|
|
|
804
804
|
Open Knowledge accretes a persistent wiki through three workflow tools, mapped to [Karpathy's three-layer knowledge-base pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f):
|
|
805
805
|
|
|
@@ -1873,12 +1873,12 @@ superseded_by: <path-to-new-canonical-article>.md
|
|
|
1873
1873
|
- **Don't rewrite research prose verbatim** — canonical articles have a different voice (direct, decided) than research (exploratory, provisional)
|
|
1874
1874
|
- **Don't skip the supersedes / superseded_by links** — the audit trail matters for future readers
|
|
1875
1875
|
`}const DESCRIPTION$25=[`Promote research into a canonical article inside the project content directory. Canonical, not provisional — the output is the source of truth for future agents.`,``,`**Use when:**`,`- A team has made a decision after research and wants the outcome committed as canonical knowledge`,`- Compacting several provisional research notes into one authoritative article`,`- A developer asks to "consolidate" or "finalize" knowledge on a topic`,``,`**Triggers on:**`,`- "consolidate", "finalize", "promote to canonical", "make this official"`,`- User says the team has decided and wants the outcome written as canonical`,`- Research has stabilized and a destination article is needed`].join(`
|
|
1876
|
-
`);function register$25(e,t){e.tool(`consolidate`,DESCRIPTION$25,{topic:string().describe(`The topic to consolidate into a canonical article`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);return s.ok?textPlusStructured(buildBody$2(e.topic,s.config.content.dir),{previewUrl:null}):textResult(`Error: ${s.error}`,!0)})}const ELECTRON_PROTOCOL_ENV_VAR=`OK_ELECTRON_PROTOCOL_HOST
|
|
1876
|
+
`);function register$25(e,t){e.tool(`consolidate`,DESCRIPTION$25,{topic:string().describe(`The topic to consolidate into a canonical article`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);return s.ok?textPlusStructured(buildBody$2(e.topic,s.config.content.dir),{previewUrl:null}):textResult(`Error: ${s.error}`,!0)})}const PREVIEW_URL_SOURCES=[`electron-protocol`,`lock`],ELECTRON_PROTOCOL_ENV_VAR=`OK_ELECTRON_PROTOCOL_HOST`;function encodeDocName(e){return e.split(`/`).map(encodeURIComponent).join(`/`)}async function resolvePreviewUrlForTool(e,t,s){let g=s??await t.resolveCwd(),S=resolveContentDir(await resolveConfig(t.config,g),g);return resolvePreviewUrl(e,{lockDir:resolveLockDir(g),contentDir:S})}function resolveUiInfo(e){try{let t=readUiLock(e.lockDir);if(t&&t.port>0)return{baseUrl:`http://localhost:${t.port}`,port:t.port}}catch(t){process.stderr.write(`[preview-url] readUiLock failed at ${e.lockDir} while building ui block: ${t instanceof Error?t.message:String(t)}\n`)}return{baseUrl:null,port:null}}async function buildListResolver(e,t){let s=t??await e.resolveCwd(),g=resolveContentDir(await resolveConfig(e.config,s),s),S={lockDir:resolveLockDir(s),contentDir:g};return{resolve:e=>resolvePreviewUrl(e,S),ui:resolveUiInfo(S)}}function docNameFromPath(e){let t=e.toLowerCase();return t.endsWith(`.md`)?e.slice(0,-3):t.endsWith(`.mdx`)?e.slice(0,-4):e}function resolvePreviewUrl(e,t){let s=`/#/${encodeDocName(e)}`;if(process.env[ELECTRON_PROTOCOL_ENV_VAR]===`1`&&t.contentDir)try{let s=realpathSync(t.contentDir);return{url:`openknowledge://open?project=${encodeURIComponent(s)}&doc=${encodeURIComponent(e)}`,source:`electron-protocol`}}catch(e){process.stderr.write(`[preview-url] realpathSync failed for ${t.contentDir}, falling through to http sources: ${e instanceof Error?e.message:String(e)}\n`)}try{let e=readUiLock(t.lockDir);if(e&&e.port>0)return{url:`http://localhost:${e.port}${s}`,source:`lock`}}catch(e){process.stderr.write(`[preview-url] readUiLock failed at ${t.lockDir}: ${e instanceof Error?e.message:String(e)}\n`)}return null}const DESCRIPTION$24=["[Requires: Hocuspocus server] Delete a document through the managed delete flow at `POST /api/delete-path` (kind: file).",`Closes all open agent sessions for the doc, unloads it from Hocuspocus, and removes the file from disk.`,``,`**Parameters:**`,"- `docName` — Document name, typically without extension. A trailing `.md` or `.mdx` is stripped automatically.",``,`**Notes:**`,'- Inbound wiki-links to the deleted doc become dead links (redlinks) — they are NOT rewritten. Call `get_backlinks({ docName: "your-doc" })` BEFORE deleting to see which docs link here, then update or remove those references first.',"- Deletion is irreversible from this tool. Use `save_version` beforehand if you may need to roll back.","- The structured response includes `previousPreviewUrl` (when a preview source resolves) so agents can close any stale preview tab pointing at the deleted doc.",``,`**Errors:**`,"- 400 — `docName` is not a valid relative content path.",`- 404 — document does not exist.`].join(`
|
|
1877
1877
|
`);function parseDeletedDocNames(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function register$24(e,t){e.tool(`delete_document`,DESCRIPTION$24,{docName:string().describe(`Document name to delete`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=normalizeDocName(e.docName);if(!w.ok)return textResult(w.error,!0);let E=t.identityRef?.current,D=await httpPost(S,`/api/delete-path`,{kind:`file`,path:w.docName,...E?{agentId:E.connectionId,agentName:E.displayName,clientName:E.clientInfo?.name,colorSeed:E.colorSeed}:{}});if(!D.ok){let e=D.error,t={ok:!1,error:e};return textPlusStructured(`Error: ${e}`,t,!0)}let O=parseDeletedDocNames(D.deletedDocNames),k=await resolvePreviewUrlForTool(w.docName,{config:t.config,resolveCwd:t.resolveCwd},g),j={ok:!0,deletedDocNames:O.length>0?O:[w.docName],...k?{previousPreviewUrl:k.url}:{}};return textPlusStructured(j.deletedDocNames.length===1?`Deleted ${j.deletedDocNames[0]}.`:`Deleted ${j.deletedDocNames.length} documents: ${j.deletedDocNames.join(`, `)}.`,j)})}const DESCRIPTION$23=[`[Operates on disk; no running OK server required] Delete a template.`,``,"**Targets.** Mirrors `write_template`:",'- `target: "project"` (default) — deletes `<folder>/.ok/templates/<name>.md` from the current project.','- `target: "user"` — deletes `~/.ok/templates/<name>.md` from the user-global library. The `folder` argument is ignored.',``,"Idempotent: deleting a template that does not exist returns success with `existed: false`. Auto-cleans empty `<folder>/.ok/templates/` and `<folder>/.ok/` directories.",``,`**Parameters:**`,'- `folder` — Project-root-relative folder. Empty / `.` means project root. Ignored when `target: "user"`.',"- `name` — Template filename without `.md` extension.",'- `target` (optional) — `"project"` (default) or `"user"`.'].join(`
|
|
1878
1878
|
`),InputSchema$5={folder:string().describe('Project-root-relative folder. Empty / `.` means project root. Ignored when `target: "user"`.'),name:string().min(1).regex(/^[A-Za-z0-9_-]+$/,"Template name must use letters, digits, `_`, or `-` only.").describe("Template filename without `.md` extension."),target:_enum([`project`,`user`]).optional().describe('Where the template lives. `"project"` (default) deletes from `<folder>/.ok/templates/`; `"user"` deletes from `~/.ok/templates/` (folder ignored).'),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},OutputSchema$5={result:union([object$1({ok:literal(!0),path:string(),existed:boolean(),cleanedEmpty:object$1({templatesDir:boolean(),okDir:boolean()})}),object$1({ok:literal(!1),error:object$1({code:string(),message:string()})})])};function register$23(e,t){e.registerTool(`delete_template`,{description:DESCRIPTION$23,inputSchema:InputSchema$5,outputSchema:OutputSchema$5,annotations:{readOnlyHint:!1,idempotentHint:!0,destructiveHint:!0}},async e=>{let s=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);if(!s.ok)return{isError:!0,content:[{type:`text`,text:`Error: ${s.error}`}]};let{cwd:g}=s,S={projectDir:g,folder:e.folder,name:e.name};e.target!==void 0&&(S.target=e.target);let w=applyTemplateDelete(S);if(!w.ok)return{isError:!0,structuredContent:{result:w},content:[{type:`text`,text:`${w.error.code}: ${w.error.message}`}]};let E=[w.existed?`Deleted template at ${w.path}`:`Template at ${w.path} did not exist (no-op)`];return w.cleanedEmpty.templatesDir&&E.push(`Removed empty .ok/templates/ directory`),w.cleanedEmpty.okDir&&E.push(`Removed empty .ok/ directory`),textPlusStructured(E.join(`
|
|
1879
1879
|
`),{result:w})})}const DESCRIPTION$22=[`[Requires: Hocuspocus server] Find-and-replace on a live document via the CRDT layer.`,`The patch is applied through Hocuspocus and propagated to all connected editors in real-time.`,"Use `offset` when you need to patch an exact occurrence; omit it to preserve first-match behavior.",``,'**Body-only.** Frontmatter-intersecting find/replace calls are rejected with HTTP 400. Frontmatter editing via MCP is currently unavailable — to change frontmatter, use `write_document` with `position: "replace"` and a payload that includes the new YAML block.',``,"**When rewriting prose, add `[[wiki-links]]` aggressively.** If the replacement mentions other documents or entities that should have their own page, link them as `[[Page Name]]`. Over-linking is the goal; underlinked documents lose their value in backlink-driven navigation.",``,`**Parameters:**`,"- `docName` — Document name, typically without extension. A trailing `.md` or `.mdx` is stripped automatically.","- `find` — Text to find (exact match)","- `replace` — Replacement text","- `offset` (optional) — Exact occurrence to patch, as a JavaScript string offset in the current markdown. If the document changed and the text no longer matches there, the server returns a stale-target error; re-run `suggest_links` to get fresh offsets.",'- `summary` — Optional one-line user-outcome description of this edit (≤80 chars). Appears as a bullet in the document timeline so readers can scan intent without opening every diff. Prefer outcome phrasing ("Fixed token-refresh race") over structural ("Changed 1 line"). Avoid including secrets or PII — summaries are persisted to git history.'].join(`
|
|
1880
|
-
`);function register$22(e,t){e.tool(`edit_document`,DESCRIPTION$22,{docName:string().describe(`Document name to edit`),find:string().describe(`Text to find (exact match)`),replace:string().describe(`Replacement text`),offset:number().int().min(0).optional().describe(`Exact occurrence to patch, as a JavaScript string offset in the current markdown`),summary:summaryArgSchema,cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,
|
|
1881
|
-
`);if(!
|
|
1880
|
+
`);function register$22(e,t){e.tool(`edit_document`,DESCRIPTION$22,{docName:string().describe(`Document name to edit`),find:string().describe(`Text to find (exact match)`),replace:string().describe(`Replacement text`),offset:number().int().min(0).optional().describe(`Exact occurrence to patch, as a JavaScript string offset in the current markdown`),summary:summaryArgSchema,cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=normalizeDocName(e.docName);if(!w.ok)return textResult(w.error,!0);let E=t.identityRef?.current,D=await httpPost(S,`/api/agent-patch`,{docName:w.docName,find:e.find,replace:e.replace,offset:e.offset,...e.summary===void 0?{}:{summary:e.summary},...E?{agentId:E.connectionId,agentName:E.displayName,clientName:E.clientInfo?.name,colorSeed:E.colorSeed}:{}});if(!D.ok)return textResult(`Error: ${D.error}`,!0);let O=resolveLockDir(g),k=resolvePreviewUrl(w.docName,{lockDir:O}),j=typeof D.subscriberCount==`number`?D.subscriberCount:void 0,F=(typeof D.systemSubscriberCount==`number`?D.systemSubscriberCount:void 0)===0,L=j===0,B=D.summary&&typeof D.summary==`object`?D.summary:void 0,H=typeof B?.hint==`string`?B.hint:void 0,q=[`Edit applied successfully.`];k&&q.push(`Preview: ${k.url}`),F&&q.push(k?`Open ${k.url} in your preview browser.`:`No preview attached. Start the UI.`),H&&q.push(H);let J=q.join(`
|
|
1881
|
+
`);if(!k&&!F&&!L&&!B)return textResult(J);let Y={};return k&&(Y.previewUrl=k.url,Y.previewUrlSource=k.source),F&&(Y.warning={message:`Open the previewUrl in your preview browser.`,action:`attach-preview-once`,previewUrl:k?.url??null}),B&&(Y.summary=B),textPlusStructured(J,Y)})}const PRODUCER_COMMANDS=new Set([`cat`,`ls`,`grep`,`find`]),PATH_FALLBACK_RE=/\b[\w./-]+\.(md|mdx)\b/g;function isWikiPath(e){return/\.(md|mdx)$/.test(e)}function normalize$1(e){let t=e.trim();return t?(t=t.replace(/\/+/g,`/`),t.startsWith(`./`)&&(t=t.slice(2)),t.endsWith(`/`)&&(t=t.slice(0,-1)),t):``}function argsOf(e){return e.args.slice(1)}function nonFlagArgs(e){return e.filter(e=>!e.startsWith(`-`))}function extractFromCat(e){return nonFlagArgs(argsOf(e)).filter(isWikiPath)}function extractFromLs(e,t){let s=nonFlagArgs(argsOf(t)),g=s.length>0?s[s.length-1]:``,S=g&&g!==`.`?normalize$1(g):``,w=[];S&&w.push(S);for(let t of e.split(`
|
|
1882
1882
|
`)){let e=t.trim();if(!e||/\.[a-z0-9]+$/i.test(e)&&!isWikiPath(e))continue;let s=S?`${S}/${e}`:e;w.push(s)}return w}function extractFromGrep(e){let t=[];for(let s of e.split(`
|
|
1883
1883
|
`)){if(!s)continue;let e=s.indexOf(`:`);if(e<0)continue;let g=normalize$1(s.slice(0,e));isWikiPath(g)&&t.push(g)}return t}function extractFromFind(e){let t=[];for(let s of e.split(`
|
|
1884
1884
|
`)){let e=normalize$1(s);e&&isWikiPath(e)&&t.push(e)}return t}function extractFromHeadTail(e){return nonFlagArgs(argsOf(e)).filter(isWikiPath)}function headTailActsAsProducer(e){return nonFlagArgs(argsOf(e)).length>0}function fallback(e){let t=[],s=e.matchAll(PATH_FALLBACK_RE);for(let e of s)t.push(normalize$1(e[0]));return t}function extractReferencedPaths(e,t){let s=null;for(let e=t.length-1;e>=0;e--){let g=t[e];if(PRODUCER_COMMANDS.has(g.command)){s=g;break}if((g.command===`head`||g.command===`tail`)&&headTailActsAsProducer(g)){s=g;break}}let g;if(!s)g=fallback(e);else{switch(s.command){case`cat`:g=extractFromCat(s);break;case`ls`:g=extractFromLs(e,s);break;case`grep`:g=extractFromGrep(e);break;case`find`:g=extractFromFind(e);break;case`head`:case`tail`:g=extractFromHeadTail(s);break;default:g=fallback(e)}g.length===0&&(g=fallback(e))}let S=new Set,w=[];for(let e of g){let t=normalize$1(e);!t||S.has(t)||(S.add(t),w.push(t))}return w}function shellEscape(e){return e===``?`''`:/^[\w.\-/]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}const MAX_STDOUT_BYTES=16*1024*1024;var StdoutOverflowError=class extends Error{limitBytes;actualBytes;partial;constructor(e,t,s){super(`Output exceeded ${e} byte buffer (got ${t}); narrow the command`),this.name=`StdoutOverflowError`,this.limitBytes=e,this.actualBytes=t,this.partial=s}};function createBashInstance(e){if(!isAbsolute(e))throw Error(`createBashInstance: cwd must be absolute (got: ${e})`);return new xt({cwd:`/`,fs:new Ss({root:resolve(e),allowSymlinks:!1})})}async function execBash(e,t){let s=await e.exec(t);if(s.stdout.length>MAX_STDOUT_BYTES)throw new StdoutOverflowError(MAX_STDOUT_BYTES,s.stdout.length,{stdout:s.stdout.slice(0,MAX_STDOUT_BYTES),stderr:s.stderr,exitCode:s.exitCode});return{stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode}}function normalizeGrepGlob(e){return e.startsWith(`**/`)?e.slice(3):e}async function grep(e,t,s={}){let g=createBashInstance(t),S=[`-rn`,`-F`];(s.caseInsensitive??!0)&&S.push(`-i`);for(let e of s.include??[])S.push(`--include=${shellEscape(normalizeGrepGlob(e))}`);for(let e of s.exclude??[])S.push(`--exclude=${shellEscape(normalizeGrepGlob(e))}`),S.push(`--exclude-dir=${shellEscape(normalizeGrepGlob(e))}`);let w=s.paths?.length?s.paths.map(shellEscape):[`.`],E=`grep ${S.join(` `)} ${shellEscape(e)} ${w.join(` `)}`,D;try{D=await execBash(g,E)}catch(e){if(e instanceof StdoutOverflowError)D=e.partial;else throw e}if(D.exitCode===1&&!D.stdout)return[];if(D.exitCode!==0&&D.exitCode!==1&&!D.stdout)throw Error(`grep exited ${D.exitCode}: ${D.stderr}`);let O=[],k=s.maxResults??1/0;for(let e of D.stdout.split(`
|
|
@@ -1889,8 +1889,8 @@ superseded_by: <path-to-new-canonical-article>.md
|
|
|
1889
1889
|
`),w=S[S.length-1]===``?S.length-1:S.length;if(w<g)return null;let E=S.slice(0,w),D=new Set(E.map(e=>{let t=e.indexOf(`:`);return t>0?e.slice(0,t):e})).size,O=e.slice(0,-1).map(e=>e.command).join(` | `);return{banner:`Output hit \`${s.command} -${g}\` cap (${w} lines, ${D} unique file${D===1?``:`s`}). The \`${O}\` stage may have had more matches that never reached stdout. For existence checks across many files, prefer \`grep -rl PATTERN <dir>\` (list files only, no head). For enumeration, drop the \`| ${s.command}\` or widen the cap.`}}function isDirectoryMeta(e){return e.type===`directory`}function formatDirectoryEntry(e){let t=[e.title?`**${e.title}** (${e.path}/)`:`**${e.path}/** (directory)`];e.description&&t.push(e.description),e.tags&&e.tags.length>0&&t.push(`tags: ${e.tags.join(`, `)}`);let s=[];return s.push(`${e.recursiveMdCount} md file${e.recursiveMdCount===1?``:`s`}`),e.childDirCount>0&&s.push(`${e.childDirCount} subdir${e.childDirCount===1?``:`s`}`),t.push(s.join(`, `)),e.mostRecentMd&&t.push(`most recent: ${e.mostRecentMd.title??e.mostRecentMd.path} (${e.mostRecentMd.path})`),e.truncated&&t.push(`scan truncated`),`- ${t.join(` — `)}`}function formatFileEntry(e){let t=[`**${e.title??e.path}** (${e.path})`];if(e.description&&t.push(e.description),e.tags.length>0&&t.push(`tags: ${e.tags.join(`, `)}`),e.backlinkCount!==null&&t.push(`backlinks: ${e.backlinkCount}`),e.forwardLinkCount!==null&&t.push(`forward links: ${e.forwardLinkCount}`),e.history&&e.history.length>0){let s=e.history.map(e=>{let t=e.writerClassification===`agent`?`agent: ${e.writerName}`:e.writerClassification===`principal`?`human: ${e.writerName}`:`${e.writerClassification}: ${e.writerName}`;return`${e.hash.slice(0,7)} [${t}] ${e.message}`});t.push(`OK edits: ${s.join(` · `)}`)}if(e.projectHistory&&e.projectHistory.length>0){let s=e.projectHistory.map(e=>`${e.hash.slice(0,7)} ${e.authorName}: ${e.subject}`);t.push(`commits: ${s.join(` · `)}`)}return`- ${t.join(` — `)}`}function buildStdoutProvenance(e,t,s){let g=null;for(let t=e.length-1;t>=0;t--){let s=e[t],S=s.command;if(S===`ls`||S===`cat`){g=s;break}if((S===`head`||S===`tail`)&&nonFlagArgs(argsOf(s)).length>0){g=s;break}}if(!g)return``;let S=nonFlagArgs(argsOf(g));if(g.command===`ls`){let e=S[S.length-1];if(!e||e===`.`)return``;let s=e.replace(/\/+/g,`/`);return s.startsWith(`./`)&&(s=s.slice(2)),s.endsWith(`/`)&&(s=s.slice(0,-1)),!s||!t.has(s)?``:`${s}/:\n`}let w=S.filter(e=>/\.(md|mdx)$/.test(e)&&s.has(e));return w.length===1?`==> ${w[0]} <==\n`:``}function formatEnrichedBlock(e){if(e.length===0)return``;let t=[``,`### Referenced files`,``];for(let s of e)t.push(isDirectoryMeta(s)?formatDirectoryEntry(s):formatFileEntry(s));return t.join(`
|
|
1890
1890
|
`)}async function classifyPaths(e,t){let s=[],g=[];return await Promise.all(t.map(async t=>{try{let S=await stat$1(resolve(e,t));S.isDirectory()?g.push(t):S.isFile()&&s.push(t)}catch{/\.(md|mdx)$/i.test(t)&&s.push(t)}})),{files:s,dirs:g}}function errorCategoryResult(e,t){return textPlusStructured(t,{enrichedPaths:[],error:{category:e,message:t}},!0)}function withPreviewUrls(e,t){return e.map(e=>{let s=t(docNameFromPath(e.path));return{...e,previewUrl:s?.url??null,...s?{previewUrlSource:s.source}:{}}})}async function buildExecResult(e,t){let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return errorCategoryResult(`shell_construct_blocked`,`exec failed: ${s.error}`);let{cwd:g,config:S,url:w}=s,E=parseCommand(e.command);if(`error`in E)return errorCategoryResult(E.error.category,E.error.message);let D=augmentStagesWithExcludes(E.stages),O=serializeStages(D),k=await snapshotMtimes(g),j=createBashInstance(g),F=``,L=``;try{let e=await execBash(j,O);F=e.stdout,L=e.stderr}catch(e){return e instanceof StdoutOverflowError?errorCategoryResult(`output_overflow`,`Output exceeded 16 MB buffer. Narrow the command (e.g., add a more specific grep pattern, use head, restrict the path).`):errorCategoryResult(`shell_construct_blocked`,`exec failed: ${e instanceof Error?e.message:String(e)}`)}let B=await snapshotMtimes(g),H=diffMtimes(k.snapshot,B.snapshot);if(H.changed.length>0)return errorCategoryResult(`security_invariant_violation`,`Security invariant violated: file(s) in the content directory were modified during a read-only exec call: ${H.changed.join(`, `)}. This indicates a parser bug; the command has been logged.`);let q=applySoftCap(F),J=extractReferencedPaths(F,D).filter(e=>resolveWithinRoot(g,e).ok),{files:Y,dirs:ee}=await classifyPaths(g,J),te=D.length===1&&D[0].command===`cat`&&Y.length===1,ne=await Promise.all(Y.map(e=>enrichPath(e,{projectDir:g,serverUrl:w},{includeRichFields:te}).catch(()=>({path:e,tags:[],frontmatter:{},backlinkCount:null,backlinks:null,forwardLinkCount:null,forwardLinks:null,history:null,historySource:null,projectHistory:null,projectHistorySource:null})))),ae=await Promise.all(ee.map(e=>enrichDirectory(e,{projectDir:g}).catch(()=>({path:e,type:`directory`,directMdCount:0,recursiveMdCount:0,childDirCount:0,truncated:!1}))));if(!te&&w&&ne.length>0){let e=await fetchBacklinkCountsBatch(w,ne.map(e=>pathToDocName$1(e.path))).catch(()=>null);if(e)for(let t of ne){let s=e.get(pathToDocName$1(t.path));typeof s==`number`&&(t.backlinkCount=s)}}let oe=new Map(ne.map(e=>[e.path,e])),se=new Map(ae.map(e=>[e.path,e])),ce=[];for(let e of J){let t=oe.get(e);if(t){ce.push(t);continue}let s=se.get(e);s&&ce.push(s)}let ue=detectBinaryArgs(D),de=[];ue.length>0&&de.push(`File${ue.length>1?`s`:``} ${ue.join(`, `)} appear${ue.length===1?`s`:``} to be binary (image/PDF/etc.) — exec returns text only (NG8). For binary retrieval, use native Read.`);let fe=detectHeadTailTruncation(D,F);fe&&de.push(fe.banner),L&&de.push(`stderr: ${L.trim()}`);let me=de.length>0?`${de.join(`
|
|
1891
1891
|
`)}\n\n`:``,ge=buildStdoutProvenance(D,se,oe)+q.text,_e=`${me}${ge}${formatEnrichedBlock(ce)}`,{resolve:ve,ui:ye}=await buildListResolver({config:S,resolveCwd:async()=>g}),Ce=withPreviewUrls(ce,ve),we=ye;return textPlusStructured(_e,{enrichedPaths:Ce,stdout:ge,stdoutTruncated:q.truncated,cwd:g,...we?{ui:we}:{},...de.length>0?{warnings:de}:{}})}function register$21(e,t){e.tool(`exec`,DESCRIPTION$21,{command:string().describe(`Read-only bash command (allowlist: cat, ls, grep, find, head, tail, wc, sort, uniq, cut; pipes OK)`),cwd:string().optional().describe("Absolute host path to run the command from. Defaults only when the MCP client advertises exactly one root; otherwise pass `cwd` explicitly.")},async e=>{try{return await buildExecResult(e,t)}catch(e){return errorCategoryResult(`shell_construct_blocked`,`exec handler error: ${e instanceof Error?e.message:String(e)}`)}})}const DESCRIPTION$20=[`[Requires: Hocuspocus server] Find all pages that link to a given page.`,`Returns source page names, resolved titles, and context snippets as JSON.`,``,`**Parameters:**`,'- `docName` — Target page docName, typically without extension (for example, "articles/project-alpha"). A trailing `.md` or `.mdx` is stripped automatically.'].join(`
|
|
1892
|
-
`);function register$20(e,t){e.tool(`get_backlinks`,DESCRIPTION$20,{docName:string().describe(`Target page docName`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=normalizeDocName(e.docName);if(!w.ok)return textResult(w.error,!0);let E=await httpGet(S,`/api/backlinks?docName=${encodeURIComponent(w.docName)}`);if(!E.ok)return textResult(`Error: ${E.error}`,!0);let{ok:D,...O}=E,k=O,{resolve:j,ui:F}=await buildListResolver(t,g),L=(k.backlinks??[]).map(e=>{let t=typeof e.source==`string`?e.source:null,s=t?j(t):null;return{...e,previewUrl:s?.url??null,...s?{previewUrlSource:s.source}:{}}}),B={...k,backlinks:L,ui:F,cwd:g};return textPlusStructured(JSON.stringify(B,null,2),B)})}const DESCRIPTION$19=[`[Operates on disk; no running OK server required] Read the effective merged Open Knowledge config (defaults → user → project).`,``,`Use this when you need to inspect the config mid-session — e.g., after a write that may have changed disk state, or to re-confirm the value of a field before reading it again.`,``,"Read returns the FULL merged config or a sub-tree when `path` is provided. There is no allowlist on reads — every field is readable.",``,"Note: the `server.*`, `mcp.*`, and `
|
|
1893
|
-
`),InputSchema$4={path:array(string()).optional().describe(`Dotted path as array of segments (e.g. ["
|
|
1892
|
+
`);function register$20(e,t){e.tool(`get_backlinks`,DESCRIPTION$20,{docName:string().describe(`Target page docName`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=normalizeDocName(e.docName);if(!w.ok)return textResult(w.error,!0);let E=await httpGet(S,`/api/backlinks?docName=${encodeURIComponent(w.docName)}`);if(!E.ok)return textResult(`Error: ${E.error}`,!0);let{ok:D,...O}=E,k=O,{resolve:j,ui:F}=await buildListResolver(t,g),L=(k.backlinks??[]).map(e=>{let t=typeof e.source==`string`?e.source:null,s=t?j(t):null;return{...e,previewUrl:s?.url??null,...s?{previewUrlSource:s.source}:{}}}),B={...k,backlinks:L,ui:F,cwd:g};return textPlusStructured(JSON.stringify(B,null,2),B)})}const DESCRIPTION$19=[`[Operates on disk; no running OK server required] Read the effective merged Open Knowledge config (defaults → user → project).`,``,`Use this when you need to inspect the config mid-session — e.g., after a write that may have changed disk state, or to re-confirm the value of a field before reading it again.`,``,"Read returns the FULL merged config or a sub-tree when `path` is provided. There is no allowlist on reads — every field is readable.",``,"Note: the `server.*`, `mcp.*`, `github.*`, and `preview.*` config sub-trees were removed; their values are now built-in constants in `@inkeep/open-knowledge-core` (or hardcoded behavior, in the case of `preview.*`). Reading those paths returns `exists: false`.",``,`**Parameters:**`,'- `path` (optional) — Dotted-segments array. `["content"]` returns the content sub-tree; `["appearance", "theme"]` returns just that leaf. Omit for full config.',"- `cwd` (optional) — Project root (see `cwd` description below)."].join(`
|
|
1893
|
+
`),InputSchema$4={path:array(string()).optional().describe(`Dotted path as array of segments (e.g. ["appearance","theme"]). Omit to return the full merged config.`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},OutputSchema$4={value:unknown().describe(`Resolved config value at the requested path (or full config).`),exists:boolean().optional().describe('Whether the requested path resolved to a value. `false` distinguishes "path absent" from "path explicitly set to null"; absent on full-config reads.'),path:array(string()).optional().describe(`Echo of the requested dotted path (empty when reading the full config).`)};function readConfigPath(e,t){let s=e;for(let e of t){if(typeof s!=`object`||!s)return;s=s[e]}return s}function register$19(e,t){e.registerTool(`get_config`,{description:DESCRIPTION$19,inputSchema:InputSchema$4,outputSchema:OutputSchema$4,annotations:{readOnlyHint:!0,idempotentHint:!0}},async e=>{let s=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);if(!s.ok)return{isError:!0,content:[{type:`text`,text:`Error: ${s.error}`}]};let g=e.path??[],S=g.length>0?readConfigPath(s.config,g):s.config;return g.length>0&&S===void 0?textPlusStructured(`(no value at ${g.join(`.`)})`,{value:null,exists:!1,path:g}):textPlusStructured(JSON.stringify(S,null,2),{value:S,exists:!0,path:g})})}const DESCRIPTION$18=[`[Requires: Hocuspocus server] Find missing internal page targets across the corpus.`,`Returns grouped dead links keyed by missing target with source-doc rows as JSON.`,``,`**Parameters:**`,"- `sourceDocNames` (optional) — Referring source docs to narrow the audit with OR semantics"].join(`
|
|
1894
1894
|
`);function register$18(e,t){e.tool(`get_dead_links`,DESCRIPTION$18,{sourceDocNames:array(string()).optional().describe(`Referring source docs to narrow the audit with OR semantics`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=new URLSearchParams;for(let t of e.sourceDocNames??[]){let e=normalizeDocName(t);if(!e.ok)return textResult(e.error,!0);w.append(`sourceDocName`,e.docName)}let E=w.toString(),D=await httpGet(S,`/api/dead-links${E?`?${E}`:``}`);if(!D.ok)return textResult(`Error: ${D.error}`,!0);let{ok:O,...k}=D,j=k,{resolve:F,ui:L}=await buildListResolver(t,g),B=(j.deadLinks??[]).map(e=>{let t=typeof e.target==`string`?e.target:null,s=t?F(t):null,g=(e.sources??[]).map(e=>{let t=typeof e.source==`string`?e.source:null,s=t?F(t):null;return{...e,previewUrl:s?.url??null,...s?{previewUrlSource:s.source}:{}}});return{...e,sources:g,previewUrl:s?.url??null,...s?{previewUrlSource:s.source}:{}}}),H={...j,deadLinks:B,ui:L,cwd:g};return textPlusStructured(JSON.stringify(H,null,2),H)})}const DESCRIPTION$17=[`[Requires: Hocuspocus server] Find all pages that a given page links to.`,`Returns forward links as JSON.`,``,`**Parameters:**`,"- `docName` — Source page docName, typically without extension. A trailing `.md` or `.mdx` is stripped automatically."].join(`
|
|
1895
1895
|
`);function register$17(e,t){e.tool(`get_forward_links`,DESCRIPTION$17,{docName:string().describe(`Source page docName`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=normalizeDocName(e.docName);if(!w.ok)return textResult(w.error,!0);let E=await httpGet(S,`/api/forward-links?docName=${encodeURIComponent(w.docName)}`);if(!E.ok)return textResult(`Error: ${E.error}`,!0);let{ok:D,...O}=E,k=O,{resolve:j,ui:F}=await buildListResolver(t,g),L=(k.forwardLinks??[]).map(e=>{let t=e.kind===`doc`&&typeof e.docName==`string`?e.docName:null,s=t?j(t):null;return{...e,previewUrl:s?.url??null,...s?{previewUrlSource:s.source}:{}}}),B={...k,forwardLinks:L,ui:F,cwd:g};return textPlusStructured(JSON.stringify(B,null,2),B)})}const DESCRIPTION$16=[`[Requires: Hocuspocus server] List version history for a document.`,`Returns timeline entries from the shadow repo, sorted by timestamp descending.`,"Each entry includes a commit SHA that can be passed to `rollback_to_version`.",``,`**Parameters:**`,"- `docName` — Document name to query history for, typically without extension. A trailing `.md` or `.mdx` is stripped automatically.","- `branch` (optional) — Branch name (default: current branch)","- `limit` (optional) — Maximum entries to return (default 50, max 200)","- `offset` (optional) — Number of entries to skip for pagination (default 0)",'- `type` (optional) — Filter by entry type: "checkpoint", "upstream", or "wip"',"- `author` (optional) — Filter to entries by this author name or email","- `excludeAuthor` (optional) — Exclude entries by this author name or email"].join(`
|
|
1896
1896
|
`);function register$16(e,t){e.tool(`get_history`,DESCRIPTION$16,{docName:string().describe(`Document name to query history for`),branch:string().optional().describe(`Branch name (default: current branch)`),limit:number().int().min(1).max(200).optional().describe(`Maximum entries to return (default 50, max 200)`),offset:number().int().min(0).optional().describe(`Number of entries to skip for pagination (default 0)`),type:_enum([`checkpoint`,`upstream`,`wip`]).optional().describe(`Filter by entry type`),author:string().optional().describe(`Filter to entries by this author name or email`),excludeAuthor:string().optional().describe(`Exclude entries by this author name or email`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=normalizeDocName(e.docName);if(!w.ok)return textResult(w.error,!0);let E=new URLSearchParams;E.set(`docName`,w.docName),e.branch&&E.set(`branch`,e.branch),e.limit!=null&&E.set(`limit`,String(e.limit)),e.offset!=null&&E.set(`offset`,String(e.offset)),e.type&&E.set(`type`,e.type),e.author&&E.set(`author`,e.author),e.excludeAuthor&&E.set(`excludeAuthor`,e.excludeAuthor);let D=await httpGet(S,`/api/history?${E.toString()}`);if(!D.ok)return textResult(`Error: ${D.error}`,!0);let{ok:O,...k}=D,j=await resolvePreviewUrlForTool(w.docName,{config:t.config,resolveCwd:t.resolveCwd},g);return textPlusStructured(JSON.stringify(k,null,2),{...k,previewUrl:j?.url??null,...j?{previewUrlSource:j.source}:{}})})}const DESCRIPTION$15=[`[Requires: Hocuspocus server] Find the most-linked pages in the knowledge graph.`,`Returns hub pages ordered by inbound link count as JSON.`,``,`**Parameters:**`,"- `limit` (optional) — Maximum number of hubs to return (default 20)"].join(`
|
|
@@ -1898,7 +1898,7 @@ superseded_by: <path-to-new-canonical-article>.md
|
|
|
1898
1898
|
`);function register$14(e,t){e.tool(`get_orphans`,DESCRIPTION$14,{mode:_enum(ORPHAN_MODES).optional().describe(`Filter which type of graph disconnection to surface`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=await httpGet(S,`/api/orphans${e.mode?`?mode=${encodeURIComponent(e.mode)}`:``}`);if(!w.ok)return textResult(`Error: ${w.error}`,!0);let{ok:E,...D}=w,O=D,{resolve:k,ui:j}=await buildListResolver(t,g),F=(O.orphans??[]).map(e=>{let t=typeof e.docName==`string`?e.docName:null,s=t?k(t):null;return{...e,previewUrl:s?.url??null,...s?{previewUrlSource:s.source}:{}}}),L={...O,orphans:F,ui:j,cwd:g};return textPlusStructured(JSON.stringify(L,null,2),L)})}const BUILTIN_SKIP_DIRS=new Set([`node_modules`,`.venv`,`venv`,`env`,`__pycache__`,`vendor`,`dist`,`build`,`out`,`output`,`.next`,`.nuxt`,`.svelte-kit`,`.astro`,`.turbo`,`.cache`,`.parcel-cache`,`coverage`,`.git`,`.ok`,`Library`,`Applications`,`.Trash`]),IGNORE_FILE_NAMES=[`.gitignore`,`.okignore`];function createContentFilter(e){let{projectDir:t,contentDir:s,onAfterRebuild:g}=e,S=relative(t,s),w=S.startsWith(`..`),E,D,O,k=0,j=0,F=0;function L(){let e=(0,import_ignore.default)();e.add(`.git`);let g=[],L=0,B=0;for(let s of IGNORE_FILE_NAMES){let S=join(t,s);if(existsSync(S))try{let t=readFileSync(S,`utf-8`);L+=t.length;let s=parseIgnorePatterns(t);g.push(...s),e.add(s)}catch(e){console.warn(`[content-filter] Failed to read ${s} at ${S}:`,e)}}if(S&&!w)for(let t of IGNORE_FILE_NAMES){let g=join(s,t);if(existsSync(g))try{let t=readFileSync(g,`utf-8`);L+=t.length,B++;let s=parseIgnorePatterns(t).map(e=>prefixPattern(e,S));e.add(s)}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${g}:`,e)}}let H={value:L};B+=loadNestedIgnoreFiles(s,t,e,H),L=H.value;let q=g.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`));return E=e,D=g,O=q,k=g.length,j=B,F=L,{patternCount:k,nestedFileCount:j,bytes:F}}L();let B=new Map;function H(e){if(w)return!1;let t=S?`${S}/${e}`:e;return E.ignores(t)}populateDirCount(s,``,H,B);function q(e){let t=stripDocExtension(e);if(isSystemDoc(t)||isConfigDoc(t))return!0;for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return w?!1:H(e)}return{isExcluded(e){if(q(e))return!0;if(isSupportedDocFile(e))return!1;let t=extname(e).slice(1).toLowerCase();if(ASSET_EXTENSIONS.has(t)){let t=dirname(e),s=t===`.`?``:t;if((B.get(s)??0)>0)return!1}return!0},isDirExcluded(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;if(w)return!1;let t=S?`${S}/${e}`:e;return E.ignores(t)||E.ignores(`${t}/`)},isPathIgnored(e){return q(e)},getWatcherIgnoreGlobs(){return O},incrementMdDir(e){let t=e===`.`?``:e;B.set(t,(B.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,s=B.get(t)??0;s<=1?B.delete(t):B.set(t,s-1)},rebuildDirCount(){let e=new Map(B);B.clear();try{populateDirCount(s,``,H,B)}catch(t){for(let[t,s]of e)B.set(t,s);getLogger(`content-filter`).warn({err:t instanceof Error?t:Error(String(t))},`content-filter rebuildDirCount walk failed — retaining previous counts`)}},async rebuildIgnorePatterns(){let e=getLogger(`content-filter`),t=E,S=D,w=O,q=k,J=j,Y=F,ee=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async te=>{try{let t=L();B.clear(),populateDirCount(s,``,H,B);let S=Date.now()-ee;if(te.setAttributes({"ok.ignore.pattern_count":t.patternCount,"ok.ignore.nested_file_count":t.nestedFileCount,"ok.ignore.bytes":t.bytes}),e.info({patternCount:t.patternCount,nestedFileCount:t.nestedFileCount,bytes:t.bytes,durationMs:S},`content-filter rebuild succeeded`),g)try{g()}catch(t){e.warn({err:t instanceof Error?t:Error(String(t))},`content-filter onAfterRebuild callback threw — derived views may be stale`)}return{ok:!0,patternCount:t.patternCount,nestedFileCount:t.nestedFileCount,bytes:t.bytes,durationMs:S}}catch(g){E=t,D=S,O=w,k=q,j=J,F=Y,B.clear();try{populateDirCount(s,``,H,B)}catch(t){e.warn({err:t instanceof Error?t:Error(String(t))},`content-filter rollback dirCount re-walk failed — sibling-asset counts may be stale until next rebuild`)}let L=g instanceof Error?g.message:String(g);return e.warn({err:g instanceof Error?g:Error(L)},`content-filter rebuild failed — rolled back to previous state`),{ok:!1,error:{message:L}}}})}}}function populateDirCount(e,t,s,g){let S;try{S=readdirSync(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory for dir-count: ${e}`,t);return}for(let w of S){let S=t?`${t}/${w.name}`:w.name;if(w.isDirectory()){if(BUILTIN_SKIP_DIRS.has(w.name)||s(S)||s(`${S}/`))continue;populateDirCount(join(e,w.name),S,s,g)}else w.isFile()&&isSupportedDocFile(w.name)&&!s(S)&&g.set(t,(g.get(t)??0)+1)}}function parseIgnorePatterns(e){return e.split(`
|
|
1899
1899
|
`).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`#`))}function prefixPattern(e,t){return e.startsWith(`!`)?`!${t}/${e.slice(1)}`:`${t}/${e}`}function loadNestedIgnoreFiles(e,t,s,g){let S;try{S=readdirSync(e,{withFileTypes:!0})}catch(t){return console.warn(`[content-filter] Failed to read directory ${e}:`,t),0}let w=0;for(let E of S){if(!E.isDirectory()||BUILTIN_SKIP_DIRS.has(E.name))continue;let S=join(e,E.name),D=relative(t,S);if(!D.startsWith(`..`)&&!(s.ignores(D)||s.ignores(`${D}/`))){for(let e of IGNORE_FILE_NAMES){let t=join(S,e);if(existsSync(t))try{let e=readFileSync(t,`utf-8`);g.value+=e.length;let S=parseIgnorePatterns(e).map(e=>prefixPattern(e,D));s.add(S),w++}catch(s){console.warn(`[content-filter] Failed to read nested ${e} at ${t}:`,s)}}w+=loadNestedIgnoreFiles(S,t,s,g)}}return w}async function initContentDirStateAsync(e,t,s,g,S,w,E){let D;try{D=await readdir(e,{withFileTypes:!0})}catch(t){console.warn(`[content-filter] Failed to read directory ${e}:`,t);return}for(let O of D){let D=t?`${t}/${O.name}`:O.name;if(O.isDirectory()){if(BUILTIN_SKIP_DIRS.has(O.name))continue;let t=join(e,O.name);if(!w){let e=relative(s,t);if(e.startsWith(`..`)||g.ignores(e)||g.ignores(`${e}/`))continue;for(let s of IGNORE_FILE_NAMES){let S=join(t,s);if(existsSync(S))try{let t=parseIgnorePatterns(await readFile$1(S,`utf-8`));g.add(t.map(t=>prefixPattern(t,e)))}catch(e){console.warn(`[content-filter] Failed to read nested ${s} at ${S}:`,e)}}}await initContentDirStateAsync(t,D,s,g,S,w,E)}else if(O.isFile()&&isSupportedDocFile(O.name)){if(!w){let e=S?`${S}/${D}`:D;if(g.ignores(e))continue}E.set(t,(E.get(t)??0)+1)}}}async function createContentFilterAsync(e){let{projectDir:t,contentDir:s,onAfterRebuild:g}=e,S=relative(t,s),w=S.startsWith(`..`),E=(0,import_ignore.default)(),D=[],O=new Map;function k(e){if(w)return!1;let t=S?`${S}/${e}`:e;return E.ignores(t)}function j(e){let t=stripDocExtension(e);if(isSystemDoc(t)||isConfigDoc(t))return!0;for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;return w?!1:k(e)}async function F(){let e=(0,import_ignore.default)();e.add(`.git`);let g=[];for(let s of IGNORE_FILE_NAMES){let S=join(t,s);if(existsSync(S))try{let t=parseIgnorePatterns(await readFile$1(S,`utf-8`));g.push(...t),e.add(t)}catch(e){console.warn(`[content-filter] Failed to read ${s} at ${S}:`,e)}}if(S&&!w)for(let t of IGNORE_FILE_NAMES){let g=join(s,t);if(existsSync(g))try{let t=parseIgnorePatterns(await readFile$1(g,`utf-8`));e.add(t.map(e=>prefixPattern(e,S)))}catch(e){console.warn(`[content-filter] Failed to read ${t} at ${g}:`,e)}}let k=new Map;await initContentDirStateAsync(s,``,t,e,S,w,k),E=e,D=g.filter(e=>e.length>0&&!e.startsWith(`!`)&&!e.startsWith(`#`)),O.clear();for(let[e,t]of k)O.set(e,t)}return await F(),{isExcluded(e){if(j(e))return!0;if(isSupportedDocFile(e))return!1;let t=extname(e).slice(1).toLowerCase();if(ASSET_EXTENSIONS.has(t)){let t=dirname(e),s=t===`.`?``:t;if((O.get(s)??0)>0)return!1}return!0},isDirExcluded(e){for(let t of e.split(`/`))if(BUILTIN_SKIP_DIRS.has(t))return!0;if(w)return!1;let t=S?`${S}/${e}`:e;return E.ignores(t)||E.ignores(`${t}/`)},isPathIgnored(e){return j(e)},getWatcherIgnoreGlobs(){return D},incrementMdDir(e){let t=e===`.`?``:e;O.set(t,(O.get(t)??0)+1)},decrementMdDir(e){let t=e===`.`?``:e,s=O.get(t)??0;s<=1?O.delete(t):O.set(t,s-1)},rebuildDirCount(){let e=new Map(O);O.clear();try{populateDirCount(s,``,k,O)}catch(t){for(let[t,s]of e)O.set(t,s);getLogger(`content-filter`).warn({err:t instanceof Error?t:Error(String(t))},`content-filter rebuildDirCount walk failed — retaining previous counts`)}},async rebuildIgnorePatterns(){let e=getLogger(`content-filter`),t=E,s=D,S=new Map(O),w=Date.now();return withSpan(`config.ignore.rebuild`,{attributes:{}},async k=>{try{await F();let t=Date.now()-w;if(k.setAttributes({"ok.ignore.pattern_count":D.length,"ok.ignore.nested_file_count":0,"ok.ignore.bytes":0}),e.info({durationMs:t},`content-filter async rebuild succeeded`),g)try{g()}catch(t){e.warn({err:t instanceof Error?t:Error(String(t))},`content-filter onAfterRebuild callback threw — derived views may be stale`)}return{ok:!0,patternCount:D.length,nestedFileCount:0,bytes:0,durationMs:t}}catch(g){E=t,D=s,O.clear();for(let[e,t]of S)O.set(e,t);let w=g instanceof Error?g.message:String(g);return e.warn({err:g instanceof Error?g:Error(w)},`content-filter async rebuild failed — rolled back`),{ok:!1,error:{message:w}}}})}}}const DESCRIPTION$13=["Find every line that literally contains a string, grouped by file with frontmatter metadata. For ranked retrieval that mirrors cmd-K, use `search`.",``,`Matches are grouped by file; each file is annotated with its title, description, and tags so you can judge relevance without opening it first.`,``,`**Use when:**`,`- Finding every occurrence of a literal phrase across the wiki`,`- Auditing a term, identifier, or quote — coverage matters more than ranking`,``,"**When the project has `.ok/`**, strongly prefer this over your native `Grep` for wiki search — results include article metadata so you can skip irrelevant matches without extra reads. In projects without `.ok/`, use native `Grep` as usual.",``,`**Parameters:**`,"- `query` — Literal text to search for (fixed-string match, no regex)","- `case_sensitive` (optional, default false) — case-sensitive match","- `cwd` (optional) — Project root the grep runs against. Defaults only when the MCP client advertises exactly one root."].join(`
|
|
1900
1900
|
`);function groupByFile(e){let t=new Map;for(let s of e){let e=t.get(s.path);e?e.push(s):t.set(s.path,[s])}return[...t.entries()].map(([e,t])=>({path:e,matches:t}))}async function buildGrepResult(e,t){let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)throw Error(s.error);let{cwd:g,config:S,url:w}=s,E=50,D=await grep(e.query,g,{caseInsensitive:!(e.case_sensitive??!1),include:[`**/*.md`,`**/*.mdx`],exclude:[`node_modules`,`.git`,`.claude`,`.changeset`,`.ok`],maxResults:51}),O=resolveContentDir(S,g),k=createContentFilter({projectDir:g,contentDir:O}),j=D.filter(e=>{let t=relative(O,resolve(g,e.path));return t.startsWith(`..`)?!1:!k.isExcluded(t)}),F=D.length>50,L=j.slice(0,50),{resolve:B,ui:H}=await buildListResolver({config:S,resolveCwd:async()=>g},g);if(L.length===0)return{text:`No matches for "${e.query}".`,structured:{query:e.query,matchCount:0,fileCount:0,truncated:!1,results:[],ui:H,cwd:g}};let q=groupByFile(L),J=new Map;await Promise.all(q.map(async e=>{try{let t=await enrichPath(e.path,{projectDir:g,serverUrl:w});J.set(e.path,t)}catch{}}));let Y=[];Y.push(`## Grep results for "${e.query}" (${L.length} match${L.length===1?``:`es`} in ${q.length} file${q.length===1?``:`s`})`,``);let ee=[];for(let e of q){let t=J.get(e.path),s=t?.title??e.path;Y.push(`### ${s} (${e.path})`),t?.tags?.length&&Y.push(`Tags: ${t.tags.join(`, `)}`),t?.description&&Y.push(`${t.description}`);for(let t of e.matches)Y.push(`- Line ${t.line}: ${t.text}`);Y.push(``);let g=docNameFromPath(e.path),S=B(g);ee.push({path:e.path,docName:g,title:t?.title??null,description:t?.description??null,tags:t?.tags??[],matches:e.matches.map(e=>({line:e.line,text:e.text})),previewUrl:S?.url??null,...S?{previewUrlSource:S.source}:{}})}return F&&Y.push(`_${L.length} of ${D.length}+ matches shown (max 50). Refine your query to narrow results._`),{text:Y.join(`
|
|
1901
|
-
`),structured:{query:e.query,matchCount:L.length,fileCount:q.length,truncated:F,results:ee,ui:H,cwd:g}}}const InputSchema$3={query:string().describe(`Literal text to search for`),case_sensitive:boolean().optional().describe(`Case-sensitive search (default false)`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},GrepResultRowSchema=object$1({path:string(),docName:string(),title:string().nullable(),description:string().nullable(),tags:array(string()),matches:array(object$1({line:number().int(),text:string()})),previewUrl:string().nullable(),previewUrlSource:_enum(
|
|
1901
|
+
`),structured:{query:e.query,matchCount:L.length,fileCount:q.length,truncated:F,results:ee,ui:H,cwd:g}}}const InputSchema$3={query:string().describe(`Literal text to search for`),case_sensitive:boolean().optional().describe(`Case-sensitive search (default false)`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},GrepResultRowSchema=object$1({path:string(),docName:string(),title:string().nullable(),description:string().nullable(),tags:array(string()),matches:array(object$1({line:number().int(),text:string()})),previewUrl:string().nullable(),previewUrlSource:_enum(PREVIEW_URL_SOURCES).optional()}),OutputSchema$3={cwd:string(),query:string(),matchCount:number().int(),fileCount:number().int(),truncated:boolean(),results:array(GrepResultRowSchema),ui:object$1({baseUrl:string().nullable(),port:number().nullable()})};function register$13(e,t){e.registerTool(`grep`,{description:DESCRIPTION$13,inputSchema:InputSchema$3,outputSchema:OutputSchema$3,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0}},async e=>{try{let{text:s,structured:g}=await buildGrepResult(e,t);return g?textPlusStructured(s,g):textResult(s)}catch(e){return textResult(`Error: ${e instanceof Error?e.message:String(e)}`,!0)}})}function buildBody$1(e,t){return`${buildWorkflowFrame(`ingest`)}Capture this external source into the project knowledge base as raw reference material. The KB is **closed-loop**: external sources are pulled INTO the knowledge base here so downstream docs cite local paths, never bare web URLs. This applies whether a user shared the source OR you fetched it yourself to ground a knowledge-base claim — agent-initiated fetches are not exempt. **Raw preservation only** — no summary, no analysis, no interpretation. Summarizing is the job of the \`research\` tool later.
|
|
1902
1902
|
|
|
1903
1903
|
Source: ${e}
|
|
1904
1904
|
|
|
@@ -2346,12 +2346,12 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
2346
2346
|
`);function register$6(e,t){e.tool(`rollback_to_version`,DESCRIPTION$6,{docName:string().describe(`Document name to restore`),commitSha:string().length(40).regex(/^[0-9a-f]+$/i).describe(`40-character commit SHA from the shadow repo timeline`),summary:summaryArgSchema.describe(`Optional one-line user-outcome description (≤80 chars). Defaults to "Restored to <sha-short>" when omitted. Appears as a bullet in the timeline.`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=normalizeDocName(e.docName);if(!w.ok)return textResult(w.error,!0);let E=w.docName,D=await httpGet(S,`/api/history/${e.commitSha}?docName=${encodeURIComponent(E)}`);if(!D.ok)return textResult(`Error: ${D.error??`Version not found`}`,!0);let O=t.identityRef?.current,k=await httpPost(S,`/api/rollback`,{docName:E,commitSha:e.commitSha,...e.summary===void 0?{}:{summary:e.summary},...O?{agentId:O.connectionId,agentName:O.displayName,clientName:O.clientInfo?.name,colorSeed:O.colorSeed}:{}});if(!k.ok)return textResult(`Error: ${k.error}`,!0);let j=k.summary&&typeof k.summary==`object`?k.summary:void 0,F=typeof j?.hint==`string`?j.hint:void 0,L=[`Restored "${E}" to version ${e.commitSha.slice(0,8)} (${D.author}, ${D.timestamp}). The change has been applied to all connected editors.`];F&&L.push(F);let B=await resolvePreviewUrlForTool(E,{config:t.config,resolveCwd:t.resolveCwd},g);return textPlusStructured(L.join(`
|
|
2347
2347
|
`),{previewUrl:B?.url??null,...B?{previewUrlSource:B.source}:{},...j?{summary:j}:{}})})}const DESCRIPTION$5=[`[Requires: Hocuspocus server] Save a version checkpoint of all documents.`,`Creates a checkpoint commit in the shadow repo and project repo,`,`preserving the current state of all documents. The checkpoint can later`,"be found via `get_history` and restored via `rollback_to_version`."].join(`
|
|
2348
2348
|
`);function register$5(e,t,s,g,S){e.tool(`save_version`,DESCRIPTION$5,{cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async(e={})=>{let w=await resolveProjectServerContext(g,t,s,e.cwd);if(!w.ok)return textResult(`Error: ${w.error}`,!0);if(!w.url)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let{url:E}=w,D=S?.current,O=await httpPost(E,`/api/save-version`,{...D?{writers:[{id:`agent-${D.connectionId}`,name:D.displayName,email:`agent-${D.connectionId}@openknowledge.local`}]}:{}});return O.ok?textPlusStructured(`Checkpoint saved. Checkpoint ref: ${O.checkpointRef}`,{checkpointRef:O.checkpointRef,previewUrl:null}):textResult(`Error: ${O.error}`,!0)})}const DESCRIPTION$4=["Find the most relevant pages for a query (ranked: title boost + body BM25 + recency). For literal-string matching across every line, use `grep`.",``,"Same engine and ranking the cmd-K palette uses. Returns a sorted list of page (and folder, with `omnibar` intent) hits with score signals plus a body snippet per page.",``,`**Use when:**`,`- Hunting for the canonical page on a topic`,`- Locating a doc by partial title or path segments`,`- Picking the best entry point before reading`,``,`**Parameters:**`,"- `query` — Search query (free-form; tokenized across title, name, path segments, and optionally body content).","- `intent` (optional) — `'omnibar'` searches title/path/folders only (fast); `'full_text'` includes body content. Default `'full_text'`.","- `scopes` (optional) — Override the result scope. Members: `'page'`, `'folder'`, `'content'`. Defaults derive from `intent`.","- `limit` (optional) — Max rows; default 20, max 100.","- `cwd` (optional) — Project root the query runs against.",``,"**Server requirement:** the Hocuspocus server must be running (`open-knowledge start`). If not, this tool returns a recovery hint; use `grep` as a server-free fallback."].join(`
|
|
2349
|
-
`),InputSchema$2={query:string().describe(`Search query — title, path, or body terms.`),intent:_enum([`omnibar`,`full_text`]).optional().describe(`'omnibar' for title/path/folder only (fast); 'full_text' includes body content. Default 'full_text'.`),scopes:array(_enum([`page`,`folder`,`content`])).optional().describe(`Override the default scope set. Members: 'page', 'folder', 'content'. Defaults derive from intent.`),limit:number().int().min(1).max(100).optional().describe(`Max rows; default 20, max 100.`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},SearchResultRowSchema=object$1({kind:_enum([`page`,`folder`]),path:string(),docName:string(),title:string().nullable(),score:number(),signals:object$1({lexical:number(),fullText:number(),recency:number()}),snippet:string().optional(),previewUrl:string().nullable(),previewUrlSource:_enum(
|
|
2349
|
+
`),InputSchema$2={query:string().describe(`Search query — title, path, or body terms.`),intent:_enum([`omnibar`,`full_text`]).optional().describe(`'omnibar' for title/path/folder only (fast); 'full_text' includes body content. Default 'full_text'.`),scopes:array(_enum([`page`,`folder`,`content`])).optional().describe(`Override the default scope set. Members: 'page', 'folder', 'content'. Defaults derive from intent.`),limit:number().int().min(1).max(100).optional().describe(`Max rows; default 20, max 100.`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},SearchResultRowSchema=object$1({kind:_enum([`page`,`folder`]),path:string(),docName:string(),title:string().nullable(),score:number(),signals:object$1({lexical:number(),fullText:number(),recency:number()}),snippet:string().optional(),previewUrl:string().nullable(),previewUrlSource:_enum(PREVIEW_URL_SOURCES).optional()}),OutputSchema$2={cwd:string(),query:string(),intent:string(),resultCount:number().int(),results:array(SearchResultRowSchema),elapsedMs:number().nullable(),ui:object$1({baseUrl:string().nullable(),port:number().nullable()})};function isSearchKind(e){return e===`page`||e===`folder`}function normalizeSignals(e){return{lexical:typeof e?.lexical==`number`?e.lexical:0,fullText:typeof e?.fullText==`number`?e.fullText:0,recency:typeof e?.recency==`number`?e.recency:0}}function formatResultsBlock(e){if(e.length===0)return``;let t=[];for(let s of e){let e=s.title?.trim()||s.path;t.push(`### ${e} (${s.path})`),t.push(`Score ${s.score.toFixed(2)} — kind: ${s.kind}`),s.snippet&&t.push(s.snippet),t.push(``)}return t.join(`
|
|
2350
2350
|
`)}function register$4(e,t){e.registerTool(`search`,{description:DESCRIPTION$4,inputSchema:InputSchema$2,outputSchema:OutputSchema$2,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0}},async e=>{try{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,config:S,url:w}=s;if(!w)return textResult(`${HOCUSPOCUS_NOT_RUNNING_ERROR}\nFor server-free literal-string search, use \`grep\` instead — it walks the filesystem and does not need Hocuspocus.`,!0);let E=e.intent??`full_text`,D=e.limit??20,O={query:e.query,intent:E,limit:D};e.scopes&&(O.scopes=e.scopes);let k=await httpPost(w,`/api/search`,O);if(!k.ok)return textResult(`Error: ${k.error}`,!0);let{resolve:j,ui:F}=await buildListResolver({config:S,resolveCwd:async()=>g},g),L=(k.results??[]).flatMap(e=>{if(!isSearchKind(e.kind)||typeof e.path!=`string`)return[];let t=docNameFromPath(e.path),s=j(t);return[{kind:e.kind,path:e.path,docName:t,title:e.title??null,score:typeof e.score==`number`?e.score:0,signals:normalizeSignals(e.signals),...e.snippet?{snippet:e.snippet}:{},previewUrl:s?.url??null,...s?{previewUrlSource:s.source}:{}}]}),B={cwd:g,query:e.query,intent:E,resultCount:L.length,results:L,elapsedMs:typeof k.elapsedMs==`number`?k.elapsedMs:null,ui:F},H=`## Search results for "${e.query}" (${L.length} hit${L.length===1?``:`s`}, intent: ${E})`;return textPlusStructured(L.length===0?`No matches for "${e.query}".`:`${H}\n\n${formatResultsBlock(L)}`,B)}catch(e){return textResult(`Error: ${e instanceof Error?e.message:String(e)}`,!0)}})}const DESCRIPTION$3=["[Operates on disk; no running OK server required] Upsert one or more folder rules — writes nested `<folder>/.ok/frontmatter.yml` files.",``,"Folder rules apply default frontmatter to every doc inside `<folder>/` (and its descendants via cascade). Open shape — any YAML-representable key is accepted. Common keys: `title`, `description`, `tags` (the well-known three) plus arbitrary additions like `status`, `team`, `owners`, `review_cycle`. Use this tool to add a new rule, replace an existing one keyed by `match`, or rename via `new_match`.",``,`**Cascade merge semantics (D6 generalized):** scalars (string / number / boolean / null) replace last-wins along the leaf → root walk; arrays union-and-dedup with first-occurrence preserved; objects replace last-wins.`,``,'Each `match` glob must resolve to a SINGLE target folder by walking leading literal segments — `"specs/**"` writes `specs/.ok/frontmatter.yml`. Multi-folder globs (e.g. `"specs/*/evidence/**"`, where the literal `evidence` follows `*`) are rejected with `MULTI_FOLDER_GLOB`; split into per-folder rules instead.',``,"Always pass an array — even for a single rule. Validation runs against every rule first; if any fails (e.g. `MULTI_FOLDER_GLOB`, `PATH_ESCAPE`), NO rules are applied to disk. Filesystem-level errors during the write phase (disk full, permissions) may leave a partial result — the error response includes `partiallyApplied` listing which rules already landed.",``,'**To remove a rule**, pass an empty `frontmatter: {}` — the merge collapses, the file is deleted, and `<folder>/.ok/` is auto-cleaned if no other tenant remains. To clear a SPECIFIC key while keeping others, set that key to `null` / `""` / `[]` in the patch.',``,`**Parameters:**`,"- `rules` — Array of `{match, frontmatter, new_match?}`.",' - `match` — Glob pattern that identifies the target folder (e.g. `"specs/**"`, `"meetings/prep-notes/**"`). Required.'," - `frontmatter` — Open `Record<string, unknown>` of key/value defaults. Common: `{title?, description?, tags?: string[]}`. Any other key persists too (`status`, `team`, etc.)."," - `new_match` — If set, move the rule from `match` to this new glob (deletes the old folder's frontmatter.yml + auto-cleans).","- `cwd` (optional) — Project root."].join(`
|
|
2351
2351
|
`),FolderRuleUpsertInputSchema=object$1({match:string().min(1).describe(`Glob pattern (e.g. "specs/**", "meetings/prep-notes/**") that identifies the target folder.`),frontmatter:record(string(),unknown()).refine(e=>!(`title`in e&&e.title!==null&&typeof e.title!=`string`||`description`in e&&e.description!==null&&typeof e.description!=`string`||`tags`in e&&e.tags!==null&&!Array.isArray(e.tags)),{message:"Well-known keys must match expected types when present: `title` (string|null), `description` (string|null), `tags` (string[]|null)."}).describe('Default frontmatter to apply to matched docs. Open shape — any YAML-representable key. Common: `{title?, description?, tags?: string[]}`; arbitrary keys (`status`, `team`, `owners`, `review_cycle`, …) also persist. Pass `{}` to remove the rule (auto-cleans `.ok/` if empty). Pass `key: null | "" | []` to clear that specific key while keeping others.'),new_match:string().min(1).optional().describe("If set, move the rule from `match` to this new folder (deletes the old folder's frontmatter.yml + auto-cleans).")}),InputSchema$1={rules:array(FolderRuleUpsertInputSchema).min(1).describe("One or more folder rules to upsert. Always an array — pass `[{...}]` for a single rule."),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},AppliedEntrySchema=object$1({match:string(),path:string(),action:_enum([`written`,`deleted`])}),SuccessOutputSchema=object$1({ok:literal(!0),applied:array(AppliedEntrySchema)}),ErrorOutputSchema=object$1({ok:literal(!1),error:object$1({code:_enum([`MULTI_FOLDER_GLOB`,`PATH_ESCAPE`,`BAD_PROJECT_DIR`,`WRITE_ERROR`]),message:string(),rule:string().optional()}),partiallyApplied:array(AppliedEntrySchema).optional()}),OutputSchema$1={result:union([SuccessOutputSchema,ErrorOutputSchema])};function register$3(e,t){e.registerTool(`set_folder_rule`,{description:DESCRIPTION$3,inputSchema:InputSchema$1,outputSchema:OutputSchema$1,annotations:{readOnlyHint:!1,idempotentHint:!0,destructiveHint:!1}},async e=>{let s=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);if(!s.ok)return{isError:!0,content:[{type:`text`,text:`Error: ${s.error}`}]};let{cwd:g}=s,S=applyNestedFolderRulesUpsert({projectDir:g,rules:e.rules.map(e=>({match:e.match,frontmatter:e.frontmatter??{},...e.new_match===void 0?{}:{new_match:e.new_match}}))});return S.ok?textPlusStructured(JSON.stringify(S,null,2),{result:S}):{isError:!0,structuredContent:{result:S},content:[{type:`text`,text:`${S.error.code}: ${S.error.message}`}]}})}const DESCRIPTION$2=[`[Requires: Hocuspocus server] Find missing link candidates for a target page.`,"Returns JSON with structure: `{ target: { docName, title, aliases }, mentions: [{ source, excerpt, offset }], truncated }`.","Each mention includes an `offset` you can pass to `edit_document` for precision patching.","When `truncated` is true, the scan hit its time budget before reading every admitted document.",``,`**Parameters:**`,'- `docName` — Target page docName, typically without extension (for example, "articles/project-alpha"). A trailing `.md` or `.mdx` is stripped automatically.'].join(`
|
|
2352
2352
|
`);function register$2(e,t){e.tool(`suggest_links`,DESCRIPTION$2,{docName:string().describe(`Target page docName`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=normalizeDocName(e.docName);if(!w.ok)return textResult(w.error,!0);let E=await httpGet(S,`/api/suggest-links?docName=${encodeURIComponent(w.docName)}`);if(!E.ok)return textResult(`Error: ${E.error}`,!0);let{ok:D,...O}=E,k=await resolvePreviewUrlForTool(w.docName,{config:t.config,resolveCwd:t.resolveCwd},g);return textPlusStructured(JSON.stringify(O,null,2),{...O,previewUrl:k?.url??null,...k?{previewUrlSource:k.source}:{}})})}const DESCRIPTION$1=[`[Requires: Hocuspocus server] Write markdown content to a document via the CRDT layer.`,`Content is applied through Hocuspocus and propagated to all connected editors in real-time.`,``,'**Frontmatter.** The markdown payload may include a YAML frontmatter block (`---`-fenced). To change frontmatter, call this tool with `position: "replace"` and a payload that includes the new YAML block — per-property MCP editing is currently unavailable. `edit_document` rejects frontmatter-intersecting find/replace calls.',``,'**Link liberally.** Every noun-phrase that names another document in this knowledge base should be a `[[wiki-link]]`, not plain prose. Backlinks are the primary navigation surface — underlinked documents become islands. Redlinks (links to pages that don\'t exist yet) are fine; they signal "this should exist." Prefer `[[Page Name]]` over Markdown `[text](./page.md)` — only wiki-links participate in the backlinks index.',``,"**Templates.** When creating a new doc, pass `template: \"<name>\"` to instantiate from a folder-scoped template. The name resolves against `templates_available` for the doc's parent folder (leaf → root walk-up; check `list_documents({ dir, depth: 1 })` to see the menu). The template's body + frontmatter become the doc's starting content; folder cascade merges naturally at read time. Templates scoped to a descendant subfolder are rejected for parent-folder targets. **`template` and `markdown` are mutually exclusive** — pass exactly one. To start from the template body and then customize, instantiate via `template` first, then call `edit_document` to fill placeholders.",``,`**Parameters:**`,'- `docName` — Document name, typically without extension (e.g., "my-doc" or "notes/meeting"). A trailing `.md` or `.mdx` is stripped automatically. New documents are created as `.md` by default; to create a `.mdx` file, first place it on disk, then use this tool for edits.',"- `markdown` — Markdown content to write. Required unless `template` is set (mutually exclusive — pass exactly one).","- `template` (optional) — Template name resolved against the parent folder's `templates_available`. The template body becomes the new doc verbatim. Cannot be combined with `markdown`.",'- `position` — Where to insert: "append", "prepend", or "replace". When `template` is set, `position` is forced to "replace".','- `summary` — Optional one-line user-outcome description of this edit (≤80 chars). Appears as a bullet in the document timeline so readers can scan intent without opening every diff. Prefer outcome phrasing ("Fixed token-refresh race") over structural ("Added 3 lines"). Avoid including secrets or PII — summaries are persisted to git history.'].join(`
|
|
2353
|
-
`);function register$1(e,t){e.tool(`write_document`,DESCRIPTION$1,{docName:string().describe(`Document name to write to`),markdown:string().optional().describe("Markdown content to write. Optional when `template` is set — the template body is used."),template:string().min(1).optional().describe(`Template name resolved against parent folder's templates_available (leaf → root walk-up; closest-wins on collision). See list_documents({ dir, depth: 1 }) to inspect the menu.`),position:_enum([`append`,`prepend`,`replace`]).describe(`Where to insert the content`),summary:summaryArgSchema,cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,
|
|
2354
|
-
`);if(!
|
|
2353
|
+
`);function register$1(e,t){e.tool(`write_document`,DESCRIPTION$1,{docName:string().describe(`Document name to write to`),markdown:string().optional().describe("Markdown content to write. Optional when `template` is set — the template body is used."),template:string().min(1).optional().describe(`Template name resolved against parent folder's templates_available (leaf → root walk-up; closest-wins on collision). See list_documents({ dir, depth: 1 }) to inspect the menu.`),position:_enum([`append`,`prepend`,`replace`]).describe(`Where to insert the content`),summary:summaryArgSchema,cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{cwd:g,url:S}=s;if(!S)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let w=normalizeDocName(e.docName);if(!w.ok)return textResult(w.error,!0);let E=t.identityRef?.current;if(e.template===void 0&&e.markdown===void 0)return textResult("Error: either `markdown` or `template` must be provided. Omitting both would write empty content.",!0);if(e.template!==void 0&&e.markdown!==void 0)return textResult("Error: TEMPLATE_AND_MARKDOWN_BOTH_SET — `template` and `markdown` are mutually exclusive. Pass one. The template body becomes the new doc verbatim; fill placeholders via subsequent `edit_document` calls.",!0);let D=e.markdown??``,O=e.position;if(e.template!==void 0){let t=parentFolderOf(w.docName),s=resolveTemplatesAvailable(g,t,{depth:1}),S=s.find(t=>t.name===e.template);if(!S)return textResult(`Error: template "${e.template}" not found for folder "${t||`.`}". Available: ${s.length===0?`(none)`:s.map(e=>`${e.name} [${e.scope}]`).join(`, `)}. Templates are resolved by walk-up (D7); check list_documents({ dir, depth: 1 }) at the parent folder to see the menu.`,!0);let k;try{k=readFileSync(resolve(g,S.path),`utf-8`)}catch(e){return textResult(`Error: failed to read template at ${S.path}: ${e.message}`,!0)}D=applySubstitution(k,{date:todayIsoUtc(),user:E?.displayName??``}),O=`replace`}let k=await httpPost(S,`/api/agent-write-md`,{docName:w.docName,markdown:D,position:O,...e.summary===void 0?{}:{summary:e.summary},...E?{agentId:E.connectionId,agentName:E.displayName,clientName:E.clientInfo?.name,colorSeed:E.colorSeed}:{}});if(!k.ok)return textResult(`Error: ${k.error}`,!0);let j=resolveLockDir(g),F=resolvePreviewUrl(w.docName,{lockDir:j}),L=typeof k.subscriberCount==`number`?k.subscriberCount:void 0,B=(typeof k.systemSubscriberCount==`number`?k.systemSubscriberCount:void 0)===0,H=L===0,q=Array.isArray(k.hints)?k.hints:void 0,J=k.summary&&typeof k.summary==`object`?k.summary:void 0,Y=typeof J?.hint==`string`?J.hint:void 0,ee=[e.template===void 0?`Written successfully (${O}).`:`Written successfully (instantiated from template "${e.template}").`];if(F&&ee.push(`Preview: ${F.url}`),B&&ee.push(F?`Open ${F.url} in your preview browser.`:`No preview attached. Start the UI.`),Y&&ee.push(Y),q)for(let e of q)e.message&&ee.push(e.message);let te=ee.join(`
|
|
2354
|
+
`);if(!F&&!B&&!H&&!q&&!J)return textResult(te);let ne={};return F&&(ne.previewUrl=F.url,ne.previewUrlSource=F.source),B&&(ne.warning={message:`Open the previewUrl in your preview browser.`,action:`attach-preview-once`,previewUrl:F?.url??null}),q&&(ne.hints=q),J&&(ne.summary=J),textPlusStructured(te,ne)})}const DESCRIPTION=[`[Operates on disk; no running OK server required] Create or update a template.`,``,"Templates are markdown starter shapes that agents pick from when creating a new doc — `write_document({ template: <name> })` resolves the name against the folder cascade and instantiates the body + frontmatter.",``,`**Targets.** A template can live in one of two locations:`,'- `target: "project"` (default) — folder-scoped within the current project at `<folder>/.ok/templates/<name>.md`. The `folder` argument selects which project folder owns it (project-wide via `folder: ""`, or scoped to a subfolder).','- `target: "user"` — user-global at `~/.ok/templates/<name>.md`, available across every OK project the same user opens. The `folder` argument is ignored when `target` is `"user"` — user templates live in a single flat location.',``,"**`title` is required** in the frontmatter — it is the menu surface agents pick from. Missing or empty title returns `TEMPLATE_TITLE_REQUIRED`. `description` is recommended (soft warning when absent) — it disambiguates similarly-named templates.",``,"**Substitution allowlist.** The body MAY contain `{{date}}` (today, ISO-8601) and `{{user}}` (calling principal display name). Any other `{{...}}` token is rejected at write time with `TEMPLATE_UNKNOWN_VARIABLE`. Substitution happens at instantiation time (when `write_document({ template })` materializes the doc), not at template-write time — templates on disk show the raw `{{date}}` token.",``,`**Parameters:**`,'- `folder` — Project-root-relative folder (e.g. `"meetings"`, `"meetings/prep-notes"`). Empty / `.` means project root. Ignored when `target` is `"user"`.',"- `name` — Template filename without `.md`. Letters, digits, `_`, `-` only.","- `body` — Markdown body. May use `{{date}}` / `{{user}}` substitution tokens. Other placeholder text in `{shape}` form (e.g. `{Meeting Title}`) is LITERAL — agents fill it in via subsequent `edit_document` calls.","- `frontmatter` — `{title (required), description?, tags?: string[]}` for the template menu.",'- `target` (optional) — `"project"` (default) or `"user"`. Selects where the template lives.'].join(`
|
|
2355
2355
|
`),InputSchema={folder:string().describe('Project-root-relative folder. Empty / `.` means project root. Ignored when `target: "user"`.'),name:string().min(1).regex(/^[A-Za-z0-9_-]+$/,"Template name must use letters, digits, `_`, or `-` only (no slashes, dots, or spaces).").describe("Template filename without `.md` extension."),body:string().describe(`Markdown body for the template.`),frontmatter:object$1({title:string().min(1,"Template `title` is required — it is the menu surface agents pick from.").describe(`Required. The menu surface agents pick from. Empty / missing returns TEMPLATE_TITLE_REQUIRED.`),description:string().optional().describe(`Recommended. Disambiguates similarly-named templates. Soft warning when absent.`),tags:array(string()).optional().describe(`Optional. Concatenated with cascade tags at instantiation time.`)}).describe("Template menu metadata. `title` MUST be present (hard error if missing). `description` SHOULD be present (warning)."),target:_enum([`project`,`user`]).optional().describe('Where the template lives. `"project"` (default) writes to `<folder>/.ok/templates/`; `"user"` writes to `~/.ok/templates/` (folder ignored).'),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},OutputSchema={result:union([object$1({ok:literal(!0),path:string(),created:boolean(),warnings:array(string())}),object$1({ok:literal(!1),error:object$1({code:string(),message:string()})})])};function register(e,t){e.registerTool(`write_template`,{description:DESCRIPTION,inputSchema:InputSchema,outputSchema:OutputSchema,annotations:{readOnlyHint:!1,idempotentHint:!0,destructiveHint:!1}},async e=>{let s=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);if(!s.ok)return{isError:!0,content:[{type:`text`,text:`Error: ${s.error}`}]};let{cwd:g}=s,S={projectDir:g,folder:e.folder,name:e.name,body:e.body,frontmatter:e.frontmatter};e.target!==void 0&&(S.target=e.target);let w=applyTemplateWrite(S);if(!w.ok)return{isError:!0,structuredContent:{result:w},content:[{type:`text`,text:`${w.error.code}: ${w.error.message}`}]};let E=[`${w.created?`Created`:`Updated`} template at ${w.path}`];if(w.warnings.length>0){E.push(``,`Warnings:`);for(let e of w.warnings)E.push(` - ${e}`)}return textPlusStructured(E.join(`
|
|
2356
2356
|
`),{result:w})})}function registerAllTools(e,t){let s=t.logger,g=createLoggedServer(e,{logger:t.logger,identityRef:t.identityRef}),S=e=>async g=>{try{let S=await t.resolveCwd(g);return(getCurrentMcpLogger()??s)?.debug(`tool cwd resolved`,{tool:e,cwd:S,...g?{explicit:g}:{}}),S}catch(t){throw(getCurrentMcpLogger()??s)?.warn(`tool call failed`,{tool:e,error:t instanceof Error?t.message:String(t),...g?{explicit:g}:{}}),t}};register$21(g,{resolveCwd:S(`exec`),serverUrl:t.serverUrl,config:t.config}),register$12(g,{config:t.config,resolveCwd:S(`ingest`)}),register$7(g,{config:t.config,resolveCwd:S(`research`)}),register$25(g,{config:t.config,resolveCwd:S(`consolidate`)}),register$10(g,{resolveCwd:S(`read_document`),config:t.config,serverUrl:t.serverUrl}),register$4(g,{resolveCwd:S(`search`),config:t.config,serverUrl:t.serverUrl}),register$13(g,{resolveCwd:S(`grep`),config:t.config,serverUrl:t.serverUrl}),register$2(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`suggest_links`)}),register$1(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`write_document`),identityRef:t.identityRef}),register$22(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`edit_document`),identityRef:t.identityRef}),register$24(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`delete_document`),identityRef:t.identityRef}),register$9(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`rename_document`),identityRef:t.identityRef}),register$8(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`rename_folder`),identityRef:t.identityRef}),register$16(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_history`)}),register$5(g,t.config,t.serverUrl,S(`save_version`),t.identityRef),register$6(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`rollback_to_version`),identityRef:t.identityRef}),register$11(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`list_documents`)}),register$20(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_backlinks`)}),register$17(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_forward_links`)}),register$14(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_orphans`)}),register$15(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_hubs`)}),register$18(g,{serverUrl:t.serverUrl,config:t.config,resolveCwd:S(`get_dead_links`)}),register$19(g,{config:t.config,resolveCwd:S(`get_config`)}),register$3(g,{config:t.config,resolveCwd:S(`set_folder_rule`)}),register(g,{config:t.config,resolveCwd:S(`write_template`)}),register$23(g,{config:t.config,resolveCwd:S(`delete_template`)})}function firstHeader(e){return Array.isArray(e)?e[0]:e}function writePlain(e,t,s){e.writableEnded||(e.statusCode=t,e.setHeader(`Content-Type`,`text/plain; charset=utf-8`),e.end(s))}function createSessionServer(e,t,s){let g=e.config,S=new McpServer({name:MCP_SERVER_NAME,version:RUNTIME_VERSION},{instructions:buildInstructions(g.content)}),w=s??randomUUID(),E={current:{connectionId:w,displayName:w,colorSeed:w}};S.server.oninitialized=()=>{let e=S.server.getClientVersion(),t=sanitizeClientName(e?.name,w);E.current={connectionId:w,clientInfo:e?{name:t,version:e.version}:void 0,displayName:t,colorSeed:t}};let D=e.projectDir??e.contentDir;return registerAllTools(S,{serverUrl:async()=>e.getServerUrl(),resolveCwd:async e=>{if(e===void 0)return D;let t=resolveWithinRoot(D,e);if(!t.ok)throw Error(`cwd "${e}" is not within the configured project root: ${t.reason}`);return t.abs},config:g,identityRef:E}),{server:S,transport:t}}function createMcpHttpHandler(e){let t=new Map,s=e.sessionTtlMs??1800*1e3,g=e.maxSessions??100;async function S(s,g){let S=t.get(s);if(!S)return;t.delete(s),S.ttlTimer!==void 0&&clearTimeout(S.ttlTimer);let w=await Promise.allSettled([S.server.close(),S.transport.close()]);for(let t of w)t.status===`rejected`&&e.log?.warn?.({err:t.reason,sessionId:s,reason:g},`MCP HTTP session close failed`);e.log?.info?.({sessionId:s,reason:g},`MCP HTTP session closed`)}function w(t,g){g.ttlTimer!==void 0&&clearTimeout(g.ttlTimer),g.ttlTimer=setTimeout(()=>{S(t,`ttl-expired`).catch(s=>{e.log?.warn?.({err:s,sessionId:t},`MCP HTTP session TTL cleanup failed`)})},s),g.ttlTimer.unref?.()}return{async handle(s,E){let D=firstHeader(s.headers[`mcp-session-id`]);if(D){let e=t.get(D);if(!e){writePlain(E,404,`MCP session not found`);return}w(D,e),await e.transport.handleRequest(s,E);return}if(s.method!==`POST`){writePlain(E,400,`Missing MCP session. Initialize with POST /mcp first.`);return}if(t.size>=g){e.log?.warn?.({activeSessions:t.size,maxSessions:g},`MCP HTTP session cap reached`),writePlain(E,503,`Too many active MCP sessions`);return}let O=firstHeader(s.headers[MCP_CONNECTION_ID_HEADER]),k=validateAgentId(O)??void 0;O!==void 0&&k===void 0&&e.log?.warn?.({headerLength:O.length},`MCP HTTP forwarded connectionId header failed validation; falling back to randomUUID`);let j=new StreamableHTTPServerTransport({sessionIdGenerator:()=>randomUUID(),enableJsonResponse:!0,onsessioninitialized:async s=>{try{let g=createSessionServer(e,j,k);await g.server.connect(j),t.set(s,g),w(s,g),e.log?.info?.({sessionId:s},`MCP HTTP session initialized`)}catch(g){throw t.delete(s),e.log?.error?.({err:g,sessionId:s},`MCP HTTP session initialization failed`),g}}});j.onerror=t=>{e.log?.warn?.({err:t},`MCP HTTP transport error`)},j.onclose=()=>{let t=j.sessionId;if(!t){e.log?.info?.({sessionId:t,reason:`transport-closed`},`MCP HTTP session closed`);return}S(t,`transport-closed`).catch(s=>{e.log?.warn?.({err:s,sessionId:t},`MCP HTTP transport-close cleanup failed`)})},await j.handleRequest(s,E)},async close(){let e=[...t.entries()];await Promise.allSettled(e.map(([e])=>S(e,`handler-close`)))}}}const DEFAULT_KEEPALIVE_GRACE_MS=1e4,MAX_COLLAB_MESSAGE_BYTES=1024*1024,MCP_CORS_HEADERS={"Access-Control-Allow-Methods":`GET, POST, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization, traceparent, tracestate, baggage, mcp-session-id, mcp-protocol-version`,"Access-Control-Max-Age":`86400`};function mountMcpAndApi(e){let{httpServer:t,hocuspocus:s,mcpHttpHandler:g,log:S,sessionManager:w,agentFocusBroadcaster:E,agentPresenceBroadcaster:D,contentAssetMiddleware:O}=e,k=e.keepaliveGraceMs??DEFAULT_KEEPALIVE_GRACE_MS,j=new import_websocket_server$1.default({noServer:!0,maxPayload:MAX_COLLAB_MESSAGE_BYTES});j.on(`error`,e=>{S.error({err:e},`WebSocketServer error`)});let F=new Map,L=new Set,B=!1;return t.on(`request`,(e,t)=>{let w=e.url?.split(`?`)[0];if(g!==void 0&&w===`/mcp`){let s=e.headers.origin,w=Array.isArray(e.headers[`mcp-session-id`])?e.headers[`mcp-session-id`][0]:e.headers[`mcp-session-id`];if(!isLoopbackAddress(e.socket.remoteAddress)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback access required.`,{handler:`mcp`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`mcp`});return}if(s!==void 0&&!isAllowedApiOrigin(s)){errorResponse(t,403,`urn:ok:error:invalid-origin`,`Origin not allowed.`,{handler:`mcp`});return}s!==void 0&&(t.setHeader(`Access-Control-Allow-Origin`,s),t.setHeader(`Vary`,`Origin`));for(let[e,s]of Object.entries(MCP_CORS_HEADERS))t.setHeader(e,s);if(e.method===`OPTIONS`){t.writeHead(204),t.end();return}g.handle(e,t).catch(e=>{S.error({err:e,sessionId:w},`Unhandled MCP HTTP error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp`,cause:e}):t.writableEnded||t.end()});return}if(w?.startsWith(`/api/`)){s.hooks(`onRequest`,{request:e,response:t}).then(()=>{t.writableEnded||t.headersSent||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`mcp-mount`,detail:`No handler for ${e.method??`GET`} ${w}`})}).catch(e=>{S.error({err:e},`Unhandled onRequest error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp-mount`,cause:e}):t.writableEnded||t.end()});return}if(O!==void 0){try{O(e,t,()=>{t.writableEnded||t.headersSent||errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`No handler for ${w??`/`}`})})}catch(e){S.error({err:e},`Unhandled content-asset middleware error`),!t.writableEnded&&!t.headersSent?errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`mcp-mount`,cause:e}):t.writableEnded||t.end()}return}errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`mcp-mount`,detail:`The React UI is served by \`ok ui\` (default port 3000). No handler for ${w??`/`}`})}),t.on(`upgrade`,(e,t,g)=>{if(e.url?.startsWith(`/collab/keepalive`)){if(!isLoopbackAddress(e.socket.remoteAddress)||!isAllowedWorkspaceHostHeader(e.headers.host)){t.destroy();return}t.on(`error`,e=>{handleCollabSocketError(e)||S.error({err:e},`MCP keepalive socket error`)}),j.handleUpgrade(e,t,g,t=>{let s=parseKeepaliveConnectionId(e.url);if(s){let e=F.get(s);e!==void 0&&(clearTimeout(e),F.delete(s),S.info({connectionId:s},`[keepalive] reconnect during grace — timer cancelled`))}let g=setInterval(()=>{try{t.ping()}catch{}},3e4);g.unref?.();let O=s?setInterval(()=>{D?.bumpPresenceTs(toBroadcasterKey(s))},3e3):null;O?.unref?.(),t.on(`close`,()=>{if(clearInterval(g),O!==null&&clearInterval(O),!s)return;let e=setTimeout(()=>{if(F.delete(s),B)return;let e=(async()=>{S.info({connectionId:s},`[keepalive] grace expired — cleaning up sessions`);try{await w?.closeAllForAgent(s)}catch(e){S.error({err:e,connectionId:s},`[keepalive] closeAllForAgent failed`)}try{E?.clearFocus(s)}catch(e){S.error({err:e,connectionId:s},`[keepalive] clearFocus failed`)}try{D?.clearPresence(toBroadcasterKey(s))}catch(e){S.error({err:e,connectionId:s},`[keepalive] clearPresence failed`)}})();L.add(e),e.finally(()=>L.delete(e))},k);e.unref?.(),F.set(s,e),S.info({connectionId:s,graceMs:k},`[keepalive] disconnected — grace timer started`)}),t.on(`error`,e=>{handleCollabSocketError(e)||S.error({err:e},`MCP keepalive WS error`),t.terminate()})});return}if(e.url?.startsWith(`/collab`)){t.on(`error`,e=>{handleCollabSocketError(e)||S.error({err:e},`Upgrade socket error`)}),j.handleUpgrade(e,t,g,t=>{let g=s.handleConnection(t,e),w=!1;t.on(`message`,e=>{if(w)return;let s=e.byteLength;if(s>MAX_COLLAB_MESSAGE_BYTES){w=!0,incrementCollabMessageTooLarge(),S.warn({event:`collab-message-too-large`,bytes:s,limit:MAX_COLLAB_MESSAGE_BYTES},`Collab WebSocket message rejected before Yjs processing`),t.close(1009,`Message Too Big`);return}g.handleMessage(new Uint8Array(e))}),t.on(`close`,(e,t)=>{g.handleClose({code:e,reason:t.toString()})}),t.on(`error`,e=>{if(e.code===`WS_ERR_UNSUPPORTED_MESSAGE_LENGTH`){incrementCollabMessageTooLarge(),S.warn({event:`collab-message-too-large`,limit:MAX_COLLAB_MESSAGE_BYTES},`Collab WebSocket frame rejected by ws maxPayload before Yjs processing`),t.terminate();return}handleCollabSocketError(e)||S.error({err:e},`WebSocket error`),t.terminate()})});return}t.destroy()}),{wss:j,shutdown:async()=>{if(!B){B=!0;for(let e of F.values())clearTimeout(e);F.clear(),L.size>0&&await Promise.allSettled([...L])}}}}function parseKeepaliveConnectionId(e){if(!e)return null;try{return validateAgentId(new URL(e,`http://localhost`).searchParams.get(`connectionId`))}catch{return null}}const MISSING_OK_CONFIG_MESSAGE=`Open Knowledge config not found at .ok/config.yml. Run ok init to scaffold OK in this directory.`;var MissingOkConfigError=class extends Error{kind;projectDir;constructor(e,t,s){super(MISSING_OK_CONFIG_MESSAGE,s),this.name=`MissingOkConfigError`,this.kind=e,this.projectDir=t}};async function startConfigFileWatcher(e,t){let s=getLogger(`config-file-watcher`),{watch:g}=await import(`./chokidar-DnkSPA-1.mjs`),S=dirname(e);try{tracedMkdirSync(S,{recursive:!0})}catch(e){e.code!==`EEXIST`&&s.warn({err:e,watchDir:S},`failed to create watch directory; watcher may be inert`)}let w=g(S,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:t=>t!==S&&t!==e});await new Promise(e=>{w.once(`ready`,e)});let E=null;try{E=readFileSync(e,`utf-8`)}catch{}let D=(g,S=!0)=>{if(g!==e)return;let w;try{w=readFileSync(g,`utf-8`)}catch(e){if(e.code===`ENOENT`){S&&s.debug({path:g},`config file disappeared between event and read; dropping`);return}s.warn({err:e,path:g},`config file read failed; dropping event`);return}if(w!==E){E=w;try{t(w)}catch(e){s.warn({err:e,path:g},`config file change handler threw`)}}},O=e=>D(e);w.on(`add`,O),w.on(`change`,O),w.on(`unlink`,t=>{t===e&&s.debug({path:t},`config file unlinked; Y.Text retained at current state`)}),w.on(`error`,t=>{s.warn({err:t,watchDir:S,absPath:e},`[config-file-watcher] chokidar error while watching ${e}`)});let k=0,j=setInterval(()=>{k++,D(e,!1),k>=20&&clearInterval(j)},500);j.unref?.();let F=!1;return async()=>{F||(F=!0,clearInterval(j),await w.close())}}async function startMultiPathConfigFileWatcher(e,t){if(e.length===0)throw Error(`startMultiPathConfigFileWatcher requires at least one absolute path`);let s=getLogger(`config-file-watcher`),{watch:g}=await import(`./chokidar-DnkSPA-1.mjs`),S=new Set(e),w=Array.from(new Set(Array.from(S,e=>dirname(e))));for(let e of w)try{tracedMkdirSync(e,{recursive:!0})}catch(t){t.code!==`EEXIST`&&s.warn({err:t,dir:e},`failed to create watch directory; watcher may be inert`)}let E=g(w,{ignoreInitial:!0,depth:0,usePolling:!0,interval:200,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},ignored:e=>!S.has(e)&&!w.includes(e)});await new Promise(e=>{E.once(`ready`,e)});let D=new Map;for(let e of S)try{D.set(e,readFileSync(e,`utf-8`))}catch{D.set(e,null)}let O=(e,g=!0)=>{if(!S.has(e))return;let w;try{w=readFileSync(e,`utf-8`)}catch(t){if(t.code===`ENOENT`){g&&s.debug({path:e},`config file disappeared between event and read; dropping`);return}s.warn({err:t,path:e},`config file read failed; dropping event`);return}if(w!==D.get(e)){D.set(e,w);try{t(e,w)}catch(t){s.warn({err:t,path:e},`config file change handler threw`)}}},k=e=>O(e);E.on(`add`,k),E.on(`change`,k),E.on(`unlink`,e=>{S.has(e)&&s.debug({path:e},`config file unlinked; downstream state retained`)}),E.on(`error`,e=>{s.warn({err:e,watchDirs:w,paths:Array.from(S)},`[config-file-watcher] chokidar error in multi-path watcher`)});let j=0,F=setInterval(()=>{j++;for(let e of S)O(e,!1);j>=20&&clearInterval(F)},500);F.unref?.();let L=!1;return async()=>{L||(L=!0,clearInterval(F),await E.close())}}const QUIET_WINDOW_MS=100,BATCH_TIMEOUT_MS=3e4,WATCHED_FILES=new Set([`HEAD`,`MERGE_HEAD`,`ORIG_HEAD`,`index.lock`]);function readHeadSha(e){try{let t=readFileSync(resolve(e,`HEAD`),`utf-8`).trim();if(t.startsWith(`ref: `)){let s=resolve(e,t.slice(5));try{return readFileSync(s,`utf-8`).trim()}catch{try{let s=readFileSync(resolve(e,`packed-refs`),`utf-8`),g=t.slice(5),S=s.split(`
|
|
2357
2357
|
`).find(e=>e.endsWith(` ${g}`));if(S)return S.split(` `)[0]}catch{}return null}}return t.length>=40?t.slice(0,40):null}catch{return null}}function readBranchFromHead(e){try{let t=readFileSync(resolve(e,`HEAD`),`utf-8`).trim();return t.startsWith(`ref: refs/heads/`)?t.slice(16):t.length>=40?`detached-${t.slice(0,12)}`:null}catch{return null}}async function startHeadWatcher(e,t,s){let g=resolveGitDir(e);if(!g)return{unsubscribe:async()=>{},getLastKnownBranch:()=>null};let S=g,w=!1,E=null,D=null,O=null,k=null;async function j(e){if(L&&await L,!w)return;E&&=(clearTimeout(E),null),D&&=(clearTimeout(D),null);let t=readHeadSha(S),g=O!==t,j=readBranchFromHead(S),F;F=j?.startsWith(`detached-`)?`detached-head`:k===j?`within-branch`:`cross-branch`;let B=k;try{await s({headMoved:g,oldHead:O,newHead:t,timeout:e,batchKind:F,oldBranch:B,newBranch:j})}catch(e){console.error(`[head-watcher] onBatchEnd callback failed:`,e)}finally{w=!1,O=t,k=j}}function F(){E&&clearTimeout(E),E=setTimeout(()=>{E=null,j(!1)},QUIET_WINDOW_MS)}let L=null;async function B(e){if(!w){w=!0,O=readHeadSha(S);let s=(async()=>{try{await t({trigger:e})}catch(e){console.error(`[head-watcher] onBatchBegin callback failed:`,e)}})();L=s,await s,L=null,D=setTimeout(()=>{D=null,j(!0)},BATCH_TIMEOUT_MS)}F()}let H,q;try{q=await import(`@parcel/watcher`)}catch(e){throw Error(`@parcel/watcher unavailable for HEAD watching: ${e instanceof Error?e.message:e}`)}try{let e=await q.subscribe(S,(e,t)=>{if(e){console.error(`[head-watcher]`,e);return}for(let e of t){let t=e.path.split(`/`).pop()??``;if(WATCHED_FILES.has(t)){B(t);break}}});H=()=>e.unsubscribe()}catch(e){throw Error(`@parcel/watcher subscribe failed for HEAD watching: ${e instanceof Error?e.message:e}`)}return O=readHeadSha(S),k=readBranchFromHead(S),console.log(`[head-watcher] Watching ${S} for HEAD changes`),{unsubscribe:async()=>{w&&await j(!1),E&&clearTimeout(E),D&&clearTimeout(D),await H()},getLastKnownBranch:()=>k}}const LIVE_DERIVED_INDEX_DEBOUNCE_MS=100;function isLocalOriginLike(e){return typeof e!=`object`||!e?!1:e.source===`local`}function serializeLiveDocument(e){return e.getText(`source`).toString()}function createLiveDerivedIndexExtension(e){let{backlinkIndex:t,tagIndex:s,signalChannel:g,debounceMs:S=100}=e,w=new Map;function E(e){let t=w.get(e);t&&(clearTimeout(t),w.delete(e))}function D(e,D){E(e),w.set(e,setTimeout(()=>{w.delete(e);try{let S=serializeLiveDocument(D);t.updateDocumentFromMarkdown(e,S),g?.(`backlinks`),g?.(`graph`),s&&(s.updateDocumentFromMarkdown(e,S),g?.(`tags`))}catch(t){console.error(`[live-derived-index] Failed to update derived views for ${e}:`,t)}},S))}return{async onChange({documentName:e,document:t,transactionOrigin:s}){isSystemDoc(e)||isConfigDoc(e)||isLocalOriginLike(s)&&s.context?.origin===`file-watcher`||D(e,t)},async beforeUnloadDocument({documentName:e}){E(e)},async onDestroy(){for(let e of w.values())clearTimeout(e);w.clear()}}}const PRINCIPAL_FILE=`principal.json`,GIT_TIMEOUT_MS=3e3;async function readGitConfig(e){try{let t=esm_default({baseDir:e,timeout:{block:GIT_TIMEOUT_MS}});return{name:(await t.raw(`config`,`--get`,`user.name`)).trim()||null,email:(await t.raw(`config`,`--get`,`user.email`)).trim()||null}}catch{return{name:null,email:null}}}async function loadPrincipal(e){let t=getLocalDir(e),s=resolve(t,PRINCIPAL_FILE),{name:g,email:S}=await readGitConfig(e);if(existsSync(s)){let e;try{e=JSON.parse(readFileSync(s,`utf-8`))}catch{e={}}let t=typeof e.id==`string`&&e.id.startsWith(`principal-`)?e.id:`principal-${randomUUID()}`,w=typeof e.created_at==`string`?e.created_at:new Date().toISOString(),E=t.slice(10,18),D={id:t,display_name:g?sanitizeGitIdentity(g):typeof e.display_name==`string`?e.display_name:`Local User`,display_email:S?sanitizeGitIdentity(S):typeof e.display_email==`string`?e.display_email:`principal-${E}@openknowledge.local`,source:g||S?`git-config`:`synthesized`,created_at:w};return writeFileSync(s,JSON.stringify(D,null,2),`utf-8`),D}mkdirSync(t,{recursive:!0});let w=`principal-${randomUUID()}`,E=w.slice(10,18),D={id:w,display_name:g?sanitizeGitIdentity(g):`Local User`,display_email:S?sanitizeGitIdentity(S):`principal-${E}@openknowledge.local`,source:g||S?`git-config`:`synthesized`,created_at:new Date().toISOString()};return writeFileSync(s,JSON.stringify(D,null,2),`utf-8`),D}const DEFAULT_CAPACITY=1e4;var RecentlyRemovedDocs=class{map=new Map;capacity;onEviction;onSizeChange;now;constructor(e=DEFAULT_CAPACITY,t={}){this.capacity=Math.max(0,Math.floor(e)),this.onEviction=t.onEviction,this.onSizeChange=t.onSizeChange,this.now=t.now??Date.now}setRenamed(e,t){this.put(e,{kind:`renamed`,newDocName:t,addedAt:this.now()})}setDeleted(e){this.put(e,{kind:`deleted`,addedAt:this.now()})}get(e){let t=this.map.get(e);if(t!==void 0)return this.map.delete(e),this.map.set(e,t),t}has(e){return this.map.has(e)}peek(e){return this.map.get(e)}delete(e){this.map.delete(e)&&this.onSizeChange?.(this.map.size)}get size(){return this.map.size}put(e,t){if(this.capacity===0){this.onSizeChange?.(0);return}for(this.map.delete(e),this.map.set(e,t);this.map.size>this.capacity;){let e=this.map.keys().next().value;if(e===void 0)break;this.map.delete(e),this.onEviction?.()}this.onSizeChange?.(this.map.size)}};function fileExistsForDocName(e,t){let s=e.resolveFilePath(t);return s!==null&&e.fileExists(s)}async function runRemovalRedirectGuard(e,t){try{if(isSystemDoc(e)||isConfigDoc(e))return;let s=t.recentlyRemovedDocs.get(e);if(s===void 0)return;if(s.kind===`deleted`){if(fileExistsForDocName(t,e)){t.recentlyRemovedDocs.delete(e);return}throw incrementAuthDocDeleted(),setActiveSpanAttributes({"auth.reason":`doc-deleted`}),new HocuspocusAuthRejection(`doc-deleted`,`removed-doc rejection for deleted ${e}`)}let g=new Set([e]),S=s.newDocName;for(;;){if(g.has(S)){incrementRemovalRedirectChainCycle(),console.warn(JSON.stringify({event:`removal-redirect-chain-cycle`,documentName:e,target:S}));return}g.add(S);let s=t.recentlyRemovedDocs.get(S);if(s===void 0)throw incrementAuthRenameRedirect(),setActiveSpanAttributes({"auth.reason":`rename-redirect`}),new HocuspocusAuthRejection(`rename-redirect`,`removed-doc redirect for ${e} → ${S}`,S);if(s.kind===`deleted`)throw fileExistsForDocName(t,S)?(t.recentlyRemovedDocs.delete(S),incrementAuthRenameRedirect(),setActiveSpanAttributes({"auth.reason":`rename-redirect`}),new HocuspocusAuthRejection(`rename-redirect`,`removed-doc redirect for ${e} → ${S}`,S)):(incrementAuthDocDeleted(),setActiveSpanAttributes({"auth.reason":`doc-deleted`}),new HocuspocusAuthRejection(`doc-deleted`,`removed-doc rejection for deleted ${e}`));S=s.newDocName}}catch(t){if(t instanceof HocuspocusAuthRejection)throw t;incrementAuthRemovalGuardError(),console.warn(JSON.stringify({event:`removal-redirect-extension-error`,documentName:e,message:t instanceof Error?t.message:String(t)}))}}function createServerObserverExtension(e){let t=new Map,s=new Map;return{async afterLoadDocument({documentName:g,document:S}){if(isSystemDoc(g)||isConfigDoc(g)||t.has(g))return;let w=S,E=w.getXmlFragment(`default`),D=w.getText(`source`),O=()=>{try{let s=setupServerObservers({doc:w,xmlFragment:E,ytext:D,mdManager:e.mdManager,schema:e.schema,docName:g,shadow:e.shadowRef?()=>e.shadowRef?.current:void 0,getBranch:e.getCurrentBranch?()=>e.getCurrentBranch?.()??`main`:void 0,contentRoot:e.contentRoot,resolveEmbed:e.resolveEmbed,resolveSize:e.resolveSize});return t.set(g,s),!0}catch(e){return console.error(`[ServerObserverExtension] Failed to attach observers for '${g}':`,e),incrementServerObserverError(`a`),incrementServerObserverError(`b`),!1}};if(!O()){let e=setTimeout(()=>{s.delete(g),!t.has(g)&&(console.warn(`[ServerObserverExtension] Retrying observer attachment for '${g}'`),O())},5e3);s.set(g,e)}},async afterUnloadDocument({documentName:e}){let g=s.get(e);g&&(clearTimeout(g),s.delete(e));let S=t.get(e);S&&(S(),t.delete(e))},async onDestroy(){for(let e of s.values())clearTimeout(e);s.clear();for(let[e,s]of t.entries())try{s()}catch(t){console.error(`[ServerObserverExtension] Cleanup failed for '${e}':`,t)}t.clear()}}}const STATE_MANIFEST_FILENAME=`state.json`;function detectProjectShape(e){return e.lockDir,existsSync(e.shadowRepoDir)?`adopt`:`fresh`}function manifestPath(e){return resolve(e,STATE_MANIFEST_FILENAME)}function isCompatibleSchema(e,t){return e===t||e===0&&t===1}var StateManifestError=class extends Error{kind;path;constructor(e){super(e.message),this.name=`StateManifestError`,this.kind=e.kind,this.path=e.path}};function isStateManifestRecord(e){if(!e||typeof e!=`object`)return!1;let t=e;if(typeof t.stateSchemaVersion!=`number`||typeof t.createdAt!=`string`||!t.createdBy||typeof t.createdBy!=`object`)return!1;let s=t.createdBy;return!(typeof s.runtimeVersion!=`string`||s.protocolVersion!==void 0&&typeof s.protocolVersion!=`number`)}function readStateManifest(e){let t=manifestPath(e);if(!existsSync(t))return{status:`absent`};let s;try{s=readFileSync(t,`utf-8`)}catch(e){throw new StateManifestError({kind:`corrupt`,path:t,message:`Failed to read state manifest at ${t}: ${e instanceof Error?e.message:String(e)}`})}let g;try{g=JSON.parse(s)}catch(e){throw new StateManifestError({kind:`corrupt`,path:t,message:`State manifest at ${t} is not valid JSON: ${e instanceof Error?e.message:String(e)}`})}if(!isStateManifestRecord(g))throw new StateManifestError({kind:`corrupt`,path:t,message:`State manifest at ${t} has invalid shape (missing or wrong-typed required fields)`});return{status:`present`,manifest:g}}function writeStateManifest(e,t){let s=manifestPath(e);mkdirSync(dirname(s),{recursive:!0}),writeFileSync(s,JSON.stringify(t,null,2),{encoding:`utf-8`,mode:384})}function assertCompatibleStateManifest(e){let t=getLogger(`state-manifest`),s=e.currentStateSchemaVersion??1,g=e.currentRuntimeVersion??RUNTIME_VERSION,S=e.currentProtocolVersion??1,w=(e.now??(()=>new Date))().toISOString(),E=manifestPath(e.lockDir),D=readStateManifest(e.lockDir);if(D.status===`present`){let O=D.manifest;if(!isCompatibleSchema(O.stateSchemaVersion,s))throw new StateManifestError({kind:`incompatible`,path:E,message:`State manifest at ${E} declares stateSchemaVersion=${O.stateSchemaVersion} but this binary supports ${s}. Refusing to boot — on-the-fly migration is out of scope. (Manifest written by runtime ${O.createdBy.runtimeVersion}, protocol ${O.createdBy.protocolVersion}.)`});try{let t={...O,lastWriteBy:{runtimeVersion:g,protocolVersion:S,at:w}};return writeStateManifest(e.lockDir,t),t}catch(e){return t.warn({err:e},`[state-manifest] failed to update lastWriteBy — proceeding`),O}}if(detectProjectShape({lockDir:e.lockDir,shadowRepoDir:e.shadowRepoDir})===`fresh`){let D={stateSchemaVersion:s,createdAt:w,createdBy:{runtimeVersion:g,protocolVersion:S}};return writeStateManifest(e.lockDir,D),t.info({path:E,stateSchemaVersion:s},`[state-manifest] fresh project — wrote manifest`),D}let O={stateSchemaVersion:0,createdAt:w,createdBy:{runtimeVersion:g,protocolVersion:S,adoptedAt:w}};return writeStateManifest(e.lockDir,O),t.warn({path:E,runtimeVersion:g},`[state-manifest] adopting pre-versioned project — wrote schema-0 manifest. Future binaries with STATE_SCHEMA_VERSION>=2 may refuse if they cannot read schema-0 state.`),O}const log$1=getLogger(`conflict-storage`);var ConflictStore=class{storePath;projectDir;branch;conflicts=[];constructor(e,t=`main`){this.storePath=join(getLocalDir(e),`conflicts.json`),this.projectDir=e,this.branch=t,this.load()}load(){if(!existsSync(this.storePath)){this.conflicts=[];return}try{let e=readFileSync(this.storePath,`utf-8`),t=JSON.parse(e);if(t.version!==1){log$1.warn({path:this.storePath},`[conflicts] unknown schema version — resetting`),this.conflicts=[];return}this.branch=t.branch??this.branch,this.conflicts=t.conflicts??[]}catch(e){log$1.warn({err:e},`[conflicts] failed to load conflicts.json — starting empty`),this.conflicts=[]}}save(){try{let e=dirname(this.storePath);existsSync(e)||mkdirSync(e,{recursive:!0});let t={version:1,branch:this.branch,conflicts:this.conflicts};writeFileSync(this.storePath,JSON.stringify(t,null,2),`utf-8`)}catch(e){log$1.warn({err:e},`[conflicts] failed to save conflicts.json`)}}addConflict(e){let t=this.conflicts.findIndex(t=>t.file===e.file);t===-1?this.conflicts.push(e):this.conflicts[t]=e,this.save()}removeConflict(e){this.conflicts=this.conflicts.filter(t=>t.file!==e),this.save()}clear(){this.conflicts=[],this.save()}count(){return this.conflicts.length}list(){return[...this.conflicts]}hasConflicts(){return this.conflicts.length>0}setBranch(e){this.branch=e}async resolveConflict(e,t,s,g=[]){if(!this.conflicts.find(t=>t.file===e))throw Error(`[conflicts] no conflict tracked for file: ${e}`);if(t===`content`&&s===void 0)throw Error(`[conflicts] strategy 'content' requires content parameter`);let{createGitInstance:S}=await import(`./git-handle-DwfYp_z--DreW3fNC.mjs`).then(e=>e.n),w=S(this.projectDir,{credentialArgs:g});switch(t){case`mine`:await w.git.raw([`checkout`,`--ours`,`--`,e]),await w.git.raw([`add`,`--`,e]);break;case`theirs`:await w.git.raw([`checkout`,`--theirs`,`--`,e]),await w.git.raw([`add`,`--`,e]);break;case`content`:{if(!s)throw Error(`[conflicts] strategy 'content' requires content parameter`);let t=resolve(this.projectDir),g=resolve(t,e);if(g!==t&&!g.startsWith(`${t}/`))throw Error(`[conflicts] file path escapes project directory: ${e}`);writeFileSync(g,s,`utf-8`),await w.git.raw([`add`,`--`,e]);break}default:throw Error(`[conflicts] unknown resolve strategy: ${t}`)}if(this.removeConflict(e),!this.hasConflicts())try{await w.git.raw([`commit`,`--no-edit`]),log$1.info({file:e},`[conflicts] all conflicts resolved — merge commit created`)}catch(t){let s=new Date().toISOString(),g=!1;try{let e=(await w.git.raw([`diff`,`--name-only`,`--diff-filter=U`])).split(`
|
|
@@ -2365,4 +2365,4 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
2365
2365
|
`).split(`
|
|
2366
2366
|
`),s=[],g=!1,S=``;for(let e of t){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(t){g?RegExp(`^\\s{0,3}${S[0]==="`"?"`":`~`}{${S.length},}\\s*$`).test(e)&&(g=!1,S=``):(g=!0,S=t[1]);continue}if(g)continue;let w=stripInlineCodeSpans(e);for(TAG_VALUE_RE.lastIndex=0;;){let e=TAG_VALUE_RE.exec(w);if(e===null)break;let t=e[2];t&&s.push(t)}}return s}var TagIndex=class{contentDir;contentFilter;state=createEmptyState();constructor(e){this.contentDir=e.contentDir,this.contentFilter=e.contentFilter}updateDocumentFromMarkdown(e,t){if(!(isSystemDoc(e)||isConfigDoc(e)))try{let{frontmatter:s,body:g}=stripFrontmatter(t),S=extractFrontmatterTags(s?unwrapFrontmatterFences(s):``),w=extractInlineTagsFromBody(g),E=new Set([...S,...w]),D=new Set;for(let e of E)for(let t of expandTagToHierarchy(e))D.add(t);this.applyDocSnapshot(e,E,D)}catch(t){console.warn(`[tag-index] Failed to scan ${e} for tag extraction:`,t),this.deleteDocument(e)}}deleteDocument(e){if(isSystemDoc(e)||isConfigDoc(e))return;let t=this.state.byDoc.get(e);if(t){for(let s of t){let t=this.state.byTag.get(s);t&&(t.delete(e),t.size===0&&this.state.byTag.delete(s))}this.state.byDoc.delete(e),this.state.byDocLiteral.delete(e)}}renameDocument(e,t,s){this.deleteDocument(e),this.updateDocumentFromMarkdown(t,s)}getDocsForTag(e){let t=this.state.byTag.get(e);return t?[...t].sort((e,t)=>e.localeCompare(t)):[]}getDocsForTagWithMatches(e){let t=this.state.byTag.get(e);if(!t)return[];let s=[];for(let g of t){let t=this.state.byDocLiteral.get(g);if(!t)continue;let S=tagsMatchingPrefix(t,e);s.push({docName:g,matchingTags:[...S].sort((e,t)=>e.localeCompare(t))})}return s.sort((e,t)=>e.docName.localeCompare(t.docName))}getAllTags(){let e=[...this.state.byTag.entries()],t=e.map(([e])=>e),s=new Set;for(let e of t){let t=e.indexOf(`/`);t>0&&s.add(e.slice(0,t));let g=t;for(;g>0;)s.add(e.slice(0,g)),g=e.indexOf(`/`,g+1)}return e.map(([e,t])=>({name:e,count:t.size,isLeaf:!s.has(e)})).sort((e,t)=>e.name.localeCompare(t.name))}init(){if(this.state=createEmptyState(),!existsSync(this.contentDir))return;let e=this.listDocsWithPaths();for(let{docName:t,filePath:s}of e)try{let e=readFileSync(s,`utf-8`);this.updateDocumentFromMarkdown(t,e)}catch(e){console.warn(`[tag-index] Failed to read ${t} during init:`,e)}}applyDocSnapshot(e,t,s){let g=this.state.byDoc.get(e)??new Set;for(let t of g){if(s.has(t))continue;let g=this.state.byTag.get(t);g&&(g.delete(e),g.size===0&&this.state.byTag.delete(t))}for(let t of s){let s=this.state.byTag.get(t);s||(s=new Set,this.state.byTag.set(t,s)),s.add(e)}s.size===0?(this.state.byDoc.delete(e),this.state.byDocLiteral.delete(e)):(this.state.byDoc.set(e,s),this.state.byDocLiteral.set(e,t))}listDocsWithPaths(){let e=[];this.walkContentDir(this.contentDir,e),e.sort((e,t)=>e.docName===t.docName?t.filePath.localeCompare(e.filePath):e.docName.localeCompare(t.docName));let t=new Set;return e.filter(({docName:e})=>t.has(e)?!1:(t.add(e),!0))}walkContentDir(e,t){let s;try{s=readdirSync(e,{withFileTypes:!0})}catch(t){console.warn(`[tag-index] Failed to read directory ${e}:`,t);return}for(let g of s){let s=join(e,g.name);if(g.isDirectory()){let e=relative(this.contentDir,s);if(this.contentFilter&&e&&this.contentFilter.isDirExcluded(e))continue;this.walkContentDir(s,t);continue}if(!g.isFile()||!isSupportedDocFile(g.name))continue;let S=relative(this.contentDir,s);this.contentFilter?.isExcluded(S)||t.push({docName:stripDocExtension(S),filePath:s})}}};const PARK_SNAPSHOT_ORIGIN=(()=>{let e=Object.freeze({origin:`park-snapshot`,paired:!0});return Object.freeze({source:`local`,skipStoreHooks:!1,context:e})})();function createServer$1(e){let{contentDir:t,projectDir:s=t,quiet:g=!0,debounce:S=2e3,maxDebounce:w=1e4,gitEnabled:E=!0,commitDebounceMs:D=3e4,wipRef:O=`refs/wip/main`,configHomedirOverride:k,enableTestRoutes:j=!1,shadowRepo:F,contentRoot:L,destroyTimeoutMs:B=1e4,localOpCliArgs:H,skipStateManifestCheck:q=!1}=e,J=getLogger(`server`);function Y(){let e=readConfigSafely({absPath:resolveConfigPath(`project-local`,s),sideline:!1,warn:e=>J.warn({message:e},`[config] could not read project-local config`)}),t=e.value.autoSync?.enabled;return t==null?(e.valid||J.warn({},`[config] project-local autoSync.enabled unavailable (config invalid) — falling back to project config`),readConfigSafely({absPath:resolveConfigPath(`project`,s),sideline:!1,warn:e=>J.warn({message:e},`[config] could not read project config`)}).value.autoSync?.enabled===!0):t===!0}initTelemetry();let ee=randomUUID(),te=getLocalDir(s);if(acquireServerLock(te,{port:e.port??0,worktreeRoot:s,kind:e.lockKind??`interactive`,capabilities:[`http`,`ws`]}),!q)try{assertCompatibleStateManifest({lockDir:te,shadowRepoDir:resolveShadowDir(s)})}catch(e){throw releaseServerLock(te),e}let ne=createBasenameIndex(),ae=(e,t)=>ne.resolveEmbed(e,t),oe=(e,s)=>{let g=ne.resolveEmbed(e,s);if(!g&&e.includes(`/`)&&(g=e.replace(/^\.?\//,``)),!g)return null;let S=resolve(t,g),w=resolve(t);if(S!==w&&!S.startsWith(`${w}/`))return null;try{let e=statSync(S);return e.isFile()?e.size:null}catch{return null}},se,ce,ue,de,fe,me,ge,_e=null,ve=null,ye=null,Ce=null,we=new Set,Te=!1,De,je,Me,Pe=new Promise((e,t)=>{je=e,Me=t});function Ie(e){_e?.signal(e)}let Re=2e3,ze=null;function Be(){ze!==null&&clearTimeout(ze),ze=setTimeout(()=>{ze=null,ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist debounced cache:`,e)})},2e3)}let Ve=new RecentlyRemovedDocs(void 0,{onEviction:()=>incrementRecentlyRemovedDocsEviction(),onSizeChange:e=>setRecentlyRemovedDocsSize(e)}),Ue=(e,t)=>{isSystemDoc(e)||isConfigDoc(e)||Ve.setRenamed(e,t)},We=e=>{if(!(isSystemDoc(e)||isConfigDoc(e))){if(Ve.peek(e)?.kind===`renamed`){console.info(JSON.stringify({event:`recently-removed-docs-unpaired-delete-suppressed`,docName:e,source:`watcher-delete`}));return}Ve.setDeleted(e)}},Ge=e=>{isSystemDoc(e)||isConfigDoc(e)||Ve.delete(e)};try{se=createContentFilter({projectDir:s,contentDir:t,onAfterRebuild:()=>{ce.rebuildFromDisk(getActiveBranch()).catch(e=>{getLogger(`server-factory`).warn({err:e},`[content-filter] backlink-index rebuild failed after onAfterRebuild`)});try{ue.init()}catch(e){getLogger(`server-factory`).warn({err:e},`[content-filter] tag-index rebuild failed after onAfterRebuild`)}try{let e=Ft?.pruneFileIndexNowExcluded()??0;e>0&&getLogger(`server-factory`).info({pruned:e},`[content-filter] pruned now-excluded entries from fileIndex`)}catch(e){getLogger(`server-factory`).warn({err:e},`[content-filter] fileIndex prune failed after onAfterRebuild`)}}}),ce=new BacklinkIndex({projectDir:s,contentDir:t,contentFilter:se}),ue=new TagIndex({contentDir:t,contentFilter:se});try{ue.init()}catch(e){console.warn(`[server-factory] tag-index init failed; continuing with empty index:`,e)}de={current:F},fe=createPersistenceExtension({contentDir:t,projectDir:s,gitEnabled:E,commitDebounceMs:D,wipRef:O,shadowRef:de,contentRoot:L,backlinkIndex:ce,configHomedirOverride:k,getCurrentBranch:()=>It?.getLastKnownBranch()??null,resolveEmbed:ae,resolveSize:oe,getPrincipal:()=>Ce,onAgentCommit:()=>_e?.signal(`session-activity`),onDiskFlush:(e,t)=>_e?.emitDiskAck(e,t),onConfigRejected:(e,t)=>_e?.emitConfigValidationRejected(e,t),mdManager:e.mdManager}),me=new Hocuspocus({quiet:g,debounce:S,maxDebounce:w,extensions:[fe.extension]});let B=me.shouldUnloadDocument.bind(me);me.shouldUnloadDocument=e=>{if((Te||we.has(e))&&B(e))return!0;let t=e.name;return isSystemDoc(t)||isConfigDoc(t)||getReconciledBase(t)!==void 0||e.getXmlFragment(`default`).length!==0||e.getText(`source`).length!==0?!1:B(e)},De=async e=>{we.add(e);try{await me.unloadDocument(e)}finally{we.delete(e)}},_e=new CC1Broadcaster(me),ve=new AgentFocusBroadcaster(me),ye=new AgentPresenceBroadcaster(me),ge=new AgentSessionManager(me);let q=createLiveDerivedIndexExtension({backlinkIndex:ce,tagIndex:ue,signalChannel:Ie});me.configuration.extensions.push(q),me.configuration.extensions.push({__kind:`principal-auth`,async onAuthenticate(e){let t=e.token,s=parseHocuspocusAuthToken(t),g=s?.expectedServerInstanceId;if(typeof g==`string`&&g.length>0&&g!==ee)throw new HocuspocusAuthRejection(`server-instance-mismatch`,`server instance mismatch: client claimed ${g}, this server is ${ee}`);let S=s?.expectedBranch,w=getActiveBranch();if(typeof S==`string`&&S.length>0&&S!==w)throw new HocuspocusAuthRejection(`branch-mismatch`,`branch mismatch: client claimed ${S}, server is on ${w}`);if(!s)return;let E=e.context;typeof s.principalId==`string`&&(Ce&&s.principalId===Ce.id?E.principalId=Ce.id:Ce?console.warn(JSON.stringify({event:`principal-token-mismatch`,claimed:s.principalId,loaded:Ce.id})):E.principalId=s.principalId),typeof s.tabSessionId==`string`&&(E.tabSessionId=s.tabSessionId),E.kind=`human`}}),me.configuration.extensions.push({__kind:`config-doc-admission-guard`,async onAuthenticate(e){if(!isConfigDoc(e.documentName))return;let t=e.request,s=t.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s))throw Error(`config-doc admission requires loopback peer (peer=${s}, doc=${e.documentName})`);let g=e.requestHeaders,S=(g&&typeof g.get==`function`?g.get(`host`):null)??t.headers?.host??void 0;if(!isAllowedWorkspaceHostHeader(S))throw Error(`config-doc admission requires loopback Host header (host=${S??`<absent>`}, doc=${e.documentName})`)}});let J=resolve(t);function Y(e){if(!isSafeDocName(e))return null;let t=resolve(J,`${e}${getDocExtension(e)}`);return!t.startsWith(`${J}/`)&&t!==J?null:t}me.configuration.extensions.push({__kind:`removal-redirect-guard`,async onAuthenticate(e){await runRemovalRedirectGuard(e.documentName,{recentlyRemovedDocs:Ve,resolveFilePath:Y,fileExists:existsSync})}}),me.configuration.extensions.push({__kind:`system-doc-broadcast-guard`,async beforeHandleMessage(e){if(e.documentName!==`__system__`)return;let t=new IncomingMessage(e.update);if(t.readVarString(),t.readVarUint()===MessageType.BroadcastStateless)throw Error(`inbound BroadcastStateless on ${SYSTEM_DOC_NAME} rejected — server-only channel`)}});let te=createApiExtension({hocuspocus:me,sessionManager:ge,contentDir:t,contentFilter:se,serverInstanceId:ee,getFileIndex:()=>Ft?Ft.getFileIndex():new Map,getFolderIndex:()=>Ft?Ft.getFolderIndex():new Map,getAliasMap:()=>Ft?Ft.getAliasMap():new Map,enableTestRoutes:j,shadowRef:de,flushGitCommit:()=>fe.flushPendingGitCommit(),flushContributors:()=>fe.flushContributors(),getCurrentBranch:()=>It?.getLastKnownBranch()??null,getDiskAckSVs:()=>_e?.getLatestDiskAckSVsAsBase64()??{},contentRoot:L,backlinkIndex:ce,tagIndex:ue,signalChannel:Ie,agentFocusBroadcaster:ve,agentPresenceBroadcaster:ye,onAgentWrite:e.onAgentWrite,getSyncEngine:()=>Lt,localOpCliArgs:H,projectDir:s,resolveEmbed:ae,getPrincipal:()=>Ce,forceUnloadDocument:De,ready:Pe,recentlyRemovedDocs:Ve});me.configuration.extensions.push(te),me.configuration.extensions.push(createServerObserverExtension({mdManager,schema,shadowRef:de,contentRoot:L,getCurrentBranch:()=>It?.getLastKnownBranch()??null,resolveEmbed:ae,resolveSize:oe}))}catch(e){throw releaseServerLock(te),e}let Ke=null,Xe=new Map,$e=[];function nt(e,t){let s=resolve(e,`rescue`),g=resolve(s,`${t}${getDocExtension(t)}`);return g.startsWith(`${s}/`)?g:null}function rt(e){let t=me.documents.get(e);if(!t)return null;let{frontmatter:s,body:g}=stripFrontmatter(t.getText(`source`).toString());return prependFrontmatter(s,g)}let it=(e,t)=>applyExternalChange(me,e,t,ae,oe),at=e=>{if(!e)return;let t=`[[${e}]]`;for(let[s]of me.documents){if(isSystemDoc(s)||isConfigDoc(s))continue;let g=me.documents.get(s);if(!g)continue;let S=g.getText(`source`).toString();if(S.includes(t))try{g.transact(()=>{applyDiskContentToDoc(g,S,ae,s)},FILE_WATCHER_ORIGIN)}catch(t){J.error({err:t,docName:s,assetBasename:e},`[asset-event] failed to re-render ${s} for asset basename ${e}`)}}},st=null,vt=e=>{e&&(st===null&&(st=new Set,setImmediate(()=>{let e=st;if(st=null,e)try{for(let t of e)at(t)}catch(t){J.error({err:t,basenames:[...e]},`[asset-event] dedup rerender pass crashed`)}})),st.add(e))};function Tt(e){switch(e.kind){case`rename`:return e.newDocName;case`asset-create`:case`asset-delete`:case`folder-create`:case`folder-delete`:return e.relativePath;case`create`:case`update`:case`delete`:case`conflict`:return e.docName;default:return assertNeverDiskEvent(e)}}async function Et(e){try{switch(e.kind){case`create`:J.info({docName:e.docName},`[reconcile] create: ${e.docName}`),ce.updateDocumentFromMarkdown(e.docName,e.content),Be(),ue.updateDocumentFromMarkdown(e.docName,e.content),Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`),Ge(e.docName);break;case`update`:{let{docName:t,content:s}=e,g=me.documents.get(t);if(!g){ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`);return}let S=getReconciledBase(t)??``,w=rt(t)??S,E=reconcile({docName:t,base:S,ours:w,theirs:s}),D=contentHash(S).slice(0,6),O=contentHash(w).slice(0,6),k=contentHash(s).slice(0,6);switch(J.info({docName:t,base:D,ours:O,theirs:k,result:E.kind},`[reconcile] ${t} base=${D} ours=${O} theirs=${k} result=${E.kind}`),E.kind){case`noop`:ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`);break;case`clean`:try{it(t,E.newContent),setReconciledBase(t,E.newContent),incrementReconcile(),ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`)}catch(e){J.error({err:e,docName:t},`[reconcile] failed to apply clean content to Y.Doc for ${t}`),setReconciledBase(t,s)}break;case`merged`:try{it(t,E.newContent),setReconciledBase(t,E.newContent),incrementReconcile(),ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`)}catch(e){J.error({err:e,docName:t},`[reconcile] failed to apply merged content to Y.Doc for ${t}`),setReconciledBase(t,s)}break;case`conflicts`:try{it(t,E.newContent),setReconciledBase(t,E.newContent),incrementReconcile(),incrementConflict(),ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`)}catch(e){J.error({err:e,docName:t},`[reconcile] failed to apply conflict content to Y.Doc for ${t}`),setReconciledBase(t,s)}break;case`refused`:{incrementConflict();let e=g.getMap(`lifecycle`);e.set(`status`,`conflict`),e.set(`reason`,E.reason);break}}break}case`delete`:{let{docName:t}=e,s=me.documents.get(t);if(!s){ce.deleteDocument(t),Be(),ue.deleteDocument(t),Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`),We(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));return}let g=getReconciledBase(t)??``,S=rt(t)??``,w=S!==g;if(w&&de.current){let e=de.current,s=It?.getLastKnownBranch()??`main`;queueMicrotask(()=>{saveInMemoryCheckpoint(e,L??``,{kind:`external-change-rescue`,docName:t,contents:S,label:`External change recovered @ ${new Date().toISOString()}`,branch:s,metadata:{incomingDiskSha:``}}).then(()=>{incrementRescueBuffer(),J.info({docName:t},`[reconcile] rescue checkpoint saved (delete): ${t}`)}).catch(e=>{J.error({docName:t,err:e},`[reconcile] rescue checkpoint write failed: ${t}`)})})}s.getMap(`lifecycle`).set(`status`,`deleted-upstream`),deleteReconciledBase(t),ce.deleteDocument(t),Be(),ue.deleteDocument(t),J.info({docName:t,isDirty:w},`[reconcile] delete: ${t} (dirty=${w})`),me.closeConnections(t),await De(s),Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`),We(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));break}case`rename`:{let{oldDocName:t,newDocName:s,content:g}=e,S=me.documents.get(t);if(deleteReconciledBase(t),setReconciledBase(s,g),ce.renameDocument(t,s,g),Be(),ue.renameDocument(t,s,g),S){let e=S.getMap(`lifecycle`);e.set(`status`,`renamed`),e.set(`newPath`,s)}J.info({oldDocName:t,newDocName:s},`[reconcile] rename: ${t} → ${s}`),Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`),Ue(t,s),console.info(JSON.stringify({event:`recently-removed-docs-populate`,from:t,to:s,kind:`renamed`,source:`watcher-rename`}));break}case`conflict`:{let{docName:t}=e,s=me.documents.get(t);if(!s)return;let g=s.getMap(`lifecycle`);g.set(`status`,`conflict`),g.set(`reason`,`conflict-markers`),J.info({docName:t},`[reconcile] conflict markers detected: ${t}`);break}case`asset-create`:ne.add(e.relativePath),Ie(`files`),vt(basename(e.relativePath));break;case`asset-delete`:ne.remove(e.relativePath),Ie(`files`),vt(basename(e.relativePath));break;case`folder-create`:case`folder-delete`:Ie(`files`);break;default:assertNeverDiskEvent(e)}}catch(t){let s=Tt(e);J.error({err:t,kind:e.kind,label:s},`[reconcile] failed to handle ${e.kind} for ${s}`)}}let Dt=[];async function jt(e){if(isBatchInProgress()){Dt.push(e);return}await Et(e)}async function Mt(){let e=Dt.splice(0,Dt.length);for(let t of e)await Et(t)}let Ft=null,It=null,Lt=null,Rt=null;async function zt(e){if(me.documents.size===0)return;let t=!1,s=new Promise(e=>{me.configuration.extensions.push({async afterUnloadDocument({instance:s}){!t&&s.getDocumentsCount()===0&&(t=!0,e())}})}),g=Array.from(me.documents.keys());me.closeConnections(),me.flushPendingStores();for(let e of me.documents.values())e.getConnectionsCount()===0&&me.unloadDocument(e).catch(t=>{console.warn(JSON.stringify({event:`ok-shutdown-unload-document-failed`,docName:e.name,reason:t instanceof Error?t.message:String(t)}))});let S,w=new Promise((s,w)=>{S=setTimeout(()=>{t=!0;let s=Array.from(me.documents.keys()),S=[],E=[];if(de.current){for(let e of s)if(!(isSystemDoc(e)||isConfigDoc(e)))try{let t=rt(e);if(t===null){J.warn({docName:e},`[rescue] skipping ${e} — document dropped from map mid-rescue`),E.push(e);continue}let s=nt(de.current.gitDir,e);if(!s){J.warn({docName:e,gitDir:de.current.gitDir},`[rescue] path-traversal guard rejected docName: ${e}`),E.push(e);continue}mkdirSync(dirname(s),{recursive:!0}),writeFileSync(s,t,`utf-8`),incrementRescueBuffer(),S.push(e),J.info({docName:e},`[rescue] rescue buffer saved on flush timeout: ${e}`)}catch(t){E.push(e),J.error({err:t,docName:e},`[rescue] failed to write rescue buffer for ${e}`)}}else J.warn({stillLoadedCount:s.length},`[rescue] shadow repo unavailable at flush timeout — ${s.length} doc(s) will be lost: [${s.join(`, `)}]`),E.push(...s);let D=S.length>0||E.length>0?` — rescued [${S.join(`, `)}]${E.length>0?`, lost [${E.join(`, `)}]`:``}`:``;w(Error(`flushAllStoresAndWait timeout after ${e}ms — ${s.length}/${g.length} docs did not unload: [${s.join(`, `)}]${D}`))},e)});try{await Promise.race([s,w])}finally{S!==void 0&&clearTimeout(S)}}async function Bt(){return Rt||(Rt=(async()=>{let e=Date.now(),t=[];Te=!0,ze!==null&&(clearTimeout(ze),ze=null);let g,S=await Promise.race([Pe.then(()=>`completed`,e=>(J.debug({err:e},`[server] init incomplete during shutdown`),`failed`)),new Promise(e=>{g=setTimeout(()=>e(`timeout`),5e3)})]);g!==void 0&&clearTimeout(g),S===`timeout`&&J.warn({},`[server] init did not complete within 5s during shutdown`);let w=me.documents.size;try{try{try{It&&=(await It.unsubscribe(),null),Ft&&=(await Ft.unsubscribe(),null);for(let{docName:e,cleanup:t}of $e)try{await t()}catch(t){J.warn({err:t,docName:e},`[server] failed to stop config-file-watcher for ${e}`)}$e.length=0}catch(e){t.push({phase:`watcher-unsubscribe`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-1 watcher unsubscribe failed`)}try{_e?.destroy(),ye?.destroy(),Ke&&=(await Ke.disconnect(),null);for(let[e,t]of Xe)try{await t.disconnect()}catch(t){J.warn({err:t,docName:e},`[server] failed to disconnect ${e} during shutdown`)}Xe.clear()}catch(e){t.push({phase:`cc1-teardown`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-1b CC1 teardown failed`)}try{await ge.closeAll()}catch(e){t.push({phase:`agent-session-drain`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-2 agent session drain failed`)}try{await zt(B)}catch(e){t.push({phase:`flush-all-stores`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-3 flush failed`)}let e;try{await Promise.race([(async()=>{await fe.flushPendingGitCommit(),await fe.waitForPendingCommits()})(),new Promise((t,s)=>{e=setTimeout(()=>s(Error(`L2 git flush timeout`)),B)})])}catch(e){t.push({phase:`git-commit-flush`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-4 git commit flush failed`)}finally{e!==void 0&&clearTimeout(e)}try{Lt&&=(await Lt.destroy(),null)}catch(e){t.push({phase:`sync-engine-stop`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown sync-engine-stop failed`)}}finally{if(de.current){try{let e=(await esm_default({baseDir:s,timeout:{block:5e3}}).revparse(`HEAD`)).trim();e&&writeFileSync(resolve(de.current.gitDir,`last-known-head`),e,`utf-8`)}catch{}try{destroyShadowRepo(de.current)}catch(e){t.push({phase:`shadow-repo-release`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-5 destroyShadowRepo failed`)}}let g=Date.now()-e;t.length===0?J.info({documentCount:w,durationMs:g},`[server] shutdown flushed ${w} documents in ${g}ms`):J.warn({documentCount:w,durationMs:g,phaseErrors:t},`[server] shutdown flushed ${w} documents in ${g}ms with ${t.length} phase error(s)`)}}finally{try{releaseServerLock(te)}catch(e){t.push({phase:`server-lock-release`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-6 releaseServerLock failed`)}try{await shutdownTelemetry()}catch(e){t.push({phase:`telemetry-shutdown`,error:e instanceof Error?e.message:String(e)})}}})(),Rt)}let Vt=[];async function Ht(){try{Ce=await loadPrincipal(s),J.info({principalId:Ce.id},`[server] principal loaded`)}catch(e){J.warn({err:e},`[server] principal load failed — browser writes will use SERVICE_WRITER`)}if(!de.current)try{de.current=await initShadowRepo(s),J.info({gitDir:de.current.gitDir},`[server] history repo initialized at ${de.current.gitDir}`)}catch(e){J.error({err:e},`[server] history repo init failed`),Vt.push(`shadow-repo`)}if(de.current){let e=null;try{e=loadRenameLogIndex(de.current.gitDir),sweepLazyPopOrphans(de.current.gitDir,e),setRenameLogIndex(de.current.gitDir,e),J.info({entries:e.byTo.size},`[server] rename log loaded (${e.byTo.size} entries)`)}catch(e){J.warn({err:e},`[rename-log] boot-time load/sweep failed; rename history unavailable`)}if(e){let t=1e4;try{await Promise.race([gcRenameLog(de.current,e,{rebuild:!0}),new Promise((e,s)=>setTimeout(()=>s(Error(`boot-time GC exceeded ${t}ms`)),t))])}catch(e){J.warn({err:e},`[rename-log] boot-time GC/rebuild failed; index loaded without GC`)}}}if(de.current)try{await shadowGit(de.current).raw(`rev-parse`,`--git-dir`)}catch(e){let t=e instanceof Error?e.message:String(e);if(t.includes(`not a git repository`)||t.includes(`invalid object`)){J.warn({},`[server] history repo appears corrupted — reinitializing`);try{de.current=await initShadowRepo(s)}catch(e){J.error({err:e},`[server] history repo reinit failed`),de.current=void 0,Vt.includes(`shadow-repo`)||Vt.push(`shadow-repo`)}}else J.error({err:e},`[server] history repo check failed (transient?)`)}if(de.current)try{let e=resolve(de.current.gitDir,`last-known-head`),t=null;try{t=readFileSync(e,`utf-8`).trim()||null}catch{}let g=null;try{g=(await esm_default({baseDir:s,timeout:{block:1e4}}).revparse(`HEAD`)).trim()||null}catch{}if(g!==null){if(g!==t){let e=`main`;try{let t=(await esm_default({baseDir:s,timeout:{block:1e4}}).raw(`rev-parse`,`--abbrev-ref`,`HEAD`)).trim();t&&t!==`HEAD`&&(e=t)}catch{}J.info({lastKnownHead:t,currentHead:g,branch:e},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${g}, action=import`);try{await commitUpstreamImport(de.current,L??``,t,g,e),incrementUpstreamImport()}catch(e){J.warn({err:e},`[head-drift] commitUpstreamImport failed — continuing`)}}else J.info({currentHead:g},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${g}, action=noop`);try{writeFileSync(e,g,`utf-8`)}catch(e){J.warn({err:e},`[head-drift] failed to write last-known-head`)}}}catch(e){J.warn({err:e},`[head-drift] check failed — continuing`)}try{let e=recoverPendingManagedRename(t,s);if(e.recovered&&e.journal){let t=e.journal.version===2?e.journal.fromPath:e.journal.sourceDocName,s=e.journal.version===2?e.journal.toPath:e.journal.destinationDocName;J.warn({journalVersion:e.journal.version,fromPath:t,toPath:s,restoredDocNames:e.restoredDocNames},`[managed-rename] recovered pending rename ${t} -> ${s}`)}}catch(e){J.error({err:e},`[server] managed rename recovery failed`),Vt.push(`managed-rename-recovery`)}try{let e=cleanupOrphanUploadTempfiles(s);(e.deleted>0||e.errors>0)&&J.info({scanned:e.scanned,deleted:e.deleted,errors:e.errors},`[upload-tempfile-sweep] swept ${e.deleted} orphan tempfile(s)`)}catch(e){J.error({err:e},`[server] upload-tempfile sweep failed`),Vt.push(`upload-tempfile-sweep`)}try{Ke=await me.openDirectConnection(SYSTEM_DOC_NAME),_e?.emitServerInfo(ee,getActiveBranch())}catch(e){J.error({err:e},`[server] failed to open __system__ direct connection — CC1 push disabled`),Vt.push(`cc1-push`)}for(let e of CONFIG_DOC_NAMES)try{let t=await me.openDirectConnection(e);Xe.set(e,t)}catch(t){J.error({err:t,docName:e},`[server] failed to open ${e} direct connection — config bind degraded`),Vt.push(`config-doc:${e}`)}let e=new Map([[CONFIG_DOC_NAME_PROJECT,resolveConfigPath(`project`,s)],[CONFIG_DOC_NAME_PROJECT_LOCAL,resolveConfigPath(`project-local`,s)],[CONFIG_DOC_NAME_USER,resolveConfigPath(`user`,s,k)]]);for(let t of CONFIG_DOC_NAMES){let s=e.get(t);if(s)try{J.info({docName:t,path:s},`[config-file-watcher] starting`);let e=await startConfigFileWatcher(s,e=>{let s=me.documents.get(t);J.info({docName:t,hasDocument:s!==void 0,contentLength:e.length},`[config-file-watcher] file changed`);let g=applyExternalConfigChange(s??null,t,e,fe.configPersistenceCtx);if(J.info({docName:t,outcome:g},`[config-file-watcher] applyExternalConfigChange outcome`),t===`__config__/project`||t===`__local__/project`){let e=Y();Lt?.setEnabled(e).catch(t=>{J.warn({err:t,enabled:e},`[sync] failed to apply autoSync.enabled from config`)})}});$e.push({docName:t,cleanup:e}),J.info({docName:t,path:s},`[config-file-watcher] started`)}catch(e){J.warn({err:e,docName:t,path:s},`[config-file-watcher] failed to start for ${t}`),Vt.push(`config-file-watcher:${t}`)}}try{let e=resolve(t,`.okignore`),g=resolve(s,`.gitignore`),S=J;S.info({okignorePath:e,gitignorePath:g},`[ignore-watcher] starting multi-path watcher for .okignore + .gitignore`);let w=await startMultiPathConfigFileWatcher([e,g],(t,g)=>{(async()=>{if(t===e)try{let e=applyExternalConfigChange(me.documents.get(`__config__/okignore`)??null,CONFIG_DOC_NAME_OKIGNORE,g,fe.configPersistenceCtx);S.info({docName:CONFIG_DOC_NAME_OKIGNORE,outcome:e},`[ignore-watcher] applyExternalConfigChange outcome`)}catch(e){S.error({err:e,changedPath:relative(s,t)},`[ignore-watcher] applyExternalConfigChange failed; rebuild proceeds independently`)}let w=await se.rebuildIgnorePatterns();if(w.ok)S.info({changedPath:relative(s,t),patternCount:w.patternCount,nestedFileCount:w.nestedFileCount,durationMs:w.durationMs},`[ignore-watcher] rebuild succeeded — broadcasting files channel`),_e?.signal(`files`);else{let e=relative(s,t)||`.`;S.warn({changedPath:e,error:w.error.message},`[ignore-watcher] rebuild failed — emitting config-ignore-nested-error`),_e?.emitConfigIgnoreNestedError(e,w.error.message)}})().catch(e=>{S.error({err:e,changedPath:relative(s,t)||`.`},`[ignore-watcher] handler threw`)})});$e.push({docName:`__ignore-files__`,cleanup:w}),S.info({okignorePath:e,gitignorePath:g},`[ignore-watcher] multi-path watcher started`)}catch(e){J.warn({err:e,projectDir:s,contentDir:t},`[ignore-watcher] failed to start multi-path watcher`),Vt.push(`ignore-files-watcher`)}let g=resolveGitDir(s),S=g?readBranchFromHead(g)??`main`:`main`;switchReconciledBaseScope(S),ce.switchBranch(S);try{{let e=getActiveBranch();try{if(await ce.loadFromDisk(e)){let t=await ce.reconcileWithDisk(e);(t.added>0||t.updated>0||t.deleted>0)&&J.info(t,`[backlinks] startup reconcile: offline changes applied`)}else await ce.rebuildFromDisk(e);ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist startup cache for ${e}:`,t)})}catch(t){J.error({err:t,branch:e},`[backlinks] startup init failed; index will populate incrementally via watcher`)}}Ft=await startWatcher(t,jt,se),ue.init();let e=0;try{seedBasenameIndex({contentDir:t,contentFilter:se,basenameIndex:ne,onSkip:(t,s,g)=>{e++,J.warn({reason:t,code:s,path:g},`[basename-index] skipped entry during seed (${t}${s?` ${s}`:``})`)}}),e>0&&(J.warn({count:e},`[basename-index] startup seed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve`),Vt.push(`basename-index-partial`))}catch(e){J.error({err:e},`[basename-index] startup seed failed`),Vt.push(`basename-index`)}}catch(e){J.error({err:e},`[server] disk bridge watcher failed to start`),Vt.push(`file-watcher`)}try{It=await startHeadWatcher(s,async({trigger:e})=>{if(J.info({trigger:e},`[batch] begin trigger=${e}`),incrementBatch(),me.flushPendingStores(),await fe.flushPendingGitCommit(),setBatchInProgress(!0),de.current){let e=getActiveBranch(),t=resolveGitDir(s),g=t?readBranchFromHead(t)??e:e,S=[];for(let[e,t]of me.documents){if(isSystemDoc(e)||isConfigDoc(e))continue;let s=null;if(t.transact(()=>{s=rt(e)},PARK_SNAPSHOT_ORIGIN),s===null)continue;let g=getReconciledBase(e)??s;S.push({docName:e,markdown:s,diskSnapshot:g})}if(S.length>0)try{let t=await parkBranch(de.current,e,SERVICE_WRITER.id,S,g);t&&(incrementPark(),J.info({count:S.length,branch:e,sha:t.slice(0,8)},`[history] parked ${S.length} docs on ${e} → ${t.slice(0,8)}`))}catch(e){J.error({err:e},`[shadow] park failed`)}}},async e=>{let s=Dt.length,g=e.newBranch??`main`;if(J.info({kind:e.batchKind,headMoved:e.headMoved,docs:s,timeout:!!e.timeout},`[batch] end kind=${e.batchKind} headMoved=${e.headMoved} docs=${s}${e.timeout?` timeout`:``}`),e.batchKind===`within-branch`)setBatchInProgress(!1),await Mt(),await fe.flushDeferredStores(`within-branch`);else{incrementBranchSwitch(),Dt.splice(0,Dt.length),switchReconciledBaseScope(g),ze!==null&&(clearTimeout(ze),ze=null),ce.switchBranch(g),se.rebuildDirCount();try{let e=0;ne.clear(),seedBasenameIndex({contentDir:t,contentFilter:se,basenameIndex:ne,onSkip:(t,s,S)=>{e++,J.warn({reason:t,code:s,path:S,branch:g},`[basename-index] skipped entry during branch-switch reseed (${t}${s?` ${s}`:``})`)}}),e>0&&(J.warn({count:e,branch:g},`[basename-index] branch-switch reseed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve on this branch`),Vt.includes(`basename-index-partial`)||Vt.push(`basename-index-partial`))}catch(e){J.error({err:e,branch:g},`[basename-index] branch-switch reseed failed`)}for(let[e,s]of me.documents)if(!(isSystemDoc(e)||isConfigDoc(e)))try{let S=safeContentPath(e,t);if(!existsSync(S)){let t=getReconciledBase(e)??``,S=rt(e)??``;if(S!==t&&de.current){let t=de.current;queueMicrotask(()=>{saveInMemoryCheckpoint(t,L??``,{kind:`external-change-rescue`,docName:e,contents:S,label:`External change recovered @ ${new Date().toISOString()}`,branch:g,metadata:{incomingDiskSha:``}}).then(()=>{incrementRescueBuffer(),J.info({docName:e},`[reconcile] rescue checkpoint saved on branch switch: ${e}`)}).catch(t=>{J.error({docName:e,err:t},`[reconcile] rescue checkpoint write failed: ${e}`)})})}s.getMap(`lifecycle`).set(`status`,`deleted-upstream`),J.info({docName:e,branch:g},`[branch-switch] tombstone: ${e} (not on ${g})`);continue}let w=readFileSync(S,`utf-8`);it(e,w),setReconciledBase(e,w),J.info({docName:e},`[branch-switch] reset: ${e}`)}catch(t){J.error({err:t,docName:e},`[branch-switch] failed to reset ${e}`)}J.info({branch:g,docCount:me.documents.size},`[branch-switch] loaded branch ${g} (${me.documents.size} docs)`);try{if(await ce.loadFromDisk(g)){let e=await ce.reconcileWithDisk(g);(e.added>0||e.updated>0||e.deleted>0)&&J.info(e,`[backlinks] branch-switch reconcile for ${g}`)}else await ce.rebuildFromDisk(g);ce.saveToDisk(g).catch(e=>{console.warn(`[backlinks] Failed to persist branch cache for ${g}:`,e)})}catch(e){J.error({err:e,branch:g},`[backlinks] branch-switch rebuild failed; backlinks may be stale`)}if(ue.init(),de.current&&e.batchKind===`cross-branch`){let e=0;for(let[t]of me.documents)if(!(isSystemDoc(t)||isConfigDoc(t)))try{let s=await readParkedState(de.current,g,SERVICE_WRITER.id,t);if(!s||s.markdown===s.diskSnapshot)continue;let S=getReconciledBase(t);if(!S)continue;let w=reconcile({docName:t,base:s.diskSnapshot,ours:s.markdown,theirs:S});switch(w.kind){case`merged`:case`clean`:it(t,w.newContent),setReconciledBase(t,w.newContent),e++;break;case`conflicts`:it(t,w.newContent),setReconciledBase(t,w.newContent),incrementConflict(),e++;break;case`noop`:case`refused`:break}}catch(e){J.error({err:e,docName:t},`[branch-switch] restore WIP failed for ${t}`)}e>0&&J.info({count:e,branch:g},`[branch-switch] restored ${e} parked docs on ${g}`)}if(e.oldBranch?.startsWith(`detached-`)&&de.current)try{let t=shadowGit(de.current),s=(await t.raw(`for-each-ref`,`refs/wip/${e.oldBranch}/`,`--format=%(refname)`)).trim();if(s){for(let e of s.split(`
|
|
2367
2367
|
`))e&&await t.raw(`update-ref`,`-d`,e);J.info({context:e.oldBranch},`[branch-switch] cleaned up detached context ${e.oldBranch}`)}}catch(e){J.error({err:e},`[branch-switch] detached cleanup failed`)}setBatchInProgress(!1),await fe.flushDeferredStores(`discard-stale`),_e?.emitBranchSwitched(g)}if(e.headMoved&&e.newHead&&de.current&&s>0){let t=L??`.`;try{let s=await commitUpstreamImport(de.current,t,e.oldHead,e.newHead,g);incrementUpstreamImport(),J.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){J.error({err:e},`[shadow] upstream-import failed`)}}})}catch(e){J.error({err:e},`[server] HEAD watcher failed to start`),Vt.push(`head-watcher`)}let w=H?.[0]??`open-knowledge`,E=[`-c`,`credential.helper=!${H&&H.length>1?H.join(` `):w} auth git-credential`];try{Lt=new SyncEngine({projectDir:s,contentDir:t,contentFilter:se,contentRoot:L,syncEnabled:Y(),credentialArgs:E,cc1Broadcaster:_e,setBatchInProgress:e=>{setBatchInProgress(e),e||fe.flushDeferredStores(`within-branch`).catch(e=>{J.error({err:e},`[persistence] deferred store drain failed after sync batch`)})},onStateChange:e=>{J.info({state:e},`[sync] state → ${e}`)},onAutoDisable:async e=>{J.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||J.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 Lt.start()}catch(e){J.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),Lt=null}Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`)}return Ht().then(je,Me),{hocuspocus:me,sessionManager:ge,cc1Broadcaster:_e,agentFocusBroadcaster:ve,agentPresenceBroadcaster:ye,contentFilter:se,basenameIndex:ne,serverInstanceId:ee,destroy:Bt,ready:Pe,degraded:Vt,lockDir:te,get syncEngine(){return Lt}}}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;async function bootServer(e){initTelemetry();let{kind:t,gitdir:s}=computeWorktreeAttributes(e.projectDir??e.contentDir),g={"ok.worktree.kind":t};return s!==null&&(g[`ok.worktree.gitdir`]=normalizeFsPath(s)),withSpan(`ok.boot`,{attributes:g},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-D7DXNVql-B5nINglj.mjs`).then(e=>e.a),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=findLegacyRuntimeFiles(F);L.length>0&&console.warn(`[boot] Found legacy runtime files at .ok/${L.join(`, `)}. Delete .ok/ and re-init — these files moved to .ok/${LOCAL_DIR}/.`);let B=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}),{hocuspocus:H,destroy:q,ready:J,degraded:Y,lockDir:ee,sessionManager:te,agentFocusBroadcaster:ne,agentPresenceBroadcaster:ae}=B,oe=(()=>{let t=e.host??`localhost`;return t===`0.0.0.0`||t===`::`?`localhost`:t.includes(`:`)&&!t.startsWith(`[`)?`[${t}]`:t})(),se=e.port??0,ce=createMcpHttpHandler({contentDir:e.contentDir,projectDir:e.projectDir??e.contentDir,config:e.config,getServerUrl:()=>`http://${oe}:${se}`,log:S}),ue=D();ue.headersTimeout=3e4,ue.requestTimeout=6e4;let de=e.serveContentAssets?createAssetServeMiddleware({contentFilter:B.contentFilter,contentSirv:build_default(e.contentDir,{dev:!0,dotfiles:!1}),inlineExtensions:INLINE_RENDERABLE_EXTENSIONS,assetExtensions:ASSET_EXTENSIONS,blocklistExtensions:EXECUTABLE_BLOCKLIST_EXTENSIONS}):void 0,fe=mountMcpAndApi({httpServer:ue,hocuspocus:H,mcpHttpHandler:ce,log:S,sessionManager:te,agentFocusBroadcaster:ne,agentPresenceBroadcaster:ae,keepaliveGraceMs:e.keepaliveGraceMs,contentAssetMiddleware:de}),me=null;g!==null&&(me=attachIdleShutdown({httpServer:ue,thresholdMs:g??DEFAULT_IDLE_THRESHOLD_MS,log:S,onShutdown:(e.idleShutdownHandler??(e=>async()=>{await e()}))(async()=>{await q()})})),await new Promise((t,s)=>{let g=e=>s(e);ue.once(`error`,g),ue.listen(e.port,e.host,()=>{ue.removeListener(`error`,g),t()})});let ge=ue.address(),_e=typeof ge==`object`&&ge?ge.port:e.port??0;if(se=_e,O(ee,_e),s&&e.spawnUiSiblingFn)try{await e.spawnUiSiblingFn({lockDir:ee,log:S})}catch(e){S.warn({err:e},`spawnUiSiblingFn failed`)}let ve=!1,ye=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{httpServer:ue,destroy:async()=>{if(ve)return;ve=!0;let e=[],t=async(t,s)=>{try{await ye(t,s)}catch(s){e.push(s),S.warn({err:s,step:t},`bootServer destroy step failed`)}};try{me?.detach()}catch(t){e.push(t),S.warn({err:t,step:`idleHandle.detach`},`bootServer destroy step failed`)}if(await t(`mount.shutdown`,()=>fe.shutdown()),await t(`mcpHttpHandler.close`,()=>ce.close()),await t(`mount.wss.close`,()=>new Promise((e,t)=>{fe.wss.close(s=>s?t(s):e())})),await t(`httpServer.closeAllConnections`,async()=>{ue.closeAllConnections?.()}),await t(`httpServer.close`,()=>new Promise((e,t)=>{ue.close(s=>s&&s.code!==`ERR_SERVER_NOT_RUNNING`?t(s):e())})),await t(`destroyHocuspocus`,()=>q()),await t(`shutdownTelemetry`,()=>shutdownTelemetry()),e.length>0)throw AggregateError(e,`bootServer destroy completed with errors`)},lockDir:ee,contentDir:e.contentDir,port:_e,ready:J,degraded:Y,didAutoInit:k,serverInstance:B}}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 ANCESTOR_WALK_DEPTH_LIMIT$1=30,GIT_MARKER=`.git`;function findEnclosingGitRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT$1;){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 ANCESTOR_WALK_DEPTH_LIMIT=30,OK_CONFIG_MARKER=`.ok/config.yml`;function findEnclosingProjectRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT;){let e=!1;try{e=existsSync(resolve(t,OK_CONFIG_MARKER))}catch{e=!1}if(e)return{rootPath:t,distance:s};let g=dirname(t);if(g===t)return null;t=g,s+=1}return null}const execFileAsync=promisify(execFile);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};console.log(`[project-git] 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?(console.log(`[project-git] backfilled missing .git/HEAD at ${t}`),{didInit:!0,repaired:!0}):(console.log(`[project-git] initialized .git/ at ${t} (branch: main)`),{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}}export{applySeed as $,runAuthReposSubprocess as $n,incrementCollabSocketFilteredError as $t,MissingOkConfigError as A,readServerPackageVersion as An,updateUiLockPort as Ar,createServer$1 as At,STARTER_FOLDER_FRONTMATTER_FILENAME as B,registerWrite as Bn,McpServer as Br,findEnclosingGitRoot as Bt,LOG_MD_TEMPLATE as C,parseHocuspocusAuthToken as Cn,tracedRenameSync as Cr,createContentFilter as Ct,MCP_SERVER_NAME as D,planSeed as Dn,tracedWriteFile as Dr,createMcpHttpHandler as Dt,MCP_CONNECTION_ID_HEADER as E,planPersonalTemplates as En,tracedUnlinkSync as Er,createLiveDerivedIndexExtension as Et,ProjectGitInitError as F,readUiLock as Fn,withSpanSync as Fr,detectProjectShape as Ft,SeedPrerequisiteError as G,resolveContentDir as Gn,isJSONRPCResultResponse as Gr,getCurrentMcpLogger as Gt,STARTER_PACK_IDS as H,removeLastKnownHash as Hn,LATEST_PROTOCOL_VERSION as Hr,formatAuthRejectionWire as Ht,ROLLBACK_ORIGIN as I,reconcile as In,writePersonalTemplates as Ir,ensureProjectGit as It,TagIndex as J,resolveLockDir as Jn,writeConfigPatch as Jr,getMeter as Jt,SeedRootDirError as K,resolveCursorBinaryDefault as Kn,readConfigSafely as Kr,getLocalDir as Kt,SERVICE_WRITER as L,recordContributor as Ln,writeStateManifest as Lr,errorResponse as Lt,PERSONAL_TEMPLATES as M,readStateManifest as Mn,validateCloneInputs as Mr,createStreamingErrorWriter as Mt,PERSONAL_TEMPLATE_NAMES as N,readTargetRecordedAt as Nn,validateSkillZip as Nr,createTestLogger as Nt,MISSING_OK_CONFIG_MESSAGE as O,readAllTargets as On,tracedWriteFileSync as Or,createOsProbe as Ot,PinoLogger as P,readTargetVersion as Pn,withSpan as Pr,detectClaudeDesktopPresence as Pt,applyExternalChange as Q,rewriteWikiLinksForDocumentRename as Qn,handleSpawnCursor as Qt,SKILL_INSTALL_EVENTS_FILE_REL as R,recordSkillInstallEvent as Rn,writeTargetVersion as Rr,evictStaleTrackerEntries as Rt,LIVE_DERIVED_INDEX_DEBOUNCE_MS as S,parseAuthRejectionWire as Sn,tracedRename as Sr,createAssetServeMiddleware as St,MAX_AGENT_SESSIONS as T,pathToDocName as Tn,tracedRmdirSync as Tr,createExternalChangeHandler as Tt,STARTER_TEMPLATES as U,resetMetrics as Un,isInitializedNotification as Ur,formatContributors as Ut,STARTER_PACKS as V,releaseUiLock as Vn,JSONRPCMessageSchema as Vr,findEnclosingProjectRoot as Vt,STATE_MANIFEST_FILENAME as W,resolveBundledSkillDir as Wn,isJSONRPCRequest as Wr,gcCheckpointRefs as Wt,acquireUiLock as X,resolvePackageVersion as Xn,MalformedGitPointerError as Xr,getTracer as Xt,UiLockCollisionError as Y,resolvePack as Yn,GitDirAccessError as Yr,getMetrics as Yt,applyAgentMarkdownWrite as Z,rewriteMarkdownLinksForDocumentRename as Zn,handleCollabSocketError as Zt,GIT_UPSTREAM_WRITER as _,listStarterPacks as _n,toBroadcasterKey as _r,commitWipFromTree as _t,AgentPresenceBroadcaster as a,isAllowedApiOrigin as an,safeSubdir as ar,buildExecResult as at,HocuspocusAuthTokenSchema as b,mountMcpAndApi as bn,tracedMkdir as br,contributorCount as bt,BacklinkIndex as c,isHocuspocusAuthRejectionReason as cn,saveInMemoryCheckpoint as cr,buildSkillZip as ct,CURSOR_BUNDLE_PATHS_BY_PLATFORM as d,isPairedWriteOrigin as dn,setActiveSpanAttributes as dr,classifyEvents as dt,incrementServerObserverFire as en,runAuthStatusSubprocess as er,assertCompatibleStateManifest as et,ConfigSchema as f,isPathWithinDir as fn,shadowGit as fr,classifyFsPath as ft,FILE_WATCHER_ORIGIN as g,listRescueCheckpoints as gn,streamingProblemEvent as gr,commitWip as gt,FILE_SYSTEM_WRITER as h,lastKnownHash as hn,startWatcher as hr,commitUpstreamImport as ht,AgentFocusBroadcaster as i,installUserSkill as in,safeContentPath as ir,buildAndOpenSkill as it,OBSERVER_SYNC_ORIGIN as j,readSkillInstallStateSnapshot as jn,validateAgentId as jr,createServerObserverExtension as jt,McpLogger as k,readBranchFromHead as kn,updateLastKnownHash as kr,createPersistenceExtension as kt,CC1Broadcaster as l,isKnownPackId as ln,saveVersion as lr,buildStarterFolderFrontmatterYaml as lt,DEFAULT_PACK_ID as m,isSystemDoc as mn,splitMarkdownBlocks as mr,coercePackId as mt,AGENT_ID_RE as n,initTelemetry as nn,runDeviceFlowSubprocess as nr,attachIdleShutdown as nt,AgentSessionCapacityError as o,isAllowedWorkspaceHostHeader as on,safetyCheckpoint as or,buildInstructions as ot,DEFAULT_CHECKPOINT_RETENTION as p,isSelfWrite as pn,shutdownTelemetry as pr,clearContributors as pt,StateManifestError as q,resolveCursorSpawnInvocation as qn,resolveConfigPath as qr,getLogger as qt,AGENT_WRITE_ORIGIN as r,installTestLoggers as rn,runWithMcpLogger as rr,bootServer as rt,AgentSessionManager as s,isConfigDoc as sn,sanitizeClientName as sr,buildReadResult as st,AGENT_ID_MAX_LEN as t,initShadowRepo as tn,runCloneSubprocess as tr,assertNeverDiskEvent as tt,CONFLICT_MARKER_RE as u,isLoopbackAddress as un,seedBasenameIndex as ur,buildWipTree as ut,HOCUSPOCUS_AUTH_REJECTION_REASONS as v,loadPrincipal as vn,tracedAppendFileSync as vr,containsConflictMarkers as vt,MANAGED_RENAME_ORIGIN as w,parseKeepaliveConnectionId as wn,tracedRmSync as wr,createContentFilterAsync as wt,INSTALLED_AGENTS_SCHEMES as x,normalizeFsPath as xn,tracedMkdirSync as xr,createApiExtension as xt,HocuspocusAuthRejection as y,loggerFactory as yn,tracedLinkSync as yr,contentHash as yt,STARTER_FOLDERS as z,registerAllTools as zn,writeTracker as zr,extractWikiLinksFromMarkdown as zt};
|
|
2368
|
-
//# sourceMappingURL=dist-
|
|
2368
|
+
//# sourceMappingURL=dist-Bfw3oOGm.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Bn as e,Ct as t,Ft as n,Lt as r,Rn as i,Sn as a,k as o}from"./dist-
|
|
1
|
+
import{Bn as e,Ct as t,Ft as n,Lt as r,Rn as i,Sn as a,k as o}from"./dist-k62w-4-v.mjs";import{_ as s,a as c,c as l,d as u,f as d,g as f,i as p,l as m,m as h,n as g,o as _,p as v,r as y,s as b,t as x,u as S}from"./server-lock-D7DXNVql-BRVVzA6T.mjs";import{$ as C,$n as w,$t as T,A as E,An as D,Ar as O,At as k,B as A,Bn as j,Bt as M,C as N,Cn as P,Cr as F,Ct as I,D as L,Dn as R,Dr as z,Dt as B,E as V,En as H,Er as U,Et as W,F as G,Fn as K,Fr as q,Ft as J,G as Y,Gn as X,Gt as Z,H as Q,Hn as $,Ht as ee,I as te,In as ne,Ir as re,It as ie,J as ae,Jn as oe,Jt as se,K as ce,Kn as le,Kt as ue,L as de,Ln as fe,Lr as pe,Lt as me,M as he,Mn as ge,Mr as _e,Mt as ve,N as ye,Nn as be,Nr as xe,Nt as Se,O as Ce,On as we,Or as Te,Ot as Ee,P as De,Pn as Oe,Pr as ke,Pt as Ae,Q as je,Qn as Me,Qt as Ne,R as Pe,Rn as Fe,Rr as Ie,Rt as Le,S as Re,Sn as ze,Sr as Be,St as Ve,T as He,Tn as Ue,Tr as We,Tt as Ge,U as Ke,Un as qe,Ut as Je,V as Ye,Vn as Xe,Vt as Ze,W as Qe,Wn as $e,Wt as et,X as tt,Xn as nt,Xr as rt,Xt as it,Y as at,Yn as ot,Yr as st,Yt as ct,Z as lt,Zn as ut,Zt as dt,_ as ft,_n as pt,_r as mt,_t as ht,a as gt,an as _t,ar as vt,at as yt,b as bt,bn as xt,br as St,bt as Ct,c as wt,cn as Tt,cr as Et,ct as Dt,d as Ot,dn as kt,dr as At,dt as jt,en as Mt,er as Nt,et as Pt,f as Ft,fn as It,fr as Lt,ft as Rt,g as zt,gn as Bt,gr as Vt,gt as Ht,h as Ut,hn as Wt,hr as Gt,ht as Kt,i as qt,in as Jt,ir as Yt,it as Xt,j as Zt,jn as Qt,jr as $t,jt as en,k as tn,kn as nn,kr as rn,kt as an,l as on,ln as sn,lr as cn,lt as ln,m as un,mn as dn,mr as fn,mt as pn,n as mn,nn as hn,nr as gn,nt as _n,o as vn,on as yn,or as bn,ot as xn,p as Sn,pn as Cn,pr as wn,pt as Tn,q as En,qn as Dn,qt as On,r as kn,rn as An,rr as jn,rt as Mn,s as Nn,sn as Pn,sr as Fn,st as In,t as Ln,tn as Rn,tr as zn,tt as Bn,u as Vn,un as Hn,ur as Un,ut as Wn,v as Gn,vn as Kn,vr as qn,vt as Jn,w as Yn,wn as Xn,wr as Zn,wt as Qn,x as $n,xn as er,xr as tr,xt as nr,y as rr,yn as ir,yr as ar,yt as or,z as sr,zn as cr,zr as lr,zt as ur}from"./dist-Bfw3oOGm.mjs";export{Ln as AGENT_ID_MAX_LEN,mn as AGENT_ID_RE,kn as AGENT_WRITE_ORIGIN,qt as AgentFocusBroadcaster,gt as AgentPresenceBroadcaster,vn as AgentSessionCapacityError,Nn as AgentSessionManager,wt as BacklinkIndex,on as CC1Broadcaster,o as CC1_CONTRACT_VERSION,Vn as CONFLICT_MARKER_RE,Ot as CURSOR_BUNDLE_PATHS_BY_PLATFORM,Ft as ConfigSchema,Sn as DEFAULT_CHECKPOINT_RETENTION,un as DEFAULT_PACK_ID,Ut as FILE_SYSTEM_WRITER,zt as FILE_WATCHER_ORIGIN,ft as GIT_UPSTREAM_WRITER,st as GitDirAccessError,Gn as HOCUSPOCUS_AUTH_REJECTION_REASONS,rr as HocuspocusAuthRejection,bt as HocuspocusAuthTokenSchema,$n as INSTALLED_AGENTS_SCHEMES,Re as LIVE_DERIVED_INDEX_DEBOUNCE_MS,N as LOG_MD_TEMPLATE,Yn as MANAGED_RENAME_ORIGIN,He as MAX_AGENT_SESSIONS,V as MCP_CONNECTION_ID_HEADER,L as MCP_SERVER_NAME,Ce as MISSING_OK_CONFIG_MESSAGE,rt as MalformedGitPointerError,tn as McpLogger,E as MissingOkConfigError,Zt as OBSERVER_SYNC_ORIGIN,t as ORPHAN_MODES,he as PERSONAL_TEMPLATES,ye as PERSONAL_TEMPLATE_NAMES,De as PinoLogger,x as ProcessLockCollisionError,G as ProjectGitInitError,te as ROLLBACK_ORIGIN,g as RUNTIME_VERSION,de as SERVICE_WRITER,Pe as SKILL_INSTALL_EVENTS_FILE_REL,n as SKILL_STATE_TARGETS,sr as STARTER_FOLDERS,A as STARTER_FOLDER_FRONTMATTER_FILENAME,Ye as STARTER_PACKS,Q as STARTER_PACK_IDS,Ke as STARTER_TEMPLATES,Qe as STATE_MANIFEST_FILENAME,y as STATE_SCHEMA_VERSION,r as SYSTEM_DOC_NAME,Y as SeedPrerequisiteError,ce as SeedRootDirError,p as ServerLockCollisionError,En as StateManifestError,ae as TagIndex,at as UiLockCollisionError,c as acquireProcessLock,_ as acquireServerLock,tt as acquireUiLock,lt as applyAgentMarkdownWrite,je as applyExternalChange,C as applySeed,Pt as assertCompatibleStateManifest,Bn as assertNeverDiskEvent,_n as attachIdleShutdown,Mn as bootServer,Xt as buildAndOpenSkill,yt as buildExecResult,xn as buildInstructions,In as buildReadResult,Dt as buildSkillZip,ln as buildStarterFolderFrontmatterYaml,Wn as buildWipTree,jt as classifyEvents,Rt as classifyFsPath,Tn as clearContributors,pn as coercePackId,a as colorFromSeed,Kt as commitUpstreamImport,Ht as commitWip,ht as commitWipFromTree,Jn as containsConflictMarkers,or as contentHash,Ct as contributorCount,nr as createApiExtension,Ve as createAssetServeMiddleware,I as createContentFilter,Qn as createContentFilterAsync,Ge as createExternalChangeHandler,W as createLiveDerivedIndexExtension,B as createMcpHttpHandler,Ee as createOsProbe,an as createPersistenceExtension,k as createServer,en as createServerObserverExtension,ve as createStreamingErrorWriter,Se as createTestLogger,Ae as detectClaudeDesktopPresence,J as detectProjectShape,ie as ensureProjectGit,me as errorResponse,Le as evictStaleTrackerEntries,ur as extractWikiLinksFromMarkdown,M as findEnclosingGitRoot,Ze as findEnclosingProjectRoot,ee as formatAuthRejectionWire,Je as formatContributors,et as gcCheckpointRefs,Z as getCurrentMcpLogger,ue as getLocalDir,On as getLogger,se as getMeter,ct as getMetrics,it as getTracer,dt as handleCollabSocketError,Ne as handleSpawnCursor,i as iconFromClientName,T as incrementCollabSocketFilteredError,Mt as incrementServerObserverFire,Rn as initShadowRepo,hn as initTelemetry,An as installTestLoggers,Jt as installUserSkill,_t as isAllowedApiOrigin,yn as isAllowedWorkspaceHostHeader,Pn as isConfigDoc,Tt as isHocuspocusAuthRejectionReason,sn as isKnownPackId,Hn as isLoopbackAddress,e as isOrphanMode,kt as isPairedWriteOrigin,It as isPathWithinDir,b as isProcessAlive,Cn as isSelfWrite,dn as isSystemDoc,l as isValidLockPid,Wt as lastKnownHash,Bt as listRescueCheckpoints,pt as listStarterPacks,Kn as loadPrincipal,m as lockFilePath,ir as loggerFactory,xt as mountMcpAndApi,er as normalizeFsPath,ze as parseAuthRejectionWire,P as parseHocuspocusAuthToken,Xn as parseKeepaliveConnectionId,Ue as pathToDocName,H as planPersonalTemplates,R as planSeed,we as readAllTargets,nn as readBranchFromHead,S as readProcessLock,u as readProcessLockDetailed,d as readServerLock,D as readServerPackageVersion,Qt as readSkillInstallStateSnapshot,ge as readStateManifest,be as readTargetRecordedAt,Oe as readTargetVersion,K as readUiLock,ne as reconcile,fe as recordContributor,Fe as recordSkillInstallEvent,cr as registerAllTools,j as registerWrite,v as releaseProcessLock,h as releaseServerLock,Xe as releaseUiLock,$ as removeLastKnownHash,qe as resetMetrics,$e as resolveBundledSkillDir,X as resolveContentDir,le as resolveCursorBinaryDefault,Dn as resolveCursorSpawnInvocation,oe as resolveLockDir,ot as resolvePack,nt as resolvePackageVersion,ut as rewriteMarkdownLinksForDocumentRename,Me as rewriteWikiLinksForDocumentRename,w as runAuthReposSubprocess,Nt as runAuthStatusSubprocess,zn as runCloneSubprocess,gn as runDeviceFlowSubprocess,jn as runWithMcpLogger,Yt as safeContentPath,vt as safeSubdir,bn as safetyCheckpoint,Fn as sanitizeClientName,Et as saveInMemoryCheckpoint,cn as saveVersion,Un as seedBasenameIndex,At as setActiveSpanAttributes,Lt as shadowGit,wn as shutdownTelemetry,fn as splitMarkdownBlocks,Gt as startWatcher,Vt as streamingProblemEvent,mt as toBroadcasterKey,qn as tracedAppendFileSync,ar as tracedLinkSync,St as tracedMkdir,tr as tracedMkdirSync,Be as tracedRename,F as tracedRenameSync,Zn as tracedRmSync,We as tracedRmdirSync,U as tracedUnlinkSync,z as tracedWriteFile,Te as tracedWriteFileSync,rn as updateLastKnownHash,f as updateProcessLockPort,s as updateServerLockPort,O as updateUiLockPort,$t as validateAgentId,_e as validateCloneInputs,xe as validateSkillZip,ke as withSpan,q as withSpanSync,re as writePersonalTemplates,pe as writeStateManifest,Ie as writeTargetVersion,lr as writeTracker};
|