@inkeep/open-knowledge 0.17.1-beta.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/skills/discovery/SKILL.md +1 -1
- package/dist/assets/skills/packs/codebase-wiki/SKILL.md +83 -0
- package/dist/assets/skills/project/SKILL.md +2 -1
- package/dist/cli.mjs +6 -6
- package/dist/constants-D0UsRgbB.mjs +2 -0
- package/dist/{dist-DfeFCiM5.mjs → dist-BHcT0KGM.mjs} +1 -1
- package/dist/{dist-DS-lr0dJ.mjs → dist-tPUaTm_u.mjs} +288 -7
- package/dist/index.mjs +1 -1
- package/dist/{init-C0ivSgZ8.mjs → init-BFG2ghkC.mjs} +4 -4
- package/dist/init-BulGTEgm.mjs +1 -0
- package/dist/{loader-Cq9-sjAl.mjs → loader-BEqRM_pR.mjs} +2 -2
- package/dist/loader-BghksmoN.mjs +1 -0
- package/dist/preview-BhPAnYGD.mjs +1 -0
- package/dist/{preview-BxpJZ3Yd.mjs → preview-_3nIZqhs.mjs} +2 -2
- package/dist/public/assets/{index-BLv-umMW.js → index-B4rb10PI.js} +97 -97
- package/dist/public/index.html +1 -1
- package/dist/{repair-launch-json-Ce3TeUe3.mjs → repair-launch-json-YeRqJWps.mjs} +2 -2
- package/dist/{repair-mcp-configs-CuapyiV-.mjs → repair-mcp-configs-BKMBSaQH.mjs} +2 -2
- package/dist/repair-skills-BsaDvWeT.mjs +1 -0
- package/dist/{repair-skills-BMwoxPAJ.mjs → repair-skills-DrU906t1.mjs} +2 -2
- package/dist/{src-CBFTj7fX.mjs → src-Bg9Hg2C5.mjs} +2 -2
- package/dist/{start-_PTfnYFZ.mjs → start-B8FKFBEY.mjs} +2 -2
- package/dist/start-DjJemr88.mjs +1 -0
- package/dist/{write-project-skill-DVFdi_YZ.mjs → write-project-skill-CdqDqhyf.mjs} +2 -2
- package/package.json +1 -1
- package/dist/constants-DI9ybvfY.mjs +0 -2
- package/dist/init-B1gdXQCY.mjs +0 -1
- package/dist/loader-CNLvkkvM.mjs +0 -1
- package/dist/preview-fO2q72Jk.mjs +0 -1
- package/dist/repair-skills-BTAEHhVs.mjs +0 -1
- package/dist/start-yX3Bgm1V.mjs +0 -1
|
@@ -1195,7 +1195,129 @@ tags: [postmortem]
|
|
|
1195
1195
|
## What went well
|
|
1196
1196
|
|
|
1197
1197
|
## Action items
|
|
1198
|
-
`},
|
|
1198
|
+
`},CODEBASE_WIKI_FOLDERS=[{path:`wiki/architecture`,title:`Architecture`,description:"System boundaries, layers, subsystems, and cross-cutting concerns — the big-picture structure. One page per architectural area, each with a `mermaid` system-context or component diagram, the key components, and the design decisions behind them. Uses the `architecture-page` template. Cross-link the modules and flows each area touches. Reference source files per the wiki source-reference convention (relative links + symbol code-spans for `internal`; GitHub blob URLs for `public`).",tags:[`wiki`,`architecture`],starterTemplate:`architecture-page`},{path:`wiki/modules`,title:`Modules`,description:"One page per package or module: purpose, responsibilities, public API / entry points, key files (linked per the source-reference convention), dependencies, and the flows it participates in. Uses the `module-page` template. At `depth: tour` these fold into the architecture pages; at `standard`+ each package gets its own page. Cross-link concepts and flows.",tags:[`wiki`,`module`],starterTemplate:`module-page`},{path:`wiki/flows`,title:`Flows`,description:"Key end-to-end flows as `mermaid` sequence or flow diagrams plus narrative — how a request, job, or interaction moves through the system. Uses the `flow-page` template; record failure modes at `depth: exhaustive`. Link every module and concept the flow crosses.",tags:[`wiki`,`flow`],starterTemplate:`flow-page`},{path:`wiki/concepts`,title:`Concepts`,description:"Glossary of atomic pages for domain terms and core abstractions — the vocabulary a newcomer needs. Uses the `concept-page` template: definition, why it matters, where it lives in the code. Keep pages small and densely cross-linked so concepts become hubs for everywhere they appear.",tags:[`wiki`,`concept`],starterTemplate:`concept-page`},{path:`wiki/guides`,title:`Guides`,description:'Task-oriented "how / where do I change X" walkthroughs. Uses the `guide-page` template: goal, steps, relevant code, gotchas. Populated at `depth: standard` and rich at `exhaustive`; thin or empty at `tour`. Link the modules and flows each guide touches.',tags:[`wiki`,`guide`,`how-to`],starterTemplate:`guide-page`}],CODEBASE_WIKI_TEMPLATES={"architecture-page":`---
|
|
1199
|
+
template:
|
|
1200
|
+
title: Architecture Page
|
|
1201
|
+
description: One subsystem, layer, or cross-cutting concern — boundaries, a diagram, and the key components.
|
|
1202
|
+
type: architecture
|
|
1203
|
+
tags: [wiki, architecture]
|
|
1204
|
+
---
|
|
1205
|
+
|
|
1206
|
+
## Summary
|
|
1207
|
+
|
|
1208
|
+
## Diagram
|
|
1209
|
+
|
|
1210
|
+
## Key components
|
|
1211
|
+
|
|
1212
|
+
## Design decisions
|
|
1213
|
+
|
|
1214
|
+
## Related
|
|
1215
|
+
`,"module-page":`---
|
|
1216
|
+
template:
|
|
1217
|
+
title: Module Page
|
|
1218
|
+
description: One package or module — its purpose, public surface, key files, and dependencies.
|
|
1219
|
+
type: module
|
|
1220
|
+
tags: [wiki, module]
|
|
1221
|
+
---
|
|
1222
|
+
|
|
1223
|
+
## Summary
|
|
1224
|
+
|
|
1225
|
+
## Responsibilities
|
|
1226
|
+
|
|
1227
|
+
## Public API / entry points
|
|
1228
|
+
|
|
1229
|
+
## Key files
|
|
1230
|
+
|
|
1231
|
+
## Dependencies
|
|
1232
|
+
|
|
1233
|
+
## Participates in
|
|
1234
|
+
|
|
1235
|
+
## Related
|
|
1236
|
+
`,"flow-page":`---
|
|
1237
|
+
template:
|
|
1238
|
+
title: Flow Page
|
|
1239
|
+
description: One end-to-end flow as a sequence diagram, with narrative and failure modes.
|
|
1240
|
+
type: flow
|
|
1241
|
+
tags: [wiki, flow]
|
|
1242
|
+
---
|
|
1243
|
+
|
|
1244
|
+
## Summary
|
|
1245
|
+
|
|
1246
|
+
## Trigger
|
|
1247
|
+
|
|
1248
|
+
## Sequence diagram
|
|
1249
|
+
|
|
1250
|
+
## Steps
|
|
1251
|
+
|
|
1252
|
+
## Failure modes
|
|
1253
|
+
|
|
1254
|
+
## Related
|
|
1255
|
+
`,"concept-page":`---
|
|
1256
|
+
template:
|
|
1257
|
+
title: Concept Page
|
|
1258
|
+
description: One domain term or core abstraction — what it means, why it matters, and where it lives in the code.
|
|
1259
|
+
type: concept
|
|
1260
|
+
tags: [wiki, concept]
|
|
1261
|
+
---
|
|
1262
|
+
|
|
1263
|
+
## Definition
|
|
1264
|
+
|
|
1265
|
+
## Why it matters
|
|
1266
|
+
|
|
1267
|
+
## Where it lives
|
|
1268
|
+
|
|
1269
|
+
## Related
|
|
1270
|
+
`,"guide-page":`---
|
|
1271
|
+
template:
|
|
1272
|
+
title: Guide Page
|
|
1273
|
+
description: A task-oriented how / where-do-I-change-X walkthrough — goal, steps, relevant code, and gotchas.
|
|
1274
|
+
type: guide
|
|
1275
|
+
tags: [wiki, guide]
|
|
1276
|
+
---
|
|
1277
|
+
|
|
1278
|
+
## Goal
|
|
1279
|
+
|
|
1280
|
+
## Steps
|
|
1281
|
+
|
|
1282
|
+
## Relevant code
|
|
1283
|
+
|
|
1284
|
+
## Gotchas
|
|
1285
|
+
|
|
1286
|
+
## Related
|
|
1287
|
+
`},CODEBASE_WIKI_OVERVIEW_MD=`---
|
|
1288
|
+
title: Codebase Wiki — Overview
|
|
1289
|
+
description: Home page and navigation hub for this codebase wiki. Generated and refreshed by the wiki workflow.
|
|
1290
|
+
profile:
|
|
1291
|
+
source_commit:
|
|
1292
|
+
tags: [wiki, overview]
|
|
1293
|
+
---
|
|
1294
|
+
|
|
1295
|
+
# Overview
|
|
1296
|
+
|
|
1297
|
+
The home page and navigation hub for this codebase's wiki. It is a stub until you run the wiki workflow — ask your agent to "build the wiki" (optionally naming an audience and depth, e.g. "public, exhaustive"), or call \`workflow({ kind: "wiki" })\` directly.
|
|
1298
|
+
|
|
1299
|
+
Once generated, this page carries: what the project is, a big-picture architecture diagram, and a navigation map linking every section below.
|
|
1300
|
+
|
|
1301
|
+
## What this is
|
|
1302
|
+
|
|
1303
|
+
## Architecture at a glance
|
|
1304
|
+
|
|
1305
|
+
## Navigation
|
|
1306
|
+
|
|
1307
|
+
- Architecture — system boundaries, layers, subsystems
|
|
1308
|
+
- Modules — one page per package / module
|
|
1309
|
+
- Flows — key end-to-end sequences
|
|
1310
|
+
- Concepts — glossary of domain terms and core abstractions
|
|
1311
|
+
- Guides — task-oriented how / where-do-I-change-X walkthroughs
|
|
1312
|
+
`,CODEBASE_WIKI_LOG_MD=`---
|
|
1313
|
+
title: Wiki Log
|
|
1314
|
+
description: Append-only audit trail of wiki generation and refresh runs.
|
|
1315
|
+
---
|
|
1316
|
+
|
|
1317
|
+
# Wiki Log
|
|
1318
|
+
|
|
1319
|
+
Append-only audit trail. Add one dated entry per generation or refresh run, recording the profile, the \`source_commit\` it was anchored to, and the coverage. The codebase-wiki skill describes the entry shape.
|
|
1320
|
+
`,PLAIN_NOTES_FOLDERS=[{path:`notes`,title:`Notes`,description:`Flat notes, one file per topic. The "I just want to write" home base — link freely and the graph builds itself.`,tags:[`notes`,`flat`],starterTemplate:`note`},{path:`daily`,title:`Daily`,description:"Daily journal entries, one file per day (`YYYY-MM-DD.md`): morning intentions, evening reflection.",tags:[`daily`,`journal`],starterTemplate:`daily`}],PLAIN_NOTES_TEMPLATES={note:`---
|
|
1199
1321
|
template:
|
|
1200
1322
|
title: Note title
|
|
1201
1323
|
description: One-line summary.
|
|
@@ -1789,8 +1911,8 @@ Every document outside this file and \`log.md\` carries a non-empty \`type\` in
|
|
|
1789
1911
|
`,OKF_LOG_MD=`# Log
|
|
1790
1912
|
|
|
1791
1913
|
Change history for this knowledge base, newest entry first. Add a dated entry (\`## YYYY-MM-DD: <summary>\`) whenever you create, edit, or restructure content — one entry per working session, not per file.
|
|
1792
|
-
`,STARTER_PACKS={"knowledge-base":{id:`knowledge-base`,name:`Knowledge base`,description:`Trusted articles from your sources.`,defaultSubfolder:`brain`,folders:KNOWLEDGE_BASE_FOLDERS,templates:KNOWLEDGE_BASE_TEMPLATES,rootFiles:{"log.md":KNOWLEDGE_BASE_LOG_MD}},"software-lifecycle":{id:`software-lifecycle`,name:`Software lifecycle`,description:`Proposals, decisions, and specs.`,defaultSubfolder:`project-docs`,folders:SOFTWARE_LIFECYCLE_FOLDERS,templates:SOFTWARE_LIFECYCLE_TEMPLATES},"plain-notes":{id:`plain-notes`,name:`Plain notes`,description:`Notes and daily entries.`,defaultSubfolder:void 0,folders:PLAIN_NOTES_FOLDERS,templates:PLAIN_NOTES_TEMPLATES},okf:{id:`okf`,name:`Open Knowledge Format`,description:`Wiki using Google's Open Knowledge Format.`,defaultSubfolder:void 0,folders:OKF_FOLDERS,templates:OKF_TEMPLATES,rootFiles:{"welcome.md":OKF_WELCOME_MD,"index.md":OKF_INDEX_MD,"log.md":OKF_LOG_MD}},"writing-pipeline":{id:`writing-pipeline`,name:`Writing pipeline`,description:`From first draft to finished piece.`,defaultSubfolder:`writing`,folders:WRITING_PIPELINE_FOLDERS,templates:WRITING_PIPELINE_TEMPLATES},"entity-vault":{id:`entity-vault`,name:`Personal CRM`,description:`Track the people, companies, and meetings.`,defaultSubfolder:`vault`,folders:ENTITY_VAULT_FOLDERS,templates:ENTITY_VAULT_TEMPLATES,rootFiles:{"log.md":ENTITY_VAULT_LOG_MD,"USER.md":ENTITY_VAULT_USER_MD,"SOUL.md":ENTITY_VAULT_SOUL_MD,"ACCESS_POLICY.md":ENTITY_VAULT_ACCESS_POLICY_MD,"HEARTBEAT.md":ENTITY_VAULT_HEARTBEAT_MD}},worldbuilding:{id:`worldbuilding`,name:`Worldbuilding`,description:`A wiki for your story world.`,defaultSubfolder:`world`,folders:WORLDBUILDING_FOLDERS,templates:WORLDBUILDING_TEMPLATES}},STARTER_PACK_IDS=Object.keys(STARTER_PACKS);function resolvePack(e){return e&&STARTER_PACKS[e]||STARTER_PACKS[DEFAULT_PACK_ID]}function isKnownPackId(e){return typeof e==`string`&&STARTER_PACK_IDS.includes(e)}function coercePackId(e){return isKnownPackId(e)?e:void 0}function deriveFolderSummary(e){let t=e.trim(),s=(/^([^.!?]+[.!?])/.exec(t)?.[1]??t).trim();return s.length<=140?s:`${s.slice(0,137)}…`}function listStarterPacks(){return STARTER_PACK_IDS.map(e=>{let t=STARTER_PACKS[e];return{id:t.id,name:t.name,description:t.description,defaultSubfolder:t.defaultSubfolder,folders:t.folders.map(e=>({path:e.path,summary:deriveFolderSummary(e.description)})),entryCounts:computePackEntryCounts(t)}})}function computePackEntryCounts(e){let t=e.folders.length,s=0;for(let t of e.folders)s+=1+(t.extraTemplates?.length??0);return s+=e.rootFiles?Object.keys(e.rootFiles).length:0,{files:s,folders:t}}const STARTER_FOLDERS=KNOWLEDGE_BASE_FOLDERS,STARTER_TEMPLATES=KNOWLEDGE_BASE_TEMPLATES,LOG_MD_TEMPLATE=KNOWLEDGE_BASE_LOG_MD,STARTER_FOLDER_FRONTMATTER_FILENAME=`frontmatter.yml`;function buildStarterFolderFrontmatterYaml(e){let t=[];t.push(`title: ${yamlScalar(e.title)}`),t.push(`description: ${yamlScalar(e.description)}`),t.push(`tags:`);for(let s of e.tags)t.push(` - ${yamlScalar(s)}`);return`${t.join(`
|
|
1793
|
-
`)}\n`}function yamlScalar(e){return e===``?`""`:/[:#\n"'\\]|^\s|\s$/.test(e)?`"${e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`:e}function resolveFileContent(e,t){let s=/^(
|
|
1914
|
+
`,STARTER_PACKS={"knowledge-base":{id:`knowledge-base`,name:`Knowledge base`,description:`Trusted articles from your sources.`,defaultSubfolder:`brain`,folders:KNOWLEDGE_BASE_FOLDERS,templates:KNOWLEDGE_BASE_TEMPLATES,rootFiles:{"log.md":KNOWLEDGE_BASE_LOG_MD}},"software-lifecycle":{id:`software-lifecycle`,name:`Software lifecycle`,description:`Proposals, decisions, and specs.`,defaultSubfolder:`project-docs`,folders:SOFTWARE_LIFECYCLE_FOLDERS,templates:SOFTWARE_LIFECYCLE_TEMPLATES},"codebase-wiki":{id:`codebase-wiki`,name:`Codebase wiki`,description:"An agent-authored, navigable wiki of your codebase — architecture, modules, flows, concepts, and guides, with diagrams, cross-links, and source references. Generated and refreshed by the `wiki` workflow; version-controlled and private by default.",defaultSubfolder:void 0,folders:CODEBASE_WIKI_FOLDERS,templates:CODEBASE_WIKI_TEMPLATES,rootFiles:{"wiki/OVERVIEW.md":CODEBASE_WIKI_OVERVIEW_MD,"wiki/log.md":CODEBASE_WIKI_LOG_MD}},"plain-notes":{id:`plain-notes`,name:`Plain notes`,description:`Notes and daily entries.`,defaultSubfolder:void 0,folders:PLAIN_NOTES_FOLDERS,templates:PLAIN_NOTES_TEMPLATES},okf:{id:`okf`,name:`Open Knowledge Format`,description:`Wiki using Google's Open Knowledge Format.`,defaultSubfolder:void 0,folders:OKF_FOLDERS,templates:OKF_TEMPLATES,rootFiles:{"welcome.md":OKF_WELCOME_MD,"index.md":OKF_INDEX_MD,"log.md":OKF_LOG_MD}},"writing-pipeline":{id:`writing-pipeline`,name:`Writing pipeline`,description:`From first draft to finished piece.`,defaultSubfolder:`writing`,folders:WRITING_PIPELINE_FOLDERS,templates:WRITING_PIPELINE_TEMPLATES},"entity-vault":{id:`entity-vault`,name:`Personal CRM`,description:`Track the people, companies, and meetings.`,defaultSubfolder:`vault`,folders:ENTITY_VAULT_FOLDERS,templates:ENTITY_VAULT_TEMPLATES,rootFiles:{"log.md":ENTITY_VAULT_LOG_MD,"USER.md":ENTITY_VAULT_USER_MD,"SOUL.md":ENTITY_VAULT_SOUL_MD,"ACCESS_POLICY.md":ENTITY_VAULT_ACCESS_POLICY_MD,"HEARTBEAT.md":ENTITY_VAULT_HEARTBEAT_MD}},worldbuilding:{id:`worldbuilding`,name:`Worldbuilding`,description:`A wiki for your story world.`,defaultSubfolder:`world`,folders:WORLDBUILDING_FOLDERS,templates:WORLDBUILDING_TEMPLATES}},STARTER_PACK_IDS=Object.keys(STARTER_PACKS);function resolvePack(e){return e&&STARTER_PACKS[e]||STARTER_PACKS[DEFAULT_PACK_ID]}function isKnownPackId(e){return typeof e==`string`&&STARTER_PACK_IDS.includes(e)}function coercePackId(e){return isKnownPackId(e)?e:void 0}function deriveFolderSummary(e){let t=e.trim(),s=(/^([^.!?]+[.!?])/.exec(t)?.[1]??t).trim();return s.length<=140?s:`${s.slice(0,137)}…`}function listStarterPacks(){return STARTER_PACK_IDS.map(e=>{let t=STARTER_PACKS[e];return{id:t.id,name:t.name,description:t.description,defaultSubfolder:t.defaultSubfolder,folders:t.folders.map(e=>({path:e.path,summary:deriveFolderSummary(e.description)})),entryCounts:computePackEntryCounts(t)}})}function computePackEntryCounts(e){let t=e.folders.length,s=0;for(let t of e.folders)s+=1+(t.extraTemplates?.length??0);return s+=e.rootFiles?Object.keys(e.rootFiles).length:0,{files:s,folders:t}}const STARTER_FOLDERS=KNOWLEDGE_BASE_FOLDERS,STARTER_TEMPLATES=KNOWLEDGE_BASE_TEMPLATES,LOG_MD_TEMPLATE=KNOWLEDGE_BASE_LOG_MD,STARTER_FOLDER_FRONTMATTER_FILENAME=`frontmatter.yml`;function buildStarterFolderFrontmatterYaml(e){let t=[];t.push(`title: ${yamlScalar(e.title)}`),t.push(`description: ${yamlScalar(e.description)}`),t.push(`tags:`);for(let s of e.tags)t.push(` - ${yamlScalar(s)}`);return`${t.join(`
|
|
1915
|
+
`)}\n`}function yamlScalar(e){return e===``?`""`:/[:#\n"'\\]|^\s|\s$/.test(e)?`"${e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`:e}function resolveFileContent(e,t){if(t.rootFiles?.[e]!==void 0)return t.rootFiles[e];let s=/^(.+)\/\.ok\/frontmatter\.yml$/.exec(e);if(s){let e=t.folders.find(e=>e.path===s[1]);return e?buildStarterFolderFrontmatterYaml(e):void 0}let g=/^(.+)\/\.ok\/templates\/([^/]+)\.md$/.exec(e);if(g){let e=g[2]??``;return t.templates[e]}}async function applySeed(e,t={}){let s=Date.now(),g=resolve(t.projectDir??process.cwd()),S=resolvePack(t.packId??`knowledge-base`),w=0,E=[],D=[];for(let t of e.created)try{let e=assertEntryPathInProject(g,t.path);D.push({entry:t,absPath:e})}catch(e){E.push({path:typeof t.path==`string`?t.path:String(t.path),error:e instanceof SeedRootDirError||e instanceof Error?e.message:String(e)})}for(let{entry:e,absPath:t}of D.filter(e=>e.entry.kind===`folder`))try{mkdirSync(t,{recursive:!0}),w+=1}catch(t){E.push({path:e.path,error:t instanceof Error?t.message:String(t)})}for(let{entry:e,absPath:t}of D.filter(e=>e.entry.kind===`file`)){let s=e.template??e.path,g=resolveFileContent(s,S);if(g===void 0){E.push({path:e.path,error:`No content template registered for template id "${s}" in pack "${S.id}"`});continue}if(!existsSync(t))try{writeFileSync(t,g,`utf-8`),w+=1}catch(t){E.push({path:e.path,error:t instanceof Error?t.message:String(t)})}}let O=installPackSkill(g,S.id);return{applied:w,errors:E,durationMs:Date.now()-s,packSkillsInstalled:O}}function frontmatterTemplateId(e){return`${e}/.ok/frontmatter.yml`}function templateFileTemplateId(e,t){return`${e}/.ok/templates/${t}.md`}function normalizeRootDir(e,t){if(!e)return``;let s=e.trim();if(s===``||s===`.`||s===`./`)return``;if(s.startsWith(`/`))throw new SeedRootDirError(`rootDir must be relative to the project directory, got: ${e}`);let g=s.replace(/\\/g,`/`).replace(/^\.\//,``).replace(/\/+$/,``);if(g.split(`/`).some(e=>e===`..`))throw new SeedRootDirError(`rootDir must not contain '..' segments, got: ${e}`);return assertEntryPathInProject(t,g),g}function joinRelative(e,t){return e===``?t:`${e}/${t}`}async function planSeed(e={}){let t=resolve(e.projectDir??process.cwd());if(!isProjectRoot(t))throw new SeedPrerequisiteError(`No ${OK_PROJECT_MARKER} found at ${t}. Run \`ok init\` first to scaffold the tool config.`);let s=normalizeRootDir(e.rootDir,t),g=resolvePack(e.packId??`knowledge-base`),S=[],w=[],E=[];s!==``&&(existsSync(join(t,s))?w.push({path:s,reason:`already-exists`}):S.push({path:s,kind:`folder`}));for(let e of g.folders){let D=joinRelative(s,e.path);existsSync(join(t,D))?w.push({path:D,reason:`already-exists`}):S.push({path:D,kind:`folder`});let O=`${D}/.ok`;existsSync(join(t,O))?w.push({path:O,reason:`already-exists`}):S.push({path:O,kind:`folder`});let k=`${O}/${STARTER_FOLDER_FRONTMATTER_FILENAME}`;existsSync(join(t,k))?w.push({path:k,reason:`already-exists`}):S.push({path:k,kind:`file`,template:frontmatterTemplateId(e.path)});let j=`${O}/templates`;existsSync(join(t,j))?w.push({path:j,reason:`already-exists`}):S.push({path:j,kind:`folder`});let F=[e.starterTemplate,...e.extraTemplates??[]];for(let s of F){let D=`${j}/${s}.md`;if(existsSync(join(t,D))){w.push({path:D,reason:`already-exists`});continue}if(g.templates[s]===void 0){let t=s===e.starterTemplate;E.push(t?`No starter template body registered for "${s}" in pack "${g.id}". The folder will land without a pre-selected template.`:`No body registered for extra template "${s}" in pack "${g.id}". The folder will land without that optional variant.`);continue}S.push({path:D,kind:`file`,template:templateFileTemplateId(e.path,s)})}}if(g.rootFiles)for(let e of Object.keys(g.rootFiles)){let g=joinRelative(s,e);existsSync(join(t,g))?w.push({path:g,reason:`already-exists`}):S.push({path:g,kind:`file`,template:e})}return{created:S,skipped:w,warnings:E}}const PACK_INSPIRATION_NOTE=[`These are patterns to adapt to your domain, not a layout to copy verbatim.`,"To build a variant: create your own folders (via `write` or your editor) and reuse only the ideas that fit.","To adopt this pack as-is: re-run without `--dry-run`."].join(`
|
|
1794
1916
|
`);function folderTemplateNames(e){return[e.starterTemplate,...e.extraTemplates??[]].join(`, `)}function formatPackRationale(e){let t=[`Pack: ${e.name} — ${e.description}`,``,PACK_INSPIRATION_NOTE,``];t.push(`Layout & rationale:`);for(let s of e.folders)t.push(` ${s.path}/ — ${s.title}`),t.push(` why: ${s.description}`),t.push(` templates: ${folderTemplateNames(s)}`);let s=e.rootFiles?Object.keys(e.rootFiles):[];return s.length>0&&t.push(``,`Root files: ${s.join(`, `)}`),t.join(`
|
|
1795
1917
|
`)}function createSingleFlight(){let e=new Map;return{run(t,s){let g=e.get(t);if(g)return{promise:g,coalesced:!0};let S=s();e.set(t,S);let w=()=>{e.get(t)===S&&e.delete(t)};return S.then(w,w),{promise:S,coalesced:!1}},get size(){return e.size}}}const log$7=getLogger(`suggest-links`),WORD_CHAR_RE=/[\p{L}\p{N}]/u,WIKI_LINK_RE=/\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/y,MD_LINK_RE=/\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y,MD_IMAGE_RE=/!\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y;var SuggestLinksTargetNotFoundError=class extends Error{constructor(e){super(`Document not found: ${e}`),this.name=`SuggestLinksTargetNotFoundError`}};function normalizeSnippet(e){return e.replace(/\s+/g,` `).trim()}function snippetAround(e,t,s){if(!normalizeSnippet(e))return null;let g=Math.max(e.lastIndexOf(`.`,t-1),e.lastIndexOf(`?`,t-1),e.lastIndexOf(`!`,t-1),e.lastIndexOf(`
|
|
1796
1918
|
`,t-1)),S=[e.indexOf(`.`,s),e.indexOf(`?`,s),e.indexOf(`!`,s),e.indexOf(`
|
|
@@ -2174,7 +2296,7 @@ Six sub-passes, each with its own STOP gate.
|
|
|
2174
2296
|
|
|
2175
2297
|
### 5b. Hub identification (⛔ STOP gate 5b)
|
|
2176
2298
|
|
|
2177
|
-
1. Run \`links({ kind: "hubs" })\` — surfaces
|
|
2299
|
+
1. Run \`links({ kind: "hubs" })\` — surfaces the most-linked-to docs (highest *inbound* links), i.e. pages already acting as hubs.
|
|
2178
2300
|
2. For each substantial \`[KB]\` folder (those that got templates in Phase 4):
|
|
2179
2301
|
- Check if a hub already exists (\`<folder>/README.md\`, \`<folder>/INDEX.md\`, \`<folder>/CATALOGUE.md\`).
|
|
2180
2302
|
- If yes: don't create a new one (anti-pattern: don't create INDEX.md hubs).
|
|
@@ -2924,8 +3046,167 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
2924
3046
|
- **Don't skip the scoping gate in Supervised mode.** The user's rubric shapes everything downstream; you cannot recover a wrong-scope article cheaply.
|
|
2925
3047
|
- **Don't mix 1P codebase analysis into the article unless asked.** Findings drift from factual synthesis to opinion when you do.
|
|
2926
3048
|
- **Don't overwrite existing research silently.** If the topic was researched before, either iterate (Path C) or create a clearly-named successor (\`crdt-alternatives-2.md\`) and mark the old one as superseded.
|
|
2927
|
-
`}
|
|
2928
|
-
|
|
3049
|
+
`}function buildWikiBody(e){return`# Codebase Wiki — Generate + Refresh
|
|
3050
|
+
|
|
3051
|
+
You're invoked because the user wants a **wiki of this codebase** — DeepWiki, but living in their own repo. Your job: read the source code and author a navigable, diagram-rich, source-grounded wiki as markdown INTO the OK knowledge base, under \`wiki/\`. It is version-controlled, private by default, co-editable, renders in OK's live preview, and becomes grounding context for future agent sessions.
|
|
3052
|
+
|
|
3053
|
+
Content directory: \`${e}\` (from \`.ok/config.yml\`). The wiki lives at \`${e}/wiki/\`.
|
|
3054
|
+
|
|
3055
|
+
**Two toolsets, two jobs.** Read source code with your NATIVE tools (\`Read\`/\`Grep\`/\`Glob\`/\`Bash\` — OK MCP does not index non-markdown source). Author and audit the wiki with OK MCP verbs (\`write\`/\`edit\` for pages, \`links\`/\`search\` for the graph, \`exec\` for markdown listings). Never hand-write the wiki markdown with native \`Write\`/\`Edit\` — that bypasses attribution, backlinks, and the live preview.
|
|
3056
|
+
|
|
3057
|
+
**Server requirement.** Phases that author or audit the wiki (\`write\`/\`edit\`/\`links\`/\`search\`) need the OK Hocuspocus server. Source reading (native tools) and git (\`exec\`/native \`Bash\`) do not. If a \`write\` returns "Hocuspocus server is not running", tell the user to run \`ok start\` and retry — do NOT fall back to native file writes for the wiki markdown.
|
|
3058
|
+
|
|
3059
|
+
**Prerequisite.** This guide assumes the \`codebase-wiki\` pack is seeded (\`ok seed --pack codebase-wiki\` → \`wiki/\` with \`architecture/ modules/ flows/ concepts/ guides/\`, each carrying folder frontmatter + a page template, plus \`wiki/OVERVIEW.md\` + \`wiki/log.md\`). If \`exec("ls -A ${e}/wiki")\` shows the layout is missing, tell the user to seed first, then re-invoke.
|
|
3060
|
+
|
|
3061
|
+
---
|
|
3062
|
+
|
|
3063
|
+
## The two knobs
|
|
3064
|
+
|
|
3065
|
+
Read these from the user's natural-language request (e.g. "build the wiki, public and exhaustive"). They are NOT engine config — they tune what you produce. Record the chosen profile in \`wiki/OVERVIEW.md\` frontmatter (\`profile: <audience>/<depth>\`) so refreshes stay consistent.
|
|
3066
|
+
|
|
3067
|
+
| Knob | Values | Effect |
|
|
3068
|
+
|---|---|---|
|
|
3069
|
+
| \`audience\` | \`internal\` (default) │ \`public\` | \`internal\`: dense; may cite internal infra; reference source via **relative links + symbol code-spans**. \`public\`: polished prose; **omit secrets, internal infra, ticket/PR numbers**; reference source via **GitHub blob URLs** (only if a remote exists — else fall back to relative). |
|
|
3070
|
+
| \`depth\` | \`tour\` │ \`standard\` (default) │ \`exhaustive\` | \`tour\`: OVERVIEW + architecture + top flows only (fold modules into architecture). \`standard\`: + one page per package/module + concepts. \`exhaustive\`: + sub-module pages, \`guides/\`, per-flow failure modes, denser diagrams. |
|
|
3071
|
+
|
|
3072
|
+
Default when the user says nothing: \`internal\` / \`standard\`.
|
|
3073
|
+
|
|
3074
|
+
---
|
|
3075
|
+
|
|
3076
|
+
## Source-reference convention (how wiki pages point at code)
|
|
3077
|
+
|
|
3078
|
+
- **Intra-wiki navigation** → OK doc links (\`[Auth flow](../flows/auth.md)\`). These build the full backlink / hub / orphan graph. Link liberally — density is how the wiki stays navigable.
|
|
3079
|
+
- **Code references, \`internal\`** → a relative markdown link to the source file plus an inline code-span for the symbol — e.g. the \`bootServer()\` symbol in [boot.ts](../../packages/server/src/boot.ts). Relative links click-open in the asset preview and produce **no dead-link noise** (the link graph only tracks \`.md\`/\`.mdx\` edges, so source links are never reported dead). A cosmetic \`#Lxx\` is fine but not navigable.
|
|
3080
|
+
- **Code references, \`public\`** → GitHub blob URLs (\`https://github.com/<org>/<repo>/blob/<branch>/path/to/file.ts\`) so a reader without the repo can follow them. Detect the remote with \`exec\` (or native \`git remote get-url origin\`); if there is none, fall back to relative links.
|
|
3081
|
+
|
|
3082
|
+
Never invent paths — every source reference must point at a file you actually read.
|
|
3083
|
+
|
|
3084
|
+
---
|
|
3085
|
+
|
|
3086
|
+
## Mode detection — generate vs. refresh
|
|
3087
|
+
|
|
3088
|
+
\`exec("cat ${e}/wiki/OVERVIEW.md")\` and read its frontmatter:
|
|
3089
|
+
|
|
3090
|
+
- **\`source_commit\` is empty / OVERVIEW is the seeded stub** → **GENERATE** (Phases 0–7 below).
|
|
3091
|
+
- **\`source_commit\` is stamped with a commit** → **REFRESH** (jump to the *Refresh mode* section). Reuse the recorded \`profile\` unless the user explicitly changes a knob.
|
|
3092
|
+
|
|
3093
|
+
---
|
|
3094
|
+
|
|
3095
|
+
## GENERATE — phased, STOP-gated (⛔ = wait for user confirmation)
|
|
3096
|
+
|
|
3097
|
+
Work the phases in order. Do not skip or batch ahead of a ⛔ gate. Each page is authored with OK \`write\`/\`edit\`; create from the seeded templates (\`write({ document: { path, template: "<name>" } })\`) so pages start with the right skeleton, then fill the sections.
|
|
3098
|
+
|
|
3099
|
+
### Phase 0 — Resolve profile + scope (⛔ STOP gate 0)
|
|
3100
|
+
|
|
3101
|
+
1. Resolve \`audience\` + \`depth\` from the request (default \`internal/standard\`).
|
|
3102
|
+
2. Propose the **coverage set** (which packages/dirs the wiki will document) and **exclusions** (vendored deps, build output, generated code, fixtures — \`node_modules/\`, \`dist/\`, \`build/\`, \`vendor/\`, \`third_party/\`, \`coverage/\`, lockfiles).
|
|
3103
|
+
3. Present profile + coverage + exclusions to the user. **Wait for confirmation.**
|
|
3104
|
+
|
|
3105
|
+
### Phase 1 — Survey (no writes) (⛔ STOP gate 1)
|
|
3106
|
+
|
|
3107
|
+
Read, don't write. Use native tools:
|
|
3108
|
+
|
|
3109
|
+
1. **Detect the stack** — languages, build system, package manager, workspace/monorepo layout, entry points. (\`Glob\` for manifests: \`package.json\`, \`Cargo.toml\`, \`go.mod\`, \`pyproject.toml\`, \`*.csproj\`; read them.)
|
|
3110
|
+
2. **Bootstrap from existing docs** — READ \`README\`, \`AGENTS.md\`/\`CLAUDE.md\`, \`ARCHITECTURE.md\`, \`CONTRIBUTING\`, per-package READMEs. **Summarize and link to them; do NOT duplicate.** They are your highest-signal starting point.
|
|
3111
|
+
3. **Map the modules** — list packages/top-level source dirs; note each one's rough purpose and entry points.
|
|
3112
|
+
4. Produce an **inventory + a proposed page list scaled to \`depth\`**:
|
|
3113
|
+
- \`tour\` → OVERVIEW + 1–3 architecture pages + top 1–3 flows.
|
|
3114
|
+
- \`standard\` → + one module page per package + a concepts glossary.
|
|
3115
|
+
- \`exhaustive\` → + sub-module pages, \`guides/\`, per-flow failure modes.
|
|
3116
|
+
5. Present the page list. **Wait for confirmation.**
|
|
3117
|
+
|
|
3118
|
+
### Phase 2 — Overview hub
|
|
3119
|
+
|
|
3120
|
+
Author \`wiki/OVERVIEW.md\` (edit the seeded stub in place):
|
|
3121
|
+
1. **What this is** — 1–2 paragraphs: what the project does, who it's for.
|
|
3122
|
+
2. **Architecture at a glance** — a big-picture \`mermaid\` diagram. Example:
|
|
3123
|
+
\`\`\`mermaid
|
|
3124
|
+
flowchart TD
|
|
3125
|
+
CLI[ok CLI] --> Server[Hocuspocus server]
|
|
3126
|
+
App[React editor] --> Server
|
|
3127
|
+
Server --> Disk[(markdown + .ok/)]
|
|
3128
|
+
\`\`\`
|
|
3129
|
+
(Mermaid label text has sharp edges — if a write returns a \`mermaid-parse-error\` warning, fix that fence and re-edit. \`palette({ components: ["Mermaid"] })\` lists the gotchas.)
|
|
3130
|
+
3. **Navigation** — a map that links **every section and every page you will create**, as OK doc links. OVERVIEW is the hub; everything must be reachable from it.
|
|
3131
|
+
4. **Stamp frontmatter**: set \`profile: <audience>/<depth>\` and \`source_commit: <git rev-parse HEAD>\` (run \`exec("git rev-parse HEAD")\` or native \`git\`). \`source_commit\` is the freshness anchor refresh mode diffs against — get it right.
|
|
3132
|
+
|
|
3133
|
+
### Phase 3 — Architecture pages
|
|
3134
|
+
|
|
3135
|
+
One page per architectural area (boundaries, layers, subsystems, cross-cutting concerns). Each: a system-context or component \`mermaid\` diagram, the key components (with source references per the convention), and the design decisions behind them. Cross-link the modules and flows each area touches. (At \`depth: tour\`, modules fold into these pages.)
|
|
3136
|
+
|
|
3137
|
+
### Phase 4 — Module pages
|
|
3138
|
+
|
|
3139
|
+
One page per package/module (skip at \`tour\`; scale sub-module depth by knob). Use the \`module-page\` template: purpose, responsibilities, public API / entry points, **key files** (linked per the convention), dependencies, and the flows it participates in. Cross-link concepts and flows.
|
|
3140
|
+
|
|
3141
|
+
### Phase 5 — Flows
|
|
3142
|
+
|
|
3143
|
+
Key end-to-end sequences (request lifecycle, build/deploy, a core interaction) as \`mermaid\` sequence or flow diagrams + narrative. At \`exhaustive\`, add a **Failure modes** section per flow. Link every module and concept the flow crosses.
|
|
3144
|
+
|
|
3145
|
+
### Phase 6 — Concepts / glossary
|
|
3146
|
+
|
|
3147
|
+
Atomic pages for domain terms and core abstractions (one term each): definition, why it matters, where it lives in the code. Keep them small and densely cross-linked so each concept becomes a hub for everywhere it appears. Link concepts from the architecture/module/flow pages that use them.
|
|
3148
|
+
|
|
3149
|
+
### Phase 7 — Link-graph activation + audit
|
|
3150
|
+
|
|
3151
|
+
1. Confirm **OVERVIEW links every page** (it is the nav hub). Add any missing nav links. This is OVERVIEW's check — it's a *source* (high out-degree), verified by forward links here, not by the \`hubs\` view below.
|
|
3152
|
+
2. Run \`links({ kind: ["orphans", "hubs", "dead"] })\`:
|
|
3153
|
+
- **orphans** — pages nothing links to. Adopt each by linking it from OVERVIEW or a relevant section page (or, rarely, justify it as intentionally standalone).
|
|
3154
|
+
- **hubs** — ranks by *inbound* links. Confirm your **concept/module pages** show up here — that's the signal cross-linking actually happened. Don't expect \`OVERVIEW\`: a freshly authored nav page has almost no inbound links, so it won't appear (and that's correct — its coverage was checked in step 1).
|
|
3155
|
+
- **dead** — fix or remove every dead link. (Source-file links never appear here — only \`.md\`/\`.mdx\` edges are tracked.)
|
|
3156
|
+
3. Append a \`wiki/log.md\` entry (see *Log discipline*).
|
|
3157
|
+
4. Tell the user the wiki is ready and surface the OVERVIEW preview URL.
|
|
3158
|
+
|
|
3159
|
+
---
|
|
3160
|
+
|
|
3161
|
+
## REFRESH mode (re-invoke after code changes)
|
|
3162
|
+
|
|
3163
|
+
Incremental by default — don't re-read the whole repo.
|
|
3164
|
+
|
|
3165
|
+
1. Read \`source_commit\` + \`profile\` from \`wiki/OVERVIEW.md\` frontmatter. Reuse the profile unless the user changed a knob.
|
|
3166
|
+
2. \`exec("git diff --stat <source_commit>..HEAD")\` (or native \`git\`). Inspect the changed paths.
|
|
3167
|
+
3. **Map changed code → affected pages.** For each changed package/area, update its module/architecture/flow pages (read the changed source first). Update OVERVIEW only if the structure changed (new package, removed subsystem, new top-level flow).
|
|
3168
|
+
4. **Full-regen fallback.** If the diff is large or structural (many packages, a restructure), or git is unavailable / \`source_commit\` is missing, fall back to a full GENERATE pass rather than a partial patch.
|
|
3169
|
+
5. **Re-stamp** \`source_commit\` to the new \`git rev-parse HEAD\` and re-run the Phase 7 link-graph audit on the touched pages.
|
|
3170
|
+
6. Append a \`wiki/log.md\` refresh entry.
|
|
3171
|
+
|
|
3172
|
+
---
|
|
3173
|
+
|
|
3174
|
+
## Log discipline
|
|
3175
|
+
|
|
3176
|
+
\`wiki/log.md\` is an append-only audit trail. Append one dated entry per generation or refresh run (one per run, not per page). Reference touched pages as markdown links so they register in the backlink graph. Entry shape:
|
|
3177
|
+
|
|
3178
|
+
\`\`\`markdown
|
|
3179
|
+
## YYYY-MM-DD: <generate | refresh>
|
|
3180
|
+
|
|
3181
|
+
- Profile: <audience>/<depth>
|
|
3182
|
+
- source_commit: <short-sha> (was <prev-sha> on refresh)
|
|
3183
|
+
- Coverage: <which sections/packages were written or updated>
|
|
3184
|
+
- Pages: [Overview](./OVERVIEW.md), [Server](./modules/server.md), ...
|
|
3185
|
+
\`\`\`
|
|
3186
|
+
|
|
3187
|
+
---
|
|
3188
|
+
|
|
3189
|
+
## STOP rules / anti-patterns (load-bearing)
|
|
3190
|
+
|
|
3191
|
+
- **Author wiki markdown only through OK \`write\`/\`edit\`** — never native \`Write\`/\`Edit\` (loses attribution, backlinks, live preview). Read source with native tools; write the wiki with OK.
|
|
3192
|
+
- **Summarize existing docs, don't duplicate them** — link to \`README\`/\`ARCHITECTURE.md\`; the wiki adds navigation and synthesis, not a copy.
|
|
3193
|
+
- **Every source reference points at a file you actually read** — no invented paths or symbols.
|
|
3194
|
+
- **Respect the profile** — at \`audience: public\`, never write secrets, internal infra, or ticket/PR numbers; reference code via GitHub URLs (or relative if no remote).
|
|
3195
|
+
- **OVERVIEW is the hub** — every page must be reachable from it. Don't leave orphans (Phase 7 catches them).
|
|
3196
|
+
- **Don't scaffold folders by hand** — the \`codebase-wiki\` pack already created \`wiki/\` with templates; if it's missing, seed first.
|
|
3197
|
+
- **Scale to \`depth\`** — don't write \`guides/\` or per-flow failure modes at \`tour\`; don't fold modules into architecture at \`exhaustive\`.
|
|
3198
|
+
- **Refresh is incremental** — diff \`source_commit..HEAD\` and touch only affected pages; full-regen only on large/structural diffs or when git is unavailable.
|
|
3199
|
+
|
|
3200
|
+
---
|
|
3201
|
+
|
|
3202
|
+
## Exit conditions
|
|
3203
|
+
|
|
3204
|
+
- **Pack not seeded** — \`wiki/\` layout missing → tell the user to run \`ok seed --pack codebase-wiki\`, then re-invoke. Exit.
|
|
3205
|
+
- **Server down** — a \`write\`/\`links\` call reports the server is not running → tell the user to run \`ok start\` and retry. Exit cleanly; re-invoking resumes (already-written pages persist).
|
|
3206
|
+
- **User aborts at a ⛔ gate** → exit cleanly, leaving any already-written pages in place.
|
|
3207
|
+
- **Empty / unreadable repo** (no source detected in Phase 1) → tell the user there's nothing to document yet. Exit.
|
|
3208
|
+
`}const DESCRIPTION$1=["Procedural guides for the three-layer wiki workflow + brownfield onboarding. Returns a numbered plan (instructional text, not data) — you execute it. Dispatches on `kind`:",``,'- `kind: "ingest"` — capture an external source (URL or local file) into the KB as raw, verbatim reference material (no analysis). Requires `source`.','- `kind: "research"` — gather sources and write provisional findings for a question. Requires `topic`.','- `kind: "consolidate"` — fold provisional material into a canonical article. Requires `topic`.','- `kind: "discover"` — extract conventions from an existing repo (folder frontmatter + templates + link graph). No payload.','- `kind: "wiki"` — generate (or refresh) a navigable, diagram-rich, source-grounded wiki of this codebase into the `wiki/` knowledge base (the `codebase-wiki` pack). No payload; tune via natural-language `audience`/`depth` in your request.',``,`**Parameters:**`,"- `kind` — `ingest` | `research` | `consolidate` | `discover` | `wiki`.","- `source` — Required for `ingest`: the URL / file path / identifier to capture.","- `topic` — Required for `research` / `consolidate`: the topic, question, or anchor URL.","- `cwd` (optional) — Project root (see `cwd` description below)."].join(`
|
|
3209
|
+
`);function register$1(e,t){let s=buildWorkflowHandler(`ingest`,t,`source`,buildIngestBody),g=buildWorkflowHandler(`research`,t,`topic`,buildResearchBody),S=buildWorkflowHandler(`consolidate`,t,`topic`,buildConsolidateBody);e.registerTool(`workflow`,{description:DESCRIPTION$1,inputSchema:{kind:_enum([`ingest`,`research`,`consolidate`,`discover`,`wiki`]).describe(`Which workflow guide to return.`),source:string().optional().describe('Required for `kind: "ingest"` — the URL / file / identifier to capture.'),topic:string().optional().describe('Required for `kind: "research"` / `"consolidate"` — the topic / question / anchor URL.'),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},outputSchema:outputSchemaWithText({previewUrl:previewUrlOutputField.describe(`Always null — a workflow guide is prose, not a previewable document.`)})},async e=>{switch(e.kind){case`ingest`:return e.source?s(e):textResult('Error: workflow({ kind: "ingest" }) requires `source` — the URL / file / identifier to capture. e.g. workflow({ kind: "ingest", source: "https://example.com/spec" }).',!0);case`research`:return e.topic?g(e):textResult('Error: workflow({ kind: "research" }) requires `topic` — the question or topic to investigate. e.g. workflow({ kind: "research", topic: "rate-limit strategies" }).',!0);case`consolidate`:return e.topic?S(e):textResult('Error: workflow({ kind: "consolidate" }) requires `topic` — the topic to fold into a canonical article. e.g. workflow({ kind: "consolidate", topic: "rate-limit strategies" }).',!0);case`discover`:{let s=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);return s.ok?textPlusStructured(buildDiscoverBody(s.config.content.dir),{previewUrl:null}):textResult(`Error: ${s.error}`,!0)}case`wiki`:{let s=await resolveProjectConfigContext(t.resolveCwd,t.config,e.cwd);return s.ok?textPlusStructured(buildWikiBody(s.config.content.dir),{previewUrl:null}):textResult(`Error: ${s.error}`,!0)}default:return textResult(`Error: unknown workflow kind.`,!0)}})}const DESCRIPTION=`${["Create or replace one thing. Pass EXACTLY ONE of `document`, `folder`, `template`, or `asset` (or `documents` for a batch of docs).",``,'- `document` — Create or overwrite a doc via the CRDT layer [Requires: Hocuspocus server]. `{ path, content }`, or `{ path, template }` to instantiate from a folder template (mutually exclusive with `content`). Optional `frontmatter` (its own YAML) and `position` (`replace` default for a new doc; required for an existing one) — note supplying `frontmatter` alongside literal `content` forces `position: replace` (the only position that persists a YAML block), overriding an explicit `append`/`prepend`. Example: `{ document: { path: "meetings/standup", content: "# Standup\\n..." } }`.','- `folder` — Create a NEW folder (optionally with its own properties) [Requires: Hocuspocus server]. `{ path, frontmatter? }`. To change an EXISTING folder use `edit`. Example: `{ folder: { path: "ideas" } }`.','- `template` — Create a reusable starting shape for new docs in a folder. `{ path: "<folder>/<name>", content, frontmatter: { title, description?, tags? } }`.','- `asset` — Upload a binary (image/file) via the media route [Requires: Hocuspocus server]. `{ path: "<folder>/<file.ext>", content(base64) | source(local path) }`.',"- `documents` — Batch: `[{ path, content?|template?, frontmatter?, position?, summary? }, ...]` written in order; the response reports each.","- `summary` — Optional one-line user-outcome (≤80 chars) for the timeline, for a single `document`/`folder`/`template`/`asset` write. For a `documents` batch, give each entry its own `summary` instead (a top-level `summary` is ignored on the batch path). Avoid secrets or PII — persisted to git history.",``,"Responses may include `structuredContent.document.warnings` (batch: per-entry under `documents[]`) — advisory entries discriminated by `kind`: `content-divergence` / `disk-edit-reconciled` (write-integrity — re-read the doc) and `mermaid-parse-error` (the write landed but that fence will not render — fix it and re-edit)."].join(`
|
|
2929
3210
|
`)}\n${renderInventoryFooter()}`;function frontmatterIgnoredNote(e,t){return e!==`prepend`&&e!==`append`||!t||stripFrontmatter(t).frontmatter.trim()===``?null:`Note: a \`---\` frontmatter block in this \`${e}\` payload was ignored — frontmatter is written only with \`position: "replace"\`. To change frontmatter, use \`edit({ document: { path, frontmatter } })\` (patch) or \`write({ document: { path, content, position: "replace" } })\` (full rewrite).`}function emptyAppendNoOpNote(e,t){return e!==`prepend`&&e!==`append`||t===void 0||stripFrontmatter(t).body!==``?null:`No content to ${e} — document unchanged. To clear a document, use \`position: "replace"\` with empty \`content\`.`}function docExtensionOnDisk(e,t){for(let s of SUPPORTED_DOC_EXTENSIONS){let g=resolveWithinRoot(e,`${t}${s}`);if(g.ok&&existsSync(g.abs))return s}return null}function requestedDocExtension(e){let t=e.toLowerCase();return t.endsWith(`.mdx`)?`.mdx`:t.endsWith(`.md`)?`.md`:null}function extensionIgnoredNote(e,t,s){return e===null||t===null||e===t?null:`Note: "${s}" already exists as \`${s}${t}\`, so the requested \`${e}\` extension was not applied — the write went to \`${s}${t}\`. Changing a doc's on-disk extension in place isn't available via the MCP today.`}function composeWithFrontmatter(e,t){let{frontmatter:s,body:g}=stripFrontmatter(t),S={};if(s!==``){let e=parseFrontmatterYaml(unwrapFrontmatterFences(s));if(e.map===null)return{ok:!1,error:`EMBEDDED_FRONTMATTER_MALFORMED — \`content\` opens with a \`---\` block whose YAML failed to parse (${e.parseError}), so it can't be merged with the \`frontmatter\` param. Fix the embedded YAML, or supply the frontmatter only via the \`frontmatter\` param (not also inline in \`content\`).`};S=e.map}let w=serializeFrontmatterMap(mergePatch(S,e));return w===``?{ok:!0,markdown:g}:{ok:!0,markdown:withFences(w)+g}}async function writeOneDoc(e,t,s,g,S){let w=normalizeDocName(e.path);if(!w.ok)return{docName:e.path,ok:!1,error:w.error};let E=w.docName,D=S.identityRef?.current;if(e.template===void 0&&e.content===void 0)return{docName:E,ok:!1,error:"either `content` or `template` must be provided — omitting both would write empty content."};if(e.template!==void 0&&e.content!==void 0)return{docName:E,ok:!1,error:"TEMPLATE_AND_CONTENT_BOTH_SET — `template` and `content` are mutually exclusive. Pass one; fill placeholders via subsequent `edit` calls."};let O=e.content??``,k=e.frontmatter!==void 0&&Object.keys(e.frontmatter).length>0,j=docExtensionOnDisk(s,E),F=j!==null,L=e.extension??requestedDocExtension(e.path),B;if(e.position!==void 0)B=e.position;else if(F)return{docName:E,ok:!1,error:`"${E}" already exists — pass \`position\` (\`append\` | \`prepend\` | \`replace\`), or use \`edit\` for a targeted change.`};else B=`replace`;if(e.template!==void 0){let s=parentFolderOf(E),g=resolveTemplatesAvailable(t,s,{depth:1}),S=g.find(t=>t.name===e.template);if(!S)return{docName:E,ok:!1,error:`template "${e.template}" not found for folder "${s||`.`}". Available: ${g.length===0?`(none)`:g.map(e=>`${e.name} [${e.scope}]`).join(`, `)}. Templates are resolved by walk-up; check the parent folder's exec listing to see the menu.`};let w;try{w=readFileSync(resolve(t,S.path),`utf-8`)}catch(e){return{docName:E,ok:!1,error:`failed to read template at ${S.path}: ${e.message}`}}O=applySubstitution(instantiateDoc(w),{date:todayIsoUtc(),user:D?.displayName??``}),B=`replace`}else if(k){let t=composeWithFrontmatter(e.frontmatter,O);if(!t.ok)return{docName:E,ok:!1,error:t.error};O=t.markdown,B=`replace`}if(!F&&normalizeBridge(O)===``)return{docName:E,ok:!1,error:`"${E}" does not exist and the content is empty — provide non-empty content to create the document.`};let H=await httpPost(g,`/api/agent-write-md`,{docName:E,markdown:O,position:B,...L!==null&&!F?{extension:L}:{},...e.summary===void 0?{}:{summary:e.summary},...agentIdentityFields(D)});if(!H.ok){let e=typeof H.detail==`string`&&H.detail.length>0?H.detail:``;return{docName:E,ok:!1,error:e?`${String(H.error)} (${e})`:String(H.error)}}if(e.template!==void 0&&k){let t=await httpPost(g,`/api/frontmatter-patch`,{docName:E,patch:e.frontmatter,...agentIdentityFields(D)});if(!t.ok)return{docName:E,ok:!1,error:`document created from template but frontmatter failed: ${String(t.error)}`}}let q=extensionIgnoredNote(L,j,E);return{docName:E,ok:!0,position:B,...e.template===void 0?{}:{fromTemplate:e.template},...q?{extensionNote:q}:{},raw:H}}async function handleFolder(e,t,s,g){if(!s)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let S=g.identityRef?.current,w=await httpPost(s,`/api/create-folder`,{path:e.path,...t===void 0?{}:{summary:t},...agentIdentityFields(S)});if(!w.ok){let e=typeof w.detail==`string`&&w.detail.length>0?w.detail:``;return textResult(e?`Error: ${w.error} (${e})`:`Error: ${w.error}`,!0)}let E=[`Created folder ${e.path}.`];if(e.frontmatter!==void 0&&Object.keys(e.frontmatter).length>0){let g=await httpPut(s,`/api/folder-config`,{path:e.path,frontmatter:e.frontmatter,...t===void 0?{}:{summary:t},...agentIdentityFields(S)});if(!g.ok)return textPlusStructured(`Created folder ${e.path}, but writing its properties failed: ${g.error}. Use edit({ folder: { path: "${e.path}", frontmatter } }) to retry the properties.`,{folder:{ok:!0,path:e.path,frontmatterError:String(g.error)}});E.push(`Set folder properties (${e.path}/.ok/frontmatter.yml).`)}return textPlusStructured(E.join(`
|
|
2930
3211
|
`),{folder:{ok:!0,path:e.path}})}async function handleTemplate(e,t,s,g){let S=resolveTemplatePath(e.path);if(!S.ok)return textResult(`Error: ${S.error}`,!0);let{folder:w,name:E}=S;if(!s)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let D=await httpPut(s,`/api/template`,{folder:w,name:E,body:e.content,frontmatter:{title:e.frontmatter.title,...typeof e.frontmatter.description==`string`?{description:e.frontmatter.description}:{},...Array.isArray(e.frontmatter.tags)?{tags:e.frontmatter.tags}:{}},...t===void 0?{}:{summary:t},...agentIdentityFields(g.identityRef?.current)});if(!D.ok)return textResult(`Error: ${D.error}`,!0);let O=D.created===!0,k=typeof D.path==`string`?D.path:void 0;return textPlusStructured(`${O?`Created`:`Updated`} template "${E}" in ${w||`(root)`}${k?` (${k})`:``}.`,{template:{ok:!0,path:k,created:O}})}async function handleAsset(e,t,s,g){if(!s)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);if(e.content===void 0==(e.source===void 0))return textResult("Error: provide exactly one of `content` (base64) or `source` (local file path) for an asset.",!0);let S;try{S=e.content===void 0?readFileSync(resolve(t,e.source)):Buffer.from(e.content,`base64`)}catch(e){return textResult(`Error: could not read asset bytes: ${e.message}`,!0)}if(S.byteLength===0)return textResult(`Error: asset is empty (0 bytes).`,!0);let{folder:w,name:E}=splitTargetPath(e.path),D=w?`${w}/${E}`:E,O=g.identityRef?.current,k=new URLSearchParams;O?.connectionId&&k.set(`agentId`,O.connectionId),O?.displayName&&k.set(`agentName`,O.displayName);let j=k.toString(),F=new FormData;F.append(`parentDocName`,D),F.append(`file`,new Blob([new Uint8Array(S)]),E);let L;try{let e=await fetch(`${s}/api/upload${j?`?${j}`:``}`,{method:`POST`,body:F}),t=await e.json().catch(()=>null);L=e.ok?{ok:!0,status:e.status,data:t??{}}:{ok:!1,status:e.status,error:t&&(typeof t.title==`string`?t.title:t.error)||`Upload failed (HTTP ${e.status}).`}}catch(e){return textResult(`Error: upload request failed: ${e.message}`,!0)}if(!L.ok)return textResult(`Error: ${L.error}`,!0);let B=typeof L.data?.src==`string`?L.data.src:void 0,H=typeof L.data?.path==`string`?L.data.path:void 0,q=L.data?.deduped===!0,ee=B??H??E;return textPlusStructured([`Uploaded asset to ${D}${q?` (deduplicated — identical bytes already present)`:``}.`,`Reference it in a doc with: `].join(`
|
|
2931
3212
|
`),{asset:{ok:!0,...B?{src:B}:{},...H?{path:H}:{},...q?{deduped:q}:{}}})}async function handleBatch(e,t,s,g,S,w,E){let D=[];for(let w of e)D.push(await writeOneDoc(w,t,s,g,S));let O=D.map(e=>{if(!e.ok)return{docName:e.docName,ok:!1,error:e.error};let t=resolvePreviewUrl(e.docName,{lockDir:w}),s=parseAdvisoryWarnings(e.raw.warnings);return{docName:e.docName,ok:!0,position:e.position,...t?{previewUrl:t.url}:{},...s?{warnings:s}:{}}}),k=O.filter(e=>e.ok).length,j=k===O.length,F=e.map((e,t)=>{let s=D[t];if(!s?.ok)return`Failed ${e.path}: ${s?.error??`unknown error`}`;if(emptyAppendNoOpNote(s.position,e.content))return`No change to ${e.path} — empty ${s.position}, document unchanged.`;let g=O[t],S=[`Wrote ${e.path} (${s.position}).`];return g?.ok&&g.warnings&&S.push(...formatAdvisoryBriefs(g.warnings)),S.join(` `)}),L=e.flatMap((e,t)=>{let s=D[t];if(!s?.ok)return[];let g=frontmatterIgnoredNote(s.position,e.content);return[...g?[g]:[],...s.extensionNote?[s.extensionNote]:[]].map(t=>`${e.path} — ${t}`)}),B=[`${k}/${O.length} written.`,...F,...L].join(`
|
|
@@ -2952,4 +3233,4 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
2952
3233
|
`))e&&await t.raw(`update-ref`,`-d`,e);Y.info({context:e.oldBranch},`[branch-switch] cleaned up detached context ${e.oldBranch}`)}}catch(e){Y.error({err:e},`[branch-switch] detached cleanup failed`)}setBatchInProgress(!1),await ye.flushDeferredStores(`discard-stale`),Te?.emitBranchSwitched(g)}if(e.headMoved&&e.newHead&&_e.current&&s>0){let t=L??`.`;try{let s=await commitUpstreamImport(_e.current,t,e.oldHead,e.newHead,g);incrementUpstreamImport(),Y.info({oldHead:e.oldHead?.slice(0,8)??`null`,newHead:e.newHead.slice(0,8),sha:s.slice(0,8)},`[history] upstream-import from ${e.oldHead?.slice(0,8)??`null`}..${e.newHead.slice(0,8)} → ${s.slice(0,8)}`)}catch(e){Y.error({err:e},`[shadow] upstream-import failed`)}}})}catch(e){Y.error({err:e},`[server] HEAD watcher failed to start`),Fr.push(`head-watcher`)}function D(e){for(let g of e)try{let e=toPosix(relative(t,join(s,g)));if(e.startsWith(`..`))continue;let S=stripDocExtension(e),w=Ce.documents.get(S);if(!w)continue;let E=jt(S);E===null?Y.warn({docName:S,file:g},`[sync] content conflict: serializeDoc returned null; reconciledBase snapshot skipped`):setReconciledBase(S,E);let D=w.getMap(`lifecycle`);D.set(`status`,`conflict`),D.set(`reason`,`sync-merge-conflict`),Y.info({docName:S,file:g},`[sync] marked loaded content conflict`)}catch(e){Y.warn({err:e,file:g},`[sync] failed to mark loaded content conflict`)}}let O=buildSyncCredentialArgs(H);try{$t=new SyncEngine({projectDir:s,contentDir:t,contentFilter:fe,contentRoot:L,syncEnabled:te(),credentialArgs:O,cc1Broadcaster:Te,detectGh:e.detectGh,tokenStore:e.tokenStore,checkPushPermissionFn:e.checkPushPermissionFn,setBatchInProgress:e=>{setBatchInProgress(e),e||ye.flushDeferredStores(`within-branch`).catch(e=>{Y.error({err:e},`[persistence] deferred store drain failed after sync batch`)})},onStateChange:e=>{Y.info({state:e},`[sync] state → ${e}`)},onContentConflictsDetected:D,onAutoDisable:async e=>{Y.warn({reason:e},`[sync] auto-disabled — persisting to project-local config`);let t=await writeConfigPatch({cwd:s,scope:`project-local`,patch:{autoSync:{enabled:!1}}});t.ok||Y.error({result:t,reason:e,humanError:humanFormat(t.error),configPath:resolveConfigPath(`project-local`,s)},`[sync] failed to persist auto-disable — next restart WILL re-enable sync and re-trigger the same failure. Check permissions on the config path.`)}}),await $t.start()}catch(e){Y.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),$t=null}Ke(`files`),Ke(`backlinks`),Ke(`graph`),Ke(`tags`)}return Ir().then(Ue,We),{hocuspocus:Ce,sessionManager:we,cc1Broadcaster:Te,agentFocusBroadcaster:De,agentPresenceBroadcaster:je,maintenanceCoordinator:ve,contentFilter:fe,basenameIndex:ce,serverInstanceId:oe,destroy:Mr,ready:Ge,degraded:Fr,lockDir:se,get syncEngine(){return $t}}}const SERVER_MEMORY_SCHEMA_VERSION=1,BYTES_PER_MB=1024*1024;function toMb(e){return e/BYTES_PER_MB}function captureServerMemorySnapshot(){let e=process.memoryUsage();return{schemaVersion:SERVER_MEMORY_SCHEMA_VERSION,capturedAt:new Date().toISOString(),snapshot:{rssMb:toMb(e.rss),heapTotalMb:toMb(e.heapTotal),heapUsedMb:toMb(e.heapUsed),externalMb:toMb(e.external),arrayBuffersMb:toMb(e.arrayBuffers)}}}let cachedGauge=null;onTelemetryShutdown(()=>{cachedGauge=null});function installServerMemoryGauge(){if(cachedGauge)return;let e=getMeter().createObservableGauge(`ok.server.memory.usage_megabytes`,{description:`Server process memory by section. Bounded labels: section ∈ {heap_used, heap_total, rss}.`,unit:`MB`});e.addCallback(e=>{let{snapshot:t}=captureServerMemorySnapshot();e.observe(t.heapUsedMb,{section:`heap_used`}),e.observe(t.heapTotalMb,{section:`heap_total`}),e.observe(t.rssMb,{section:`rss`})}),cachedGauge=e}const TELEMETRY_FILENAME=`tolerance-telemetry.jsonl`,TELEMETRY_PREV_FILENAME=`tolerance-telemetry.prev.jsonl`,TELEMETRY_MAX_BYTES=8*1024*1024;let appender=null,appendFailureWarned=!1;function isToleranceTelemetryEnabled(e=process.env){return e.OK_BRIDGE_TOLERANCE_TELEMETRY===`1`}function initToleranceTelemetryWriter(e){if(!isToleranceTelemetryEnabled())return;let t=getLocalDir(e);appender=new RotatingAppender({currentPath:resolve(t,TELEMETRY_FILENAME),previousPath:resolve(t,TELEMETRY_PREV_FILENAME),maxBytes:TELEMETRY_MAX_BYTES}),setToleranceTelemetryHook(e=>{let t={event:`bridge-tolerance-fire`,timestamp:e.timestamp,class:e.className,document:e.documentName??null,codeUnitPosition:e.codeUnitPosition,severity:e.severity};appender?.append(`${JSON.stringify(t)}\n`).catch(e=>{appendFailureWarned||(appendFailureWarned=!0,console.warn(`[tolerance-telemetry] append failed; further failures are silent:`,e instanceof Error?e.message:String(e)))})})}async function teardownToleranceTelemetryWriter(){setToleranceTelemetryHook(null),await appender?.drain(),appender=null,appendFailureWarned=!1}const LEGACY_RUNTIME_FILENAMES=[`server.lock`,`ui.lock`,`state.json`,`principal.json`,`sync-state.json`,`conflicts.json`,`last-spawn-error.log`],LEGACY_RUNTIME_DIRNAMES=[`cache`,`tmp`];function findLegacyRuntimeFiles(e){let t=resolve(e,LOCAL_DIR);if(!(()=>{if(!existsSync(t))return!0;try{return readdirSync(t).length===0}catch{return!0}})())return[];let s=[];for(let t of LEGACY_RUNTIME_FILENAMES)existsSync(resolve(e,t))&&s.push(t);for(let t of LEGACY_RUNTIME_DIRNAMES){let g=resolve(e,t);try{existsSync(g)&&statSync(g).isDirectory()&&s.push(`${t}/`)}catch{}}return s}function computeWorktreeAttributes(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return{kind:`main`,gitdir:t.path};case`linked`:return{kind:`linked`,gitdir:t.path};case`malformed-pointer`:return{kind:`linked`,gitdir:null};case`inaccessible`:case`absent`:return{kind:`main`,gitdir:null}}}const DEFAULT_IDLE_THRESHOLD_MS=1800*1e3,DESTROY_STEP_TIMEOUT_MS=5e3,PINO_REDACT_MAX_DEPTH=5;async function bootServer(e){let t=e.projectDir??e.contentDir,s=resolveLocalSinkConfig({projectDir:t});if(s){let e=s.telemetry.attributeDenylist,t=[];for(let s of e){t.push(s);for(let e=1;e<=PINO_REDACT_MAX_DEPTH;e++)t.push(`${`*.`.repeat(e)}${s}`)}loggerFactory.configure({pinoConfig:{fileSink:s.logs,redactPaths:t}})}initTelemetry({localSink:s?.telemetry}),initToleranceTelemetryWriter(t),installServerMemoryGauge();let{kind:g,gitdir:S}=computeWorktreeAttributes(e.projectDir??e.contentDir),w={"ok.worktree.kind":g};return S!==null&&(w[`ok.worktree.gitdir`]=normalizeFsPath(S)),withSpan(`ok.boot`,{attributes:w},async()=>bootServerInner(e))}async function bootServerInner(e){let t=e.skipAutoInit??!1,s=e.attachUiSibling??!0,g=e.idleShutdownMs,S=e.log??getLogger(`boot`),w=process.env.OK_LOCK_KIND===`mcp-spawned`||process.env.OK_LOCK_KIND===`interactive`?process.env.OK_LOCK_KIND:void 0,E=e.lockKind??w??`interactive`,{createServer:D}=await import(`node:http`),{updateServerLockPort:O}=await import(`./server-lock-CyhBidkz-D48N1gMX.mjs`),k=!1;if(!t&&e.autoInitFn)try{k=!!await e.autoInitFn()}catch(e){S.warn({err:e},`autoInitFn failed`)}let j=e.projectDir??e.contentDir,F=resolve(j,`.ok`);if(!existsSync(resolve(F,`config.yml`)))throw new MissingOkConfigError(existsSync(F)?`config`:`okdir`,j);existsSync(resolve(F,`.gitignore`))||console.warn("[boot] Note: .ok/.gitignore is missing — per-machine state files in .ok/ may show up as untracked changes. Run `ok init` to add the recommended ignore entries.");let L=e.gitPreflight??assertGitAvailable;try{e.gitEnabled!==!1&&L()}catch(e){if(e instanceof GitNotAvailableError||e instanceof GitTooOldError){let t=e instanceof GitTooOldError?e.detected:``,s=e instanceof GitTooOldError?`too_old`:`not_available`;emitPreflightFailureSpan(e),S.warn({event:`git_preflight_fail`,platform:e.platform,reason:s,detectedVersion:t},s===`not_available`?`git binary not found`:`git binary too old`),process.stderr.write(`${e.message}\n`)}throw await shutdownTelemetry(),await Promise.race([teardownToleranceTelemetryWriter(),new Promise(e=>setTimeout(e,DESTROY_STEP_TIMEOUT_MS))]),e}let B=findLegacyRuntimeFiles(F);B.length>0&&console.warn(`[boot] Found legacy runtime files at .ok/${B.join(`, `)}. Delete .ok/ and re-init — these files moved to .ok/${LOCAL_DIR}/.`);let H=createServer$1({contentDir:e.contentDir,projectDir:e.projectDir,contentRoot:e.contentRoot,port:e.port,host:e.host,quiet:e.quiet??!1,debounce:e.debounce,maxDebounce:e.maxDebounce,gitEnabled:e.gitEnabled,commitDebounceMs:e.commitDebounceMs,wipRef:e.wipRef,enableTestRoutes:e.enableTestRoutes,shadowRepo:e.shadowRepo,destroyTimeoutMs:e.destroyTimeoutMs,localOpCliArgs:e.localOpCliArgs,onAgentWrite:e.onAgentWrite,lockKind:E,skipStateManifestCheck:e.skipStateManifestCheck,detectGh:e.detectGh,tokenStore:e.tokenStore,embeddingsKeyStore:e.embeddingsKeyStore,singleDocRelPath:e.singleDocRelPath,ephemeral:e.ephemeral}),{hocuspocus:q,destroy:ee,ready:J,degraded:Y,lockDir:te,sessionManager:ne,agentFocusBroadcaster:ae,agentPresenceBroadcaster:oe,maintenanceCoordinator:se}=H,ce=(()=>{let t=e.host??`localhost`;return t===`0.0.0.0`||t===`::`?`localhost`:t.includes(`:`)&&!t.startsWith(`[`)?`[${t}]`:t})(),ue=e.port??0,de=e.ephemeral?void 0:createMcpHttpHandler({contentDir:e.contentDir,projectDir:e.projectDir??e.contentDir,config:e.config,getServerUrl:()=>`http://${ce}:${ue}`,log:S}),fe=D();fe.headersTimeout=3e4,fe.requestTimeout=6e4;let me=e.serveContentAssets?createAssetServeMiddleware({contentFilter:H.contentFilter,contentSirv:build_default(e.contentDir,{dev:!0,dotfiles:!1}),inlineExtensions:INLINE_RENDERABLE_EXTENSIONS,assetExtensions:ASSET_EXTENSIONS,blocklistExtensions:EXECUTABLE_BLOCKLIST_EXTENSIONS}):void 0,ge=!1;if(e.reactShellDistDir)try{acquireUiLock(te,{port:0,worktreeRoot:e.projectDir??e.contentDir}),ge=!0}catch(e){if(e instanceof UiLockCollisionError)S.info({event:`ui-lock-yielded-to-live-holder`,pid:process.pid,existingPid:e.existing.pid,existingPort:e.existing.port,lockDir:te},`ui.lock already held by a live process — yielding (advertisement is fulfilled)`);else throw await ee().catch(()=>{}),e}let _e=e.reactShellDistDir?build_default(e.reactShellDistDir,{single:!0,gzip:!0,immutable:!0}):void 0,ve=mountMcpAndApi({httpServer:fe,hocuspocus:q,mcpHttpHandler:de,log:S,sessionManager:ne,agentFocusBroadcaster:ae,agentPresenceBroadcaster:oe,maintenanceCoordinator:se,keepaliveGraceMs:e.keepaliveGraceMs,contentAssetMiddleware:me,reactShellMiddleware:_e,ephemeral:e.ephemeral}),ye=async()=>{throw Error(`bootServer: destroy() invoked before initialization — boot did not complete`)},Ce=null;g!==null&&(Ce=attachIdleShutdown({httpServer:fe,thresholdMs:g??DEFAULT_IDLE_THRESHOLD_MS,log:S,onShutdown:(e.idleShutdownHandler??(e=>async()=>{await e()}))(async()=>{await ye()})})),await restoreLifecycleFromConflictsJson({hocuspocus:q,projectDir:e.projectDir??e.contentDir,log:S});try{await new Promise((t,s)=>{let g=e=>s(e);fe.once(`error`,g),fe.listen(e.port,e.host,()=>{fe.removeListener(`error`,g),t()})})}catch(e){if(ge)try{releaseUiLock(te)}catch(e){S.warn({err:e},`releaseUiLock failed during listen-error cleanup`)}throw await ee().catch(()=>{}),e}let we=fe.address(),Te=typeof we==`object`&&we?we.port:e.port??0;if(ue=Te,O(te,Te),ge&&updateUiLockPort(te,Te),s&&e.spawnUiSiblingFn)try{await e.spawnUiSiblingFn({lockDir:te,log:S})}catch(e){S.warn({err:e},`spawnUiSiblingFn failed`)}let De=!1,je=async(e,t)=>{let s;try{await Promise.race([t(),new Promise((t,g)=>{s=setTimeout(()=>{g(Error(`${e} timed out after ${DESTROY_STEP_TIMEOUT_MS}ms`))},DESTROY_STEP_TIMEOUT_MS),s.unref?.()})])}finally{s!==void 0&&clearTimeout(s)}};return ye=async()=>{if(De)return;De=!0;let e=[],t=async(t,s)=>{try{await je(t,s)}catch(s){e.push(s),S.warn({err:s,step:t},`bootServer destroy step failed`)}};try{Ce?.detach()}catch(t){e.push(t),S.warn({err:t,step:`idleHandle.detach`},`bootServer destroy step failed`)}if(await t(`mount.shutdown`,()=>ve.shutdown()),de!==void 0&&await t(`mcpHttpHandler.close`,()=>de.close()),await t(`mount.wss.close`,()=>new Promise((e,t)=>{ve.wss.close(s=>s?t(s):e())})),await t(`httpServer.closeAllConnections`,async()=>{fe.closeAllConnections?.()}),await t(`httpServer.close`,()=>new Promise((e,t)=>{fe.close(s=>s&&s.code!==`ERR_SERVER_NOT_RUNNING`?t(s):e())})),await t(`destroyHocuspocus`,()=>ee()),ge&&await t(`releaseUiLock`,async()=>releaseUiLock(te)),await t(`shutdownTelemetry`,()=>shutdownTelemetry()),await t(`teardownToleranceTelemetry`,()=>teardownToleranceTelemetryWriter()),await t(`flushLogFileSinks`,()=>loggerFactory.flushAllFileSinks()),e.length>0)throw AggregateError(e,`bootServer destroy completed with errors`)},{httpServer:fe,destroy:ye,lockDir:te,contentDir:e.contentDir,port:Te,ready:J,degraded:Y,didAutoInit:k,serverInstance:H}}async function restoreLifecycleFromConflictsJson(e){let{hocuspocus:t,projectDir:s,log:g}=e,S,w;try{S=new ConflictStore(s),w=S.list()}catch(e){g.warn({err:e,projectDir:s},`[boot] lifecycle restore: failed to read conflicts.json — skipping`);return}if(w.length===0)return;let E=null;try{let e=resolveGitDir(s),t=e?join(e,`MERGE_HEAD`):null;if(!t||!existsSync(t)){S.clear(),console.warn(JSON.stringify({event:`lifecycle-restore-cleared-stale-conflicts`,reason:`no-merge-head`,count:w.length}));return}let g=(await simpleGit({baseDir:s,timeout:{block:5e3}}).raw([`diff`,`--name-only`,`--diff-filter=U`])).trim();E=new Set(g?g.split(`
|
|
2953
3234
|
`).map(e=>e.trim()).filter(Boolean):[])}catch(e){g.warn({err:e,projectDir:s},`[boot] lifecycle restore: git unmerged probe failed — restoring all entries`)}if(E!==null){let e=0;for(let t of w)E.has(t.file)||(S.removeConflict(t.file),e++);if(e>0&&console.warn(JSON.stringify({event:`lifecycle-restore-pruned-resolved-entries`,pruned:e,remaining:w.length-e})),w=w.filter(e=>E?.has(e.file)),w.length===0)return}for(let e of w){let s=stripDocExtension(e.file),S=null,w=!1;try{S=await t.openDirectConnection(s);let e=S.document;if(!e)continue;let g=e.getMap(`lifecycle`);g.set(`status`,`conflict`),g.set(`reason`,`conflict-markers`),w=!0,console.warn(JSON.stringify({event:`lifecycle-restored-from-conflicts-json`,"doc.name":s}))}catch(e){g.warn({err:e,docName:s},`[boot] lifecycle restore: failed to set lifecycle for doc — skipping`)}finally{if(S)try{await S.disconnect()}catch(e){g.warn({err:e,docName:s,restored:w},`[boot] lifecycle restore: disconnect failed after lifecycle write`)}}}}const ConfigSchema=ConfigSchema$1;function detectClaudeDesktopPresence(e={}){let t=e.home??homedir(),s=e.platformName??process.platform,g=e.env??process.env;return s===`darwin`?existsSync(join(t,`Library`,`Application Support`,`Claude`)):s===`win32`?existsSync(join(g.APPDATA??join(t,`AppData`,`Roaming`),`Claude`)):!1}const OK_LOGS_DIR=join(homedir(),`.ok`,`logs`),MAX_ROTATED_FILES=2,MAX_AGE_DAYS=7,MAX_DIR_SIZE_BYTES=45*1024*1024,REDACT_PATHS=[`authorization`,`password`,`token`,`apiKey`,`secret`,`*.authorization`,`*.password`,`*.token`,`*.apiKey`,`*.secret`];function resolveLogLevel(){let e=process.env.OK_LOG_LEVEL??process.env.LOG_LEVEL;if(e){let t=[`fatal`,`error`,`warn`,`info`,`debug`],s=e.toLowerCase();if(t.includes(s))return s}return process.env.NODE_ENV===`test`?`silent`:`info`}function ensureDir(e){mkdirSync(e,{recursive:!0})}function todayDateString(){return new Date().toISOString().slice(0,10)}function rotateIfNeeded(e){try{if(statSync(e).size<5242880)return}catch{return}for(let t=MAX_ROTATED_FILES;t>=1;t--){let s=t===1?e:`${e}.${t-1}`,g=`${e}.${t}`;try{renameSync(s,g)}catch{}}try{unlinkSync(`${e}.${MAX_ROTATED_FILES+1}`)}catch{}}function pruneLogsDir(e){try{let t=Date.now(),s=MAX_AGE_DAYS*24*60*60*1e3,g=readdirSync(e).filter(e=>e.endsWith(`.log`)||/\.log\.\d+$/.test(e)).map(t=>{try{let s=statSync(join(e,t));return{name:t,mtime:s.mtimeMs,size:s.size}}catch{return null}}).filter(Boolean);for(let S of g)if(t-S.mtime>s)try{unlinkSync(join(e,S.name))}catch{}let S=g.filter(e=>t-e.mtime<=s).sort((e,t)=>e.mtime-t.mtime),w=S.reduce((e,t)=>e+t.size,0);for(let t of S){if(w<=MAX_DIR_SIZE_BYTES)break;try{unlinkSync(join(e,t.name)),w-=t.size}catch{}}}catch{}}function createFileLogger(e){ensureDir(OK_LOGS_DIR);let t=todayDateString(),s=e.filePath??join(OK_LOGS_DIR,`${e.name}.${t}.log`);rotateIfNeeded(s),(e._setTimeout??setTimeout)(()=>pruneLogsDir(OK_LOGS_DIR),5e3).unref();let g=import_pino.default.destination({dest:s,append:!0,sync:!0});return(0,import_pino.default)({level:resolveLogLevel(),name:e.name,redact:{paths:REDACT_PATHS,censor:`[REDACTED]`},base:{pid:process.pid,hostname:void 0,runtime:`cli`,project:e.project??`<no-project>`},timestamp:import_pino.default.stdTimeFunctions.isoTime,...e.additionalOptions},g)}function flushFileLogger(e,t=250){return new Promise(s=>{if(!e){s();return}let g=e[import_pino.default.symbols.streamSym],S=!1,w=()=>{S||(S=!0,s())};if(!g||typeof g.flushSync!=`function`){w();return}let E=()=>{try{g.flushSync?.()}catch{}w()},D=setTimeout(w,t);typeof D.unref==`function`&&D.unref(),typeof g.fd==`number`&&g.fd>=0?(clearTimeout(D),E()):typeof g.once==`function`?g.once(`ready`,()=>{clearTimeout(D),E()}):(clearTimeout(D),E())})}function getLogFilePath(e){return join(OK_LOGS_DIR,`${e}.${todayDateString()}.log`)}function getLogsDir(){return OK_LOGS_DIR}const ANCESTOR_WALK_DEPTH_LIMIT=30,GIT_MARKER=`.git`;function findEnclosingGitRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT;){let e=!1;try{e=existsSync(resolve(t,GIT_MARKER))}catch{e=!1}if(e)return{gitRoot:t,distance:s};let g=dirname(t);if(g===t)return null;t=g,s+=1}return null}const execFileAsync=promisify(execFile),log=getLogger(`project-git`);var ProjectGitInitError=class extends Error{stderr;constructor(e,t=``,s){super(e,s),this.name=`ProjectGitInitError`,this.stderr=t}};async function isInsideExistingWorkTree(e){try{let{stdout:t}=await execFileAsync(`git`,[`rev-parse`,`--is-inside-work-tree`],{cwd:e});return t.trim()===`true`}catch{return!1}}async function ensureProjectGit(e){let t=resolve(e),s=resolve(t,`.git`),g=resolve(s,`HEAD`),S=!1;if(existsSync(s)){if(!statSync(s).isDirectory()||existsSync(g))return{didInit:!1};log.info({},`detected partial .git/ — running git init to repair`),S=!0}else if(await isInsideExistingWorkTree(t))return{didInit:!1};let w=``;try{w=(await execFileAsync(`git`,[`init`,`--initial-branch=main`,t])).stderr??``}catch(e){let s=typeof e==`object`&&e&&`stderr`in e?String(e.stderr??``):``;throw new ProjectGitInitError(`git init failed at ${t}: ${e instanceof Error?e.message:String(e)}`,s,{cause:e})}if(!existsSync(g))throw new ProjectGitInitError(`git init reported success but ${s}/HEAD is missing (partial init detected)`,w);return S?(log.info({path:t},`backfilled missing .git/HEAD`),{didInit:!0,repaired:!0}):(log.info({path:t,branch:`main`},`initialized .git/`),{didInit:!0})}async function resolvePackageVersion(e,t){let s;try{s=createRequire(t).resolve(e)}catch(e){if(e?.code===`MODULE_NOT_FOUND`)return;throw e}for(let t=dirname(s),g=0;g<32;g+=1){let s=join(t,`package.json`);if(existsSync(s))try{let t=JSON.parse(await readFile$1(s,`utf-8`));if(t.name===e&&typeof t.version==`string`)return t.version}catch{}let g=dirname(t);if(g===t)return;t=g}}const MAX_CAUSE_DEPTH=5,HOME_PATH_PATTERNS=[{regex:/\/Users\/[^/]+\//g,replacement:`~/`},{regex:/\/home\/[^/]+\//g,replacement:`~/`},{regex:/C:\\\\Users\\\\[^\\\\]+\\\\/g,replacement:`~\\`},{regex:/C:\\Users\\[^\\]+\\/g,replacement:`~\\`}];function scrubPaths(e){if(e===void 0)return;let t=e;for(let{regex:e,replacement:s}of HOME_PATH_PATTERNS)t=t.replace(e,s);return t}function serializeError(e,t=0,s=new WeakSet){if(t>=MAX_CAUSE_DEPTH)return{name:`SerializedError.CauseDepthExceeded`,message:`cause chain depth > ${MAX_CAUSE_DEPTH}; truncated`};if(typeof e==`object`&&e){if(s.has(e))return{name:`SerializedError.CauseCycle`,message:`cyclic cause; truncated`};s.add(e)}if(e instanceof Error)return{name:e.name,message:scrubPaths(e.message)??``,stack:scrubPaths(e.stack),code:e.code,cause:e.cause===void 0?void 0:serializeError(e.cause,t+1,s)};if(e==null)return{name:`UnknownError`,message:String(e)};if(typeof e==`string`)return{name:`StringError`,message:scrubPaths(e)??e};if(typeof e==`object`){let g=e;return{name:String(g.name??`ObjectError`),message:scrubPaths(String(g.message??``))??``,stack:scrubPaths(g.stack),code:g.code,cause:g.cause===void 0?void 0:serializeError(g.cause,t+1,s)}}return{name:`UnknownError`,message:String(e)}}var SingleFileNotFoundError=class extends Error{constructor(e){super(`File not found: ${e}`),this.filePath=e,this.name=`SingleFileNotFoundError`}},SingleFileNotAFileError=class extends Error{constructor(e){super(`Not a file: ${e}. \`ok <file>\` opens a single markdown file.`),this.filePath=e,this.name=`SingleFileNotAFileError`}},SingleFileNotMarkdownError=class extends Error{constructor(e){super(`Open Knowledge edits markdown files (.md / .mdx): ${e}`),this.filePath=e,this.name=`SingleFileNotMarkdownError`}};function prepareSingleFileOpen(e){if(!isSupportedDocFile(e))throw new SingleFileNotMarkdownError(e);let t;try{t=realpathSync(resolve(e))}catch(t){throw t.code===`ENOENT`?new SingleFileNotFoundError(e):t}if(!statSync(t).isFile())throw new SingleFileNotAFileError(e);let s=dirname(t),g=findEnclosingProjectRoot(s);if(g){let e=g.rootPath;return{mode:`project`,projectRoot:e,docName:stripDocExtension(relative(resolveProjectContentDir(e),t).split(sep).join(`/`)),canonicalFilePath:t}}let S=basename(t);return{mode:`ephemeral`,canonicalFilePath:t,contentDir:s,singleDocRelPath:S,docName:stripDocExtension(S)}}function resolveProjectContentDir(e){return resolve(e,readConfigSafely({absPath:resolveConfigPath(`project`,e),sideline:!1,warn:()=>{}}).value.content?.dir??`.`)}function createEphemeralProjectDir(e){let t=mkdtempSync(resolve(tmpdir(),`ok-ephemeral-`)),s=resolve(t,`.ok`);return mkdirSync(s,{recursive:!0}),writeFileSync(resolve(s,`config.yml`),`# Ephemeral single-file session (\`ok <file>\`). Throwaway — safe to delete.\ncontent:\n dir: ${JSON.stringify(e)}\n`,`utf-8`),writeFileSync(resolve(s,`.gitignore`),`local/
|
|
2954
3235
|
`,`utf-8`),t}export{STARTER_TEMPLATES as $,withFileLockSync as $i,isProjectRoot as $n,runCloneSubprocess as $r,createOsProbe as $t,LIVE_DERIVED_INDEX_DEBOUNCE_MS as A,tracedUnlinkSync as Ai,getMeter as An,readUiLock as Ar,clearContributors as At,OBSERVER_SYNC_ORIGIN as B,writeRootGitignoreForNewRepo as Bi,initTelemetry as Bn,resolveContentDir as Br,countShadowObjects as Bt,GIT_UPSTREAM_WRITER as C,tracedLinkSync as Ci,formatPackRationale as Cn,readBranchFromHead as Cr,buildExecResult as Ct,HocuspocusAuthRejection as D,tracedRenameSync as Di,getLogFilePath as Dn,readStateManifest as Dr,classifyEvents as Dt,HOCUSPOCUS_AUTH_REJECTION_REASONS as E,tracedRename as Ei,getLocalDir as En,readSkillInstallStateSnapshot as Er,buildWipTree as Et,MCP_SERVER_NAME as F,validateAgentId as Fi,hasGcLogLatch as Fn,registerWrite as Fr,commitWipFromTree as Ft,ROLLBACK_ORIGIN as G,JSONRPCMessageSchema as Gi,isAllowedApiOrigin as Gn,resolvePackageVersion as Gr,createContentFilter as Gt,PANE_TARGET_TTL_MS as H,writeTargetVersion as Hi,installPrettyZodErrors as Hn,resolveCursorSpawnInvocation as Hr,countWipRefs as Ht,MIN_GIT_VERSION as I,validateCloneInputs as Ii,incrementCollabSocketFilteredError as In,releaseUiLock as Ir,compareSemver as It,SKILL_INSTALL_EVENTS_FILE_REL as J,isJSONRPCRequest as Ji,isHocuspocusAuthRejectionReason as Jn,restoreLifecycleFromConflictsJson as Jr,createEphemeralProjectDir as Jt,ROOT_GITIGNORE_TEMPLATE as K,LATEST_PROTOCOL_VERSION as Ki,isAllowedWorkspaceHostHeader as Kn,resolveUiInfo as Kr,createContentFilterAsync as Kt,MISSING_OK_CONFIG_MESSAGE as L,validateSkillZip as Li,incrementServerObserverFire as Ln,removeLastKnownHash as Lr,containsConflictMarkers as Lt,MANAGED_RENAME_ORIGIN as M,tracedWriteFileSync as Mi,getTracer as Mn,recordContributor as Mr,coercePackId as Mt,MAX_AGENT_SESSIONS as N,updateLastKnownHash as Ni,handleCollabSocketError as Nn,recordSkillInstallEvent as Nr,commitUpstreamImport as Nt,HocuspocusAuthTokenSchema as O,tracedRmSync as Oi,getLogger as On,readTargetRecordedAt as Or,classifyFsPath as Ot,MCP_CONNECTION_ID_HEADER as P,updateUiLockPort as Pi,handleSpawnCursor as Pn,registerAllTools as Pr,commitWip as Pt,STARTER_PACK_IDS as Q,resolveConfigPath as Qi,isPathWithinDir as Qn,runAuthStatusSubprocess as Qr,createMcpHttpHandler as Qt,McpLogger as R,withSpan as Ri,initContent as Rn,resetMetrics as Rr,contentHash as Rt,GIT_PREFLIGHT_FAIL_SPAN_NAME as S,tracedAppendFileSync as Si,formatContributorsFrom as Sn,readArmedPaneTarget as Sr,buildConfigYmlContent as St,GitTooOldError as T,tracedMkdirSync as Ti,getCurrentMcpLogger as Tn,readServerPackageVersion as Tr,buildStarterFolderFrontmatterYaml as Tt,PinoLogger as U,writeTracker as Ui,installTestLoggers as Un,resolveLockDir as Ur,createApiExtension as Ut,OK_OKIGNORE_TEMPLATE as V,writeStateManifest as Vi,initToleranceTelemetryWriter as Vn,resolveCursorBinaryDefault as Vr,countStaleAgentWipRefs as Vt,ProjectGitInitError as W,McpServer as Wi,installUserSkill as Wn,resolvePack as Wr,createAssetServeMiddleware as Wt,STARTER_FOLDER_FRONTMATTER_FILENAME as X,atomicWriteFileSync as Xi,isLoopbackAddress as Xn,rewriteWikiLinksForDocumentRename as Xr,createFileLogger as Xt,STARTER_FOLDERS as Y,isJSONRPCResultResponse as Yi,isKnownPackId as Yn,rewriteMarkdownLinksForDocumentRename as Yr,createExternalChangeHandler as Yt,STARTER_PACKS as Z,readConfigSafely as Zi,isPairedWriteOrigin as Zn,runAuthReposSubprocess as Zr,createLiveDerivedIndexExtension as Zt,DEFAULT_PACK_ID as _,startWatcher as _i,findEnclosingGitRoot as _n,parseKeepaliveConnectionId as _r,assertGitAvailable as _t,AgentPresenceBroadcaster as a,resolveShadowDir as aa,sanitizeClientName as ai,describeStoredEmbeddingsKey as an,listStarterPacks as ar,SingleFileNotMarkdownError as at,FILE_WATCHER_ORIGIN as b,teardownToleranceTelemetryWriter as bi,formatAuthRejectionWire as bn,prepareSingleFileOpen as br,bootServer as bt,AutoStartDisabledError as c,seedBasenameIndex as ci,detectProjectShape as cn,logsCurrentPath as cr,UiLockCollisionError as ct,CONFIG_FILENAME as d,shadowGit as di,encodeFolderRoute as dn,mountMcpAndApi as dr,acquireUiLock as dt,writeConfigPatch as ea,runDeviceFlowSubprocess as ei,createPersistenceExtension as en,isSelfWrite as er,STATE_MANIFEST_FILENAME as et,CONFLICT_MARKER_RE as f,shutdownTelemetry as fi,ensureProjectGit as fn,normalizeFsPath as fr,applyAgentMarkdownWrite as ft,DEFAULT_EMBEDDINGS_DIMENSIONS as g,splitMarkdownBlocks as gi,fallbackPaths as gn,parseHocuspocusAuthToken as gr,assertCompatibleStateManifest as gt,DEFAULT_CHECKPOINT_RETENTION as h,spawnDetached as hi,extractWikiLinksFromMarkdown as hn,parseGitVersion as hr,armPaneTarget as ht,AgentFocusBroadcaster as i,resolveGitDirDetailed as ia,safetyCheckpoint as ii,createTestLogger as in,listRescueCheckpoints as ir,SingleFileNotFoundError as it,LOG_MD_TEMPLATE as j,tracedWriteFile as ji,getMetrics as jn,reconcile as jr,clearEmbeddingsKeyFromAllBackends as jt,INSTALLED_AGENTS_SCHEMES as k,tracedRmdirSync as ki,getLogsDir as kn,readTargetVersion as kr,clearArmedPaneTarget as kt,BacklinkIndex as l,serializeError as li,emitPreflightFailureSpan as ln,logsPreviousPath as lr,__getShowAllWalkStatsForTesting as lt,ConfigSchema as m,spansPreviousPath as mi,evictStaleTrackerEntries as mn,parseAuthRejectionWire as mr,applySeed as mt,AGENT_ID_RE as n,MalformedGitPointerError as na,safeContentPath as ni,createServerObserverExtension as nn,isToleranceTelemetryEnabled as nr,SeedRootDirError as nt,AgentSessionCapacityError as o,saveInMemoryCheckpoint as oi,detectClaudeDesktopPresence as on,loadPrincipal as or,StateManifestError as ot,CURSOR_BUNDLE_PATHS_BY_PLATFORM as p,spansCurrentPath as pi,errorResponse as pn,packageVersionMajorMinor as pr,applyExternalChange as pt,SERVICE_WRITER as q,isInitializedNotification as qi,isConfigDoc as qn,restoreContributors as qr,createEmbeddingsSecretStore as qt,AGENT_WRITE_ORIGIN as r,parseCheckpoint as ra,safeSubdir as ri,createStreamingErrorWriter as rn,lastKnownHash as rr,SingleFileNotAFileError as rt,AgentSessionManager as s,saveVersion as si,detectGit as sn,loggerFactory as sr,TagIndex as st,AGENT_ID_MAX_LEN as t,GitDirAccessError as ta,runWithMcpLogger as ti,createServer$1 as tn,isSystemDoc as tr,SeedPrerequisiteError as tt,CC1Broadcaster as u,setActiveSpanAttributes as ui,encodeDocName as un,makeLazyEmbeddingsKeyStore as ur,__resetShowAllWalkStatsForTesting as ut,EMBEDDINGS_API_KEY_ENV as v,streamingProblemEvent as vi,findEnclosingProjectRoot as vn,pathToDocName as vr,assertNeverDiskEvent as vt,GitNotAvailableError as w,tracedMkdir as wi,gcCheckpointRefs as wn,readProjectLocalSemanticConfig as wr,buildSkillZip as wt,FileEmbeddingsBackend as x,toBroadcasterKey as xi,formatContributors as xn,readAllTargets as xr,buildAndOpenSkill as xt,FILE_SYSTEM_WRITER as y,swapContributors as yi,flushFileLogger as yn,planSeed as yr,attachIdleShutdown as yt,MissingOkConfigError as z,withSpanSync as zi,initShadowRepo as zn,resolveBundledSkillDir as zr,contributorCount as zt};
|
|
2955
|
-
//# sourceMappingURL=dist-
|
|
3236
|
+
//# sourceMappingURL=dist-tPUaTm_u.mjs.map
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e,r as t,t as n}from"./gh-detect-CenJLuMO.mjs";import{C as r,E as i,S as a,T as o,_ as s,b as c,d as l,g as u,h as d,i as f,o as p,r as m,s as h,t as g,w as _,x as v,y}from"./init-
|
|
1
|
+
import{i as e,r as t,t as n}from"./gh-detect-CenJLuMO.mjs";import{C as r,E as i,S as a,T as o,_ as s,b as c,d as l,g as u,h as d,i as f,o as p,r as m,s as h,t as g,w as _,x as v,y}from"./init-BFG2ghkC.mjs";import{d as b,f as x,m as S,n as C,p as w,r as T,t as E}from"./src-Bg9Hg2C5.mjs";import{a as D,c as O,o as k,r as A,s as j,t as M}from"./write-project-skill-CdqDqhyf.mjs";import{n as N}from"./loader-BEqRM_pR.mjs";import{n as P}from"./preview-_3nIZqhs.mjs";import{n as F,t as I}from"./mcp-migrate-event-D0NrGjvc.mjs";export{A as ALL_EDITOR_IDS,D as EDITOR_LABELS,k as EDITOR_TARGETS,g as LAUNCH_CONFIG_NAME,m as LAUNCH_UI_CHAIN_SENTINEL,f as LAUNCH_UI_CHAIN_V1,c as addOkPathsToGitExclude,M as assertProjectPathSafe,j as buildManagedServerEntry,I as buildMcpConfigMigrateEvent,p as classifyExistingMcpEntry,t as createTokenStore,n as detectGh,h as detectInstalledEditors,v as formatTrackedRemediation,a as getExcludedOkPaths,r as getOkArtifactPaths,O as isEntryUpToDate,N as loadConfig,e as makeLazyProbeTokenStore,b as parseGitHubBlobUrl,x as parseGitHubShareUrl,w as parseGitHubTreeUrl,S as parseGitUrl,P as previewContent,_ as probeTrackedOkPaths,l as readExistingMcpEntry,o as readSharingMode,i as removeOkPathsFromGitExclude,y as resolveProjectRoot,T as runStop,d as scaffoldLaunchJson,F as truncatePriorEntry,C as validateLocalFolderForShare,u as writeEditorMcpConfig,E as writeProjectAiIntegrations,s as writeUserMcpConfigs};
|