@inkeep/open-knowledge 0.13.0-beta.6 → 0.13.0-beta.7

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.
@@ -1706,7 +1706,7 @@ description: When the agent does scheduled work: daily briefings, end-of-day dos
1706
1706
  `);k=s.pop()??``;for(let e of s){if(!e.trim())continue;let s=null;try{s=JSON.parse(e)}catch{}if(s&&s.type===`error`){S(500,`urn:ok:error:auth-failed`,`Auth repos subprocess reported an error.`,{detail:typeof s.message==`string`?s.message:void 0});continue}if(!t.writableEnded&&!t.destroyed)try{t.write(`${e}\n`)}catch{}}}),j.stderr.on(`data`,e=>{log$6.debug({msg:e.toString(`utf-8`).trim()},`[local-op/auth/repos] stderr`)}),j.on(`close`,e=>{clearTimeout(F),O||(O=!0,e!==0&&!t.writableEnded&&S(500,`urn:ok:error:auth-failed`,`Auth repos subprocess exited with code ${e}.`),t.end(),Ie.release(Vc))}),j.on(`error`,e=>{clearTimeout(F),O||(O=!0,t.writableEnded||(S(500,`urn:ok:error:auth-failed`,`Failed to spawn the auth repos subprocess.`,{cause:e}),t.end()),Ie.release(Vc))}),t.on(`close`,()=>{O||(O=!0,clearTimeout(F),j.kill(`SIGTERM`),Ie.release(Vc))})}let Qc=`local-op-auth-signout`,$c=withValidation(LocalOpAuthHostRequestSchema,async(e,t,s)=>{let g=s.host??`github.com`;if(!Ie.tryAcquire(Hc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth signout operation is already in progress.`,{handler:Qc,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...s]=fe,S=[...s,`auth`,`signout`,`--host`,g];await new Promise((t,s)=>{let g=spawn(e,S,{stdio:`ignore`,env:{...process.env}}),w=setTimeout(()=>{g.kill(`SIGTERM`)},3e4);g.on(`close`,()=>{clearTimeout(w),t()}),g.on(`error`,e=>{clearTimeout(w),s(e)})}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:Qc})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth signout failed.`,{handler:Qc,cause:e})}finally{Ie.release(Hc)}},{handler:Qc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Qc})}),nl=`/api/local-op/auth/set-identity`,il=`local-op-auth-set-identity`,al=withValidation(LocalOpAuthSetIdentityRequestSchema,async(e,t,s)=>{let g=s.name.trim(),S=s.email.trim();if(!me){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:il});return}if(!Ie.tryAcquire(nl)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A set-identity operation is already in progress.`,{handler:il,extraHeaders:{"Retry-After":`5`}});return}try{writeGitIdentity(me,g,S),de?.()?.refreshIdentity().catch(()=>{}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:il})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Set-identity failed.`,{handler:il,cause:e})}finally{Ie.release(nl)}},{handler:il,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:il})});async function cl(e,t){if(checkLocalOpSecurity(e,t,{handler:`sync-status`})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-status`,extraHeaders:{Allow:`GET`}});return}try{let e=de?.();if(!e){successResponse(t,200,SyncStatusSchema,{state:`dormant`,lastSyncUtc:null,lastFetchUtc:null,lastPushedSha:null,ahead:0,behind:0,consecutiveFailures:0,conflictCount:0,hasRemote:!1,syncEnabled:!1,identityUnresolved:!1,remote:null},{handler:`sync-status`});return}await e.refreshRemote(),successResponse(t,200,SyncStatusSchema,e.getStatus(),{handler:`sync-status`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`sync-status`,cause:e})}}}let ll=withValidation(SyncTriggerRequestSchema,async(e,t,s)=>{let g=de?.();if(!g){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`});return}let S=s.op??`sync`;successResponse(t,202,SyncTriggerSuccessSchema,{op:S},{handler:`sync-trigger`}),g.trigger(S)},{handler:`sync-trigger`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-trigger`})?de?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`}),!1):!1});async function ul(e,t){if(checkLocalOpSecurity(e,t,{handler:`sync-conflicts`})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflicts`,extraHeaders:{Allow:`GET`}});return}try{let e=de?.();successResponse(t,200,SyncConflictsSuccessSchema,{conflicts:e?e.getConflicts():[]},{handler:`sync-conflicts`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`sync-conflicts`,cause:e})}}}let dl=withValidation(SyncResolveConflictRequestSchema,async(e,t,s)=>{let g=de?.();if(!g){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`});return}let{file:S,strategy:w,content:E}=s;try{await g.resolveConflict(S,w,E),successResponse(t,200,SyncResolveConflictSuccessSchema,{},{handler:`sync-resolve-conflict`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to resolve conflict.`,{handler:`sync-resolve-conflict`,cause:e,detail:e instanceof Error?e.message:void 0})}},{handler:`sync-resolve-conflict`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-resolve-conflict`})?de?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`}),!1):!1});async function fl(e,s){if(!checkLocalOpSecurity(e,s,{handler:`sync-conflict-content`}))return;if(e.method!==`GET`){errorResponse(s,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflict-content`,extraHeaders:{Allow:`GET`}});return}if(!me){errorResponse(s,503,`urn:ok:error:project-repo-not-configured`,`Project repo not configured.`,{handler:`sync-conflict-content`});return}let g=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`),S=g.searchParams.get(`file`);if(!S){errorResponse(s,400,`urn:ok:error:invalid-request`,`Missing required query param: file.`,{handler:`sync-conflict-content`});return}if(S.includes(`..`)||S.startsWith(`/`)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Invalid file path.`,{handler:`sync-conflict-content`});return}let w=stripDocExtension(S),E=t.documents.get(w)?.getMap(`lifecycle`).get(`status`)===`conflict`,D=de?.(),O=D?D.getConflicts().some(e=>e.file===S):!1;if(!E&&!O){errorResponse(s,404,`urn:ok:error:no-conflict-tracked`,`No conflict is tracked for this path.`,{handler:`sync-conflict-content`,extensions:{file:S}});return}let k=g.searchParams.get(`source`),j=esm_default({baseDir:me,timeout:{block:15e3}});async function F(e){try{return{present:!0,content:await j.raw([`show`,`:${e}:${S}`])}}catch(t){let s=t instanceof Error?t.message:String(t);if(!/pathspec|did not match|exists on disk, but not in|is in the index, but not at stage/i.test(s))throw console.warn(JSON.stringify({event:`showstage-unexpected-error`,stage:e,file:S,detail:s,handler:`sync-conflict-content`})),t;return{present:!1}}}try{let[e,g,w]=await Promise.all([F(1),F(2),F(3)]),E=e.present?e.content:``,D=w.present?w.content:``,O=g.present&&w.present?`both-modified`:!g.present&&w.present?`delete-modify`:g.present&&!w.present?`modify-delete`:`both-modified`,j=g.present?g.content:``,L=null;if(k===`ytext`){let e=stripDocExtension(S),s=t.documents.get(e);if(s){let t=s.getMap(`lifecycle`).get(`status`);if(L=typeof t==`string`&&t.length>0?t:null,O!==`delete-modify`){let t=Te?Te(e):null;t!==null&&!ytextHasConflictMarkers(t)?j=t:t!==null&&console.warn(JSON.stringify({event:`ytext-conflict-marker-detected`,"doc.name":e,handler:`sync-conflict-content`}))}}else console.warn(`[conflict-content] doc ${e} not loaded; lifecycleStatus unavailable`)}successResponse(s,200,SyncConflictContentSuccessSchema,{file:S,base:E,ours:j,theirs:D,kind:O,lifecycleStatus:L},{handler:`sync-conflict-content`})}catch(e){errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to read conflict content.`,{handler:`sync-conflict-content`,cause:e})}}async function pl(e,t){if(!checkLocalOpSecurity(e,t,{handler:`seed-plan`}))return;if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`seed-plan`,extraHeaders:{Allow:`GET`}});return}let s=new URL(e.url??`/`,`http://localhost`),S=s.searchParams.get(`rootDir`)??void 0,w=s.searchParams.get(`packId`),E=coercePackId(w);if(w!==null&&w!==``&&E===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-plan`,detail:`Pack id "${w}" is not registered.`});return}try{successResponse(t,200,SeedPlanSuccessSchema,{plan:await planSeed({projectDir:g,rootDir:S,packId:E})},{handler:`seed-plan`})}catch(e){if(e instanceof SeedPrerequisiteError){errorResponse(t,422,`urn:ok:error:seed-prerequisite-missing`,`Seed prerequisite missing.`,{handler:`seed-plan`,cause:e});return}if(e instanceof SeedRootDirError){errorResponse(t,400,`urn:ok:error:seed-invalid-root`,`Invalid seed root directory.`,{handler:`seed-plan`,detail:`The provided root directory is not within the workspace content directory.`,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`seed-plan`,cause:e})}}let ml=withValidation(SeedApplyRequestSchema,async(e,t,s)=>{let S=s.plan;if(!S||typeof S!=`object`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid plan payload.`,{handler:`seed-apply`});return}let w=S,E=s.packId,D=coercePackId(E);if(typeof E==`string`&&E.length>0&&D===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-apply`,detail:`Pack id "${E}" is not registered.`});return}try{successResponse(t,200,SeedApplySuccessSchema,{result:await applySeed(w,{projectDir:g,packId:D})},{handler:`seed-apply`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to apply seed plan.`,{handler:`seed-apply`,cause:e})}},{handler:`seed-apply`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`seed-apply`})});async function hl(e,t){if(checkLocalOpSecurity(e,t,{handler:`seed-packs`})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`seed-packs`,extraHeaders:{Allow:`GET`}});return}successResponse(t,200,SeedListPacksSuccessSchema,{packs:listStarterPacks()},{handler:`seed-packs`})}}let gl=withValidation(InstallSkillRequestSchema,async(e,t,s)=>{if(s.out!==void 0&&!isSafeLocalPath(s.out)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Output path must be within home directory.`,{handler:`install-skill`});return}try{successResponse(t,200,InstallSkillSuccessSchema,await buildAndOpenSkill({...s.noOpen===void 0?{}:{noOpen:s.noOpen},...s.out===void 0?{}:{out:s.out}}),{handler:`install-skill`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to install skill.`,{handler:`install-skill`,cause:e})}},{handler:`install-skill`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`install-skill`})});async function _l(e,t){if(checkLocalOpSecurity(e,t,{handler:`installed-agents`}))try{await handleInstalledAgents(e,t,nt.probeAll)}catch(e){t.headersSent||(log$6.error({err:e},`[installed-agents] route wrapper failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`installed-agents`,cause:e}))}}let vl=withValidation(EmptyRequestSchema,async(e,t)=>{if(!ae){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-list`});return}try{successResponse(t,200,TagsListSuccessSchema,{tags:ae.getAllTags()},{handler:`tags-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read tags.`,{handler:`tags-list`,cause:e})}},{handler:`tags-list`,method:`GET`,skipBodyParse:!0});async function yl(e,t,s){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`tags-for-name`,extraHeaders:{Allow:`GET`}});return}if(!ae){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-for-name`});return}let g;try{g=decodeURIComponent(s)}catch{errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid tag name encoding.`,{handler:`tags-for-name`});return}if(!g){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing tag name.`,{handler:`tags-for-name`});return}try{let e=ae.getDocsForTagWithMatches(g).map(({docName:e,matchingTags:t})=>({docName:e,title:it(e),matchingTags:t,snippet:null}));successResponse(t,200,TagsForNameSuccessSchema,{name:g,docs:e},{handler:`tags-for-name`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read tag membership.`,{handler:`tags-for-name`,cause:e})}}function xl(e,t,s=`path`,S=`folder-config`){let w=e.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``);if(w.split(`/`).some(e=>e===`..`)||e.startsWith(`/`))return errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid ${s}: must be project-root-relative.`,{handler:S}),null;let E=resolve(g),D=w===``?E:resolve(E,w);return D!==E&&!D.startsWith(`${E}${sep}`)?(errorResponse(t,400,`urn:ok:error:invalid-request`,`Path escapes content directory.`,{handler:S}),null):{folderRel:w,resolvedContentDir:E}}let Cl=/^[A-Za-z0-9_-]+$/;function Tl(e,t,s=`template`){return!e||!Cl.test(e)?(errorResponse(t,400,`urn:ok:error:invalid-request`,"Invalid name: must be letters / digits / `_` / `-` only (no `.md` extension).",{handler:s}),!1):!0}function El(e,t,s){let g=t===``?[]:t.split(`/`);for(let t=g.length;t>=0;t--){let S=t===0?``:g.slice(0,t).join(`/`),w=S===``?e:resolve(e,S);if(w!==e&&!w.startsWith(`${e}${sep}`))continue;let E=resolve(w,`.ok`,`templates`,`${s}.md`);if(existsSync(E))return{abs:E,folder:S,scope:t===g.length?`local`:`inherited`}}return null}function Dl(e){let t={};if(!e||typeof e!=`object`||Array.isArray(e))return t;for(let[s,g]of Object.entries(e))g!==void 0&&(t[s]=g);return t}async function Ol(e,t){if(e.method===`GET`)return kl(e,t);if(e.method===`PUT`)return jl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`folder-config`,extraHeaders:{Allow:`GET, PUT`}})}let kl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=xl(new URL(e.url??``,`http://localhost`).searchParams.get(`path`)??``,t,`path`,`folder-config-get`);if(!s)return;let g=await enrichDirectory(s.folderRel,{projectDir:s.resolvedContentDir}),S=resolve(resolve(s.resolvedContentDir,s.folderRel,`.ok`),`frontmatter.yml`),w=null;if(existsSync(S))try{let e=(0,import_dist$1.parse)(await readFile$1(S,`utf-8`));w=e&&typeof e==`object`&&!Array.isArray(e)?e:{}}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[folder-config:get] malformed YAML in ${S}: ${t}`),w=null}successResponse(t,200,FolderConfigGetSuccessSchema,{folder:g,frontmatter_local:w},{handler:`folder-config-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read folder config.`,{handler:`folder-config-get`,cause:e})}},{handler:`folder-config-get`,method:`GET`,skipBodyParse:!0}),jl=withValidation(FolderConfigPutRequestSchema,async(e,t,s)=>{try{if(Pe){errorResponse(t,403,`urn:ok:error:single-file-mode`,`Folder configuration is not available in single-file mode.`,{handler:`folder-config-put`});return}let e=extractActorIdentity(s,ge);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`folder-config-put`});return}let g=xl(s.path,t,`path`,`folder-config-put`);if(!g)return;let S=[];if(s.frontmatter!==void 0){let w=applyFolderFrontmatterPatch({anchorDir:g.resolvedContentDir,folderRel:g.folderRel,patch:s.frontmatter});if(!w.ok){let e=w.error.code===`WRITE_ERROR`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to write folder config.`:w.error.message,{handler:`folder-config-put`,detail:w.error.code,cause:Error(w.error.message)});return}S.push({path:w.path,action:w.action}),w.action!==`noop`&&(Ui(e,Hi(`folder-frontmatter`,g.folderRel),`folder-frontmatter-${w.action===`deleted`?`delete`:`edit`}: ${w.path}`),await Gi(`folder-config-put`))}successResponse(t,200,FolderConfigPutSuccessSchema,{applied:S},{handler:`folder-config-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write folder config.`,{handler:`folder-config-put`,cause:e})}},{handler:`folder-config-put`,method:`PUT`});function Ml(e,s,g,S){if(!s)return!1;let w=e===``?`.ok/templates/${s}`:`${e.replace(/\/$/,``)}/.ok/templates/${s}`,E=t.documents.get(w);return E&&isDocInConflict(E)?(respondDocInConflict(S,new DocInConflictError({file:`${w}.md`}),g),!0):!1}let Pl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=resolveProjectTemplates(resolve(g));successResponse(t,200,TemplatesListSuccessSchema,{templates:e.templates.map(e=>{let{scope:t,...s}=e;return s}),truncated:e.truncated},{handler:`templates-list`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list templates.`,{handler:`templates-list`,cause:e})}},{handler:`templates-list`,method:`GET`,skipBodyParse:!0});async function Fl(e,t){if(e.method===`GET`)return Ll(e,t);if(e.method===`PUT`)return Rl(e,t);if(e.method===`POST`)return Bl(e,t);if(e.method===`DELETE`)return zl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`template`,extraHeaders:{Allow:`GET, PUT, POST, DELETE`}})}let Il=e=>{let{frontmatter:t,body:s}=stripFrontmatter(e),g={};if(t!==``)try{let e=(0,import_dist$1.parse)(unwrapFrontmatterFences(t));e&&typeof e==`object`&&!Array.isArray(e)&&(g=e)}catch{}return{frontmatter:g,body:s}},Ll=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Tl(g,t,`template-get`))return;let S=xl(s.searchParams.get(`folder`)??``,t,`folder`,`template-get`);if(!S)return;let{folderRel:w,resolvedContentDir:E}=S,D=El(E,w,g);if(!D){errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-get`,detail:`Template "${g}" not found for folder "${w||`.`}". Walked leaf → root.`});return}let{abs:O,folder:k,scope:j}=D,{frontmatter:F,body:L}=Il(await readFile$1(O,`utf-8`));successResponse(t,200,TemplateGetSuccessSchema,{template:{name:g,folder:k,scope:j,path:relative(E,O).split(/[\\/]/).filter(Boolean).join(`/`),frontmatter:F,body:L}},{handler:`template-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read template.`,{handler:`template-get`,cause:e})}},{handler:`template-get`,method:`GET`,skipBodyParse:!0}),Rl=withValidation(TemplatePutRequestSchema,async(e,t,s)=>{try{if(Pe){errorResponse(t,403,`urn:ok:error:single-file-mode`,`Templates are not available in single-file mode.`,{handler:`template-put`});return}let e=extractActorIdentity(s,ge);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`template-put`});return}let g=s.name;if(!Tl(g,t,`template-put`))return;let S=xl(s.folder,t,`folder`,`template-put`);if(!S||Ml(S.folderRel,g,`template-put`,t))return;let w=applyTemplateWrite({projectDir:S.resolvedContentDir,folder:S.folderRel,name:g,body:typeof s.body==`string`?s.body:``,frontmatter:Dl(s.frontmatter)});if(!w.ok){let e=w.error.code===`WRITE_ERROR`||w.error.code===`BAD_PROJECT_DIR`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to write template.`:`Invalid template request.`,{handler:`template-put`,detail:w.error.code,cause:Error(w.error.message)});return}Ui(e,Hi(`template`,S.folderRel,g),`${w.created?`template-create`:`template-edit`}: ${w.path}`),await Gi(`template-put`),successResponse(t,200,TemplatePutSuccessSchema,{path:w.path,created:w.created,warnings:w.warnings},{handler:`template-put`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to write template.`,{handler:`template-put`,cause:e})}},{handler:`template-put`,method:`PUT`}),zl=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Tl(g,t,`template-delete`))return;let S=xl(s.searchParams.get(`folder`)??``,t,`folder`,`template-delete`);if(!S)return;let w=s.searchParams,E=extractActorIdentity({agentId:w.get(`agentId`)??void 0,agentName:w.get(`agentName`)??void 0,colorSeed:w.get(`colorSeed`)??void 0,clientName:w.get(`clientName`)??void 0,clientVersion:w.get(`clientVersion`)??void 0,label:w.get(`label`)??void 0,summary:w.get(`summary`)??void 0},ge);if(E.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`template-delete`});return}if(Ml(S.folderRel,g,`template-delete`,t))return;let D=applyTemplateDelete({projectDir:S.resolvedContentDir,folder:S.folderRel,name:g});if(!D.ok){let e=D.error.code===`WRITE_ERROR`||D.error.code===`UNLINK_FAILED`||D.error.code===`BAD_PROJECT_DIR`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to delete template.`:`Invalid template request.`,{handler:`template-delete`,detail:D.error.code,cause:Error(D.error.message)});return}D.existed&&(Ui(E,Hi(`template`,S.folderRel,g),`template-delete: ${D.path}`),await Gi(`template-delete`)),successResponse(t,200,TemplateDeleteSuccessSchema,{existed:D.existed,path:D.path},{handler:`template-delete`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to delete template.`,{handler:`template-delete`,cause:e})}},{handler:`template-delete`,method:`DELETE`,skipBodyParse:!0}),Bl=withValidation(TemplateMoveRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,ge);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`template-move`});return}if(!Tl(s.fromName,t,`template-move`)||!Tl(s.toName,t,`template-move`))return;let g=xl(s.fromFolder,t,`folder`,`template-move`);if(!g)return;let S=xl(s.toFolder,t,`folder`,`template-move`);if(!S||Ml(g.folderRel,s.fromName,`template-move`,t))return;let w=await applyTemplateMove({projectDir:g.resolvedContentDir,fromFolder:g.folderRel,fromName:s.fromName,toFolder:S.folderRel,toName:s.toName,relocate:async(e,t)=>{let s=await renameTrackedPathInGit(me,e,t);return s||renamePathOnDisk(e,t),s}});if(!w.ok){if(w.error.code===`TEMPLATE_NOT_FOUND`){let e=El(g.resolvedContentDir,g.folderRel,s.fromName);if(e?.scope===`inherited`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Template "${s.fromName}" is inherited from "${e.folder||`(root)`}", not local to "${g.folderRel||`(root)`}". Move it from the folder that owns it, or create a local copy here first (then move that).`,{handler:`template-move`,detail:`TEMPLATE_INHERITED`});return}errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-move`,detail:w.error.message});return}if(w.error.code===`TEMPLATE_EXISTS`){errorResponse(t,409,`urn:ok:error:doc-already-exists`,w.error.message,{handler:`template-move`,detail:w.error.code});return}let e=w.error.code===`WRITE_ERROR`||w.error.code===`MOVE_FAILED`?500:400;errorResponse(t,e,e===500?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,e===500?`Failed to move template.`:`Invalid template move request.`,{handler:`template-move`,detail:w.error.code,cause:Error(w.error.message)});return}let E=null;if(s.body!==void 0||s.frontmatter!==void 0){let e;if(typeof s.body==`string`)e=s.body;else try{e=Il(readFileSync(resolve(S.resolvedContentDir,w.toPath),`utf-8`)).body}catch{e=null}if(e===null)E={code:`READ_FAILED`,message:`could not read the moved template to apply the metadata change; the move succeeded with the original content intact — retry the edit`};else{let t=applyTemplateWrite({projectDir:S.resolvedContentDir,folder:S.folderRel,name:s.toName,body:e,frontmatter:Dl(s.frontmatter)});t.ok||(E=t.error)}}if(Ui(e,Hi(`template`,S.folderRel,s.toName),`template-rename: ${w.fromPath} -> ${w.toPath}`,[{from:w.fromPath,to:w.toPath}]),await Gi(`template-move`),oe?.(`files`),E){let e=E.code===`WRITE_ERROR`||E.code===`READ_FAILED`;errorResponse(t,e?500:400,e?`urn:ok:error:internal-server-error`:`urn:ok:error:invalid-request`,`Template moved to "${w.toPath}", but updating its content failed.`,{handler:`template-move`,detail:E.code,cause:Error(E.message)});return}successResponse(t,200,TemplateMoveSuccessSchema,{from:w.fromPath,to:w.toPath,committed:w.committed},{handler:`template-move`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to move template.`,{handler:`template-move`,cause:e})}},{handler:`template-move`,method:`POST`});function Vl(e){let t=new Map;for(let s of e){let e=s.path.split(`/`).filter(Boolean);e.pop();for(let g=1;g<=e.length;g++){let S=e.slice(0,g).join(`/`);t.set(S,Math.max(t.get(S)??0,s.modifiedTs))}}return[...t.entries()].map(([e,t])=>createWorkspaceSearchDocument({kind:`folder`,path:e,modifiedTs:t}))}function Hl(e,t){let s=t.trim().toLowerCase();if(!s||!e)return;let g=e.toLowerCase().indexOf(s);if(g<0)return;let S=Math.max(0,g-80),w=Math.min(e.length,g+s.length+120),E=S>0?`…`:``,D=w<e.length?`…`:``;return`${E}${e.slice(S,w).replace(/\s+/g,` `).trim()}${D}`}function Ul(e){return e===`autocomplete`||e===`full_text`||e===`omnibar`?e:`omnibar`}function Wl(e){let t=typeof e==`string`?e.split(`,`):Array.isArray(e)?e:void 0;if(!t)return;let s=t.filter(e=>e===`page`||e===`folder`||e===`content`);return s.length>0?s:void 0}function Gl(e){if(typeof e==`boolean`)return e;if(e===`true`)return!0;if(e===`false`)return!1}function Kl(e){return e===`omnibar`||e===`mcp`||e===`http`?e:`http`}async function ql(e,t,s,g){let S=g.documents.reduce((e,t)=>e+(t.kind===`page`?1:0),0);if(!De?.isEnabled()||s!==!0)return{queryEmbedMs:null,pageTotal:S,capable:!1};De.embedCorpus(g.documents);let w,E=null;if(t===`full_text`&&e.trim().length>=3){let t=performance.now(),s=await De.queryScores(e,g.documents);if(E=performance.now()-t,s&&s.size>0){let e=je?.();w=e===void 0?{scores:s}:{scores:s,similarityFloor:e}}}let D=De.getStatus();return{input:w,status:{capable:D.capable,applied:!1,coverage:{embedded:D.embeddedCount,total:S}},queryEmbedMs:E,pageTotal:S,capable:D.capable}}function Jl(e,t){return{kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?Hl(e.document.content,t):void 0}}async function Yl(e){let t=performance.now(),s=await Ql(),g=await ql(e.query,e.intent,e.semanticParam,s),S=searchWorkspaceCorpus(s,e.query,{intent:e.intent,scopes:e.scopes,limit:e.limit,semantic:g.input}).map(t=>Jl(t,e.query)),w;if(g.status){let t=S.reduce((e,t)=>e+(t.signals.vector===void 0?0:1),0),s=t>0;w={...g.status,applied:s},recordSemanticQuery({outcome:g.capable?s?`applied`:g.status.coverage.embedded===0?`warming`:`no_match`:`incapable`,source:e.source,capable:g.capable,embedded:g.status.coverage.embedded,total:g.pageTotal,queryEmbedMs:g.queryEmbedMs,vectorContributors:t})}return{query:e.query,intent:e.intent,results:S,elapsedMs:Math.max(0,performance.now()-t),...w?{semantic:w}:{}}}async function Xl(){let e=[];for(let[t,s]of w()){if(isSystemDoc(t)||isConfigDoc(t)||isHiddenDocName(t))continue;let g=``,S=t;try{g=await readFile$1(s.canonicalPath,`utf-8`),S=extractPageTitle(g,t)}catch(e){console.warn(`[search] Failed to index ${t}:`,e)}e.push(createWorkspaceSearchDocument({kind:`page`,path:t,title:S,content:g,modifiedTs:Date.parse(s.modified)}))}return[...e,...Vl(e)]}function Zl(){return[...w()].filter(([e])=>!isSystemDoc(e)&&!isConfigDoc(e)&&!isHiddenDocName(e)).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}${t.modified}${t.size}${t.canonicalPath}${t.inode}${t.aliases.join(`,`)}`).join(``)}async function Ql(){let e=`${g}${me??``}`,t=Zl(),s=workspaceSearchCaches.get(e);if(s?.fingerprint===t&&s.corpus)return s.corpus;if(s?.fingerprint===t&&s.pending)return s.pending;let S=Xl().then(e=>createWorkspaceSearchCorpus(e));workspaceSearchCaches.set(e,{fingerprint:t,pending:S});try{let s=await S;return workspaceSearchCaches.get(e)?.pending===S&&workspaceSearchCaches.set(e,{fingerprint:t,corpus:s}),s}catch(t){throw workspaceSearchCaches.get(e)?.pending===S&&workspaceSearchCaches.delete(e),t}}function $l(){if(process.env.NODE_ENV!==`test`)for(let e of[0,1e3,3e3])setTimeout(()=>{Ql().catch(e=>{console.warn(`[search] Failed to prewarm workspace search cache:`,e)})},e)}$l();async function eu(e,t){if(e.method===`GET`)return tu(e,t);if(e.method===`POST`)return nu(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`search`,extraHeaders:{Allow:`GET, POST`}})}let tu=withValidation(EmptyRequestSchema,async(e,t)=>{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`limit`),S=s.searchParams.get(`query`)??``,w=Ul(s.searchParams.get(`intent`)),E=Wl(s.searchParams.get(`scope`)??s.searchParams.get(`scopes`)),D=Gl(s.searchParams.get(`semantic`)),O=Kl(s.searchParams.get(`source`)),k=g===null?void 0:Number(g);if(S.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-get`});return}try{successResponse(t,200,SearchSuccessSchema,await Yl({query:S,intent:w,scopes:E,limit:k,semanticParam:D,source:O}),{handler:`search-get`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to search workspace.`,{handler:`search-get`,cause:e})}},{handler:`search-get`,method:`GET`,skipBodyParse:!0}),nu=withValidation(SearchRequestSchema,async(e,t,s)=>{let g=typeof s.query==`string`?s.query:``,S=Ul(s.intent),w=Wl(s.scopes??s.scope),E=typeof s.limit==`number`?s.limit:void 0,D=Gl(s.semantic),O=Kl(s.source);if(g.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-post`});return}try{successResponse(t,200,SearchSuccessSchema,await Yl({query:g,intent:S,scopes:w,limit:E,semanticParam:D,source:O}),{handler:`search-post`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to search workspace.`,{handler:`search-post`,cause:e})}},{handler:`search-post`,method:`POST`}),ru=withValidation(EmptyRequestSchema,async(e,t)=>{try{successResponse(t,200,SkillInstallStateSuccessSchema,{...await readSkillInstallStateSnapshot(homedir())},{handler:`skill-install-state`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read skill install state.`,{handler:`skill-install-state`,cause:e})}},{handler:`skill-install-state`,method:`GET`,skipBodyParse:!0,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`skill-install-state`})});async function iu(e,t){if(checkLocalOpSecurity(e,t,{handler:`handoff`}))try{await handleHandoffDispatch(e,t,{contentDir:g,platform:process.platform})}catch(e){t.headersSent||(log$6.error({err:e},`[handoff] route wrapper failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`handoff`,cause:e}))}}async function au(e,t){if(checkLocalOpSecurity(e,t,{handler:`spawn-cursor`}))try{await handleSpawnCursor(e,t,{contentDir:g,platform:process.platform})}catch(e){t.headersSent||(log$6.error({err:e},`[spawn-cursor] route wrapper failed`),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`spawn-cursor`,cause:e}))}}let ou=withValidation(ShareConstructUrlRequestSchema,async(e,t,s)=>{try{if(!me){emitShareConstructUrlLog(`no-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!isValidSharePath(s.kind===`doc`?s.docPath:s.folderPath,s.kind)){emitShareConstructUrlLog(`invalid-path`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`invalid-path`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let e=readGitHeadBranch(me);if(e===null){if(readOriginGitHubRepo(me).kind===`no-remote`){emitShareConstructUrlLog(`no-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}emitShareConstructUrlLog(`detached-head`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`detached-head`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let S=readOriginGitHubRepo(me);if(S.kind===`no-remote`){emitShareConstructUrlLog(`no-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`no-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(S.kind===`non-github`){emitShareConstructUrlLog(`non-github-remote`,{kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`non-github-remote`},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}if(!branchExistsOnOrigin(me,e)){emitShareConstructUrlLog(`branch-not-on-origin`,{branchExists:!1,kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!1,error:`branch-not-on-origin`,branch:e},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG});return}let w=toGitRelativePath(me,g);if(w===null)throw Error(`content dir is not contained within the project dir`);let E=s.kind===`doc`?s.docPath!==``:s.folderPath!==``;w!==``&&E&&getLogger(`share`).warn({action:`construct-url`,kind:s.kind},`[share] content.dir != "." — non-root share URL omits the content.dir prefix; the github.com link may point at the wrong subtree. In-app receive navigation is content-relative and lands correctly.`);let D;if(s.kind===`doc`)D=buildGitHubBlobUrl(S.owner,S.repo,e,s.docPath);else{let t=s.folderPath===``?w:s.folderPath;D=buildGitHubTreeUrl(S.owner,S.repo,e,t)}let O=`${SHARE_BASE_URL}${encodeShareUrl(D)}`;emitShareConstructUrlLog(`ok`,{branchExists:!0,kind:s.kind}),successResponse(t,200,ShareConstructUrlResponseSchema,{ok:!0,shareUrl:O,sharedUrl:D,branch:e},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG,cause:e})}},{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_CONSTRUCT_URL_HANDLER_TAG})}),su=withValidation(EmptyRequestSchema,async(e,t)=>{try{if(!me){errorResponse(t,500,`urn:ok:error:internal-server-error`,`projectDir is not configured for this server.`,{handler:BRANCH_INFO_HANDLER_TAG});return}let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`branch`),S=s.searchParams.get(`path`),w=s.searchParams.get(`kind`)===`folder`?`folder`:`doc`;if(!isValidBranchName(g)){errorResponse(t,400,`urn:ok:error:invalid-request`,`branch query param missing or malformed.`,{handler:BRANCH_INFO_HANDLER_TAG});return}if(!isValidBranchInfoPath(S,w)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path query param missing or malformed.`,{handler:BRANCH_INFO_HANDLER_TAG});return}successResponse(t,200,BranchInfoResponseSchema,await computeBranchInfo(me,g,S,w),{handler:BRANCH_INFO_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:BRANCH_INFO_HANDLER_TAG,cause:e})}},{handler:BRANCH_INFO_HANDLER_TAG,method:`GET`,skipBodyParse:!0}),cu=withValidation(CheckoutRequestSchema,async(e,t,s)=>{if(extractActorIdentity(s,ge).kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:CHECKOUT_HANDLER_TAG});return}if(!me){errorResponse(t,500,`urn:ok:error:internal-server-error`,`projectDir is not configured for this server.`,{handler:CHECKOUT_HANDLER_TAG});return}try{successResponse(t,200,CheckoutResponseSchema,await withParentLock(()=>runCheckoutFlow(me,s.branch)),{handler:CHECKOUT_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:CHECKOUT_HANDLER_TAG,cause:e})}},{handler:CHECKOUT_HANDLER_TAG,method:`POST`});async function lu(e){let[t,...s]=fe,g=[...s,...e];return await new Promise((e,s)=>{let S=spawn(t,g,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),w=!1,E=setTimeout(()=>{w=!0,S.kill(`SIGTERM`)},SHARE_PUBLISH_TIMEOUT_MS),D=[],O=[];S.stdout.on(`data`,e=>D.push(e)),S.stderr.on(`data`,e=>O.push(e)),S.on(`close`,t=>{if(clearTimeout(E),w){s(Error(`share subprocess timed out after ${SHARE_PUBLISH_TIMEOUT_MS}ms`));return}let g=Buffer.concat(D).toString(`utf-8`);if(t!==0){let e=redactShareSubprocessStderr(Buffer.concat(O).toString(`utf-8`)).slice(0,500);console.warn(`[share] subprocess exited code=${t} stderr=${e}`)}e({stdout:g,code:t})}),S.on(`error`,e=>{clearTimeout(E),s(e)})})}let uu=withValidation(EmptyRequestSchema,async(e,t)=>{if(!Ie.tryAcquire(`/api/share/publish/owners`)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A share owners operation is already in progress.`,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG,extraHeaders:{"Retry-After":`5`}});return}try{let{stdout:e}=await lu([`share`,`owners`,`--json`]),s=parseOwnersEvent(pickTerminalJsonLine(e));emitSharePublishLog(`owners-list`,s.ok?`ok`:s.error,s.ok?{count:s.owners.length}:void 0),successResponse(t,200,SharePublishOwnersResponseSchema,s,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG,cause:e})}finally{Ie.release(SHARE_PUBLISH_OWNERS_KEY)}},{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG,method:`GET`,skipBodyParse:!0,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_OWNERS_HANDLER_TAG})}),du=withValidation(EmptyRequestSchema,async(e,t)=>{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`owner`)??``,S=s.searchParams.get(`name`)??``;if(!isValidShareOwnerName(g)||!isValidShareRepoName(S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`owner and name query params must be valid GitHub identifiers.`,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG});return}if(!Ie.tryAcquire(`/api/share/publish/name-check`)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A share name-check operation is already in progress.`,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG,extraHeaders:{"Retry-After":`5`}});return}try{let{stdout:e}=await lu([`share`,`name-check`,`--owner`,g,`--name`,S,`--json`]),s=parseNameCheckEvent(pickTerminalJsonLine(e));emitSharePublishLog(`name-check`,s.ok?`ok`:s.error,s.ok?{available:s.available}:void 0),successResponse(t,200,SharePublishNameCheckResponseSchema,s,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG,cause:e})}finally{Ie.release(SHARE_PUBLISH_NAME_CHECK_KEY)}},{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG,method:`GET`,skipBodyParse:!0,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_NAME_CHECK_HANDLER_TAG})}),fu=withValidation(SharePublishRequestSchema,async(e,t,s)=>{if(!me){emitSharePublishLog(`publish-create`,`no-project`),successResponse(t,200,SharePublishResponseSchema,{ok:!1,error:`no-project`},{handler:SHARE_PUBLISH_HANDLER_TAG});return}if(!isValidShareOwnerName(s.owner)||!isValidShareRepoName(s.name)){errorResponse(t,400,`urn:ok:error:invalid-request`,`owner and name must be valid GitHub identifiers.`,{handler:SHARE_PUBLISH_HANDLER_TAG});return}if(!Ie.tryAcquire(`/api/share/publish`)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A share publish operation is already in progress.`,{handler:SHARE_PUBLISH_HANDLER_TAG,extraHeaders:{"Retry-After":`5`}});return}try{let e=[`share`,`publish`,`--owner`,s.owner,`--name`,s.name,`--visibility`,s.visibility,`--project-dir`,me,`--json`];s.description!==void 0&&s.description.length>0&&e.push(`--description`,s.description);let{stdout:g}=await lu(e),S=parsePublishEvent(pickTerminalJsonLine(g));emitSharePublishLog(`publish-create`,S.ok?`ok`:S.error),S.ok&&de?.()?.refreshRemote().catch(()=>{}),successResponse(t,200,SharePublishResponseSchema,S,{handler:SHARE_PUBLISH_HANDLER_TAG})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:SHARE_PUBLISH_HANDLER_TAG,cause:e})}finally{Ie.release(SHARE_PUBLISH_KEY)}},{handler:SHARE_PUBLISH_HANDLER_TAG,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:SHARE_PUBLISH_HANDLER_TAG})}),pu=withValidation(ClientLogsRequestSchema,async(e,t,s)=>{try{let e=getLogger(`renderer`);for(let t of s.entries)try{e[t.level]({...t.fields,source:`renderer-console`,transport:`web`,...t.sourceId?{sourceId:t.sourceId}:{},...t.lineNumber===void 0?{}:{lineNumber:t.lineNumber},...t.ts===void 0?{}:{clientTs:t.ts}},t.event??t.message)}catch{}successResponse(t,200,ClientLogsSuccessSchema,{accepted:s.entries.length},{handler:`client-logs`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`client-logs`,cause:e})}},{handler:`client-logs`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`client-logs`})}),mu=me?getLocalDir(me):null;async function hu(e,t){if(e.method===`DELETE`){let s=e.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`api-config`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`api-config`});return}mu&&clearArmedPaneTarget(mu),t.setHeader(`Cache-Control`,`no-store`),t.statusCode=204,t.end();return}if(e.method===`GET`||e.method===`HEAD`){try{let s=e.headers.host,g={collabUrl:s?`ws://${s}/collab`:null,previewUrl:null,port:mu?readServerLock(mu)?.port??0:0,paneTarget:mu?readArmedPaneTarget(mu):null,singleFile:Pe};if(e.method===`HEAD`){t.setHeader(`Content-Type`,`application/json`),t.setHeader(`Cache-Control`,`no-store`),t.setHeader(`X-Content-Type-Options`,`nosniff`),t.statusCode=200,t.end();return}successResponse(t,200,ApiConfigSuccessSchema,g,{handler:`api-config`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`api-config`,cause:e})}return}errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`api-config`,extraHeaders:{Allow:`GET, HEAD, DELETE`}})}let gu=`local-op-embeddings-set-key`,_u=`local-op-embeddings-clear-key`,vu=`/api/local-op/embeddings`,yu=withValidation(LocalOpEmbeddingsSetKeyRequestSchema,async(e,t,s)=>{if(!Ie.tryAcquire(vu)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An embeddings key operation is already in progress.`,{handler:gu,extraHeaders:{"Retry-After":`5`}});return}try{await new FileEmbeddingsBackend(Me).set(s.key),successResponse(t,200,LocalOpEmbeddingsMutationSuccessSchema,{keyPresent:!0},{handler:gu,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to store the key.`,{handler:gu,cause:e})}finally{Ie.release(vu)}},{handler:gu,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:gu})}),bu=withValidation(EmptyRequestSchema,async(e,t)=>{if(!Ie.tryAcquire(vu)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An embeddings key operation is already in progress.`,{handler:_u,extraHeaders:{"Retry-After":`5`}});return}try{await clearEmbeddingsKeyFromAllBackends(Me),successResponse(t,200,LocalOpEmbeddingsMutationSuccessSchema,{keyPresent:!1},{handler:_u,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to clear the key.`,{handler:_u,cause:e})}finally{Ie.release(vu)}},{handler:_u,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:_u})}),xu=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=!1,s=!1,g=!1,S=0;if(De){let t=De.getStatus();e=t.enabled,s=t.ready,g=t.capable,S=t.embeddedCount}let E=await new FileEmbeddingsBackend(Me).get(),D=process.env.OK_EMBEDDINGS_API_KEY??null,O=E?`file`:D?`env`:null,k=O!==null,j=E??D,F=j&&j.length>=8?j.slice(-4):null,L=0;for(let[e]of w())!isSystemDoc(e)&&!isConfigDoc(e)&&!isHiddenDocName(e)&&(L+=1);successResponse(t,200,SemanticIndexStatusSchema,{enabled:e,keyPresent:k,keySource:O,keyHint:F,ready:s,capable:g,embedded:S,total:L},{handler:`semantic-status`,extraHeaders:{"Cache-Control":`no-store`}})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`semantic-status`,cause:e})}},{handler:`semantic-status`,method:`GET`,skipBodyParse:!0}),Su={"/api/config":hu,"/api/asset":mc,"/api/asset-text":gc,"/api/document":ka,"/api/documents":_s,"/api/backlinks":xs,"/api/backlink-counts":Cs,"/api/forward-links":Ts,"/api/link-graph":Ds,"/api/dead-links":As,"/api/orphans":Os,"/api/hubs":ks,"/api/tags":vl,"/api/pages":Ec,"/api/folder-config":Ol,"/api/template":Fl,"/api/templates":Pl,"/api/search":eu,"/api/semantic-status":xu,"/api/suggest-links":Dc,"/api/page-headings":Sc,"/api/create-page":yc,"/api/create-folder":bc,"/api/duplicate-path":xc,"/api/rename-path":Cc,"/api/delete-path":wc,"/api/trash/cleanup":Tc,"/api/upload":Oc,"/api/agent-write":Ki,"/api/agent-write-md":Yi,"/api/frontmatter-patch":Xi,"/api/agent-patch":Ns,"/api/agent-undo":Ps,"/api/agent-activity":Is,"/api/agent-burst-diff":Rs,"/api/save-version":rc,"/api/history":ic,"/api/rollback":oc,"/api/metrics/reconciliation":sc,"/api/metrics/parse-health":cc,"/api/metrics/agent-presence":dc,"/api/__embed-detect":fc,"/api/server-info":lc,"/api/share/construct-url":ou,"/api/git/branch-info":su,"/api/git/checkout":cu,"/api/share/publish/owners":uu,"/api/share/publish/name-check":du,"/api/share/publish":fu,"/api/principal":uc,"/api/rescue":vc,"/api/workspace":pc,"/api/sync/status":cl,"/api/sync/trigger":ll,"/api/sync/conflicts":ul,"/api/sync/conflict-content":fl,"/api/sync/resolve-conflict":dl,"/api/local-op/clone":Pc,"/api/local-op/ok-init":Rc,"/api/local-op/auth/login":Gc,"/api/local-op/auth/status":Jc,"/api/local-op/auth/repos":Xc,"/api/local-op/auth/signout":$c,"/api/local-op/auth/set-identity":al,"/api/local-op/embeddings/set-key":yu,"/api/local-op/embeddings/clear-key":bu,"/api/installed-agents":_l,"/api/spawn-cursor":au,"/api/handoff":iu,"/api/install-skill":gl,"/api/skill/install-state":ru,"/api/seed/plan":pl,"/api/seed/apply":ml,"/api/seed/packs":hl,"/api/client-logs":pu};j&&(Su[`/api/test-reset`]=ec,Su[`/api/test-flush-git`]=$s,Su[`/api/test-rescan-backlinks`]=tc,Su[`/api/test-rescan-files`]=nc);let Cu=new Set(`/api/upload./api/create-page./api/create-folder./api/duplicate-path./api/rename-path./api/delete-path./api/trash/cleanup./api/agent-write./api/agent-write-md./api/frontmatter-patch./api/agent-patch./api/agent-undo./api/save-version./api/rollback./api/sync/trigger./api/sync/resolve-conflict./api/git/checkout./api/test-reset./api/test-flush-git./api/test-rescan-backlinks./api/test-rescan-files./api/install-skill./api/folder-config./api/template./api/seed/apply./api/client-logs`.split(`.`)),wu=[`/api/local-op/`];return{priority:100,async onRequest({request:e,response:t}){let s=e.url?.split(`?`)[0];if(!s)return;let g=t=>{let s=e.headers[t];if(s!==void 0)return Array.isArray(s)?s.join(`, `):s};if(recordEmbedProbe({ts:Date.now(),url:s,method:e.method??``,ua:g(`user-agent`),origin:g(`origin`),referer:g(`referer`),host:g(`host`),remote:e.socket?.remoteAddress,secChUa:g(`sec-ch-ua`),secChUaMobile:g(`sec-ch-ua-mobile`),secChUaPlatform:g(`sec-ch-ua-platform`),secFetchSite:g(`sec-fetch-site`),secFetchDest:g(`sec-fetch-dest`),secFetchMode:g(`sec-fetch-mode`),secFetchUser:g(`sec-fetch-user`)}),s.startsWith(`/api/`)){let s=e.headers.origin;if(s!==void 0&&!isAllowedApiOrigin(s)){errorResponse(t,403,`urn:ok:error:invalid-origin`,`Origin not allowed.`,{handler:`api-origin-gate`});return}if(typeof t.setHeader==`function`&&(s!==void 0&&(t.setHeader(`Access-Control-Allow-Origin`,s),t.setHeader(`Vary`,`Origin`)),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, traceparent, tracestate, baggage, ${CLIENT_VERSION_HEADER.protocol}, ${CLIENT_VERSION_HEADER.runtime}, ${CLIENT_VERSION_HEADER.kind}`)),e.method===`OPTIONS`){t.writeHead(204),t.end();return}}if(Cu.has(s)||wu.some(e=>s.startsWith(e))){let s=e.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`api-mutating-gate`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`api-mutating-gate`});return}}if(Pe&&s.startsWith(`/api/`)){let s=e.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s)){errorResponse(t,403,`urn:ok:error:loopback-required`,`Loopback required.`,{handler:`api-ephemeral-gate`});return}if(!isAllowedWorkspaceHostHeader(e.headers.host)){errorResponse(t,403,`urn:ok:error:host-not-allowed`,`Host header not allowed.`,{handler:`api-ephemeral-gate`});return}}if(!s.startsWith(`/api/`))return;let S=propagation.extract(context.active(),e.headers),w=e.method??`GET`,E=s;s.startsWith(`/api/history/`)?E=`/api/history/:sha`:s.startsWith(`/api/tags/`)?E=`/api/tags/:name`:Su[s]||(E=`/api/*`);let D=getTracer(),O=Date.now();await context.with(S,()=>D.startActiveSpan(`HTTP ${w} ${E}`,{kind:SpanKind.SERVER,attributes:{[ATTR_HTTP_REQUEST_METHOD]:w,[ATTR_HTTP_ROUTE]:E,[ATTR_URL_PATH]:s,[ATTR_URL_SCHEME]:`http`,[ATTR_USER_AGENT_ORIGINAL]:e.headers[`user-agent`]??``}},async g=>{try{let S=Su[s],E=!1;if(S)E=!0,await S(e,t);else if(s.startsWith(`/api/history/`)){let g=decodeURIComponent(s.slice(13));g&&(E=!0,await ac(e,t,g))}else if(s.startsWith(`/api/tags/`)){let g=s.slice(10);g&&(E=!0,await yl(e,t,g))}E||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`api-dispatch`,detail:`No handler for ${w} ${s}`});let D=t.statusCode;g.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE,D),D>=500&&g.setStatus({code:SpanStatusCode.ERROR,message:`status ${D}`})}catch(e){throw g.recordException(e),g.setStatus({code:SpanStatusCode.ERROR,message:e instanceof Error?e.message:String(e)}),!t.headersSent&&!t.writableEnded&&!t.destroyed&&errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:E,cause:e}),e}finally{g.end();let e=(Date.now()-O)/1e3;httpDurationHist().record(e,{[ATTR_HTTP_REQUEST_METHOD]:w,[ATTR_HTTP_ROUTE]:E,[ATTR_HTTP_RESPONSE_STATUS_CODE]:t.statusCode})}}))}}}function isWithinDir(e,t){return e===t?!0:e.startsWith(`${t}${sep}`)}function errnoCode(e){let t=e?.code;return typeof t==`string`?t:void 0}function seedSingleDirBasenameIndex(e){let t;try{t=readdirSync(e.contentDir,{withFileTypes:!0})}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`read-failed`,s,e.contentDir);return}for(let s of t)s.isFile()&&isSupportedAssetFile(s.name,ASSET_EXTENSIONS)&&e.basenameIndex.add(s.name)}async function seedBasenameIndex(e){let t=e.contentDir,s=new Set;async function g(S){let w;try{w=await readdir(S,{withFileTypes:!0})}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`read-failed`,s,S);return}for(let E of w){let w=join(S,E.name),D=relative(t,w);if(D.startsWith(`..`)||e.contentFilter?.isDirExcluded(D)&&E.isDirectory())continue;let O;try{O=await lstat(w)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`lstat-failed`,s,w);continue}if(O.isSymbolicLink()){let S;try{S=await realpath(w)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`realpath-failed`,s,w);continue}if(!isWithinDir(S,t)){e.onSkip?.(`symlink-escape`,void 0,w);continue}let E;try{E=await stat$1(S)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`symlink-stat-failed`,s,S);continue}if(s.has(E.ino))continue;s.add(E.ino),E.isDirectory()?await g(S):E.isFile()&&isSupportedAssetFile(w,LINKABLE_ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D);continue}if(O.isDirectory()){if(s.has(O.ino))continue;s.add(O.ino),await g(w);continue}O.isFile()&&isSupportedAssetFile(w,LINKABLE_ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D)}}await g(t)}var AutoStartDisabledError=class extends Error{constructor(e){super(e),this.name=`AutoStartDisabledError`}};const log$5=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$5.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$5.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$5.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-BaZ9y3AC-CCCU9J5d.mjs`),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===void 0)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}case`delete`:await w.git.raw([`rm`,`--`,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$5.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(`
1707
1707
  `).map(e=>e.trim()).filter(Boolean);for(let t of e)this.addConflict({file:t,detectedAt:s});g=e.length>0}catch(e){log$5.warn({err:e},`[conflicts] commit failed and re-scan of unmerged files failed — falling back to single-file re-add`)}g||this.addConflict({file:e,detectedAt:s}),log$5.warn({err:t},`[conflicts] failed to commit merge after all conflicts resolved — unmerged files re-added`);let S=t instanceof Error?t.message:String(t);throw Error(`Merge commit failed after resolving ${e}; ${g?`unmerged files re-added`:`original file re-added`} — ${S}`,{cause:t})}}};const MIN_GIT_VERSION=`2.31.0`,PROBE_TIMEOUT_MS$1=5e3;var GitNotAvailableError=class extends Error{code=`GIT_NOT_AVAILABLE`;platform;guidance;constructor(e,t,s){super(buildMissingMessage(t),s),this.name=`GitNotAvailableError`,this.platform=e,this.guidance=t}},GitTooOldError=class extends Error{code=`GIT_TOO_OLD`;platform;detected;required;resolvedPath;guidance;constructor(e,t,s,g,S,w){super(buildTooOldMessage(t,s,g,S),w),this.name=`GitTooOldError`,this.platform=e,this.detected=t,this.required=s,this.resolvedPath=g,this.guidance=S}};function detectGit(){let e=probeGit(`git`);if(e.kind===`ok`)return{ok:!0,version:e.version,resolvedPath:e.resolvedPath,source:`PATH`};for(let e of fallbackPaths(process.platform)){if(!existsSync(e))continue;let t=probeGit(e);if(t.kind===`ok`)return{ok:!0,version:t.version,resolvedPath:e,source:`fallback`}}throw new GitNotAvailableError(process.platform,buildGuidance(process.platform))}function assertGitAvailable(){let e=detectGit();if(compareSemver(e.version,`2.31.0`)<0)throw new GitTooOldError(process.platform,e.version,MIN_GIT_VERSION,e.resolvedPath,buildGuidance(process.platform));return e}function probeGit(e){let t=spawnSync(e,[`--version`],{encoding:`utf-8`,timeout:PROBE_TIMEOUT_MS$1,env:{...process.env,LANG:`C`,LC_ALL:`C`}});if(t.error)return`signal`in t&&t.signal===`SIGTERM`?{kind:`fail`,reason:`timeout`}:{kind:`fail`,reason:`enoent`};if(t.status!==0)return{kind:`fail`,reason:`nonzero`};let s=parseGitVersion(typeof t.stdout==`string`?t.stdout:``);return s===null?{kind:`fail`,reason:`unparseable`}:{kind:`ok`,version:s,resolvedPath:e===`git`?resolveOnPath(`git`)??e:e}}function parseGitVersion(e){let t=e.match(/git version (\d+)\.(\d+)\.(\d+)/);return t?`${t[1]}.${t[2]}.${t[3]}`:null}const SAFE_COMMAND_NAME_RE=/^[a-zA-Z0-9_.-]+$/,resolveOnPathCache=new Map;function resolveOnPath(e){if(!SAFE_COMMAND_NAME_RE.test(e))return null;let t=resolveOnPathCache.get(e);if(t!==void 0)return t;let s;if(process.platform===`win32`){let t=spawnSync(`where`,[e],{encoding:`utf-8`,timeout:PROBE_TIMEOUT_MS$1});s=t.status===0&&(typeof t.stdout==`string`?t.stdout:``).trim().split(/\r?\n/)[0]||null}else{let t=spawnSync(`/bin/sh`,[`-c`,`command -v ${e}`],{encoding:`utf-8`,timeout:PROBE_TIMEOUT_MS$1});s=t.status===0&&(typeof t.stdout==`string`?t.stdout:``).trim().split(/\r?\n/)[0]||null}return s!==null&&resolveOnPathCache.set(e,s),s}function fallbackPaths(e){switch(e){case`darwin`:return[`/opt/homebrew/bin/git`,`/usr/local/bin/git`,`/Library/Developer/CommandLineTools/usr/bin/git`,`/usr/bin/git`];case`win32`:return[`C:\\Program Files\\Git\\cmd\\git.exe`,`C:\\Program Files (x86)\\Git\\cmd\\git.exe`,join(homedir(),`scoop`,`apps`,`git`,`current`,`cmd`,`git.exe`)];default:return[`/usr/bin/git`,`/usr/local/bin/git`,join(homedir(),`.local`,`bin`,`git`),`/snap/bin/git`]}}function buildGuidance(e){switch(e){case`darwin`:{let e=[];return hasBrew()&&e.push({label:`Install with Homebrew (recommended; no admin needed)`,command:`brew install git`,requiresAdmin:!1}),e.push({label:`Install Xcode Command Line Tools`,command:`xcode-select --install`,requiresAdmin:!0}),{product:`Git`,url:`https://git-scm.com/download/mac`,options:e}}case`win32`:{let e=[];return hasWinget()&&e.push({label:`Install with winget`,command:`winget install --id Git.Git -e --source winget`,requiresAdmin:!0}),hasScoop()&&e.push({label:`Install with Scoop (no admin)`,command:`scoop install git`,requiresAdmin:!1}),hasChoco()&&e.push({label:`Install with Chocolatey`,command:`choco install git -y`,requiresAdmin:!0}),e.push({label:`Download the official installer`,command:`Open https://gitforwindows.org/ in your browser`,requiresAdmin:!1}),{product:`Git for Windows`,url:`https://gitforwindows.org/`,options:e}}default:return{product:`Git`,url:`https://git-scm.com/download/linux`,options:linuxInstallOptions()}}}function linuxInstallOptions(){switch(detectLinuxFamily()){case`debian`:return[{label:`Install with apt`,command:`sudo apt install git`,requiresAdmin:!0}];case`fedora`:return[{label:`Install with dnf`,command:`sudo dnf install git`,requiresAdmin:!0}];case`arch`:return[{label:`Install with pacman`,command:`sudo pacman -S git`,requiresAdmin:!0}];case`opensuse`:return[{label:`Install with zypper`,command:`sudo zypper install git`,requiresAdmin:!0}];case`alpine`:return[{label:`Install with apk`,command:`sudo apk add git`,requiresAdmin:!0}];default:return[{label:`Use your distribution's package manager`,command:`apt / dnf / pacman / zypper / apk install git (one of these will fit your system)`,requiresAdmin:!0}]}}function detectLinuxFamily(e){let t=e;if(t===void 0)try{t=readFileSync(`/etc/os-release`,`utf-8`)}catch{return`unknown`}let s=[/^ID=(.+)$/m.exec(t)?.[1]?.replace(/["']/g,``),...(/^ID_LIKE=(.+)$/m.exec(t)?.[1]?.replace(/["']/g,``)??``).split(/\s+/)].filter(e=>!!e);return s.some(e=>/^(debian|ubuntu|mint|pop)$/i.test(e))?`debian`:s.some(e=>/^(fedora|rhel|centos|alma|rocky)$/i.test(e))?`fedora`:s.some(e=>/^(arch|manjaro|endeavouros)$/i.test(e))?`arch`:s.some(e=>/^opensuse/i.test(e))||s.includes(`suse`)?`opensuse`:s.some(e=>/^alpine$/i.test(e))?`alpine`:`unknown`}function hasCommand(e){return resolveOnPath(e)!==null}function hasBrew(){return hasCommand(`brew`)}function hasWinget(){return hasCommand(`winget`)}function hasScoop(){return hasCommand(`scoop`)}function hasChoco(){return hasCommand(`choco`)}function buildMissingMessage(e){let t=[];if(t.push(`Open Knowledge needs ${e.product} to track changes to your knowledge base, but it isn't installed (or isn't on PATH).`),t.push(``),e.options.length>0){t.push(`Install ${e.product}:`);for(let s of e.options){let e=s.requiresAdmin?` (admin required)`:``;t.push(` • ${s.label}${e}`),t.push(` ${s.command}`)}t.push(``)}return t.push(`Or download from: ${e.url}`),t.push(``),t.push(`After installing, re-run Open Knowledge.`),t.push("Run `ok diagnose health --check git` to verify your installation."),t.join(`
1708
1708
  `)}function buildTooOldMessage(e,t,s,g){let S=[];if(S.push(`Open Knowledge requires ${g.product} ${t} or newer (detected ${e} at ${s}).`),S.push(``),g.options.length>0){S.push(`Update ${g.product}:`);for(let e of g.options){let t=e.requiresAdmin?` (admin required)`:``;S.push(` • ${e.label}${t}`),S.push(` ${e.command}`)}S.push(``)}return S.push(`Or download from: ${g.url}`),S.push(``),S.push(`After updating, re-run Open Knowledge.`),S.push("Run `ok diagnose health --check git` to verify your installation."),S.join(`
1709
- `)}function compareSemver(e,t){let s=e.split(`.`).map(e=>Number.parseInt(e,10)||0),g=t.split(`.`).map(e=>Number.parseInt(e,10)||0);for(let e=0;e<3;e++){let t=s[e]??0,S=g[e]??0;if(t!==S)return t-S}return 0}const GIT_PREFLIGHT_FAIL_SPAN_NAME=`ok.preflight.git.fail`;function emitPreflightFailureSpan(e){let t=e instanceof GitTooOldError?`too_old`:`not_available`,s=e instanceof GitTooOldError?e.detected:``;withSpanSync(GIT_PREFLIGHT_FAIL_SPAN_NAME,{attributes:{"ok.platform":e.platform,"ok.preflight.git.reason":t,"ok.preflight.git.detected_version":s}},()=>{})}const DEFAULT_WARN_BEFORE_MS=300*1e3;function attachIdleShutdown(e){let t=e.scheduler??defaultScheduler,s=e.warnBeforeMs??DEFAULT_WARN_BEFORE_MS,g=0,S=null,w=null,E=!1,D=!1;function O(){S!==null&&(t.clearTimeout(S),S=null),w!==null&&(t.clearTimeout(w),w=null)}function k(){O(),!(D||E)&&g===0&&(s>0&&s<e.thresholdMs&&(w=t.setTimeout(()=>{w=null,g===0&&!E&&e.log?.warn({msUntilShutdown:s,webSocketClientCount:0},`idle shutdown pending: no WebSocket clients`)},e.thresholdMs-s)),S=t.setTimeout(()=>{if(S=null,!(D||E)&&g===0){E=!0,e.log?.info({webSocketClientCount:0},`idle shutdown firing`);try{let t=e.onShutdown();t&&typeof t.then==`function`&&t.catch(t=>{e.log?.error({err:t},`idle shutdown handler rejected`)})}catch(t){e.log?.error({err:t},`idle shutdown handler threw`)}}},e.thresholdMs))}let j=(e,t)=>{e.url?.startsWith(`/collab`)&&(g++,O(),t.once(`close`,()=>{g--,g<0&&(g=0),g===0&&k()}))};return e.httpServer.on(`upgrade`,j),k(),{detach:()=>{D||(D=!0,e.httpServer.off(`upgrade`,j),O())}}}function isObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function readRawSinkBlock(e){if(!existsSync(e))return{};let t;try{t=(0,import_dist$1.parse)(readFileSync(e,`utf-8`))}catch(t){return console.warn(`[telemetry.localSink] failed to parse ${e}; falling back to schema defaults — any explicit telemetry.localSink fields in this file are being ignored. Reason: ${t instanceof Error?t.message:String(t)}`),{}}if(!isObject(t))return{};let s=t.telemetry;if(!isObject(s))return{};let g=s.localSink;return isObject(g)?g:{}}function readBoolean(e){return typeof e==`boolean`?e:void 0}function readPositiveNumber(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?e:void 0}function readStringArray(e){if(Array.isArray(e)&&e.every(e=>typeof e==`string`))return e}function readMaxBytes(e){if(isObject(e))return readPositiveNumber(e.maxBytes)}function resolveLocalSinkConfig(e){if(process.env.OK_DISABLE_LOCAL_SINK===`1`||process.env.OK_DISABLE_LOCAL_SINK===`true`)return null;let t=readRawSinkBlock(resolveConfigPath(`project`,e.projectDir)),s=readRawSinkBlock(resolveConfigPath(`project-local`,e.projectDir));if((readBoolean(s.enabled)??readBoolean(t.enabled)??!0)===!1)return null;let g=readMaxBytes(s.spans)??readMaxBytes(t.spans)??52428800,S=readMaxBytes(s.logs)??readMaxBytes(t.logs)??26214400,w=readStringArray(s.attributeDenylist)??readStringArray(t.attributeDenylist)??DEFAULT_TELEMETRY_ATTRIBUTE_DENYLIST;return{telemetry:{projectDir:e.projectDir,spansMaxBytes:g,attributeDenylist:w},logs:{projectDir:e.projectDir,maxBytes:S}}}const MCP_SERVER_NAME=`open-knowledge`,MCP_CONNECTION_ID_HEADER=`x-ok-connection-id`;function sanitizeClientName(e,t){let s=Array.from(e??``).map(e=>{let t=e.charCodeAt(0);return t<=31||t===127?` `:e}).join(``).replace(/\s+/g,` `).trim();return s?s.slice(0,128):t}function buildInstructions(e){return"Open Knowledge is a markdown-CRDT knowledge base exposed via MCP.\n\n## STOP — native tools on in-scope `.md` / `.mdx`\n\nWhen this workspace has Open Knowledge MCP configured, do **not** use your host's native file tools on markdown paths inside the content directory. The ban covers every common rationalization:\n\n- **Native `Read` / `Grep` / `Glob` on in-scope `.md` / `.mdx`** — the original case.\n- **`Bash ls` / `Bash find` / `Bash cat` on dirs containing in-scope markdown** — use `exec(\"ls -A …\")` / `exec(\"find … -name '*.md'\")` / `exec(\"cat …\")` instead. Native returns bare names; `exec` returns frontmatter, backlink counts, and recent activity per child. `-A` shows hidden entries (`.ok/`, `.okignore`) which OK projects carry; omit `.` and `..` rows that `-a` would add.\n- **Glob patterns that target markdown** (`**/*.md`, any dir known to be markdown-heavy like `specs/**`, `reports/**`, `docs/**`) — use `exec` with `find`, or `exec(\"ls -A <dir>\")`.\n- **Dispatching the Explore / general-purpose subagent for markdown-heavy exploration** — subagents use native `Read` / `Grep` / `Glob` internally and bypass Open Knowledge entirely. Do markdown exploration yourself via `exec` / `search`. Subagents remain appropriate for **source-code** exploration.\n- **Native `Read` / `Grep` on any in-scope markdown inside `.ok/`** — the `.ok/` directory is in-scope; if it carries `.md` / `.mdx`, treat those the same as any other knowledge-base file.\n\nWhy: native tools skip frontmatter, backlinks, shadow-repo activity, and project git history that OK's tools return for every matched knowledge-base file. `exec` is the primary read surface; it runs read-only bash (`cat`, `ls`, `grep`, `find`, `head`, `tail`, `wc`, `sort`, `uniq`, `cut`) and returns raw stdout plus enriched metadata per file. One command or a pipe (`|`) per call — it is NOT a shell, so `&&` / `;` / redirects are rejected; list several dirs with `ls -A a b c` or make separate calls.\n\n**MCP tool visibility — not seeing `exec` is NOT the escape hatch.** MCP wiring varies by client. Claude Code, Cursor, Codex, Windsurf, VS Code — each surfaces MCP differently. Server labels are user-defined; tools may not appear as top-level symbols named `exec` in your specific UI. If Open Knowledge is registered as an MCP server in this workspace, route markdown reads through its `exec` / `search` via your client's documented MCP invocation (including any generic \"call MCP tool\" flow). Registration is the test, not top-level-symbol visibility.\n\n**Escape hatch.** Native `Read` / `Grep` / `Glob` on `.md` / `.mdx` is allowed **only** when no Open Knowledge MCP server is registered for this project, **or** immediately after you tried an MCP call and it failed — then begin a user-visible sentence with `Open Knowledge MCP unavailable:`. Never use the hatch because you skipped your client's MCP path, didn't see `exec` as a top-level tool, or rationalized the skill wasn't necessary.\n\n**Source code and non-markdown files** (`.ts`, `.py`, `package.json`, …): native `Read` / `Grep` / `Glob` always.\n\n## Reads — examples\n\n- Read a file: `exec(\"cat <path>.md\")` — contents + full rich enrichment.\n- List a directory: `exec(\"ls -A <dir>\")` — per-child frontmatter, recursive markdown counts, most-recently-updated doc per subdir, the folder's own `title`/`description`/`tags` + `templates_available`. Prefer `-A` over plain `ls` to surface dot-prefixed entries (`.ok/`, `.okignore`) without the noisy `.`/`..` rows that `-a` adds.\n- Literal search: `exec(\"grep -rn <term> <dir> | head -5\")` — matches + enrichment on matched files.\n- Ranked search: `search({ query })` — cmd-K parity (title boost + body BM25 + recency); use when picking the best doc, not when listing every occurrence.\n\n## Preview — open the browser at session start\n\nThe user watches your edits land in a live browser preview. Open it once at session start, then keep working. Re-navigate only when the user asks to open a different doc, or to land them on a finished deliverable (see below) — not to re-check your own edits.\n\n**End a turn on the deliverable, not your scratch space.** Keep the preview steady *during* a multi-doc task — don't yank it around to re-check your own edits. But when a turn created or substantially changed user-facing docs, navigate the preview to the primary deliverable before you hand back: the hub / overview / index page when you created several docs, or the changed doc when you changed one. Don't step the user through every supporting source card — the user is watching, so leave them on the result.\n\n**`previewUrl` is a route, not a URL to open.** Every read response (per-doc, on `exec` / `search` / `links` rows) and every write response carries a `previewUrl` — a route fragment like `/#/specs/foo/SPEC`, with **no scheme, host, or port**. It identifies *which doc* to preview, not a URL to hand a browser by itself. Never construct or guess preview URLs.\n\n**Pick how to open the preview by tool capability — not by host name.** Look at the tools actually available to you this session. If a tool can navigate to a URL, it counts as an in-app browser — match on the capability, not on what your host is called.\n\n- **You have `preview_*` tools** (e.g. `preview_start` + `preview_eval`) → **First open of the session:** to land directly on a doc, arm it first with `preview_url({ armPaneTarget: true, document })` (or `folder`), then `preview_start(\"open-knowledge-ui\")` — `ok ui` redirects the base-open straight to the armed route, so the pane opens on the doc, not root. Plain `preview_start` (no arm) opens at root. **Moving between docs once the pane is open: do it in one `preview_eval` step — set `window.location.hash` to the target's route fragment from the response `previewUrl`, the part from `#` on (e.g. `window.location.hash = '#/specs/foo/SPEC'`).** That drives the SPA router directly. Arm + `preview_start` only redirects a *fresh* open; it can't move an already-open pane (`preview_start` reuses the live process without reloading), so use `preview_eval` there. Don't read or edit `.claude/launch.json` — host-managed; the OK lock-collision proxy handles the UI-already-running case. If `preview_start` fails, report it; don't \"fix\" `launch.json`.\n- **No `preview_*` tool, but you have an in-app / built-in browser tool** — Codex's built-in browser, or any host tool that navigates to a URL (`browser`, `view_url`, `open_url`, `web.browse`, etc.) → call `preview_url` once for the **exact** target (`document` for a doc, `folder` for a folder) and navigate your **in-app browser** straight to the returned `url`. Open that deep URL directly — never the root then navigate. Omit both args only for the root.\n- **Truly no browser-capable tool — if you have ANY tool that navigates to a URL, use the in-app branch above** (a pure stdio host with no URL-navigation tool at all, e.g. the Claude Code CLI) → for an \"open `<doc>`/`<folder>`\" request, run **`ok open <doc>`** (`--folder` for a folder) — opens the doc in OK Desktop via deep link (folders in the browser), with browser fallback; an action, not a URL to print. No `ok` on PATH or no shell → `preview_url`, then `open <url>` in the system browser as a last resort, and say so plainly. The system browser is the fallback, never the default.\n- **Honor `autoOpen`** (on `preview_url`, or on `warning` for write tools). If `false`, do not open or refresh any preview UI; surface the URL only if asked.\n\n**Opening or reading a file IS a preview navigation.** On any \"open `<file>`\" / \"read `<file>`\" request, navigate the browser to that doc's `previewUrl` route from the tool response — not a separate fetch, not a fresh system-browser launch.\n\n**Four signals to check if the preview is already attached** (read these from each write response):\n\n1. You opened/navigated earlier this session → don't reopen.\n2. Write response has `previewUrl` (non-null route) and NO `warning` → a browser is attached somewhere; do nothing.\n3. `warning: { action: \"attach-preview-once\", previewUrl, message }` → UI reachable, no browser attached; navigate one-shot (`preview_start`, or `preview_url` → in-app browser).\n4. `warning: { action: \"start-ui\", previewUrl: null, message }` → no UI running anywhere. Surface the message verbatim — recovery options are in the in-band copy. Don't loop on retries.\n\nWarnings fire at most once per session in the fresh-start case.\n\n**`previewUrl: null` only means \"no UI reachable\" on the two attach-warning tools: `write` / `edit`.** Workflow tools return prose and don't carry `previewUrl`. `delete` / `move` emit `previousPreviewUrl` (different field, for closing stale tabs) and don't fire attach warnings. `preview_url` auto-starts the backend on demand (same `OK_MCP_AUTOSTART` gate as writes; a cold first call can take seconds) and reports `running: false` + `url: null` only when no UI could be reached — its hint names the right command.\n\nIf you see `\"Hocuspocus server is not running\"`, run `ok start` and retry.\n\nOK Electron and `ok ui` share `ui.lock`; when a second UI binds a different port, the OK lock-collision proxy bridges it to the live server transparently. That is exactly why `previewUrl` is route-only — the port behind the proxy is not the agent's to use. **Do not nudge the user to quit OK Electron to free a port** — the proxy handles it, and quitting tears down a UI in active use.\n\n**The preview is read-only for the agent — it is the user's view, not a surface you read back.** You cannot click or type to drive edits — the CRDT flow is one-way (agent → MCP → CRDT → preview).\n\n**No screenshots to confirm edits, no generic verification loop.** Do NOT take `preview_screenshot` (host tool, not OK MCP) after a write, and do not run a generic snapshot/eval/screenshot verification loop — OK's preview is a read-only, one-way mirror, so the CRDT tool response *is* the confirmation that an edit landed. Screenshot only when debugging a visual rendering issue or when the user explicitly asks to see the preview — never to confirm an edit landed. (Navigating the pane with `preview_eval` by setting `window.location.hash` is fine — that drives the view, it is not a read-back verification loop.)\n\n## Scope recap\n\nOpen Knowledge looks for documents under the resolved `content.dir` (discoverable at runtime via `config({ key: 'content.dir' })`). `.gitignore` and `.okignore` (at the project root and at any folder depth) define exclusions. A folder's own metadata + templates live in nested `<folder>/.ok/frontmatter.yml` + `<folder>/.ok/templates/` — NOT in `.ok/config.yml`.\n\nDefault mental model (no jargon): **every `.md` and `.mdx` under `content.dir`** not excluded by `.gitignore` or `.okignore` is an Open Knowledge document — including under `specs/`, `reports/`, `docs/`, etc. Read `.okignore` (and any nested `.okignore` files) once per turn to know what's excluded.\n\n**First session in this project?** If substantial folders have no frontmatter of their own and no `templates_available`, the project isn't onboarded — invoke `workflow({ kind: 'discover' })` before writing.\n\n**Working in a git worktree?** Pass the worktree's absolute path as `cwd` on your OK tool calls once — it sticks for the rest of the session, so reads, writes, and the preview all target that worktree instead of the main checkout. If a tool warns that it routed to the main checkout while you're in a worktree, passing `cwd` once is the fix.\n\n\nFull guidance lives in the bundled `open-knowledge` skill at `~/.ok/skills/open-knowledge/SKILL.md`.\n"}function installPrettyZodErrors(e){let t=e;if(t.__prettyZodErrorsInstalled===!0)return;let s=t.validateToolInput;if(typeof s!=`function`){console.warn(`[pretty-zod-errors] McpServer.validateToolInput not found — SDK internals may have changed. Falling back to default error formatting.`);return}t.validateToolInput=async function(e,t,g){if(!e.inputSchema||!isZodSchema(e.inputSchema))return s.call(this,e,t,g);let S=await e.inputSchema.safeParseAsync(t);if(S.success)return S.data;let w=prettifyError(S.error);throw new McpError(ErrorCode.InvalidParams,`Input validation error: Invalid arguments for tool ${g}:\n${w}`)},t.__prettyZodErrorsInstalled=!0}function isZodSchema(e){return typeof e!=`object`||!e?!1:typeof e.safeParseAsync==`function`}const loggerContext=new AsyncLocalStorage;var McpLogger=class e{sessionId;corrId;component;constructor(e=`mcp`,t){this.sessionId=t??randomUUID$1().slice(0,12),this.corrId=randomUUID$1().slice(0,8),this.component=e}info(e,t={}){this.emit(`info`,e,t)}warn(e,t={}){this.emit(`warn`,e,t)}error(e,t,s={}){let g=t?{error:t instanceof Error?t.message:String(t),...s}:s;this.emit(`error`,e,g)}debug(e,t={}){(process.env.MCP_DEBUG===`1`||process.env.DEBUG?.includes(`mcp`))&&this.emit(`debug`,e,t)}child(t){return new e(t??this.component,this.sessionId)}asCallback(){return e=>this.info(e)}emit(e,t,s){let g={ts:new Date().toISOString(),level:e,sessionId:this.sessionId,corrId:this.corrId,component:this.component,msg:t,...s},S=`${JSON.stringify(g)}\n`;process.stderr.write(S);let w=process.env.OK_LOG_FILE;if(w)try{appendFileSync(w,S)}catch(e){console.warn(`[mcp-logger] Failed to write to OK_LOG_FILE: ${e instanceof Error?e.message:e}`)}}};function runWithMcpLogger(e,t){return loggerContext.run(e,t)}function getCurrentMcpLogger(){return loggerContext.getStore()}const REDACTED_STRING_KEYS=new Set([`find`,`markdown`,`replace`]),COMMON_ARRAY_KEYS=[`backlinks`,`deadLinks`,`documents`,`enrichedPaths`,`entries`,`forwardLinks`,`hints`,`hubs`,`orphans`,`results`],COMMON_SCALAR_KEYS=[`checkpointRef`,`cwd`,`fileCount`,`matchCount`,`ok`,`query`,`stdoutTruncated`,`truncated`];function isPlainObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function isToolExtraLike(e){return isPlainObject(e)&&`requestId`in e}function summarizeStringForLog(e,t){if(REDACTED_STRING_KEYS.has(e))return{redacted:!0,type:`string`,length:t.length,lines:t.length===0?0:t.split(`
1709
+ `)}function compareSemver(e,t){let s=e.split(`.`).map(e=>Number.parseInt(e,10)||0),g=t.split(`.`).map(e=>Number.parseInt(e,10)||0);for(let e=0;e<3;e++){let t=s[e]??0,S=g[e]??0;if(t!==S)return t-S}return 0}const GIT_PREFLIGHT_FAIL_SPAN_NAME=`ok.preflight.git.fail`;function emitPreflightFailureSpan(e){let t=e instanceof GitTooOldError?`too_old`:`not_available`,s=e instanceof GitTooOldError?e.detected:``;withSpanSync(GIT_PREFLIGHT_FAIL_SPAN_NAME,{attributes:{"ok.platform":e.platform,"ok.preflight.git.reason":t,"ok.preflight.git.detected_version":s}},()=>{})}const DEFAULT_WARN_BEFORE_MS=300*1e3;function attachIdleShutdown(e){let t=e.scheduler??defaultScheduler,s=e.warnBeforeMs??DEFAULT_WARN_BEFORE_MS,g=0,S=null,w=null,E=!1,D=!1;function O(){S!==null&&(t.clearTimeout(S),S=null),w!==null&&(t.clearTimeout(w),w=null)}function k(){O(),!(D||E)&&g===0&&(s>0&&s<e.thresholdMs&&(w=t.setTimeout(()=>{w=null,g===0&&!E&&e.log?.warn({msUntilShutdown:s,webSocketClientCount:0},`idle shutdown pending: no WebSocket clients`)},e.thresholdMs-s)),S=t.setTimeout(()=>{if(S=null,!(D||E)&&g===0){E=!0,e.log?.info({webSocketClientCount:0},`idle shutdown firing`);try{let t=e.onShutdown();t&&typeof t.then==`function`&&t.catch(t=>{e.log?.error({err:t},`idle shutdown handler rejected`)})}catch(t){e.log?.error({err:t},`idle shutdown handler threw`)}}},e.thresholdMs))}let j=(e,t)=>{e.url?.startsWith(`/collab`)&&(g++,O(),t.once(`close`,()=>{g--,g<0&&(g=0),g===0&&k()}))};return e.httpServer.on(`upgrade`,j),k(),{detach:()=>{D||(D=!0,e.httpServer.off(`upgrade`,j),O())}}}function isObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function readRawSinkBlock(e){if(!existsSync(e))return{};let t;try{t=(0,import_dist$1.parse)(readFileSync(e,`utf-8`))}catch(t){return console.warn(`[telemetry.localSink] failed to parse ${e}; falling back to schema defaults — any explicit telemetry.localSink fields in this file are being ignored. Reason: ${t instanceof Error?t.message:String(t)}`),{}}if(!isObject(t))return{};let s=t.telemetry;if(!isObject(s))return{};let g=s.localSink;return isObject(g)?g:{}}function readBoolean(e){return typeof e==`boolean`?e:void 0}function readPositiveNumber(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?e:void 0}function readStringArray(e){if(Array.isArray(e)&&e.every(e=>typeof e==`string`))return e}function readMaxBytes(e){if(isObject(e))return readPositiveNumber(e.maxBytes)}function resolveLocalSinkConfig(e){if(process.env.OK_DISABLE_LOCAL_SINK===`1`||process.env.OK_DISABLE_LOCAL_SINK===`true`)return null;let t=readRawSinkBlock(resolveConfigPath(`project`,e.projectDir)),s=readRawSinkBlock(resolveConfigPath(`project-local`,e.projectDir));if((readBoolean(s.enabled)??readBoolean(t.enabled)??!0)===!1)return null;let g=readMaxBytes(s.spans)??readMaxBytes(t.spans)??52428800,S=readMaxBytes(s.logs)??readMaxBytes(t.logs)??26214400,w=readStringArray(s.attributeDenylist)??readStringArray(t.attributeDenylist)??DEFAULT_TELEMETRY_ATTRIBUTE_DENYLIST;return{telemetry:{projectDir:e.projectDir,spansMaxBytes:g,attributeDenylist:w},logs:{projectDir:e.projectDir,maxBytes:S}}}const MCP_SERVER_NAME=`open-knowledge`,MCP_CONNECTION_ID_HEADER=`x-ok-connection-id`;function sanitizeClientName(e,t){let s=Array.from(e??``).map(e=>{let t=e.charCodeAt(0);return t<=31||t===127?` `:e}).join(``).replace(/\s+/g,` `).trim();return s?s.slice(0,128):t}function buildInstructions(e){return"Open Knowledge is a markdown-CRDT knowledge base exposed via MCP.\n\n## STOP — native tools on in-scope `.md` / `.mdx`\n\nWhen this workspace has Open Knowledge MCP configured, do **not** use your host's native file tools on markdown paths inside the content directory. The ban covers every common rationalization:\n\n- **Native `Read` / `Grep` / `Glob` on in-scope `.md` / `.mdx`** — the original case.\n- **`Bash ls` / `Bash find` / `Bash cat` on dirs containing in-scope markdown** — use `exec(\"ls -A …\")` / `exec(\"find … -name '*.md'\")` / `exec(\"cat …\")` instead. Native returns bare names; `exec` returns frontmatter, backlink counts, and recent activity per child. `-A` shows hidden entries (`.ok/`, `.okignore`) which OK projects carry; omit `.` and `..` rows that `-a` would add.\n- **Glob patterns that target markdown** (`**/*.md`, any dir known to be markdown-heavy like `specs/**`, `reports/**`, `docs/**`) — use `exec` with `find`, or `exec(\"ls -A <dir>\")`.\n- **Dispatching the Explore / general-purpose subagent for markdown-heavy exploration** — subagents use native `Read` / `Grep` / `Glob` internally and bypass Open Knowledge entirely. Do markdown exploration yourself via `exec` / `search`. Subagents remain appropriate for **source-code** exploration.\n- **Native `Read` / `Grep` on any in-scope markdown inside `.ok/`** — the `.ok/` directory is in-scope; if it carries `.md` / `.mdx`, treat those the same as any other knowledge-base file.\n\nWhy: native tools skip frontmatter, backlinks, shadow-repo activity, and project git history that OK's tools return for every matched knowledge-base file. `exec` is the primary read surface; it runs read-only bash (`cat`, `ls`, `grep`, `find`, `head`, `tail`, `wc`, `sort`, `uniq`, `cut`) and returns raw stdout plus enriched metadata per file. One command or a pipe (`|`) per call — it is NOT a shell, so `&&` / `;` / redirects are rejected; list several dirs with `ls -A a b c` or make separate calls.\n\n**MCP tool visibility — not seeing `exec` is NOT the escape hatch.** MCP wiring varies by client. Claude Code, Cursor, Codex, Windsurf, VS Code — each surfaces MCP differently. Server labels are user-defined; tools may not appear as top-level symbols named `exec` in your specific UI. If Open Knowledge is registered as an MCP server in this workspace, route markdown reads through its `exec` / `search` via your client's documented MCP invocation (including any generic \"call MCP tool\" flow). Registration is the test, not top-level-symbol visibility.\n\n**Escape hatch.** Native `Read` / `Grep` / `Glob` on `.md` / `.mdx` is allowed **only** when no Open Knowledge MCP server is registered for this project, **or** immediately after you tried an MCP call and it failed — then begin a user-visible sentence with `Open Knowledge MCP unavailable:`. Never use the hatch because you skipped your client's MCP path, didn't see `exec` as a top-level tool, or rationalized the skill wasn't necessary.\n\n**Source code and non-markdown files** (`.ts`, `.py`, `package.json`, …): native `Read` / `Grep` / `Glob` always.\n\n## Reads — examples\n\n- Read a file: `exec(\"cat <path>.md\")` — contents + full rich enrichment.\n- List a directory: `exec(\"ls -A <dir>\")` — per-child frontmatter, recursive markdown counts, most-recently-updated doc per subdir, the folder's own `title`/`description`/`tags` + `templates_available`. Prefer `-A` over plain `ls` to surface dot-prefixed entries (`.ok/`, `.okignore`) without the noisy `.`/`..` rows that `-a` adds.\n- Literal search: `exec(\"grep -rn <term> <dir> | head -5\")` — matches + enrichment on matched files.\n- Ranked search: `search({ query })` — cmd-K parity (title boost + body BM25 + recency); use when picking the best doc, not when listing every occurrence.\n\n## Preview — open the browser at session start\n\nThe user watches your edits land in a live browser preview. Open it once at session start, then keep working. Re-navigate only when the user asks to open a different doc, or to land them on a finished deliverable (see below) — not to re-check your own edits.\n\n**End a turn on the deliverable, not your scratch space.** Keep the preview steady *during* a multi-doc task — don't yank it around to re-check your own edits. But when a turn created or substantially changed user-facing docs, navigate the preview to the primary deliverable before you hand back: the hub / overview / index page when you created several docs, or the changed doc when you changed one. Don't step the user through every supporting source card — the user is watching, so leave them on the result.\n\n**`previewUrl` is a route, not a URL to open.** Every read response (per-doc, on `exec` / `search` / `links` rows) and every write response carries a `previewUrl` — a route fragment like `/#/specs/foo/SPEC`, with **no scheme, host, or port**. It identifies *which doc* to preview, not a URL to hand a browser by itself. Never construct or guess preview URLs.\n\n**Pick how to open the preview by tool capability — not by host name.** Look at the tools actually available to you this session. If a tool can navigate to a URL, it counts as an in-app browser — match on the capability, not on what your host is called.\n\n- **You have `preview_*` tools** (e.g. `preview_start` + `preview_eval`) → **First open of the session:** to land directly on a doc, arm it first with `preview_url({ armPaneTarget: true, document })` (or `folder`), then `preview_start(\"open-knowledge-ui\")` — `ok ui` redirects the base-open straight to the armed route, so the pane opens on the doc, not root. Plain `preview_start` (no arm) opens at root. **Moving between docs once the pane is open: do it in one `preview_eval` step — set `window.location.hash` to the target's route fragment from the response `previewUrl`, the part from `#` on (e.g. `window.location.hash = '#/specs/foo/SPEC'`).** That drives the SPA router directly. Arm + `preview_start` only redirects a *fresh* open; it can't move an already-open pane (`preview_start` reuses the live process without reloading), so use `preview_eval` there. Don't read or edit `.claude/launch.json` — host-managed; the OK lock-collision proxy handles the UI-already-running case. If `preview_start` fails, report it; don't \"fix\" `launch.json`.\n- **No `preview_*` tool, but you have an in-app / built-in browser tool** — Codex's built-in browser, or any host tool that navigates to a URL (`browser`, `view_url`, `open_url`, `web.browse`, etc.) → call `preview_url` once for the **exact** target (`document` for a doc, `folder` for a folder) and navigate your **in-app browser** straight to the returned `url`. Open that deep URL directly — never the root then navigate. Omit both args only for the root.\n- **Truly no browser-capable tool — if you have ANY tool that navigates to a URL, use the in-app branch above** (a pure stdio host with no URL-navigation tool at all, e.g. the Claude Code CLI) → for an \"open `<doc>`/`<folder>`\" request, run **`ok open <doc>`** (`--folder` for a folder) — opens the doc in OK Desktop via deep link (folders in the browser), with browser fallback; an action, not a URL to print. No `ok` on PATH or no shell → `preview_url`, then `open <url>` in the system browser as a last resort, and say so plainly. The system browser is the fallback, never the default.\n- **Honor `autoOpen`** (on `preview_url`, or on `warning` for write tools). If `false`, do not open or refresh any preview UI; surface the URL only if asked.\n\n**Opening or reading a file IS a preview navigation.** On any \"open `<file>`\" / \"read `<file>`\" request, navigate the browser to that doc's `previewUrl` route from the tool response — not a separate fetch, not a fresh system-browser launch.\n\n**Four signals to check if the preview is already attached** (read these from each write response):\n\n1. You opened/navigated earlier this session → don't reopen.\n2. Write response has `previewUrl` (non-null route) and NO `warning` → a browser is attached somewhere; do nothing.\n3. `warning: { action: \"attach-preview-once\", previewUrl, message }` → UI reachable, no browser attached; navigate one-shot (`preview_start`, or `preview_url` → in-app browser).\n4. `warning: { action: \"start-ui\", previewUrl: null, message }` → no UI running anywhere. Surface the message verbatim — recovery options are in the in-band copy. Don't loop on retries.\n\nWarnings fire at most once per session in the fresh-start case.\n\n**Re-point at the end of a multi-doc workflow; don't claim a doc is on screen unless you put it there.** The one-shot attach (signal 3) opens the preview *once* — later writes do NOT move the pane; it stays on the doc you last navigated to. When a turn touches several docs, finish by navigating the preview to the doc the user should land on, using your host's move mechanism (`preview_eval` setting `window.location.hash` from the response `previewUrl`, or `preview_url` → in-app browser; honor `autoOpen`). Until you have navigated there *this* turn, don't tell the user a doc is \"open\" / \"on screen\" — at most, say the preview may still be on the doc you opened earlier.\n\n**`previewUrl: null` only means \"no UI reachable\" on the two attach-warning tools: `write` / `edit`.** Workflow tools return prose and don't carry `previewUrl`. `delete` / `move` emit `previousPreviewUrl` (different field, for closing stale tabs) and don't fire attach warnings. `preview_url` auto-starts the backend on demand (same `OK_MCP_AUTOSTART` gate as writes; a cold first call can take seconds) and reports `running: false` + `url: null` only when no UI could be reached — its hint names the right command.\n\nIf you see `\"Hocuspocus server is not running\"`, run `ok start` and retry.\n\nOK Electron and `ok ui` share `ui.lock`; when a second UI binds a different port, the OK lock-collision proxy bridges it to the live server transparently. That is exactly why `previewUrl` is route-only — the port behind the proxy is not the agent's to use. **Do not nudge the user to quit OK Electron to free a port** — the proxy handles it, and quitting tears down a UI in active use.\n\n**The preview is read-only for the agent — it is the user's view, not a surface you read back.** You cannot click or type to drive edits — the CRDT flow is one-way (agent → MCP → CRDT → preview).\n\n**No screenshots to confirm edits, no generic verification loop.** Do NOT take `preview_screenshot` (host tool, not OK MCP) after a write, and do not run a generic snapshot/eval/screenshot verification loop — OK's preview is a read-only, one-way mirror, so the CRDT tool response *is* the confirmation that an edit landed. Screenshot only when debugging a visual rendering issue or when the user explicitly asks to see the preview — never to confirm an edit landed. (Navigating the pane with `preview_eval` by setting `window.location.hash` is fine — that drives the view, it is not a read-back verification loop.)\n\n## Scope recap\n\nOpen Knowledge looks for documents under the resolved `content.dir` (discoverable at runtime via `config({ key: 'content.dir' })`). `.gitignore` and `.okignore` (at the project root and at any folder depth) define exclusions. A folder's own metadata + templates live in nested `<folder>/.ok/frontmatter.yml` + `<folder>/.ok/templates/` — NOT in `.ok/config.yml`.\n\nDefault mental model (no jargon): **every `.md` and `.mdx` under `content.dir`** not excluded by `.gitignore` or `.okignore` is an Open Knowledge document — including under `specs/`, `reports/`, `docs/`, etc. Read `.okignore` (and any nested `.okignore` files) once per turn to know what's excluded.\n\n**First session in this project?** If substantial folders have no frontmatter of their own and no `templates_available`, the project isn't onboarded — invoke `workflow({ kind: 'discover' })` before writing.\n\n**Working in a git worktree?** Pass the worktree's absolute path as `cwd` on your OK tool calls once — it sticks for the rest of the session, so reads, writes, and the preview all target that worktree instead of the main checkout. If a tool warns that it routed to the main checkout while you're in a worktree, passing `cwd` once is the fix.\n\n\nFull guidance lives in the bundled `open-knowledge` skill at `~/.ok/skills/open-knowledge/SKILL.md`.\n"}function installPrettyZodErrors(e){let t=e;if(t.__prettyZodErrorsInstalled===!0)return;let s=t.validateToolInput;if(typeof s!=`function`){console.warn(`[pretty-zod-errors] McpServer.validateToolInput not found — SDK internals may have changed. Falling back to default error formatting.`);return}t.validateToolInput=async function(e,t,g){if(!e.inputSchema||!isZodSchema(e.inputSchema))return s.call(this,e,t,g);let S=await e.inputSchema.safeParseAsync(t);if(S.success)return S.data;let w=prettifyError(S.error);throw new McpError(ErrorCode.InvalidParams,`Input validation error: Invalid arguments for tool ${g}:\n${w}`)},t.__prettyZodErrorsInstalled=!0}function isZodSchema(e){return typeof e!=`object`||!e?!1:typeof e.safeParseAsync==`function`}const loggerContext=new AsyncLocalStorage;var McpLogger=class e{sessionId;corrId;component;constructor(e=`mcp`,t){this.sessionId=t??randomUUID$1().slice(0,12),this.corrId=randomUUID$1().slice(0,8),this.component=e}info(e,t={}){this.emit(`info`,e,t)}warn(e,t={}){this.emit(`warn`,e,t)}error(e,t,s={}){let g=t?{error:t instanceof Error?t.message:String(t),...s}:s;this.emit(`error`,e,g)}debug(e,t={}){(process.env.MCP_DEBUG===`1`||process.env.DEBUG?.includes(`mcp`))&&this.emit(`debug`,e,t)}child(t){return new e(t??this.component,this.sessionId)}asCallback(){return e=>this.info(e)}emit(e,t,s){let g={ts:new Date().toISOString(),level:e,sessionId:this.sessionId,corrId:this.corrId,component:this.component,msg:t,...s},S=`${JSON.stringify(g)}\n`;process.stderr.write(S);let w=process.env.OK_LOG_FILE;if(w)try{appendFileSync(w,S)}catch(e){console.warn(`[mcp-logger] Failed to write to OK_LOG_FILE: ${e instanceof Error?e.message:e}`)}}};function runWithMcpLogger(e,t){return loggerContext.run(e,t)}function getCurrentMcpLogger(){return loggerContext.getStore()}const REDACTED_STRING_KEYS=new Set([`find`,`markdown`,`replace`]),COMMON_ARRAY_KEYS=[`backlinks`,`deadLinks`,`documents`,`enrichedPaths`,`entries`,`forwardLinks`,`hints`,`hubs`,`orphans`,`results`],COMMON_SCALAR_KEYS=[`checkpointRef`,`cwd`,`fileCount`,`matchCount`,`ok`,`query`,`stdoutTruncated`,`truncated`];function isPlainObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function isToolExtraLike(e){return isPlainObject(e)&&`requestId`in e}function summarizeStringForLog(e,t){if(REDACTED_STRING_KEYS.has(e))return{redacted:!0,type:`string`,length:t.length,lines:t.length===0?0:t.split(`
1710
1710
  `).length};let s=e===`command`?240:120;return t.length<=s?t:{type:`string`,length:t.length,preview:`${t.slice(0,s)}...`}}function summarizeArgValue(e,t){if(t===null)return null;if(typeof t==`string`)return summarizeStringForLog(e,t);if(typeof t==`number`||typeof t==`boolean`)return t;if(Array.isArray(t))return{type:`array`,length:t.length};if(isPlainObject(t)){let e=Object.keys(t).sort();return{type:`object`,keyCount:e.length,keys:e.slice(0,12)}}if(t!==void 0)return{type:typeof t}}function summarizeArgsForLog(e,t){return isPlainObject(t)?Object.fromEntries(Object.entries(t).map(([e,t])=>[e,summarizeArgValue(e,t)])):summarizeArgValue(e,t)}function summarizeStructuredContentForLog(e){let t={structuredKeys:Object.keys(e).sort()};for(let s of COMMON_SCALAR_KEYS)s in e&&(t[s]=e[s]);for(let s of COMMON_ARRAY_KEYS){let g=e[s];Array.isArray(g)&&(t[`${s}Count`]=g.length)}return`previewUrl`in e&&(t.previewUrl=e.previewUrl??null),`previewUrlSource`in e&&(t.previewUrlSource=e.previewUrlSource),Array.isArray(e.warnings)&&(t.warningsCount=e.warnings.length),isPlainObject(e.warning)&&(t.warning=!0,`previewUrl`in e.warning&&(t.warningPreviewUrl=e.warning.previewUrl??null)),t}function summarizeToolResultForLog(e){if(!isPlainObject(e))return{resultType:typeof e};let t={isError:e.isError===!0};return Array.isArray(e.content)&&(t.contentItems=e.content.length,t.contentTextChars=e.content.reduce((e,t)=>isPlainObject(t)&&typeof t.text==`string`?e+t.text.length:e,0)),isPlainObject(e.structuredContent)&&Object.assign(t,summarizeStructuredContentForLog(e.structuredContent)),t}function summarizeIdentityForLog(e){return{connectionId:e.connectionId.slice(0,8),displayName:e.displayName,...e.clientInfo?.name?{clientName:e.clientInfo.name}:{}}}function splitInvocationArgs(e){let t=e.at(-1);return isToolExtraLike(t)?{toolArgs:e.length>1?e[0]:void 0,extra:t}:{toolArgs:e[0],extra:void 0}}function wrapToolHandlerForLogging(e,t,s){let g=s.logger;return g?async(...S)=>{let w=g.child(),E=Date.now(),{toolArgs:D,extra:O}=splitInvocationArgs(S);w.info(`tool start`,{tool:e,...O?.requestId===void 0?{}:{requestId:O.requestId},...O?.sessionId?{transportSessionId:O.sessionId}:{},...s.identityRef?.current?{agent:summarizeIdentityForLog(s.identityRef.current)}:{},...D===void 0?{}:{args:summarizeArgsForLog(e,D)}});try{let s=await runWithMcpLogger(w,async()=>await t(...S));return w.info(`tool finish`,{tool:e,...O?.requestId===void 0?{}:{requestId:O.requestId},durationMs:Date.now()-E,result:summarizeToolResultForLog(s)}),s}catch(t){throw w.error(`tool error`,t,{tool:e,...O?.requestId===void 0?{}:{requestId:O.requestId},durationMs:Date.now()-E}),t}}:t}function createLoggedServer(e,t){if(!t.logger)return e;let s=e.tool.bind(e),g=e.registerTool,S=typeof g==`function`?g.bind(e):void 0,w=Object.create(e);return w.tool=((...e)=>{let g=String(e[0]),S=e.at(-1);if(typeof S!=`function`)return s(...e);let w=[...e];return w[w.length-1]=wrapToolHandlerForLogging(g,S,t),s(...w)}),S&&(w.registerTool=((e,s,g)=>typeof g==`function`?S(e,s,wrapToolHandlerForLogging(e,g,t)):S(e,s,g))),w}const DESCRIPTION$16=[`[Requires: Hocuspocus server] Save a project-wide checkpoint of every document — a single restore point you can return to.`,``,`**Parameters:**`,'- `summary` — Optional one-line label for the checkpoint (≤80 chars). Defaults to "Checkpoint version". Appears as the checkpoint subject in `history`. Avoid secrets or PII — persisted to git history.',``,"Returns `{ version }` — the 40-char checkpoint SHA. Find checkpoints later via `history`; restore a single doc with `restore_version({ document, version })`."].join(`
1711
1711
  `);function register$16(e,t){e.registerTool(`checkpoint`,{description:DESCRIPTION$16,inputSchema:{summary:summaryArgSchema.describe(`Optional one-line label for the checkpoint (≤80 chars). Defaults to "Checkpoint version". Persisted to git history.`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},outputSchema:outputSchemaWithText({version:string().describe(VERSION_FIELD_DESCRIBE),previewUrl:previewUrlOutputField.describe(`Always null — a checkpoint is project-wide, not scoped to one doc.`)})},async e=>{let s=await resolveProjectServerContext(t.resolveCwd,t.config,t.serverUrl,e.cwd);if(!s.ok)return textResult(`Error: ${s.error}`,!0);let{url:g}=s;if(!g)return textResult(HOCUSPOCUS_NOT_RUNNING_ERROR,!0);let S=t.identityRef?.current,w=await httpPost(g,`/api/save-version`,{...e.summary===void 0?{}:{summary:e.summary},...S?{writers:[{id:`agent-${S.connectionId}`,name:S.displayName,email:`agent-${S.connectionId}@openknowledge.local`}]}:{}});if(!w.ok)return textResult(`Error: ${w.error}`,!0);let E=typeof w.checkpointRef==`string`?w.checkpointRef:``,D=E.split(`/`).pop()??``;return/^[0-9a-f]{40}$/i.test(D)?textPlusStructured(`Checkpoint saved. Version: ${D}`,{version:D,previewUrl:null}):textResult(`Error: checkpoint committed but the server returned no usable version ref ("${E}"). Find the latest checkpoint via \`history\`.`,!0)})}const DESCRIPTION$15=[`[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 `key` is provided. There is no allowlist on reads — every field is readable.",``,"Note: the `server.*`, `mcp.*`, and `github.*` config sub-trees, plus `preview.baseUrl` and `preview.scriptSrc`, were removed; their values are now built-in constants in `@inkeep/open-knowledge-core` (or, for the preview iframe, a fixed open network policy). Reading those keys returns `exists: false`. (`appearance.preview.autoOpen` is still a live key.)",``,`**Parameters:**`,'- `key` (optional) — Dotted config key. `"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(`
1712
1712
  `),InputSchema$3={key:string().optional().describe(`Dotted config key (e.g. "appearance.theme"). Omit to return the full merged config.`),cwd:string().optional().describe(ROUTED_CWD_DESCRIPTION)},OutputSchema$5=outputSchemaWithText({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". Always emitted — `true` on a full-config read.'),key:string().optional().describe(`Echo of the requested dotted key (absent 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$15(e,t){e.registerTool(`config`,{description:DESCRIPTION$15,inputSchema:InputSchema$3,outputSchema:OutputSchema$5,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.key?e.key.split(`.`).filter(e=>e.length>0):[],S=g.length>0?readConfigPath(s.config,g):s.config;return g.length>0&&S===void 0?textPlusStructured(`(no value at ${e.key})`,{value:null,exists:!1,...e.key?{key:e.key}:{}}):textPlusStructured(JSON.stringify(S,null,2),{value:S,exists:!0,...e.key?{key:e.key}:{}})})}const DESCRIPTION$14=["[Requires: Hocuspocus server] Read GitHub-sync merge conflicts. Dispatches on `kind`:",``,'- `kind: "list"` — enumerate every doc currently tracked in a merge-conflict state. Returns `{ list: [{ file, detectedAt, ... }] }` (empty when none). The entry point to the resolve flow.','- `kind: "content"` — fetch the three merge stages for one `file`. Returns `{ content: { file, base, ours, theirs, shape, lifecycleStatus } }`. `ours` reflects the live Y.Text (what the human sees) when the doc is loaded server-side.',``,`**Parameters:**`,"- `kind` — `list` | `content`.",'- `file` — Required for `kind: "content"`. Relative path WITH the `.md`/`.mdx` extension (e.g. `notes/sso.md`) — git stages key on the exact path, so do NOT strip the extension.',``,"The `shape` field discriminates the conflict: `both-modified` (both sides edited), `delete-modify` (you deleted, they edited — `ours` empty), or `modify-delete` (you edited, they deleted — `theirs` empty). Use it to pick the `resolve_conflict` strategy."].join(`
@@ -2829,4 +2829,4 @@ In headless mode, write the recap into the research article's "Further reading"
2829
2829
  `))e&&await t.raw(`update-ref`,`-d`,e);Y.info({context:e.oldBranch},`[branch-switch] cleaned up detached context ${e.oldBranch}`)}}catch(e){Y.error({err:e},`[branch-switch] detached cleanup failed`)}setBatchInProgress(!1),await ye.flushDeferredStores(`discard-stale`),Te?.emitBranchSwitched(g)}if(e.headMoved&&e.newHead&&_e.current&&s>0){let t=L??`.`;try{let s=await commitUpstreamImport(_e.current,t,e.oldHead,e.newHead,g);incrementUpstreamImport(),Y.info({oldHead:e.oldHead?.slice(0,8)??`null`,newHead:e.newHead.slice(0,8),sha:s.slice(0,8)},`[history] upstream-import from ${e.oldHead?.slice(0,8)??`null`}..${e.newHead.slice(0,8)} → ${s.slice(0,8)}`)}catch(e){Y.error({err:e},`[shadow] upstream-import failed`)}}})}catch(e){Y.error({err:e},`[server] HEAD watcher failed to start`),Fr.push(`head-watcher`)}function D(e){for(let g of e)try{let e=relative(t,join(s,g));if(e.startsWith(`..`))continue;let S=stripDocExtension(e),w=Ce.documents.get(S);if(!w)continue;let E=jt(S);E===null?Y.warn({docName:S,file:g},`[sync] content conflict: serializeDoc returned null; reconciledBase snapshot skipped`):setReconciledBase(S,E);let D=w.getMap(`lifecycle`);D.set(`status`,`conflict`),D.set(`reason`,`sync-merge-conflict`),Y.info({docName:S,file:g},`[sync] marked loaded content conflict`)}catch(e){Y.warn({err:e,file:g},`[sync] failed to mark loaded content conflict`)}}let O=buildSyncCredentialArgs(H);try{$t=new SyncEngine({projectDir:s,contentDir:t,contentFilter:fe,contentRoot:L,syncEnabled:te(),credentialArgs:O,cc1Broadcaster:Te,detectGh:e.detectGh,tokenStore:e.tokenStore,checkPushPermissionFn:e.checkPushPermissionFn,setBatchInProgress:e=>{setBatchInProgress(e),e||ye.flushDeferredStores(`within-branch`).catch(e=>{Y.error({err:e},`[persistence] deferred store drain failed after sync batch`)})},onStateChange:e=>{Y.info({state:e},`[sync] state → ${e}`)},onContentConflictsDetected:D,onAutoDisable:async e=>{Y.warn({reason:e},`[sync] auto-disabled — persisting to project-local config`);let t=await writeConfigPatch({cwd:s,scope:`project-local`,patch:{autoSync:{enabled:!1}}});t.ok||Y.error({result:t,reason:e,humanError:humanFormat(t.error),configPath:resolveConfigPath(`project-local`,s)},`[sync] failed to persist auto-disable — next restart WILL re-enable sync and re-trigger the same failure. Check permissions on the config path.`)}}),await $t.start()}catch(e){Y.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),$t=null}Ke(`files`),Ke(`backlinks`),Ke(`graph`),Ke(`tags`)}return Ir().then(Ue,We),{hocuspocus:Ce,sessionManager:we,cc1Broadcaster:Te,agentFocusBroadcaster:De,agentPresenceBroadcaster:je,maintenanceCoordinator:ve,contentFilter:fe,basenameIndex:ce,serverInstanceId:oe,destroy:Mr,ready:Ge,degraded:Fr,lockDir:se,get syncEngine(){return $t}}}const SERVER_MEMORY_SCHEMA_VERSION=1,BYTES_PER_MB=1024*1024;function toMb(e){return e/BYTES_PER_MB}function captureServerMemorySnapshot(){let e=process.memoryUsage();return{schemaVersion:SERVER_MEMORY_SCHEMA_VERSION,capturedAt:new Date().toISOString(),snapshot:{rssMb:toMb(e.rss),heapTotalMb:toMb(e.heapTotal),heapUsedMb:toMb(e.heapUsed),externalMb:toMb(e.external),arrayBuffersMb:toMb(e.arrayBuffers)}}}let cachedGauge=null;onTelemetryShutdown(()=>{cachedGauge=null});function installServerMemoryGauge(){if(cachedGauge)return;let e=getMeter().createObservableGauge(`ok.server.memory.usage_megabytes`,{description:`Server process memory by section. Bounded labels: section ∈ {heap_used, heap_total, rss}.`,unit:`MB`});e.addCallback(e=>{let{snapshot:t}=captureServerMemorySnapshot();e.observe(t.heapUsedMb,{section:`heap_used`}),e.observe(t.heapTotalMb,{section:`heap_total`}),e.observe(t.rssMb,{section:`rss`})}),cachedGauge=e}const TELEMETRY_FILENAME=`tolerance-telemetry.jsonl`,TELEMETRY_PREV_FILENAME=`tolerance-telemetry.prev.jsonl`,TELEMETRY_MAX_BYTES=8*1024*1024;let appender=null,appendFailureWarned=!1;function isToleranceTelemetryEnabled(e=process.env){return e.OK_BRIDGE_TOLERANCE_TELEMETRY===`1`}function initToleranceTelemetryWriter(e){if(!isToleranceTelemetryEnabled())return;let t=getLocalDir(e);appender=new RotatingAppender({currentPath:resolve(t,TELEMETRY_FILENAME),previousPath:resolve(t,TELEMETRY_PREV_FILENAME),maxBytes:TELEMETRY_MAX_BYTES}),setToleranceTelemetryHook(e=>{let t={event:`bridge-tolerance-fire`,timestamp:e.timestamp,class:e.className,document:e.documentName??null,codeUnitPosition:e.codeUnitPosition,severity:e.severity};appender?.append(`${JSON.stringify(t)}\n`).catch(e=>{appendFailureWarned||(appendFailureWarned=!0,console.warn(`[tolerance-telemetry] append failed; further failures are silent:`,e instanceof Error?e.message:String(e)))})})}async function teardownToleranceTelemetryWriter(){setToleranceTelemetryHook(null),await appender?.drain(),appender=null,appendFailureWarned=!1}const LEGACY_RUNTIME_FILENAMES=[`server.lock`,`ui.lock`,`state.json`,`principal.json`,`sync-state.json`,`conflicts.json`,`last-spawn-error.log`],LEGACY_RUNTIME_DIRNAMES=[`cache`,`tmp`];function findLegacyRuntimeFiles(e){let t=resolve(e,LOCAL_DIR);if(!(()=>{if(!existsSync(t))return!0;try{return readdirSync(t).length===0}catch{return!0}})())return[];let s=[];for(let t of LEGACY_RUNTIME_FILENAMES)existsSync(resolve(e,t))&&s.push(t);for(let t of LEGACY_RUNTIME_DIRNAMES){let g=resolve(e,t);try{existsSync(g)&&statSync(g).isDirectory()&&s.push(`${t}/`)}catch{}}return s}function computeWorktreeAttributes(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return{kind:`main`,gitdir:t.path};case`linked`:return{kind:`linked`,gitdir:t.path};case`malformed-pointer`:return{kind:`linked`,gitdir:null};case`inaccessible`:case`absent`:return{kind:`main`,gitdir:null}}}const DEFAULT_IDLE_THRESHOLD_MS=1800*1e3,DESTROY_STEP_TIMEOUT_MS=5e3,PINO_REDACT_MAX_DEPTH=5;async function bootServer(e){let t=e.projectDir??e.contentDir,s=resolveLocalSinkConfig({projectDir:t});if(s){let e=s.telemetry.attributeDenylist,t=[];for(let s of e){t.push(s);for(let e=1;e<=PINO_REDACT_MAX_DEPTH;e++)t.push(`${`*.`.repeat(e)}${s}`)}loggerFactory.configure({pinoConfig:{fileSink:s.logs,redactPaths:t}})}initTelemetry({localSink:s?.telemetry}),initToleranceTelemetryWriter(t),installServerMemoryGauge();let{kind:g,gitdir:S}=computeWorktreeAttributes(e.projectDir??e.contentDir),w={"ok.worktree.kind":g};return S!==null&&(w[`ok.worktree.gitdir`]=normalizeFsPath(S)),withSpan(`ok.boot`,{attributes:w},async()=>bootServerInner(e))}async function bootServerInner(e){let t=e.skipAutoInit??!1,s=e.attachUiSibling??!0,g=e.idleShutdownMs,S=e.log??getLogger(`boot`),w=process.env.OK_LOCK_KIND===`mcp-spawned`||process.env.OK_LOCK_KIND===`interactive`?process.env.OK_LOCK_KIND:void 0,E=e.lockKind??w??`interactive`,{createServer:D}=await import(`node:http`),{updateServerLockPort:O}=await import(`./server-lock-CyhBidkz-BOUYNO6u.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(`
2830
2830
  `).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/
2831
2831
  `,`utf-8`),t}export{STARTER_TEMPLATES as $,withFileLockSync as $i,isProjectRoot as $n,runCloneSubprocess as $r,createMcpHttpHandler as $t,LIVE_DERIVED_INDEX_DEBOUNCE_MS as A,tracedUnlinkSync as Ai,getMeter as An,readUiLock as Ar,clearArmedPaneTarget as At,OBSERVER_SYNC_ORIGIN as B,writeRootGitignoreForNewRepo as Bi,initTelemetry as Bn,resolveContentDir as Br,contributorCount as Bt,GIT_UPSTREAM_WRITER as C,tracedLinkSync as Ci,formatContributorsFrom as Cn,readBranchFromHead as Cr,buildExecResult as Ct,HocuspocusAuthRejection as D,tracedRenameSync as Di,getLogFilePath as Dn,readStateManifest as Dr,buildWipTree as Dt,HOCUSPOCUS_AUTH_REJECTION_REASONS as E,tracedRename as Ei,getLocalDir as En,readSkillInstallStateSnapshot as Er,buildStarterFolderFrontmatterYaml as Et,MCP_SERVER_NAME as F,validateAgentId as Fi,hasGcLogLatch as Fn,registerWrite as Fr,commitWip as Ft,ROLLBACK_ORIGIN as G,JSONRPCMessageSchema as Gi,isAllowedApiOrigin as Gn,resolvePackageVersion as Gr,createAssetServeMiddleware as Gt,PANE_TARGET_TTL_MS as H,writeTargetVersion as Hi,installPrettyZodErrors as Hn,resolveCursorSpawnInvocation as Hr,countStaleAgentWipRefs as Ht,MIN_GIT_VERSION as I,validateCloneInputs as Ii,incrementCollabSocketFilteredError as In,releaseUiLock as Ir,commitWipFromTree as It,SKILL_INSTALL_EVENTS_FILE_REL as J,isJSONRPCRequest as Ji,isHocuspocusAuthRejectionReason as Jn,restoreLifecycleFromConflictsJson as Jr,createEmbeddingsSecretStore as Jt,ROOT_GITIGNORE_TEMPLATE as K,LATEST_PROTOCOL_VERSION as Ki,isAllowedWorkspaceHostHeader as Kn,resolveUiInfo as Kr,createContentFilter as Kt,MISSING_OK_CONFIG_MESSAGE as L,validateSkillZip as Li,incrementServerObserverFire as Ln,removeLastKnownHash as Lr,compareSemver as Lt,MANAGED_RENAME_ORIGIN as M,tracedWriteFileSync as Mi,getTracer as Mn,recordContributor as Mr,clearEmbeddingsKeyFromAllBackends as Mt,MAX_AGENT_SESSIONS as N,updateLastKnownHash as Ni,handleCollabSocketError as Nn,recordSkillInstallEvent as Nr,coercePackId as Nt,HocuspocusAuthTokenSchema as O,tracedRmSync as Oi,getLogger as On,readTargetRecordedAt as Or,classifyEvents as Ot,MCP_CONNECTION_ID_HEADER as P,updateUiLockPort as Pi,handleSpawnCursor as Pn,registerAllTools as Pr,commitUpstreamImport as Pt,STARTER_PACK_IDS as Q,resolveConfigPath as Qi,isPathWithinDir as Qn,runAuthStatusSubprocess as Qr,createLiveDerivedIndexExtension as Qt,McpLogger as R,withSpan as Ri,initContent as Rn,resetMetrics as Rr,containsConflictMarkers as Rt,GIT_PREFLIGHT_FAIL_SPAN_NAME as S,tracedAppendFileSync as Si,formatContributors as Sn,readArmedPaneTarget as Sr,buildConfigYmlContent as St,GitTooOldError as T,tracedMkdirSync as Ti,getCurrentMcpLogger as Tn,readServerPackageVersion as Tr,buildSkillZip as Tt,PinoLogger as U,writeTracker as Ui,installTestLoggers as Un,resolveLockDir as Ur,countWipRefs as Ut,OK_OKIGNORE_TEMPLATE as V,writeStateManifest as Vi,initToleranceTelemetryWriter as Vn,resolveCursorBinaryDefault as Vr,countShadowObjects as Vt,ProjectGitInitError as W,McpServer as Wi,installUserSkill as Wn,resolvePack as Wr,createApiExtension as Wt,STARTER_FOLDER_FRONTMATTER_FILENAME as X,atomicWriteFileSync as Xi,isLoopbackAddress as Xn,rewriteWikiLinksForDocumentRename as Xr,createExternalChangeHandler as Xt,STARTER_FOLDERS as Y,isJSONRPCResultResponse as Yi,isKnownPackId as Yn,rewriteMarkdownLinksForDocumentRename as Yr,createEphemeralProjectDir as Yt,STARTER_PACKS as Z,readConfigSafely as Zi,isPairedWriteOrigin as Zn,runAuthReposSubprocess as Zr,createFileLogger as Zt,DEFAULT_PACK_ID as _,startWatcher as _i,fallbackPaths as _n,parseKeepaliveConnectionId as _r,assertGitAvailable as _t,AgentPresenceBroadcaster as a,resolveShadowDir as aa,sanitizeClientName as ai,createTestLogger as an,listStarterPacks as ar,SingleFileNotMarkdownError as at,FILE_WATCHER_ORIGIN as b,teardownToleranceTelemetryWriter as bi,flushFileLogger as bn,prepareSingleFileOpen as br,bootServer as bt,AutoStartDisabledError as c,seedBasenameIndex as ci,detectGit as cn,logsCurrentPath as cr,UiLockCollisionError as ct,CONFIG_FILENAME as d,shadowGit as di,encodeDocName as dn,mountMcpAndApi as dr,acquireUiLock as dt,writeConfigPatch as ea,runDeviceFlowSubprocess as ei,createOsProbe as en,isSelfWrite as er,STATE_MANIFEST_FILENAME as et,CONFLICT_MARKER_RE as f,shutdownTelemetry as fi,encodeFolderRoute as fn,normalizeFsPath as fr,applyAgentMarkdownWrite as ft,DEFAULT_EMBEDDINGS_DIMENSIONS as g,splitMarkdownBlocks as gi,extractWikiLinksFromMarkdown as gn,parseHocuspocusAuthToken as gr,assertCompatibleStateManifest as gt,DEFAULT_CHECKPOINT_RETENTION as h,spawnDetached as hi,evictStaleTrackerEntries as hn,parseGitVersion as hr,armPaneTarget as ht,AgentFocusBroadcaster as i,resolveGitDirDetailed as ia,safetyCheckpoint as ii,createStreamingErrorWriter as in,listRescueCheckpoints as ir,SingleFileNotFoundError as it,LOG_MD_TEMPLATE as j,tracedWriteFile as ji,getMetrics as jn,reconcile as jr,clearContributors as jt,INSTALLED_AGENTS_SCHEMES as k,tracedRmdirSync as ki,getLogsDir as kn,readTargetVersion as kr,classifyFsPath as kt,BacklinkIndex as l,serializeError as li,detectProjectShape as ln,logsPreviousPath as lr,__getShowAllWalkStatsForTesting as lt,ConfigSchema as m,spansPreviousPath as mi,errorResponse as mn,parseAuthRejectionWire as mr,applySeed as mt,AGENT_ID_RE as n,MalformedGitPointerError as na,safeContentPath as ni,createServer$1 as nn,isToleranceTelemetryEnabled as nr,SeedRootDirError as nt,AgentSessionCapacityError as o,saveInMemoryCheckpoint as oi,describeStoredEmbeddingsKey as on,loadPrincipal as or,StateManifestError as ot,CURSOR_BUNDLE_PATHS_BY_PLATFORM as p,spansCurrentPath as pi,ensureProjectGit as pn,packageVersionMajorMinor as pr,applyExternalChange as pt,SERVICE_WRITER as q,isInitializedNotification as qi,isConfigDoc as qn,restoreContributors as qr,createContentFilterAsync as qt,AGENT_WRITE_ORIGIN as r,parseCheckpoint as ra,safeSubdir as ri,createServerObserverExtension as rn,lastKnownHash as rr,SingleFileNotAFileError as rt,AgentSessionManager as s,saveVersion as si,detectClaudeDesktopPresence as sn,loggerFactory as sr,TagIndex as st,AGENT_ID_MAX_LEN as t,GitDirAccessError as ta,runWithMcpLogger as ti,createPersistenceExtension as tn,isSystemDoc as tr,SeedPrerequisiteError as tt,CC1Broadcaster as u,setActiveSpanAttributes as ui,emitPreflightFailureSpan as un,makeLazyEmbeddingsKeyStore as ur,__resetShowAllWalkStatsForTesting as ut,EMBEDDINGS_API_KEY_ENV as v,streamingProblemEvent as vi,findEnclosingGitRoot as vn,pathToDocName as vr,assertNeverDiskEvent as vt,GitNotAvailableError as w,tracedMkdir as wi,gcCheckpointRefs as wn,readProjectLocalSemanticConfig as wr,buildInstructions as wt,FileEmbeddingsBackend as x,toBroadcasterKey as xi,formatAuthRejectionWire as xn,readAllTargets as xr,buildAndOpenSkill as xt,FILE_SYSTEM_WRITER as y,swapContributors as yi,findEnclosingProjectRoot as yn,planSeed as yr,attachIdleShutdown as yt,MissingOkConfigError as z,withSpanSync as zi,initShadowRepo as zn,resolveBundledSkillDir as zr,contentHash as zt};
2832
- //# sourceMappingURL=dist-DNsu2kId.mjs.map
2832
+ //# sourceMappingURL=dist-DhBWJZmw.mjs.map
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{i as e,r as t,t as n}from"./gh-detect-BjSRN7jT.mjs";import{A as r,C as i,D as a,E as o,O as s,S as c,T as l,_ as u,b as d,d as f,g as p,h as m,i as h,j as g,k as _,o as v,r as y,s as b,t as x,w as S,x as C,y as w}from"./init-CrI1V6Yx.mjs";import{d as T,f as E,m as D,n as O,p as k,r as A,t as j}from"./src-DZVhMPtn.mjs";import{n as M}from"./loader-Dq6BqiYw.mjs";import{n as N}from"./preview-woGHUkwp.mjs";import{n as P,t as F}from"./mcp-migrate-event-D0NrGjvc.mjs";export{a as ALL_EDITOR_IDS,s as EDITOR_LABELS,_ as EDITOR_TARGETS,x as LAUNCH_CONFIG_NAME,y as LAUNCH_UI_CHAIN_SENTINEL,h as LAUNCH_UI_CHAIN_V1,d as addOkPathsToGitExclude,r as buildManagedServerEntry,F as buildMcpConfigMigrateEvent,v as classifyExistingMcpEntry,t as createTokenStore,n as detectGh,b as detectInstalledEditors,C as formatTrackedRemediation,c as getExcludedOkPaths,i as getOkArtifactPaths,g as isEntryUpToDate,M as loadConfig,e as makeLazyProbeTokenStore,T as parseGitHubBlobUrl,E as parseGitHubShareUrl,k as parseGitHubTreeUrl,D as parseGitUrl,N as previewContent,S as probeTrackedOkPaths,f as readExistingMcpEntry,l as readSharingMode,o as removeOkPathsFromGitExclude,w as resolveProjectRoot,A as runStop,m as scaffoldLaunchJson,P as truncatePriorEntry,O as validateLocalFolderForShare,p as writeEditorMcpConfig,j as writeProjectAiIntegrations,u as writeUserMcpConfigs};
1
+ import{i as e,r as t,t as n}from"./gh-detect-BjSRN7jT.mjs";import{A as r,C as i,D as a,E as o,O as s,S as c,T as l,_ as u,b as d,d as f,g as p,h as m,i as h,j as g,k as _,o as v,r as y,s as b,t as x,w as S,x as C,y as w}from"./init-KcxJDN4J.mjs";import{d as T,f as E,m as D,n as O,p as k,r as A,t as j}from"./src-DLDEqC8Q.mjs";import{n as M}from"./loader-swjVUkhG.mjs";import{n as N}from"./preview-DryhvQ49.mjs";import{n as P,t as F}from"./mcp-migrate-event-D0NrGjvc.mjs";export{a as ALL_EDITOR_IDS,s as EDITOR_LABELS,_ as EDITOR_TARGETS,x as LAUNCH_CONFIG_NAME,y as LAUNCH_UI_CHAIN_SENTINEL,h as LAUNCH_UI_CHAIN_V1,d as addOkPathsToGitExclude,r as buildManagedServerEntry,F as buildMcpConfigMigrateEvent,v as classifyExistingMcpEntry,t as createTokenStore,n as detectGh,b as detectInstalledEditors,C as formatTrackedRemediation,c as getExcludedOkPaths,i as getOkArtifactPaths,g as isEntryUpToDate,M as loadConfig,e as makeLazyProbeTokenStore,T as parseGitHubBlobUrl,E as parseGitHubShareUrl,k as parseGitHubTreeUrl,D as parseGitUrl,N as previewContent,S as probeTrackedOkPaths,f as readExistingMcpEntry,l as readSharingMode,o as removeOkPathsFromGitExclude,w as resolveProjectRoot,A as runStop,m as scaffoldLaunchJson,P as truncatePriorEntry,O as validateLocalFolderForShare,p as writeEditorMcpConfig,j as writeProjectAiIntegrations,u as writeUserMcpConfigs};
@@ -0,0 +1 @@
1
+ import{m as e}from"./init-KcxJDN4J.mjs";export{e as runInit};
@@ -1,4 +1,4 @@
1
- import{a as e,s as t,t as n}from"./chunk-C94x7I9S.mjs";import{r,t as i}from"./esm-BLMtE3s6.mjs";import{Ft as a,Or as o,St as s,ln as c,v as l,xt as u,y as d}from"./server-lock-BpjJj3OD-DR9UrMHX.mjs";import{$i as f,$n as p,Bi as m,F as h,Gn as g,Kn as _,Rn as v,W as y,Wn as b,Xi as x,Xn as S,ia as C,pn as w,sn as ee}from"./dist-DNsu2kId.mjs";import"./constants-Q1dSeYtu.mjs";import{t as T}from"./is-object-Cie0xXKD.mjs";import{i as E,o as D,r as O,s as k,t as A}from"./colors-8SzMRIVy.mjs";import{t as te}from"./preview-woGHUkwp.mjs";import{n as ne,t as j}from"./write-project-skill-c27daLaM.mjs";import{execFileSync as re}from"node:child_process";import{existsSync as M,mkdirSync as ie,readFileSync as N,realpathSync as ae,writeFileSync as P}from"node:fs";import F,{basename as I,dirname as L,isAbsolute as oe,join as R,posix as se,relative as z,resolve as ce,sep as le,win32 as ue}from"node:path";import B from"node:process";import{homedir as V}from"node:os";import{randomUUID as de}from"node:crypto";import{stripVTControlCharacters as fe,styleText as H}from"node:util";import{AsyncLocalStorage as pe,AsyncResource as me}from"node:async_hooks";import{createServer as he,request as ge}from"node:http";import*as _e from"node:readline";import{connect as ve}from"node:net";function ye(){return B.platform.startsWith(`win`)?!!B.env.CI||!!B.env.WT_SESSION||!!B.env.TERMINUS_SUBLIME||B.env.ConEmuTask===`{cmd::Cmder}`||B.env.TERM_PROGRAM===`Terminus-Sublime`||B.env.TERM_PROGRAM===`vscode`||B.env.TERM===`xterm-256color`||B.env.TERM===`alacritty`||B.env.TERMINAL_EMULATOR===`JetBrains-JediTerm`:B.env.TERM!==`linux`}const be={circleQuestionMark:`(?)`,questionMarkPrefix:`(?)`,square:`█`,squareDarkShade:`▓`,squareMediumShade:`▒`,squareLightShade:`░`,squareTop:`▀`,squareBottom:`▄`,squareLeft:`▌`,squareRight:`▐`,squareCenter:`■`,bullet:`●`,dot:`․`,ellipsis:`…`,pointerSmall:`›`,triangleUp:`▲`,triangleUpSmall:`▴`,triangleDown:`▼`,triangleDownSmall:`▾`,triangleLeftSmall:`◂`,triangleRightSmall:`▸`,home:`⌂`,heart:`♥`,musicNote:`♪`,musicNoteBeamed:`♫`,arrowUp:`↑`,arrowDown:`↓`,arrowLeft:`←`,arrowRight:`→`,arrowLeftRight:`↔`,arrowUpDown:`↕`,almostEqual:`≈`,notEqual:`≠`,lessOrEqual:`≤`,greaterOrEqual:`≥`,identical:`≡`,infinity:`∞`,subscriptZero:`₀`,subscriptOne:`₁`,subscriptTwo:`₂`,subscriptThree:`₃`,subscriptFour:`₄`,subscriptFive:`₅`,subscriptSix:`₆`,subscriptSeven:`₇`,subscriptEight:`₈`,subscriptNine:`₉`,oneHalf:`½`,oneThird:`⅓`,oneQuarter:`¼`,oneFifth:`⅕`,oneSixth:`⅙`,oneEighth:`⅛`,twoThirds:`⅔`,twoFifths:`⅖`,threeQuarters:`¾`,threeFifths:`⅗`,threeEighths:`⅜`,fourFifths:`⅘`,fiveSixths:`⅚`,fiveEighths:`⅝`,sevenEighths:`⅞`,line:`─`,lineBold:`━`,lineDouble:`═`,lineDashed0:`┄`,lineDashed1:`┅`,lineDashed2:`┈`,lineDashed3:`┉`,lineDashed4:`╌`,lineDashed5:`╍`,lineDashed6:`╴`,lineDashed7:`╶`,lineDashed8:`╸`,lineDashed9:`╺`,lineDashed10:`╼`,lineDashed11:`╾`,lineDashed12:`−`,lineDashed13:`–`,lineDashed14:`‐`,lineDashed15:`⁃`,lineVertical:`│`,lineVerticalBold:`┃`,lineVerticalDouble:`║`,lineVerticalDashed0:`┆`,lineVerticalDashed1:`┇`,lineVerticalDashed2:`┊`,lineVerticalDashed3:`┋`,lineVerticalDashed4:`╎`,lineVerticalDashed5:`╏`,lineVerticalDashed6:`╵`,lineVerticalDashed7:`╷`,lineVerticalDashed8:`╹`,lineVerticalDashed9:`╻`,lineVerticalDashed10:`╽`,lineVerticalDashed11:`╿`,lineDownLeft:`┐`,lineDownLeftArc:`╮`,lineDownBoldLeftBold:`┓`,lineDownBoldLeft:`┒`,lineDownLeftBold:`┑`,lineDownDoubleLeftDouble:`╗`,lineDownDoubleLeft:`╖`,lineDownLeftDouble:`╕`,lineDownRight:`┌`,lineDownRightArc:`╭`,lineDownBoldRightBold:`┏`,lineDownBoldRight:`┎`,lineDownRightBold:`┍`,lineDownDoubleRightDouble:`╔`,lineDownDoubleRight:`╓`,lineDownRightDouble:`╒`,lineUpLeft:`┘`,lineUpLeftArc:`╯`,lineUpBoldLeftBold:`┛`,lineUpBoldLeft:`┚`,lineUpLeftBold:`┙`,lineUpDoubleLeftDouble:`╝`,lineUpDoubleLeft:`╜`,lineUpLeftDouble:`╛`,lineUpRight:`└`,lineUpRightArc:`╰`,lineUpBoldRightBold:`┗`,lineUpBoldRight:`┖`,lineUpRightBold:`┕`,lineUpDoubleRightDouble:`╚`,lineUpDoubleRight:`╙`,lineUpRightDouble:`╘`,lineUpDownLeft:`┤`,lineUpBoldDownBoldLeftBold:`┫`,lineUpBoldDownBoldLeft:`┨`,lineUpDownLeftBold:`┥`,lineUpBoldDownLeftBold:`┩`,lineUpDownBoldLeftBold:`┪`,lineUpDownBoldLeft:`┧`,lineUpBoldDownLeft:`┦`,lineUpDoubleDownDoubleLeftDouble:`╣`,lineUpDoubleDownDoubleLeft:`╢`,lineUpDownLeftDouble:`╡`,lineUpDownRight:`├`,lineUpBoldDownBoldRightBold:`┣`,lineUpBoldDownBoldRight:`┠`,lineUpDownRightBold:`┝`,lineUpBoldDownRightBold:`┡`,lineUpDownBoldRightBold:`┢`,lineUpDownBoldRight:`┟`,lineUpBoldDownRight:`┞`,lineUpDoubleDownDoubleRightDouble:`╠`,lineUpDoubleDownDoubleRight:`╟`,lineUpDownRightDouble:`╞`,lineDownLeftRight:`┬`,lineDownBoldLeftBoldRightBold:`┳`,lineDownLeftBoldRightBold:`┯`,lineDownBoldLeftRight:`┰`,lineDownBoldLeftBoldRight:`┱`,lineDownBoldLeftRightBold:`┲`,lineDownLeftRightBold:`┮`,lineDownLeftBoldRight:`┭`,lineDownDoubleLeftDoubleRightDouble:`╦`,lineDownDoubleLeftRight:`╥`,lineDownLeftDoubleRightDouble:`╤`,lineUpLeftRight:`┴`,lineUpBoldLeftBoldRightBold:`┻`,lineUpLeftBoldRightBold:`┷`,lineUpBoldLeftRight:`┸`,lineUpBoldLeftBoldRight:`┹`,lineUpBoldLeftRightBold:`┺`,lineUpLeftRightBold:`┶`,lineUpLeftBoldRight:`┵`,lineUpDoubleLeftDoubleRightDouble:`╩`,lineUpDoubleLeftRight:`╨`,lineUpLeftDoubleRightDouble:`╧`,lineUpDownLeftRight:`┼`,lineUpBoldDownBoldLeftBoldRightBold:`╋`,lineUpDownBoldLeftBoldRightBold:`╈`,lineUpBoldDownLeftBoldRightBold:`╇`,lineUpBoldDownBoldLeftRightBold:`╊`,lineUpBoldDownBoldLeftBoldRight:`╉`,lineUpBoldDownLeftRight:`╀`,lineUpDownBoldLeftRight:`╁`,lineUpDownLeftBoldRight:`┽`,lineUpDownLeftRightBold:`┾`,lineUpBoldDownBoldLeftRight:`╂`,lineUpDownLeftBoldRightBold:`┿`,lineUpBoldDownLeftBoldRight:`╃`,lineUpBoldDownLeftRightBold:`╄`,lineUpDownBoldLeftBoldRight:`╅`,lineUpDownBoldLeftRightBold:`╆`,lineUpDoubleDownDoubleLeftDoubleRightDouble:`╬`,lineUpDoubleDownDoubleLeftRight:`╫`,lineUpDownLeftDoubleRightDouble:`╪`,lineCross:`╳`,lineBackslash:`╲`,lineSlash:`╱`},xe={tick:`✔`,info:`ℹ`,warning:`⚠`,cross:`✘`,squareSmall:`◻`,squareSmallFilled:`◼`,circle:`◯`,circleFilled:`◉`,circleDotted:`◌`,circleDouble:`◎`,circleCircle:`ⓞ`,circleCross:`ⓧ`,circlePipe:`Ⓘ`,radioOn:`◉`,radioOff:`◯`,checkboxOn:`☒`,checkboxOff:`☐`,checkboxCircleOn:`ⓧ`,checkboxCircleOff:`Ⓘ`,pointer:`❯`,triangleUpOutline:`△`,triangleLeft:`◀`,triangleRight:`▶`,lozenge:`◆`,lozengeOutline:`◇`,hamburger:`☰`,smiley:`㋡`,mustache:`෴`,star:`★`,play:`▶`,nodejs:`⬢`,oneSeventh:`⅐`,oneNinth:`⅑`,oneTenth:`⅒`},Se={tick:`√`,info:`i`,warning:`‼`,cross:`×`,squareSmall:`□`,squareSmallFilled:`■`,circle:`( )`,circleFilled:`(*)`,circleDotted:`( )`,circleDouble:`( )`,circleCircle:`(○)`,circleCross:`(×)`,circlePipe:`(│)`,radioOn:`(*)`,radioOff:`( )`,checkboxOn:`[×]`,checkboxOff:`[ ]`,checkboxCircleOn:`(×)`,checkboxCircleOff:`( )`,pointer:`>`,triangleUpOutline:`∆`,triangleLeft:`◄`,triangleRight:`►`,lozenge:`♦`,lozengeOutline:`◊`,hamburger:`≡`,smiley:`☺`,mustache:`┌─┐`,star:`✶`,play:`►`,nodejs:`♦`,oneSeventh:`1/7`,oneNinth:`1/9`,oneTenth:`1/10`},Ce={...be,...xe},we={...be,...Se},U=ye()?Ce:we;Object.entries(xe);var Te=n(((t,n)=>{n.exports=i;function r(t){let n={defaultWidth:0,output:process.stdout,tty:e(`tty`)};return t?(Object.keys(n).forEach(function(e){t[e]||(t[e]=n[e])}),t):n}function i(e){let t=r(e);if(t.output.getWindowSize)return t.output.getWindowSize()[0]||t.defaultWidth;if(t.tty.getWindowSize)return t.tty.getWindowSize()[1]||t.defaultWidth;if(t.output.columns)return t.output.columns;if(process.env.CLI_WIDTH){let e=parseInt(process.env.CLI_WIDTH,10);if(!isNaN(e)&&e!==0)return e}return t.defaultWidth}}));const Ee=(()=>{let e=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return t=>{let n=0;for(e.lastIndex=0;e.test(t);)n+=1;return t.length-n}})(),De=e=>e===12288||e>=65281&&e<=65376||e>=65504&&e<=65510,Oe=e=>e===8987||e===9001||e>=12272&&e<=12287||e>=12289&&e<=12350||e>=12441&&e<=12543||e>=12549&&e<=12591||e>=12593&&e<=12686||e>=12688&&e<=12771||e>=12783&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=19903||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=127488&&e<=127490||e>=127504&&e<=127547||e>=127552&&e<=127560||e>=131072&&e<=196605||e>=196608&&e<=262141,ke=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,Ae=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,je=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/uy,Me=/\t{1,1000}/y,Ne=/[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/uy,Pe=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,Fe=/\p{M}+/gu,Ie={limit:1/0,ellipsis:``},Le=(e,t={},n={})=>{let r=t.limit??1/0,i=t.ellipsis??``,a=t?.ellipsisWidth??(i?Le(i,Ie,n).width:0),o=n.controlWidth??0,s=n.tabWidth??8,c=n.emojiWidth??2,l=n.regularWidth??1,u=n.wideWidth??2,d=[[Pe,l],[ke,0],[Ae,o],[Me,s],[Ne,c],[je,u]],f=0,p=0,m=e.length,h=0,g=!1,_=m,v=Math.max(0,r-a),y=0,b=0,x=0,S=0;outer:for(;;){if(b>y||p>=m&&p>f){let t=e.slice(y,b)||e.slice(f,p);h=0;for(let e of t.replaceAll(Fe,``)){let t=e.codePointAt(0)||0;if(S=De(t)?2:Oe(t)?u:l,x+S>v&&(_=Math.min(_,Math.max(y,f)+h)),x+S>r){g=!0;break outer}h+=e.length,x+=S}y=b=0}if(p>=m)break outer;for(let t=0,n=d.length;t<n;t++){let[n,i]=d[t];if(n.lastIndex=p,n.test(e)){if(h=n===je?Ee(e.slice(p,n.lastIndex)):n===Ne?1:n.lastIndex-p,S=h*i,x+S>v&&(_=Math.min(_,p+Math.floor((v-x)/i))),x+S>r){g=!0;break outer}x+=S,y=f,b=p,p=f=n.lastIndex;continue outer}}p+=1}return{width:g?v:x,index:g?_:m,truncated:g,ellipsed:g&&r>=a}},Re={limit:1/0,ellipsis:``,ellipsisWidth:0},W=(e,t={})=>Le(e,Re,t).width,ze=`]8;;`,Be=RegExp(`(?:\\[(?<code>\\d+)m|\\${ze}(?<uri>.*))`,`y`),Ve=e=>{if(e>=30&&e<=37||e>=90&&e<=97)return 39;if(e>=40&&e<=47||e>=100&&e<=107)return 49;if(e===1||e===2)return 22;if(e===3)return 23;if(e===4)return 24;if(e===7)return 27;if(e===8)return 28;if(e===9)return 29;if(e===0)return 0},He=e=>`[${e}m`,Ue=e=>`${ze}${e}`,We=(e,t,n)=>{let r=t[Symbol.iterator](),i=!1,a=!1,o=e.at(-1),s=o===void 0?0:W(o),c=r.next(),l=r.next(),u=0;for(;!c.done;){let o=c.value,d=W(o);s+d<=n?e[e.length-1]+=o:(e.push(o),s=0),(o===`\x1B`||o===`›`)&&(i=!0,a=t.startsWith(ze,u+1)),i?a?o===`\x07`&&(i=!1,a=!1):o===`m`&&(i=!1):(s+=d,s===n&&!l.done&&(e.push(``),s=0)),c=l,l=r.next(),u+=o.length}o=e.at(-1),!s&&o!==void 0&&o.length&&e.length>1&&(e[e.length-2]+=e.pop())},Ge=e=>{let t=e.split(` `),n=t.length;for(;n&&!W(t[n-1]);)n--;return n===t.length?e:t.slice(0,n).join(` `)+t.slice(n).join(``)},Ke=(e,t,n={})=>{if(n.trim!==!1&&e.trim()===``)return``;let r=``,i,a,o=e.split(` `),s=[``],c=0;for(let e=0;e<o.length;e++){let r=o[e];if(n.trim!==!1){let e=s.at(-1)??``,t=e.trimStart();e.length!==t.length&&(s[s.length-1]=t,c=W(t))}e!==0&&(c>=t&&(n.wordWrap===!1||n.trim===!1)&&(s.push(``),c=0),(c||n.trim===!1)&&(s[s.length-1]+=` `,c++));let i=W(r);if(n.hard&&i>t){let e=t-c,n=1+Math.floor((i-e-1)/t);Math.floor((i-1)/t)<n&&s.push(``),We(s,r,t),c=W(s.at(-1)??``);continue}if(c+i>t&&c&&i){if(n.wordWrap===!1&&c<t){We(s,r,t),c=W(s.at(-1)??``);continue}s.push(``),c=0}if(c+i>t&&n.wordWrap===!1){We(s,r,t),c=W(s.at(-1)??``);continue}s[s.length-1]+=r,c+=i}n.trim!==!1&&(s=s.map(e=>Ge(e)));let l=s.join(`
1
+ import{a as e,s as t,t as n}from"./chunk-C94x7I9S.mjs";import{r,t as i}from"./esm-BLMtE3s6.mjs";import{Ft as a,Or as o,St as s,ln as c,v as l,xt as u,y as d}from"./server-lock-BpjJj3OD-DR9UrMHX.mjs";import{$i as f,$n as p,Bi as m,F as h,Gn as g,Kn as _,Rn as v,W as y,Wn as b,Xi as x,Xn as S,ia as C,pn as w,sn as ee}from"./dist-DhBWJZmw.mjs";import"./constants-CQjg8jG7.mjs";import{t as T}from"./is-object-Cie0xXKD.mjs";import{i as E,o as D,r as O,s as k,t as A}from"./colors-8SzMRIVy.mjs";import{t as te}from"./preview-DryhvQ49.mjs";import{n as ne,t as j}from"./write-project-skill-BV7yzBRP.mjs";import{execFileSync as re}from"node:child_process";import{existsSync as M,mkdirSync as ie,readFileSync as N,realpathSync as ae,writeFileSync as P}from"node:fs";import F,{basename as I,dirname as L,isAbsolute as oe,join as R,posix as se,relative as z,resolve as ce,sep as le,win32 as ue}from"node:path";import B from"node:process";import{homedir as V}from"node:os";import{randomUUID as de}from"node:crypto";import{stripVTControlCharacters as fe,styleText as H}from"node:util";import{AsyncLocalStorage as pe,AsyncResource as me}from"node:async_hooks";import{createServer as he,request as ge}from"node:http";import*as _e from"node:readline";import{connect as ve}from"node:net";function ye(){return B.platform.startsWith(`win`)?!!B.env.CI||!!B.env.WT_SESSION||!!B.env.TERMINUS_SUBLIME||B.env.ConEmuTask===`{cmd::Cmder}`||B.env.TERM_PROGRAM===`Terminus-Sublime`||B.env.TERM_PROGRAM===`vscode`||B.env.TERM===`xterm-256color`||B.env.TERM===`alacritty`||B.env.TERMINAL_EMULATOR===`JetBrains-JediTerm`:B.env.TERM!==`linux`}const be={circleQuestionMark:`(?)`,questionMarkPrefix:`(?)`,square:`█`,squareDarkShade:`▓`,squareMediumShade:`▒`,squareLightShade:`░`,squareTop:`▀`,squareBottom:`▄`,squareLeft:`▌`,squareRight:`▐`,squareCenter:`■`,bullet:`●`,dot:`․`,ellipsis:`…`,pointerSmall:`›`,triangleUp:`▲`,triangleUpSmall:`▴`,triangleDown:`▼`,triangleDownSmall:`▾`,triangleLeftSmall:`◂`,triangleRightSmall:`▸`,home:`⌂`,heart:`♥`,musicNote:`♪`,musicNoteBeamed:`♫`,arrowUp:`↑`,arrowDown:`↓`,arrowLeft:`←`,arrowRight:`→`,arrowLeftRight:`↔`,arrowUpDown:`↕`,almostEqual:`≈`,notEqual:`≠`,lessOrEqual:`≤`,greaterOrEqual:`≥`,identical:`≡`,infinity:`∞`,subscriptZero:`₀`,subscriptOne:`₁`,subscriptTwo:`₂`,subscriptThree:`₃`,subscriptFour:`₄`,subscriptFive:`₅`,subscriptSix:`₆`,subscriptSeven:`₇`,subscriptEight:`₈`,subscriptNine:`₉`,oneHalf:`½`,oneThird:`⅓`,oneQuarter:`¼`,oneFifth:`⅕`,oneSixth:`⅙`,oneEighth:`⅛`,twoThirds:`⅔`,twoFifths:`⅖`,threeQuarters:`¾`,threeFifths:`⅗`,threeEighths:`⅜`,fourFifths:`⅘`,fiveSixths:`⅚`,fiveEighths:`⅝`,sevenEighths:`⅞`,line:`─`,lineBold:`━`,lineDouble:`═`,lineDashed0:`┄`,lineDashed1:`┅`,lineDashed2:`┈`,lineDashed3:`┉`,lineDashed4:`╌`,lineDashed5:`╍`,lineDashed6:`╴`,lineDashed7:`╶`,lineDashed8:`╸`,lineDashed9:`╺`,lineDashed10:`╼`,lineDashed11:`╾`,lineDashed12:`−`,lineDashed13:`–`,lineDashed14:`‐`,lineDashed15:`⁃`,lineVertical:`│`,lineVerticalBold:`┃`,lineVerticalDouble:`║`,lineVerticalDashed0:`┆`,lineVerticalDashed1:`┇`,lineVerticalDashed2:`┊`,lineVerticalDashed3:`┋`,lineVerticalDashed4:`╎`,lineVerticalDashed5:`╏`,lineVerticalDashed6:`╵`,lineVerticalDashed7:`╷`,lineVerticalDashed8:`╹`,lineVerticalDashed9:`╻`,lineVerticalDashed10:`╽`,lineVerticalDashed11:`╿`,lineDownLeft:`┐`,lineDownLeftArc:`╮`,lineDownBoldLeftBold:`┓`,lineDownBoldLeft:`┒`,lineDownLeftBold:`┑`,lineDownDoubleLeftDouble:`╗`,lineDownDoubleLeft:`╖`,lineDownLeftDouble:`╕`,lineDownRight:`┌`,lineDownRightArc:`╭`,lineDownBoldRightBold:`┏`,lineDownBoldRight:`┎`,lineDownRightBold:`┍`,lineDownDoubleRightDouble:`╔`,lineDownDoubleRight:`╓`,lineDownRightDouble:`╒`,lineUpLeft:`┘`,lineUpLeftArc:`╯`,lineUpBoldLeftBold:`┛`,lineUpBoldLeft:`┚`,lineUpLeftBold:`┙`,lineUpDoubleLeftDouble:`╝`,lineUpDoubleLeft:`╜`,lineUpLeftDouble:`╛`,lineUpRight:`└`,lineUpRightArc:`╰`,lineUpBoldRightBold:`┗`,lineUpBoldRight:`┖`,lineUpRightBold:`┕`,lineUpDoubleRightDouble:`╚`,lineUpDoubleRight:`╙`,lineUpRightDouble:`╘`,lineUpDownLeft:`┤`,lineUpBoldDownBoldLeftBold:`┫`,lineUpBoldDownBoldLeft:`┨`,lineUpDownLeftBold:`┥`,lineUpBoldDownLeftBold:`┩`,lineUpDownBoldLeftBold:`┪`,lineUpDownBoldLeft:`┧`,lineUpBoldDownLeft:`┦`,lineUpDoubleDownDoubleLeftDouble:`╣`,lineUpDoubleDownDoubleLeft:`╢`,lineUpDownLeftDouble:`╡`,lineUpDownRight:`├`,lineUpBoldDownBoldRightBold:`┣`,lineUpBoldDownBoldRight:`┠`,lineUpDownRightBold:`┝`,lineUpBoldDownRightBold:`┡`,lineUpDownBoldRightBold:`┢`,lineUpDownBoldRight:`┟`,lineUpBoldDownRight:`┞`,lineUpDoubleDownDoubleRightDouble:`╠`,lineUpDoubleDownDoubleRight:`╟`,lineUpDownRightDouble:`╞`,lineDownLeftRight:`┬`,lineDownBoldLeftBoldRightBold:`┳`,lineDownLeftBoldRightBold:`┯`,lineDownBoldLeftRight:`┰`,lineDownBoldLeftBoldRight:`┱`,lineDownBoldLeftRightBold:`┲`,lineDownLeftRightBold:`┮`,lineDownLeftBoldRight:`┭`,lineDownDoubleLeftDoubleRightDouble:`╦`,lineDownDoubleLeftRight:`╥`,lineDownLeftDoubleRightDouble:`╤`,lineUpLeftRight:`┴`,lineUpBoldLeftBoldRightBold:`┻`,lineUpLeftBoldRightBold:`┷`,lineUpBoldLeftRight:`┸`,lineUpBoldLeftBoldRight:`┹`,lineUpBoldLeftRightBold:`┺`,lineUpLeftRightBold:`┶`,lineUpLeftBoldRight:`┵`,lineUpDoubleLeftDoubleRightDouble:`╩`,lineUpDoubleLeftRight:`╨`,lineUpLeftDoubleRightDouble:`╧`,lineUpDownLeftRight:`┼`,lineUpBoldDownBoldLeftBoldRightBold:`╋`,lineUpDownBoldLeftBoldRightBold:`╈`,lineUpBoldDownLeftBoldRightBold:`╇`,lineUpBoldDownBoldLeftRightBold:`╊`,lineUpBoldDownBoldLeftBoldRight:`╉`,lineUpBoldDownLeftRight:`╀`,lineUpDownBoldLeftRight:`╁`,lineUpDownLeftBoldRight:`┽`,lineUpDownLeftRightBold:`┾`,lineUpBoldDownBoldLeftRight:`╂`,lineUpDownLeftBoldRightBold:`┿`,lineUpBoldDownLeftBoldRight:`╃`,lineUpBoldDownLeftRightBold:`╄`,lineUpDownBoldLeftBoldRight:`╅`,lineUpDownBoldLeftRightBold:`╆`,lineUpDoubleDownDoubleLeftDoubleRightDouble:`╬`,lineUpDoubleDownDoubleLeftRight:`╫`,lineUpDownLeftDoubleRightDouble:`╪`,lineCross:`╳`,lineBackslash:`╲`,lineSlash:`╱`},xe={tick:`✔`,info:`ℹ`,warning:`⚠`,cross:`✘`,squareSmall:`◻`,squareSmallFilled:`◼`,circle:`◯`,circleFilled:`◉`,circleDotted:`◌`,circleDouble:`◎`,circleCircle:`ⓞ`,circleCross:`ⓧ`,circlePipe:`Ⓘ`,radioOn:`◉`,radioOff:`◯`,checkboxOn:`☒`,checkboxOff:`☐`,checkboxCircleOn:`ⓧ`,checkboxCircleOff:`Ⓘ`,pointer:`❯`,triangleUpOutline:`△`,triangleLeft:`◀`,triangleRight:`▶`,lozenge:`◆`,lozengeOutline:`◇`,hamburger:`☰`,smiley:`㋡`,mustache:`෴`,star:`★`,play:`▶`,nodejs:`⬢`,oneSeventh:`⅐`,oneNinth:`⅑`,oneTenth:`⅒`},Se={tick:`√`,info:`i`,warning:`‼`,cross:`×`,squareSmall:`□`,squareSmallFilled:`■`,circle:`( )`,circleFilled:`(*)`,circleDotted:`( )`,circleDouble:`( )`,circleCircle:`(○)`,circleCross:`(×)`,circlePipe:`(│)`,radioOn:`(*)`,radioOff:`( )`,checkboxOn:`[×]`,checkboxOff:`[ ]`,checkboxCircleOn:`(×)`,checkboxCircleOff:`( )`,pointer:`>`,triangleUpOutline:`∆`,triangleLeft:`◄`,triangleRight:`►`,lozenge:`♦`,lozengeOutline:`◊`,hamburger:`≡`,smiley:`☺`,mustache:`┌─┐`,star:`✶`,play:`►`,nodejs:`♦`,oneSeventh:`1/7`,oneNinth:`1/9`,oneTenth:`1/10`},Ce={...be,...xe},we={...be,...Se},U=ye()?Ce:we;Object.entries(xe);var Te=n(((t,n)=>{n.exports=i;function r(t){let n={defaultWidth:0,output:process.stdout,tty:e(`tty`)};return t?(Object.keys(n).forEach(function(e){t[e]||(t[e]=n[e])}),t):n}function i(e){let t=r(e);if(t.output.getWindowSize)return t.output.getWindowSize()[0]||t.defaultWidth;if(t.tty.getWindowSize)return t.tty.getWindowSize()[1]||t.defaultWidth;if(t.output.columns)return t.output.columns;if(process.env.CLI_WIDTH){let e=parseInt(process.env.CLI_WIDTH,10);if(!isNaN(e)&&e!==0)return e}return t.defaultWidth}}));const Ee=(()=>{let e=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return t=>{let n=0;for(e.lastIndex=0;e.test(t);)n+=1;return t.length-n}})(),De=e=>e===12288||e>=65281&&e<=65376||e>=65504&&e<=65510,Oe=e=>e===8987||e===9001||e>=12272&&e<=12287||e>=12289&&e<=12350||e>=12441&&e<=12543||e>=12549&&e<=12591||e>=12593&&e<=12686||e>=12688&&e<=12771||e>=12783&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=19903||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=127488&&e<=127490||e>=127504&&e<=127547||e>=127552&&e<=127560||e>=131072&&e<=196605||e>=196608&&e<=262141,ke=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,Ae=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,je=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/uy,Me=/\t{1,1000}/y,Ne=/[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/uy,Pe=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,Fe=/\p{M}+/gu,Ie={limit:1/0,ellipsis:``},Le=(e,t={},n={})=>{let r=t.limit??1/0,i=t.ellipsis??``,a=t?.ellipsisWidth??(i?Le(i,Ie,n).width:0),o=n.controlWidth??0,s=n.tabWidth??8,c=n.emojiWidth??2,l=n.regularWidth??1,u=n.wideWidth??2,d=[[Pe,l],[ke,0],[Ae,o],[Me,s],[Ne,c],[je,u]],f=0,p=0,m=e.length,h=0,g=!1,_=m,v=Math.max(0,r-a),y=0,b=0,x=0,S=0;outer:for(;;){if(b>y||p>=m&&p>f){let t=e.slice(y,b)||e.slice(f,p);h=0;for(let e of t.replaceAll(Fe,``)){let t=e.codePointAt(0)||0;if(S=De(t)?2:Oe(t)?u:l,x+S>v&&(_=Math.min(_,Math.max(y,f)+h)),x+S>r){g=!0;break outer}h+=e.length,x+=S}y=b=0}if(p>=m)break outer;for(let t=0,n=d.length;t<n;t++){let[n,i]=d[t];if(n.lastIndex=p,n.test(e)){if(h=n===je?Ee(e.slice(p,n.lastIndex)):n===Ne?1:n.lastIndex-p,S=h*i,x+S>v&&(_=Math.min(_,p+Math.floor((v-x)/i))),x+S>r){g=!0;break outer}x+=S,y=f,b=p,p=f=n.lastIndex;continue outer}}p+=1}return{width:g?v:x,index:g?_:m,truncated:g,ellipsed:g&&r>=a}},Re={limit:1/0,ellipsis:``,ellipsisWidth:0},W=(e,t={})=>Le(e,Re,t).width,ze=`]8;;`,Be=RegExp(`(?:\\[(?<code>\\d+)m|\\${ze}(?<uri>.*))`,`y`),Ve=e=>{if(e>=30&&e<=37||e>=90&&e<=97)return 39;if(e>=40&&e<=47||e>=100&&e<=107)return 49;if(e===1||e===2)return 22;if(e===3)return 23;if(e===4)return 24;if(e===7)return 27;if(e===8)return 28;if(e===9)return 29;if(e===0)return 0},He=e=>`[${e}m`,Ue=e=>`${ze}${e}`,We=(e,t,n)=>{let r=t[Symbol.iterator](),i=!1,a=!1,o=e.at(-1),s=o===void 0?0:W(o),c=r.next(),l=r.next(),u=0;for(;!c.done;){let o=c.value,d=W(o);s+d<=n?e[e.length-1]+=o:(e.push(o),s=0),(o===`\x1B`||o===`›`)&&(i=!0,a=t.startsWith(ze,u+1)),i?a?o===`\x07`&&(i=!1,a=!1):o===`m`&&(i=!1):(s+=d,s===n&&!l.done&&(e.push(``),s=0)),c=l,l=r.next(),u+=o.length}o=e.at(-1),!s&&o!==void 0&&o.length&&e.length>1&&(e[e.length-2]+=e.pop())},Ge=e=>{let t=e.split(` `),n=t.length;for(;n&&!W(t[n-1]);)n--;return n===t.length?e:t.slice(0,n).join(` `)+t.slice(n).join(``)},Ke=(e,t,n={})=>{if(n.trim!==!1&&e.trim()===``)return``;let r=``,i,a,o=e.split(` `),s=[``],c=0;for(let e=0;e<o.length;e++){let r=o[e];if(n.trim!==!1){let e=s.at(-1)??``,t=e.trimStart();e.length!==t.length&&(s[s.length-1]=t,c=W(t))}e!==0&&(c>=t&&(n.wordWrap===!1||n.trim===!1)&&(s.push(``),c=0),(c||n.trim===!1)&&(s[s.length-1]+=` `,c++));let i=W(r);if(n.hard&&i>t){let e=t-c,n=1+Math.floor((i-e-1)/t);Math.floor((i-1)/t)<n&&s.push(``),We(s,r,t),c=W(s.at(-1)??``);continue}if(c+i>t&&c&&i){if(n.wordWrap===!1&&c<t){We(s,r,t),c=W(s.at(-1)??``);continue}s.push(``),c=0}if(c+i>t&&n.wordWrap===!1){We(s,r,t),c=W(s.at(-1)??``);continue}s[s.length-1]+=r,c+=i}n.trim!==!1&&(s=s.map(e=>Ge(e)));let l=s.join(`
2
2
  `),u=!1;for(let e=0;e<l.length;e++){let t=l[e];if(r+=t,u)u=!1;else if(u=t>=`\ud800`&&t<=`\udbff`,u)continue;if(t===`\x1B`||t===`›`){Be.lastIndex=e+1;let t=Be.exec(l)?.groups;if(t?.code!==void 0){let e=Number.parseFloat(t.code);i=e===39?void 0:e}else t?.uri!==void 0&&(a=t.uri.length===0?void 0:t.uri)}if(l[e+1]===`
3
3
  `){a&&(r+=Ue(``));let e=i?Ve(i):void 0;i&&e&&(r+=He(e))}else t===`
4
4
  `&&(i&&Ve(i)&&(r+=He(i)),a&&(r+=Ue(a)))}return r},qe=/\r?\n/;function Je(e,t,n){return String(e).normalize().split(qe).map(e=>Ke(e,t,n)).join(`
@@ -291,7 +291,7 @@ let bi=/^[a-z0-9-_]+$/i;function xi(e){let t=typeof e;if(t===`object`){if(Array.
291
291
  `}}return e&&(a||!o)&&(a=a?`[${e}]\n${a}`:`[${e}]`),a&&o?`${a}\n${o}`:a||o}function ki(e,{maxDepth:t=1e3,numbersAsFloat:n=!1}={}){if(xi(e)!==`object`)throw TypeError(`stringify can only be called with an object`);let r=Oi(0,e,``,t,n);return r[r.length-1]===`
292
292
  `?r:r+`
293
293
  `}function Ai(e,t){let n=z(t,e);return n.length>0&&!n.startsWith(`..`)&&!oe(n)}const ji=e=>{try{let t=re(`git`,[`rev-parse`,`--show-toplevel`],{cwd:e,encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim();return t.length>0?t:null}catch{return null}};function Mi(e,t={}){let n=t.homeDir??V(),r=t.gitTopLevel??ji,i=ce(e),a;try{a=ae(i)}catch{a=i}let o=a,s=0;for(;s<30&&!(o===n||o===`/`||o===``);){if(p(o))return{projectRoot:o,defaultContentDir:`.`,ancestorPromoted:o!==a,gitRootPromoted:!1};let e=L(o);if(e===o)break;o=e,s+=1}let c=r(a);return c!==null&&Ai(c,n)?c===a?{projectRoot:i,defaultContentDir:`.`,ancestorPromoted:!1,gitRootPromoted:!1}:{projectRoot:c,defaultContentDir:`.`,ancestorPromoted:!1,gitRootPromoted:!0}:{projectRoot:i,defaultContentDir:`.`,ancestorPromoted:!1,gitRootPromoted:!1}}function $(e,t,n,r,i){let a=`urn:uuid:${de()}`;if(e.headersSent||e.writableEnded||e.destroyed){console.error(`[ok ui] emitProblem called after headers sent — suppressed`,{type:n,status:t,instance:a});return}let o={type:n,title:r,status:t,instance:a,...i===void 0?{}:{detail:i}},s=c.safeParse(o);if(!s.success){console.error(`[ok ui] emitProblem produced an invalid ProblemDetails body:`,{issues:s.error.issues,originalStatus:t,body:o}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-store`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:a}));return}e.writeHead(t,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-store`}),e.end(JSON.stringify(o))}const Ni=1e4;function Pi(e,t){let n=e.socket?.remoteAddress;if(n!==void 0&&!S(n))return $(t,403,`urn:ok:error:loopback-required`,`Request must originate from a loopback address.`),!0;if(!_(e.headers.host))return $(t,403,`urn:ok:error:host-not-allowed`,`Host header is not in the loopback allowlist.`),!0;let r=e.headers.origin;return r!==void 0&&!g(r)?($(t,403,`urn:ok:error:invalid-origin`,`Origin header is not in the loopback allowlist.`),!0):!1}const Fi=3e4;function Ii(e,t){let n=e.socket?.remoteAddress;if(n!==void 0&&!S(n)||!_(e.headers.host))return t.destroy(),!0;let r=e.headers.origin;return typeof r==`string`&&!g(r)?(t.destroy(),!0):!1}function Li(e,t,n,r,i,a){a.add(t),t.once(`close`,()=>a.delete(t));let o=ve({host:r,port:i,timeout:Ni});a.add(o),o.once(`close`,()=>a.delete(o));let s=!1,c=n=>{if(!s){if(s=!0,n!==void 0){let t=n.err;console.warn(JSON.stringify({event:n.event,upstreamHost:r,upstreamPort:i,url:e.url,code:t instanceof Error?t.code:void 0,message:t instanceof Error?t.message:void 0}))}try{o.destroy()}catch{}try{t.destroy()}catch{}}};o.once(`connect`,()=>{o.setTimeout(0);let a=[`${e.method??`GET`} ${e.url??`/`} HTTP/1.1`,`host: ${r}:${i}`];for(let[t,n]of Object.entries(e.headers))if(t.toLowerCase()!==`host`&&n!==void 0)if(Array.isArray(n))for(let e of n)a.push(`${t}: ${e}`);else a.push(`${t}: ${n}`);try{o.write(`${a.join(`\r
294
- `)}\r\n\r\n`),n.length>0&&o.write(n)}catch(e){c({event:`proxy-upgrade-handshake-write-failed`,err:e});return}o.on(`data`,e=>{t.writable&&t.write(e)}),t.on(`data`,e=>{o.writable&&o.write(e)})}),o.once(`timeout`,()=>{c({event:`proxy-upgrade-upstream-connect-timeout`})}),o.on(`error`,e=>c({event:`proxy-upgrade-upstream-error`,err:e})),t.on(`error`,e=>c({event:`proxy-upgrade-client-error`,err:e})),o.once(`close`,()=>c()),t.once(`close`,()=>c())}const Ri=[`connection`,`keep-alive`,`proxy-authenticate`,`proxy-authorization`,`te`,`trailer`,`transfer-encoding`,`upgrade`,`cookie`,`set-cookie`];async function zi(e){let t=e.upstreamTimeoutMs??Ni,n=new Set,r=he((n,r)=>{Pi(n,r)||Vi(n,r,e.upstreamHost,e.upstreamPort,t)});r.on(`upgrade`,(t,r,i)=>{Ii(t,r)||Li(t,r,i,e.upstreamHost,e.upstreamPort,n)}),await new Promise((t,n)=>{let i=e=>n(e);r.once(`error`,i),r.listen(e.listenPort,e.host,()=>{r.off(`error`,i),t()})});let i=r.address();return{httpServer:r,port:typeof i==`object`&&i?i.port:e.listenPort,close:()=>new Promise(e=>{for(let e of n)try{e.destroy()}catch{}n.clear(),r.close(()=>e()),r.closeIdleConnections()})}}function Bi(e,t,n){Vi(e,t,n.upstreamHost,n.upstreamPort,n.upstreamTimeoutMs??Ni)}function Vi(e,t,n,r,i){let a={...e.headers};delete a.host;for(let e of Ri)delete a[e];e.setTimeout(Fi,()=>{if(t.headersSent)try{t.end()}catch{}else try{$(t,408,`urn:ok:error:request-timeout`,`Proxy request exceeded the per-request deadline.`,`Slow-loris-class: client did not finish within ${Fi/1e3}s.`)}catch{}try{e.socket?.destroy()}catch{}});let o=ge({host:n,port:r,method:e.method,path:e.url,headers:{...a,host:`${n}:${r}`}},e=>{let n={...e.headers};for(let e of Ri)delete n[e];t.writeHead(e.statusCode??502,n),e.pipe(t),e.once(`error`,()=>{try{t.end()}catch{}})});i>0&&o.setTimeout(i,()=>{if(!t.headersSent)$(t,504,`urn:ok:error:gateway-timeout`,`Upstream did not respond before the gateway deadline.`,`Upstream timeout: ${i/1e3}s elapsed without a response.`);else try{t.end()}catch{}o.destroy()}),o.on(`error`,()=>{if(!t.headersSent)$(t,502,`urn:ok:error:collab-server-not-running`,`Collab server is unreachable.`,`Upstream connection failed or dropped before a response was received.`);else try{t.end()}catch{}}),e.on(`error`,()=>{o.destroy()}),e.pipe(o)}const Hi=39847,Ui=39848;async function Wi(e){await Promise.all(e.map(e=>new Promise(t=>{e.close(()=>t())})))}async function Gi(e){let{existsSync:t}=await import(`node:fs`),{createServer:n}=await import(`node:http`),{resolve:r}=await import(`node:path`),{acquireUiLock:i,clearArmedPaneTarget:c,createAssetServeMiddleware:l,createContentFilter:u,readArmedPaneTarget:f,readServerLock:p,releaseUiLock:m,updateUiLockPort:h}=await import(`./dist-BxQnNdO0.mjs`),{default:g}=await import(`./build-CCDQyip-.mjs`),{resolveContentDir:_,resolveLockDir:v}=await import(`./dist-BxQnNdO0.mjs`),y=_(e.config,e.cwd),b=v(e.cwd);i(b,{port:0,worktreeRoot:e.cwd});let x=import.meta.dirname??new URL(`.`,import.meta.url).pathname,S=[r(x,`public`),r(x,`../../app/dist`),r(x,`../../../app/dist`)],C=e.assetDir??S.find(e=>t(e)),w=C?g(C,{single:!0,gzip:!0,etag:!0,dev:!0,extensions:[]}):null,ee=t(y)?l({contentFilter:u({projectDir:e.cwd,contentDir:y}),contentSirv:g(y,{dotfiles:!1,dev:!0,extensions:[]}),inlineExtensions:a,assetExtensions:d,blocklistExtensions:s}):null,T=e.port,E=null,D=(e,t)=>{let n=e.url?.split(`?`)[0];if(e.method===`GET`&&(n===`/`||n===``)){let e=f(b);if(e&&!/[\r\n]/.test(e)){c(b),t.statusCode=302,t.setHeader(`Location`,`/${e}`),t.setHeader(`Cache-Control`,`no-store`),t.end();return}}if((n===`/`||n===``)&&(e.url=`/index.html`),!(n?.startsWith(`/api/`)&&Pi(e,t))){if(n===`/api/config`&&e.method===`DELETE`){c(b),t.setHeader(`Cache-Control`,`no-store`),t.statusCode=204,t.end();return}if(n===`/api/config`&&(e.method===`GET`||e.method===`HEAD`)){E?.();let n=p(b),r=e.headers.host??`localhost:${T}`,i=n&&n.port>0?`ws://${r}/collab`:null,a=f(b),o=JSON.stringify({collabUrl:i,previewUrl:null,port:T,paneTarget:a});t.setHeader(`Content-Type`,`application/json`),t.setHeader(`Cache-Control`,`no-store`),t.setHeader(`X-Content-Type-Options`,`nosniff`),t.statusCode=200,e.method===`HEAD`?t.end():t.end(o);return}if(n?.startsWith(`/api/`)){E?.();let r=p(b);if(!r||r.port<=0){$(t,503,`urn:ok:error:collab-server-not-running`,"Collab server not running. Start `ok start` or run `ok status`.",`Path: ${n}`);return}Bi(e,t,{upstreamHost:`localhost`,upstreamPort:r.port});return}if(w&&n?.startsWith(`/assets/`)){w(e,t,()=>{ee?ee(e,t,()=>Ki(t)):Ki(t)});return}if(ee){ee(e,t,()=>{w?w(e,t):Ki(t)});return}if(w){w(e,t);return}Ki(t)}},O=new Set,k=(e,t,n)=>{if(Ii(e,t))return;let r=e.url?.split(`?`)[0]??``;if(r!==`/collab`&&!r.startsWith(`/collab/`)){t.destroy();return}let i=p(b);if(!i||i.port<=0){console.warn(JSON.stringify({event:`ok-ui-upgrade-no-collab-lock`,url:r,reason:"server.lock missing or port unbound — is `ok start` running?"})),t.destroy();return}Li(e,t,n,`localhost`,i.port,O)},A=()=>{for(let e of O)try{e.destroy()}catch{}O.clear()},te=e.host===void 0?[`::1`,`127.0.0.1`]:[e.host],ne=[],j=e.port,re=e=>e instanceof Error&&e.code===`EADDRINUSE`,M=async()=>{await Promise.all(ne.splice(0).map(e=>new Promise(t=>{try{e.close(()=>t())}catch{t()}})))},ie=async e=>{j=e;for(let e of te){let t=n(D);t.on(`upgrade`,k),ne.push(t),await new Promise((n,r)=>{let i=e=>r(e);t.once(`error`,i),t.listen(j,e,()=>{t.off(`error`,i);let e=t.address();typeof e==`object`&&e&&(j=e.port),n()})})}};try{try{await ie(e.port)}catch(t){if(e.fallbackToKernel===!0&&re(t))await M(),await ie(0);else throw t}}catch(e){await M();try{m(b)}catch{}throw e}let N=j;T=N,h(b,N);let ae=e.scheduler??o,P=e.safetyNetMs??432e5,F=null,I=!1,L=!1,oe=()=>{I||(I=!0,F!==null&&(ae.clearTimeout(F),F=null))},R=()=>{if(oe(),!L){L=!0;try{m(b)}catch{}}},se=()=>{I||P<=0||(F!==null&&(ae.clearTimeout(F),F=null),F=ae.setTimeout(()=>{F=null,console.warn(`[ui] safety-net (${P}ms) reached — shutting down (D-025 backstop)`);try{e.onSafetyNet?.()}catch{}A();for(let e of ne)try{e.close()}catch{}R()},P))},z=()=>{I||P<=0||se()};return E=z,se(),{httpServers:ne,port:N,release:R,detachSafetyNet:oe,nudgeSafetyNet:z,drainUpgradeSockets:A}}function Ki(e){e.headersSent||e.writableEnded||e.destroyed||(e.setHeader(`X-Content-Type-Options`,`nosniff`),e.setHeader(`Cache-Control`,`no-store`),e.statusCode=404,e.end())}function qi(e,t){if(e!==void 0){let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<0||t>65535)throw Error(`Invalid --port value '${e}'`);return{port:t,fallbackToKernel:!1}}if(t!==void 0&&t!==``){let e=Number.parseInt(t,10);if(Number.isNaN(e)||e<0||e>65535)throw Error(`Invalid PORT env value '${t}'`);return{port:e,fallbackToKernel:!1}}return{port:Hi,fallbackToKernel:!0}}async function Ji(e){let t=e.readLock??(async()=>{let{readUiLock:t}=await import(`./dist-BxQnNdO0.mjs`);return t(e.lockDir)}),n=await t();if(!n)throw Error(`UI lock collision reported but the lock disappeared before handling — retry acquiring.`);if(n.port===e.requestedPort&&n.port>0)return{mode:`already-running`,port:n.port};let r=n.port;if(r===0){let n=Date.now()+(e.pollDeadlineMs??2e3),i=e.pollIntervalMs??100;for(;Date.now()<n;){await new Promise(e=>{setTimeout(e,i)});let e=await t();if(e&&e.port>0){r=e.port;break}}if(r===0)throw Error("UI did not bind within 2s; run `ok clean`");if(r===e.requestedPort)return{mode:`already-running`,port:r}}return{mode:`proxy`,handle:await zi({listenPort:e.requestedPort,host:e.host,upstreamHost:`localhost`,upstreamPort:r}),upstreamPort:r}}function Yi(e){return new i(`ui`).description(`Serve the Open Knowledge React editor UI`).option(`-p, --port <port>`,`UI port (default: $PORT env or ${Hi}, kernel-allocated fallback if busy)`).option(`-H, --host <host>`,"UI host. Default: two-socket loopback bind (`[::1]` + `127.0.0.1`) so cross-family collisions fail loud. Pass an explicit host (e.g. `127.0.0.1`, `0.0.0.0`) to bind a single socket on that host.").action(async t=>{let{dim:n}=await import(`./colors-CkPULM8m.mjs`),{UiLockCollisionError:r}=await import(`./dist-BxQnNdO0.mjs`),{resolveLockDir:i}=await import(`./dist-BxQnNdO0.mjs`),a=e(),o=t.host,s;try{s=qi(t.port,process.env.PORT)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=1;return}let c=s.port;try{let e=await Gi({config:a,cwd:process.cwd(),port:c,fallbackToKernel:s.fallbackToKernel,host:o}),t=o===void 0||o===`::`||o===`0.0.0.0`?`localhost`:o;console.log(`${n(`[ui]`)} listening on http://${t}:${e.port}`);let r=!1,i=t=>{if(r)return;r=!0,console.log(n(`\n[ui] Shutting down (${t})`)),e.detachSafetyNet();let i=()=>{try{e.release()}finally{process.exit(process.exitCode??0)}};e.drainUpgradeSockets(),Wi(e.httpServers).then(i,i),setTimeout(i,2e3).unref()};process.once(`SIGINT`,()=>i(`SIGINT`)),process.once(`SIGTERM`,()=>i(`SIGTERM`));return}catch(e){if(!(e instanceof r))throw e;let t=i(process.cwd()),a=o??`localhost`,s;try{s=await Ji({requestedPort:c,host:a,lockDir:t})}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}if(s.mode===`already-running`){if(console.log(`UI already running at http://${a}:${s.port}`),Xi(process)){await new Promise(e=>{let t=t=>{console.log(n(`\n[ui-keepalive] Shutting down (${t})`)),e()};process.once(`SIGINT`,()=>t(`SIGINT`)),process.once(`SIGTERM`,()=>t(`SIGTERM`))});return}process.exit(0)}console.log(`UI running at http://${a}:${s.upstreamPort}; acting as HTTP proxy on port ${s.handle.port}`);let l=!1,u=e=>{l||(l=!0,console.log(n(`\n[ui-proxy] Shutting down (${e})`)),s.handle.close().finally(()=>process.exit(process.exitCode??0)),setTimeout(()=>process.exit(process.exitCode??0),2e3).unref())};process.once(`SIGINT`,()=>u(`SIGINT`)),process.once(`SIGTERM`,()=>u(`SIGTERM`))}})}function Xi(e){let t=e.stdout.isTTY===!0,n=typeof e.env.PORT==`string`&&e.env.PORT!==``;return!t||n}function Zi(e){if(!M(e))return{};let t=N(e,`utf-8`).trim();if(t===``)return{};try{let n=JSON.parse(t);if(T(n))return n;throw Error(`${e} root must be a JSON object`)}catch(t){throw t instanceof SyntaxError?Error(`${e} contains invalid JSON: ${t.message}`):t}}function Qi(e){if(!M(e))return{};let t=N(e,`utf-8`).trim();if(t===``)return{};try{let n=yi(t);if(T(n))return n;throw Error(`${e} root must be a TOML table`)}catch(t){throw Error(`${e} contains invalid TOML: ${t instanceof Error?t.message:String(t)}`)}}function $i(e,t){x(e,`${JSON.stringify(t,null,2)}\n`)}function ea(e,t){let n=ki(t);x(e,n.endsWith(`
294
+ `)}\r\n\r\n`),n.length>0&&o.write(n)}catch(e){c({event:`proxy-upgrade-handshake-write-failed`,err:e});return}o.on(`data`,e=>{t.writable&&t.write(e)}),t.on(`data`,e=>{o.writable&&o.write(e)})}),o.once(`timeout`,()=>{c({event:`proxy-upgrade-upstream-connect-timeout`})}),o.on(`error`,e=>c({event:`proxy-upgrade-upstream-error`,err:e})),t.on(`error`,e=>c({event:`proxy-upgrade-client-error`,err:e})),o.once(`close`,()=>c()),t.once(`close`,()=>c())}const Ri=[`connection`,`keep-alive`,`proxy-authenticate`,`proxy-authorization`,`te`,`trailer`,`transfer-encoding`,`upgrade`,`cookie`,`set-cookie`];async function zi(e){let t=e.upstreamTimeoutMs??Ni,n=new Set,r=he((n,r)=>{Pi(n,r)||Vi(n,r,e.upstreamHost,e.upstreamPort,t)});r.on(`upgrade`,(t,r,i)=>{Ii(t,r)||Li(t,r,i,e.upstreamHost,e.upstreamPort,n)}),await new Promise((t,n)=>{let i=e=>n(e);r.once(`error`,i),r.listen(e.listenPort,e.host,()=>{r.off(`error`,i),t()})});let i=r.address();return{httpServer:r,port:typeof i==`object`&&i?i.port:e.listenPort,close:()=>new Promise(e=>{for(let e of n)try{e.destroy()}catch{}n.clear(),r.close(()=>e()),r.closeIdleConnections()})}}function Bi(e,t,n){Vi(e,t,n.upstreamHost,n.upstreamPort,n.upstreamTimeoutMs??Ni)}function Vi(e,t,n,r,i){let a={...e.headers};delete a.host;for(let e of Ri)delete a[e];e.setTimeout(Fi,()=>{if(t.headersSent)try{t.end()}catch{}else try{$(t,408,`urn:ok:error:request-timeout`,`Proxy request exceeded the per-request deadline.`,`Slow-loris-class: client did not finish within ${Fi/1e3}s.`)}catch{}try{e.socket?.destroy()}catch{}});let o=ge({host:n,port:r,method:e.method,path:e.url,headers:{...a,host:`${n}:${r}`}},e=>{let n={...e.headers};for(let e of Ri)delete n[e];t.writeHead(e.statusCode??502,n),e.pipe(t),e.once(`error`,()=>{try{t.end()}catch{}})});i>0&&o.setTimeout(i,()=>{if(!t.headersSent)$(t,504,`urn:ok:error:gateway-timeout`,`Upstream did not respond before the gateway deadline.`,`Upstream timeout: ${i/1e3}s elapsed without a response.`);else try{t.end()}catch{}o.destroy()}),o.on(`error`,()=>{if(!t.headersSent)$(t,502,`urn:ok:error:collab-server-not-running`,`Collab server is unreachable.`,`Upstream connection failed or dropped before a response was received.`);else try{t.end()}catch{}}),e.on(`error`,()=>{o.destroy()}),e.pipe(o)}const Hi=39847,Ui=39848;async function Wi(e){await Promise.all(e.map(e=>new Promise(t=>{e.close(()=>t())})))}async function Gi(e){let{existsSync:t}=await import(`node:fs`),{createServer:n}=await import(`node:http`),{resolve:r}=await import(`node:path`),{acquireUiLock:i,clearArmedPaneTarget:c,createAssetServeMiddleware:l,createContentFilter:u,readArmedPaneTarget:f,readServerLock:p,releaseUiLock:m,updateUiLockPort:h}=await import(`./dist-Db57TeUO.mjs`),{default:g}=await import(`./build-CCDQyip-.mjs`),{resolveContentDir:_,resolveLockDir:v}=await import(`./dist-Db57TeUO.mjs`),y=_(e.config,e.cwd),b=v(e.cwd);i(b,{port:0,worktreeRoot:e.cwd});let x=import.meta.dirname??new URL(`.`,import.meta.url).pathname,S=[r(x,`public`),r(x,`../../app/dist`),r(x,`../../../app/dist`)],C=e.assetDir??S.find(e=>t(e)),w=C?g(C,{single:!0,gzip:!0,etag:!0,dev:!0,extensions:[]}):null,ee=t(y)?l({contentFilter:u({projectDir:e.cwd,contentDir:y}),contentSirv:g(y,{dotfiles:!1,dev:!0,extensions:[]}),inlineExtensions:a,assetExtensions:d,blocklistExtensions:s}):null,T=e.port,E=null,D=(e,t)=>{let n=e.url?.split(`?`)[0];if(e.method===`GET`&&(n===`/`||n===``)){let e=f(b);if(e&&!/[\r\n]/.test(e)){c(b),t.statusCode=302,t.setHeader(`Location`,`/${e}`),t.setHeader(`Cache-Control`,`no-store`),t.end();return}}if((n===`/`||n===``)&&(e.url=`/index.html`),!(n?.startsWith(`/api/`)&&Pi(e,t))){if(n===`/api/config`&&e.method===`DELETE`){c(b),t.setHeader(`Cache-Control`,`no-store`),t.statusCode=204,t.end();return}if(n===`/api/config`&&(e.method===`GET`||e.method===`HEAD`)){E?.();let n=p(b),r=e.headers.host??`localhost:${T}`,i=n&&n.port>0?`ws://${r}/collab`:null,a=f(b),o=JSON.stringify({collabUrl:i,previewUrl:null,port:T,paneTarget:a});t.setHeader(`Content-Type`,`application/json`),t.setHeader(`Cache-Control`,`no-store`),t.setHeader(`X-Content-Type-Options`,`nosniff`),t.statusCode=200,e.method===`HEAD`?t.end():t.end(o);return}if(n?.startsWith(`/api/`)){E?.();let r=p(b);if(!r||r.port<=0){$(t,503,`urn:ok:error:collab-server-not-running`,"Collab server not running. Start `ok start` or run `ok status`.",`Path: ${n}`);return}Bi(e,t,{upstreamHost:`localhost`,upstreamPort:r.port});return}if(w&&n?.startsWith(`/assets/`)){w(e,t,()=>{ee?ee(e,t,()=>Ki(t)):Ki(t)});return}if(ee){ee(e,t,()=>{w?w(e,t):Ki(t)});return}if(w){w(e,t);return}Ki(t)}},O=new Set,k=(e,t,n)=>{if(Ii(e,t))return;let r=e.url?.split(`?`)[0]??``;if(r!==`/collab`&&!r.startsWith(`/collab/`)){t.destroy();return}let i=p(b);if(!i||i.port<=0){console.warn(JSON.stringify({event:`ok-ui-upgrade-no-collab-lock`,url:r,reason:"server.lock missing or port unbound — is `ok start` running?"})),t.destroy();return}Li(e,t,n,`localhost`,i.port,O)},A=()=>{for(let e of O)try{e.destroy()}catch{}O.clear()},te=e.host===void 0?[`::1`,`127.0.0.1`]:[e.host],ne=[],j=e.port,re=e=>e instanceof Error&&e.code===`EADDRINUSE`,M=async()=>{await Promise.all(ne.splice(0).map(e=>new Promise(t=>{try{e.close(()=>t())}catch{t()}})))},ie=async e=>{j=e;for(let e of te){let t=n(D);t.on(`upgrade`,k),ne.push(t),await new Promise((n,r)=>{let i=e=>r(e);t.once(`error`,i),t.listen(j,e,()=>{t.off(`error`,i);let e=t.address();typeof e==`object`&&e&&(j=e.port),n()})})}};try{try{await ie(e.port)}catch(t){if(e.fallbackToKernel===!0&&re(t))await M(),await ie(0);else throw t}}catch(e){await M();try{m(b)}catch{}throw e}let N=j;T=N,h(b,N);let ae=e.scheduler??o,P=e.safetyNetMs??432e5,F=null,I=!1,L=!1,oe=()=>{I||(I=!0,F!==null&&(ae.clearTimeout(F),F=null))},R=()=>{if(oe(),!L){L=!0;try{m(b)}catch{}}},se=()=>{I||P<=0||(F!==null&&(ae.clearTimeout(F),F=null),F=ae.setTimeout(()=>{F=null,console.warn(`[ui] safety-net (${P}ms) reached — shutting down (D-025 backstop)`);try{e.onSafetyNet?.()}catch{}A();for(let e of ne)try{e.close()}catch{}R()},P))},z=()=>{I||P<=0||se()};return E=z,se(),{httpServers:ne,port:N,release:R,detachSafetyNet:oe,nudgeSafetyNet:z,drainUpgradeSockets:A}}function Ki(e){e.headersSent||e.writableEnded||e.destroyed||(e.setHeader(`X-Content-Type-Options`,`nosniff`),e.setHeader(`Cache-Control`,`no-store`),e.statusCode=404,e.end())}function qi(e,t){if(e!==void 0){let t=Number.parseInt(e,10);if(Number.isNaN(t)||t<0||t>65535)throw Error(`Invalid --port value '${e}'`);return{port:t,fallbackToKernel:!1}}if(t!==void 0&&t!==``){let e=Number.parseInt(t,10);if(Number.isNaN(e)||e<0||e>65535)throw Error(`Invalid PORT env value '${t}'`);return{port:e,fallbackToKernel:!1}}return{port:Hi,fallbackToKernel:!0}}async function Ji(e){let t=e.readLock??(async()=>{let{readUiLock:t}=await import(`./dist-Db57TeUO.mjs`);return t(e.lockDir)}),n=await t();if(!n)throw Error(`UI lock collision reported but the lock disappeared before handling — retry acquiring.`);if(n.port===e.requestedPort&&n.port>0)return{mode:`already-running`,port:n.port};let r=n.port;if(r===0){let n=Date.now()+(e.pollDeadlineMs??2e3),i=e.pollIntervalMs??100;for(;Date.now()<n;){await new Promise(e=>{setTimeout(e,i)});let e=await t();if(e&&e.port>0){r=e.port;break}}if(r===0)throw Error("UI did not bind within 2s; run `ok clean`");if(r===e.requestedPort)return{mode:`already-running`,port:r}}return{mode:`proxy`,handle:await zi({listenPort:e.requestedPort,host:e.host,upstreamHost:`localhost`,upstreamPort:r}),upstreamPort:r}}function Yi(e){return new i(`ui`).description(`Serve the Open Knowledge React editor UI`).option(`-p, --port <port>`,`UI port (default: $PORT env or ${Hi}, kernel-allocated fallback if busy)`).option(`-H, --host <host>`,"UI host. Default: two-socket loopback bind (`[::1]` + `127.0.0.1`) so cross-family collisions fail loud. Pass an explicit host (e.g. `127.0.0.1`, `0.0.0.0`) to bind a single socket on that host.").action(async t=>{let{dim:n}=await import(`./colors-CkPULM8m.mjs`),{UiLockCollisionError:r}=await import(`./dist-Db57TeUO.mjs`),{resolveLockDir:i}=await import(`./dist-Db57TeUO.mjs`),a=e(),o=t.host,s;try{s=qi(t.port,process.env.PORT)}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exitCode=1;return}let c=s.port;try{let e=await Gi({config:a,cwd:process.cwd(),port:c,fallbackToKernel:s.fallbackToKernel,host:o}),t=o===void 0||o===`::`||o===`0.0.0.0`?`localhost`:o;console.log(`${n(`[ui]`)} listening on http://${t}:${e.port}`);let r=!1,i=t=>{if(r)return;r=!0,console.log(n(`\n[ui] Shutting down (${t})`)),e.detachSafetyNet();let i=()=>{try{e.release()}finally{process.exit(process.exitCode??0)}};e.drainUpgradeSockets(),Wi(e.httpServers).then(i,i),setTimeout(i,2e3).unref()};process.once(`SIGINT`,()=>i(`SIGINT`)),process.once(`SIGTERM`,()=>i(`SIGTERM`));return}catch(e){if(!(e instanceof r))throw e;let t=i(process.cwd()),a=o??`localhost`,s;try{s=await Ji({requestedPort:c,host:a,lockDir:t})}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(1)}if(s.mode===`already-running`){if(console.log(`UI already running at http://${a}:${s.port}`),Xi(process)){await new Promise(e=>{let t=t=>{console.log(n(`\n[ui-keepalive] Shutting down (${t})`)),e()};process.once(`SIGINT`,()=>t(`SIGINT`)),process.once(`SIGTERM`,()=>t(`SIGTERM`))});return}process.exit(0)}console.log(`UI running at http://${a}:${s.upstreamPort}; acting as HTTP proxy on port ${s.handle.port}`);let l=!1,u=e=>{l||(l=!0,console.log(n(`\n[ui-proxy] Shutting down (${e})`)),s.handle.close().finally(()=>process.exit(process.exitCode??0)),setTimeout(()=>process.exit(process.exitCode??0),2e3).unref())};process.once(`SIGINT`,()=>u(`SIGINT`)),process.once(`SIGTERM`,()=>u(`SIGTERM`))}})}function Xi(e){let t=e.stdout.isTTY===!0,n=typeof e.env.PORT==`string`&&e.env.PORT!==``;return!t||n}function Zi(e){if(!M(e))return{};let t=N(e,`utf-8`).trim();if(t===``)return{};try{let n=JSON.parse(t);if(T(n))return n;throw Error(`${e} root must be a JSON object`)}catch(t){throw t instanceof SyntaxError?Error(`${e} contains invalid JSON: ${t.message}`):t}}function Qi(e){if(!M(e))return{};let t=N(e,`utf-8`).trim();if(t===``)return{};try{let n=yi(t);if(T(n))return n;throw Error(`${e} root must be a TOML table`)}catch(t){throw Error(`${e} contains invalid TOML: ${t instanceof Error?t.message:String(t)}`)}}function $i(e,t){x(e,`${JSON.stringify(t,null,2)}\n`)}function ea(e,t){let n=ki(t);x(e,n.endsWith(`
295
295
  `)?n:`${n}\n`)}const ta=e=>e!==`project`,na=e=>e!==`user`;async function ra(){let e=await Bn({message:`Where should the MCP server be configured?
296
296
  `,required:!1,theme:{icon:{checked:`[x]`,unchecked:`[ ]`}},choices:[{name:`User-level (~/.claude.json, ~/.cursor/mcp.json, …)`,value:`user`,checked:!0},{name:`Project-level (.mcp.json, .cursor/mcp.json, …)`,value:`project`,checked:!0}]});return e.includes(`user`)&&e.includes(`project`)?`both`:e.includes(`user`)?`user`:e.includes(`project`)?`project`:null}async function ia(e){return e.mcp===!1?null:e.scope?e.scope:e.isTTY??process.stdout.isTTY?(e.promptFn??ra)():`both`}async function aa(e){return Yr({message:`How do you want to handle Open Knowledge config files (.ok/, .mcp.json, project skills, launch.json)?`,default:e,choices:[{name:`Share with my team (commit alongside content)`,value:`shared`,description:`OK config gets committed alongside your project content.`},{name:`Local only (keep out of git via .git/info/exclude)`,value:`local-only`,description:"OK config stays on this machine only; teammates do not see it. Safe escape hatch via `ok config-sharing share`."}]})}async function oa(e){if(e.sharing!==void 0)return e.sharing;let t=Nt(e.projectRoot)===`local-only`?`local-only`:`shared`;return e.isTTY??process.stdout.isTTY?(e.promptFn??aa)(t):t}const sa=`0.0.1`,ca=`open-knowledge-ui`,la=[`-y`,`@inkeep/open-knowledge@latest`,`ui`],ua=`# ok-ui-v1`,da=`${ua}
297
297
  UIPORT="\${PORT:-${Ui}}"
@@ -310,6 +310,6 @@ UIPORT="\${PORT:-${Ui}}"
310
310
  unset PORT
311
311
  exec node "${xt()}" start --ui-port "$UIPORT"`],port:Ui,autoPort:!0}:{name:ca,runtimeExecutable:`/bin/sh`,runtimeArgs:[`-l`,`-c`,da],port:Ui,autoPort:!0};try{if(j(n,e),!M(n))return ie(L(n),{recursive:!0}),P(n,`${JSON.stringify({version:sa,configurations:[r]},null,2)}\n`,`utf-8`),{action:`created`,configPath:n};let t=N(n,`utf-8`).trim(),i=t?JSON.parse(t):{};if(!T(i))return{action:`failed`,configPath:n,error:`launch.json root is not an object`};let a=Array.isArray(i.configurations)?i.configurations:[],o=a.findIndex(e=>T(e)&&e.name===`open-knowledge-ui`);o>=0?a[o]=r:a.push(r);let s={...i,version:i.version??sa,configurations:a};return P(n,`${JSON.stringify(s,null,2)}\n`,`utf-8`),{action:o>=0?`merged`:`created`,configPath:n}}catch(e){return{action:`failed`,configPath:n,error:e instanceof Error?e.message:String(e)}}}function pa(e,t,n){try{return M(e.detectPath?.(t,n)??L(e.configPath(t,n)))}catch{return!1}}function ma(e,t,n,r,i){let a=e.serverName(t),o;try{o=i??e.configPath(t,r)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:``,serverName:a,error:t instanceof Error?t.message:String(t)}}if(!i&&!n.skipAvailabilityCheck&&!pa(e,t,r))return{editorId:e.id,label:e.label,action:`skipped-missing`,configPath:o,serverName:a};if(i!==void 0)try{j(o,t)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:o,serverName:a,error:t instanceof Error?t.message:String(t),configScope:`project`}}let s;try{s=e.buildEntry(t,n)}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:o,serverName:a,error:t instanceof Error?t.message:String(t),...i===void 0?{}:{configScope:`project`}}}try{ie(L(o),{recursive:!0})}catch(t){return{editorId:e.id,label:e.label,action:`failed`,configPath:o,serverName:a,error:t instanceof Error?t.message:String(t),...i===void 0?{}:{configScope:`project`}}}let c,l;try{f(`${o}.lock`,()=>{let t=e.format===`toml`?Qi(o):Zi(o),n=t[e.topLevelKey]??{};c=n[a];let r={...t,[e.topLevelKey]:{...n,[a]:s}};e.format===`toml`?ea(o,r):$i(o,r)},{onWarn:(e,t)=>process.stderr.write(`[ok] ${e} ${JSON.stringify(t)}\n`)})}catch(e){l=e instanceof Error?e:Error(String(e))}return l?{editorId:e.id,label:e.label,action:`failed`,configPath:o,serverName:a,error:l.message,...i===void 0?{}:{configScope:`project`}}:{editorId:e.id,label:e.label,action:c===void 0?`written`:`overwritten`,configPath:o,serverName:a,...i===void 0?{}:{configScope:`project`}}}function ha(e,t){let n=e.projectConfigPath?.(t);if(!(!n||!M(n)))return{editorId:e.id,label:e.label,path:n}}async function ga(e){let t=kt(e.editors),n={mode:`published`,skipAvailabilityCheck:!0};return t.map(t=>ma(t,``,n,e.home))}function _a(e,t,n,r){let i=va(e,t,n,r);return i.kind===`present`?i.entry:null}function va(e,t,n,r){let i;try{i=r??e.configPath(t,n)}catch{return{kind:`absent`}}if(!M(i))return{kind:`absent`};let a;try{a=N(i,`utf-8`)}catch(e){return{kind:`corrupt`,error:e instanceof Error?e.message:String(e)}}if(a.trim()===``)return{kind:`corrupt`,error:`file is empty`};let o;try{o=e.format===`toml`?Qi(i):Zi(i)}catch(e){return{kind:`corrupt`,error:e instanceof Error?e.message:String(e)}}let s=o[e.topLevelKey];if(!T(s))return{kind:`no-entry`};let c=s[e.serverName(t)];return T(c)?{kind:`present`,entry:c}:{kind:`no-entry`}}async function ya(e={}){let t=ce(e.cwd??process.cwd()),n=Mi(t,{homeDir:e.home}),r=n.projectRoot,i=!M(R(r,`.ok`));n.ancestorPromoted?console.log(`[ok] Opened existing project at ${r}`):n.gitRootPromoted&&i&&console.log(`[ok] Initialized OK at ${r} — opened parent of ${z(r,t)} because it contains a .git folder`);let a={mode:e.devMcp?`dev`:`published`},o=await w(r),s;try{s=v(r,{contentDir:n.defaultContentDir})}catch(t){let n=G.claude.configPath(r,e.home);return{projectRoot:r,contentCreated:[],contentUpdated:[],contentSkipped:[],editors:[],projectSkills:[],legacyProjectConfigs:[],didGitInit:o.didInit,rootGitignoreCreated:!1,claudeDesktopDetected:!1,mcpAction:`failed`,mcpPath:n,mcpError:`Content scaffolding failed: ${t instanceof Error?t.message:String(t)}`,sharing:{kind:`no-exclude`,reason:`no-git`,localOnlyRequested:!1}}}let c=!1;if(o.didInit)try{c=m(r)===`created`}catch(e){console.warn(`[ok] Skipping .gitignore seed at ${r}: ${e instanceof Error?e.message:String(e)}`)}let l=await ia({scope:e.scope,mcp:e.mcp,isTTY:e.isTTY,promptFn:e.promptFn}),u=e.editors??Ca(r,e.home),d=e.editors??_t.filter(e=>G[e].projectConfigPath!==void 0),f=kt(u),p=kt(d),h=e.mcp===!1||l===null,g=Array.from(new Map([...f,...h?[]:p].map(e=>[e.id,e])).values()),_=f.filter(t=>pa(t,r,e.home)),y=[],x=[],S=new Set;for(let t of g){if(h){let n=``;try{n=t.configPath(r,e.home)}catch{}y.push({editorId:t.id,label:t.label,action:`skipped-flag`,configPath:n,serverName:t.serverName(r)});continue}if(ta(l)&&f.includes(t)&&y.push(ma(t,r,a,e.home)),na(l)&&p.includes(t)&&t.projectConfigPath){let n=t.projectConfigPath(r),i=ma(t,r,a,e.home,n);y.push(i),(i.action===`written`||i.action===`overwritten`)&&S.add(n)}}for(let e of p)e.projectSkillPath&&x.push(ne(e,r));let C=!h&&l!==null&&na(l)?p.filter(e=>!e.projectConfigPath).map(e=>e.label):void 0,T=h?[]:_.map(e=>ha(e,r)).filter(e=>e!==void 0).filter(e=>!S.has(e.path)),E=_.some(e=>e.id===`claude`)&&!h?fa(r,a):void 0,D=await(e.installUserSkill??b)({home:e.home}),O=ee({home:e.home}),k=h?`skipped-flag`:`skipped-missing`,A=y.find(e=>e.editorId===`claude`)??y[0]??{action:k,configPath:G.claude.configPath(r,e.home)},te=await ba({projectRoot:r,desiredMode:await oa({sharing:e.sharing,projectRoot:r,isTTY:e.isTTY,promptFn:e.sharingPromptFn}),explicitFlag:e.sharing});return{projectRoot:r,contentCreated:s.created,contentUpdated:s.updated,contentSkipped:s.skipped,editors:y,projectSkills:x,legacyProjectConfigs:T,launchJson:E,skillInstall:D,didGitInit:o.didInit,rootGitignoreCreated:c,claudeDesktopDetected:O,mcpAction:A.action,mcpPath:A.configPath,mcpError:`error`in A?A.error:void 0,projectScopeUnsupportedLabels:C,sharing:te}}async function ba(e){let{projectRoot:t,desiredMode:n,explicitFlag:r}=e,i=Nt(t);if(i===`no-git`)return{kind:`no-exclude`,reason:`no-git`,localOnlyRequested:r===`local-only`};let a=At(t);if(n===`local-only`){let e=jt(t,a);if(e.kind===`refused-tracked`){let t=e;return{kind:`refused-tracked`,tracked:t.tracked,remediation:t.remediation}}return e.kind===`no-exclude`?{kind:`no-exclude`,reason:e.reason,localOnlyRequested:r===`local-only`}:xa(t,e,`add`)}if(i===`shared`)return{kind:`applied`,mode:`shared`,action:`noop`,appended:[],alreadyPresent:[],removed:[]};let o=Mt(t,a);return o.kind===`no-exclude`?{kind:`no-exclude`,reason:o.reason,localOnlyRequested:!1}:xa(t,o,`remove`)}function xa(e,t,n){let r=Nt(e);return n===`add`?{kind:`applied`,mode:r,action:t.appended.length>0?`added`:`noop`,appended:t.appended,alreadyPresent:t.alreadyPresent,removed:[]}:{kind:`applied`,mode:r,action:`removed`,appended:[],alreadyPresent:[],removed:t.removed}}function Sa(e,t){let n=[],r=e.editors.some(e=>e.action===`written`||e.action===`overwritten`),i=e.editors.some(e=>e.action===`failed`)||e.projectSkills.some(e=>e.action===`failed`),a=e.editors.length>0&&e.editors.every(e=>e.action===`skipped-flag`),o=e.editors.length>0&&e.editors.every(e=>e.action===`skipped-missing`),s=e=>{let n=e.configPath.startsWith(t)?z(t,e.configPath):e.configPath;switch(e.action){case`created`:return` app preview server ${n} configured for Claude Code Desktop embedded browser`;case`merged`:return` app preview server ${n} updated for Claude Code Desktop embedded browser`;case`failed`:return` app preview server ${n} FAILED: ${e.error}`}};e.didGitInit&&n.push(`Initialized git repo at ${t}/.git/ (default branch: main)`),e.rootGitignoreCreated&&n.push(`Seeded .gitignore at ${t}/.gitignore (.DS_Store)`);let c=R(t,`.ok`);if(e.contentCreated.length>0||e.contentUpdated.length>0?(n.push(A(`Content scaffolded at ${c}/`)),e.contentCreated.length>0&&n.push(` Created: ${e.contentCreated.join(`, `)}`),e.contentUpdated.length>0&&n.push(` Updated: ${e.contentUpdated.join(`, `)}`)):n.push(A(`Content already present at ${c}/`)),e.contentSkipped.length>0&&n.push(` Skipped (already exist): ${e.contentSkipped.join(`, `)}`),n.push(``),e.mcpError&&e.editors.length===0)n.push(`Warning: ${e.mcpError}`);else if(e.editors.length===0)if(n.push(A(`MCP server configuration:`)),e.mcpAction===`skipped-flag`)n.push(` MCP config not written — use without --no-mcp to configure editors`);else if(e.projectScopeUnsupportedLabels&&e.projectScopeUnsupportedLabels.length>0){let t=e.projectScopeUnsupportedLabels.join(`, `),r=e.projectScopeUnsupportedLabels.length===1?`does`:`do`;n.push(` ${t} ${r} not support project-level config; skipped`)}else n.push(` No supported editor config directories detected; skipped MCP registration`);else if(a)n.push(`MCP config not written — use without --no-mcp to configure editors`);else if(o)n.push(A(`MCP server configuration:`)),n.push(` No supported editor config directories detected; skipped MCP registration`);else{n.push(A(`MCP server configuration:`));for(let r of e.editors){let i=r.configPath.startsWith(t)?z(t,r.configPath):r.configPath.replace(/^\/Users\/[^/]+/,`~`),a=r.serverName===`open-knowledge`?``:` (${r.serverName})`,o=r.configScope===`project`?` (project)`:``,c=`${r.label}${o}`,l=` `.repeat(Math.max(1,20-c.length)),u=r.editorId===`claude-desktop`&&(r.action===`written`||r.action===`overwritten`)?` — quit and relaunch Claude Desktop to activate`:``;switch(r.action){case`written`:n.push(` ${c}${l}${i} ${D(`registered`)}${a}${u}`);break;case`overwritten`:n.push(` ${c}${l}${i} ${D(`updated`)}${a}${u}`);break;case`skipped-missing`:n.push(` ${c}${l}${i} config root missing; skipped`);break;case`failed`:n.push(` ${c}${l}${i} ${O(`FAILED`)}: ${r.error}`);break;case`skipped-flag`:break}r.editorId===`claude`&&e.launchJson&&n.push(s(e.launchJson))}if(e.projectScopeUnsupportedLabels&&e.projectScopeUnsupportedLabels.length>0){let t=e.projectScopeUnsupportedLabels.join(`, `),r=e.projectScopeUnsupportedLabels.length===1?`does`:`do`;n.push(` ${t} ${r} not support project-level config; skipped`)}}if(e.projectSkills.length>0){n.push(``),n.push(A(`Project-local skills:`));for(let r of e.projectSkills){let e=`${r.label} (project)`,i=` `.repeat(Math.max(1,20-e.length)),a=r.path?z(t,r.path):``;switch(r.action){case`written`:n.push(` ${e}${i}${a} ${D(`installed`)}`);break;case`overwritten`:n.push(` ${e}${i}${a} ${D(`updated`)}`);break;case`skipped-unsupported`:n.push(` ${e}${i}no known project skill surface; skipped`);break;case`failed`:n.push(` ${e}${i}${a} ${O(`FAILED`)}: ${r.error}`);break}}}if(i&&(n.push(``),n.push(`For failed editors, add the MCP server entry or project skill manually. See:`),n.push(` https://github.com/inkeep/open-knowledge#mcp-setup`)),e.legacyProjectConfigs.length>0){n.push(``),n.push(`Project MCP configs found:`);for(let r of e.legacyProjectConfigs)n.push(` ${r.label} ${z(t,r.path)}`);n.push(` These project-local files may override the global config. Remove them if you want fully user-scoped MCP setup in this project.`)}if(e.skillInstall)switch(n.push(``),n.push(A(`User-global skill:`)),e.skillInstall){case`installed`:n.push(` open-knowledge ${D(`installed to detected agent hosts`)} via \`npx skills\``);break;case`skip-current`:n.push(` open-knowledge ${D(`already installed at current version`)}`);break;case`failed`:n.push(` ${k(`open-knowledge install failed — MCP still configured; run manually:`)}`),n.push(` ${k(` npx skills@~1.5.0 add <bundled-path> --agent '*' -g -y --copy`)}`);break}if(e.claudeDesktopDetected&&(n.push(``),n.push(`Claude Desktop App detected. To enable in Claude Chat & Cowork, run: ${A(`ok install-skill`)}`)),e.preview?(n.push(``),n.push(te(e.preview,t))):e.previewWarning&&(n.push(``),n.push(`Content preview unavailable: ${e.previewWarning}`)),n.push(``),n.push(...Ta(e.sharing,t)),r){let t=new Set,r=e.editors.filter(e=>e.action===`written`||e.action===`overwritten`).filter(e=>!t.has(e.editorId)&&t.add(e.editorId)).map(e=>e.label);n.push(``),n.push(`${D(`✓`)} ${A(`Next steps:`)}`),n.push(` 1. Open your editor (${E(r.join(` / `))})`),n.push(` 2. Approve the MCP server when prompted`),n.push(` 3. (Optional) scaffold the starter knowledge-base structure:`),n.push(` - ${E(`ok seed`)} — empty repo, Karpathy 3-layer`),n.push(` - ${E(`mcp__open-knowledge__discover`)} — existing repo, extract conventions`),n.push(` 4. Use the MCP workflow tools as you build the wiki:`),n.push(` - ${E(`mcp__open-knowledge__ingest`)} — capture an external source`),n.push(` - ${E(`mcp__open-knowledge__research`)} — gather sources and write findings`),n.push(` - ${E(`mcp__open-knowledge__consolidate`)} — promote research to canonical articles`)}return n.join(`
312
312
  `)}function Ca(e,t){let n=[];for(let r of _t)pa(G[r],e,t)&&n.push(r);return n}function wa(){return new i(`init`).description(`Scaffold .ok/ in the current directory and register the MCP server for your editor(s)`).option(`--mcp`,`Register the MCP server for selected editors (default: true)`,!0).option(`--no-mcp`,`Scaffold the .ok/ directory but do not touch MCP config`).option(`--dev-mcp`,`Register a local dev MCP entry using node + packages/cli/dist/cli.mjs with debug logging`).addOption(new r(`--scope <scope>`,`Write MCP config at user level, project level, or both`).choices([`user`,`project`,`both`])).addOption(new r(`--shared`,`Commit OK config alongside content (the default for fresh repos)`).conflicts(`localOnly`)).addOption(new r(`--local-only`,`Keep OK config out of git via .git/info/exclude (per-clone, not committed)`).conflicts(`shared`)).action(async e=>{let t=process.cwd(),n=e.shared?`shared`:e.localOnly?`local-only`:void 0,r;try{r=await ya({cwd:t,mcp:e.mcp,devMcp:e.devMcp,scope:e.scope,sharing:n})}catch(e){if(e instanceof y){process.stderr.write(`open-knowledge requires git to initialize a parent repo. Install git or run 'git init' yourself, then re-run.
313
- `),e.stderr&&process.stderr.write(`${e.stderr.trim()}\n`),process.exitCode=1;return}throw e}try{let{previewContent:e}=await import(`./preview-CivTRJYh.mjs`),{loadConfig:t}=await import(`./loader-C-YEycYU.mjs`),{resolveContentDir:n}=await import(`./dist-BxQnNdO0.mjs`),{config:i}=t(r.projectRoot),a=n(i,r.projectRoot);r.preview=e({projectDir:r.projectRoot,contentDir:a})}catch(e){r.previewWarning=e instanceof Error?e.message:String(e)}process.stdout.write(`${Sa(r,r.projectRoot)}\n`),(r.editors.some(e=>e.action===`failed`)||r.mcpAction===`failed`)&&(process.exitCode=1)})}function Ta(e,t){let n=[];switch(e.kind){case`applied`:return n.push(A(`Sharing mode:`)),e.mode===`local-only`?e.action===`added`?n.push(` ${D(`local-only`)} — appended ${e.appended.length} path(s) to ${A(`${t}/.git/info/exclude`)} (per-clone, not committed).`):e.action===`noop`&&e.alreadyPresent.length>0?n.push(` ${D(`local-only`)} — already excluded; nothing to do.`):n.push(` ${D(`local-only`)}`):e.action===`removed`?n.push(` ${D(`shared`)} — removed OK paths from ${A(`${t}/.git/info/exclude`)}; commit the files to share with teammates.`):n.push(` ${D(`shared`)} — OK config will be committed alongside content.`),n;case`refused-tracked`:n.push(k(`Sharing mode: switch to local-only deferred`));for(let t of e.remediation.split(`
313
+ `),e.stderr&&process.stderr.write(`${e.stderr.trim()}\n`),process.exitCode=1;return}throw e}try{let{previewContent:e}=await import(`./preview-CXjC0-tX.mjs`),{loadConfig:t}=await import(`./loader-1HEZ-mso.mjs`),{resolveContentDir:n}=await import(`./dist-Db57TeUO.mjs`),{config:i}=t(r.projectRoot),a=n(i,r.projectRoot);r.preview=e({projectDir:r.projectRoot,contentDir:a})}catch(e){r.previewWarning=e instanceof Error?e.message:String(e)}process.stdout.write(`${Sa(r,r.projectRoot)}\n`),(r.editors.some(e=>e.action===`failed`)||r.mcpAction===`failed`)&&(process.exitCode=1)})}function Ta(e,t){let n=[];switch(e.kind){case`applied`:return n.push(A(`Sharing mode:`)),e.mode===`local-only`?e.action===`added`?n.push(` ${D(`local-only`)} — appended ${e.appended.length} path(s) to ${A(`${t}/.git/info/exclude`)} (per-clone, not committed).`):e.action===`noop`&&e.alreadyPresent.length>0?n.push(` ${D(`local-only`)} — already excluded; nothing to do.`):n.push(` ${D(`local-only`)}`):e.action===`removed`?n.push(` ${D(`shared`)} — removed OK paths from ${A(`${t}/.git/info/exclude`)}; commit the files to share with teammates.`):n.push(` ${D(`shared`)} — OK config will be committed alongside content.`),n;case`refused-tracked`:n.push(k(`Sharing mode: switch to local-only deferred`));for(let t of e.remediation.split(`
314
314
  `))n.push(t.length>0?` ${t}`:``);return n.push(` Re-run ${E(`ok config-sharing unshare`)} after resolving to complete the switch.`),n;case`no-exclude`:if(e.localOnlyRequested)n.push(k(`Sharing mode: --local-only requested but no git repo found — option ignored`)),n.push(` Run ${E(`git init`)} (or open this folder via OK Desktop, which can scaffold a repo) and then ${E(`ok config-sharing unshare`)}.`);else if(e.reason===`no-git`)return[];else n.push(k(`Sharing mode unavailable: ${e.reason}.`));return n}}export{St as A,Je as B,At as C,_t as D,Mt as E,mt as F,U as H,ft as I,gt as L,pt as M,ut as N,vt as O,dt as P,st as R,Pt as S,Nt as T,Te as V,ga as _,ba as a,jt as b,Sa as c,_a as d,ia as f,ma as g,fa as h,da as i,bt as j,G as k,Ta as l,ya as m,la as n,va as o,oa as p,ua as r,Ca as s,ca as t,wa as u,Yi as v,Ft as w,It as x,Mi as y,Ye as z};
315
- //# sourceMappingURL=init-CrI1V6Yx.mjs.map
315
+ //# sourceMappingURL=init-KcxJDN4J.mjs.map
@@ -0,0 +1 @@
1
+ import{n as e}from"./loader-swjVUkhG.mjs";export{e as loadConfig};
@@ -1,4 +1,4 @@
1
- import{Ii as e,Ni as t,Pi as n,Ta as r}from"./server-lock-BpjJj3OD-DR9UrMHX.mjs";import{Qi as i,Zi as a,m as o}from"./dist-DNsu2kId.mjs";import{t as s}from"./constants-Q1dSeYtu.mjs";import{t as c}from"./is-object-Cie0xXKD.mjs";import{existsSync as l,readFileSync as u}from"node:fs";import{resolve as d}from"node:path";import{realpath as f}from"node:fs/promises";async function p(e){let t=d(e);try{return await f(t)}catch(e){if(e.code!==`ENOENT`){let n=e instanceof Error?e.message:String(e);console.warn(`[normalize-cwd] realpath failed for ${t}: ${n}`)}return t}}var m=r();function h(e,t){let n={...e};for(let r of Object.keys(t)){let i=e[r],a=t[r];c(a)&&c(i)?n[r]=h(i,a):a!==void 0&&(n[r]=a)}return n}function g(e){if(!l(e))return{value:null,path:e,source:null,doc:null};let t;try{t=u(e,`utf-8`)}catch(t){return console.warn(`[config] Failed to read ${e}: ${t instanceof Error?t.message:t}`),{value:null,path:e,source:null,doc:null}}let n=(0,m.parseDocument)(t);if(n.errors.length>0)return console.warn(`[config] Failed to parse ${e}: ${n.errors.map(e=>e.message).join(`; `)}`),{value:null,path:e,source:t,doc:null};let r=n.toJSON();return c(r)?{value:r,path:e,source:t,doc:n}:{value:null,path:e,source:t,doc:n}}function _(t,n){return t.map(t=>{let r=t.path.map(e=>typeof e==`symbol`?String(e):e),i={path:r,message:t.message,issueCode:t.code};if(n.doc!==null&&n.source!==null){let t=e({file:n.path,source:n.source,doc:n.doc,path:r});if(t!==void 0)return{...i,source:t}}return i})}function v(e){let r=e??process.cwd(),c=[],l=i(`user`,r),u=a({absPath:l}),f={};u.valid&&u.source!==void 0?(f=h(f,u.value),c.push(l)):u.valid;let p=d(r,`.ok`,s),m=g(p);if(m.value!==null){let e=t({value:m.value,file:m.path,source:m.source,doc:m.doc});if(e.length>0)throw Error(e.map(n).join(`
1
+ import{Ii as e,Ni as t,Pi as n,Ta as r}from"./server-lock-BpjJj3OD-DR9UrMHX.mjs";import{Qi as i,Zi as a,m as o}from"./dist-DhBWJZmw.mjs";import{t as s}from"./constants-CQjg8jG7.mjs";import{t as c}from"./is-object-Cie0xXKD.mjs";import{existsSync as l,readFileSync as u}from"node:fs";import{resolve as d}from"node:path";import{realpath as f}from"node:fs/promises";async function p(e){let t=d(e);try{return await f(t)}catch(e){if(e.code!==`ENOENT`){let n=e instanceof Error?e.message:String(e);console.warn(`[normalize-cwd] realpath failed for ${t}: ${n}`)}return t}}var m=r();function h(e,t){let n={...e};for(let r of Object.keys(t)){let i=e[r],a=t[r];c(a)&&c(i)?n[r]=h(i,a):a!==void 0&&(n[r]=a)}return n}function g(e){if(!l(e))return{value:null,path:e,source:null,doc:null};let t;try{t=u(e,`utf-8`)}catch(t){return console.warn(`[config] Failed to read ${e}: ${t instanceof Error?t.message:t}`),{value:null,path:e,source:null,doc:null}}let n=(0,m.parseDocument)(t);if(n.errors.length>0)return console.warn(`[config] Failed to parse ${e}: ${n.errors.map(e=>e.message).join(`; `)}`),{value:null,path:e,source:t,doc:null};let r=n.toJSON();return c(r)?{value:r,path:e,source:t,doc:n}:{value:null,path:e,source:t,doc:n}}function _(t,n){return t.map(t=>{let r=t.path.map(e=>typeof e==`symbol`?String(e):e),i={path:r,message:t.message,issueCode:t.code};if(n.doc!==null&&n.source!==null){let t=e({file:n.path,source:n.source,doc:n.doc,path:r});if(t!==void 0)return{...i,source:t}}return i})}function v(e){let r=e??process.cwd(),c=[],l=i(`user`,r),u=a({absPath:l}),f={};u.valid&&u.source!==void 0?(f=h(f,u.value),c.push(l)):u.valid;let p=d(r,`.ok`,s),m=g(p);if(m.value!==null){let e=t({value:m.value,file:m.path,source:m.source,doc:m.doc});if(e.length>0)throw Error(e.map(n).join(`
2
2
 
3
3
  `));f=h(f,m.value),c.push(p)}let v=o.safeParse(f);if(!v.success){let e={code:`SCHEMA_INVALID`,issues:_(v.error.issues,m)};throw Error(n(e))}return{config:v.data,sources:c}}function y(e){let t=e.cacheMs??1e3,n=e.loadConfigFn??v,r=new Map,i=new Map,a=p(e.startupCwd);return async o=>{let s=await p(o??e.startupCwd),c=Date.now(),l=r.get(s);if(l&&l.expiresAt>c)return l.config;let u=i.get(s);if(u)return await u;let d=(async()=>{if(s===await a)return r.set(s,{config:e.startupConfig,expiresAt:Date.now()+t}),e.startupConfig;let i=n(s).config;return r.set(s,{config:i,expiresAt:Date.now()+t}),i})();i.set(s,d);try{return await d}finally{i.delete(s)}}}export{v as n,y as t};
4
- //# sourceMappingURL=loader-Dq6BqiYw.mjs.map
4
+ //# sourceMappingURL=loader-swjVUkhG.mjs.map
@@ -0,0 +1 @@
1
+ import{n as e,t}from"./preview-DryhvQ49.mjs";export{t as formatPreviewBlock,e as previewContent};
@@ -1,3 +1,3 @@
1
- import{Kt as e}from"./dist-DNsu2kId.mjs";import"./constants-Q1dSeYtu.mjs";import{existsSync as t,lstatSync as n,readdirSync as r,realpathSync as i,statSync as a}from"node:fs";import{join as o,relative as s}from"node:path";function c(t){let{projectDir:c,contentDir:l,sampleCap:u=5}=t,d=[],f=[];try{n(l)}catch(e){return{totalCount:0,sample:[],contentDir:l,warnings:[`cannot access content directory ${l}: ${e instanceof Error?e.message:String(e)}`]}}let p;try{p=e({projectDir:c,contentDir:l})}catch(e){return{totalCount:0,sample:[],contentDir:l,warnings:[e instanceof Error?e.message:String(e)]}}function m(e){let t;try{t=r(e,{withFileTypes:!0})}catch(t){let n=t instanceof Error?t.message:String(t);d.push(`could not read directory ${s(l,e)||`.`}: ${n}`);return}for(let n of t){let t=o(e,n.name);if(n.isSymbolicLink()){let e;try{e=i(t)}catch(e){let n=e.code;n===`ENOENT`||n===`ELOOP`?d.push(`broken or cyclic symlink: ${s(l,t)}`):d.push(`cannot resolve symlink ${s(l,t)}: ${n??`unknown error`}`);continue}let n;try{n=a(e)}catch{continue}if(n.isDirectory()){let e=s(l,t);if(p.isDirExcluded(e))continue;m(t)}else if(n.isFile()){let e=s(l,t);if(p.isExcluded(e))continue;f.push(e)}}else if(n.isDirectory()){let e=s(l,t);if(p.isDirExcluded(e))continue;m(t)}else if(n.isFile()){let e=s(l,t);if(p.isExcluded(e))continue;f.push(e)}}}return m(l),{totalCount:f.length,sample:f.slice(0,u),contentDir:l,warnings:d}}function l(e,n){let r=[],i=s(n,e.contentDir),a=i===``?`./`:`./${i}`;if(r.push(`Content:`),r.push(` Found ${e.totalCount} markdown files in ${a}`),e.sample.length>0){let t=e.sample.join(`, `),n=e.totalCount>e.sample.length?`, …`:``;r.push(` Sample: ${t}${n}`)}if(e.warnings.length>0)for(let t of e.warnings)r.push(` Warning: ${t}`);return r.push(``),t(o(n,`.ok`,`config.yml`))?(r.push(` To adjust scope, add patterns to .okignore at the project root.`),r.push(` To change the content root, edit .ok/config.yml → content.dir.`)):r.push(" Run `open-knowledge init` to scaffold config + .okignore."),r.push(``),r.push(` Re-check anytime: open-knowledge preview`),r.join(`
1
+ import{Kt as e}from"./dist-DhBWJZmw.mjs";import"./constants-CQjg8jG7.mjs";import{existsSync as t,lstatSync as n,readdirSync as r,realpathSync as i,statSync as a}from"node:fs";import{join as o,relative as s}from"node:path";function c(t){let{projectDir:c,contentDir:l,sampleCap:u=5}=t,d=[],f=[];try{n(l)}catch(e){return{totalCount:0,sample:[],contentDir:l,warnings:[`cannot access content directory ${l}: ${e instanceof Error?e.message:String(e)}`]}}let p;try{p=e({projectDir:c,contentDir:l})}catch(e){return{totalCount:0,sample:[],contentDir:l,warnings:[e instanceof Error?e.message:String(e)]}}function m(e){let t;try{t=r(e,{withFileTypes:!0})}catch(t){let n=t instanceof Error?t.message:String(t);d.push(`could not read directory ${s(l,e)||`.`}: ${n}`);return}for(let n of t){let t=o(e,n.name);if(n.isSymbolicLink()){let e;try{e=i(t)}catch(e){let n=e.code;n===`ENOENT`||n===`ELOOP`?d.push(`broken or cyclic symlink: ${s(l,t)}`):d.push(`cannot resolve symlink ${s(l,t)}: ${n??`unknown error`}`);continue}let n;try{n=a(e)}catch{continue}if(n.isDirectory()){let e=s(l,t);if(p.isDirExcluded(e))continue;m(t)}else if(n.isFile()){let e=s(l,t);if(p.isExcluded(e))continue;f.push(e)}}else if(n.isDirectory()){let e=s(l,t);if(p.isDirExcluded(e))continue;m(t)}else if(n.isFile()){let e=s(l,t);if(p.isExcluded(e))continue;f.push(e)}}}return m(l),{totalCount:f.length,sample:f.slice(0,u),contentDir:l,warnings:d}}function l(e,n){let r=[],i=s(n,e.contentDir),a=i===``?`./`:`./${i}`;if(r.push(`Content:`),r.push(` Found ${e.totalCount} markdown files in ${a}`),e.sample.length>0){let t=e.sample.join(`, `),n=e.totalCount>e.sample.length?`, …`:``;r.push(` Sample: ${t}${n}`)}if(e.warnings.length>0)for(let t of e.warnings)r.push(` Warning: ${t}`);return r.push(``),t(o(n,`.ok`,`config.yml`))?(r.push(` To adjust scope, add patterns to .okignore at the project root.`),r.push(` To change the content root, edit .ok/config.yml → content.dir.`)):r.push(" Run `open-knowledge init` to scaffold config + .okignore."),r.push(``),r.push(` Re-check anytime: open-knowledge preview`),r.join(`
2
2
  `)}export{c as n,l as t};
3
- //# sourceMappingURL=preview-woGHUkwp.mjs.map
3
+ //# sourceMappingURL=preview-DryhvQ49.mjs.map
@@ -1,2 +1,2 @@
1
- import{h as e,n as t}from"./init-CrI1V6Yx.mjs";import{t as n}from"./is-object-Cie0xXKD.mjs";import{existsSync as r,readFileSync as i}from"node:fs";import{join as a}from"node:path";const o=[[`@inkeep/open-knowledge`,`ui`],[`-y`,`@inkeep/open-knowledge`,`ui`],t];function s(e){if(e.runtimeExecutable===`/bin/sh`&&Array.isArray(e.runtimeArgs)){let t=e.runtimeArgs[2];if(typeof t==`string`){if(t.includes(`# ok-ui-v1`))return`canonical`;if(/# ok-ui-v\d+/.test(t))return`legacy-bare`}return`preserved`}if(e.runtimeExecutable===`npx`&&Array.isArray(e.runtimeArgs)){for(let t of o)if(c(e.runtimeArgs,t))return`legacy-bare`}return`preserved`}function c(e,t){if(e.length!==t.length)return!1;for(let n=0;n<t.length;n++)if(e[n]!==t[n])return!1;return!0}function l(t){let o=t.logger??u,c=a(t.projectDir,`.claude`,`launch.json`);if(t.reclaimDisableEnv===`1`)return o({event:`launch-json-repair-skipped`,reason:`reclaim-disabled`}),{outcome:{configPath:c,outcome:`skipped-reclaim-disabled`},repairedCount:0};if(!r(c))return{outcome:{configPath:c,outcome:`no-file`},repairedCount:0};let l;try{let e=i(c,`utf-8`).trim();l=e?JSON.parse(e):{}}catch(e){let t=e instanceof Error?e.message:String(e);return o({event:`launch-json-repair-read-failed`,configPath:c,error:t}),{outcome:{configPath:c,outcome:`read-failed`,error:t},repairedCount:0}}if(!n(l)){let e=`launch.json root is not an object`;return o({event:`launch-json-repair-read-failed`,configPath:c,error:e}),{outcome:{configPath:c,outcome:`read-failed`,error:e},repairedCount:0}}let d=l.configurations;if(!Array.isArray(d))return{outcome:{configPath:c,outcome:`no-entry`},repairedCount:0};let f=d.find(e=>n(e)&&e.name===`open-knowledge-ui`);if(!f)return{outcome:{configPath:c,outcome:`no-entry`},repairedCount:0};let p=s(f);if(p===`canonical`)return{outcome:{configPath:c,outcome:`canonical`},repairedCount:0};if(p===`preserved`)return{outcome:{configPath:c,outcome:`preserved`},repairedCount:0};let m=e(t.projectDir,{mode:`published`});if(m.action===`failed`){let e=m.error??`unknown write failure`;return o({event:`launch-json-repair-write-failed`,configPath:c,error:e}),{outcome:{configPath:c,outcome:`write-failed`,error:e},repairedCount:0}}return o({event:`launch-json-repair-applied`,configPath:c}),{outcome:{configPath:c,outcome:`repaired`},repairedCount:1}}function u(e){process.stderr.write(`${JSON.stringify(e)}\n`)}export{l as repairLaunchJson};
2
- //# sourceMappingURL=repair-launch-json-M8CeiMua.mjs.map
1
+ import{h as e,n as t}from"./init-KcxJDN4J.mjs";import{t as n}from"./is-object-Cie0xXKD.mjs";import{existsSync as r,readFileSync as i}from"node:fs";import{join as a}from"node:path";const o=[[`@inkeep/open-knowledge`,`ui`],[`-y`,`@inkeep/open-knowledge`,`ui`],t];function s(e){if(e.runtimeExecutable===`/bin/sh`&&Array.isArray(e.runtimeArgs)){let t=e.runtimeArgs[2];if(typeof t==`string`){if(t.includes(`# ok-ui-v1`))return`canonical`;if(/# ok-ui-v\d+/.test(t))return`legacy-bare`}return`preserved`}if(e.runtimeExecutable===`npx`&&Array.isArray(e.runtimeArgs)){for(let t of o)if(c(e.runtimeArgs,t))return`legacy-bare`}return`preserved`}function c(e,t){if(e.length!==t.length)return!1;for(let n=0;n<t.length;n++)if(e[n]!==t[n])return!1;return!0}function l(t){let o=t.logger??u,c=a(t.projectDir,`.claude`,`launch.json`);if(t.reclaimDisableEnv===`1`)return o({event:`launch-json-repair-skipped`,reason:`reclaim-disabled`}),{outcome:{configPath:c,outcome:`skipped-reclaim-disabled`},repairedCount:0};if(!r(c))return{outcome:{configPath:c,outcome:`no-file`},repairedCount:0};let l;try{let e=i(c,`utf-8`).trim();l=e?JSON.parse(e):{}}catch(e){let t=e instanceof Error?e.message:String(e);return o({event:`launch-json-repair-read-failed`,configPath:c,error:t}),{outcome:{configPath:c,outcome:`read-failed`,error:t},repairedCount:0}}if(!n(l)){let e=`launch.json root is not an object`;return o({event:`launch-json-repair-read-failed`,configPath:c,error:e}),{outcome:{configPath:c,outcome:`read-failed`,error:e},repairedCount:0}}let d=l.configurations;if(!Array.isArray(d))return{outcome:{configPath:c,outcome:`no-entry`},repairedCount:0};let f=d.find(e=>n(e)&&e.name===`open-knowledge-ui`);if(!f)return{outcome:{configPath:c,outcome:`no-entry`},repairedCount:0};let p=s(f);if(p===`canonical`)return{outcome:{configPath:c,outcome:`canonical`},repairedCount:0};if(p===`preserved`)return{outcome:{configPath:c,outcome:`preserved`},repairedCount:0};let m=e(t.projectDir,{mode:`published`});if(m.action===`failed`){let e=m.error??`unknown write failure`;return o({event:`launch-json-repair-write-failed`,configPath:c,error:e}),{outcome:{configPath:c,outcome:`write-failed`,error:e},repairedCount:0}}return o({event:`launch-json-repair-applied`,configPath:c}),{outcome:{configPath:c,outcome:`repaired`},repairedCount:1}}function u(e){process.stderr.write(`${JSON.stringify(e)}\n`)}export{l as repairLaunchJson};
2
+ //# sourceMappingURL=repair-launch-json-yC7GeR_5.mjs.map