@inkeep/open-knowledge 0.5.0-beta.2 → 0.5.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/THIRD_PARTY_NOTICES.md +10 -0
- package/dist/assets/skills/open-knowledge/SKILL.md +1 -1
- package/dist/cli.mjs +40 -40
- package/dist/constants-BX3j-Yin.mjs +2 -0
- package/dist/{dist-DLi5l7jc.mjs → dist-B-QGEbwX.mjs} +1 -1
- package/dist/{dist-DD3jbGts.mjs → dist-Buq7uUK7.mjs} +20 -20
- package/dist/{dist-CKbBtGcV.mjs → dist-C2XvqbzG.mjs} +5 -5
- package/dist/index.mjs +1 -1
- package/dist/init-C4vpeHcE.mjs +1 -0
- package/dist/{init-BVF99f4p.mjs → init-waQJnje3.mjs} +3 -3
- package/dist/{loader-BuVjsSVh.mjs → loader-PJR8tk3Q.mjs} +2 -2
- package/dist/loader-V2wyK36w.mjs +1 -0
- package/dist/{preview-CgtprTPm.mjs → preview-BbtR5Qqj.mjs} +2 -2
- package/dist/preview-DR_OP2am.mjs +1 -0
- package/dist/public/assets/ActivityModeContent-baqsrxsY.js +2 -0
- package/dist/public/assets/ConsentDialogBody-zb1TKG9i.js +2 -0
- package/dist/public/assets/DocumentContext-D4lHVgL4.js +52 -0
- package/dist/public/assets/{GraphPanel-C3gvPdoq.js → GraphPanel-Bqt87S0c.js} +2 -2
- package/dist/public/assets/McpConsentDialogBody-C8ewMYVI.js +1 -0
- package/dist/public/assets/SettingsDialog-D6nNBqeV.js +11 -0
- package/dist/public/assets/{SourceEditor-Xxy5TvNJ.js → SourceEditor-CJiFlEvK.js} +2 -2
- package/dist/public/assets/{_baseFor-CVV1DSgL.js → _baseFor-Dewzr4ka.js} +1 -1
- package/dist/public/assets/{arc-DoxD41WW.js → arc-DA-_Qgty.js} +1 -1
- package/dist/public/assets/architecture-YZFGNWBL-ii1DMScC.js +1 -0
- package/dist/public/assets/{architectureDiagram-Q4EWVU46-Du5oNRD5.js → architectureDiagram-Q4EWVU46-Wd0Ua0Z1.js} +1 -1
- package/dist/public/assets/{blockDiagram-DXYQGD6D-CuxUJ8VP.js → blockDiagram-DXYQGD6D-B_z4vCOg.js} +1 -1
- package/dist/public/assets/{c4Diagram-AHTNJAMY-D58kKzW4.js → c4Diagram-AHTNJAMY-CXNX0C7S.js} +1 -1
- package/dist/public/assets/channel-BsgewBDI.js +1 -0
- package/dist/public/assets/{chunk-2KRD3SAO-uai9wz3V.js → chunk-2KRD3SAO-QHu6lS2z.js} +1 -1
- package/dist/public/assets/{chunk-336JU56O-CtkQ28bg.js → chunk-336JU56O-D77Rj_75.js} +2 -2
- package/dist/public/assets/chunk-426QAEUC-b3iWz8H-.js +1 -0
- package/dist/public/assets/{chunk-4BX2VUAB-BTctgoF3.js → chunk-4BX2VUAB-CDjfF5mJ.js} +1 -1
- package/dist/public/assets/{chunk-4TB4RGXK-Cnl-K_AI.js → chunk-4TB4RGXK-DgzpC1RW.js} +1 -1
- package/dist/public/assets/chunk-55IACEB6-DLoy8CmX.js +1 -0
- package/dist/public/assets/{chunk-5FUZZQ4R-DF0EG1O8.js → chunk-5FUZZQ4R-pDx0Wde8.js} +1 -1
- package/dist/public/assets/{chunk-5PVQY5BW-BpceE2BZ.js → chunk-5PVQY5BW-kcWn_d-_.js} +1 -1
- package/dist/public/assets/{chunk-67CJDMHE-DiSIolj4.js → chunk-67CJDMHE-DlS8iVRi.js} +1 -1
- package/dist/public/assets/{chunk-7N4EOEYR-Yp7Nf16N.js → chunk-7N4EOEYR-BhSQn_oU.js} +1 -1
- package/dist/public/assets/{chunk-AA7GKIK3--s2NNuet.js → chunk-AA7GKIK3-C1CcYx5B.js} +1 -1
- package/dist/public/assets/{chunk-BSJP7CBP-BrRqu__W.js → chunk-BSJP7CBP-B5xN369R.js} +1 -1
- package/dist/public/assets/{chunk-CIAEETIT-BUzaopy6.js → chunk-CIAEETIT-ecxKAxUb.js} +1 -1
- package/dist/public/assets/{chunk-EDXVE4YY-Bo83e0iq.js → chunk-EDXVE4YY-Bm2-fU6x.js} +1 -1
- package/dist/public/assets/{chunk-ENJZ2VHE-CY9yto8o.js → chunk-ENJZ2VHE-1bYQNnwE.js} +1 -1
- package/dist/public/assets/{chunk-FMBD7UC4-DEzvlUl3.js → chunk-FMBD7UC4-Da7gMLWx.js} +1 -1
- package/dist/public/assets/{chunk-FOC6F5B3-BtjWNx10.js → chunk-FOC6F5B3-CHF5QCPz.js} +1 -1
- package/dist/public/assets/{chunk-ICPOFSXX-BC5Xd13f.js → chunk-ICPOFSXX-rmT7ehAO.js} +1 -1
- package/dist/public/assets/{chunk-K5T4RW27-CfU2wPmV.js → chunk-K5T4RW27-CHoEPFOL.js} +1 -1
- package/dist/public/assets/{chunk-KGLVRYIC-BV1pDifD.js → chunk-KGLVRYIC-DRtjGHKV.js} +1 -1
- package/dist/public/assets/{chunk-LIHQZDEY-C40dIbib.js → chunk-LIHQZDEY-GDhBbkMd.js} +1 -1
- package/dist/public/assets/{chunk-ORNJ4GCN-8cFqvOFf.js → chunk-ORNJ4GCN-C9FrQ4Hp.js} +1 -1
- package/dist/public/assets/{chunk-OYMX7WX6-D0C6jdl8.js → chunk-OYMX7WX6-CAW2HwTq.js} +1 -1
- package/dist/public/assets/chunk-QZHKN3VN-XrJADtWP.js +1 -0
- package/dist/public/assets/{chunk-U2HBQHQK-DenE4TdD.js → chunk-U2HBQHQK-Cg7rxXd1.js} +1 -1
- package/dist/public/assets/{chunk-X2U36JSP-DSyuGkzP.js → chunk-X2U36JSP-Z4V8etFJ.js} +1 -1
- package/dist/public/assets/{chunk-XPW4576I-CLO5Bb_q.js → chunk-XPW4576I-Ci37cmyJ.js} +1 -1
- package/dist/public/assets/{chunk-YZCP3GAM-D8kUvWu6.js → chunk-YZCP3GAM-BlAQKShJ.js} +1 -1
- package/dist/public/assets/{chunk-ZZ45TVLE-DHB0SHUz.js → chunk-ZZ45TVLE-CKHp-exc.js} +1 -1
- package/dist/public/assets/classDiagram-6PBFFD2Q-Bt8hJVX9.js +1 -0
- package/dist/public/assets/classDiagram-v2-HSJHXN6E-BTPIteVB.js +1 -0
- package/dist/public/assets/clone-B_tH2FKO.js +1 -0
- package/dist/public/assets/config-validation-events-CuJstsYS.js +10 -0
- package/dist/public/assets/{cose-bilkent-S5V4N54A-6FB6GAoi.js → cose-bilkent-S5V4N54A-CzOLOBap.js} +1 -1
- package/dist/public/assets/{dagre-D2_448Gx.js → dagre-CbTJGa51.js} +1 -1
- package/dist/public/assets/{dagre-KV5264BT-Bn9RtFC-.js → dagre-KV5264BT-CzrIWBHi.js} +1 -1
- package/dist/public/assets/{diagram-5BDNPKRD-XCR9sVhK.js → diagram-5BDNPKRD-DDHvw5SM.js} +1 -1
- package/dist/public/assets/{diagram-G4DWMVQ6-Bz0ngc_7.js → diagram-G4DWMVQ6-DiQx8aIN.js} +1 -1
- package/dist/public/assets/{diagram-MMDJMWI5-o_IQFxK_.js → diagram-MMDJMWI5-CJELLr4J.js} +1 -1
- package/dist/public/assets/{diagram-TYMM5635-D2QJXyfV.js → diagram-TYMM5635-BHwicR15.js} +1 -1
- package/dist/public/assets/dialog-CY2eQd6O.js +45 -0
- package/dist/public/assets/{dist-BYGzJeLM.js → dist-B3L7cm0M.js} +1 -1
- package/dist/public/assets/{dist-CXGJFbY5.js → dist-BMooy-F_.js} +1 -1
- package/dist/public/assets/{dist-DsbVHLNy.js → dist-BiYnsAMa.js} +1 -1
- package/dist/public/assets/{dist-Cq1LYbUj.js → dist-CATLRngz.js} +1 -1
- package/dist/public/assets/{dist-BrsSsfiw.js → dist-Cp-iTcML.js} +1 -1
- package/dist/public/assets/{dist-CyaBbyDQ.js → dist-Dwop2AD8.js} +1 -1
- package/dist/public/assets/doc-hash-D-COaeDG.js +422 -0
- package/dist/public/assets/{erDiagram-SMLLAGMA-C1Mr5jbs.js → erDiagram-SMLLAGMA-DdltplqB.js} +1 -1
- package/dist/public/assets/{flatten-DFiFicpD.js → flatten-BdgTwKTr.js} +1 -1
- package/dist/public/assets/{flowDiagram-DWJPFMVM--ukgnTYS.js → flowDiagram-DWJPFMVM-CQHlOxjR.js} +1 -1
- package/dist/public/assets/{ganttDiagram-T4ZO3ILL-CVeIdgCM.js → ganttDiagram-T4ZO3ILL-CNDOT9hb.js} +1 -1
- package/dist/public/assets/gitGraph-7Q5UKJZL-CIz9LX1B.js +1 -0
- package/dist/public/assets/{gitGraphDiagram-UUTBAWPF-BSivDyLh.js → gitGraphDiagram-UUTBAWPF-BgXxQBs9.js} +1 -1
- package/dist/public/assets/{graphlib-DvRtwu4N.js → graphlib-CrrIJ98S.js} +1 -1
- package/dist/public/assets/index-BHqEYdAv.css +1 -0
- package/dist/public/assets/index-Bzh2wENQ.js +1853 -0
- package/dist/public/assets/info-OMHHGYJF-CIFsXa-y.js +1 -0
- package/dist/public/assets/{infoDiagram-42DDH7IO-DtO1Tc8U.js → infoDiagram-42DDH7IO-BNSprTvD.js} +1 -1
- package/dist/public/assets/{isEmpty-gGVpRSDa.js → isEmpty-XlV2b3kS.js} +1 -1
- package/dist/public/assets/isSymbol-CiN6ou2H.js +1 -0
- package/dist/public/assets/{ishikawaDiagram-UXIWVN3A-BY3noyNF.js → ishikawaDiagram-UXIWVN3A-COSeJVOI.js} +1 -1
- package/dist/public/assets/{journeyDiagram-VCZTEJTY-DdFdkR8_.js → journeyDiagram-VCZTEJTY-sGfNXUrs.js} +1 -1
- package/dist/public/assets/{kanban-definition-6JOO6SKY-WoLnXp48.js → kanban-definition-6JOO6SKY-DknMinG3.js} +1 -1
- package/dist/public/assets/{line-C59Ezo8Z.js → line-BI6r6-S8.js} +1 -1
- package/dist/public/assets/{linear-faBQNtcz.js → linear-1aKBO-v1.js} +1 -1
- package/dist/public/assets/{mermaid-parser.core-CFsvu03i.js → mermaid-parser.core-BrufKICx.js} +2 -2
- package/dist/public/assets/{mermaid.core-CWYso-V4.js → mermaid.core-hgzeX18g.js} +3 -3
- package/dist/public/assets/{mindmap-definition-QFDTVHPH-BG3Kwhhs.js → mindmap-definition-QFDTVHPH-X4KQZFdB.js} +1 -1
- package/dist/public/assets/{now-D_m-3Vjm.js → now--RAZR_wd.js} +1 -1
- package/dist/public/assets/{ordinal-BLFwWMHf.js → ordinal-C6wHcby9.js} +1 -1
- package/dist/public/assets/packet-4T2RLAQJ-BaGTVTK6.js +1 -0
- package/dist/public/assets/pie-ZZUOXDRM-BlBm3k_7.js +1 -0
- package/dist/public/assets/{pieDiagram-DEJITSTG-B1wtn7py.js → pieDiagram-DEJITSTG-5kceM3o3.js} +1 -1
- package/dist/public/assets/{quadrantDiagram-34T5L4WZ-yboV7Kxh.js → quadrantDiagram-34T5L4WZ-CQehowKY.js} +1 -1
- package/dist/public/assets/radar-PYXPWWZC-DcDFZeKR.js +1 -0
- package/dist/public/assets/{reduce-DmI60TfL.js → reduce-C4NH7ua9.js} +1 -1
- package/dist/public/assets/{requirementDiagram-MS252O5E-BpVLqxNT.js → requirementDiagram-MS252O5E-DySfGFfG.js} +1 -1
- package/dist/public/assets/{sankeyDiagram-XADWPNL6-CH1ZYL1H.js → sankeyDiagram-XADWPNL6-CMU0uGgr.js} +1 -1
- package/dist/public/assets/{sequenceDiagram-FGHM5R23-CwQvwa3m.js → sequenceDiagram-FGHM5R23-BlnukeK1.js} +1 -1
- package/dist/public/assets/{src-DOAilbaA.js → src-BXk72DrU.js} +1 -1
- package/dist/public/assets/{stateDiagram-FHFEXIEX-DL3pXt3n.js → stateDiagram-FHFEXIEX-B7C4fJw1.js} +1 -1
- package/dist/public/assets/stateDiagram-v2-QKLJ7IA2-BjMTOSSV.js +1 -0
- package/dist/public/assets/{target-navigation-intent-Bsa-5sN4.js → target-navigation-intent-BebfMyQT.js} +1 -1
- package/dist/public/assets/{telemetry-impl-H--5W_Jc.js → telemetry-impl-C6x9yckj.js} +2 -2
- package/dist/public/assets/{timeline-definition-GMOUNBTQ-CDbb3c--.js → timeline-definition-GMOUNBTQ-DAcQtRlS.js} +1 -1
- package/dist/public/assets/{toggle-group-fH3GS2vu.js → toggle-group-B6Y5d2LH.js} +1 -1
- package/dist/public/assets/{tooltip-BuwIhPCp.js → tooltip-Cn5mq_qc.js} +1 -1
- package/dist/public/assets/treeView-SZITEDCU-DT6-aoa9.js +1 -0
- package/dist/public/assets/treemap-W4RFUUIX-JWBoWOdi.js +1 -0
- package/dist/public/assets/{typing-burst-detector-isOlON7R.js → typing-burst-detector-BizuT3zF.js} +2 -2
- package/dist/public/assets/{vennDiagram-DHZGUBPP-BaHOUqGA.js → vennDiagram-DHZGUBPP-D5QpqXSc.js} +1 -1
- package/dist/public/assets/wardley-RL74JXVD-GxyzoOqN.js +1 -0
- package/dist/public/assets/{wardleyDiagram-NUSXRM2D-5ysokC2z.js → wardleyDiagram-NUSXRM2D-CV74dN2L.js} +1 -1
- package/dist/public/assets/{xychartDiagram-5P7HB3ND-CFQqcNjf.js → xychartDiagram-5P7HB3ND-VYAkLjyv.js} +1 -1
- package/dist/public/index.html +19 -20
- package/dist/{src-ClUycJ-8.mjs → src-C2dzaqiT.mjs} +2 -2
- package/dist/{start-9GiauZpx.mjs → start-BPgTRJoS.mjs} +2 -2
- package/dist/start-DI5JWpBI.mjs +1 -0
- package/package.json +1 -1
- package/dist/constants-DaHLULeB.mjs +0 -2
- package/dist/init-C5EZlTRi.mjs +0 -1
- package/dist/loader-hhLpWo02.mjs +0 -1
- package/dist/preview-B3SUZJxp.mjs +0 -1
- package/dist/public/assets/ActivityModeContent-BPpQcXSp.js +0 -2
- package/dist/public/assets/ConsentDialogBody-CPwBJJLE.js +0 -2
- package/dist/public/assets/DocumentContext-DOBntg5q.js +0 -37
- package/dist/public/assets/McpConsentDialogBody-0w9-K4mU.js +0 -1
- package/dist/public/assets/SettingsDialog-DJeu0WRa.js +0 -11
- package/dist/public/assets/architecture-YZFGNWBL-C7rs88Cj.js +0 -1
- package/dist/public/assets/channel-kvPH_LHg.js +0 -1
- package/dist/public/assets/chunk-426QAEUC-jRhC4EYv.js +0 -1
- package/dist/public/assets/chunk-55IACEB6-dtXOOCuI.js +0 -1
- package/dist/public/assets/chunk-QZHKN3VN-Bz4XrtbS.js +0 -1
- package/dist/public/assets/classDiagram-6PBFFD2Q-MrFnlVPS.js +0 -1
- package/dist/public/assets/classDiagram-v2-HSJHXN6E-DFkKo4Ct.js +0 -1
- package/dist/public/assets/clone-jj9sSaF-.js +0 -1
- package/dist/public/assets/config-validation-events-BpvRjXIZ.js +0 -10
- package/dist/public/assets/dialog-BFN-ujuF.js +0 -1
- package/dist/public/assets/dist-OTL8-1C2.js +0 -45
- package/dist/public/assets/doc-hash-DefAyZGx.js +0 -422
- package/dist/public/assets/gitGraph-7Q5UKJZL-Bmgp5n-M.js +0 -1
- package/dist/public/assets/index-Cfu0nrKh.js +0 -1853
- package/dist/public/assets/index-Cl4ZMMDO.css +0 -1
- package/dist/public/assets/info-OMHHGYJF-DCMX4pS_.js +0 -1
- package/dist/public/assets/isSymbol-D0ur5y-p.js +0 -1
- package/dist/public/assets/packet-4T2RLAQJ-DveBhlQF.js +0 -1
- package/dist/public/assets/pie-ZZUOXDRM-yiLyabeZ.js +0 -1
- package/dist/public/assets/radar-PYXPWWZC-D8GV_2fZ.js +0 -1
- package/dist/public/assets/stateDiagram-v2-QKLJ7IA2-6f8E13YF.js +0 -1
- package/dist/public/assets/treeView-SZITEDCU-A2Cj-I1J.js +0 -1
- package/dist/public/assets/treemap-W4RFUUIX-uOn6xcZK.js +0 -1
- package/dist/public/assets/wardley-RL74JXVD-DrTPuxUO.js +0 -1
- package/dist/start-BOjZrRX3.mjs +0 -1
- /package/dist/public/assets/{ActivityPanelDiffView-DeDaG2lq.js → ActivityPanelDiffView-EaCFURAu.js} +0 -0
- /package/dist/public/assets/{__vite-browser-external-sCjVW6Bj.js → __vite-browser-external-mvD4HPu0.js} +0 -0
- /package/dist/public/assets/{array-COEOjKUv.js → array-o2rfyIz3.js} +0 -0
- /package/dist/public/assets/{colors-D6LRuSY-.js → colors-BbIH8S-B.js} +0 -0
- /package/dist/public/assets/{cytoscape.esm-4jw_vW_Q.js → cytoscape.esm-xzkCxEpv.js} +0 -0
- /package/dist/public/assets/{defaultLocale-CoF2cqkH.js → defaultLocale-D3xTVDt1.js} +0 -0
- /package/dist/public/assets/{dist-Du-s1q8P.js → dist-D2RGH7XO.js} +0 -0
- /package/dist/public/assets/{dist-Bog19bCH.js → dist-TlK-S7KL.js} +0 -0
- /package/dist/public/assets/{go-wMvjCq97.js → go-e6pdpn6U.js} +0 -0
- /package/dist/public/assets/{init-8GNx5phc.js → init-gbiKrEzm.js} +0 -0
- /package/dist/public/assets/{input-BOmkuBId.js → input-hZk8Tm0e.js} +0 -0
- /package/dist/public/assets/{isObjectLike-DFnkciUU.js → isObjectLike-BNNgtFA6.js} +0 -0
- /package/dist/public/assets/{min-BiwsSkbB.js → min-VayDM1tY.js} +0 -0
- /package/dist/public/assets/{path-C-grg3CZ.js → path-DFpIsaqN.js} +0 -0
- /package/dist/public/assets/{pdf-CtJiipL_.js → pdf-w2KBoLit.js} +0 -0
- /package/dist/public/assets/{pdf.worker-BZq-wJdz.js → pdf.worker-BpRoOtgY.js} +0 -0
- /package/dist/public/assets/{project-paths-Cs3srSjk.js → project-paths-hiY0fNWB.js} +0 -0
- /package/dist/public/assets/{rough.esm-DDK-gphn.js → rough.esm-BgPNbngg.js} +0 -0
- /package/dist/public/assets/{shell-DdhS5_h8.js → shell-BkCD5kyH.js} +0 -0
- /package/dist/public/assets/{src-L3wpjxBL.js → src-BYmEUJ3I.js} +0 -0
- /package/dist/public/assets/{stex-CzCFWeB9.js → stex-J8UMaf7u.js} +0 -0
- /package/dist/public/assets/{textarea-CaFqgjns.js → textarea-gXd-JXvQ.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as __toCommonJS,i as __require$1,n as __esmMin,o as __toESM$1,r as __exportAll,t as __commonJSMin$1}from"./chunk-FK9Q3tQk.mjs";import{$ as FolderConfigPutSuccessSchema,$n as toWikiLinkSlug,$t as SyncConflictContentSuccessSchema,A as CONFIG_DOC_NAMES,An as emptySkillState,Ar as record,At as RenamePathSuccessSchema,Bn as isOrphanMode,Br as $ZodObject,Bt as SearchRequestSchema,C as CC1ServerInfoPayloadSchema,Cn as createBasenameIndex,Cr as intersection,Ct as ORPHAN_MODES,D as CC1_CHANNEL_DISK_ACK,Dn as createWorkspaceSearchDocument,Dr as object$1,Dt as PrincipalSuccessSchema,E as CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,En as createWorkspaceSearchCorpus,Er as number,Et as PagesSuccessSchema,F as CreateFolderRequestSchema,Fn as getParseHealth,Fr as datetime,Ft as SKILL_STATE_TARGETS,G as DiffSuccessSchema,Gn as readFmMap,Gr as safeParseAsync$1,Gt as SeedPlanSuccessSchema,H as DeadLinksSuccessSchema,Hn as mergeThreeWay,Hr as parse$1,Ht as SeedApplyRequestSchema,I as CreateFolderSuccessSchema,In as getWikiLinkText,Ir as toJSONSchema,It as SKILL_STATE_VERSION_RE,Jn as searchWorkspaceCorpus,Jr as normalizeParams,Jt as SkillStateSchema,K as DocumentListSuccessSchema,Kn as resolveAssetProjectPath,Kr as clone,Kt as ServerInfoSuccessSchema,L as CreatePageRequestSchema,Ln as humanFormat,Lt as SYSTEM_DOC_NAME,M as CONFIG_DOC_NAME_PROJECT,Mn as extractFrontmatterTags,Mr as union,Mt as RollbackRequestSchema,N as CONFIG_DOC_NAME_PROJECT_LOCAL,Nn as fnv1aDigest,Nr as unknown,Nt as RollbackSuccessSchema,O as CC1_CHANNEL_SERVER_INFO,On as defaultScheduler,Or as optional,Ot as ProblemDetailsSchema,P as CONFIG_DOC_NAME_USER,Pn as getHeadingSlug,Pt as SKILL_STATE_REL,Q as FolderConfigPutRequestSchema,Qn as toBridgeInvariantLog,Qt as SyncAbortMergeSuccessSchema,R as CreatePageSuccessSchema,Rn as iconFromClientName,Rr as describe$1,Rt as SaveVersionRequestSchema,S as CC1DiskAckPayloadSchema,Sn as colorFromSeed,Sr as discriminatedUnion,St as MetricsReconciliationSuccessSchema,T as CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,Tn as createTagInTextRegex,Tr as looseObject,Tt as PageHeadingsSuccessSchema,U as DeletePathRequestSchema,Un as normalizeBridge,Ur as parseAsync,Ut as SeedApplySuccessSchema,Vn as mediaKindForSidebarAssetExtension,Vr as $ZodType,Vt as SearchSuccessSchema,W as DeletePathSuccessSchema,Wn as prependFrontmatter,Wr as safeParse$1,Wt as SeedListPacksSuccessSchema,X as EmptyRequestSchema,Xn as stripFrontmatter,Xt as StreamingProblemEventSchema,Y as EXECUTABLE_BLOCKLIST_EXTENSIONS,Yn as sharedExtensions,Yr as $constructor,Yt as SpawnCursorSuccessSchema,Z as FolderConfigGetSuccessSchema,Zn as tagsMatchingPrefix,Zr as require_dist$2,Zt as SuggestLinksSuccessSchema,_ as BridgeMergeContentLossError,_n as applyFastDiff,_r as _null,_t as LocalOpOpenRequestSchema,a as AgentBurstDiffSuccessSchema,an as SyncTriggerSuccessSchema,ar as ConfigSchema$1,at as InstallSkillRequestSchema,b as CC1ConfigValidationRejectedPayloadSchema,bn as classifyMarkdownHref,br as boolean,bt as MetricsAgentPresenceSuccessSchema,c as AgentUndoRequestSchema,cn as TemplateDeleteSuccessSchema,cr as applyPatchToDocument,ct as LinkGraphSuccessSchema,d as AgentWriteMdSuccessSchema,dn as TemplatePutSuccessSchema,dr as validatePatchScopes,dt as LocalOpAuthIdentitySuccessSchema,en as SyncConflictsSuccessSchema,er as unwrapFrontmatterFences,et as ForwardLinksSuccessSchema,f as AgentWriteRequestSchema,fn as TestRescanBacklinksSuccessSchema,fr as withConfigSpan,ft as LocalOpAuthPatRequestSchema,g as BridgeInvariantViolationError,gn as WorkspaceSuccessSchema,gr as _enum,gt as LocalOpCloneRequestSchema,h as BacklinksSuccessSchema,hn as UploadRequestSchema,hr as ZodOptional$1,ht as LocalOpAuthStatusSuccessSchema,i as AgentActivitySuccessSchema,in as SyncTriggerRequestSchema,ir as CONFIG_SCHEMA_MAJOR_PATH,it as INLINE_RENDERABLE_EXTENSIONS,j as CONFIG_DOC_NAME_OKIGNORE,jn as expandTagToHierarchy,jr as string,jt as RescueListSuccessSchema,k as CC1_CONTRACT_VERSION,kn as detectAppliedToleranceClasses,kr as preprocess,kt as RenamePathRequestSchema,l as AgentUndoSuccessSchema,ln as TemplateGetSuccessSchema,lr as locateIssue,lt as LocalOpAuthEmptySuccessSchema,m as BacklinkCountsSuccessSchema,mn as UploadAssetSuccessSchema,mt as LocalOpAuthSetIdentityRequestSchema,nn as SyncResolveConflictSuccessSchema,nr as PluginKey,nt as HistoryVersionSuccessSchema,o as AgentPatchRequestSchema,on as TagsForNameSuccessSchema,or as LOCAL_DIR,ot as InstallSkillSuccessSchema,p as AgentWriteSuccessSchema,pn as TestResetSuccessSchema,pr as withConfigSpanSync,pt as LocalOpAuthPatSuccessSchema,q as DocumentReadSuccessSchema,qn as resolveInternalHref,qr as defineLazy,qt as SkillInstallStateSuccessSchema,r as ASSET_EXTENSIONS,rn as SyncStatusSchema,rr as Fragment,rt as HubsSuccessSchema,s as AgentPatchSuccessSchema,sn as TagsListSuccessSchema,sr as addConfigSpanEvent,st as InstalledAgentsSuccessSchema,t as AGENT_ICON_COLORS,tn as SyncResolveConflictRequestSchema,tr as getSchema,tt as HistorySuccessSchema,u as AgentWriteMdRequestSchema,un as TemplatePutRequestSchema,ur as toConfigIssue,ut as LocalOpAuthHostRequestSchema,v as CC1BranchSwitchedPayloadSchema,vn as applyIncrementalDiff,vt as LocalOpOpenSuccessSchema,w as CC1_CHANNEL_BRANCH_SWITCHED,wn as createCodeFenceTracker,wr as literal,wt as OrphansSuccessSchema,x as CC1DerivedViewPayloadSchema,xn as classifyWikiLinkTarget,xr as custom,xt as MetricsParseHealthSuccessSchema,y as CC1ConfigIgnoreNestedErrorPayloadSchema,yn as assertNeverProblemType,yr as array,yt as MarkdownManager,z as DEFAULT_DEDUP_MODE,zn as isKnownConfigError,zr as meta$1,zt as SaveVersionSuccessSchema}from"./dist-DD3jbGts.mjs";import{a as metrics,c as SpanStatusCode,i as propagation,l as SpanKind,n as init_esm$2,o as diag,r as trace,s as context,t as esm_exports$2}from"./esm-BbkJd7ro.mjs";import{a as acquireProcessLock,c as isValidLockPid,f as readServerLock,g as updateProcessLockPort,m as releaseServerLock,n as RUNTIME_VERSION,o as acquireServerLock,p as releaseProcessLock,s as isProcessAlive,t as ProcessLockCollisionError,u as readProcessLock}from"./server-lock-D7DXNVql-BRVVzA6T.mjs";import{a as require_src$15,i as esm_default,r as withParentLock,t as createGitInstance}from"./git-handle-DwfYp_z--CfyPz4Dz.mjs";import{r as diffLines,t as createPatch}from"./libesm-YL3Bqolr.mjs";import{n as mimes,t as build_default}from"./build-fAc55Z_L.mjs";import{t as b1}from"./chunk-YNYSPYQ5-Dq-BWW-f.mjs";import{a as c,c as h,d as m,f as p,h as x,i as b,l as i,m as v,n as C,o as d,p as u,r as a,s as f,t as $$1,u as l}from"./chunk-GFQRA5P5-CkMj9l7f.mjs";import{A as gt,B as wt,C as _i$1,D as da$1,E as bt,F as pe,H as zi$1,I as qi,L as us$1,M as ma$1,N as mt$1,O as di$1,P as pa$1,S as X$1,T as bl,V as xi$1,_ as Ti$1,a as Fi$1,b as W$1,c as M,d as P,f as Pt$1,g as T,h as Sl,i as En$1,j as he,k as ga$1,l as Nl,m as Se,n as Bi$1,o as Fs$1,p as R,r as Ci$1,s as G$1,t as Al,u as Oi$1,v as V,w as be,x as Wi$1,y as Vi$1,z as wl}from"./chunk-FEIOJCZD-Vm1q1kLH.mjs";import{a as d$1,c as m$1,d as y,i as c$1,l as p$1,n as N,o as f$1,r as P$1,s as h$1,t as $$2,u as v$1}from"./chunk-XHM67O4N-Cd7Fiqsb.mjs";import{n as l$1,r as o,t as h$2}from"./chunk-R6VWJ2ZL-DSqbA7Rj.mjs";import{r as o$1}from"./chunk-CWQS3NFK-BQ5SUtd7.mjs";import"./chunk-DXB73IDG-DfmyzFzL.mjs";import{n as d$2,t as _$1}from"./chunk-5QMZ5MUS-SLhNX8t9.mjs";import{n as u$1,t as b$1}from"./chunk-A5O5YHGN-DQP-O5US.mjs";import{n,r,t as c$2}from"./chunk-OJDRYQWQ-D4lSWh0K.mjs";import{r as x$1,t as a$1}from"./chunk-24IMIIXA-_PX4ITYZ.mjs";import{n as n$1}from"./chunk-3THT3N7L-DrzOuTpA.mjs";import{t as n$2}from"./chunk-44UOCSGV-BbZqjKvt.mjs";import{createRequire}from"node:module";import{execFile,spawn,spawnSync}from"node:child_process";import*as U from"node:path";import{basename,dirname,extname,isAbsolute,join,normalize,posix,relative,resolve,sep,win32}from"node:path";import*as I from"node:fs";import{appendFileSync,closeSync,createReadStream,createWriteStream,existsSync,linkSync,lstatSync,mkdirSync,openSync,readFile,readFileSync,readSync,readdirSync,realpathSync,renameSync,rmSync,rmdirSync,statSync,unlinkSync,writeFileSync}from"node:fs";import{homedir,hostname,platform,tmpdir}from"node:os";import{URLSearchParams as URLSearchParams$1,fileURLToPath}from"node:url";import{AsyncLocalStorage}from"node:async_hooks";import{promisify}from"node:util";import{Readable}from"stream";import{Transform}from"node:stream";import crypto$1,{createHash,randomUUID,webcrypto}from"node:crypto";import crypto$2 from"crypto";import*as zlib$2 from"zlib";import{access,constants,mkdir,readFile as readFile$1,readdir,realpath,rename,stat as stat$1,writeFile}from"node:fs/promises";import{pipeline}from"node:stream/promises";import{setTimeout as setTimeout$1}from"node:timers/promises";import{Http2ServerRequest,constants as constants$1}from"http2";import{lookup}from"node:dns";import{createServer}from"node:http";const WRITER_ID_RE=/^(agent-[^/]+|principal-[^/]+|file-system|git-upstream|openknowledge-service)$/;function classifyGitEntry(e,t,s){let g;try{g=statSync(e)}catch(t){let s=t.code;return s===`ENOENT`||s===`ENOTDIR`?{kind:`absent`}:{kind:`inaccessible`,gitPath:e,cause:t}}let S=computeProjectSubPath(t,s);if(g.isDirectory())return{kind:`directory`,path:e,projectSubPath:S};if(g.isFile()){let s;try{s=readFileSync(e,`utf-8`).trim()}catch(t){return{kind:`malformed-pointer`,gitPath:e,target:``,cause:t}}let g=s.match(/^gitdir:\s*(.+)$/);return g?{kind:`linked`,path:resolve(t,g[1]),gitPath:e,projectSubPath:S}:{kind:`malformed-pointer`,gitPath:e,target:``}}return{kind:`absent`}}function computeProjectSubPath(e,t){let s=relative(e,t);return s===``||s===`.`||s.startsWith(`..`)||isAbsolute(s)?``:s}function findAncestorGitEntry(e){let t=homedir(),s=resolve(e),g=64;for(let e=0;e<64;e++){if(s===t)return null;let e=dirname(s);if(e===s||e===t)return null;let g=resolve(e,`.git`);try{let t=statSync(g);if(t.isDirectory()||t.isFile())return{gitPath:g,workTreeRoot:e}}catch(e){let t=e.code;t!==`ENOENT`&&t!==`ENOTDIR`&&console.warn(`[shadow-repo-layout] Cannot stat ${g} (${t??`unknown`}); skipping ancestor`)}s=e}return null}function resolveGitDirDetailed(e){let t=resolve(e),s=classifyGitEntry(resolve(t,`.git`),t,t);if(s.kind!==`absent`)return s;let g=findAncestorGitEntry(t);return g===null?{kind:`absent`}:classifyGitEntry(g.gitPath,g.workTreeRoot,t)}function resolveGitDir(e){let t=resolveGitDirDetailed(e);return t.kind===`directory`||t.kind===`linked`?t.path:null}function resolveShadowDir(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return resolve(t.path,shadowSubdirName(t.projectSubPath));case`linked`:if(!existsSync(t.path))throw new MalformedGitPointerError(t.gitPath,t.path);return resolve(t.path,shadowSubdirName(t.projectSubPath));case`malformed-pointer`:throw new MalformedGitPointerError(t.gitPath,t.target,{cause:t.cause});case`inaccessible`:throw new GitDirAccessError(t.gitPath,{cause:t.cause});case`absent`:return resolve(e,`.git/ok`)}}function shadowSubdirName(e){return e===``?`ok`:`ok-${slugifyShadowSubPath(e)}`}function slugifyShadowSubPath(e){let t=e.split(sep).join(`-`).replace(/\/+/g,`-`).replace(/[^A-Za-z0-9._-]/g,`_`).replace(/^\.+/,`_`),s=64;if(t.length<=64)return t||`sub`;let g=djb2(e).toString(16).padStart(8,`0`);return`${t.slice(0,55)}-${g}`}function djb2(e){let t=5381;for(let s=0;s<e.length;s++)t=t*33+e.charCodeAt(s)>>>0;return t}var MalformedGitPointerError=class extends Error{gitPointerPath;resolvedTarget;constructor(e,t,s){let g=t?`references a missing or unreadable gitdir at ${t}`:`is unreadable or has no valid gitdir: pointer`;super(`\`.git\` pointer at ${e} ${g}. Run \`git worktree prune\` from the source repo and try again.`,s),this.name=`MalformedGitPointerError`,this.gitPointerPath=e,this.resolvedTarget=t}},GitDirAccessError=class extends Error{gitPath;constructor(e,t){let s=t?.cause!==void 0&&t.cause!==null&&typeof t.cause==`object`&&`code`in t.cause&&typeof t.cause.code==`string`?` (${t.cause.code})`:``;super(`Cannot access \`.git\` at ${e}${s}. Check filesystem permissions and that the volume is mounted.`,t),this.name=`GitDirAccessError`,this.gitPath=e}};function getShadowRepoPath(e){let t;try{t=resolveShadowDir(e)}catch(e){if(e instanceof MalformedGitPointerError||e instanceof GitDirAccessError)return null;throw e}return existsSync(resolve(t,`HEAD`))?t:null}function getWipRefPattern(e){return`refs/wip/${e}/`}const OK_CONTRIBUTORS_PREFIX=`ok-contributors: `;function parseContributors(e){if(!e)return[];let t=[];for(let s of e.split(`
|
|
1
|
+
import{a as __toCommonJS,i as __require$1,n as __esmMin,o as __toESM$1,r as __exportAll,t as __commonJSMin$1}from"./chunk-FK9Q3tQk.mjs";import{$ as FolderConfigPutSuccessSchema,$n as toWikiLinkSlug,$t as SyncConflictContentSuccessSchema,A as CONFIG_DOC_NAMES,An as emptySkillState,Ar as record,At as RenamePathSuccessSchema,Bn as isOrphanMode,Br as $ZodObject,Bt as SearchRequestSchema,C as CC1ServerInfoPayloadSchema,Cn as createBasenameIndex,Cr as intersection,Ct as ORPHAN_MODES,D as CC1_CHANNEL_DISK_ACK,Dn as createWorkspaceSearchDocument,Dr as object$1,Dt as PrincipalSuccessSchema,E as CC1_CHANNEL_CONFIG_VALIDATION_REJECTED,En as createWorkspaceSearchCorpus,Er as number,Et as PagesSuccessSchema,F as CreateFolderRequestSchema,Fn as getParseHealth,Fr as datetime,Ft as SKILL_STATE_TARGETS,G as DiffSuccessSchema,Gn as readFmMap,Gr as safeParseAsync$1,Gt as SeedPlanSuccessSchema,H as DeadLinksSuccessSchema,Hn as mergeThreeWay,Hr as parse$1,Ht as SeedApplyRequestSchema,I as CreateFolderSuccessSchema,In as getWikiLinkText,Ir as toJSONSchema,It as SKILL_STATE_VERSION_RE,Jn as searchWorkspaceCorpus,Jr as normalizeParams,Jt as SkillStateSchema,K as DocumentListSuccessSchema,Kn as resolveAssetProjectPath,Kr as clone,Kt as ServerInfoSuccessSchema,L as CreatePageRequestSchema,Ln as humanFormat,Lt as SYSTEM_DOC_NAME,M as CONFIG_DOC_NAME_PROJECT,Mn as extractFrontmatterTags,Mr as union,Mt as RollbackRequestSchema,N as CONFIG_DOC_NAME_PROJECT_LOCAL,Nn as fnv1aDigest,Nr as unknown,Nt as RollbackSuccessSchema,O as CC1_CHANNEL_SERVER_INFO,On as defaultScheduler,Or as optional,Ot as ProblemDetailsSchema,P as CONFIG_DOC_NAME_USER,Pn as getHeadingSlug,Pt as SKILL_STATE_REL,Q as FolderConfigPutRequestSchema,Qn as toBridgeInvariantLog,Qt as SyncAbortMergeSuccessSchema,R as CreatePageSuccessSchema,Rn as iconFromClientName,Rr as describe$1,Rt as SaveVersionRequestSchema,S as CC1DiskAckPayloadSchema,Sn as colorFromSeed,Sr as discriminatedUnion,St as MetricsReconciliationSuccessSchema,T as CC1_CHANNEL_CONFIG_IGNORE_NESTED_ERROR,Tn as createTagInTextRegex,Tr as looseObject,Tt as PageHeadingsSuccessSchema,U as DeletePathRequestSchema,Un as normalizeBridge,Ur as parseAsync,Ut as SeedApplySuccessSchema,Vn as mediaKindForSidebarAssetExtension,Vr as $ZodType,Vt as SearchSuccessSchema,W as DeletePathSuccessSchema,Wn as prependFrontmatter,Wr as safeParse$1,Wt as SeedListPacksSuccessSchema,X as EmptyRequestSchema,Xn as stripFrontmatter,Xt as StreamingProblemEventSchema,Y as EXECUTABLE_BLOCKLIST_EXTENSIONS,Yn as sharedExtensions,Yr as $constructor,Yt as SpawnCursorSuccessSchema,Z as FolderConfigGetSuccessSchema,Zn as tagsMatchingPrefix,Zr as require_dist$2,Zt as SuggestLinksSuccessSchema,_ as BridgeMergeContentLossError,_n as applyFastDiff,_r as _null,_t as LocalOpOpenRequestSchema,a as AgentBurstDiffSuccessSchema,an as SyncTriggerSuccessSchema,ar as ConfigSchema$1,at as InstallSkillRequestSchema,b as CC1ConfigValidationRejectedPayloadSchema,bn as classifyMarkdownHref,br as boolean,bt as MetricsAgentPresenceSuccessSchema,c as AgentUndoRequestSchema,cn as TemplateDeleteSuccessSchema,cr as applyPatchToDocument,ct as LinkGraphSuccessSchema,d as AgentWriteMdSuccessSchema,dn as TemplatePutSuccessSchema,dr as validatePatchScopes,dt as LocalOpAuthIdentitySuccessSchema,en as SyncConflictsSuccessSchema,er as unwrapFrontmatterFences,et as ForwardLinksSuccessSchema,f as AgentWriteRequestSchema,fn as TestRescanBacklinksSuccessSchema,fr as withConfigSpan,ft as LocalOpAuthPatRequestSchema,g as BridgeInvariantViolationError,gn as WorkspaceSuccessSchema,gr as _enum,gt as LocalOpCloneRequestSchema,h as BacklinksSuccessSchema,hn as UploadRequestSchema,hr as ZodOptional$1,ht as LocalOpAuthStatusSuccessSchema,i as AgentActivitySuccessSchema,in as SyncTriggerRequestSchema,ir as CONFIG_SCHEMA_MAJOR_PATH,it as INLINE_RENDERABLE_EXTENSIONS,j as CONFIG_DOC_NAME_OKIGNORE,jn as expandTagToHierarchy,jr as string,jt as RescueListSuccessSchema,k as CC1_CONTRACT_VERSION,kn as detectAppliedToleranceClasses,kr as preprocess,kt as RenamePathRequestSchema,l as AgentUndoSuccessSchema,ln as TemplateGetSuccessSchema,lr as locateIssue,lt as LocalOpAuthEmptySuccessSchema,m as BacklinkCountsSuccessSchema,mn as UploadAssetSuccessSchema,mt as LocalOpAuthSetIdentityRequestSchema,nn as SyncResolveConflictSuccessSchema,nr as PluginKey,nt as HistoryVersionSuccessSchema,o as AgentPatchRequestSchema,on as TagsForNameSuccessSchema,or as LOCAL_DIR,ot as InstallSkillSuccessSchema,p as AgentWriteSuccessSchema,pn as TestResetSuccessSchema,pr as withConfigSpanSync,pt as LocalOpAuthPatSuccessSchema,q as DocumentReadSuccessSchema,qn as resolveInternalHref,qr as defineLazy,qt as SkillInstallStateSuccessSchema,r as ASSET_EXTENSIONS,rn as SyncStatusSchema,rr as Fragment,rt as HubsSuccessSchema,s as AgentPatchSuccessSchema,sn as TagsListSuccessSchema,sr as addConfigSpanEvent,st as InstalledAgentsSuccessSchema,t as AGENT_ICON_COLORS,tn as SyncResolveConflictRequestSchema,tr as getSchema,tt as HistorySuccessSchema,u as AgentWriteMdRequestSchema,un as TemplatePutRequestSchema,ur as toConfigIssue,ut as LocalOpAuthHostRequestSchema,v as CC1BranchSwitchedPayloadSchema,vn as applyIncrementalDiff,vt as LocalOpOpenSuccessSchema,w as CC1_CHANNEL_BRANCH_SWITCHED,wn as createCodeFenceTracker,wr as literal,wt as OrphansSuccessSchema,x as CC1DerivedViewPayloadSchema,xn as classifyWikiLinkTarget,xr as custom,xt as MetricsParseHealthSuccessSchema,y as CC1ConfigIgnoreNestedErrorPayloadSchema,yn as assertNeverProblemType,yr as array,yt as MarkdownManager,z as DEFAULT_DEDUP_MODE,zn as isKnownConfigError,zr as meta$1,zt as SaveVersionSuccessSchema}from"./dist-Buq7uUK7.mjs";import{a as metrics,c as SpanStatusCode,i as propagation,l as SpanKind,n as init_esm$2,o as diag,r as trace,s as context,t as esm_exports$2}from"./esm-BbkJd7ro.mjs";import{a as acquireProcessLock,c as isValidLockPid,f as readServerLock,g as updateProcessLockPort,m as releaseServerLock,n as RUNTIME_VERSION,o as acquireServerLock,p as releaseProcessLock,s as isProcessAlive,t as ProcessLockCollisionError,u as readProcessLock}from"./server-lock-D7DXNVql-BRVVzA6T.mjs";import{a as require_src$15,i as esm_default,r as withParentLock,t as createGitInstance}from"./git-handle-DwfYp_z--CfyPz4Dz.mjs";import{r as diffLines,t as createPatch}from"./libesm-YL3Bqolr.mjs";import{n as mimes,t as build_default}from"./build-fAc55Z_L.mjs";import{t as b1}from"./chunk-YNYSPYQ5-Dq-BWW-f.mjs";import{a as c,c as h,d as m,f as p,h as x,i as b,l as i,m as v,n as C,o as d,p as u,r as a,s as f,t as $$1,u as l}from"./chunk-GFQRA5P5-CkMj9l7f.mjs";import{A as gt,B as wt,C as _i$1,D as da$1,E as bt,F as pe,H as zi$1,I as qi,L as us$1,M as ma$1,N as mt$1,O as di$1,P as pa$1,S as X$1,T as bl,V as xi$1,_ as Ti$1,a as Fi$1,b as W$1,c as M,d as P,f as Pt$1,g as T,h as Sl,i as En$1,j as he,k as ga$1,l as Nl,m as Se,n as Bi$1,o as Fs$1,p as R,r as Ci$1,s as G$1,t as Al,u as Oi$1,v as V,w as be,x as Wi$1,y as Vi$1,z as wl}from"./chunk-FEIOJCZD-Vm1q1kLH.mjs";import{a as d$1,c as m$1,d as y,i as c$1,l as p$1,n as N,o as f$1,r as P$1,s as h$1,t as $$2,u as v$1}from"./chunk-XHM67O4N-Cd7Fiqsb.mjs";import{n as l$1,r as o,t as h$2}from"./chunk-R6VWJ2ZL-DSqbA7Rj.mjs";import{r as o$1}from"./chunk-CWQS3NFK-BQ5SUtd7.mjs";import"./chunk-DXB73IDG-DfmyzFzL.mjs";import{n as d$2,t as _$1}from"./chunk-5QMZ5MUS-SLhNX8t9.mjs";import{n as u$1,t as b$1}from"./chunk-A5O5YHGN-DQP-O5US.mjs";import{n,r,t as c$2}from"./chunk-OJDRYQWQ-D4lSWh0K.mjs";import{r as x$1,t as a$1}from"./chunk-24IMIIXA-_PX4ITYZ.mjs";import{n as n$1}from"./chunk-3THT3N7L-DrzOuTpA.mjs";import{t as n$2}from"./chunk-44UOCSGV-BbZqjKvt.mjs";import{createRequire}from"node:module";import{execFile,spawn,spawnSync}from"node:child_process";import*as U from"node:path";import{basename,dirname,extname,isAbsolute,join,normalize,posix,relative,resolve,sep,win32}from"node:path";import*as I from"node:fs";import{appendFileSync,closeSync,createReadStream,createWriteStream,existsSync,linkSync,lstatSync,mkdirSync,openSync,readFile,readFileSync,readSync,readdirSync,realpathSync,renameSync,rmSync,rmdirSync,statSync,unlinkSync,writeFileSync}from"node:fs";import{homedir,hostname,platform,tmpdir}from"node:os";import{URLSearchParams as URLSearchParams$1,fileURLToPath}from"node:url";import{AsyncLocalStorage}from"node:async_hooks";import{promisify}from"node:util";import{Readable}from"stream";import{Transform}from"node:stream";import crypto$1,{createHash,randomUUID,webcrypto}from"node:crypto";import crypto$2 from"crypto";import*as zlib$2 from"zlib";import{access,constants,mkdir,readFile as readFile$1,readdir,realpath,rename,stat as stat$1,writeFile}from"node:fs/promises";import{pipeline}from"node:stream/promises";import{setTimeout as setTimeout$1}from"node:timers/promises";import{Http2ServerRequest,constants as constants$1}from"http2";import{lookup}from"node:dns";import{createServer}from"node:http";const WRITER_ID_RE=/^(agent-[^/]+|principal-[^/]+|file-system|git-upstream|openknowledge-service)$/;function classifyGitEntry(e,t,s){let g;try{g=statSync(e)}catch(t){let s=t.code;return s===`ENOENT`||s===`ENOTDIR`?{kind:`absent`}:{kind:`inaccessible`,gitPath:e,cause:t}}let S=computeProjectSubPath(t,s);if(g.isDirectory())return{kind:`directory`,path:e,projectSubPath:S};if(g.isFile()){let s;try{s=readFileSync(e,`utf-8`).trim()}catch(t){return{kind:`malformed-pointer`,gitPath:e,target:``,cause:t}}let g=s.match(/^gitdir:\s*(.+)$/);return g?{kind:`linked`,path:resolve(t,g[1]),gitPath:e,projectSubPath:S}:{kind:`malformed-pointer`,gitPath:e,target:``}}return{kind:`absent`}}function computeProjectSubPath(e,t){let s=relative(e,t);return s===``||s===`.`||s.startsWith(`..`)||isAbsolute(s)?``:s}function findAncestorGitEntry(e){let t=homedir(),s=resolve(e),g=64;for(let e=0;e<64;e++){if(s===t)return null;let e=dirname(s);if(e===s||e===t)return null;let g=resolve(e,`.git`);try{let t=statSync(g);if(t.isDirectory()||t.isFile())return{gitPath:g,workTreeRoot:e}}catch(e){let t=e.code;t!==`ENOENT`&&t!==`ENOTDIR`&&console.warn(`[shadow-repo-layout] Cannot stat ${g} (${t??`unknown`}); skipping ancestor`)}s=e}return null}function resolveGitDirDetailed(e){let t=resolve(e),s=classifyGitEntry(resolve(t,`.git`),t,t);if(s.kind!==`absent`)return s;let g=findAncestorGitEntry(t);return g===null?{kind:`absent`}:classifyGitEntry(g.gitPath,g.workTreeRoot,t)}function resolveGitDir(e){let t=resolveGitDirDetailed(e);return t.kind===`directory`||t.kind===`linked`?t.path:null}function resolveShadowDir(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return resolve(t.path,shadowSubdirName(t.projectSubPath));case`linked`:if(!existsSync(t.path))throw new MalformedGitPointerError(t.gitPath,t.path);return resolve(t.path,shadowSubdirName(t.projectSubPath));case`malformed-pointer`:throw new MalformedGitPointerError(t.gitPath,t.target,{cause:t.cause});case`inaccessible`:throw new GitDirAccessError(t.gitPath,{cause:t.cause});case`absent`:return resolve(e,`.git/ok`)}}function shadowSubdirName(e){return e===``?`ok`:`ok-${slugifyShadowSubPath(e)}`}function slugifyShadowSubPath(e){let t=e.split(sep).join(`-`).replace(/\/+/g,`-`).replace(/[^A-Za-z0-9._-]/g,`_`).replace(/^\.+/,`_`),s=64;if(t.length<=64)return t||`sub`;let g=djb2(e).toString(16).padStart(8,`0`);return`${t.slice(0,55)}-${g}`}function djb2(e){let t=5381;for(let s=0;s<e.length;s++)t=t*33+e.charCodeAt(s)>>>0;return t}var MalformedGitPointerError=class extends Error{gitPointerPath;resolvedTarget;constructor(e,t,s){let g=t?`references a missing or unreadable gitdir at ${t}`:`is unreadable or has no valid gitdir: pointer`;super(`\`.git\` pointer at ${e} ${g}. Run \`git worktree prune\` from the source repo and try again.`,s),this.name=`MalformedGitPointerError`,this.gitPointerPath=e,this.resolvedTarget=t}},GitDirAccessError=class extends Error{gitPath;constructor(e,t){let s=t?.cause!==void 0&&t.cause!==null&&typeof t.cause==`object`&&`code`in t.cause&&typeof t.cause.code==`string`?` (${t.cause.code})`:``;super(`Cannot access \`.git\` at ${e}${s}. Check filesystem permissions and that the volume is mounted.`,t),this.name=`GitDirAccessError`,this.gitPath=e}};function getShadowRepoPath(e){let t;try{t=resolveShadowDir(e)}catch(e){if(e instanceof MalformedGitPointerError||e instanceof GitDirAccessError)return null;throw e}return existsSync(resolve(t,`HEAD`))?t:null}function getWipRefPattern(e){return`refs/wip/${e}/`}const OK_CONTRIBUTORS_PREFIX=`ok-contributors: `;function parseContributors(e){if(!e)return[];let t=[];for(let s of e.split(`
|
|
2
2
|
`)){let e=s.trim();if(e.startsWith(OK_CONTRIBUTORS_PREFIX))try{let s=JSON.parse(e.slice(17));if(typeof s==`object`&&s&&`id`in s&&typeof s.id==`string`&&`name`in s&&typeof s.name==`string`&&`docs`in s&&Array.isArray(s.docs)&&s.docs.every(e=>typeof e==`string`)&&(!(`colorSeed`in s)||typeof s.colorSeed==`string`)){let e=s;if(`summaries`in e){let t=e.summaries;(!Array.isArray(t)||!t.every(e=>typeof e==`string`))&&delete e.summaries}t.push(s)}}catch{}}return t}const OK_CHECKPOINT_PREFIX=`ok-checkpoint-v1: `;function parseCheckpoint(e){if(!e)return null;for(let t of e.split(`
|
|
3
3
|
`)){let e=t.trim();if(!e.startsWith(OK_CHECKPOINT_PREFIX))continue;let s;try{s=JSON.parse(e.slice(18))}catch{return null}if(typeof s!=`object`||!s)return null;let g=s,S=g.kind,w=g.metadata;if(typeof w!=`object`||!w)return null;let E=typeof g.docName==`string`?g.docName:null,D=typeof g.size==`number`&&Number.isFinite(g.size)?g.size:null;if(S===`bridge-merge-loss`){let e=w;return Array.isArray(e.lostSubstrings)&&e.lostSubstrings.every(e=>typeof e==`string`)?{kind:`bridge-merge-loss`,docName:E,size:D,metadata:{lostSubstrings:e.lostSubstrings}}:null}if(S===`external-change-rescue`){let e=w;return typeof e.incomingDiskSha==`string`?{kind:`external-change-rescue`,docName:E,size:D,metadata:{incomingDiskSha:e.incomingDiskSha}}:null}return null}return null}function formatCheckpointBodyLine(e){let t={kind:e.kind,metadata:e.metadata};return e.docName!==null&&(t.docName=e.docName),e.size!==null&&(t.size=e.size),`${OK_CHECKPOINT_PREFIX}${JSON.stringify(t)}`}const OK_ACTOR_PREFIX=`ok-actor: `;function formatOkActor(e){let{summaries:t,previous_paths:s,...g}=e,S={...g};return t&&t.length>0&&(S.summaries=t),s&&s.length>0&&(S.previous_paths=s),`${OK_ACTOR_PREFIX}${JSON.stringify(S)}`}function parseOkActorObject(e){if(e.v!==1||!(`display_name`in e)||typeof e.display_name!=`string`||!(`docs`in e)||!Array.isArray(e.docs))return null;let t=typeof e.principal==`string`?e.principal:null,s=typeof e.agent_session==`string`?e.agent_session:null,g;if(typeof e.writer_id==`string`&&e.writer_id.length>0)g=e.writer_id;else if(s)g=`agent-${s}`;else if(t)g=t;else switch(e.display_name){case`File System`:g=`file-system`;break;case`Git (upstream)`:g=`git-upstream`;break;default:g=`openknowledge-service`}let S=`summaries`in e&&Array.isArray(e.summaries)&&e.summaries.every(e=>typeof e==`string`)?e.summaries:void 0,w=parsePreviousPaths(e);return{v:1,writer_id:g,principal:t,agent_session:s,agent_type:typeof e.agent_type==`string`?e.agent_type:null,client_name:typeof e.client_name==`string`?e.client_name:null,client_version:typeof e.client_version==`string`?e.client_version:null,label:typeof e.label==`string`?e.label:null,display_name:e.display_name,color_seed:typeof e.color_seed==`string`?e.color_seed:`unknown`,docs:e.docs.filter(e=>typeof e==`string`),...S&&S.length>0?{summaries:S}:{},...w&&w.length>0?{previous_paths:w}:{}}}function parsePreviousPaths(e){if(!(`previous_paths`in e)||!Array.isArray(e.previous_paths))return;let t=[];for(let s of e.previous_paths){if(typeof s!=`object`||!s)continue;let e=s;typeof e.from!=`string`||typeof e.to!=`string`||t.push({from:e.from,to:e.to})}return t}function parseOkActors(e){if(!e)return[];let t=[];for(let s of e.split(`
|
|
4
4
|
`)){let e=s.trim();if(!e.startsWith(OK_ACTOR_PREFIX))continue;let g;try{g=JSON.parse(e.slice(10))}catch{continue}if(typeof g!=`object`||!g)continue;let S=parseOkActorObject(g);S&&t.push(S)}return t}function okActorToShadowContributor(e){let t={v:1,id:e.writer_id,name:e.display_name,colorSeed:e.color_seed,docs:e.docs};return e.summaries&&e.summaries.length>0&&(t.summaries=e.summaries),t}function readContributors(e){let t=parseOkActors(e);return t.length>0?t.map(okActorToShadowContributor):parseContributors(e)}function formatWipSubject(e){return e.length===0?`wip: auto-save`:e.length===1?`wip: ${e[0]}`:`wip: ${e.length} docs`}function formatReconcileSubject(e){return`reconcile: ${e}`}function formatRollbackSubject(e,t){return`rollback: ${e} to ${t.slice(0,7)}`}function formatParkSubject(e,t){return`park: ${e} -> ${t}`}function formatRenameSubject(e,t){return`rename: ${e} -> ${t}`}function formatCheckpointSubject(e){return`checkpoint: ${e}`}function formatImportSubject(e,t){return e?`import: from ${e.slice(0,8)}..${t.slice(0,8)}`:`import: initial at ${t.slice(0,8)}`}const SUBJECT_LINE_BREAK_RE=RegExp(`[\\r\\n\\v\\f\\u0085\\u2028\\u2029]`,`g`);function stripLineBreaks(e){return e.replace(SUBJECT_LINE_BREAK_RE,` `)}function composeCommitSubject(e,t){let s=stripLineBreaks(e);if(t.length===0)return s;if(t.length>=2)return`${s} (${t.length} edits)`;let[g]=t;if(g===void 0)return s;let S=stripLineBreaks(g),w=`${s} — ${S}`;if(w.length<=72)return w;let E=`${s} — `,D=72-E.length-1;return D<=0?w.slice(0,72):`${E}${S.slice(0,D)}…`}function parseWriterId(e){return WRITER_ID_RE.test(e)?e.startsWith(`agent-`)?{id:e,classification:`agent`,isAgent:!0}:e.startsWith(`principal-`)?{id:e,classification:`principal`,isAgent:!1}:e===`file-system`?{id:e,classification:`classified-file-system`,isAgent:null}:e===`git-upstream`?{id:e,classification:`classified-git-upstream`,isAgent:null}:e===`openknowledge-service`?{id:e,classification:`classified-openknowledge-service`,isAgent:null}:{id:e,classification:`unknown`,isAgent:null}:{id:e,classification:`unknown`,isAgent:null}}var require_err_helpers=__commonJSMin$1(((e,t)=>{let s=e=>e&&typeof e.message==`string`,g=e=>{if(!e)return;let t=e.cause;if(typeof t==`function`){let t=e.cause();return s(t)?t:void 0}else return s(t)?t:void 0},S=(e,t)=>{if(!s(e))return``;let w=e.stack||``;if(t.has(e))return w+`
|
|
@@ -818,10 +818,10 @@ Karpathy's insight: "The tedious part of maintaining a knowledge base is not the
|
|
|
818
818
|
|
|
819
819
|
`}async function resolveServerUrl(e,t){return typeof e==`function`?await e(t):e}async function resolveConfig(e,t){return typeof e==`function`?await e(t):e}async function resolveProjectConfigContext(e,t,s){let g;try{g=await e(s)}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}try{let e=await resolveConfig(t,g);return{ok:!0,cwd:g,config:e}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async function resolveProjectServerContext(e,t,s,g){let S=await resolveProjectConfigContext(e,t,g);if(!S.ok)return S;let{cwd:w,config:E}=S;try{return{ok:!0,cwd:w,config:E,url:await resolveServerUrl(s,w)}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}function normalizeDocName(e){let t=e.toLowerCase();return t.endsWith(`.md`)?{ok:!0,docName:e.slice(0,-3)}:t.endsWith(`.mdx`)?{ok:!0,docName:e.slice(0,-4)}:t.endsWith(`.markdown`)?{ok:!1,error:`Error: docName "${e}" ends in ".markdown", which is not a supported extension. Use ".md" or ".mdx", or strip the extension to let the server auto-detect.`}:{ok:!0,docName:e}}function normalizeResponse(e,t){if(e.ok){if(typeof t!=`object`||!t||Array.isArray(t))return{ok:!0,data:t};let{ok:e,...s}=t;return{ok:!0,...s}}if(typeof t!=`object`||!t||Array.isArray(t))return{ok:!1,error:`Server returned HTTP ${e.status} with non-object body`};let s=t;if(typeof s.type==`string`&&typeof s.title==`string`){let{type:e,title:t,status:g,instance:S,detail:w,...E}=s;return{...E,ok:!1,error:t,type:e,...typeof g==`number`?{status:g}:{},...typeof S==`string`?{instance:S}:{},...typeof w==`string`?{detail:w}:{}}}let{ok:g,error:S,...w}=s,E=typeof S==`string`?S:typeof s.message==`string`?s.message:`Server returned HTTP ${e.status}`;return{...w,ok:!1,error:E}}async function httpGet(e,t){let s;try{s=await fetch(`${e}${t}`,{signal:AbortSignal.timeout(3e4)})}catch(e){return{ok:!1,error:`Server unreachable: ${e instanceof Error?e.message:e}`}}let g;try{g=await s.json()}catch(e){let t=e instanceof Error?e.message:String(e);return s.ok?{ok:!1,error:`Server returned 2xx response with non-JSON body: ${t}`}:{ok:!1,error:`Server returned HTTP ${s.status} with non-JSON body: ${t}`}}return normalizeResponse(s,g)}async function httpPost(e,t,s){let g;if(s!==void 0)try{g=JSON.stringify(s)}catch(e){return{ok:!1,error:`Request body is not JSON-serializable: ${e instanceof Error?e.message:String(e)}`}}let S;try{S=await fetch(`${e}${t}`,{method:`POST`,headers:{"Content-Type":`application/json`},body:g,signal:AbortSignal.timeout(3e4)})}catch(e){return{ok:!1,error:`Server unreachable: ${e instanceof Error?e.message:e}`}}let w;try{w=await S.json()}catch(e){let t=e instanceof Error?e.message:String(e);return S.ok?{ok:!1,error:`Server returned 2xx response with non-JSON body: ${t}`}:{ok:!1,error:`Server returned HTTP ${S.status} with non-JSON body: ${t}`}}return normalizeResponse(S,w)}function parseRenameCollidingPairs(e){return Array.isArray(e)?e.flatMap(e=>{if(!e||typeof e!=`object`)return[];let{existing:t,incoming:s,to:g}=e;return typeof t==`string`&&typeof s==`string`&&typeof g==`string`?[{existing:t,incoming:s,to:g}]:[]}):[]}function mergeCascade(e,t){let s={...e},g=new Map;for(let[e,S]of Object.entries(t))if(S!==void 0)if(Array.isArray(S)){let t=Array.isArray(s[e])?[...s[e]]:[],w=g.get(e)??new Set(t.map(toDedupKey));g.set(e,w);for(let e of S){let s=toDedupKey(e);w.has(s)||(w.add(s),t.push(e))}s[e]=t}else s[e]=S;return s}function mergePatch(e,t){let s={...e};for(let[e,g]of Object.entries(t))if(g!==void 0){if(isEmpty$1(g)){delete s[e];continue}s[e]=g}return s}function isEmpty$1(e){return!!(e===null||typeof e==`string`&&e===``||Array.isArray(e)&&e.length===0)}function toDedupKey(e){return typeof e==`string`?`s:${e}`:typeof e==`number`?`n:${e}`:typeof e==`boolean`?`b:${e}`:e===null?`null`:e===void 0?`undefined`:`j:${JSON.stringify(e)}`}function resolveNestedFrontmatter(e,t){return resolveNestedFrontmatterWithSources(e,t).merged}function resolveNestedFrontmatterWithSources(e,t){let s=t.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``),g=s===``||s===`.`?[]:s.split(`/`).filter(e=>e.length>0),S={},w={},E=!1;for(let t=0;t<=g.length;t++){let s=t===0?``:g.slice(0,t).join(`/`),D=t===0?resolve(e,`.ok`,`frontmatter.yml`):resolve(e,s,`.ok`,`frontmatter.yml`);if(!existsSync(D))continue;let O=readFrontmatterYaml(D);if(O!=null){S=mergeCascade(S,O);for(let e of Object.keys(O))O[e]!==void 0&&(w[e]=s);E=!0}}return E?{merged:coerceWellKnown(S),sources:w}:{merged:{},sources:{}}}function coerceWellKnown(e){let t={};for(let[s,g]of Object.entries(e))t[s]=g;return typeof e.title==`string`?t.title=e.title:delete t.title,typeof e.description==`string`?t.description=e.description:delete t.description,Array.isArray(e.tags)?t.tags=e.tags.filter(e=>typeof e==`string`):delete t.tags,t}const warnedPaths=new Set;function readFrontmatterYaml(e){let t;try{t=readFileSync(e,`utf-8`)}catch{return null}let s;try{s=(0,import_dist$1.parse)(t)}catch(t){if(!warnedPaths.has(e)){warnedPaths.add(e);let s=t instanceof Error?t.message:String(t);console.warn(`[ok-folder-frontmatter] malformed YAML at ${e} — folder defaults skipped. Fix the file or delete it. Reason: ${s}`)}return null}return typeof s!=`object`||!s||Array.isArray(s)?null:s}function parentFolderOf(e){let t=e.lastIndexOf(`/`);return t===-1?``:e.slice(0,t)}const GIT_TIMEOUT_MS$2=5e3;function projectHasGitDir(e){try{return statSync(resolve(e,`.git`)).isDirectory()}catch{return!1}}function openProjectGit(e){return esm_default({baseDir:resolve(e),timeout:{block:GIT_TIMEOUT_MS$2}})}async function readProjectGitLog(e,t,s=5){if(!projectHasGitDir(e))return{commits:[],source:`git-absent`};let g=openProjectGit(e),S=``;try{S=await g.raw(`log`,`-${Math.max(1,s)}`,`--format=%H|%aI|%an|%s`,`--follow`,`--`,t)}catch{return{commits:[],source:`git`}}let w=[];for(let e of S.split(`
|
|
820
820
|
`)){if(!e)continue;let t=e.indexOf(`|`);if(t<0)continue;let s=e.indexOf(`|`,t+1);if(s<0)continue;let g=e.indexOf(`|`,s+1);g<0||w.push({hash:e.slice(0,t),date:e.slice(t+1,s),authorName:e.slice(s+1,g),subject:e.slice(g+1)})}return{commits:w,source:`git`}}const GIT_TIMEOUT_MS$1=5e3;async function currentProjectBranch(e){try{let t=(await esm_default({baseDir:e,timeout:{block:GIT_TIMEOUT_MS$1}}).revparse([`--abbrev-ref`,`HEAD`])).trim();return t&&t!==`HEAD`?t:null}catch{return null}}function openShadowGit(e,t){return esm_default({baseDir:t,timeout:{block:GIT_TIMEOUT_MS$1}}).env({GIT_DIR:e,GIT_WORK_TREE:t})}function writerIdFromRef(e,t){let s=getWipRefPattern(t);return e.startsWith(s)?e.slice(s.length):e}async function logOnRef(e,t,s,g,S){let w=``;try{w=await e.raw(`log`,t,`-${Math.max(1,S*2)}`,`--format=%H%x00%aI%x00%an%x00%s%x00%B%x1e`,`--`,s)}catch{return[]}let E=writerIdFromRef(t,g),D=parseWriterId(E),O=[];for(let e of w.split(``)){let t=e.trimStart();if(!t)continue;let[s=``,S=``,w=``,k=``,j=``]=t.split(`\0`),F=s.trim();F.length===40&&O.push({hash:F,date:S,writerName:w,message:k,contributors:readContributors(j),writerId:E,isAgent:D.isAgent,writerClassification:D.classification,branch:g})}return O}async function readShadowLog(e,t,s=5){let g=getShadowRepoPath(e);if(!g)return{commits:[],source:`shadow-repo-absent`};let S=await currentProjectBranch(e);if(!S)return{commits:[],source:`shadow-repo`};let w=openShadowGit(g,resolve(e)),E=``;try{E=await w.raw(`for-each-ref`,getWipRefPattern(S),`--format=%(refname)`)}catch{return{commits:[],source:`shadow-repo`}}let D=E.split(`
|
|
821
|
-
`).map(e=>e.trim()).filter(Boolean);return D.length===0?{commits:[],source:`shadow-repo`}:{commits:(await Promise.all(D.map(e=>logOnRef(w,e,t,S,s)))).flat().sort((e,t)=>t.date.localeCompare(e.date)).slice(0,s),source:`shadow-repo`}}const defaultProvider=()=>{try{return homedir()}catch{return null}};let userHomeProvider=defaultProvider;const USER_TEMPLATES_SOURCE_LABEL=`~/.ok`;function getUserHome(){return userHomeProvider()}function getUserTemplatesDir(){let e=userHomeProvider();return e?join(e,`.ok`,`templates`):null}function resolveTemplatesAvailable(e,t,s={}){let g=normalizeFolderPath(t),S=g===``?[]:g.split(`/`),w=new Set,E=[];collectFromFolder(e,g,`local`,w,E);for(let t=S.length-1;t>=1;t--)collectFromFolder(e,S.slice(0,t).join(`/`),`inherited`,w,E);return S.length>0&&collectFromFolder(e,``,`inherited`,w,E),collectUserTemplates(w,E),E}function collectUserTemplates(e,t){let s=getUserTemplatesDir();if(!s||!existsSync(s))return;let g;try{g=readdirSync(s)}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[ok-templates] failed to read user templates directory at ${s}: ${t}`);return}for(let S of g){if(!S.endsWith(`.md`))continue;let g=S.slice(0,-3);if(e.has(g))continue;let w=join(s,S),E;try{E=statSync(w)}catch{continue}if(!E.isFile())continue;let D=readTemplateMeta(w),O={name:g,path:w.split(/\\/g).join(`/`),source_folder:USER_TEMPLATES_SOURCE_LABEL,scope:`user`};D.title!==void 0&&(O.title=D.title),D.description!==void 0&&(O.description=D.description),e.add(g),t.push(O)}}function collectFromFolder(e,t,s,g,S){let w=t?join(e,t,`.ok`,`templates`):join(e,`.ok`,`templates`);if(!existsSync(w))return;let E;try{E=readdirSync(w)}catch{return}for(let e of E){if(!e.endsWith(`.md`))continue;let E=e.slice(0,-3);if(g.has(E))continue;let D=join(w,e),O;try{O=statSync(D)}catch{continue}if(!O.isFile())continue;let k=readTemplateMeta(D),j={name:E,path:t?posix.join(t,`.ok`,`templates`,e):posix.join(`.ok`,`templates`,e),source_folder:t,scope:s};k.title!==void 0&&(j.title=k.title),k.description!==void 0&&(j.description=k.description),g.add(E),S.push(j)}}function normalizeFolderPath(e){return e.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``).replace(/^\.$/,``)}const templateMetaWarnedPaths=new Set;function readTemplateMeta(e){let t;try{t=readFileSync(e,`utf-8`)}catch(t){if(t?.code!==`ENOENT`&&!templateMetaWarnedPaths.has(e)){templateMetaWarnedPaths.add(e);let s=t instanceof Error?t.message:String(t);console.warn(`[ok-templates] failed to read template at ${e} — metadata skipped. Reason: ${s}`)}return{}}let s=extractFrontmatterYaml(t);if(s===null)return{};let g;try{g=(0,import_dist$1.parse)(s)}catch(t){if(!templateMetaWarnedPaths.has(e)){templateMetaWarnedPaths.add(e);let s=t instanceof Error?t.message:String(t);console.warn(`[ok-templates] malformed YAML frontmatter at ${e} — title/description unavailable. Reason: ${s}`)}return{}}if(typeof g!=`object`||!g)return{};let S=g,w={};return typeof S.title==`string`&&(w.title=S.title),typeof S.description==`string`&&(w.description=S.description),w}function extractFrontmatterYaml(e){let t=e.replace(/^/,``),s=/^[ \t]*---\r?\n([\s\S]*?)\r?\n[ \t]*---(\r?\n|$)/.exec(t);return s?s[1]??null:null}const FRONTMATTER_RE=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;function parseFrontmatterRaw(e){let t=e.match(FRONTMATTER_RE);if(!t)return null;try{let e=(0,import_dist$1.parse)(t[1]);if(typeof e==`object`&&e&&!Array.isArray(e))return e}catch{}return null}const DIRECTORY_SCAN_CAP=1e3,DIR_SKIP=new Set([`.git`,`.ok`,`node_modules`,`.changeset`,`.claude`,`.agents`,`dist`,`build`]),WIKI_EXT_RE=/\.(md|mdx)$/i;function pathToDocName$1(e){return e.replace(/\.md$/,``).replace(/\.mdx$/,``)}const fmReadWarnedPaths=new Set;async function readFrontmatter(e){try{return parseFrontmatterRaw(await readFile$1(e,`utf-8`))??{}}catch(t){if(t?.code!==`ENOENT`&&!fmReadWarnedPaths.has(e)){fmReadWarnedPaths.add(e);let s=t instanceof Error?t.message:String(t);console.warn(`[ok-enrich] failed to read frontmatter at ${e} — enrichment degraded for this file. Reason: ${s}`)}return null}}async function fetchBacklinks(e,t){if(!e)return null;let s=await httpGet(e,`/api/backlinks?docName=${encodeURIComponent(t)}`);if(!s.ok)return null;let g=s.backlinks??s.results??s.links;if(!Array.isArray(g))return[];let S=[];for(let e of g){if(typeof e!=`object`||!e)continue;let t=e,s=typeof t.docName==`string`?t.docName:typeof t.source==`string`?t.source:typeof t.page==`string`?t.page:void 0;s&&S.push({source:s,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null})}return S}const BACKLINK_COUNT_CHUNK=100;async function fetchBacklinkCountsBatch(e,t){if(!e||t.length===0)return null;let s=[...new Set(t)],g=[];for(let e=0;e<s.length;e+=BACKLINK_COUNT_CHUNK)g.push(s.slice(e,e+BACKLINK_COUNT_CHUNK));let S=await Promise.all(g.map(async t=>{let s=await httpGet(e,`/api/backlink-counts?docNames=${encodeURIComponent(t.join(`,`))}`);return s.ok?s.counts??{}:null})),w=new Map,E=!1;for(let e of S)if(e){E=!0;for(let[t,s]of Object.entries(e))typeof s==`number`&&Number.isFinite(s)&&w.set(t,s)}return E?w:null}async function fetchForwardLinks(e,t){if(!e)return null;let s=await httpGet(e,`/api/forward-links?docName=${encodeURIComponent(t)}`);if(!s.ok)return null;let g=s.forwardLinks??s.links??s.results;if(!Array.isArray(g))return[];let S=[];for(let e of g){if(typeof e!=`object`||!e)continue;let t=e;if(t.kind===`external`&&typeof t.url==`string`){S.push({kind:`external`,url:t.url,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null});continue}let s=typeof t.docName==`string`?t.docName:void 0;s&&S.push({kind:`doc`,docName:s,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null})}return S}function mergeFileAndFolder(e,t,s){let g=mergeCascade(s?resolveNestedFrontmatter(s,parentFolderOf(t)):{},e??{});return{title:typeof g.title==`string`?g.title:void 0,description:typeof g.description==`string`?g.description:void 0,tags:Array.isArray(g.tags)?g.tags.filter(e=>typeof e==`string`):[],frontmatter:g}}async function enrichPath(e,t,s={}){let g=resolveWithinRoot(t.projectDir,e);if(!g.ok)throw Error(`enrichPath: ${g.reason}`);let S=g.rel,w=g.abs,E=t.historyDepth??5,D=s.includeRichFields===!0,O=readFrontmatter(w);if(!D){let e=mergeFileAndFolder(await O,S,t.projectDir);return{path:S,title:e.title,description:e.description,tags:e.tags,frontmatter:e.frontmatter,backlinkCount:null,backlinks:null,forwardLinkCount:null,forwardLinks:null,history:null,historySource:null,projectHistory:null,projectHistorySource:null}}let[k,j,F,L,B]=await Promise.all([O,fetchBacklinks(t.serverUrl,pathToDocName$1(S)).catch(()=>null),fetchForwardLinks(t.serverUrl,pathToDocName$1(S)).catch(()=>null),readShadowLog(t.projectDir,S,E).catch(()=>({commits:[],source:`shadow-repo`})),readProjectGitLog(t.projectDir,S,E).catch(()=>({commits:[],source:`git`}))]),H=mergeFileAndFolder(k,S,t.projectDir);return{path:S,title:H.title,description:H.description,tags:H.tags,frontmatter:H.frontmatter,backlinkCount:j?.length??null,backlinks:j,forwardLinkCount:F?.length??null,forwardLinks:F,history:L.commits,historySource:L.source,projectHistory:B.commits,projectHistorySource:B.source}}async function scanDirectory(e,t){let s={directMdCount:0,recursiveMdCount:0,childDirCount:0,mostRecent:null,truncated:!1},g=0,S=[{path:e,depth:0}];for(;S.length>0;){let e=S.shift();if(!e)break;if(g>=DIRECTORY_SCAN_CAP){s.truncated=!0;break}let w;try{w=await readdir(e.path,{withFileTypes:!0})}catch{continue}for(let E of w){if(g>=DIRECTORY_SCAN_CAP){s.truncated=!0;break}g++;let w=E.name;if(E.isDirectory()){if(DIR_SKIP.has(w)||w.startsWith(`.`))continue;e.depth===0&&s.childDirCount++,S.push({path:`${e.path}/${w}`,depth:e.depth+1})}else if(E.isFile()&&WIKI_EXT_RE.test(w)){s.recursiveMdCount++,e.depth===0&&s.directMdCount++;let g=`${e.path}/${w}`;try{let e=await stat$1(g);(!s.mostRecent||e.mtimeMs>s.mostRecent.mtimeMs)&&(s.mostRecent={absPath:g,relPath:relative(t,g).split(/[\\/]/).filter(Boolean).join(`/`),mtimeMs:e.mtimeMs})}catch{}}}}return s}async function enrichDirectory(e,t){let s=resolveWithinRoot(t.projectDir,e);if(!s.ok)throw Error(`enrichDirectory: ${s.reason}`);let g=s.rel,S=s.abs,w=await scanDirectory(S,t.projectDir),E;if(w.mostRecent){let e=await readFrontmatter(w.mostRecent.absPath),t=typeof e?.title==`string`?e.title:void 0;E={path:w.mostRecent.relPath,title:t??basename(w.mostRecent.relPath),updatedAt:new Date(w.mostRecent.mtimeMs).toISOString()}}let D={path:g,type:`directory`,directMdCount:w.directMdCount,recursiveMdCount:w.recursiveMdCount,childDirCount:w.childDirCount,mostRecentMd:E,truncated:w.truncated},O=resolveNestedFrontmatter(t.projectDir,g),k=O.title,j=O.description,F=O.tags??[];k!==void 0&&(D.title=k),j!==void 0&&(D.description=j),F.length>0&&(D.tags=F),Object.keys(O).length>0&&(D.frontmatter_defaults=O);let L=resolveTemplatesAvailable(t.projectDir,g);return L.length>0&&(D.templates_available=L),D}async function enrichDirectoryRecursive(e,t,s){let g=await enrichDirectory(e,s);if(t<=1)return g;let S=g.path,w=resolve(s.projectDir,S),E;try{E=await readdir(w,{withFileTypes:!0})}catch{return g}let D=[];for(let e of E){if(!e.isDirectory()||RECURSIVE_LISTING_SKIP_DIRS.has(e.name)||e.name.startsWith(`.`))continue;let g=await enrichDirectoryRecursive(S?`${S}/${e.name}`:e.name,t-1,s);D.push(g)}return D.length>0&&(g.subfolders=D),g}const RECURSIVE_LISTING_SKIP_DIRS=new Set([`.git`,`.ok`,`node_modules`,`.venv`,`venv`,`env`,`__pycache__`,`vendor`,`dist`,`build`,`out`,`output`,`.next`,`.nuxt`,`.svelte-kit`,`.astro`,`.turbo`,`.cache`,`.parcel-cache`,`coverage`]);function applyNestedFolderRulesUpsert(e){if(!isAbsolute(e.projectDir))return{ok:!1,error:{code:`BAD_PROJECT_DIR`,message:`projectDir must be absolute`}};let t=[];for(let s of e.rules){let g=resolveTargetFolderFromMatch(s.new_match??s.match);if(!g.ok)return{ok:!1,error:{code:`MULTI_FOLDER_GLOB`,message:g.message,rule:s.match}};let S=g.folder?resolve(e.projectDir,g.folder):e.projectDir,w=resolve(e.projectDir);if(!S.startsWith(w+sep)&&S!==w)return{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved target folder escapes projectDir: ${S}`,rule:s.match}};let E=null,D=null;if(s.new_match!==void 0&&s.new_match!==s.match){let t=resolveTargetFolderFromMatch(s.match);if(!t.ok)return{ok:!1,error:{code:`MULTI_FOLDER_GLOB`,message:t.message,rule:s.match}};if(E=t.folder,D=t.folder?resolve(e.projectDir,t.folder):e.projectDir,!D.startsWith(w+sep)&&D!==w)return{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved source folder escapes projectDir: ${D}`,rule:s.match}}}t.push({targetFolder:g.folder,targetAbs:S,sourceFolder:E,sourceAbs:D,rule:s})}let s=[];for(let g of t)try{if(g.sourceAbs&&g.sourceAbs!==g.targetAbs){let t=join(g.sourceAbs,`.ok`,`frontmatter.yml`);existsSync(t)&&(unlinkSync(t),autoCleanOkDir(join(g.sourceAbs,`.ok`)),s.push({match:g.rule.match,path:relPathOf$1(e.projectDir,t),action:`deleted`}))}let t=join(g.targetAbs,`.ok`),S=join(t,`frontmatter.yml`),w=readExistingFrontmatter(S),E=Object.keys(g.rule.frontmatter).length===0?{}:mergePatch(w,g.rule.frontmatter);if(Object.keys(E).length===0){existsSync(S)&&(unlinkSync(S),autoCleanOkDir(t),s.push({match:g.rule.new_match??g.rule.match,path:relPathOf$1(e.projectDir,S),action:`deleted`}));continue}mkdirSync(t,{recursive:!0});let D=(0,import_dist$1.stringify)(E),O=`${S}.tmp.${process.pid}.${Date.now()}`;writeFileSync(O,D,`utf-8`),renameSync(O,S),s.push({match:g.rule.new_match??g.rule.match,path:relPathOf$1(e.projectDir,S),action:`written`})}catch(e){return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to write nested frontmatter for ${g.rule.match}: ${e.message}`,rule:g.rule.match},...s.length>0?{partiallyApplied:s}:{}}}return{ok:!0,applied:s}}function resolveTargetFolderFromMatch(e){let t=e.split(`/`).filter(e=>e.length>0),s=[],g=!1;for(let S of t){let t=/[*?[\]{}]/.test(S);if(g&&!t)return{ok:!1,message:`Glob "${e}" matches multiple folders (literal segment "${S}" appears after a glob). Split it into one rule per folder, e.g. set_folder_rule({ rules: [{ match: "specs/foo/${S}/**", ... }, ...] }).`};if(t){if(g=!0,S!==`**`&&S!==`*`)return{ok:!1,message:`Glob "${e}" uses an unsupported pattern segment "${S}". Only "*" and "**" are supported in nested folder rules.`};continue}s.push(S)}return{ok:!0,folder:s.join(`/`)}}function readExistingFrontmatter(e){if(!existsSync(e))return{};let t=(0,import_dist$1.parse)(readFileSync(e,`utf-8`));return typeof t!=`object`||!t||Array.isArray(t)?{}:{...t}}function autoCleanOkDir(e){if(!existsSync(e))return;let t;try{t=readdirSync(e)}catch{return}if(t.length===0)try{rmdirSync(e)}catch{}}function relPathOf$1(e,t){let s=resolve(e);return t.startsWith(s+sep)?t.slice(s.length+1).split(sep).join(`/`):t}const SUBSTITUTION_ALLOWLIST=[`date`,`user`],TOKEN_PATTERN=/\{\{([^{}\n]+?)\}\}/g;function validateSubstitution(e){let t=[];for(let s of e.matchAll(TOKEN_PATTERN)){let e=(s[1]??``).trim();isAllowedToken(e)||t.push({token:e,offset:s.index??0})}return t}function applySubstitution(e,t){return e.replace(TOKEN_PATTERN,(e,s)=>{let g=s.trim();return isAllowedToken(g)?t[g]:e})}function isAllowedToken(e){return SUBSTITUTION_ALLOWLIST.includes(e)}function todayIsoUtc(e=new Date){return`${e.getUTCFullYear().toString().padStart(4,`0`)}-${(e.getUTCMonth()+1).toString().padStart(2,`0`)}-${e.getUTCDate().toString().padStart(2,`0`)}`}const NAME_RE=/^[A-Za-z0-9_-]+$/;function applyTemplateWrite(e){let t=e.target??`project`,s=resolveRootForTarget(t,e.projectDir);if(!s.ok)return{ok:!1,error:s.error};let g=t===`user`?``:e.folder,S=validateInputs(s.rootDir,g,e.name);if(!S.ok)return{ok:!1,error:S.error};let w=validateTitle(e.frontmatter.title);if(!w.ok)return{ok:!1,error:w.error};let E=validateSubstitutionAllowlist(e.body);if(!E.ok)return{ok:!1,error:E.error};let{templatesDir:D,filePath:O}=templatePaths(s.rootDir,S.folderRel,e.name),k=serializeFrontmatter(e.frontmatter),j=k?`---\n${k}---\n${e.body}`:e.body;try{mkdirSync(D,{recursive:!0})}catch(e){return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to create template directory at ${displayPath(t,s.rootDir,D)}: ${e.message}`}}}let F=!existsSync(O),L=`${O}.tmp.${process.pid}.${Date.now()}`;try{writeFileSync(L,j,`utf-8`),renameSync(L,O)}catch(e){try{unlinkSync(L)}catch{}return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to write template at ${displayPath(t,s.rootDir,O)}: ${e.message}`}}}let B=[];return(e.frontmatter.description===void 0||typeof e.frontmatter.description!=`string`||e.frontmatter.description.length===0)&&B.push("Template frontmatter.description is missing — `description` disambiguates between similarly-named templates in the menu. Recommended but not required."),{ok:!0,path:displayPath(t,s.rootDir,O),created:F,warnings:B}}function applyTemplateDelete(e){let t=e.target??`project`,s=resolveRootForTarget(t,e.projectDir);if(!s.ok)return{ok:!1,error:s.error};let g=t===`user`?``:e.folder,S=validateInputs(s.rootDir,g,e.name);if(!S.ok)return{ok:!1,error:S.error};let{templatesDir:w,okDir:E,filePath:D}=templatePaths(s.rootDir,S.folderRel,e.name),O=existsSync(D);if(O)try{unlinkSync(D)}catch(e){return{ok:!1,error:{code:`UNLINK_FAILED`,message:`Failed to delete template at ${displayPath(t,s.rootDir,D)}: ${e.message}`}}}let k=!1,j=!1;if(existsSync(w)&&isEmpty(w))try{rmdirSync(w),k=!0}catch{}if(existsSync(E)&&isEmpty(E))try{rmdirSync(E),j=!0}catch{}return{ok:!0,path:displayPath(t,s.rootDir,D),existed:O,cleanedEmpty:{templatesDir:k,okDir:j}}}function resolveRootForTarget(e,t){if(e===`user`){let e=getUserHome();return e?{ok:!0,rootDir:e}:{ok:!1,error:{code:`USER_HOME_UNAVAILABLE`,message:`User home directory could not be resolved. User templates require a writable home directory at ~/.ok/templates/.`}}}return{ok:!0,rootDir:t}}function displayPath(e,t,s){return e===`user`?s.startsWith(t+sep)?`~/${s.slice(t.length+1).split(sep).join(`/`)}`:s.split(sep).join(`/`):relPathOf(t,s)}function validateInputs(e,t,s){if(!isAbsolute(e))return{ok:!1,error:{code:`BAD_PROJECT_DIR`,message:`projectDir must be absolute`}};if(!NAME_RE.test(s))return{ok:!1,error:{code:`BAD_NAME`,message:`Template name must match /^[A-Za-z0-9_-]+$/ (got: ${JSON.stringify(s)}). Use letters, digits, underscores, or hyphens — no slashes, dots, or spaces.`}};let g=t.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``).replace(/^\.$/,``);if(g.includes(`..`))return{ok:!1,error:{code:`PATH_TRAVERSAL`,message:`Folder path may not contain "..": ${JSON.stringify(t)}`}};let S=g?resolve(e,g):e,w=resolve(e);return!S.startsWith(w+sep)&&S!==w?{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved folder path escapes projectDir: ${S}`}}:{ok:!0,folderRel:g}}function validateTitle(e){return typeof e!=`string`||e.length===0?{ok:!1,error:{code:`TEMPLATE_TITLE_REQUIRED`,message:"Template frontmatter.title is required. `title` is the menu surface — agents pick templates by name+title; a title-less template is effectively invisible. Set a non-empty `title` and retry."}}:{ok:!0}}function validateSubstitutionAllowlist(e){let t=validateSubstitution(e);return t.length===0?{ok:!0}:{ok:!1,error:{code:`TEMPLATE_UNKNOWN_VARIABLE`,message:`Template body contains unknown substitution token(s): ${t.map(e=>`\`{{${e.token}}}\` at offset ${e.offset}`).join(`, `)}. v1 allowlist: \`{{date}}\`, \`{{user}}\`. Remove or rename the offending tokens and retry.`}}}function templatePaths(e,t,s){let g=t?join(e,t,`.ok`):join(e,`.ok`),S=join(g,`templates`);return{okDir:g,templatesDir:S,filePath:join(S,`${s}.md`)}}function relPathOf(e,t){return normalize(t.startsWith(e+sep)?t.slice(e.length+1):t).split(sep).join(`/`)}function serializeFrontmatter(e){let t={};return e.title!==void 0&&(t.title=e.title),e.description!==void 0&&(t.description=e.description),Array.isArray(e.tags)&&e.tags.length>0&&(t.tags=e.tags),Object.keys(t).length===0?``:(0,import_dist$1.stringify)(t)}function isEmpty(e){try{return readdirSync(e).length===0}catch{return!1}}const log$6=()=>getLogger(`http`);let _apiErrorCounter=null;function apiErrorCounter(){return _apiErrorCounter||=getMeter().createCounter(`ok.api.error.count`,{description:`API error responses by problem type and handler`,unit:`1`}),_apiErrorCounter}function errorResponse(e,t,s,g,S={}){let w=S.instance??`urn:uuid:${randomUUID()}`;if(e.headersSent||e.writableEnded||e.destroyed){log$6().error({event:`api.error.double-write`,instance:w,type:s,status:t,handler:S.handler},`errorResponse called after headers already sent — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...S.handler?{handler:S.handler}:{}});return}let E={type:s,title:g,status:t,instance:w,detail:S.detail??void 0},D=ProblemDetailsSchema.safeParse(E);if(!D.success){log$6().error({event:`api.error.malformed-envelope`,issues:D.error.issues,body:E,handler:S.handler,originalStatus:t},`errorResponse produced an invalid ProblemDetails body — emitting fallback`);let s=500;apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...S.handler?{handler:S.handler}:{}}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:w}));return}let O=S.extensions?{...S.extensions,...E}:E;apiErrorCounter().add(1,{type:s,...S.handler?{handler:S.handler}:{}});let k=t>=500?`error`:`warn`;log$6()[k]({event:`api.error`,instance:w,type:s,status:t,handler:S.handler,detail:S.detail,err:S.cause},g);let j;try{j=JSON.stringify(O)}catch(s){log$6().error({event:`api.error.unserializable-body`,bodyKeys:Object.keys(O),handler:S.handler,originalStatus:t,instance:w,err:s},`errorResponse wireBody is not JSON-serializable — emitting hardcoded fallback`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...S.handler?{handler:S.handler}:{}}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:w}));return}e.writeHead(t,{...S.extraHeaders,"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(j)}function streamingProblemEvent(e,t,s,g={}){let S=g.instance??`urn:uuid:${randomUUID()}`,w={type:`error`,problem:{type:t,title:s,status:e,instance:S,detail:g.detail??void 0}},E=StreamingProblemEventSchema.safeParse(w);if(!E.success){log$6().error({event:`api.streaming.malformed-envelope`,issues:E.error.issues,body:w,handler:g.handler,originalStatus:e},`streamingProblemEvent produced an invalid StreamingProblemEvent — returning fallback`);let t=500;return apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...g.handler?{handler:g.handler}:{}}),{type:`error`,problem:{type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:S}}}apiErrorCounter().add(1,{type:t,...g.handler?{handler:g.handler}:{}});let D=e>=500?`error`:`warn`;return log$6()[D]({event:`api.streaming.error`,instance:S,type:t,status:e,handler:g.handler,detail:g.detail,err:g.cause},s),w}function createStreamingErrorWriter(e,t){return(s,g,S,w={})=>{if(e.writableEnded||e.destroyed){log$6().error({event:`api.streaming.error.suppressed`,type:g,status:s,handler:t,detail:w.detail,err:w.cause},`createStreamingErrorWriter called after writableEnded/destroyed — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...t?{handler:t}:{}});return}let E=streamingProblemEvent(s,g,S,{handler:t,...w});try{e.write(`${JSON.stringify(E)}\n`)}catch(e){log$6().error({event:`api.streaming.error.write-failed`,type:g,status:s,handler:t,err:w.cause,writeErr:e},`createStreamingErrorWriter: res.write threw — original error preserved in log`)}}}const log$5=()=>getLogger(`http`);function successResponse(e,t,s,g,S={}){if(e.headersSent||e.writableEnded||e.destroyed){log$5().error({event:`api.success.double-write`,status:t,handler:S.handler},`successResponse called after headers already sent — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...S.handler?{handler:S.handler}:{}});return}let w=s.safeParse(g);if(!w.success){log$5().error({event:`api.success.malformed-body`,issues:w.error.issues,bodyKeys:typeof g==`object`&&g?Object.keys(g):null,handler:S.handler,originalStatus:t},`successResponse produced an invalid body for the supplied schema — emitting fallback`),errorResponse(e,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:S.handler});return}let E;try{E=JSON.stringify(w.data)}catch(s){log$5().error({event:`api.success.unserializable-body`,bodyKeys:typeof w.data==`object`&&w.data!==null?Object.keys(w.data):null,handler:S.handler,originalStatus:t,err:s},`successResponse parsed body is not JSON-serializable — emitting fallback`),errorResponse(e,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:S.handler});return}e.writeHead(t,{...S.extraHeaders,"Content-Type":`application/json`,"X-Content-Type-Options":`nosniff`}),e.end(E)}const INSTALLED_AGENTS_SCHEMES=[`claude`,`codex`,`cursor`],INSTALLED_AGENTS_PROBE_TIMEOUT_MS=2e3,MACOS_APP_NAMES={claude:[`Claude`],codex:[`Codex`,`OpenAI Codex`],cursor:[`Cursor`]};function createInstalledAgentsProbe(e){let t=new Map,s=e.now??Date.now,g=e.ttlMs??6e4;async function S(S){let w=t.get(S);if(w?.status===`resolved`&&w.expiresAt>s())return w.installed;if(w?.status===`inflight`)return w.promise;let E=(async()=>{try{let w=await e.probe(S);return t.set(S,{status:`resolved`,installed:w,expiresAt:s()+g}),w}catch{return t.set(S,{status:`resolved`,installed:!1,expiresAt:s()+g}),!1}})();return t.set(S,{status:`inflight`,promise:E}),E}async function w(){let e=await Promise.all(INSTALLED_AGENTS_SCHEMES.map(async e=>[e,await S(e)]));return Object.fromEntries(e)}return{probeAll:w,probeWithCache:S}}async function handleInstalledAgents(e,t,s){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`installed-agents`,extraHeaders:{Allow:`GET`}});return}try{successResponse(t,200,InstalledAgentsSuccessSchema,await s(),{handler:`installed-agents`})}catch(e){console.error(`[installed-agents]`,e),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`installed-agents`,cause:e})}}function createOsProbe(e,t=execFile){return s=>e===`darwin`?probeMacOs(s,t):e===`win32`?probeWindows(s,t):probeLinux(s,t)}function probeMacOs(e,t){let s=MACOS_APP_NAMES[e];function g(e){return new Promise(s=>{t(`osascript`,[`-e`,`id of app "${e}"`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},(e,t)=>{if(e){s(!1);return}s(t.trim().length>0)})})}return(async()=>{for(let e of s)if(await g(e))return!0;return!1})()}function probeWindows(e,t){return new Promise(s=>{t(`reg`,[`query`,`HKCR\\${e}`,`/ve`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},e=>{s(!e)})})}function probeLinux(e,t){return new Promise(s=>{t(`xdg-mime`,[`query`,`default`,`x-scheme-handler/${e}`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},(e,t)=>{if(e){s(!1);return}s(t.trim().length>0)})})}const FIXED_HUB_BASENAMES=[`INDEX`,`README`,`REPORT`,`SPEC`],MAX_CANDIDATES=3;function findHubCandidates(e,t){let s=[],g=new Set,S=t=>{!t||g.has(t)||t!==e&&(g.add(t),s.push(t))},w=buildLowerDocNameIndex(t),E=parentFolder(e);for(;;){for(let e of FIXED_HUB_BASENAMES)if(S(lookup$1(t,w,joinDocName(E,e))),s.length>=MAX_CANDIDATES)return s;let e=E===``?null:basename$1(E);if(e&&(S(lookup$1(t,w,joinDocName(E,e))),s.length>=MAX_CANDIDATES))return s;if(E===``)break;E=parentFolder(E)}return s}function lookup$1(e,t,s){return e.has(s)?s:t.get(s.toLowerCase())??null}function buildLowerDocNameIndex(e){let t=new Map;for(let s of e.keys()){let e=s.toLowerCase();t.has(e)||t.set(e,s)}return t}function parentFolder(e){let t=e.lastIndexOf(`/`);return t<0?``:e.slice(0,t)}function basename$1(e){let t=e.lastIndexOf(`/`);return t<0?e:e.slice(t+1)}function joinDocName(e,t){return e===``?t:`${e}/${t}`}function splitFrontmatterLines(e){return e?e.replace(/^---\r?\n/,``).replace(/\r?\n---(?:\r?\n)?$/,``).split(/\r?\n/):[]}function normalizeFrontmatterScalar(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).trim():t}function extractFrontmatterScalar(e,t){let s=`${t}:`;for(let t of splitFrontmatterLines(e))if(t.startsWith(s))return normalizeFrontmatterScalar(t.slice(s.length))||null;return null}function parseInlineAliases(e){let t=[],s=``,g=null;for(let S of e){if(g){s+=S,S===g&&(g=null);continue}if(S===`"`||S===`'`){g=S,s+=S;continue}if(S===`,`){let e=normalizeFrontmatterScalar(s);e&&t.push(e),s=``;continue}s+=S}let S=normalizeFrontmatterScalar(s);return S&&t.push(S),t}function dedupeExact(e){let t=[],s=new Set;for(let g of e)!g||s.has(g)||(s.add(g),t.push(g));return t}function extractPageAliases(e){let{frontmatter:t}=stripFrontmatter(e);if(!t)return[];let s=splitFrontmatterLines(t);for(let e=0;e<s.length;e+=1){let t=s[e]?.match(/^aliases:\s*(.*)$/);if(!t)continue;let g=t[1]?.trim()??``;if(g){if(g.startsWith(`[`)&&g.endsWith(`]`))return dedupeExact(parseInlineAliases(g.slice(1,-1)));let e=normalizeFrontmatterScalar(g);return e?[e]:[]}let S=[];for(let t=e+1;t<s.length;t+=1){let e=s[t];if(e?.trim()){if(/^\s*-\s+/.test(e)){let t=normalizeFrontmatterScalar(e.replace(/^\s*-\s+/,``));t&&S.push(t);continue}if(/^[^\s][^:]*:\s*/.test(e))break;break}}return dedupeExact(S)}return[]}function extractPageTitle(e,t){let{frontmatter:s,body:g}=stripFrontmatter(e),S=extractFrontmatterScalar(s,`title`);if(S)return S;let w=g.match(/^# (.+)$/m);return w?w[1].trim():t}function parseFrontmatterMetadata(e){return e?.trim()?{cluster:extractFrontmatterScalar(e,`cluster`)??void 0,category:extractFrontmatterScalar(e,`category`)??void 0,tags:extractFrontmatterArray(e,`tags`)}:{cluster:void 0,category:void 0,tags:void 0}}function extractFrontmatterArray(e,t){let s=`${t}:`,g=splitFrontmatterLines(e);for(let e=0;e<g.length;e+=1){let t=g[e];if(!t?.startsWith(s))continue;let S=t.slice(s.length).trim();if(S){if(S.startsWith(`[`)&&S.endsWith(`]`)){let e=parseInlineAliases(S.slice(1,-1));return e.length>0?e:void 0}let e=normalizeFrontmatterScalar(S);return e?[e]:void 0}let w=[];for(let t=e+1;t<g.length;t+=1){let e=g[t];if(e?.trim()){if(/^\s*-\s+/.test(e)){let t=normalizeFrontmatterScalar(e.replace(/^\s*-\s+/,``));t&&w.push(t);continue}if(/^[^\s][^:]*:\s*/.test(e))break;break}}return w.length>0?w:void 0}}function extractPageIdentity(e,t){let s=extractPageTitle(e,t),g=extractPageAliases(e),S=dedupeExact([s,...g]),w=[],E=new Set;for(let e of S){let t=toWikiLinkSlug(e);!t||E.has(t)||(E.add(t),w.push(t))}return{docName:t,title:s,aliases:g,matchLabels:S,normalizedMatchLabels:w}}const MAX_ZIP_BYTES=102400;function resolveBundledSkillDir(){let e=[`../assets/skills/open-knowledge`,`./assets/skills/open-knowledge`],t=[];for(let s of e){let e=fileURLToPath(new URL(s,import.meta.url));if(existsSync(e))return e;t.push(e)}throw Error(`Bundled skill asset directory not found. Tried: ${t.join(`, `)}. This usually means the CLI build did not copy packages/server/assets into dist/assets. Run \`cd packages/cli && bun run build\` before publishing.`)}async function*walkFiles(e,t=e){let s=await readdir(e,{withFileTypes:!0});for(let g of s){let s=join(e,g.name);g.isDirectory()?yield*walkFiles(s,t):g.isFile()&&(yield relative(t,s))}}function computeWrapperFolderName(e,t=basename){return t(e)||`open-knowledge`}function toPosixZipPath(e,t=sep){return t===`/`?e:e.split(t).join(`/`)}async function zipDirectory(e,t){let s=computeWrapperFolderName(e),g=new import_yazl.ZipFile;g.addEmptyDirectory(`${s}/`);let S=[];for await(let t of walkFiles(e))S.push(t);S.sort();for(let t of S){let S=join(e,t),w=`${s}/${toPosixZipPath(t)}`;g.addFile(S,w)}g.end(),await new Promise((e,s)=>{let S=createWriteStream(t);g.outputStream.pipe(S),S.on(`close`,()=>e()),S.on(`error`,s),g.outputStream.on(`error`,s)})}async function sha256OfFile(e){return new Promise((t,s)=>{let g=createHash(`sha256`),S=createReadStream(e);S.on(`data`,e=>g.update(e)),S.on(`end`,()=>t(g.digest(`hex`))),S.on(`error`,s)})}function extractMetadataVersion(e){let t=e.indexOf(`
|
|
821
|
+
`).map(e=>e.trim()).filter(Boolean);return D.length===0?{commits:[],source:`shadow-repo`}:{commits:(await Promise.all(D.map(e=>logOnRef(w,e,t,S,s)))).flat().sort((e,t)=>t.date.localeCompare(e.date)).slice(0,s),source:`shadow-repo`}}const defaultProvider=()=>{try{return homedir()}catch{return null}};let userHomeProvider=defaultProvider;const USER_TEMPLATES_SOURCE_LABEL=`~/.ok`;function getUserHome(){return userHomeProvider()}function getUserTemplatesDir(){let e=userHomeProvider();return e?join(e,`.ok`,`templates`):null}function resolveTemplatesAvailable(e,t,s={}){let g=normalizeFolderPath(t),S=g===``?[]:g.split(`/`),w=new Set,E=[];collectFromFolder(e,g,`local`,w,E);for(let t=S.length-1;t>=1;t--)collectFromFolder(e,S.slice(0,t).join(`/`),`inherited`,w,E);return S.length>0&&collectFromFolder(e,``,`inherited`,w,E),collectUserTemplates(w,E),E}function collectUserTemplates(e,t){let s=getUserTemplatesDir();if(!s||!existsSync(s))return;let g;try{g=readdirSync(s)}catch(e){let t=e instanceof Error?e.message:String(e);console.warn(`[ok-templates] failed to read user templates directory at ${s}: ${t}`);return}for(let S of g){if(!S.endsWith(`.md`))continue;let g=S.slice(0,-3);if(e.has(g))continue;let w=join(s,S),E;try{E=statSync(w)}catch{continue}if(!E.isFile())continue;let D=readTemplateMeta(w),O={name:g,path:w.split(/\\/g).join(`/`),source_folder:USER_TEMPLATES_SOURCE_LABEL,scope:`user`};D.title!==void 0&&(O.title=D.title),D.description!==void 0&&(O.description=D.description),e.add(g),t.push(O)}}function collectFromFolder(e,t,s,g,S){let w=t?join(e,t,`.ok`,`templates`):join(e,`.ok`,`templates`);if(!existsSync(w))return;let E;try{E=readdirSync(w)}catch{return}for(let e of E){if(!e.endsWith(`.md`))continue;let E=e.slice(0,-3);if(g.has(E))continue;let D=join(w,e),O;try{O=statSync(D)}catch{continue}if(!O.isFile())continue;let k=readTemplateMeta(D),j={name:E,path:t?posix.join(t,`.ok`,`templates`,e):posix.join(`.ok`,`templates`,e),source_folder:t,scope:s};k.title!==void 0&&(j.title=k.title),k.description!==void 0&&(j.description=k.description),g.add(E),S.push(j)}}function normalizeFolderPath(e){return e.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``).replace(/^\.$/,``)}const templateMetaWarnedPaths=new Set;function readTemplateMeta(e){let t;try{t=readFileSync(e,`utf-8`)}catch(t){if(t?.code!==`ENOENT`&&!templateMetaWarnedPaths.has(e)){templateMetaWarnedPaths.add(e);let s=t instanceof Error?t.message:String(t);console.warn(`[ok-templates] failed to read template at ${e} — metadata skipped. Reason: ${s}`)}return{}}let s=extractFrontmatterYaml(t);if(s===null)return{};let g;try{g=(0,import_dist$1.parse)(s)}catch(t){if(!templateMetaWarnedPaths.has(e)){templateMetaWarnedPaths.add(e);let s=t instanceof Error?t.message:String(t);console.warn(`[ok-templates] malformed YAML frontmatter at ${e} — title/description unavailable. Reason: ${s}`)}return{}}if(typeof g!=`object`||!g)return{};let S=g,w={};return typeof S.title==`string`&&(w.title=S.title),typeof S.description==`string`&&(w.description=S.description),w}function extractFrontmatterYaml(e){let t=e.replace(/^/,``),s=/^[ \t]*---\r?\n([\s\S]*?)\r?\n[ \t]*---(\r?\n|$)/.exec(t);return s?s[1]??null:null}const FRONTMATTER_RE=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;function parseFrontmatterRaw(e){let t=e.match(FRONTMATTER_RE);if(!t)return null;try{let e=(0,import_dist$1.parse)(t[1]);if(typeof e==`object`&&e&&!Array.isArray(e))return e}catch{}return null}const DIRECTORY_SCAN_CAP=1e3,DIR_SKIP=new Set([`.git`,`.ok`,`node_modules`,`.changeset`,`.claude`,`.agents`,`dist`,`build`]),WIKI_EXT_RE=/\.(md|mdx)$/i;function pathToDocName$1(e){return e.replace(/\.md$/,``).replace(/\.mdx$/,``)}const fmReadWarnedPaths=new Set;async function readFrontmatter(e){try{return parseFrontmatterRaw(await readFile$1(e,`utf-8`))??{}}catch(t){if(t?.code!==`ENOENT`&&!fmReadWarnedPaths.has(e)){fmReadWarnedPaths.add(e);let s=t instanceof Error?t.message:String(t);console.warn(`[ok-enrich] failed to read frontmatter at ${e} — enrichment degraded for this file. Reason: ${s}`)}return null}}async function fetchBacklinks(e,t){if(!e)return null;let s=await httpGet(e,`/api/backlinks?docName=${encodeURIComponent(t)}`);if(!s.ok)return null;let g=s.backlinks??s.results??s.links;if(!Array.isArray(g))return[];let S=[];for(let e of g){if(typeof e!=`object`||!e)continue;let t=e,s=typeof t.docName==`string`?t.docName:typeof t.source==`string`?t.source:typeof t.page==`string`?t.page:void 0;s&&S.push({source:s,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null})}return S}const BACKLINK_COUNT_CHUNK=100;async function fetchBacklinkCountsBatch(e,t){if(!e||t.length===0)return null;let s=[...new Set(t)],g=[];for(let e=0;e<s.length;e+=BACKLINK_COUNT_CHUNK)g.push(s.slice(e,e+BACKLINK_COUNT_CHUNK));let S=await Promise.all(g.map(async t=>{let s=await httpGet(e,`/api/backlink-counts?docNames=${encodeURIComponent(t.join(`,`))}`);return s.ok?s.counts??{}:null})),w=new Map,E=!1;for(let e of S)if(e){E=!0;for(let[t,s]of Object.entries(e))typeof s==`number`&&Number.isFinite(s)&&w.set(t,s)}return E?w:null}async function fetchForwardLinks(e,t){if(!e)return null;let s=await httpGet(e,`/api/forward-links?docName=${encodeURIComponent(t)}`);if(!s.ok)return null;let g=s.forwardLinks??s.links??s.results;if(!Array.isArray(g))return[];let S=[];for(let e of g){if(typeof e!=`object`||!e)continue;let t=e;if(t.kind===`external`&&typeof t.url==`string`){S.push({kind:`external`,url:t.url,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null});continue}let s=typeof t.docName==`string`?t.docName:void 0;s&&S.push({kind:`doc`,docName:s,title:typeof t.title==`string`?t.title:void 0,snippet:typeof t.snippet==`string`?t.snippet:null})}return S}function mergeFileAndFolder(e,t,s){let g=mergeCascade(s?resolveNestedFrontmatter(s,parentFolderOf(t)):{},e??{});return{title:typeof g.title==`string`?g.title:void 0,description:typeof g.description==`string`?g.description:void 0,tags:Array.isArray(g.tags)?g.tags.filter(e=>typeof e==`string`):[],frontmatter:g}}async function enrichPath(e,t,s={}){let g=resolveWithinRoot(t.projectDir,e);if(!g.ok)throw Error(`enrichPath: ${g.reason}`);let S=g.rel,w=g.abs,E=t.historyDepth??5,D=s.includeRichFields===!0,O=readFrontmatter(w);if(!D){let e=mergeFileAndFolder(await O,S,t.projectDir);return{path:S,title:e.title,description:e.description,tags:e.tags,frontmatter:e.frontmatter,backlinkCount:null,backlinks:null,forwardLinkCount:null,forwardLinks:null,history:null,historySource:null,projectHistory:null,projectHistorySource:null}}let[k,j,F,L,B]=await Promise.all([O,fetchBacklinks(t.serverUrl,pathToDocName$1(S)).catch(()=>null),fetchForwardLinks(t.serverUrl,pathToDocName$1(S)).catch(()=>null),readShadowLog(t.projectDir,S,E).catch(()=>({commits:[],source:`shadow-repo`})),readProjectGitLog(t.projectDir,S,E).catch(()=>({commits:[],source:`git`}))]),H=mergeFileAndFolder(k,S,t.projectDir);return{path:S,title:H.title,description:H.description,tags:H.tags,frontmatter:H.frontmatter,backlinkCount:j?.length??null,backlinks:j,forwardLinkCount:F?.length??null,forwardLinks:F,history:L.commits,historySource:L.source,projectHistory:B.commits,projectHistorySource:B.source}}async function scanDirectory(e,t){let s={directMdCount:0,recursiveMdCount:0,childDirCount:0,mostRecent:null,truncated:!1},g=0,S=[{path:e,depth:0}];for(;S.length>0;){let e=S.shift();if(!e)break;if(g>=DIRECTORY_SCAN_CAP){s.truncated=!0;break}let w;try{w=await readdir(e.path,{withFileTypes:!0})}catch{continue}for(let E of w){if(g>=DIRECTORY_SCAN_CAP){s.truncated=!0;break}g++;let w=E.name;if(E.isDirectory()){if(DIR_SKIP.has(w)||w.startsWith(`.`))continue;e.depth===0&&s.childDirCount++,S.push({path:`${e.path}/${w}`,depth:e.depth+1})}else if(E.isFile()&&WIKI_EXT_RE.test(w)){s.recursiveMdCount++,e.depth===0&&s.directMdCount++;let g=`${e.path}/${w}`;try{let e=await stat$1(g);(!s.mostRecent||e.mtimeMs>s.mostRecent.mtimeMs)&&(s.mostRecent={absPath:g,relPath:relative(t,g).split(/[\\/]/).filter(Boolean).join(`/`),mtimeMs:e.mtimeMs})}catch{}}}}return s}async function enrichDirectory(e,t){let s=resolveWithinRoot(t.projectDir,e);if(!s.ok)throw Error(`enrichDirectory: ${s.reason}`);let g=s.rel,S=s.abs,w=await scanDirectory(S,t.projectDir),E;if(w.mostRecent){let e=await readFrontmatter(w.mostRecent.absPath),t=typeof e?.title==`string`?e.title:void 0;E={path:w.mostRecent.relPath,title:t??basename(w.mostRecent.relPath),updatedAt:new Date(w.mostRecent.mtimeMs).toISOString()}}let D={path:g,type:`directory`,directMdCount:w.directMdCount,recursiveMdCount:w.recursiveMdCount,childDirCount:w.childDirCount,mostRecentMd:E,truncated:w.truncated},O=resolveNestedFrontmatter(t.projectDir,g),k=O.title,j=O.description,F=O.tags??[];k!==void 0&&(D.title=k),j!==void 0&&(D.description=j),F.length>0&&(D.tags=F),Object.keys(O).length>0&&(D.frontmatter_defaults=O);let L=resolveTemplatesAvailable(t.projectDir,g);return L.length>0&&(D.templates_available=L),D}async function enrichDirectoryRecursive(e,t,s){let g=await enrichDirectory(e,s);if(t<=1)return g;let S=g.path,w=resolve(s.projectDir,S),E;try{E=await readdir(w,{withFileTypes:!0})}catch{return g}let D=[];for(let e of E){if(!e.isDirectory()||RECURSIVE_LISTING_SKIP_DIRS.has(e.name)||e.name.startsWith(`.`))continue;let g=await enrichDirectoryRecursive(S?`${S}/${e.name}`:e.name,t-1,s);D.push(g)}return D.length>0&&(g.subfolders=D),g}const RECURSIVE_LISTING_SKIP_DIRS=new Set([`.git`,`.ok`,`node_modules`,`.venv`,`venv`,`env`,`__pycache__`,`vendor`,`dist`,`build`,`out`,`output`,`.next`,`.nuxt`,`.svelte-kit`,`.astro`,`.turbo`,`.cache`,`.parcel-cache`,`coverage`]);function applyNestedFolderRulesUpsert(e){if(!isAbsolute(e.projectDir))return{ok:!1,error:{code:`BAD_PROJECT_DIR`,message:`projectDir must be absolute`}};let t=[];for(let s of e.rules){let g=resolveTargetFolderFromMatch(s.new_match??s.match);if(!g.ok)return{ok:!1,error:{code:`MULTI_FOLDER_GLOB`,message:g.message,rule:s.match}};let S=g.folder?resolve(e.projectDir,g.folder):e.projectDir,w=resolve(e.projectDir);if(!S.startsWith(w+sep)&&S!==w)return{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved target folder escapes projectDir: ${S}`,rule:s.match}};let E=null,D=null;if(s.new_match!==void 0&&s.new_match!==s.match){let t=resolveTargetFolderFromMatch(s.match);if(!t.ok)return{ok:!1,error:{code:`MULTI_FOLDER_GLOB`,message:t.message,rule:s.match}};if(E=t.folder,D=t.folder?resolve(e.projectDir,t.folder):e.projectDir,!D.startsWith(w+sep)&&D!==w)return{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved source folder escapes projectDir: ${D}`,rule:s.match}}}t.push({targetFolder:g.folder,targetAbs:S,sourceFolder:E,sourceAbs:D,rule:s})}let s=[];for(let g of t)try{if(g.sourceAbs&&g.sourceAbs!==g.targetAbs){let t=join(g.sourceAbs,`.ok`,`frontmatter.yml`);existsSync(t)&&(unlinkSync(t),autoCleanOkDir(join(g.sourceAbs,`.ok`)),s.push({match:g.rule.match,path:relPathOf$1(e.projectDir,t),action:`deleted`}))}let t=join(g.targetAbs,`.ok`),S=join(t,`frontmatter.yml`),w=readExistingFrontmatter(S),E=Object.keys(g.rule.frontmatter).length===0?{}:mergePatch(w,g.rule.frontmatter);if(Object.keys(E).length===0){existsSync(S)&&(unlinkSync(S),autoCleanOkDir(t),s.push({match:g.rule.new_match??g.rule.match,path:relPathOf$1(e.projectDir,S),action:`deleted`}));continue}mkdirSync(t,{recursive:!0});let D=(0,import_dist$1.stringify)(E),O=`${S}.tmp.${process.pid}.${Date.now()}`;writeFileSync(O,D,`utf-8`),renameSync(O,S),s.push({match:g.rule.new_match??g.rule.match,path:relPathOf$1(e.projectDir,S),action:`written`})}catch(e){return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to write nested frontmatter for ${g.rule.match}: ${e.message}`,rule:g.rule.match},...s.length>0?{partiallyApplied:s}:{}}}return{ok:!0,applied:s}}function resolveTargetFolderFromMatch(e){let t=e.split(`/`).filter(e=>e.length>0),s=[],g=!1;for(let S of t){let t=/[*?[\]{}]/.test(S);if(g&&!t)return{ok:!1,message:`Glob "${e}" matches multiple folders (literal segment "${S}" appears after a glob). Split it into one rule per folder, e.g. set_folder_rule({ rules: [{ match: "specs/foo/${S}/**", ... }, ...] }).`};if(t){if(g=!0,S!==`**`&&S!==`*`)return{ok:!1,message:`Glob "${e}" uses an unsupported pattern segment "${S}". Only "*" and "**" are supported in nested folder rules.`};continue}s.push(S)}return{ok:!0,folder:s.join(`/`)}}function readExistingFrontmatter(e){if(!existsSync(e))return{};let t=(0,import_dist$1.parse)(readFileSync(e,`utf-8`));return typeof t!=`object`||!t||Array.isArray(t)?{}:{...t}}function autoCleanOkDir(e){if(!existsSync(e))return;let t;try{t=readdirSync(e)}catch{return}if(t.length===0)try{rmdirSync(e)}catch{}}function relPathOf$1(e,t){let s=resolve(e);return t.startsWith(s+sep)?t.slice(s.length+1).split(sep).join(`/`):t}const SUBSTITUTION_ALLOWLIST=[`date`,`user`],TOKEN_PATTERN=/\{\{([^{}\n]+?)\}\}/g;function validateSubstitution(e){let t=[];for(let s of e.matchAll(TOKEN_PATTERN)){let e=(s[1]??``).trim();isAllowedToken(e)||t.push({token:e,offset:s.index??0})}return t}function applySubstitution(e,t){return e.replace(TOKEN_PATTERN,(e,s)=>{let g=s.trim();return isAllowedToken(g)?t[g]:e})}function isAllowedToken(e){return SUBSTITUTION_ALLOWLIST.includes(e)}function todayIsoUtc(e=new Date){return`${e.getUTCFullYear().toString().padStart(4,`0`)}-${(e.getUTCMonth()+1).toString().padStart(2,`0`)}-${e.getUTCDate().toString().padStart(2,`0`)}`}const NAME_RE=/^[A-Za-z0-9_-]+$/;function applyTemplateWrite(e){let t=e.target??`project`,s=resolveRootForTarget(t,e.projectDir);if(!s.ok)return{ok:!1,error:s.error};let g=t===`user`?``:e.folder,S=validateInputs(s.rootDir,g,e.name);if(!S.ok)return{ok:!1,error:S.error};let w=validateTitle(e.frontmatter.title);if(!w.ok)return{ok:!1,error:w.error};let E=validateSubstitutionAllowlist(e.body);if(!E.ok)return{ok:!1,error:E.error};let{templatesDir:D,filePath:O}=templatePaths(s.rootDir,S.folderRel,e.name),k=serializeFrontmatter(e.frontmatter),j=k?`---\n${k}---\n${e.body}`:e.body;try{mkdirSync(D,{recursive:!0})}catch(e){return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to create template directory at ${displayPath(t,s.rootDir,D)}: ${e.message}`}}}let F=!existsSync(O),L=`${O}.tmp.${process.pid}.${Date.now()}`;try{writeFileSync(L,j,`utf-8`),renameSync(L,O)}catch(e){try{unlinkSync(L)}catch{}return{ok:!1,error:{code:`WRITE_ERROR`,message:`Failed to write template at ${displayPath(t,s.rootDir,O)}: ${e.message}`}}}let B=[];return(e.frontmatter.description===void 0||typeof e.frontmatter.description!=`string`||e.frontmatter.description.length===0)&&B.push("Template frontmatter.description is missing — `description` disambiguates between similarly-named templates in the menu. Recommended but not required."),{ok:!0,path:displayPath(t,s.rootDir,O),created:F,warnings:B}}function applyTemplateDelete(e){let t=e.target??`project`,s=resolveRootForTarget(t,e.projectDir);if(!s.ok)return{ok:!1,error:s.error};let g=t===`user`?``:e.folder,S=validateInputs(s.rootDir,g,e.name);if(!S.ok)return{ok:!1,error:S.error};let{templatesDir:w,okDir:E,filePath:D}=templatePaths(s.rootDir,S.folderRel,e.name),O=existsSync(D);if(O)try{unlinkSync(D)}catch(e){return{ok:!1,error:{code:`UNLINK_FAILED`,message:`Failed to delete template at ${displayPath(t,s.rootDir,D)}: ${e.message}`}}}let k=!1,j=!1;if(existsSync(w)&&isEmpty(w))try{rmdirSync(w),k=!0}catch{}if(existsSync(E)&&isEmpty(E))try{rmdirSync(E),j=!0}catch{}return{ok:!0,path:displayPath(t,s.rootDir,D),existed:O,cleanedEmpty:{templatesDir:k,okDir:j}}}function resolveRootForTarget(e,t){if(e===`user`){let e=getUserHome();return e?{ok:!0,rootDir:e}:{ok:!1,error:{code:`USER_HOME_UNAVAILABLE`,message:`User home directory could not be resolved. User templates require a writable home directory at ~/.ok/templates/.`}}}return{ok:!0,rootDir:t}}function displayPath(e,t,s){return e===`user`?s.startsWith(t+sep)?`~/${s.slice(t.length+1).split(sep).join(`/`)}`:s.split(sep).join(`/`):relPathOf(t,s)}function validateInputs(e,t,s){if(!isAbsolute(e))return{ok:!1,error:{code:`BAD_PROJECT_DIR`,message:`projectDir must be absolute`}};if(!NAME_RE.test(s))return{ok:!1,error:{code:`BAD_NAME`,message:`Template name must match /^[A-Za-z0-9_-]+$/ (got: ${JSON.stringify(s)}). Use letters, digits, underscores, or hyphens — no slashes, dots, or spaces.`}};let g=t.replace(/^\.\//,``).replace(/^\/+/,``).replace(/\/+$/,``).replace(/^\.$/,``);if(g.includes(`..`))return{ok:!1,error:{code:`PATH_TRAVERSAL`,message:`Folder path may not contain "..": ${JSON.stringify(t)}`}};let S=g?resolve(e,g):e,w=resolve(e);return!S.startsWith(w+sep)&&S!==w?{ok:!1,error:{code:`PATH_ESCAPE`,message:`Resolved folder path escapes projectDir: ${S}`}}:{ok:!0,folderRel:g}}function validateTitle(e){return typeof e!=`string`||e.length===0?{ok:!1,error:{code:`TEMPLATE_TITLE_REQUIRED`,message:"Template frontmatter.title is required. `title` is the menu surface — agents pick templates by name+title; a title-less template is effectively invisible. Set a non-empty `title` and retry."}}:{ok:!0}}function validateSubstitutionAllowlist(e){let t=validateSubstitution(e);return t.length===0?{ok:!0}:{ok:!1,error:{code:`TEMPLATE_UNKNOWN_VARIABLE`,message:`Template body contains unknown substitution token(s): ${t.map(e=>`\`{{${e.token}}}\` at offset ${e.offset}`).join(`, `)}. v1 allowlist: \`{{date}}\`, \`{{user}}\`. Remove or rename the offending tokens and retry.`}}}function templatePaths(e,t,s){let g=t?join(e,t,`.ok`):join(e,`.ok`),S=join(g,`templates`);return{okDir:g,templatesDir:S,filePath:join(S,`${s}.md`)}}function relPathOf(e,t){return normalize(t.startsWith(e+sep)?t.slice(e.length+1):t).split(sep).join(`/`)}function serializeFrontmatter(e){let t={};return e.title!==void 0&&(t.title=e.title),e.description!==void 0&&(t.description=e.description),Array.isArray(e.tags)&&e.tags.length>0&&(t.tags=e.tags),Object.keys(t).length===0?``:(0,import_dist$1.stringify)(t)}function isEmpty(e){try{return readdirSync(e).length===0}catch{return!1}}const log$6=()=>getLogger(`http`);let _apiErrorCounter=null;function apiErrorCounter(){return _apiErrorCounter||=getMeter().createCounter(`ok.api.error.count`,{description:`API error responses by problem type and handler`,unit:`1`}),_apiErrorCounter}function errorResponse(e,t,s,g,S={}){let w=S.instance??`urn:uuid:${randomUUID()}`;if(e.headersSent||e.writableEnded||e.destroyed){log$6().error({event:`api.error.double-write`,instance:w,type:s,status:t,handler:S.handler},`errorResponse called after headers already sent — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...S.handler?{handler:S.handler}:{}});return}let E={type:s,title:g,status:t,instance:w,detail:S.detail??void 0},D=ProblemDetailsSchema.safeParse(E);if(!D.success){log$6().error({event:`api.error.malformed-envelope`,issues:D.error.issues,body:E,handler:S.handler,originalStatus:t},`errorResponse produced an invalid ProblemDetails body — emitting fallback`);let s=500;apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...S.handler?{handler:S.handler}:{}}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:w}));return}let O=S.extensions?{...S.extensions,...E}:E;apiErrorCounter().add(1,{type:s,...S.handler?{handler:S.handler}:{}});let k=t>=500?`error`:`warn`;log$6()[k]({event:`api.error`,instance:w,type:s,status:t,handler:S.handler,detail:S.detail,err:S.cause},g);let j;try{j=JSON.stringify(O)}catch(s){log$6().error({event:`api.error.unserializable-body`,bodyKeys:Object.keys(O),handler:S.handler,originalStatus:t,instance:w,err:s},`errorResponse wireBody is not JSON-serializable — emitting hardcoded fallback`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...S.handler?{handler:S.handler}:{}}),e.writeHead(500,{"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(JSON.stringify({type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:w}));return}e.writeHead(t,{...S.extraHeaders,"Content-Type":`application/problem+json`,"X-Content-Type-Options":`nosniff`}),e.end(j)}function streamingProblemEvent(e,t,s,g={}){let S=g.instance??`urn:uuid:${randomUUID()}`,w={type:`error`,problem:{type:t,title:s,status:e,instance:S,detail:g.detail??void 0}},E=StreamingProblemEventSchema.safeParse(w);if(!E.success){log$6().error({event:`api.streaming.malformed-envelope`,issues:E.error.issues,body:w,handler:g.handler,originalStatus:e},`streamingProblemEvent produced an invalid StreamingProblemEvent — returning fallback`);let t=500;return apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...g.handler?{handler:g.handler}:{}}),{type:`error`,problem:{type:`urn:ok:error:internal-server-error`,title:`Internal server error.`,status:500,instance:S}}}apiErrorCounter().add(1,{type:t,...g.handler?{handler:g.handler}:{}});let D=e>=500?`error`:`warn`;return log$6()[D]({event:`api.streaming.error`,instance:S,type:t,status:e,handler:g.handler,detail:g.detail,err:g.cause},s),w}function createStreamingErrorWriter(e,t){return(s,g,S,w={})=>{if(e.writableEnded||e.destroyed){log$6().error({event:`api.streaming.error.suppressed`,type:g,status:s,handler:t,detail:w.detail,err:w.cause},`createStreamingErrorWriter called after writableEnded/destroyed — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...t?{handler:t}:{}});return}let E=streamingProblemEvent(s,g,S,{handler:t,...w});try{e.write(`${JSON.stringify(E)}\n`)}catch(e){log$6().error({event:`api.streaming.error.write-failed`,type:g,status:s,handler:t,err:w.cause,writeErr:e},`createStreamingErrorWriter: res.write threw — original error preserved in log`)}}}const log$5=()=>getLogger(`http`);function successResponse(e,t,s,g,S={}){if(e.headersSent||e.writableEnded||e.destroyed){log$5().error({event:`api.success.double-write`,status:t,handler:S.handler},`successResponse called after headers already sent — suppressed`),apiErrorCounter().add(1,{type:`urn:ok:error:internal-server-error`,...S.handler?{handler:S.handler}:{}});return}let w=s.safeParse(g);if(!w.success){log$5().error({event:`api.success.malformed-body`,issues:w.error.issues,bodyKeys:typeof g==`object`&&g?Object.keys(g):null,handler:S.handler,originalStatus:t},`successResponse produced an invalid body for the supplied schema — emitting fallback`),errorResponse(e,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:S.handler});return}let E;try{E=JSON.stringify(w.data)}catch(s){log$5().error({event:`api.success.unserializable-body`,bodyKeys:typeof w.data==`object`&&w.data!==null?Object.keys(w.data):null,handler:S.handler,originalStatus:t,err:s},`successResponse parsed body is not JSON-serializable — emitting fallback`),errorResponse(e,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:S.handler});return}e.writeHead(t,{...S.extraHeaders,"Content-Type":`application/json`,"X-Content-Type-Options":`nosniff`}),e.end(E)}const INSTALLED_AGENTS_SCHEMES=[`claude`,`codex`,`cursor`],INSTALLED_AGENTS_PROBE_TIMEOUT_MS=2e3,MACOS_APP_NAMES={claude:[`Claude`],codex:[`Codex`,`OpenAI Codex`],cursor:[`Cursor`]};function createInstalledAgentsProbe(e){let t=new Map,s=e.now??Date.now,g=e.ttlMs??6e4;async function S(S){let w=t.get(S);if(w?.status===`resolved`&&w.expiresAt>s())return w.installed;if(w?.status===`inflight`)return w.promise;let E=(async()=>{try{let w=await e.probe(S);return t.set(S,{status:`resolved`,installed:w,expiresAt:s()+g}),w}catch{return t.set(S,{status:`resolved`,installed:!1,expiresAt:s()+g}),!1}})();return t.set(S,{status:`inflight`,promise:E}),E}async function w(){let e=await Promise.all(INSTALLED_AGENTS_SCHEMES.map(async e=>[e,await S(e)]));return Object.fromEntries(e)}return{probeAll:w,probeWithCache:S}}async function handleInstalledAgents(e,t,s){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`installed-agents`,extraHeaders:{Allow:`GET`}});return}try{successResponse(t,200,InstalledAgentsSuccessSchema,await s(),{handler:`installed-agents`})}catch(e){console.error(`[installed-agents]`,e),errorResponse(t,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:`installed-agents`,cause:e})}}function createOsProbe(e,t=execFile){return s=>e===`darwin`?probeMacOs(s,t):e===`win32`?probeWindows(s,t):probeLinux(s,t)}function probeMacOs(e,t){let s=MACOS_APP_NAMES[e];function g(e){return new Promise(s=>{t(`osascript`,[`-e`,`id of app "${e}"`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},(e,t)=>{if(e){s(!1);return}s(t.trim().length>0)})})}return(async()=>{for(let e of s)if(await g(e))return!0;return!1})()}function probeWindows(e,t){return new Promise(s=>{t(`reg`,[`query`,`HKCR\\${e}`,`/ve`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},e=>{s(!e)})})}function probeLinux(e,t){return new Promise(s=>{t(`xdg-mime`,[`query`,`default`,`x-scheme-handler/${e}`],{timeout:INSTALLED_AGENTS_PROBE_TIMEOUT_MS,encoding:`utf-8`},(e,t)=>{if(e){s(!1);return}s(t.trim().length>0)})})}const MAX_BODY_BYTES=1048576,REQUEST_BODY_TIMEOUT_MS=3e4;function readRequestBody(e){return readBoundedJsonBody(e,{maxBytes:MAX_BODY_BYTES,timeoutMs:REQUEST_BODY_TIMEOUT_MS})}async function readBoundedJsonBody(e,t){let s=[],g=0,S=AbortSignal.timeout(t.timeoutMs),w=()=>e.destroy(new RequestBodyTimeoutError(t.timeoutMs));S.addEventListener(`abort`,w,{once:!0});try{for await(let S of e){if(g+=S.length,g>t.maxBytes)throw new PayloadTooLargeError(t.maxBytes);s.push(S)}return Buffer.concat(s)}finally{S.removeEventListener(`abort`,w)}}var PayloadTooLargeError=class extends Error{maxBytes;constructor(e){super(e===void 0?`Request body exceeded cap`:`Request body exceeded ${formatBytes(e)} cap`),this.name=`PayloadTooLargeError`,this.maxBytes=e}},RequestBodyTimeoutError=class extends Error{timeoutMs;constructor(e){super(e===void 0?`Request body read exceeded timeout`:`Request body read exceeded ${e}ms timeout`),this.name=`RequestBodyTimeoutError`,this.timeoutMs=e}};function formatBytes(e){return e>=1048576?`${(e/1048576).toFixed(0)} MB`:e>=1024?`${(e/1024).toFixed(0)} KB`:`${e} B`}function validateBody(e,t,s,g={}){let S=e.safeParse(t);if(S.success)return{ok:!0,value:S.data};let w=S.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `);return errorResponse(s,400,`urn:ok:error:invalid-request`,`Request body is invalid.`,{handler:g.handler,detail:w}),{ok:!1}}function withValidation(e,t,s={}){return async(g,S)=>{if(s.method!==void 0&&g.method!==s.method){errorResponse(S,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:s.handler,extraHeaders:{Allow:s.method}});return}if(s.preBodyGate!==void 0&&!s.preBodyGate(g,S)){!S.headersSent&&!S.writableEnded&&!S.destroyed&&errorResponse(S,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:s.handler,cause:Error(`preBodyGate returned false without writing a response`)});return}if(s.skipBodyParse){let w=validateBody(e,{},S,s);if(!w.ok)return;await t(g,S,w.value);return}let w;try{w=await readRequestBody(g)}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(S,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:s.handler,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(S,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:s.handler,cause:e});return}errorResponse(S,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:s.handler,cause:e});return}let E;try{E=w.length===0?{}:JSON.parse(w.toString(`utf8`))}catch(e){errorResponse(S,400,`urn:ok:error:invalid-request`,`Request body is not valid JSON.`,{handler:s.handler,cause:e});return}let D=validateBody(e,E,S,s);D.ok&&await t(g,S,D.value)}}function spawnDetached(e,t,s){return new Promise(g=>{let S=!1,w=e=>{S||(S=!0,g(e))},E=setTimeout(()=>w({ok:!1,reason:`timeout`}),s);try{let s=spawn(e,[...t],{detached:!0,stdio:`ignore`,shell:!1});s.once(`error`,e=>{clearTimeout(E);let t=e instanceof Error?e.message:String(e);w(/ENOENT|EACCES|EPERM/.test(t)?{ok:!1,reason:`not-installed`}:{ok:!1,reason:`spawn-error`})}),queueMicrotask(()=>{if(!S){try{s.unref()}catch{}clearTimeout(E),w({ok:!0})}})}catch(e){console.warn(`[spawn-detached] synchronous spawn throw:`,e),clearTimeout(E),w({ok:!1,reason:`spawn-error`})}})}const SPAWN_CURSOR_WHICH_TIMEOUT_MS=500,SPAWN_CURSOR_SPAWN_TIMEOUT_MS=2e3,SPAWN_CURSOR_MAX_BODY_BYTES=4*1024,SPAWN_CURSOR_BODY_READ_TIMEOUT_MS=5e3,HANDLER$1=`spawn-cursor`;function assertNeverSpawnReason(e){throw Error(`Unhandled spawn-cursor outcome.reason: ${String(e)}`)}async function handleSpawnCursor(e,t,s){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:HANDLER$1,extraHeaders:{Allow:`POST`}});return}let g;try{g=await readBoundedJsonBody(e,{maxBytes:SPAWN_CURSOR_MAX_BODY_BYTES,timeoutMs:SPAWN_CURSOR_BODY_READ_TIMEOUT_MS})}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(t,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:HANDLER$1,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(t,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:HANDLER$1,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:HANDLER$1,cause:e});return}let S;try{S=JSON.parse(g.toString(`utf-8`))}catch(e){errorResponse(t,400,`urn:ok:error:invalid-request`,`Malformed JSON body.`,{handler:HANDLER$1,cause:e});return}let w=typeof S.path==`string`?S.path:``;if(!w){errorResponse(t,400,`urn:ok:error:invalid-request`,"Missing or empty `path` field.",{handler:HANDLER$1});return}if(!isPathWithinDir(w,s.contentDir,s.platform)){errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER$1});return}let E=await(s.resolveCursorBinary??resolveCursorBinaryDefault)(SPAWN_CURSOR_WHICH_TIMEOUT_MS);if(!E){errorResponse(t,422,`urn:ok:error:cursor-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER$1});return}let D=resolveCursorSpawnInvocation(E,w,s.platform),O=await(s.spawnDetached??spawnDetached)(D.exec,D.args,SPAWN_CURSOR_SPAWN_TIMEOUT_MS);if(O.ok){successResponse(t,200,SpawnCursorSuccessSchema,{},{handler:HANDLER$1});return}switch(O.reason){case`not-installed`:errorResponse(t,422,`urn:ok:error:cursor-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER$1});return;case`timeout`:errorResponse(t,504,`urn:ok:error:cursor-spawn-timeout`,`Cursor spawn exceeded the deadline.`,{handler:HANDLER$1});return;case`spawn-error`:errorResponse(t,502,`urn:ok:error:cursor-spawn-failed`,`Cursor spawn failed.`,{handler:HANDLER$1});return;case`invalid-path`:errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER$1});return;default:return assertNeverSpawnReason(O.reason)}}const CURSOR_BUNDLE_PATHS_BY_PLATFORM={darwin:[()=>`/Applications/Cursor.app/Contents/Resources/app/bin/cursor`,e=>`${e}/Applications/Cursor.app/Contents/Resources/app/bin/cursor`],win32:[e=>`${e}\\AppData\\Local\\Programs\\cursor\\resources\\app\\bin\\cursor.cmd`,()=>`C:\\Program Files\\Cursor\\resources\\app\\bin\\cursor.cmd`]};async function resolveCursorBinaryDefault(e){let t=CURSOR_BUNDLE_PATHS_BY_PLATFORM[process.platform];if(t&&t.length>0){let e=homedir();for(let s of t){let t=s(e);try{return await access(t,constants.X_OK),t}catch(e){let s=e?.code;s!==`ENOENT`&&s!==`EACCES`&&s!==`EPERM`&&console.warn(`[spawn-cursor] unexpected fs.access error on bundle probe:`,s,t)}}}return new Promise(t=>{execFile(process.platform===`win32`?`where`:`which`,[`cursor`],{timeout:e,encoding:`utf-8`},(e,s)=>{if(e){t(null);return}let g=s.split(/\r?\n/)[0]?.trim();t(g&&g.length>0?g:null)})})}function resolveCursorSpawnInvocation(e,t,s){return s===`darwin`&&/\.app\/?$/.test(e)?{exec:`/usr/bin/open`,args:[`-a`,e.replace(/\/$/,``),t]}:{exec:e,args:[t]}}function isPathWithinDir(e,t,s){if(!e||typeof e!=`string`||e.includes(`\0`)||!t||typeof t!=`string`)return!1;if(s===`win32`){if(!/^([a-zA-Z]:[\\/]|\\\\)/.test(e)||!/^([a-zA-Z]:[\\/]|\\\\)/.test(t))return!1}else if(!e.startsWith(`/`)||!t.startsWith(`/`))return!1;let g=s===`win32`?win32:posix;try{let S=g.resolve(e),w=g.resolve(t);if(s===`win32`){let e=g.parse(S).root.toLowerCase(),t=g.parse(w).root.toLowerCase();if(!e||!t||e!==t)return!1}if(S===w)return!0;let E=g.relative(w,S);return E===``||E===`.`?!0:!(E===`..`||E.startsWith(`..${g.sep}`)||s===`win32`&&(/^[a-zA-Z]:[\\/]/.test(E)||E.startsWith(`\\\\`))||s!==`win32`&&E.startsWith(`/`))}catch(e){return console.warn(`[spawn-cursor] unexpected path-resolution error:`,e),!1}}const HANDLER=`handoff`,HANDOFF_MAX_BODY_BYTES=4*1024,HANDOFF_BODY_READ_TIMEOUT_MS=5e3,SPAWN_TIMEOUT_MS=2e3,WHICH_TIMEOUT_MS=500,QUIT_SETTLE_MS=3e3,APP_BUNDLE_SETTLE_MS=5e3,CURSOR_SETTLE_MS=1500,RECIPES={"claude-cowork":{type:`app-bundle`,appName:`Claude`,urlScheme:`claude:`,quitFirst:!1},"claude-code":{type:`app-bundle`,appName:`Claude`,urlScheme:`claude:`,quitFirst:!1},codex:{type:`app-bundle`,appName:`Codex`,urlScheme:`codex:`,quitFirst:!0},cursor:{type:`cli-binary`,binaryName:`cursor`,urlScheme:`cursor:`}},TARGET_VALUES=Object.keys(RECIPES),HandoffRequestSchema=object$1({target:_enum(TARGET_VALUES),url:string().min(1).max(4096),workspacePath:string().optional()}),HandoffSuccessSchema=object$1({}).loose();function defaultSleep(e){return new Promise(t=>setTimeout(t,e))}async function handleHandoffDispatch(e,t,s){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:HANDLER,extraHeaders:{Allow:`POST`}});return}if(s.platform!==`darwin`){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Handoff is currently macOS-only.`,{handler:HANDLER});return}let g;try{g=await readBoundedJsonBody(e,{maxBytes:HANDOFF_MAX_BODY_BYTES,timeoutMs:HANDOFF_BODY_READ_TIMEOUT_MS})}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(t,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:HANDLER,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(t,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:HANDLER,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:HANDLER,cause:e});return}let S;try{S=JSON.parse(g.toString(`utf-8`))}catch(e){errorResponse(t,400,`urn:ok:error:invalid-request`,`Malformed JSON body.`,{handler:HANDLER,cause:e});return}let w=HandoffRequestSchema.safeParse(S);if(!w.success){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid request body.`,{handler:HANDLER});return}let{target:E,url:D,workspacePath:O}=w.data,k=RECIPES[E];if(!D.startsWith(k.urlScheme)){errorResponse(t,400,`urn:ok:error:invalid-request`,`URL scheme must be ${k.urlScheme} for target ${E}.`,{handler:HANDLER});return}let j=s.sleep??defaultSleep,F=s.spawnDetached??spawnDetached;if(k.type===`app-bundle`){k.quitFirst&&(await F(`/usr/bin/osascript`,[`-e`,`tell application "${k.appName}" to quit`],SPAWN_TIMEOUT_MS).catch(()=>void 0),await j(QUIT_SETTLE_MS));let e=await F(`/usr/bin/open`,[`-a`,k.appName],SPAWN_TIMEOUT_MS);if(!e.ok){emitSpawnFailure(t,E,e.reason);return}await j(APP_BUNDLE_SETTLE_MS);let s=await F(`/usr/bin/open`,[D],SPAWN_TIMEOUT_MS);if(!s.ok){emitSpawnFailure(t,E,s.reason);return}successResponse(t,200,HandoffSuccessSchema,{},{handler:HANDLER});return}if(!O){errorResponse(t,400,`urn:ok:error:invalid-request`,`workspacePath is required for cursor handoff.`,{handler:HANDLER});return}if(!isPathWithinDir(O,s.contentDir,s.platform)){errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER});return}let L=await(s.resolveCursorBinary??resolveCursorBinaryDefault)(WHICH_TIMEOUT_MS);if(!L){errorResponse(t,422,`urn:ok:error:handoff-target-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER,extensions:{target:`cursor`}});return}let B=resolveCursorSpawnInvocation(L,O,s.platform),H=await F(B.exec,B.args,SPAWN_TIMEOUT_MS);if(!H.ok){emitSpawnFailure(t,E,H.reason);return}await j(CURSOR_SETTLE_MS);let q=await F(`/usr/bin/open`,[D],SPAWN_TIMEOUT_MS);if(!q.ok){emitSpawnFailure(t,E,q.reason);return}successResponse(t,200,HandoffSuccessSchema,{},{handler:HANDLER})}function emitSpawnFailure(e,t,s){switch(s){case`not-installed`:errorResponse(e,422,`urn:ok:error:handoff-target-not-installed`,`Required binary or application not found.`,{handler:HANDLER,extensions:{target:t}});return;case`timeout`:errorResponse(e,504,`urn:ok:error:handoff-spawn-timeout`,`Handoff spawn exceeded the deadline.`,{handler:HANDLER,extensions:{target:t}});return;case`spawn-error`:errorResponse(e,502,`urn:ok:error:handoff-spawn-failed`,`Handoff spawn failed.`,{handler:HANDLER,extensions:{target:t}});return;default:assertNeverReason(s)}}function assertNeverReason(e){throw Error(`Unhandled spawn reason: ${String(e)}`)}const FIXED_HUB_BASENAMES=[`INDEX`,`README`,`REPORT`,`SPEC`],MAX_CANDIDATES=3;function findHubCandidates(e,t){let s=[],g=new Set,S=t=>{!t||g.has(t)||t!==e&&(g.add(t),s.push(t))},w=buildLowerDocNameIndex(t),E=parentFolder(e);for(;;){for(let e of FIXED_HUB_BASENAMES)if(S(lookup$1(t,w,joinDocName(E,e))),s.length>=MAX_CANDIDATES)return s;let e=E===``?null:basename$1(E);if(e&&(S(lookup$1(t,w,joinDocName(E,e))),s.length>=MAX_CANDIDATES))return s;if(E===``)break;E=parentFolder(E)}return s}function lookup$1(e,t,s){return e.has(s)?s:t.get(s.toLowerCase())??null}function buildLowerDocNameIndex(e){let t=new Map;for(let s of e.keys()){let e=s.toLowerCase();t.has(e)||t.set(e,s)}return t}function parentFolder(e){let t=e.lastIndexOf(`/`);return t<0?``:e.slice(0,t)}function basename$1(e){let t=e.lastIndexOf(`/`);return t<0?e:e.slice(t+1)}function joinDocName(e,t){return e===``?t:`${e}/${t}`}function splitFrontmatterLines(e){return e?e.replace(/^---\r?\n/,``).replace(/\r?\n---(?:\r?\n)?$/,``).split(/\r?\n/):[]}function normalizeFrontmatterScalar(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).trim():t}function extractFrontmatterScalar(e,t){let s=`${t}:`;for(let t of splitFrontmatterLines(e))if(t.startsWith(s))return normalizeFrontmatterScalar(t.slice(s.length))||null;return null}function parseInlineAliases(e){let t=[],s=``,g=null;for(let S of e){if(g){s+=S,S===g&&(g=null);continue}if(S===`"`||S===`'`){g=S,s+=S;continue}if(S===`,`){let e=normalizeFrontmatterScalar(s);e&&t.push(e),s=``;continue}s+=S}let S=normalizeFrontmatterScalar(s);return S&&t.push(S),t}function dedupeExact(e){let t=[],s=new Set;for(let g of e)!g||s.has(g)||(s.add(g),t.push(g));return t}function extractPageAliases(e){let{frontmatter:t}=stripFrontmatter(e);if(!t)return[];let s=splitFrontmatterLines(t);for(let e=0;e<s.length;e+=1){let t=s[e]?.match(/^aliases:\s*(.*)$/);if(!t)continue;let g=t[1]?.trim()??``;if(g){if(g.startsWith(`[`)&&g.endsWith(`]`))return dedupeExact(parseInlineAliases(g.slice(1,-1)));let e=normalizeFrontmatterScalar(g);return e?[e]:[]}let S=[];for(let t=e+1;t<s.length;t+=1){let e=s[t];if(e?.trim()){if(/^\s*-\s+/.test(e)){let t=normalizeFrontmatterScalar(e.replace(/^\s*-\s+/,``));t&&S.push(t);continue}if(/^[^\s][^:]*:\s*/.test(e))break;break}}return dedupeExact(S)}return[]}function extractPageTitle(e,t){let{frontmatter:s,body:g}=stripFrontmatter(e),S=extractFrontmatterScalar(s,`title`);if(S)return S;let w=g.match(/^# (.+)$/m);return w?w[1].trim():t}function parseFrontmatterMetadata(e){return e?.trim()?{cluster:extractFrontmatterScalar(e,`cluster`)??void 0,category:extractFrontmatterScalar(e,`category`)??void 0,tags:extractFrontmatterArray(e,`tags`)}:{cluster:void 0,category:void 0,tags:void 0}}function extractFrontmatterArray(e,t){let s=`${t}:`,g=splitFrontmatterLines(e);for(let e=0;e<g.length;e+=1){let t=g[e];if(!t?.startsWith(s))continue;let S=t.slice(s.length).trim();if(S){if(S.startsWith(`[`)&&S.endsWith(`]`)){let e=parseInlineAliases(S.slice(1,-1));return e.length>0?e:void 0}let e=normalizeFrontmatterScalar(S);return e?[e]:void 0}let w=[];for(let t=e+1;t<g.length;t+=1){let e=g[t];if(e?.trim()){if(/^\s*-\s+/.test(e)){let t=normalizeFrontmatterScalar(e.replace(/^\s*-\s+/,``));t&&w.push(t);continue}if(/^[^\s][^:]*:\s*/.test(e))break;break}}return w.length>0?w:void 0}}function extractPageIdentity(e,t){let s=extractPageTitle(e,t),g=extractPageAliases(e),S=dedupeExact([s,...g]),w=[],E=new Set;for(let e of S){let t=toWikiLinkSlug(e);!t||E.has(t)||(E.add(t),w.push(t))}return{docName:t,title:s,aliases:g,matchLabels:S,normalizedMatchLabels:w}}const MAX_ZIP_BYTES=102400;function resolveBundledSkillDir(){let e=[`../assets/skills/open-knowledge`,`./assets/skills/open-knowledge`],t=[];for(let s of e){let e=fileURLToPath(new URL(s,import.meta.url));if(existsSync(e))return e;t.push(e)}throw Error(`Bundled skill asset directory not found. Tried: ${t.join(`, `)}. This usually means the CLI build did not copy packages/server/assets into dist/assets. Run \`cd packages/cli && bun run build\` before publishing.`)}async function*walkFiles(e,t=e){let s=await readdir(e,{withFileTypes:!0});for(let g of s){let s=join(e,g.name);g.isDirectory()?yield*walkFiles(s,t):g.isFile()&&(yield relative(t,s))}}function computeWrapperFolderName(e,t=basename){return t(e)||`open-knowledge`}function toPosixZipPath(e,t=sep){return t===`/`?e:e.split(t).join(`/`)}async function zipDirectory(e,t){let s=computeWrapperFolderName(e),g=new import_yazl.ZipFile;g.addEmptyDirectory(`${s}/`);let S=[];for await(let t of walkFiles(e))S.push(t);S.sort();for(let t of S){let S=join(e,t),w=`${s}/${toPosixZipPath(t)}`;g.addFile(S,w)}g.end(),await new Promise((e,s)=>{let S=createWriteStream(t);g.outputStream.pipe(S),S.on(`close`,()=>e()),S.on(`error`,s),g.outputStream.on(`error`,s)})}async function sha256OfFile(e){return new Promise((t,s)=>{let g=createHash(`sha256`),S=createReadStream(e);S.on(`data`,e=>g.update(e)),S.on(`end`,()=>t(g.digest(`hex`))),S.on(`error`,s)})}function extractMetadataVersion(e){let t=e.indexOf(`
|
|
822
822
|
---`,4);if(!e.startsWith(`---
|
|
823
823
|
`)||t<0)return;let s=e.slice(4,t),g=s.search(/^metadata:/m);if(g<0)return;let S=s.slice(g).split(`
|
|
824
|
-
`).slice(1);for(let e of S){if(/^[^\s]/.test(e))break;let t=e.match(/^\s+version:\s*["']?([^"'\s]+)["']?$/);if(t)return t[1]}}async function validateSkillZip(e,t){let s=statSync(e).size;if(s>MAX_ZIP_BYTES)throw Error(`Built ${e} is ${s} bytes, exceeds ${MAX_ZIP_BYTES}-byte ceiling`);let g=await sha256OfFile(e),S=await readFile$1(join(resolveBundledSkillDir(),`SKILL.md`),`utf-8`);if(!/^name:\s+open-knowledge$/m.test(S.slice(0,1e3)))throw Error("SKILL.md frontmatter `name:` does not match 'open-knowledge'. Check packages/server/assets/skills/open-knowledge/SKILL.md frontmatter.");let w=extractMetadataVersion(S);if(t!==void 0){if(!w)throw Error("SKILL.md metadata.version missing. Add it to packages/server/assets/skills/open-knowledge/SKILL.md or run `bash scripts/sync-skill-version.sh`.");if(w!==t)throw Error(`SKILL.md metadata.version (${w}) does not match expected version (${t}). Run \`bash scripts/sync-skill-version.sh\` after bumping package versions.`)}return{size:s,sha256:g,skillVersion:w}}async function buildSkillZip(e={}){let t=e.sourceDir??resolveBundledSkillDir(),s=e.outputPath??join(process.cwd(),`openknowledge.skill`);await zipDirectory(t,s);let{size:g,sha256:S,skillVersion:w}=await validateSkillZip(s,e.expectedSkillVersion);return{outputPath:s,size:g,sha256:S,skillVersion:w}}const SKILL_INSTALL_EVENTS_FILE_REL=[`.ok`,`skill-install-events.jsonl`];async function recordSkillInstallEvent(e,t){let s=t?.homedir??(()=>process.env.HOME??``),g=t?.warn??((e,t)=>{console.warn(t,e)}),S=s();if(!S){g({event:`skill-install-events.no-home`},`[skill-install-events] HOME not resolvable; telemetry skipped`);return}let w=join(S,...SKILL_INSTALL_EVENTS_FILE_REL),E=`${JSON.stringify(e)}\n`;try{await tracedMkdir(dirname(w),{recursive:!0})}catch(e){g({event:`skill-install-events.mkdir-failed`,error:String(e)},`[skill-install-events] mkdir failed; telemetry skipped`);return}try{await tracedWriteFile(w,E,{flag:`a`,encoding:`utf-8`})}catch(e){g({event:`skill-install-events.append-failed`,error:String(e)},`[skill-install-events] append failed; telemetry skipped`)}}const readFileAsync=promisify(readFile);function skillStateYamlPath(e){return join(e,...SKILL_STATE_REL)}const DEFAULT_LOGGER={warn:(e,t)=>console.warn(t,e)},TRACED_FS_ADAPTER={writeFile:(e,t,s)=>tracedWriteFile(e,t,s),rename:(e,t)=>tracedRename(e,t)};async function readSkillStateFile(e,t=DEFAULT_LOGGER){let s=skillStateYamlPath(e),g;try{g=await readFileAsync(s,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}let S=(0,import_dist$1.parseDocument)(g);if(S.errors.length>0)return t.warn({event:`skill-state.yaml-parse-error`,path:s,errors:S.errors.map(e=>e.message)},`skill-state.yml parse failed; treating as fresh install`),null;let w=SkillStateSchema.safeParse(S.toJSON());if(!w.success){let e=w.error.issues.find(e=>e.path.length===1&&e.path[0]===`schema`);return e?t.warn({event:`skill-state.invalid-schema-version`,path:s,issue:e.message},`skill-state.yml has unknown schema version; treating as fresh install`):t.warn({event:`skill-state.schema-violation`,path:s,issues:w.error.issues.map(e=>({path:e.path,message:e.message}))},`skill-state.yml failed schema validation; treating as fresh install`),null}return w.data}async function writeSkillStateFile(e,t){let s=SkillStateSchema.safeParse(t);if(!s.success)throw Error(`Refusing to write invalid skill-state: ${s.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `)}`);let g=skillStateYamlPath(e);await tracedMkdir(dirname(g),{recursive:!0});let S=(0,import_dist$1.parseDocument)(``);S.contents=S.createNode(s.data),await atomicWriteFile(g,S.toString(),{fs:TRACED_FS_ADAPTER})}async function readTargetVersion(e,t,s){let g=await readSkillStateFile(e,s);return g===null?null:g.targets[t]?.version??null}async function readTargetRecordedAt(e,t,s){let g=await readSkillStateFile(e,s);return g===null?null:g.targets[t]?.recordedAt??null}async function writeTargetVersion(e,t,s,g,S){if(!SKILL_STATE_VERSION_RE.test(s))throw Error(`Refusing to write invalid version string: ${s}`);let w=await readSkillStateFile(e,S)??emptySkillState(),E=new Date().toISOString(),D=w.targets[t],O=g===void 0?D?.surface??void 0:g,k=O===void 0?{version:s,recordedAt:E}:{version:s,recordedAt:E,surface:O};await writeSkillStateFile(e,{...w,targets:{...w.targets,[t]:k}})}async function readServerPackageVersion(){let e=await readFileAsync(fileURLToPath(new URL(`../package.json`,import.meta.url)),`utf-8`),t=JSON.parse(e);if(typeof t.version!=`string`||t.version.length===0)throw Error(`@inkeep/open-knowledge-server/package.json missing version field`);return t.version}async function readSkillInstallStateSnapshot(e,t){let[s,g]=await Promise.all([readServerPackageVersion(),readAllTargets(e,t)]);return{currentVersion:s,targets:g}}async function readAllTargets(e,t=DEFAULT_LOGGER){let s=null;try{s=await readSkillStateFile(e,t)}catch(g){t.warn({event:`skill-state.read-error`,path:skillStateYamlPath(e),error:String(g)},`non-ENOENT error reading skill-state.yml; treating as absent`),s=null}let g=SKILL_STATE_TARGETS.map(e=>{let t=s?.targets[e];return t?[e,{version:t.version,recordedAt:t.recordedAt}]:[e,null]});return Object.fromEntries(g)}const CENTRAL_SKILL_DIR_REL=[`.agents`,`skills`,`open-knowledge`],SKILLS_CLI_SPEC=`skills@~1.5.0`,DEFAULT_TIMEOUT_MS$3=6e4;function centralSkillDir(e){return join(e,...CENTRAL_SKILL_DIR_REL)}async function centralSkillExists(e){try{return(await stat$1(centralSkillDir(e))).isDirectory()}catch{return!1}}function runSpawn(e,t,s,g,S){return new Promise(w=>{let E;try{E=e(t,s,{env:g,stdio:[`ignore`,`pipe`,`pipe`]})}catch(e){w({kind:`spawn-error`,stderr:``,error:e});return}let D=``,O=!1,k=e=>{O||(O=!0,clearTimeout(j),w(e))};E.stderr?.on(`data`,e=>{D+=typeof e==`string`?e:e.toString(`utf-8`)}),E.on(`error`,e=>{k({kind:`spawn-error`,stderr:D,error:e})}),E.on(`exit`,e=>{k(e===0?{kind:`ok`,exitCode:e,stderr:D}:{kind:`nonzero`,exitCode:e,stderr:D})});let j=setTimeout(()=>{try{E.kill(`SIGTERM`)}catch{}k({kind:`timeout`,stderr:D})},S)})}async function installUserSkill(e={}){let t=e.home??homedir(),s=e.logger??{warn:(e,t)=>console.warn(t,e),info:(e,t)=>console.info(t,e)},g=e.spawn??spawn,S=e.timeoutMs??DEFAULT_TIMEOUT_MS$3,w=e.surface??`cli-npx-skills-add`,E=async(e,g,S)=>{await recordSkillInstallEvent({ts:new Date().toISOString(),surface:w,target:`cli-hosts`,outcome:e,...g===void 0?{}:{version:g},...S===void 0?{}:{reason:S}},{homedir:()=>t,warn:s.warn})},D;try{D=await readServerPackageVersion()}catch(e){return s.warn({event:`skill-install.failed`,reason:`version-read-failed`,error:String(e)},`Skill install aborted — could not read @inkeep/open-knowledge-server version.`),await E(`failed`,void 0,`version-read-failed`),`failed`}let O=await readTargetVersion(t,`cli-hosts`,s).catch(e=>(s.warn({event:`skill-install.gate.read-failed`,error:String(e)},`Could not read cli-hosts install-state; proceeding with fresh install.`),null));if(O!==null&&O===D){if(await centralSkillExists(t))return s.info?.({event:`skill-install.skip-current`,version:D},`Open Knowledge skill already installed at current version; skipping.`),await E(`skip-current`,D),`skip-current`;s.info?.({event:`skill-install.reinstall-missing`,version:D,path:centralSkillDir(t)},`Sidecar matches current version but skill files are missing; reinstalling.`)}let k;try{k=resolveBundledSkillDir()}catch(e){return s.warn({event:`skill-install.failed`,reason:`bundled-asset-missing`,error:String(e)},`Skill install aborted — bundled SKILL.md asset not found.`),await E(`failed`,D,`bundled-asset-missing`),`failed`}let j=await runSpawn(g,`npx`,[`-y`,SKILLS_CLI_SPEC,`add`,k,`--agent`,`*`,`-g`,`-y`,`--copy`],{...process.env,HOME:t},S);if(j.kind===`ok`){try{await writeTargetVersion(t,`cli-hosts`,D,w,s)}catch(e){return s.warn({event:`skill-install.failed`,reason:`sidecar-write-failed`,error:String(e)},`Skill install succeeded but sidecar write failed.`),await E(`failed`,D,`sidecar-write-failed`),`failed`}return s.info?.({event:`skill-install.installed`,version:D},`Open Knowledge skill installed to detected agent hosts.`),await E(`installed`,D),`installed`}return j.kind===`timeout`?(s.warn({event:`skill-install.failed`,reason:`timeout`,timeoutMs:S,stderr:j.stderr},`Skill install subprocess timed out. Run manually: npx ${SKILLS_CLI_SPEC} add ${k} --agent '*' -g -y --copy`),await E(`failed`,D,`timeout`),`failed`):j.kind===`spawn-error`?(s.warn({event:`skill-install.failed`,reason:`spawn-error`,error:String(j.error),stderr:j.stderr},`Skill install failed — \`npx\` unavailable or spawn errored. Run manually: npx ${SKILLS_CLI_SPEC} add ${k} --agent '*' -g -y --copy`),await E(`failed`,D,`spawn-error`),`failed`):(s.warn({event:`skill-install.failed`,reason:`nonzero-exit`,exitCode:j.exitCode,stderr:j.stderr},`Skill install subprocess exited non-zero. Run manually: npx ${SKILLS_CLI_SPEC} add ${k} --agent '*' -g -y --copy`),await E(`failed`,D,`nonzero-exit:${j.exitCode??`unknown`}`),`failed`)}const DOWNLOADS_DIR=`Downloads`,SKILL_FILENAME=`openknowledge.skill`;function defaultDownloadsPath(e){return join(e,DOWNLOADS_DIR,SKILL_FILENAME)}function invokeFileAssociation(e,t,s){let g={detached:!0,stdio:`ignore`};try{return t===`darwin`?(s(`open`,[e],g).unref(),{ok:!0}):t===`win32`?(s(`cmd`,[`/c`,`start`,`""`,e],g).unref(),{ok:!0}):t===`linux`?(s(`xdg-open`,[e],g).unref(),{ok:!0}):{ok:!1,reason:`unsupported-platform`,message:`Platform '${t}' has no file-association invocation wired.`}}catch(e){return{ok:!1,reason:`spawn-error`,message:e instanceof Error?e.message:String(e)}}}async function buildAndOpenSkill(e={}){let t=e.home??homedir(),s=resolve(e.out??defaultDownloadsPath(t)),g=e.platformName??platform(),S=e.spawnFn??spawn,w=e.logger,E=async(e,s,g)=>{await recordSkillInstallEvent({ts:new Date().toISOString(),surface:`server-build-and-open`,target:`claude-cowork`,outcome:e,...s===void 0?{}:{version:s},...g===void 0?{}:{reason:g}},{homedir:()=>t,warn:w?.warn})};if(!e.force){let e=null;try{e=await readServerPackageVersion()}catch(e){w?.warn?.({event:`skill-install.gate.version-read-failed`,error:String(e)},`Could not read @inkeep/open-knowledge-server version for gate check; rebuilding.`)}if(e!==null){let s=null,g=null;try{[s,g]=await Promise.all([readTargetVersion(t,`claude-cowork`,w),readTargetRecordedAt(t,`claude-cowork`,w)])}catch(e){w?.warn?.({event:`skill-install.gate.read-failed`,error:String(e)},`Could not read claude-cowork install-state; rebuilding.`)}if(s!==null&&s===e)return w?.info?.({event:`skill-install.skip-current`,target:`claude-cowork`,version:e},`Open Knowledge skill already delivered at current version; skipping rebuild.`),await E(`skip-current`,e),{status:`skip-current`,skillVersion:e,...g===null?{}:{recordedAt:g}}}}try{await tracedMkdir(dirname(s),{recursive:!0})}catch(e){let t=e instanceof Error?e.message:String(e);return await E(`failed`,void 0,`mkdir-failed:${t}`),{status:`failed`,buildError:`could not create output directory: ${t}`}}let D;try{D=await buildSkillZip({outputPath:s})}catch(e){let t=e instanceof Error?e.message:String(e);return await E(`failed`,void 0,`build-failed:${t}`),{status:`failed`,buildError:t}}let O={status:`built`,outputPath:D.outputPath,size:D.size,sha256:D.sha256,skillVersion:D.skillVersion};if(D.skillVersion)try{await writeTargetVersion(t,`claude-cowork`,D.skillVersion,`server-build-and-open`,w)}catch(e){w?.warn?.({event:`skill-install.state-write-failed`,target:`claude-cowork`,version:D.skillVersion,error:String(e)},`Skill bundle built but install-state write failed; gate will re-trigger build on next click.`)}if(e.noOpen)return await E(`built`,D.skillVersion),O;let k=invokeFileAssociation(D.outputPath,g,S);return k.ok?(await E(`installed`,D.skillVersion),{...O,status:`installed`}):(await E(`built`,D.skillVersion,`handoff-${k.reason}`),{...O,handoffError:{reason:k.reason,message:k.message}})}const MAX_BODY_BYTES=1048576,REQUEST_BODY_TIMEOUT_MS=3e4;async function readRequestBody(e){let t=[],s=0,g=AbortSignal.timeout(REQUEST_BODY_TIMEOUT_MS),S=()=>e.destroy(new RequestBodyTimeoutError);g.addEventListener(`abort`,S,{once:!0});try{for await(let g of e){if(s+=g.length,s>MAX_BODY_BYTES)throw new PayloadTooLargeError;t.push(g)}return Buffer.concat(t)}finally{g.removeEventListener(`abort`,S)}}var PayloadTooLargeError=class extends Error{constructor(){super(`Request body exceeded 1 MB cap`),this.name=`PayloadTooLargeError`}},RequestBodyTimeoutError=class extends Error{constructor(){super(`Request body read exceeded ${REQUEST_BODY_TIMEOUT_MS}ms timeout`),this.name=`RequestBodyTimeoutError`}};function validateBody(e,t,s,g={}){let S=e.safeParse(t);if(S.success)return{ok:!0,value:S.data};let w=S.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `);return errorResponse(s,400,`urn:ok:error:invalid-request`,`Request body is invalid.`,{handler:g.handler,detail:w}),{ok:!1}}function withValidation(e,t,s={}){return async(g,S)=>{if(s.method!==void 0&&g.method!==s.method){errorResponse(S,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:s.handler,extraHeaders:{Allow:s.method}});return}if(s.preBodyGate!==void 0&&!s.preBodyGate(g,S)){!S.headersSent&&!S.writableEnded&&!S.destroyed&&errorResponse(S,500,`urn:ok:error:internal-server-error`,`Internal server error.`,{handler:s.handler,cause:Error(`preBodyGate returned false without writing a response`)});return}if(s.skipBodyParse){let w=validateBody(e,{},S,s);if(!w.ok)return;await t(g,S,w.value);return}let w;try{w=await readRequestBody(g)}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(S,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:s.handler,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(S,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:s.handler,cause:e});return}errorResponse(S,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:s.handler,cause:e});return}let E;try{E=w.length===0?{}:JSON.parse(w.toString(`utf8`))}catch(e){errorResponse(S,400,`urn:ok:error:invalid-request`,`Request body is not valid JSON.`,{handler:s.handler,cause:e});return}let D=validateBody(e,E,S,s);D.ok&&await t(g,S,D.value)}}const SPAWN_CURSOR_WHICH_TIMEOUT_MS=500,SPAWN_CURSOR_SPAWN_TIMEOUT_MS=2e3,SPAWN_CURSOR_MAX_BODY_BYTES=4*1024,SPAWN_CURSOR_BODY_READ_TIMEOUT_MS=5e3,HANDLER=`spawn-cursor`;function assertNeverSpawnReason(e){throw Error(`Unhandled spawn-cursor outcome.reason: ${String(e)}`)}async function handleSpawnCursor(e,t,s){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:HANDLER,extraHeaders:{Allow:`POST`}});return}let g;try{g=await readBoundedJsonBody(e)}catch(e){if(e instanceof PayloadTooLargeError){errorResponse(t,413,`urn:ok:error:payload-too-large`,`Payload too large.`,{handler:HANDLER,cause:e});return}if(e instanceof RequestBodyTimeoutError){errorResponse(t,408,`urn:ok:error:request-timeout`,`Request body read timed out.`,{handler:HANDLER,cause:e});return}errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read request body.`,{handler:HANDLER,cause:e});return}let S;try{S=JSON.parse(g.toString(`utf-8`))}catch(e){errorResponse(t,400,`urn:ok:error:invalid-request`,`Malformed JSON body.`,{handler:HANDLER,cause:e});return}let w=typeof S.path==`string`?S.path:``;if(!w){errorResponse(t,400,`urn:ok:error:invalid-request`,"Missing or empty `path` field.",{handler:HANDLER});return}if(!isPathWithinDir(w,s.contentDir,s.platform)){errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER});return}let E=await(s.resolveCursorBinary??resolveCursorBinaryDefault)(SPAWN_CURSOR_WHICH_TIMEOUT_MS);if(!E){errorResponse(t,422,`urn:ok:error:cursor-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER});return}let D=resolveCursorSpawnInvocation(E,w,s.platform),O=await(s.spawnDetached??spawnDetachedReal)(D.exec,D.args,SPAWN_CURSOR_SPAWN_TIMEOUT_MS);if(O.ok){successResponse(t,200,SpawnCursorSuccessSchema,{},{handler:HANDLER});return}switch(O.reason){case`not-installed`:errorResponse(t,422,`urn:ok:error:cursor-not-installed`,`Cursor CLI not found on this machine.`,{handler:HANDLER});return;case`timeout`:errorResponse(t,504,`urn:ok:error:cursor-spawn-timeout`,`Cursor spawn exceeded the deadline.`,{handler:HANDLER});return;case`spawn-error`:errorResponse(t,502,`urn:ok:error:cursor-spawn-failed`,`Cursor spawn failed.`,{handler:HANDLER});return;case`invalid-path`:errorResponse(t,403,`urn:ok:error:path-escape`,`Path escapes the content directory.`,{handler:HANDLER});return;default:return assertNeverSpawnReason(O.reason)}}const CURSOR_BUNDLE_PATHS_BY_PLATFORM={darwin:[()=>`/Applications/Cursor.app/Contents/Resources/app/bin/cursor`,e=>`${e}/Applications/Cursor.app/Contents/Resources/app/bin/cursor`],win32:[e=>`${e}\\AppData\\Local\\Programs\\cursor\\resources\\app\\bin\\cursor.cmd`,()=>`C:\\Program Files\\Cursor\\resources\\app\\bin\\cursor.cmd`]};async function resolveCursorBinaryDefault(e){let t=CURSOR_BUNDLE_PATHS_BY_PLATFORM[process.platform];if(t&&t.length>0){let e=homedir();for(let s of t){let t=s(e);try{return await access(t,constants.X_OK),t}catch(e){let s=e?.code;s!==`ENOENT`&&s!==`EACCES`&&s!==`EPERM`&&console.warn(`[spawn-cursor] unexpected fs.access error on bundle probe:`,s,t)}}}return new Promise(t=>{execFile(process.platform===`win32`?`where`:`which`,[`cursor`],{timeout:e,encoding:`utf-8`},(e,s)=>{if(e){t(null);return}let g=s.split(/\r?\n/)[0]?.trim();t(g&&g.length>0?g:null)})})}function spawnDetachedReal(e,t,s){return new Promise(g=>{let S=!1,w=e=>{S||(S=!0,g(e))},E=setTimeout(()=>w({ok:!1,reason:`timeout`}),s);try{let s=spawn(e,[...t],{detached:!0,stdio:`ignore`,shell:!1});s.once(`error`,e=>{clearTimeout(E);let t=e instanceof Error?e.message:String(e);w(/ENOENT|EACCES|EPERM/.test(t)?{ok:!1,reason:`not-installed`}:{ok:!1,reason:`spawn-error`})}),queueMicrotask(()=>{if(!S){try{s.unref()}catch{}clearTimeout(E),w({ok:!0})}})}catch(e){console.warn(`[spawn-cursor] synchronous spawn throw:`,e),clearTimeout(E),w({ok:!1,reason:`spawn-error`})}})}function resolveCursorSpawnInvocation(e,t,s){return s===`darwin`&&/\.app\/?$/.test(e)?{exec:`/usr/bin/open`,args:[`-a`,e.replace(/\/$/,``),t]}:{exec:e,args:[t]}}async function readBoundedJsonBody(e){let t=[],s=0,g=AbortSignal.timeout(SPAWN_CURSOR_BODY_READ_TIMEOUT_MS),S=()=>e.destroy(new RequestBodyTimeoutError);g.addEventListener(`abort`,S,{once:!0});try{for await(let g of e){if(s+=g.length,s>SPAWN_CURSOR_MAX_BODY_BYTES)throw new PayloadTooLargeError;t.push(g)}return Buffer.concat(t)}finally{g.removeEventListener(`abort`,S)}}function isPathWithinDir(e,t,s){if(!e||typeof e!=`string`||e.includes(`\0`)||!t||typeof t!=`string`)return!1;if(s===`win32`){if(!/^([a-zA-Z]:[\\/]|\\\\)/.test(e)||!/^([a-zA-Z]:[\\/]|\\\\)/.test(t))return!1}else if(!e.startsWith(`/`)||!t.startsWith(`/`))return!1;let g=s===`win32`?win32:posix;try{let S=g.resolve(e),w=g.resolve(t);if(s===`win32`){let e=g.parse(S).root.toLowerCase(),t=g.parse(w).root.toLowerCase();if(!e||!t||e!==t)return!1}if(S===w)return!0;let E=g.relative(w,S);return E===``||E===`.`?!0:!(E===`..`||E.startsWith(`..${g.sep}`)||s===`win32`&&(/^[a-zA-Z]:[\\/]/.test(E)||E.startsWith(`\\\\`))||s!==`win32`&&E.startsWith(`/`))}catch(e){return console.warn(`[spawn-cursor] unexpected path-resolution error:`,e),!1}}var UiLockCollisionError=class extends ProcessLockCollisionError{constructor(e,t){super(e,t,`ui`),this.name=`UiLockCollisionError`}};function acquireUiLock(e,t){try{return acquireProcessLock({lockName:`ui`,lockDir:e,metadata:t}).lockPath}catch(e){throw e instanceof ProcessLockCollisionError&&e.lockName===`ui`?new UiLockCollisionError(e.existing,e.lockPath):e}}function updateUiLockPort(e,t){updateProcessLockPort({lockName:`ui`,lockDir:e,port:t})}function readUiLock(e){return readProcessLock({lockName:`ui`,lockDir:e})}function releaseUiLock(e){releaseProcessLock({lockName:`ui`,lockDir:e})}var UploadWriteError=class extends Error{reason;constructor(e,t){super(`UploadWriteError: ${e}`,{cause:t}),this.name=`UploadWriteError`,this.reason=e}};function uploadStatusFor(e){switch(e){case`urn:ok:error:malformed-upload`:return 400;case`urn:ok:error:storage-full`:return 507;case`urn:ok:error:storage-readonly`:return 500;case`urn:ok:error:storage-error`:return 500;case`urn:ok:error:collision-exhaustion`:return 500;default:return assertNeverProblemType(e)}}function classifyUploadErrno(e){return e.code===`ENOSPC`||e.code===`EDQUOT`?`urn:ok:error:storage-full`:e.code===`EROFS`||e.code===`EACCES`||e.code===`EPERM`?`urn:ok:error:storage-readonly`:`urn:ok:error:storage-error`}function uploadTitleFor(e){switch(e){case`urn:ok:error:malformed-upload`:return`Upload payload is malformed.`;case`urn:ok:error:storage-full`:return`Storage is full.`;case`urn:ok:error:storage-readonly`:return`Storage is read-only.`;case`urn:ok:error:storage-error`:return`Failed to write upload.`;case`urn:ok:error:collision-exhaustion`:return`Filename collision retries exhausted.`;default:return assertNeverProblemType(e)}}const log$4=getLogger(`upload-streaming`);var HashingPassThrough=class extends Transform{hash=createHash(`sha256`);bytes=0;digested=!1;_transform(e,t,s){this.hash.update(e),this.bytes+=e.length,s(null,e)}digest(){if(this.digested)throw Error(`HashingPassThrough.digest() already called`);return this.digested=!0,this.hash.digest(`hex`)}byteLength(){return this.bytes}};function tmpUploadDir(e){return resolve(getLocalDir(e),`tmp`)}function mintTempUploadPath(e){let t=tmpUploadDir(e);return tracedMkdirSync(t,{recursive:!0}),resolve(t,`upload-${randomUUID()}`)}function linkTempToFinalWithCollisionRetry(e,t,s){let g=extname(s),S=s.slice(0,s.length-g.length),w=[s,...Array.from({length:99},(e,t)=>`${S}-${t+1}${g}`)];for(let s of w){let g=resolve(t,s);try{tracedLinkSync(e,g);try{tracedUnlinkSync(e)}catch{}return s}catch(t){let s=t.code;if(s===`EEXIST`)continue;try{tracedUnlinkSync(e)}catch{}throw s===`ENOSPC`||s===`EDQUOT`?new UploadWriteError(`urn:ok:error:storage-full`,t):s===`EROFS`||s===`EACCES`||s===`EPERM`?new UploadWriteError(`urn:ok:error:storage-readonly`,t):new UploadWriteError(`urn:ok:error:storage-error`,t)}}try{tracedUnlinkSync(e)}catch{}throw new UploadWriteError(`urn:ok:error:collision-exhaustion`)}function cleanupOrphanUploadTempfiles(e,{ageMs:t=1440*60*1e3}={}){let s=tmpUploadDir(e),g={scanned:0,deleted:0,errors:0};if(!existsSync(s))return g;let S;try{S=readdirSync(s)}catch(e){return log$4.warn({err:e,dir:s},`[upload-tempfile-sweep] readdir failed`),g.errors++,g}let w=Date.now()-t;for(let e of S){if(!e.startsWith(`upload-`))continue;g.scanned++;let t=resolve(s,e);try{if(statSync(t).mtimeMs>=w)continue;tracedUnlinkSync(t),g.deleted++}catch(e){log$4.warn({err:e,path:t},`[upload-tempfile-sweep] entry failed`),g.errors++}}return(g.deleted>0||g.errors>0)&&log$4.info({dir:s,scanned:g.scanned,deleted:g.deleted,errors:g.errors},`[upload-tempfile-sweep] swept ${g.deleted}/${g.scanned} (errors: ${g.errors})`),g}function matchFence$2(e){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(!t)return null;let s=t[1],g=s[0];return g!=="`"&&g!==`~`?null:{char:g,length:s.length}}function isFenceClose$2(e,t){return RegExp(`^\\s{0,3}\\${t.char}{${t.length},}\\s*$`).test(e)}function leadingMarkdownPrefixLength$2(e){let t=/^\s{0,3}(?:#{1,6}\s+|>\s+|(?:[-+*]|\d+[.)])\s+)/.exec(e);return t?t[0].length:0}function readInlineCode$2(e,t){let s=0;for(;e[t+s]==="`";)s++;if(s===0)return null;let g=t+s,S=g;for(;S<e.length;){if(e[S]!=="`"){S++;continue}let t=0;for(;e[S+t]==="`";)t++;if(t===s)return{nextIndex:S+s};S+=t}return{nextIndex:g}}function readWikiLink$2(e,t){let s=/^\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/.exec(e.slice(t));if(!s)return null;let g=s[1]?.trim(),S=s[2]?.trim()||null,w=s[3]?.trim()||null;return g?{target:g,alias:w,anchor:S,nextIndex:t+s[0].length}:null}function readMarkdownLink$2(e,t){let s=/^\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)((?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?)\)/.exec(e.slice(t));if(!s)return null;let g=s[2]??``;return{text:s[1]??``,hrefRaw:g,href:g.startsWith(`<`)&&g.endsWith(`>`)?g.slice(1,-1):g,titleSuffix:s[3]??``,nextIndex:t+s[0].length}}function readImageRef(e,t){let s=/^!\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)((?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?)\)/.exec(e.slice(t));if(!s)return null;let g=s[2]??``;return{alt:s[1]??``,hrefRaw:g,href:g.startsWith(`<`)&&g.endsWith(`>`)?g.slice(1,-1):g,titleSuffix:s[3]??``,nextIndex:t+s[0].length}}function splitLines(e){let t=e.split(/(\r\n|\r|\n)/),s=[];for(let e=0;e<t.length;e+=2)s.push({line:t[e]??``,ending:t[e+1]??``});return s}function rewriteWikiLinksInLine(e,t,s){let g=``,S=0,w=0,E=leadingMarkdownPrefixLength$2(e);for(E>0&&(g+=e.slice(0,E),w=E);w<e.length;){if(e[w]===`\\`&&w+1<e.length){g+=e.slice(w,w+2),w+=2;continue}if(e[w]==="`"){let t=readInlineCode$2(e,w);if(t){g+=e.slice(w,t.nextIndex),w=t.nextIndex;continue}}if(e[w]===`[`&&e[w+1]===`[`){let E=readWikiLink$2(e,w);if(E){E.target===t?(g+=`[[${s}${E.anchor?`#${E.anchor}`:``}${E.alias?`|${E.alias}`:``}]]`,S++):g+=e.slice(w,E.nextIndex),w=E.nextIndex;continue}}g+=e[w],w++}return{markdown:g,rewrites:S}}function recomputeRelativeImageHref(e,t,s){let g=e.indexOf(`#`),S=g>=0?e.slice(g):``,w=g>=0?e.slice(0,g):e,E=w.indexOf(`?`),D=E>=0?w.slice(E):``,O=E>=0?w.slice(0,E):w;if(O.startsWith(`/`)||O.startsWith(`//`)||/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(O))return null;let k=posix.dirname(t),j=posix.dirname(s);if(k===j)return null;let F=k===`.`?`/`:`/${k}/`,L=posix.resolve(F,O).slice(1),B=posix.relative(j===`.`?``:j,L);return B||=posix.basename(L),O.startsWith(`./`)&&!B.startsWith(`./`)&&!B.startsWith(`../`)&&(B=`./${B}`),`${B}${D}${S}`}function recomputeRelativeMarkdownHref(e,t,s){let g=e.indexOf(`#`),S=g>=0?e.slice(g):``,w=g>=0?e.slice(0,g):e,E=w.indexOf(`?`),D=E>=0?w.slice(E):``,O=E>=0?w.slice(0,E):w,k=posix.dirname(t),j=posix.relative(k===`.`?``:k,s);return j||=posix.basename(s),O.endsWith(`.mdx`)?j+=`.mdx`:O.endsWith(`.md`)&&(j+=`.md`),O.startsWith(`./`)&&!j.startsWith(`./`)&&!j.startsWith(`../`)&&(j=`./${j}`),`${j}${D}${S}`}function rewriteMarkdownLinksInLine(e,t,s,g){let S=``,w=0,E=0,D=leadingMarkdownPrefixLength$2(e);for(D>0&&(S+=e.slice(0,D),E=D);E<e.length;){if(e[E]===`\\`&&E+1<e.length){S+=e.slice(E,E+2),E+=2;continue}if(e[E]==="`"){let t=readInlineCode$2(e,E);if(t){S+=e.slice(E,t.nextIndex),E=t.nextIndex;continue}}if(e[E]===`[`&&e[E+1]===`[`){let t=readWikiLink$2(e,E);if(t){S+=e.slice(E,t.nextIndex),E=t.nextIndex;continue}}if(e[E]===`!`&&e[E+1]===`[`){let D=readImageRef(e,E);if(D){let O=t===s&&s!==g?recomputeRelativeImageHref(D.href,s,g):null;if(O!==null){let e=D.hrefRaw.startsWith(`<`)&&D.hrefRaw.endsWith(`>`)?`<${O}>`:O;S+=``,w++}else S+=e.slice(E,D.nextIndex);E=D.nextIndex;continue}}if(e[E]===`[`){let D=readMarkdownLink$2(e,E);if(D){if(resolveInternalHref(D.href,t)?.docName===s){let e=recomputeRelativeMarkdownHref(D.href,t,g),s=D.hrefRaw.startsWith(`<`)&&D.hrefRaw.endsWith(`>`)?`<${e}>`:e;S+=`[${D.text}](${s}${D.titleSuffix})`,w++}else S+=e.slice(E,D.nextIndex);E=D.nextIndex;continue}}S+=e[E],E++}return{markdown:S,rewrites:w}}function rewriteWikiLinksForDocumentRename(e,t,s){let g=null,S=0;return{markdown:splitLines(e).map(({line:e,ending:w})=>{if(g)return isFenceClose$2(e,g)&&(g=null),`${e}${w}`;let E=matchFence$2(e);if(E)return g=E,`${e}${w}`;let D=rewriteWikiLinksInLine(e,t,s);return S+=D.rewrites,`${D.markdown}${w}`}).join(``),rewrites:S}}function rewriteMarkdownLinksForDocumentRename(e,t,s,g){let S=null,w=0;return{markdown:splitLines(e).map(({line:e,ending:E})=>{if(S)return isFenceClose$2(e,S)&&(S=null),`${e}${E}`;let D=matchFence$2(e);if(D)return S=D,`${e}${E}`;let O=rewriteMarkdownLinksInLine(e,t,s,g);return w+=O.rewrites,`${O.markdown}${E}`}).join(``),rewrites:w}}function rewriteOutboundMarkdownLinksInLine(e,t,s){let g=``,S=0,w=0,E=leadingMarkdownPrefixLength$2(e);for(E>0&&(g+=e.slice(0,E),w=E);w<e.length;){if(e[w]===`\\`&&w+1<e.length){g+=e.slice(w,w+2),w+=2;continue}if(e[w]==="`"){let t=readInlineCode$2(e,w);if(t){g+=e.slice(w,t.nextIndex),w=t.nextIndex;continue}}if(e[w]===`[`&&e[w+1]===`[`){let t=readWikiLink$2(e,w);if(t){g+=e.slice(w,t.nextIndex),w=t.nextIndex;continue}}if(e[w]===`!`&&e[w+1]===`[`){let t=readImageRef(e,w);if(t){g+=e.slice(w,t.nextIndex),w=t.nextIndex;continue}}if(e[w]===`[`){let E=readMarkdownLink$2(e,w);if(E){let D=resolveInternalHref(E.href,t);if(D!==null){let t=recomputeRelativeMarkdownHref(E.href,s,D.docName);if(t!==E.href){let e=E.hrefRaw.startsWith(`<`)&&E.hrefRaw.endsWith(`>`)?`<${t}>`:t;g+=`[${E.text}](${e}${E.titleSuffix})`,S++}else g+=e.slice(w,E.nextIndex)}else g+=e.slice(w,E.nextIndex);w=E.nextIndex;continue}}g+=e[w],w++}return{markdown:g,rewrites:S}}function rewriteOutboundMarkdownLinksForSourceMove(e,t,s){if(posix.dirname(t)===posix.dirname(s))return{markdown:e,rewrites:0};let g=null,S=0;return{markdown:splitLines(e).map(({line:e,ending:w})=>{if(g)return isFenceClose$2(e,g)&&(g=null),`${e}${w}`;let E=matchFence$2(e);if(E)return g=E,`${e}${w}`;let D=rewriteOutboundMarkdownLinksInLine(e,t,s);return S+=D.rewrites,`${D.markdown}${w}`}).join(``),rewrites:S}}var ManagedRenameCollisionError=class extends Error{colliding;constructor(e){super(`Managed rename collision: ${e.map(e=>`'${e.existing}' and '${e.incoming}' both target '${e.to}'`).join(`; `)}`),this.name=`ManagedRenameCollisionError`,this.colliding=e}},ManagedRenameSourceNotFoundError=class extends Error{kind;constructor(e){super(`${e} does not exist`),this.name=`ManagedRenameSourceNotFoundError`,this.kind=e}},ManagedRenameDestinationExistsError=class extends Error{constructor(){super(`Destination already exists`),this.name=`ManagedRenameDestinationExistsError`}},ManagedRenameSourceTypeMismatchError=class extends Error{kind;constructor(e){super(`Source path is not a ${e}`),this.name=`ManagedRenameSourceTypeMismatchError`,this.kind=e}},SymlinkEscapeError=class extends Error{constructor(e){super(`symlink-escape: ${e}`),this.name=`SymlinkEscapeError`}},BacklinkIndexRequiredError=class extends Error{constructor(){super(`Managed rename requires backlink index support`),this.name=`BacklinkIndexRequiredError`}},ManagedRenameSnapshotMissingError=class extends Error{docName;constructor(e){super(`Cannot snapshot missing document: ${e}`),this.name=`ManagedRenameSnapshotMissingError`,this.docName=e}},ManagedRenameMissingDocumentError=class extends Error{docName;constructor(e){super(`Cannot rename missing document: ${e}`),this.name=`ManagedRenameMissingDocumentError`,this.docName=e}};function buildRenameMap(e){let t=new Map,s=[];for(let{from:g,to:S}of e){for(let[e,w]of t)e!==g&&w===S&&s.push({existing:e,incoming:g,to:S});t.set(g,S)}if(s.length>0)throw new ManagedRenameCollisionError(s);return t}function rewriteSupportedLinksForRename(e,t,s,g){let{frontmatter:S,body:w}=stripFrontmatter(e),E=rewriteWikiLinksForDocumentRename(w,s,g),D=rewriteMarkdownLinksForDocumentRename(E.markdown,t,s,g);return{markdown:prependFrontmatter(S,D.markdown),rewrites:E.rewrites+D.rewrites}}function applyRenameMap(e,t,s){let g=e,S=0,w,E=[];for(let[e,g]of s)e!==g&&(e===t?w=g:E.push([e,g]));if(w!==void 0){let e=rewriteSupportedLinksForRename(g,t,t,w);g=e.markdown,S+=e.rewrites;let{frontmatter:s,body:E}=stripFrontmatter(g),D=rewriteOutboundMarkdownLinksForSourceMove(E,t,w);g=prependFrontmatter(s,D.markdown),S+=D.rewrites}let D=w??t,O=new Map;for(let[e,t]of E){let s=`__OK_RENAME_${randomUUID().replaceAll(`-`,``)}__`,w=rewriteSupportedLinksForRename(g,D,e,s);w.rewrites>0&&(g=w.markdown,S+=w.rewrites,O.set(s,t))}for(let[e,t]of O)g=rewriteSupportedLinksForRename(g,D,e,t).markdown;return{markdown:g,rewrites:S}}const WIKI_LINK_RE$1=/\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/y,MD_LINK_RE$1=/\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y;function createEmptyState$1(){return{backward:new Map,forward:new Map,externalForward:new Map,externalBackward:new Map}}function mergeLinkMeta(e,t){return e?{anchor:e.anchor??t.anchor,snippet:e.snippet??t.snippet}:t}function getRepresentativeAnchor(e){if(!e)return null;for(let[,t]of[...e.entries()].sort(([e],[t])=>e.localeCompare(t)))if(t.anchor)return t.anchor;return null}function externalNodeId(e){return`external:${e}`}function externalUrlFromNodeId(e){return e.startsWith(`external:`)?e.slice(9):null}function normalizeSnippet$1(e){return e.replace(/\s+/g,` `).trim()}function snippetAround$1(e,t,s){if(!normalizeSnippet$1(e))return null;let g=Math.max(e.lastIndexOf(`.`,t-1),e.lastIndexOf(`?`,t-1),e.lastIndexOf(`!`,t-1),e.lastIndexOf(`
|
|
824
|
+
`).slice(1);for(let e of S){if(/^[^\s]/.test(e))break;let t=e.match(/^\s+version:\s*["']?([^"'\s]+)["']?$/);if(t)return t[1]}}async function validateSkillZip(e,t){let s=statSync(e).size;if(s>MAX_ZIP_BYTES)throw Error(`Built ${e} is ${s} bytes, exceeds ${MAX_ZIP_BYTES}-byte ceiling`);let g=await sha256OfFile(e),S=await readFile$1(join(resolveBundledSkillDir(),`SKILL.md`),`utf-8`);if(!/^name:\s+open-knowledge$/m.test(S.slice(0,1e3)))throw Error("SKILL.md frontmatter `name:` does not match 'open-knowledge'. Check packages/server/assets/skills/open-knowledge/SKILL.md frontmatter.");let w=extractMetadataVersion(S);if(t!==void 0){if(!w)throw Error("SKILL.md metadata.version missing. Add it to packages/server/assets/skills/open-knowledge/SKILL.md or run `bash scripts/sync-skill-version.sh`.");if(w!==t)throw Error(`SKILL.md metadata.version (${w}) does not match expected version (${t}). Run \`bash scripts/sync-skill-version.sh\` after bumping package versions.`)}return{size:s,sha256:g,skillVersion:w}}async function buildSkillZip(e={}){let t=e.sourceDir??resolveBundledSkillDir(),s=e.outputPath??join(process.cwd(),`openknowledge.skill`);await zipDirectory(t,s);let{size:g,sha256:S,skillVersion:w}=await validateSkillZip(s,e.expectedSkillVersion);return{outputPath:s,size:g,sha256:S,skillVersion:w}}const SKILL_INSTALL_EVENTS_FILE_REL=[`.ok`,`skill-install-events.jsonl`];async function recordSkillInstallEvent(e,t){let s=t?.homedir??(()=>process.env.HOME??``),g=t?.warn??((e,t)=>{console.warn(t,e)}),S=s();if(!S){g({event:`skill-install-events.no-home`},`[skill-install-events] HOME not resolvable; telemetry skipped`);return}let w=join(S,...SKILL_INSTALL_EVENTS_FILE_REL),E=`${JSON.stringify(e)}\n`;try{await tracedMkdir(dirname(w),{recursive:!0})}catch(e){g({event:`skill-install-events.mkdir-failed`,error:String(e)},`[skill-install-events] mkdir failed; telemetry skipped`);return}try{await tracedWriteFile(w,E,{flag:`a`,encoding:`utf-8`})}catch(e){g({event:`skill-install-events.append-failed`,error:String(e)},`[skill-install-events] append failed; telemetry skipped`)}}const readFileAsync=promisify(readFile);function skillStateYamlPath(e){return join(e,...SKILL_STATE_REL)}const DEFAULT_LOGGER={warn:(e,t)=>console.warn(t,e)},TRACED_FS_ADAPTER={writeFile:(e,t,s)=>tracedWriteFile(e,t,s),rename:(e,t)=>tracedRename(e,t)};async function readSkillStateFile(e,t=DEFAULT_LOGGER){let s=skillStateYamlPath(e),g;try{g=await readFileAsync(s,`utf-8`)}catch(e){if(e.code===`ENOENT`)return null;throw e}let S=(0,import_dist$1.parseDocument)(g);if(S.errors.length>0)return t.warn({event:`skill-state.yaml-parse-error`,path:s,errors:S.errors.map(e=>e.message)},`skill-state.yml parse failed; treating as fresh install`),null;let w=SkillStateSchema.safeParse(S.toJSON());if(!w.success){let e=w.error.issues.find(e=>e.path.length===1&&e.path[0]===`schema`);return e?t.warn({event:`skill-state.invalid-schema-version`,path:s,issue:e.message},`skill-state.yml has unknown schema version; treating as fresh install`):t.warn({event:`skill-state.schema-violation`,path:s,issues:w.error.issues.map(e=>({path:e.path,message:e.message}))},`skill-state.yml failed schema validation; treating as fresh install`),null}return w.data}async function writeSkillStateFile(e,t){let s=SkillStateSchema.safeParse(t);if(!s.success)throw Error(`Refusing to write invalid skill-state: ${s.error.issues.map(e=>`${e.path.join(`.`)}: ${e.message}`).join(`; `)}`);let g=skillStateYamlPath(e);await tracedMkdir(dirname(g),{recursive:!0});let S=(0,import_dist$1.parseDocument)(``);S.contents=S.createNode(s.data),await atomicWriteFile(g,S.toString(),{fs:TRACED_FS_ADAPTER})}async function readTargetVersion(e,t,s){let g=await readSkillStateFile(e,s);return g===null?null:g.targets[t]?.version??null}async function readTargetRecordedAt(e,t,s){let g=await readSkillStateFile(e,s);return g===null?null:g.targets[t]?.recordedAt??null}async function writeTargetVersion(e,t,s,g,S){if(!SKILL_STATE_VERSION_RE.test(s))throw Error(`Refusing to write invalid version string: ${s}`);let w=await readSkillStateFile(e,S)??emptySkillState(),E=new Date().toISOString(),D=w.targets[t],O=g===void 0?D?.surface??void 0:g,k=O===void 0?{version:s,recordedAt:E}:{version:s,recordedAt:E,surface:O};await writeSkillStateFile(e,{...w,targets:{...w.targets,[t]:k}})}async function readServerPackageVersion(){let e=await readFileAsync(fileURLToPath(new URL(`../package.json`,import.meta.url)),`utf-8`),t=JSON.parse(e);if(typeof t.version!=`string`||t.version.length===0)throw Error(`@inkeep/open-knowledge-server/package.json missing version field`);return t.version}async function readSkillInstallStateSnapshot(e,t){let[s,g]=await Promise.all([readServerPackageVersion(),readAllTargets(e,t)]);return{currentVersion:s,targets:g}}async function readAllTargets(e,t=DEFAULT_LOGGER){let s=null;try{s=await readSkillStateFile(e,t)}catch(g){t.warn({event:`skill-state.read-error`,path:skillStateYamlPath(e),error:String(g)},`non-ENOENT error reading skill-state.yml; treating as absent`),s=null}let g=SKILL_STATE_TARGETS.map(e=>{let t=s?.targets[e];return t?[e,{version:t.version,recordedAt:t.recordedAt}]:[e,null]});return Object.fromEntries(g)}const CENTRAL_SKILL_DIR_REL=[`.agents`,`skills`,`open-knowledge`],SKILLS_CLI_SPEC=`skills@~1.5.0`,DEFAULT_TIMEOUT_MS$3=6e4;function centralSkillDir(e){return join(e,...CENTRAL_SKILL_DIR_REL)}async function centralSkillExists(e){try{return(await stat$1(centralSkillDir(e))).isDirectory()}catch{return!1}}function runSpawn(e,t,s,g,S){return new Promise(w=>{let E;try{E=e(t,s,{env:g,stdio:[`ignore`,`pipe`,`pipe`]})}catch(e){w({kind:`spawn-error`,stderr:``,error:e});return}let D=``,O=!1,k=e=>{O||(O=!0,clearTimeout(j),w(e))};E.stderr?.on(`data`,e=>{D+=typeof e==`string`?e:e.toString(`utf-8`)}),E.on(`error`,e=>{k({kind:`spawn-error`,stderr:D,error:e})}),E.on(`exit`,e=>{k(e===0?{kind:`ok`,exitCode:e,stderr:D}:{kind:`nonzero`,exitCode:e,stderr:D})});let j=setTimeout(()=>{try{E.kill(`SIGTERM`)}catch{}k({kind:`timeout`,stderr:D})},S)})}async function installUserSkill(e={}){let t=e.home??homedir(),s=e.logger??{warn:(e,t)=>console.warn(t,e),info:(e,t)=>console.info(t,e)},g=e.spawn??spawn,S=e.timeoutMs??DEFAULT_TIMEOUT_MS$3,w=e.surface??`cli-npx-skills-add`,E=async(e,g,S)=>{await recordSkillInstallEvent({ts:new Date().toISOString(),surface:w,target:`cli-hosts`,outcome:e,...g===void 0?{}:{version:g},...S===void 0?{}:{reason:S}},{homedir:()=>t,warn:s.warn})},D;try{D=await readServerPackageVersion()}catch(e){return s.warn({event:`skill-install.failed`,reason:`version-read-failed`,error:String(e)},`Skill install aborted — could not read @inkeep/open-knowledge-server version.`),await E(`failed`,void 0,`version-read-failed`),`failed`}let O=await readTargetVersion(t,`cli-hosts`,s).catch(e=>(s.warn({event:`skill-install.gate.read-failed`,error:String(e)},`Could not read cli-hosts install-state; proceeding with fresh install.`),null));if(O!==null&&O===D){if(await centralSkillExists(t))return s.info?.({event:`skill-install.skip-current`,version:D},`Open Knowledge skill already installed at current version; skipping.`),await E(`skip-current`,D),`skip-current`;s.info?.({event:`skill-install.reinstall-missing`,version:D,path:centralSkillDir(t)},`Sidecar matches current version but skill files are missing; reinstalling.`)}let k;try{k=resolveBundledSkillDir()}catch(e){return s.warn({event:`skill-install.failed`,reason:`bundled-asset-missing`,error:String(e)},`Skill install aborted — bundled SKILL.md asset not found.`),await E(`failed`,D,`bundled-asset-missing`),`failed`}let j=await runSpawn(g,`npx`,[`-y`,SKILLS_CLI_SPEC,`add`,k,`--agent`,`*`,`-g`,`-y`,`--copy`],{...process.env,HOME:t},S);if(j.kind===`ok`){try{await writeTargetVersion(t,`cli-hosts`,D,w,s)}catch(e){return s.warn({event:`skill-install.failed`,reason:`sidecar-write-failed`,error:String(e)},`Skill install succeeded but sidecar write failed.`),await E(`failed`,D,`sidecar-write-failed`),`failed`}return s.info?.({event:`skill-install.installed`,version:D},`Open Knowledge skill installed to detected agent hosts.`),await E(`installed`,D),`installed`}return j.kind===`timeout`?(s.warn({event:`skill-install.failed`,reason:`timeout`,timeoutMs:S,stderr:j.stderr},`Skill install subprocess timed out. Run manually: npx ${SKILLS_CLI_SPEC} add ${k} --agent '*' -g -y --copy`),await E(`failed`,D,`timeout`),`failed`):j.kind===`spawn-error`?(s.warn({event:`skill-install.failed`,reason:`spawn-error`,error:String(j.error),stderr:j.stderr},`Skill install failed — \`npx\` unavailable or spawn errored. Run manually: npx ${SKILLS_CLI_SPEC} add ${k} --agent '*' -g -y --copy`),await E(`failed`,D,`spawn-error`),`failed`):(s.warn({event:`skill-install.failed`,reason:`nonzero-exit`,exitCode:j.exitCode,stderr:j.stderr},`Skill install subprocess exited non-zero. Run manually: npx ${SKILLS_CLI_SPEC} add ${k} --agent '*' -g -y --copy`),await E(`failed`,D,`nonzero-exit:${j.exitCode??`unknown`}`),`failed`)}const DOWNLOADS_DIR=`Downloads`,SKILL_FILENAME=`openknowledge.skill`;function defaultDownloadsPath(e){return join(e,DOWNLOADS_DIR,SKILL_FILENAME)}function invokeFileAssociation(e,t,s){let g={detached:!0,stdio:`ignore`};try{return t===`darwin`?(s(`open`,[e],g).unref(),{ok:!0}):t===`win32`?(s(`cmd`,[`/c`,`start`,`""`,e],g).unref(),{ok:!0}):t===`linux`?(s(`xdg-open`,[e],g).unref(),{ok:!0}):{ok:!1,reason:`unsupported-platform`,message:`Platform '${t}' has no file-association invocation wired.`}}catch(e){return{ok:!1,reason:`spawn-error`,message:e instanceof Error?e.message:String(e)}}}async function buildAndOpenSkill(e={}){let t=e.home??homedir(),s=resolve(e.out??defaultDownloadsPath(t)),g=e.platformName??platform(),S=e.spawnFn??spawn,w=e.logger,E=async(e,s,g)=>{await recordSkillInstallEvent({ts:new Date().toISOString(),surface:`server-build-and-open`,target:`claude-cowork`,outcome:e,...s===void 0?{}:{version:s},...g===void 0?{}:{reason:g}},{homedir:()=>t,warn:w?.warn})};if(!e.force){let e=null;try{e=await readServerPackageVersion()}catch(e){w?.warn?.({event:`skill-install.gate.version-read-failed`,error:String(e)},`Could not read @inkeep/open-knowledge-server version for gate check; rebuilding.`)}if(e!==null){let s=null,g=null;try{[s,g]=await Promise.all([readTargetVersion(t,`claude-cowork`,w),readTargetRecordedAt(t,`claude-cowork`,w)])}catch(e){w?.warn?.({event:`skill-install.gate.read-failed`,error:String(e)},`Could not read claude-cowork install-state; rebuilding.`)}if(s!==null&&s===e)return w?.info?.({event:`skill-install.skip-current`,target:`claude-cowork`,version:e},`Open Knowledge skill already delivered at current version; skipping rebuild.`),await E(`skip-current`,e),{status:`skip-current`,skillVersion:e,...g===null?{}:{recordedAt:g}}}}try{await tracedMkdir(dirname(s),{recursive:!0})}catch(e){let t=e instanceof Error?e.message:String(e);return await E(`failed`,void 0,`mkdir-failed:${t}`),{status:`failed`,buildError:`could not create output directory: ${t}`}}let D;try{D=await buildSkillZip({outputPath:s})}catch(e){let t=e instanceof Error?e.message:String(e);return await E(`failed`,void 0,`build-failed:${t}`),{status:`failed`,buildError:t}}let O={status:`built`,outputPath:D.outputPath,size:D.size,sha256:D.sha256,skillVersion:D.skillVersion};if(D.skillVersion)try{await writeTargetVersion(t,`claude-cowork`,D.skillVersion,`server-build-and-open`,w)}catch(e){w?.warn?.({event:`skill-install.state-write-failed`,target:`claude-cowork`,version:D.skillVersion,error:String(e)},`Skill bundle built but install-state write failed; gate will re-trigger build on next click.`)}if(e.noOpen)return await E(`built`,D.skillVersion),O;let k=invokeFileAssociation(D.outputPath,g,S);return k.ok?(await E(`installed`,D.skillVersion),{...O,status:`installed`}):(await E(`built`,D.skillVersion,`handoff-${k.reason}`),{...O,handoffError:{reason:k.reason,message:k.message}})}var UiLockCollisionError=class extends ProcessLockCollisionError{constructor(e,t){super(e,t,`ui`),this.name=`UiLockCollisionError`}};function acquireUiLock(e,t){try{return acquireProcessLock({lockName:`ui`,lockDir:e,metadata:t}).lockPath}catch(e){throw e instanceof ProcessLockCollisionError&&e.lockName===`ui`?new UiLockCollisionError(e.existing,e.lockPath):e}}function updateUiLockPort(e,t){updateProcessLockPort({lockName:`ui`,lockDir:e,port:t})}function readUiLock(e){return readProcessLock({lockName:`ui`,lockDir:e})}function releaseUiLock(e){releaseProcessLock({lockName:`ui`,lockDir:e})}var UploadWriteError=class extends Error{reason;constructor(e,t){super(`UploadWriteError: ${e}`,{cause:t}),this.name=`UploadWriteError`,this.reason=e}};function uploadStatusFor(e){switch(e){case`urn:ok:error:malformed-upload`:return 400;case`urn:ok:error:storage-full`:return 507;case`urn:ok:error:storage-readonly`:return 500;case`urn:ok:error:storage-error`:return 500;case`urn:ok:error:collision-exhaustion`:return 500;default:return assertNeverProblemType(e)}}function classifyUploadErrno(e){return e.code===`ENOSPC`||e.code===`EDQUOT`?`urn:ok:error:storage-full`:e.code===`EROFS`||e.code===`EACCES`||e.code===`EPERM`?`urn:ok:error:storage-readonly`:`urn:ok:error:storage-error`}function uploadTitleFor(e){switch(e){case`urn:ok:error:malformed-upload`:return`Upload payload is malformed.`;case`urn:ok:error:storage-full`:return`Storage is full.`;case`urn:ok:error:storage-readonly`:return`Storage is read-only.`;case`urn:ok:error:storage-error`:return`Failed to write upload.`;case`urn:ok:error:collision-exhaustion`:return`Filename collision retries exhausted.`;default:return assertNeverProblemType(e)}}const log$4=getLogger(`upload-streaming`);var HashingPassThrough=class extends Transform{hash=createHash(`sha256`);bytes=0;digested=!1;_transform(e,t,s){this.hash.update(e),this.bytes+=e.length,s(null,e)}digest(){if(this.digested)throw Error(`HashingPassThrough.digest() already called`);return this.digested=!0,this.hash.digest(`hex`)}byteLength(){return this.bytes}};function tmpUploadDir(e){return resolve(getLocalDir(e),`tmp`)}function mintTempUploadPath(e){let t=tmpUploadDir(e);return tracedMkdirSync(t,{recursive:!0}),resolve(t,`upload-${randomUUID()}`)}function linkTempToFinalWithCollisionRetry(e,t,s){let g=extname(s),S=s.slice(0,s.length-g.length),w=[s,...Array.from({length:99},(e,t)=>`${S}-${t+1}${g}`)];for(let s of w){let g=resolve(t,s);try{tracedLinkSync(e,g);try{tracedUnlinkSync(e)}catch{}return s}catch(t){let s=t.code;if(s===`EEXIST`)continue;try{tracedUnlinkSync(e)}catch{}throw s===`ENOSPC`||s===`EDQUOT`?new UploadWriteError(`urn:ok:error:storage-full`,t):s===`EROFS`||s===`EACCES`||s===`EPERM`?new UploadWriteError(`urn:ok:error:storage-readonly`,t):new UploadWriteError(`urn:ok:error:storage-error`,t)}}try{tracedUnlinkSync(e)}catch{}throw new UploadWriteError(`urn:ok:error:collision-exhaustion`)}function cleanupOrphanUploadTempfiles(e,{ageMs:t=1440*60*1e3}={}){let s=tmpUploadDir(e),g={scanned:0,deleted:0,errors:0};if(!existsSync(s))return g;let S;try{S=readdirSync(s)}catch(e){return log$4.warn({err:e,dir:s},`[upload-tempfile-sweep] readdir failed`),g.errors++,g}let w=Date.now()-t;for(let e of S){if(!e.startsWith(`upload-`))continue;g.scanned++;let t=resolve(s,e);try{if(statSync(t).mtimeMs>=w)continue;tracedUnlinkSync(t),g.deleted++}catch(e){log$4.warn({err:e,path:t},`[upload-tempfile-sweep] entry failed`),g.errors++}}return(g.deleted>0||g.errors>0)&&log$4.info({dir:s,scanned:g.scanned,deleted:g.deleted,errors:g.errors},`[upload-tempfile-sweep] swept ${g.deleted}/${g.scanned} (errors: ${g.errors})`),g}function matchFence$2(e){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(!t)return null;let s=t[1],g=s[0];return g!=="`"&&g!==`~`?null:{char:g,length:s.length}}function isFenceClose$2(e,t){return RegExp(`^\\s{0,3}\\${t.char}{${t.length},}\\s*$`).test(e)}function leadingMarkdownPrefixLength$2(e){let t=/^\s{0,3}(?:#{1,6}\s+|>\s+|(?:[-+*]|\d+[.)])\s+)/.exec(e);return t?t[0].length:0}function readInlineCode$2(e,t){let s=0;for(;e[t+s]==="`";)s++;if(s===0)return null;let g=t+s,S=g;for(;S<e.length;){if(e[S]!=="`"){S++;continue}let t=0;for(;e[S+t]==="`";)t++;if(t===s)return{nextIndex:S+s};S+=t}return{nextIndex:g}}function readWikiLink$2(e,t){let s=/^\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/.exec(e.slice(t));if(!s)return null;let g=s[1]?.trim(),S=s[2]?.trim()||null,w=s[3]?.trim()||null;return g?{target:g,alias:w,anchor:S,nextIndex:t+s[0].length}:null}function readMarkdownLink$2(e,t){let s=/^\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)((?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?)\)/.exec(e.slice(t));if(!s)return null;let g=s[2]??``;return{text:s[1]??``,hrefRaw:g,href:g.startsWith(`<`)&&g.endsWith(`>`)?g.slice(1,-1):g,titleSuffix:s[3]??``,nextIndex:t+s[0].length}}function readImageRef(e,t){let s=/^!\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)((?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?)\)/.exec(e.slice(t));if(!s)return null;let g=s[2]??``;return{alt:s[1]??``,hrefRaw:g,href:g.startsWith(`<`)&&g.endsWith(`>`)?g.slice(1,-1):g,titleSuffix:s[3]??``,nextIndex:t+s[0].length}}function splitLines(e){let t=e.split(/(\r\n|\r|\n)/),s=[];for(let e=0;e<t.length;e+=2)s.push({line:t[e]??``,ending:t[e+1]??``});return s}function rewriteWikiLinksInLine(e,t,s){let g=``,S=0,w=0,E=leadingMarkdownPrefixLength$2(e);for(E>0&&(g+=e.slice(0,E),w=E);w<e.length;){if(e[w]===`\\`&&w+1<e.length){g+=e.slice(w,w+2),w+=2;continue}if(e[w]==="`"){let t=readInlineCode$2(e,w);if(t){g+=e.slice(w,t.nextIndex),w=t.nextIndex;continue}}if(e[w]===`[`&&e[w+1]===`[`){let E=readWikiLink$2(e,w);if(E){E.target===t?(g+=`[[${s}${E.anchor?`#${E.anchor}`:``}${E.alias?`|${E.alias}`:``}]]`,S++):g+=e.slice(w,E.nextIndex),w=E.nextIndex;continue}}g+=e[w],w++}return{markdown:g,rewrites:S}}function recomputeRelativeImageHref(e,t,s){let g=e.indexOf(`#`),S=g>=0?e.slice(g):``,w=g>=0?e.slice(0,g):e,E=w.indexOf(`?`),D=E>=0?w.slice(E):``,O=E>=0?w.slice(0,E):w;if(O.startsWith(`/`)||O.startsWith(`//`)||/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(O))return null;let k=posix.dirname(t),j=posix.dirname(s);if(k===j)return null;let F=k===`.`?`/`:`/${k}/`,L=posix.resolve(F,O).slice(1),B=posix.relative(j===`.`?``:j,L);return B||=posix.basename(L),O.startsWith(`./`)&&!B.startsWith(`./`)&&!B.startsWith(`../`)&&(B=`./${B}`),`${B}${D}${S}`}function recomputeRelativeMarkdownHref(e,t,s){let g=e.indexOf(`#`),S=g>=0?e.slice(g):``,w=g>=0?e.slice(0,g):e,E=w.indexOf(`?`),D=E>=0?w.slice(E):``,O=E>=0?w.slice(0,E):w,k=posix.dirname(t),j=posix.relative(k===`.`?``:k,s);return j||=posix.basename(s),O.endsWith(`.mdx`)?j+=`.mdx`:O.endsWith(`.md`)&&(j+=`.md`),O.startsWith(`./`)&&!j.startsWith(`./`)&&!j.startsWith(`../`)&&(j=`./${j}`),`${j}${D}${S}`}function rewriteMarkdownLinksInLine(e,t,s,g){let S=``,w=0,E=0,D=leadingMarkdownPrefixLength$2(e);for(D>0&&(S+=e.slice(0,D),E=D);E<e.length;){if(e[E]===`\\`&&E+1<e.length){S+=e.slice(E,E+2),E+=2;continue}if(e[E]==="`"){let t=readInlineCode$2(e,E);if(t){S+=e.slice(E,t.nextIndex),E=t.nextIndex;continue}}if(e[E]===`[`&&e[E+1]===`[`){let t=readWikiLink$2(e,E);if(t){S+=e.slice(E,t.nextIndex),E=t.nextIndex;continue}}if(e[E]===`!`&&e[E+1]===`[`){let D=readImageRef(e,E);if(D){let O=t===s&&s!==g?recomputeRelativeImageHref(D.href,s,g):null;if(O!==null){let e=D.hrefRaw.startsWith(`<`)&&D.hrefRaw.endsWith(`>`)?`<${O}>`:O;S+=``,w++}else S+=e.slice(E,D.nextIndex);E=D.nextIndex;continue}}if(e[E]===`[`){let D=readMarkdownLink$2(e,E);if(D){if(resolveInternalHref(D.href,t)?.docName===s){let e=recomputeRelativeMarkdownHref(D.href,t,g),s=D.hrefRaw.startsWith(`<`)&&D.hrefRaw.endsWith(`>`)?`<${e}>`:e;S+=`[${D.text}](${s}${D.titleSuffix})`,w++}else S+=e.slice(E,D.nextIndex);E=D.nextIndex;continue}}S+=e[E],E++}return{markdown:S,rewrites:w}}function rewriteWikiLinksForDocumentRename(e,t,s){let g=null,S=0;return{markdown:splitLines(e).map(({line:e,ending:w})=>{if(g)return isFenceClose$2(e,g)&&(g=null),`${e}${w}`;let E=matchFence$2(e);if(E)return g=E,`${e}${w}`;let D=rewriteWikiLinksInLine(e,t,s);return S+=D.rewrites,`${D.markdown}${w}`}).join(``),rewrites:S}}function rewriteMarkdownLinksForDocumentRename(e,t,s,g){let S=null,w=0;return{markdown:splitLines(e).map(({line:e,ending:E})=>{if(S)return isFenceClose$2(e,S)&&(S=null),`${e}${E}`;let D=matchFence$2(e);if(D)return S=D,`${e}${E}`;let O=rewriteMarkdownLinksInLine(e,t,s,g);return w+=O.rewrites,`${O.markdown}${E}`}).join(``),rewrites:w}}function rewriteOutboundMarkdownLinksInLine(e,t,s){let g=``,S=0,w=0,E=leadingMarkdownPrefixLength$2(e);for(E>0&&(g+=e.slice(0,E),w=E);w<e.length;){if(e[w]===`\\`&&w+1<e.length){g+=e.slice(w,w+2),w+=2;continue}if(e[w]==="`"){let t=readInlineCode$2(e,w);if(t){g+=e.slice(w,t.nextIndex),w=t.nextIndex;continue}}if(e[w]===`[`&&e[w+1]===`[`){let t=readWikiLink$2(e,w);if(t){g+=e.slice(w,t.nextIndex),w=t.nextIndex;continue}}if(e[w]===`!`&&e[w+1]===`[`){let t=readImageRef(e,w);if(t){g+=e.slice(w,t.nextIndex),w=t.nextIndex;continue}}if(e[w]===`[`){let E=readMarkdownLink$2(e,w);if(E){let D=resolveInternalHref(E.href,t);if(D!==null){let t=recomputeRelativeMarkdownHref(E.href,s,D.docName);if(t!==E.href){let e=E.hrefRaw.startsWith(`<`)&&E.hrefRaw.endsWith(`>`)?`<${t}>`:t;g+=`[${E.text}](${e}${E.titleSuffix})`,S++}else g+=e.slice(w,E.nextIndex)}else g+=e.slice(w,E.nextIndex);w=E.nextIndex;continue}}g+=e[w],w++}return{markdown:g,rewrites:S}}function rewriteOutboundMarkdownLinksForSourceMove(e,t,s){if(posix.dirname(t)===posix.dirname(s))return{markdown:e,rewrites:0};let g=null,S=0;return{markdown:splitLines(e).map(({line:e,ending:w})=>{if(g)return isFenceClose$2(e,g)&&(g=null),`${e}${w}`;let E=matchFence$2(e);if(E)return g=E,`${e}${w}`;let D=rewriteOutboundMarkdownLinksInLine(e,t,s);return S+=D.rewrites,`${D.markdown}${w}`}).join(``),rewrites:S}}var ManagedRenameCollisionError=class extends Error{colliding;constructor(e){super(`Managed rename collision: ${e.map(e=>`'${e.existing}' and '${e.incoming}' both target '${e.to}'`).join(`; `)}`),this.name=`ManagedRenameCollisionError`,this.colliding=e}},ManagedRenameSourceNotFoundError=class extends Error{kind;constructor(e){super(`${e} does not exist`),this.name=`ManagedRenameSourceNotFoundError`,this.kind=e}},ManagedRenameDestinationExistsError=class extends Error{constructor(){super(`Destination already exists`),this.name=`ManagedRenameDestinationExistsError`}},ManagedRenameSourceTypeMismatchError=class extends Error{kind;constructor(e){super(`Source path is not a ${e}`),this.name=`ManagedRenameSourceTypeMismatchError`,this.kind=e}},SymlinkEscapeError=class extends Error{constructor(e){super(`symlink-escape: ${e}`),this.name=`SymlinkEscapeError`}},BacklinkIndexRequiredError=class extends Error{constructor(){super(`Managed rename requires backlink index support`),this.name=`BacklinkIndexRequiredError`}},ManagedRenameSnapshotMissingError=class extends Error{docName;constructor(e){super(`Cannot snapshot missing document: ${e}`),this.name=`ManagedRenameSnapshotMissingError`,this.docName=e}},ManagedRenameMissingDocumentError=class extends Error{docName;constructor(e){super(`Cannot rename missing document: ${e}`),this.name=`ManagedRenameMissingDocumentError`,this.docName=e}};function buildRenameMap(e){let t=new Map,s=[];for(let{from:g,to:S}of e){for(let[e,w]of t)e!==g&&w===S&&s.push({existing:e,incoming:g,to:S});t.set(g,S)}if(s.length>0)throw new ManagedRenameCollisionError(s);return t}function rewriteSupportedLinksForRename(e,t,s,g){let{frontmatter:S,body:w}=stripFrontmatter(e),E=rewriteWikiLinksForDocumentRename(w,s,g),D=rewriteMarkdownLinksForDocumentRename(E.markdown,t,s,g);return{markdown:prependFrontmatter(S,D.markdown),rewrites:E.rewrites+D.rewrites}}function applyRenameMap(e,t,s){let g=e,S=0,w,E=[];for(let[e,g]of s)e!==g&&(e===t?w=g:E.push([e,g]));if(w!==void 0){let e=rewriteSupportedLinksForRename(g,t,t,w);g=e.markdown,S+=e.rewrites;let{frontmatter:s,body:E}=stripFrontmatter(g),D=rewriteOutboundMarkdownLinksForSourceMove(E,t,w);g=prependFrontmatter(s,D.markdown),S+=D.rewrites}let D=w??t,O=new Map;for(let[e,t]of E){let s=`__OK_RENAME_${randomUUID().replaceAll(`-`,``)}__`,w=rewriteSupportedLinksForRename(g,D,e,s);w.rewrites>0&&(g=w.markdown,S+=w.rewrites,O.set(s,t))}for(let[e,t]of O)g=rewriteSupportedLinksForRename(g,D,e,t).markdown;return{markdown:g,rewrites:S}}const WIKI_LINK_RE$1=/\[\[([^\n#[\]|]+)(?:#([^\n[\]|]+))?(?:\|([^\n[\]]+))?\]\]/y,MD_LINK_RE$1=/\[([^\]\n]*)\]\((<[^>\n]+>|[^)\s\n]+)(?:\s+(?:"[^"\n]*"|'[^'\n]*'|\([^)\n]*\)))?\)/y;function createEmptyState$1(){return{backward:new Map,forward:new Map,externalForward:new Map,externalBackward:new Map}}function mergeLinkMeta(e,t){return e?{anchor:e.anchor??t.anchor,snippet:e.snippet??t.snippet}:t}function getRepresentativeAnchor(e){if(!e)return null;for(let[,t]of[...e.entries()].sort(([e],[t])=>e.localeCompare(t)))if(t.anchor)return t.anchor;return null}function externalNodeId(e){return`external:${e}`}function externalUrlFromNodeId(e){return e.startsWith(`external:`)?e.slice(9):null}function normalizeSnippet$1(e){return e.replace(/\s+/g,` `).trim()}function snippetAround$1(e,t,s){if(!normalizeSnippet$1(e))return null;let g=Math.max(e.lastIndexOf(`.`,t-1),e.lastIndexOf(`?`,t-1),e.lastIndexOf(`!`,t-1),e.lastIndexOf(`
|
|
825
825
|
`,t-1)),S=[e.indexOf(`.`,s),e.indexOf(`?`,s),e.indexOf(`!`,s),e.indexOf(`
|
|
826
826
|
`,s)].filter(e=>e>=0),w=g>=0?g+1:Math.max(0,t-60),E=S.length>0?Math.min(...S)+1:Math.min(e.length,s+60),D=w>0?`…`:``,O=E<e.length?`…`:``,k=normalizeSnippet$1(e.slice(w,E));return k?`${D}${k}${O}`:null}function matchFence$1(e){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(!t)return null;let s=t[1],g=s[0];return g!=="`"&&g!==`~`?null:{char:g,length:s.length}}function isFenceClose$1(e,t){return RegExp(`^\\s{0,3}\\${t.char}{${t.length},}\\s*$`).test(e)}function leadingMarkdownPrefixLength$1(e){let t=/^\s{0,3}(?:#{1,6}\s+|>\s+|(?:[-+*]|\d+[.)])\s+)/.exec(e);return t?t[0].length:0}function readInlineCode$1(e,t){let s=0;for(;e[t+s]==="`";)s++;if(s===0)return null;let g=t+s,S=g;for(;S<e.length;){if(e[S]!=="`"){S++;continue}let t=0;for(;e[S+t]==="`";)t++;if(t===s)return{text:e.slice(g,S),nextIndex:S+s};S+=t}return{text:e.slice(t,g),nextIndex:g}}function readWikiLink$1(e,t){WIKI_LINK_RE$1.lastIndex=t;let s=WIKI_LINK_RE$1.exec(e);if(!s)return null;let g=s[1]?.trim(),S=s[2]?.trim()||null,w=s[3]?.trim()||null;return g?{target:g,alias:w,anchor:S,nextIndex:t+s[0].length}:null}function extractWikiLinksFromLine(e){let t=``,s=[],g=leadingMarkdownPrefixLength$1(e);for(;g<e.length;){if(e[g]===`\\`&&g+1<e.length){t+=e[g+1],g+=2;continue}if(e[g]==="`"){let s=readInlineCode$1(e,g);if(s){t+=s.text,g=s.nextIndex;continue}}if(e[g]===`[`&&e[g+1]===`[`){let S=readWikiLink$1(e,g);if(S){let e=getWikiLinkText(S),w=t.length;t+=e;let E=classifyWikiLinkTarget(S.target,S.anchor);E?.kind===`doc`&&s.push({target:E.docName,anchor:E.anchor,start:w,end:w+e.length}),g=S.nextIndex;continue}}t+=e[g],g++}return{text:t,occurrences:s}}function extractExternalWikiLinksFromLine(e){let t=``,s=[],g=leadingMarkdownPrefixLength$1(e);for(;g<e.length;){if(e[g]===`\\`&&g+1<e.length){t+=e[g+1],g+=2;continue}if(e[g]==="`"){let s=readInlineCode$1(e,g);if(s){t+=s.text,g=s.nextIndex;continue}}if(e[g]===`[`&&e[g+1]===`[`){let S=readWikiLink$1(e,g);if(S){let e=getWikiLinkText(S),w=t.length;t+=e;let E=classifyWikiLinkTarget(S.target,S.anchor);E?.kind===`external`&&s.push({url:E.url,label:e,start:w,end:w+e.length}),g=S.nextIndex;continue}}t+=e[g],g++}return{text:t,occurrences:s}}function normalizeMarkdownHref$1(e){return e.startsWith(`<`)&&e.endsWith(`>`)?e.slice(1,-1):e}function readMarkdownLink$1(e,t){MD_LINK_RE$1.lastIndex=t;let s=MD_LINK_RE$1.exec(e);return s?{text:s[1]??``,href:normalizeMarkdownHref$1(s[2]??``),nextIndex:t+s[0].length}:null}function extractMarkdownLinksFromLine(e,t){let s=``,g=[],S=leadingMarkdownPrefixLength$1(e);for(;S<e.length;){if(e[S]===`\\`&&S+1<e.length){s+=e[S+1],S+=2;continue}if(e[S]==="`"){let t=readInlineCode$1(e,S);if(t){s+=t.text,S=t.nextIndex;continue}}if(e[S]===`[`&&e[S+1]===`[`){let t=readWikiLink$1(e,S);if(t){s+=getWikiLinkText(t),S=t.nextIndex;continue}}if(e[S]===`[`&&e[S-1]!==`!`){let w=readMarkdownLink$1(e,S);if(w){let e=classifyMarkdownHref(w.href,t);if(e?.kind===`doc`){let t=s.length;s+=w.text,g.push({target:e.docName,anchor:e.anchor,start:t,end:t+w.text.length})}else s+=w.text;S=w.nextIndex;continue}}s+=e[S],S++}return{text:s,occurrences:g}}function extractExternalMarkdownLinksFromLine(e,t){let s=``,g=[],S=leadingMarkdownPrefixLength$1(e);for(;S<e.length;){if(e[S]===`\\`&&S+1<e.length){s+=e[S+1],S+=2;continue}if(e[S]==="`"){let t=readInlineCode$1(e,S);if(t){s+=t.text,S=t.nextIndex;continue}}if(e[S]===`[`&&e[S+1]===`[`){let t=readWikiLink$1(e,S);if(t){s+=getWikiLinkText(t),S=t.nextIndex;continue}}if(e[S]===`[`&&e[S-1]!==`!`){let w=readMarkdownLink$1(e,S);if(w){let e=classifyMarkdownHref(w.href,t);if(s+=w.text,e?.kind===`external`){let t=s.length-w.text.length;g.push({url:e.url,label:w.text||null,start:t,end:t+w.text.length})}S=w.nextIndex;continue}}s+=e[S],S++}return{text:s,occurrences:g}}function extractMarkdownLinksFromMarkdown(e,t){let s=e.replaceAll(`\r
|
|
827
827
|
`,`
|
|
@@ -1919,7 +1919,7 @@ tags: [travel]
|
|
|
1919
1919
|
`)[0]??``).split(/\s+/)[2];if(s){let g=await e.raw(`cat-file`,`-p`,s);t.writeHead(200,{"Content-Type":`text/markdown`,"X-Content-Type-Options":`nosniff`}),t.end(g);return}}}catch(e){console.warn(`[rescue] timeline-ref fallback failed:`,e)}errorResponse(t,404,`urn:ok:error:not-found`,`Not found.`,{handler:`rescue-get`})}let Yi=withValidation(CreatePageRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`create-page`});return}let S=s.path;if(!isSupportedDocFile(S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must end with .md or .mdx.`,{handler:`create-page`});return}if(S.includes(`..`)||S.startsWith(`/`)||S.includes(`\0`)||S.includes(`\\`)){errorResponse(t,400,`urn:ok:error:path-escape`,`Invalid path.`,{handler:`create-page`,detail:`path must not contain .. or start with /`});return}let E=resolve(g),D=resolve(E,S);if(!D.startsWith(`${E}/`)&&D!==E){errorResponse(t,400,`urn:ok:error:path-escape`,`path must not escape content directory.`,{handler:`create-page`});return}let O=stripDocExtension(S);if(isSystemDoc(O)||isConfigDoc(O)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'${O}' is a reserved document name.`,{handler:`create-page`});return}let k=typeof s.template==`string`?s.template.trim():``,j=``,F;if(k.length>0){if(!/^[A-Za-z0-9_-]+$/.test(k)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Template name must match [A-Za-z0-9_-]+.`,{handler:`create-page`});return}let s=S.includes(`/`)?S.slice(0,S.lastIndexOf(`/`)):``,g=resolveTemplatesAvailable(E,s),w=g.find(e=>e.name===k);if(!w){let e=g.length===0?`(none)`:g.map(e=>`"${e.name}" (${e.scope})`).join(`, `);errorResponse(t,400,`urn:ok:error:invalid-request`,`Template "${k}" does not resolve for folder "${s||`(root)`}". Available: ${e}`,{handler:`create-page`});return}let D=w.scope===`user`?w.path:resolve(E,w.path),O;try{O=readFileSync(D,`utf-8`)}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read template at ${w.scope===`user`?`~/.ok/templates/${w.name}.md`:w.path}.`,{handler:`create-page`,cause:e});return}let{body:L}=stripFrontmatter(O),B=e.kind===`agent`||e.kind===`principal`?e.displayName??``:``;j=applySubstitution(L,{date:todayIsoUtc(),user:B}),F=w.scope}mkdirSync(dirname(D),{recursive:!0});try{writeFileSync(D,j,{encoding:`utf-8`,flag:`wx`})}catch(e){if(e.code===`EEXIST`){errorResponse(t,409,`urn:ok:error:doc-already-exists`,`File already exists.`,{handler:`create-page`,cause:e});return}throw e}let L=stripDocExtension(S);switch(ge?.delete(L),ue&&ue.incrementMdDir(dirname(L)),registerWrite(D,contentHash(j)),e.kind){case`agent`:case`principal`:recordContributor(L,e.writerId,e.displayName,e.colorSeed,void 0,e.actor);break;case`anonymous`:break;default:throw Error(`Unhandled actor kind in handleCreatePage: ${String(e.kind)}`)}let B=typeof w==`function`?w():null;B instanceof Map&&updateFileIndex({kind:`create`,path:D,docName:L,content:j},B),q&&(q.updateDocumentFromMarkdown(L,j),q.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist create-page cache for ${L}:`,e)}),Y?.(`backlinks`),Y?.(`graph`)),Y?.(`files`),F!==void 0&&console.warn(JSON.stringify({event:`template-instantiate`,templateName:k,templateScope:F,docName:L})),successResponse(t,200,CreatePageSuccessSchema,{docName:L},{handler:`create-page`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to create page.`,{handler:`create-page`,cause:e})}},{handler:`create-page`,method:`POST`}),Xi=withValidation(CreateFolderRequestSchema,async(e,t,s)=>{try{if(extractActorIdentity(s,ce).kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`create-folder`});return}let e=s.path;if(!isValidRelativeContentPath(e)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`create-folder`});return}if(e===`.ok`||e.startsWith(`.ok/`)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`'.ok' is a reserved directory.`,{handler:`create-folder`});return}if(ue?.isDirExcluded(e)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Destination folder is excluded by the workspace content config.`,{handler:`create-folder`});return}let S=resolveContentEntryPath(g,`folder`,e);if(existsSync(S)){errorResponse(t,409,`urn:ok:error:doc-already-exists`,`Folder already exists.`,{handler:`create-folder`});return}tracedMkdirSync(S,{recursive:!0}),we(e),Y?.(`files`),successResponse(t,200,CreateFolderSuccessSchema,{path:e},{handler:`create-folder`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to create folder.`,{handler:`create-folder`,cause:e})}},{handler:`create-folder`,method:`POST`}),Zi=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!s||s.length===0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing docName query parameter.`,{handler:`page-headings`});return}if(!isSafeDocName(s)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`page-headings`});return}let g=Pe(s);if(!g){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`page-headings`});return}if(!existsSync(g)){errorResponse(t,404,`urn:ok:error:doc-not-found`,`Page not found.`,{handler:`page-headings`});return}successResponse(t,200,PageHeadingsSuccessSchema,{docName:s,headings:extractHeadings(readFileSync(g,`utf-8`))},{handler:`page-headings`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read headings.`,{handler:`page-headings`,cause:e})}},{handler:`page-headings`,method:`GET`,skipBodyParse:!0}),ka=withValidation(RenamePathRequestSchema,async(e,t,s)=>{try{let e=extractActorIdentity(s,ce);if(e.kind===`invalid-summary`){errorResponse(t,400,`urn:ok:error:invalid-request`,`Summary must be a string.`,{handler:`rename-path`});return}let{kind:S,fromPath:w,toPath:E}=s;if(!isValidRelativeContentPath(w)||!isValidRelativeContentPath(E)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Paths must be relative content paths.`,{handler:`rename-path`});return}if(S===`file`&&(isSystemDoc(w)||isSystemDoc(E)||isConfigDoc(w)||isConfigDoc(E))){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`Reserved document names cannot be renamed.`,{handler:`rename-path`});return}if(w===`.ok`||w.startsWith(`.ok/`)||E===`.ok`||E.startsWith(`.ok/`)){errorResponse(t,400,`urn:ok:error:reserved-doc-name`,`.ok is a reserved directory.`,{handler:`rename-path`});return}if(w===E){successResponse(t,200,RenamePathSuccessSchema,{renamed:[],rewrittenDocs:[]},{handler:`rename-path`});return}if(w.toLowerCase()===E.toLowerCase()){errorResponse(t,400,`urn:ok:error:invalid-request`,`Case-only renames are not supported.`,{handler:`rename-path`});return}if(S===`file`&&probeAndRegisterSourceFileExtension(g,w),ue&&(S===`file`?ue.isExcluded(isSupportedDocFile(E)?E:`${E}${getDocExtension(w)}`):ue.isDirExcluded(E))){errorResponse(t,400,`urn:ok:error:invalid-request`,`Destination ${S===`file`?`document`:`folder`} is excluded by the project content config.`,{handler:`rename-path`});return}let D=e.kind===`agent`||e.kind===`principal`?{writerId:e.writerId,displayName:e.displayName,colorSeed:e.colorSeed,actorMetadata:e.actor}:void 0,O;try{O=await Mt(w,E,S,{...D?{actor:D}:{}})}catch(e){if(e instanceof ManagedRenameCollisionError){errorResponse(t,409,`urn:ok:error:doc-already-exists`,it(e.message),{handler:`rename-path`,extensions:{colliding:e.colliding},cause:e});return}throw e}if(O.renamed.length===0){successResponse(t,200,RenamePathSuccessSchema,{renamed:[],rewrittenDocs:[]},{handler:`rename-path`});return}let k;switch(e.kind){case`agent`:{let t=e.summary.kind===`value`,s=t?e.summary:normalizeSummary(`Renamed ${w} → ${E}`),g=Lt(s);k=t||!g.response?g.response:Rt(g.response);for(let t=0;t<O.renamed.length;t++){let{fromDocName:s,toDocName:S}=O.renamed[t];recordContributor(S,e.writerId,e.displayName,e.colorSeed,formatRenameSubject(s,S),e.actor,t===0?g.stored:void 0)}incrementAgentWriteCalls(),zt(s,!t);for(let{toDocName:e}of O.renamed)Xe(e,`rename-path`);break}case`principal`:{let t=Lt(e.summary);k=t.response;for(let s=0;s<O.renamed.length;s++){let{fromDocName:g,toDocName:S}=O.renamed[s];recordContributor(S,e.writerId,e.displayName,e.colorSeed,formatRenameSubject(g,S),e.actor,s===0?t.stored:void 0)}zt(e.summary,!1);for(let{toDocName:e}of O.renamed)Xe(e,`rename-path`);break}case`anonymous`:log$2.debug({kind:S,fromPath:w,toPath:E,affectedDocs:O.renamed.length},`[rename-path] anonymous actor — no contributor recorded (no agentId in body and getPrincipal() returned null)`);break;default:throw Error(`Unhandled actor kind in handleRenamePath: ${String(e.kind)}`)}if(renameAttributionCounter().add(1,{kind:`rename-${S}`,attribution_kind:e.kind}),F)try{await F()}catch(e){console.warn(`[rename-path] flushContributors failed (commitSha backfill may be deferred):`,e)}successResponse(t,200,RenamePathSuccessSchema,{renamed:O.renamed,rewrittenDocs:O.rewrittenDocs,...k?{summary:k}:{}},{handler:`rename-path`})}catch(e){let{status:s,type:g,error:S}=at(e);errorResponse(t,s,g,S,{handler:`rename-path`,cause:e})}},{handler:`rename-path`,method:`POST`}),_s=withValidation(DeletePathRequestSchema,async(e,t,s)=>{try{Ft(s);let{kind:e,path:S}=s;if(!isValidRelativeContentPath(S)){errorResponse(t,400,`urn:ok:error:invalid-request`,`path must be a relative content path.`,{handler:`delete-path`});return}let E=resolveContentEntryPath(g,e,S);if(!existsSync(E)){errorResponse(t,404,`urn:ok:error:doc-not-found`,`${e} does not exist.`,{handler:`delete-path`});return}let D=statSync(E);if(e===`file`&&!D.isFile()||e===`folder`&&!D.isDirectory()){errorResponse(t,400,`urn:ok:error:invalid-request`,`Target path is not a ${e}.`,{handler:`delete-path`});return}let O=e===`file`?[S]:listAffectedDocNames(w(),e,S);if(await st(O),ge)for(let e of O)isSystemDoc(e)||isConfigDoc(e)||(ge.setDeleted(e),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:e,kind:`deleted`,source:`handleDeletePath`})));e===`file`?unlinkSync(E):(rmSync(E,{recursive:!0,force:!1}),Te(S));let k=w();if(k instanceof Map)for(let e of O)updateFileIndex({kind:`delete`,path:resolve(g,`${e}${getDocExtension(e)}`),docName:e},k);successResponse(t,200,DeletePathSuccessSchema,{deletedDocNames:O},{handler:`delete-path`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to delete path.`,{handler:`delete-path`,cause:e})}},{handler:`delete-path`,method:`POST`}),xs=withValidation(EmptyRequestSchema,async(e,t)=>{try{let e=w(),s=[];for(let[t,S]of e){let e=t,w=getDocExtension(t);try{e=extractPageTitle(readFileSync(resolve(g,`${t}${w}`),`utf-8`),t)}catch(e){console.warn(`[pages] Failed to read title for ${t}:`,e)}s.push({docName:t,title:e,docExt:w,size:S.size,modified:S.modified})}s.sort((e,t)=>e.docName.localeCompare(t.docName)),successResponse(t,200,PagesSuccessSchema,{pages:s},{handler:`pages`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to list pages.`,{handler:`pages`,cause:e})}},{handler:`pages`,method:`GET`,skipBodyParse:!0}),Cs=withValidation(EmptyRequestSchema,async(e,s)=>{try{let g=new URL(e.url??``,`http://localhost`).searchParams.get(`docName`);if(!g){errorResponse(s,400,`urn:ok:error:invalid-request`,`Missing docName parameter.`,{handler:`suggest-links`});return}if(!isSafeDocName(g)){errorResponse(s,400,`urn:ok:error:invalid-request`,`Invalid docName.`,{handler:`suggest-links`});return}if(isSystemDoc(g)||isConfigDoc(g)){errorResponse(s,400,`urn:ok:error:reserved-doc-name`,`'${g}' is a reserved document name.`,{handler:`suggest-links`});return}successResponse(s,200,SuggestLinksSuccessSchema,await suggestLinks({hocuspocus:t,fileIndex:w(),docName:g}),{handler:`suggest-links`})}catch(e){if(e instanceof SuggestLinksTargetNotFoundError){errorResponse(s,404,`urn:ok:error:doc-not-found`,`Page not found.`,{handler:`suggest-links`,cause:e});return}errorResponse(s,500,`urn:ok:error:internal-server-error`,`Failed to suggest links.`,{handler:`suggest-links`,cause:e})}},{handler:`suggest-links`,method:`GET`,skipBodyParse:!0});async function Ts(e,t){if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`upload-asset`,extraHeaders:{Allow:`POST`}});return}let s;try{s=await readUploadBody(e,se??g)}catch(e){if(e instanceof UploadWriteError){errorResponse(t,uploadStatusFor(e.reason),e.reason,uploadTitleFor(e.reason),{handler:`upload-asset`,cause:e});return}errorResponse(t,400,`urn:ok:error:malformed-upload`,`Failed to parse upload.`,{handler:`upload-asset`,cause:e});return}let{filename:S,tempPath:w,sha:E,byteLength:D,parentDocName:O}=s,k=()=>{if(existsSync(w))try{unlinkSync(w)}catch{}},j=validateBody(UploadRequestSchema,{parentDocName:O},t,{handler:`upload-asset`});if(!j.ok){k();return}let{parentDocName:F}=j.value,{agentId:L,agentName:B}=Ft(Object.fromEntries(new URL(e.url??``,`http://localhost`).searchParams.entries()));if(D===0){k(),errorResponse(t,400,`urn:ok:error:no-file-received`,`No file received.`,{handler:`upload-asset`});return}if(F.includes(`\0`)||F.includes(`..`)||F.startsWith(`/`)){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}let H=resolve(g),q=resolveUploadDestDir(F,`./`,H);if(!isWithinContentDir(q,H)){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}try{assertNoSymlinkEscape(q,H)}catch(e){if(k(),(e instanceof Error?e.message:String(e)).startsWith(`symlink-escape:`)){errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}log$2.error({err:e,destDir:q},`[upload] failed to validate destination directory`),errorResponse(t,500,`urn:ok:error:storage-error`,`Storage error.`,{handler:`upload-asset`,cause:e});return}try{mkdirSync(q,{recursive:!0})}catch(e){if(e.code!==`EEXIST`){k();let s=classifyUploadErrno(e);errorResponse(t,uploadStatusFor(s),s,uploadTitleFor(s),{handler:`upload-asset`,cause:e,detail:`failed to create attachment directory`});return}}try{let e=realpathSync(q),s;try{s=realpathSync(H)}catch{s=H}if(!isWithinContentDir(e,s)){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`});return}}catch(e){if(e.code!==`ENOENT`){k(),errorResponse(t,400,`urn:ok:error:path-escape`,`Path escape detected.`,{handler:`upload-asset`,cause:e});return}}let J=await fileTypeFromFile(w),Y=J?.mime,ee=J?.ext;if(!Y){let e=readTempFileHead(w,256).toString(`utf-8`).replace(/^/,``).trimStart();(e.startsWith(`<svg`)||e.startsWith(`<?xml`)&&e.includes(`<svg`))&&(Y=`image/svg+xml`,ee=`svg`)}{let s=await findDuplicateAsset(q,E,D);if(s){k();let S=relative(g,resolve(q,s));log$2.info({event:`upload`,endpoint:e.url??`/api/upload`,agentId:L,agentName:B,dedup:!0,mime:Y??null,size:D,destPath:S,httpStatus:200},`[upload] dedup hit`),successResponse(t,200,UploadAssetSuccessSchema,{src:s,path:S,deduped:!0},{handler:`upload-asset`});return}}let te;if(!S||S===`upload`||GENERIC_PASTE_NAMES.test(S)){let e=new Date().toISOString().replace(/[-:T]/g,``).slice(0,14).replace(/(\d{8})(\d{6})/,`$1-$2`),t=S?extname(S).slice(1):``,s=ee??t??``;te=s===``?`pasted-${e}`:`pasted-${e}.${s}`}else te=sanitizeFilename(S);try{let s=linkTempToFinalWithCollisionRetry(w,q,te),S=relative(g,resolve(q,s));log$2.info({event:`upload`,endpoint:e.url??`/api/upload`,agentId:L,agentName:B,dedup:!1,mime:Y??null,size:D,destPath:S,httpStatus:200},`[upload] write ok`),successResponse(t,200,UploadAssetSuccessSchema,{src:s,path:S,deduped:!1},{handler:`upload-asset`})}catch(s){let g=s instanceof UploadWriteError?s.reason:`urn:ok:error:storage-error`;log$2.error({event:`upload`,endpoint:e.url??`/api/upload`,agentId:L,agentName:B,filename:te,size:D,reason:g,httpStatus:uploadStatusFor(g),err:s},`[upload] write failed`),errorResponse(t,uploadStatusFor(g),g,uploadTitleFor(g),{handler:`upload-asset`,cause:s})}}let Ds=`/api/local-op/clone`,Os=`/api/local-op/open`,ks=600*1e3,As=45e3,Ns=`local-op-clone`,Ps=withValidation(LocalOpCloneRequestSchema,Is,{handler:Ns,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:Ns})});async function Is(e,t,s){let{url:g,dir:S}=s;if(!isAllowedGitUrl(g)){errorResponse(t,400,`urn:ok:error:url-not-allowed`,`URL protocol is not allowed for clone.`,{handler:Ns,cause:Error(`url=${g}`)});return}if(!isSafeLocalPath(S)){errorResponse(t,400,`urn:ok:error:dir-outside-home`,`Clone destination must be within the user home directory.`,{handler:Ns,cause:Error(`dir=${S}`)});return}if(!_e.tryAcquire(Ds)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A clone operation is already in progress.`,{handler:Ns,extraHeaders:{"Retry-After":`30`}});return}t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let w=createStreamingErrorWriter(t,Ns),E=null,D=runCloneSubprocess({cliArgs:oe,url:g,dir:S,timeoutMs:ks,onEvent:e=>{if(e.type===`complete`){E=e.dir;return}if(e.type===`error`){e.message&&log$2.warn({stderr:e.message,url:g,dir:S},`[local-op/clone] clone failed`),w(500,`urn:ok:error:clone-failed`,`Clone subprocess reported an error.`,{cause:e.message?Error(e.message):void 0});return}if(!t.writableEnded&&!t.destroyed)try{t.write(`${JSON.stringify(e)}\n`)}catch{}}});(async()=>{try{if(await D.done,E&&!t.writableEnded&&!t.destroyed){let e=await Rs(E);!t.writableEnded&&!t.destroyed&&(`port`in e?t.write(`${JSON.stringify({type:`complete`,port:e.port,dir:E})}\n`):w(500,`urn:ok:error:server-start-failed`,`Cloned successfully but failed to start the project server.`,{cause:Error(e.error)}))}}catch(e){!t.writableEnded&&!t.destroyed?w(500,`urn:ok:error:internal-server-error`,`Unexpected error during clone post-processing.`,{cause:e}):log$2.error({err:e,handler:Ns},`clone IIFE rejected after stream ended`)}finally{t.writableEnded||t.end(),_e.release(Ds)}})(),t.on(`close`,()=>{D.cancel()})}async function Rs(e){let t=resolve(expandTilde(e)),s=getLocalDir(t),g=readUiLock(s);if(g&&g.port>0)return{port:g.port};let S=readServerLock(s),[w,...E]=oe,D=S&&S.port>0?`ui`:`start`,O=spawn(w,[...E,D],{cwd:t,detached:!0,stdio:[`ignore`,`ignore`,`pipe`],env:{...process.env,OK_LOCK_KIND:`interactive`}}),k=[];O.stderr?.on(`data`,e=>{k.push(e),log$2.warn({cwd:t,cliCmd:D,msg:e.toString(`utf-8`).trim()},`[local-op/open] child stderr`)});let j=null;O.on(`exit`,e=>{j=e??-1}),O.unref();let F=Date.now()+45e3;for(;Date.now()<F;){await setTimeout$1(500);let e=readUiLock(s);if(e&&e.port>0)return{port:e.port};if(j!==null){let e=Buffer.concat(k).toString(`utf-8`).trim();return{error:`\`ok ${D}\` exited (code ${j})${e?` — ${e}`:``}`}}}let L=Buffer.concat(k).toString(`utf-8`).trim();return{error:`UI did not start within the expected time${L?` — ${L}`:``}`}}let $s=`local-op-open`,ec=withValidation(LocalOpOpenRequestSchema,async(e,t,s)=>{let{dir:g}=s;if(!isSafeLocalPath(g)){errorResponse(t,400,`urn:ok:error:dir-outside-home`,`dir must be within the user home directory.`,{handler:$s,cause:Error(`dir=${g}`)});return}if(!_e.tryAcquire(Os)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A server-open operation is already in progress.`,{handler:$s,extraHeaders:{"Retry-After":`5`}});return}try{let e=await Rs(g);`port`in e?successResponse(t,200,LocalOpOpenSuccessSchema,{port:e.port},{handler:$s}):errorResponse(t,504,`urn:ok:error:server-open-failed`,`Failed to open project server.`,{handler:$s,cause:Error(e.error)})}finally{_e.release(Os)}},{handler:$s,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:$s})}),tc=`/api/local-op/auth/login`,nc=`/api/local-op/auth/status`,rc=`/api/local-op/auth/repos`,ic=`/api/local-op/auth/signout`,ac=`/api/local-op/auth/pat`,oc=`local-op-auth-login`,sc=withValidation(LocalOpAuthHostRequestSchema,cc,{handler:oc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:oc})});async function cc(e,t,s){let g=s.host??`github.com`;if(!_e.tryAcquire(tc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth login operation is already in progress.`,{handler:oc,extraHeaders:{"Retry-After":`5`}});return}t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let S=createStreamingErrorWriter(t,oc),w=runDeviceFlowSubprocess({cliArgs:oe,host:g,timeoutMs:ks,onEvent:e=>{if(e.type===`error`){S(500,`urn:ok:error:auth-failed`,`Auth subprocess reported an error.`,{cause:e.message?Error(e.message):void 0});return}if(!t.writableEnded&&!t.destroyed)try{t.write(`${JSON.stringify(e)}\n`)}catch{}}}),E=()=>{w.cancel()};t.on(`close`,E),w.done.finally(()=>{t.off(`close`,E),t.writableEnded||t.end(),_e.release(tc)})}let lc=`local-op-auth-status`,uc=withValidation(LocalOpAuthHostRequestSchema,async(e,t,s)=>{let g=s.host??`github.com`;if(!_e.tryAcquire(nc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth status operation is already in progress.`,{handler:lc,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...s]=oe,S=[...s,`auth`,`status`,`--json`,`--host`,g],w=(await new Promise((t,s)=>{let g=spawn(e,S,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),w=!1,E=setTimeout(()=>{w=!0,g.kill(`SIGTERM`)},3e4),D=[];g.stdout.on(`data`,e=>D.push(e)),g.on(`close`,()=>{if(clearTimeout(E),w){s(Error(`auth status subprocess timed out after 30s`));return}t(Buffer.concat(D).toString(`utf-8`))}),g.on(`error`,e=>{clearTimeout(E),s(e)})})).split(`
|
|
1920
1920
|
`).map(e=>e.trim()).filter(Boolean),E=null;for(let e=w.length-1;e>=0;e--)try{E=JSON.parse(w[e]);break}catch{}E===null?successResponse(t,200,LocalOpAuthStatusSuccessSchema,{authenticated:!1},{handler:lc}):successResponse(t,200,LocalOpAuthStatusSuccessSchema,E,{handler:lc})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth status check failed.`,{handler:lc,cause:e})}finally{_e.release(nc)}},{handler:lc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:lc})}),dc=`local-op-auth-repos`,fc=withValidation(LocalOpAuthHostRequestSchema,pc,{handler:dc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:dc})});async function pc(e,t,s){let g=s.host??`github.com`;if(!_e.tryAcquire(rc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth repos operation is already in progress.`,{handler:dc,extraHeaders:{"Retry-After":`5`}});return}t.writeHead(200,{"Content-Type":`application/x-ndjson`,"Transfer-Encoding":`chunked`,"X-Content-Type-Options":`nosniff`,"Cache-Control":`no-cache`});let S=createStreamingErrorWriter(t,dc),[w,...E]=oe,D=[...E,`auth`,`repos`,`--json`,`--host`,g],O=!1,k=``,j=spawn(w,D,{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env}}),F=setTimeout(()=>{j.kill(`SIGTERM`)},ks);j.stdout.on(`data`,e=>{k+=e.toString(`utf-8`);let s=k.split(`
|
|
1921
1921
|
`);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$2.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(),_e.release(rc))}),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()),_e.release(rc))}),t.on(`close`,()=>{O||(O=!0,clearTimeout(F),j.kill(`SIGTERM`),_e.release(rc))})}let mc=`local-op-auth-signout`,hc=withValidation(LocalOpAuthHostRequestSchema,async(e,t,s)=>{let g=s.host??`github.com`;if(!_e.tryAcquire(ic)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth signout operation is already in progress.`,{handler:mc,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...s]=oe,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:mc})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth signout failed.`,{handler:mc,cause:e})}finally{_e.release(ic)}},{handler:mc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:mc})}),gc=`local-op-auth-pat`,_c=withValidation(LocalOpAuthPatRequestSchema,async(e,t,s)=>{let{pat:g,host:S}=s,w=S??`github.com`;if(!_e.tryAcquire(ac)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`An auth pat operation is already in progress.`,{handler:gc,extraHeaders:{"Retry-After":`5`}});return}try{let[e,...s]=oe,S=[...s,`auth`,`pat`,`--json`,`--host`,w],E=(await new Promise((t,s)=>{let w=spawn(e,S,{stdio:[`pipe`,`pipe`,`pipe`],env:{...process.env}}),E=setTimeout(()=>{w.kill(`SIGTERM`)},3e4);w.stdin.write(`${g}\n`),w.stdin.end();let D=[];w.stdout.on(`data`,e=>D.push(e)),w.on(`close`,e=>{clearTimeout(E),e===0?t(Buffer.concat(D).toString(`utf-8`)):s(Error(`auth pat exited with code ${e}`))}),w.on(`error`,e=>{clearTimeout(E),s(e)})})).split(`
|
|
1922
|
-
`).map(e=>e.trim()).filter(Boolean),D=null;for(let e=E.length-1;e>=0;e--)try{D=JSON.parse(E[e]);break}catch{}D===null?successResponse(t,200,LocalOpAuthPatSuccessSchema,{},{handler:gc}):successResponse(t,200,LocalOpAuthPatSuccessSchema,D,{handler:gc})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth pat failed.`,{handler:gc,cause:e})}finally{_e.release(ac)}},{handler:gc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:gc})}),vc=`local-op-auth-identity`;async function yc(e,t){if(checkLocalOpSecurity(e,t,{handler:vc})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:vc,extraHeaders:{Allow:`GET`}});return}if(!se){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:vc});return}try{successResponse(t,200,LocalOpAuthIdentitySuccessSchema,{identity:await resolveGitIdentity(se)},{handler:vc})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Identity resolution failed.`,{handler:vc,cause:e})}}}let bc=`/api/local-op/auth/set-identity`,xc=`local-op-auth-set-identity`,Sc=withValidation(LocalOpAuthSetIdentityRequestSchema,async(e,t,s)=>{let g=s.name.trim(),S=s.email.trim();if(!se){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:xc});return}if(!_e.tryAcquire(bc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A set-identity operation is already in progress.`,{handler:xc,extraHeaders:{"Retry-After":`5`}});return}try{writeGitIdentity(se,g,S),ae?.()?.refreshIdentity().catch(()=>{}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:xc})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Set-identity failed.`,{handler:xc,cause:e})}finally{_e.release(bc)}},{handler:xc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:xc})});async function Cc(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=ae?.();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},{handler:`sync-status`});return}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 wc=withValidation(SyncTriggerRequestSchema,async(e,t,s)=>{let g=ae?.();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`})?ae?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`}),!1):!1});async function Tc(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=ae?.();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 Ec=withValidation(SyncResolveConflictRequestSchema,async(e,t,s)=>{let g=ae?.();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})}},{handler:`sync-resolve-conflict`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-resolve-conflict`})?ae?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`}),!1):!1});async function Dc(e,t){if(!checkLocalOpSecurity(e,t,{handler:`sync-conflict-content`}))return;if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflict-content`,extraHeaders:{Allow:`GET`}});return}if(!se){errorResponse(t,503,`urn:ok:error:project-repo-not-configured`,`Project repo not configured.`,{handler:`sync-conflict-content`});return}let s=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`file`);if(!s){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing required query param: file.`,{handler:`sync-conflict-content`});return}if(s.includes(`..`)||s.startsWith(`/`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid file path.`,{handler:`sync-conflict-content`});return}let g=esm_default({baseDir:se,timeout:{block:15e3}});async function S(e){try{return await g.raw([`show`,`:${e}:${s}`])}catch{return``}}try{let[e,g,w]=await Promise.all([S(1),S(2),S(3)]);successResponse(t,200,SyncConflictContentSuccessSchema,{file:s,base:e,ours:g,theirs:w},{handler:`sync-conflict-content`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read conflict content.`,{handler:`sync-conflict-content`,cause:e})}}async function Oc(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}let D=s.searchParams.get(`includePersonalTemplates`)===`true`;try{let e=await planSeed({projectDir:g,rootDir:S,packId:E});successResponse(t,200,SeedPlanSuccessSchema,{plan:D?{...e,personalTemplates:planPersonalTemplates()}: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 kc=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,D=E.packId,O=coercePackId(D);if(typeof D==`string`&&D.length>0&&O===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-apply`,detail:`Pack id "${D}" is not registered.`});return}let k=E.includePersonalTemplates===!0;try{let e=await applySeed(w,{projectDir:g,packId:O}),s=k?writePersonalTemplates():void 0;successResponse(t,200,SeedApplySuccessSchema,s?{result:e,personalTemplates:s}:{result:e},{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 Ac(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 jc=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 Mc(e,t){if(checkLocalOpSecurity(e,t,{handler:`installed-agents`}))try{await handleInstalledAgents(e,t,Me.probeAll)}catch(e){t.headersSent||(log$2.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}))}}async function Nc(e,t){if(!checkLocalOpSecurity(e,t,{handler:`sync-abort-merge`}))return;if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-abort-merge`,extraHeaders:{Allow:`POST`}});return}let s=ae?.();if(!s){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-abort-merge`});return}try{await s.abortMerge(),successResponse(t,200,SyncAbortMergeSuccessSchema,{},{handler:`sync-abort-merge`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to abort merge.`,{handler:`sync-abort-merge`,cause:e})}}let Pc=withValidation(EmptyRequestSchema,async(e,t)=>{if(!J){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-list`});return}try{successResponse(t,200,TagsListSuccessSchema,{tags:J.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 Fc(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(!J){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=J.getDocsForTagWithMatches(g).map(({docName:e,matchingTags:t})=>({docName:e,title:Ie(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 Ic(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 Lc=/^[A-Za-z0-9_-]+$/;function Rc(e,t,s=`template`){return!e||!Lc.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 zc(e,t,s=`template`){if(!(e==null||e===``))return e===`project`||e===`user`?e:(errorResponse(t,400,`urn:ok:error:invalid-request`,`target must be "project" or "user", got: ${JSON.stringify(e)}`,{handler:s}),null)}function Bc(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 Vc(e,t){if(e.method===`GET`)return Hc(e,t);if(e.method===`PUT`)return Uc(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`folder-config`,extraHeaders:{Allow:`GET, PUT`}})}let Hc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=Ic(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(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}),Uc=withValidation(FolderConfigPutRequestSchema,async(e,t,s)=>{try{let e=Ic(s.path,t,`path`,`folder-config-put`);if(!e)return;let g=e.folderRel===``?`**`:`${e.folderRel}/**`,S=applyNestedFolderRulesUpsert({projectDir:e.resolvedContentDir,rules:[{match:g,frontmatter:Bc(s.frontmatter)}]});if(!S.ok){let e=S.error.code===`WRITE_ERROR`||S.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 folder config.`:`Invalid folder config request.`,{handler:`folder-config-put`,detail:S.error.code,cause:Error(S.error.message)});return}successResponse(t,200,FolderConfigPutSuccessSchema,{applied:S.applied},{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`});async function Wc(e,t){if(e.method===`GET`)return qc(e,t);if(e.method===`PUT`)return Jc(e,t);if(e.method===`DELETE`)return Yc(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`template`,extraHeaders:{Allow:`GET, PUT, DELETE`}})}let Gc=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/,Kc=e=>{let t=e.match(Gc),s={},g=e;if(t){try{let e=(0,import_dist$1.parse)(t[1]??``);e&&typeof e==`object`&&!Array.isArray(e)&&(s=e)}catch{}g=e.slice(t[0].length)}return{frontmatter:s,body:g}},qc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Rc(g,t,`template-get`))return;let S=zc(s.searchParams.get(`target`),t,`template-get`);if(S===null)return;if(S===`user`){let e=getUserHome();if(!e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`User home directory could not be resolved.`,{handler:`template-get`});return}let s=resolve(e,`.ok`,`templates`,`${g}.md`);if(!existsSync(s)){errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-get`,detail:`User template "${g}" not found at ~/.ok/templates/${g}.md`});return}let{frontmatter:S,body:w}=Kc(await readFile$1(s,`utf-8`));successResponse(t,200,TemplateGetSuccessSchema,{template:{name:g,folder:`~/.ok`,scope:`user`,path:`~/.ok/templates/${g}.md`,frontmatter:S,body:w}},{handler:`template-get`});return}let w=Ic(s.searchParams.get(`folder`)??``,t,`folder`,`template-get`);if(!w)return;let{folderRel:E,resolvedContentDir:D}=w,O=E===``?[]:E.split(`/`),k=null,j=null,F=null;for(let e=O.length;e>=0;e--){let t=e===0?``:O.slice(0,e).join(`/`),s=t===``?D:resolve(D,t);if(s!==D&&!s.startsWith(`${D}${sep}`))continue;let S=resolve(s,`.ok`,`templates`,`${g}.md`);if(existsSync(S)){k=S,j=t,F=e===O.length?`local`:`inherited`;break}}if(!k||j===null||F===null){errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-get`,detail:`Template "${g}" not found for folder "${E||`.`}". Walked leaf → root.`});return}let{frontmatter:L,body:B}=Kc(await readFile$1(k,`utf-8`)),H=relative(D,k).split(/[\\/]/).filter(Boolean).join(`/`);successResponse(t,200,TemplateGetSuccessSchema,{template:{name:g,folder:j,scope:F,path:H,frontmatter:L,body:B}},{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}),Jc=withValidation(TemplatePutRequestSchema,async(e,t,s)=>{try{let e=s.name;if(!Rc(e,t,`template-put`))return;let g=zc(s.target,t,`template-put`);if(g===null)return;let S=Ic(g===`user`?``:s.folder,t,`folder`,`template-put`);if(!S)return;let w={projectDir:S.resolvedContentDir,folder:S.folderRel,name:e,body:typeof s.body==`string`?s.body:``,frontmatter:Bc(s.frontmatter)};g!==void 0&&(w.target=g);let E=applyTemplateWrite(w);if(!E.ok){let e=E.error.code===`WRITE_ERROR`||E.error.code===`BAD_PROJECT_DIR`||E.error.code===`USER_HOME_UNAVAILABLE`?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:E.error.code,cause:Error(E.error.message)});return}successResponse(t,200,TemplatePutSuccessSchema,{path:E.path,created:E.created,warnings:E.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`}),Yc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Rc(g,t,`template-delete`))return;let S=zc(s.searchParams.get(`target`),t,`template-delete`);if(S===null)return;let w=Ic(S===`user`?``:s.searchParams.get(`folder`)??``,t,`folder`,`template-delete`);if(!w)return;let E={projectDir:w.resolvedContentDir,folder:w.folderRel,name:g};S!==void 0&&(E.target=S);let D=applyTemplateDelete(E);if(!D.ok){let e=D.error.code===`WRITE_ERROR`||D.error.code===`UNLINK_FAILED`||D.error.code===`BAD_PROJECT_DIR`||D.error.code===`USER_HOME_UNAVAILABLE`?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}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});function Xc(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 Zc(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 Qc(e){return e===`autocomplete`||e===`full_text`||e===`omnibar`?e:`omnibar`}function $c(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}async function nl(){let e=[];for(let[t,s]of w()){if(isSystemDoc(t)||isConfigDoc(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,...Xc(e)]}function il(){return[...w()].filter(([e])=>!isSystemDoc(e)&&!isConfigDoc(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 al(){let e=`${g}${se??``}`,t=il(),s=workspaceSearchCaches.get(e);if(s?.fingerprint===t&&s.corpus)return s.corpus;if(s?.fingerprint===t&&s.pending)return s.pending;let S=nl().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 cl(){if(process.env.NODE_ENV!==`test`)for(let e of[0,1e3,3e3])setTimeout(()=>{al().catch(e=>{console.warn(`[search] Failed to prewarm workspace search cache:`,e)})},e)}cl();async function ll(e,t){if(e.method===`GET`)return ul(e,t);if(e.method===`POST`)return dl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`search`,extraHeaders:{Allow:`GET, POST`}})}let ul=withValidation(EmptyRequestSchema,async(e,t)=>{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`limit`),S=s.searchParams.get(`query`)??``,w=Qc(s.searchParams.get(`intent`)),E=$c(s.searchParams.get(`scope`)??s.searchParams.get(`scopes`)),D=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{let e=performance.now();successResponse(t,200,SearchSuccessSchema,{query:S,intent:w,results:searchWorkspaceCorpus(await al(),S,{intent:w,scopes:E,limit:D}).map(e=>({kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?Zc(e.document.content,S):void 0})),elapsedMs:Math.max(0,performance.now()-e)},{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}),dl=withValidation(SearchRequestSchema,async(e,t,s)=>{let g=typeof s.query==`string`?s.query:``,S=Qc(s.intent),w=$c(s.scopes??s.scope),E=typeof s.limit==`number`?s.limit:void 0;if(g.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-post`});return}try{let e=performance.now();successResponse(t,200,SearchSuccessSchema,{query:g,intent:S,results:searchWorkspaceCorpus(await al(),g,{intent:S,scopes:w,limit:E}).map(e=>({kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?Zc(e.document.content,g):void 0})),elapsedMs:Math.max(0,performance.now()-e)},{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`}),fl=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 pl(e,t){if(checkLocalOpSecurity(e,t,{handler:`spawn-cursor`}))try{await handleSpawnCursor(e,t,{contentDir:g,platform:process.platform})}catch(e){t.headersSent||(log$2.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 ml={"/api/asset":Hi,"/api/document":Ht,"/api/documents":Ut,"/api/backlinks":Wt,"/api/backlink-counts":Kt,"/api/forward-links":$t,"/api/link-graph":en,"/api/dead-links":Fr,"/api/orphans":jr,"/api/hubs":Mr,"/api/tags":Pc,"/api/pages":xs,"/api/folder-config":Vc,"/api/template":Wc,"/api/search":ll,"/api/suggest-links":Cs,"/api/page-headings":Zi,"/api/create-page":Yi,"/api/create-folder":Xi,"/api/rename-path":ka,"/api/delete-path":_s,"/api/upload":Ts,"/api/agent-write":Bt,"/api/agent-write-md":Vt,"/api/agent-patch":Ir,"/api/agent-undo":Lr,"/api/agent-activity":zr,"/api/agent-burst-diff":Br,"/api/save-version":Ur,"/api/history":Wr,"/api/diff":Kr,"/api/rollback":qr,"/api/metrics/reconciliation":Jr,"/api/metrics/parse-health":Yr,"/api/metrics/agent-presence":Qr,"/api/server-info":Xr,"/api/principal":Zr,"/api/rescue":Gi,"/api/workspace":ji,"/api/sync/status":Cc,"/api/sync/trigger":wc,"/api/sync/conflicts":Tc,"/api/sync/conflict-content":Dc,"/api/sync/resolve-conflict":Ec,"/api/sync/abort-merge":Nc,"/api/local-op/clone":Ps,"/api/local-op/open":ec,"/api/local-op/auth/login":sc,"/api/local-op/auth/status":uc,"/api/local-op/auth/repos":fc,"/api/local-op/auth/signout":hc,"/api/local-op/auth/pat":_c,"/api/local-op/auth/identity":yc,"/api/local-op/auth/set-identity":Sc,"/api/installed-agents":Mc,"/api/spawn-cursor":pl,"/api/install-skill":jc,"/api/skill/install-state":fl,"/api/seed/plan":Oc,"/api/seed/apply":kc,"/api/seed/packs":Ac};O&&(ml[`/api/test-reset`]=Vr,ml[`/api/test-rescan-backlinks`]=Hr);let hl=new Set([`/api/upload`,`/api/create-page`,`/api/create-folder`,`/api/rename-path`,`/api/delete-path`,`/api/agent-write`,`/api/agent-write-md`,`/api/agent-patch`,`/api/agent-undo`,`/api/save-version`,`/api/rollback`,`/api/sync/trigger`,`/api/sync/resolve-conflict`,`/api/sync/abort-merge`,`/api/test-reset`,`/api/test-rescan-backlinks`,`/api/install-skill`,`/api/folder-config`,`/api/template`,`/api/seed/apply`]),gl=[`/api/local-op/`];return{priority:100,async onRequest({request:e,response:t}){let s=e.url?.split(`?`)[0];if(!s)return;if(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`)),e.method===`OPTIONS`){t.writeHead(204),t.end();return}}if(hl.has(s)||gl.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(!s.startsWith(`/api/`))return;let g=propagation.extract(context.active(),e.headers),S=e.method??`GET`,w=s;s.startsWith(`/api/rescue/`)?w=`/api/rescue/:docName`:s.startsWith(`/api/history/`)?w=`/api/history/:sha`:s.startsWith(`/api/tags/`)?w=`/api/tags/:name`:ml[s]||(w=`/api/*`);let E=getTracer(),D=Date.now();await context.with(g,()=>E.startActiveSpan(`HTTP ${S} ${w}`,{kind:SpanKind.SERVER,attributes:{[ATTR_HTTP_REQUEST_METHOD]:S,[ATTR_HTTP_ROUTE]:w,[ATTR_URL_PATH]:s,[ATTR_URL_SCHEME]:`http`,[ATTR_USER_AGENT_ORIGINAL]:e.headers[`user-agent`]??``}},async g=>{try{let w=ml[s],E=!1;if(w)E=!0,await w(e,t);else if(s.startsWith(`/api/rescue/`)){let g=decodeURIComponent(s.slice(12));g&&(E=!0,await Ki(e,t,g))}else if(s.startsWith(`/api/history/`)){let g=decodeURIComponent(s.slice(13));g&&(E=!0,await Gr(e,t,g))}else if(s.startsWith(`/api/tags/`)){let g=s.slice(10);g&&(E=!0,await Fc(e,t,g))}E||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`api-dispatch`,detail:`No handler for ${S} ${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:w,cause:e}),e}finally{g.end();let e=(Date.now()-D)/1e3;httpDurationHist().record(e,{[ATTR_HTTP_REQUEST_METHOD]:S,[ATTR_HTTP_ROUTE]:w,[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 seedBasenameIndex(e){let t=e.contentDir,s=new Set;function g(S){let w;try{w=readdirSync(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=lstatSync(w)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`lstat-failed`,s,w);continue}if(O.isSymbolicLink()){let S;try{S=realpathSync(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=statSync(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()?g(S):E.isFile()&&isSupportedAssetFile(w,ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D);continue}if(O.isDirectory()){if(s.has(O.ino))continue;s.add(O.ino),g(w);continue}O.isFile()&&isSupportedAssetFile(w,ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D)}}g(t)}const HocuspocusAuthTokenSchema=object$1({principalId:string().optional(),tabSessionId:string().optional(),expectedServerInstanceId:string().optional(),expectedBranch:string().optional()}).loose(),HOCUSPOCUS_AUTH_REJECTION_REASONS=[`server-instance-mismatch`,`branch-mismatch`,`rename-redirect`,`doc-deleted`];function isHocuspocusAuthRejectionReason(e){return HOCUSPOCUS_AUTH_REJECTION_REASONS.includes(e)}const WIRE_PAYLOAD_SEPARATOR=`:`;function formatAuthRejectionWire(e,t){return typeof t!=`string`||t.length===0?e:`${e}${WIRE_PAYLOAD_SEPARATOR}${t}`}function parseAuthRejectionWire(e){if(e.length===0)return{kind:null,payload:void 0};let t=e.indexOf(WIRE_PAYLOAD_SEPARATOR),s=t===-1?e:e.slice(0,t);if(!isHocuspocusAuthRejectionReason(s))return{kind:null,payload:void 0};if(t===-1)return{kind:s,payload:void 0};let g=e.slice(t+1);return{kind:s,payload:g.length>0?g:void 0}}var HocuspocusAuthRejection=class extends Error{kind;payload;reason;constructor(e,t,s){super(t),this.name=`HocuspocusAuthRejection`,this.kind=e,this.payload=typeof s==`string`&&s.length>0?s:void 0,this.reason=formatAuthRejectionWire(e,this.payload)}};function parseHocuspocusAuthToken(e){if(typeof e!=`string`||e.length===0)return;let t;try{t=JSON.parse(e)}catch{return}let s=HocuspocusAuthTokenSchema.safeParse(t);return s.success?s.data:void 0}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())}}}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 (OK) — collaborative markdown via MCP
|
|
1922
|
+
`).map(e=>e.trim()).filter(Boolean),D=null;for(let e=E.length-1;e>=0;e--)try{D=JSON.parse(E[e]);break}catch{}D===null?successResponse(t,200,LocalOpAuthPatSuccessSchema,{},{handler:gc}):successResponse(t,200,LocalOpAuthPatSuccessSchema,D,{handler:gc})}catch(e){errorResponse(t,500,`urn:ok:error:auth-failed`,`Auth pat failed.`,{handler:gc,cause:e})}finally{_e.release(ac)}},{handler:gc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:gc})}),vc=`local-op-auth-identity`;async function yc(e,t){if(checkLocalOpSecurity(e,t,{handler:vc})){if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:vc,extraHeaders:{Allow:`GET`}});return}if(!se){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:vc});return}try{successResponse(t,200,LocalOpAuthIdentitySuccessSchema,{identity:await resolveGitIdentity(se)},{handler:vc})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Identity resolution failed.`,{handler:vc,cause:e})}}}let bc=`/api/local-op/auth/set-identity`,xc=`local-op-auth-set-identity`,Sc=withValidation(LocalOpAuthSetIdentityRequestSchema,async(e,t,s)=>{let g=s.name.trim(),S=s.email.trim();if(!se){errorResponse(t,503,`urn:ok:error:no-project-dir`,`No project directory configured.`,{handler:xc});return}if(!_e.tryAcquire(bc)){errorResponse(t,429,`urn:ok:error:concurrent-operation`,`A set-identity operation is already in progress.`,{handler:xc,extraHeaders:{"Retry-After":`5`}});return}try{writeGitIdentity(se,g,S),ae?.()?.refreshIdentity().catch(()=>{}),successResponse(t,200,LocalOpAuthEmptySuccessSchema,{},{handler:xc})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Set-identity failed.`,{handler:xc,cause:e})}finally{_e.release(bc)}},{handler:xc,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:xc})});async function Cc(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=ae?.();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},{handler:`sync-status`});return}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 wc=withValidation(SyncTriggerRequestSchema,async(e,t,s)=>{let g=ae?.();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`})?ae?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-trigger`}),!1):!1});async function Tc(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=ae?.();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 Ec=withValidation(SyncResolveConflictRequestSchema,async(e,t,s)=>{let g=ae?.();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})}},{handler:`sync-resolve-conflict`,method:`POST`,preBodyGate:(e,t)=>checkLocalOpSecurity(e,t,{handler:`sync-resolve-conflict`})?ae?.()?!0:(errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-resolve-conflict`}),!1):!1});async function Dc(e,t){if(!checkLocalOpSecurity(e,t,{handler:`sync-conflict-content`}))return;if(e.method!==`GET`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-conflict-content`,extraHeaders:{Allow:`GET`}});return}if(!se){errorResponse(t,503,`urn:ok:error:project-repo-not-configured`,`Project repo not configured.`,{handler:`sync-conflict-content`});return}let s=new URL(e.url??`/`,`http://${e.headers.host??`localhost`}`).searchParams.get(`file`);if(!s){errorResponse(t,400,`urn:ok:error:invalid-request`,`Missing required query param: file.`,{handler:`sync-conflict-content`});return}if(s.includes(`..`)||s.startsWith(`/`)){errorResponse(t,400,`urn:ok:error:invalid-request`,`Invalid file path.`,{handler:`sync-conflict-content`});return}let g=esm_default({baseDir:se,timeout:{block:15e3}});async function S(e){try{return await g.raw([`show`,`:${e}:${s}`])}catch{return``}}try{let[e,g,w]=await Promise.all([S(1),S(2),S(3)]);successResponse(t,200,SyncConflictContentSuccessSchema,{file:s,base:e,ours:g,theirs:w},{handler:`sync-conflict-content`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to read conflict content.`,{handler:`sync-conflict-content`,cause:e})}}async function Oc(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}let D=s.searchParams.get(`includePersonalTemplates`)===`true`;try{let e=await planSeed({projectDir:g,rootDir:S,packId:E});successResponse(t,200,SeedPlanSuccessSchema,{plan:D?{...e,personalTemplates:planPersonalTemplates()}: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 kc=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,D=E.packId,O=coercePackId(D);if(typeof D==`string`&&D.length>0&&O===void 0){errorResponse(t,400,`urn:ok:error:invalid-request`,`Unknown packId.`,{handler:`seed-apply`,detail:`Pack id "${D}" is not registered.`});return}let k=E.includePersonalTemplates===!0;try{let e=await applySeed(w,{projectDir:g,packId:O}),s=k?writePersonalTemplates():void 0;successResponse(t,200,SeedApplySuccessSchema,s?{result:e,personalTemplates:s}:{result:e},{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 Ac(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 jc=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 Mc(e,t){if(checkLocalOpSecurity(e,t,{handler:`installed-agents`}))try{await handleInstalledAgents(e,t,Me.probeAll)}catch(e){t.headersSent||(log$2.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}))}}async function Nc(e,t){if(!checkLocalOpSecurity(e,t,{handler:`sync-abort-merge`}))return;if(e.method!==`POST`){errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`sync-abort-merge`,extraHeaders:{Allow:`POST`}});return}let s=ae?.();if(!s){errorResponse(t,503,`urn:ok:error:sync-not-active`,`Sync engine not active.`,{handler:`sync-abort-merge`});return}try{await s.abortMerge(),successResponse(t,200,SyncAbortMergeSuccessSchema,{},{handler:`sync-abort-merge`})}catch(e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`Failed to abort merge.`,{handler:`sync-abort-merge`,cause:e})}}let Pc=withValidation(EmptyRequestSchema,async(e,t)=>{if(!J){errorResponse(t,503,`urn:ok:error:tag-index-not-configured`,`Tag index not configured.`,{handler:`tags-list`});return}try{successResponse(t,200,TagsListSuccessSchema,{tags:J.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 Fc(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(!J){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=J.getDocsForTagWithMatches(g).map(({docName:e,matchingTags:t})=>({docName:e,title:Ie(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 Ic(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 Lc=/^[A-Za-z0-9_-]+$/;function Rc(e,t,s=`template`){return!e||!Lc.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 zc(e,t,s=`template`){if(!(e==null||e===``))return e===`project`||e===`user`?e:(errorResponse(t,400,`urn:ok:error:invalid-request`,`target must be "project" or "user", got: ${JSON.stringify(e)}`,{handler:s}),null)}function Bc(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 Vc(e,t){if(e.method===`GET`)return Hc(e,t);if(e.method===`PUT`)return Uc(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`folder-config`,extraHeaders:{Allow:`GET, PUT`}})}let Hc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=Ic(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(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}),Uc=withValidation(FolderConfigPutRequestSchema,async(e,t,s)=>{try{let e=Ic(s.path,t,`path`,`folder-config-put`);if(!e)return;let g=e.folderRel===``?`**`:`${e.folderRel}/**`,S=applyNestedFolderRulesUpsert({projectDir:e.resolvedContentDir,rules:[{match:g,frontmatter:Bc(s.frontmatter)}]});if(!S.ok){let e=S.error.code===`WRITE_ERROR`||S.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 folder config.`:`Invalid folder config request.`,{handler:`folder-config-put`,detail:S.error.code,cause:Error(S.error.message)});return}successResponse(t,200,FolderConfigPutSuccessSchema,{applied:S.applied},{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`});async function Wc(e,t){if(e.method===`GET`)return qc(e,t);if(e.method===`PUT`)return Jc(e,t);if(e.method===`DELETE`)return Yc(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`template`,extraHeaders:{Allow:`GET, PUT, DELETE`}})}let Gc=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/,Kc=e=>{let t=e.match(Gc),s={},g=e;if(t){try{let e=(0,import_dist$1.parse)(t[1]??``);e&&typeof e==`object`&&!Array.isArray(e)&&(s=e)}catch{}g=e.slice(t[0].length)}return{frontmatter:s,body:g}},qc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Rc(g,t,`template-get`))return;let S=zc(s.searchParams.get(`target`),t,`template-get`);if(S===null)return;if(S===`user`){let e=getUserHome();if(!e){errorResponse(t,500,`urn:ok:error:internal-server-error`,`User home directory could not be resolved.`,{handler:`template-get`});return}let s=resolve(e,`.ok`,`templates`,`${g}.md`);if(!existsSync(s)){errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-get`,detail:`User template "${g}" not found at ~/.ok/templates/${g}.md`});return}let{frontmatter:S,body:w}=Kc(await readFile$1(s,`utf-8`));successResponse(t,200,TemplateGetSuccessSchema,{template:{name:g,folder:`~/.ok`,scope:`user`,path:`~/.ok/templates/${g}.md`,frontmatter:S,body:w}},{handler:`template-get`});return}let w=Ic(s.searchParams.get(`folder`)??``,t,`folder`,`template-get`);if(!w)return;let{folderRel:E,resolvedContentDir:D}=w,O=E===``?[]:E.split(`/`),k=null,j=null,F=null;for(let e=O.length;e>=0;e--){let t=e===0?``:O.slice(0,e).join(`/`),s=t===``?D:resolve(D,t);if(s!==D&&!s.startsWith(`${D}${sep}`))continue;let S=resolve(s,`.ok`,`templates`,`${g}.md`);if(existsSync(S)){k=S,j=t,F=e===O.length?`local`:`inherited`;break}}if(!k||j===null||F===null){errorResponse(t,404,`urn:ok:error:template-not-found`,`Template not found.`,{handler:`template-get`,detail:`Template "${g}" not found for folder "${E||`.`}". Walked leaf → root.`});return}let{frontmatter:L,body:B}=Kc(await readFile$1(k,`utf-8`)),H=relative(D,k).split(/[\\/]/).filter(Boolean).join(`/`);successResponse(t,200,TemplateGetSuccessSchema,{template:{name:g,folder:j,scope:F,path:H,frontmatter:L,body:B}},{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}),Jc=withValidation(TemplatePutRequestSchema,async(e,t,s)=>{try{let e=s.name;if(!Rc(e,t,`template-put`))return;let g=zc(s.target,t,`template-put`);if(g===null)return;let S=Ic(g===`user`?``:s.folder,t,`folder`,`template-put`);if(!S)return;let w={projectDir:S.resolvedContentDir,folder:S.folderRel,name:e,body:typeof s.body==`string`?s.body:``,frontmatter:Bc(s.frontmatter)};g!==void 0&&(w.target=g);let E=applyTemplateWrite(w);if(!E.ok){let e=E.error.code===`WRITE_ERROR`||E.error.code===`BAD_PROJECT_DIR`||E.error.code===`USER_HOME_UNAVAILABLE`?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:E.error.code,cause:Error(E.error.message)});return}successResponse(t,200,TemplatePutSuccessSchema,{path:E.path,created:E.created,warnings:E.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`}),Yc=withValidation(EmptyRequestSchema,async(e,t)=>{try{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`name`)??``;if(!Rc(g,t,`template-delete`))return;let S=zc(s.searchParams.get(`target`),t,`template-delete`);if(S===null)return;let w=Ic(S===`user`?``:s.searchParams.get(`folder`)??``,t,`folder`,`template-delete`);if(!w)return;let E={projectDir:w.resolvedContentDir,folder:w.folderRel,name:g};S!==void 0&&(E.target=S);let D=applyTemplateDelete(E);if(!D.ok){let e=D.error.code===`WRITE_ERROR`||D.error.code===`UNLINK_FAILED`||D.error.code===`BAD_PROJECT_DIR`||D.error.code===`USER_HOME_UNAVAILABLE`?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}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});function Xc(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 Zc(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 Qc(e){return e===`autocomplete`||e===`full_text`||e===`omnibar`?e:`omnibar`}function $c(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}async function nl(){let e=[];for(let[t,s]of w()){if(isSystemDoc(t)||isConfigDoc(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,...Xc(e)]}function il(){return[...w()].filter(([e])=>!isSystemDoc(e)&&!isConfigDoc(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 al(){let e=`${g}${se??``}`,t=il(),s=workspaceSearchCaches.get(e);if(s?.fingerprint===t&&s.corpus)return s.corpus;if(s?.fingerprint===t&&s.pending)return s.pending;let S=nl().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 cl(){if(process.env.NODE_ENV!==`test`)for(let e of[0,1e3,3e3])setTimeout(()=>{al().catch(e=>{console.warn(`[search] Failed to prewarm workspace search cache:`,e)})},e)}cl();async function ll(e,t){if(e.method===`GET`)return ul(e,t);if(e.method===`POST`)return dl(e,t);errorResponse(t,405,`urn:ok:error:method-not-allowed`,`Method not allowed.`,{handler:`search`,extraHeaders:{Allow:`GET, POST`}})}let ul=withValidation(EmptyRequestSchema,async(e,t)=>{let s=new URL(e.url??``,`http://localhost`),g=s.searchParams.get(`limit`),S=s.searchParams.get(`query`)??``,w=Qc(s.searchParams.get(`intent`)),E=$c(s.searchParams.get(`scope`)??s.searchParams.get(`scopes`)),D=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{let e=performance.now();successResponse(t,200,SearchSuccessSchema,{query:S,intent:w,results:searchWorkspaceCorpus(await al(),S,{intent:w,scopes:E,limit:D}).map(e=>({kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?Zc(e.document.content,S):void 0})),elapsedMs:Math.max(0,performance.now()-e)},{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}),dl=withValidation(SearchRequestSchema,async(e,t,s)=>{let g=typeof s.query==`string`?s.query:``,S=Qc(s.intent),w=$c(s.scopes??s.scope),E=typeof s.limit==`number`?s.limit:void 0;if(g.length>200){errorResponse(t,400,`urn:ok:error:invalid-request`,`Query is too long (max 200 chars).`,{handler:`search-post`});return}try{let e=performance.now();successResponse(t,200,SearchSuccessSchema,{query:g,intent:S,results:searchWorkspaceCorpus(await al(),g,{intent:S,scopes:w,limit:E}).map(e=>({kind:e.document.kind,path:e.document.path,title:e.document.title,score:e.score,signals:e.signals,snippet:e.document.kind===`page`?Zc(e.document.content,g):void 0})),elapsedMs:Math.max(0,performance.now()-e)},{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`}),fl=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 pl(e,t){if(checkLocalOpSecurity(e,t,{handler:`handoff`}))try{await handleHandoffDispatch(e,t,{contentDir:g,platform:process.platform})}catch(e){t.headersSent||(log$2.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 ml(e,t){if(checkLocalOpSecurity(e,t,{handler:`spawn-cursor`}))try{await handleSpawnCursor(e,t,{contentDir:g,platform:process.platform})}catch(e){t.headersSent||(log$2.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 hl={"/api/asset":Hi,"/api/document":Ht,"/api/documents":Ut,"/api/backlinks":Wt,"/api/backlink-counts":Kt,"/api/forward-links":$t,"/api/link-graph":en,"/api/dead-links":Fr,"/api/orphans":jr,"/api/hubs":Mr,"/api/tags":Pc,"/api/pages":xs,"/api/folder-config":Vc,"/api/template":Wc,"/api/search":ll,"/api/suggest-links":Cs,"/api/page-headings":Zi,"/api/create-page":Yi,"/api/create-folder":Xi,"/api/rename-path":ka,"/api/delete-path":_s,"/api/upload":Ts,"/api/agent-write":Bt,"/api/agent-write-md":Vt,"/api/agent-patch":Ir,"/api/agent-undo":Lr,"/api/agent-activity":zr,"/api/agent-burst-diff":Br,"/api/save-version":Ur,"/api/history":Wr,"/api/diff":Kr,"/api/rollback":qr,"/api/metrics/reconciliation":Jr,"/api/metrics/parse-health":Yr,"/api/metrics/agent-presence":Qr,"/api/server-info":Xr,"/api/principal":Zr,"/api/rescue":Gi,"/api/workspace":ji,"/api/sync/status":Cc,"/api/sync/trigger":wc,"/api/sync/conflicts":Tc,"/api/sync/conflict-content":Dc,"/api/sync/resolve-conflict":Ec,"/api/sync/abort-merge":Nc,"/api/local-op/clone":Ps,"/api/local-op/open":ec,"/api/local-op/auth/login":sc,"/api/local-op/auth/status":uc,"/api/local-op/auth/repos":fc,"/api/local-op/auth/signout":hc,"/api/local-op/auth/pat":_c,"/api/local-op/auth/identity":yc,"/api/local-op/auth/set-identity":Sc,"/api/installed-agents":Mc,"/api/spawn-cursor":ml,"/api/handoff":pl,"/api/install-skill":jc,"/api/skill/install-state":fl,"/api/seed/plan":Oc,"/api/seed/apply":kc,"/api/seed/packs":Ac};O&&(hl[`/api/test-reset`]=Vr,hl[`/api/test-rescan-backlinks`]=Hr);let gl=new Set([`/api/upload`,`/api/create-page`,`/api/create-folder`,`/api/rename-path`,`/api/delete-path`,`/api/agent-write`,`/api/agent-write-md`,`/api/agent-patch`,`/api/agent-undo`,`/api/save-version`,`/api/rollback`,`/api/sync/trigger`,`/api/sync/resolve-conflict`,`/api/sync/abort-merge`,`/api/test-reset`,`/api/test-rescan-backlinks`,`/api/install-skill`,`/api/folder-config`,`/api/template`,`/api/seed/apply`]),_l=[`/api/local-op/`];return{priority:100,async onRequest({request:e,response:t}){let s=e.url?.split(`?`)[0];if(!s)return;if(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`)),e.method===`OPTIONS`){t.writeHead(204),t.end();return}}if(gl.has(s)||_l.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(!s.startsWith(`/api/`))return;let g=propagation.extract(context.active(),e.headers),S=e.method??`GET`,w=s;s.startsWith(`/api/rescue/`)?w=`/api/rescue/:docName`:s.startsWith(`/api/history/`)?w=`/api/history/:sha`:s.startsWith(`/api/tags/`)?w=`/api/tags/:name`:hl[s]||(w=`/api/*`);let E=getTracer(),D=Date.now();await context.with(g,()=>E.startActiveSpan(`HTTP ${S} ${w}`,{kind:SpanKind.SERVER,attributes:{[ATTR_HTTP_REQUEST_METHOD]:S,[ATTR_HTTP_ROUTE]:w,[ATTR_URL_PATH]:s,[ATTR_URL_SCHEME]:`http`,[ATTR_USER_AGENT_ORIGINAL]:e.headers[`user-agent`]??``}},async g=>{try{let w=hl[s],E=!1;if(w)E=!0,await w(e,t);else if(s.startsWith(`/api/rescue/`)){let g=decodeURIComponent(s.slice(12));g&&(E=!0,await Ki(e,t,g))}else if(s.startsWith(`/api/history/`)){let g=decodeURIComponent(s.slice(13));g&&(E=!0,await Gr(e,t,g))}else if(s.startsWith(`/api/tags/`)){let g=s.slice(10);g&&(E=!0,await Fc(e,t,g))}E||errorResponse(t,404,`urn:ok:error:not-found`,`API endpoint not found.`,{handler:`api-dispatch`,detail:`No handler for ${S} ${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:w,cause:e}),e}finally{g.end();let e=(Date.now()-D)/1e3;httpDurationHist().record(e,{[ATTR_HTTP_REQUEST_METHOD]:S,[ATTR_HTTP_ROUTE]:w,[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 seedBasenameIndex(e){let t=e.contentDir,s=new Set;function g(S){let w;try{w=readdirSync(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=lstatSync(w)}catch(t){let s=errnoCode(t);s!==`ENOENT`&&e.onSkip?.(`lstat-failed`,s,w);continue}if(O.isSymbolicLink()){let S;try{S=realpathSync(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=statSync(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()?g(S):E.isFile()&&isSupportedAssetFile(w,ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D);continue}if(O.isDirectory()){if(s.has(O.ino))continue;s.add(O.ino),g(w);continue}O.isFile()&&isSupportedAssetFile(w,ASSET_EXTENSIONS)&&!e.contentFilter?.isExcluded(D)&&e.basenameIndex.add(D)}}g(t)}const HocuspocusAuthTokenSchema=object$1({principalId:string().optional(),tabSessionId:string().optional(),expectedServerInstanceId:string().optional(),expectedBranch:string().optional()}).loose(),HOCUSPOCUS_AUTH_REJECTION_REASONS=[`server-instance-mismatch`,`branch-mismatch`,`rename-redirect`,`doc-deleted`];function isHocuspocusAuthRejectionReason(e){return HOCUSPOCUS_AUTH_REJECTION_REASONS.includes(e)}const WIRE_PAYLOAD_SEPARATOR=`:`;function formatAuthRejectionWire(e,t){return typeof t!=`string`||t.length===0?e:`${e}${WIRE_PAYLOAD_SEPARATOR}${t}`}function parseAuthRejectionWire(e){if(e.length===0)return{kind:null,payload:void 0};let t=e.indexOf(WIRE_PAYLOAD_SEPARATOR),s=t===-1?e:e.slice(0,t);if(!isHocuspocusAuthRejectionReason(s))return{kind:null,payload:void 0};if(t===-1)return{kind:s,payload:void 0};let g=e.slice(t+1);return{kind:s,payload:g.length>0?g:void 0}}var HocuspocusAuthRejection=class extends Error{kind;payload;reason;constructor(e,t,s){super(t),this.name=`HocuspocusAuthRejection`,this.kind=e,this.payload=typeof s==`string`&&s.length>0?s:void 0,this.reason=formatAuthRejectionWire(e,this.payload)}};function parseHocuspocusAuthToken(e){if(typeof e!=`string`||e.length===0)return;let t;try{t=JSON.parse(e)}catch{return}let s=HocuspocusAuthTokenSchema.safeParse(t);return s.success?s.data:void 0}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())}}}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 (OK) — collaborative markdown via MCP
|
|
1923
1923
|
|
|
1924
1924
|
**STOP** *(when \`.ok/\` exists)* — do NOT use native \`Read\`, \`Grep\`, \`Glob\`, \`Edit\`, \`Write\` on in-scope \`.md\` / \`.mdx\`. Reads: \`exec\` / \`read_document\` / \`search\` / \`grep\`. Writes: \`write_document\` / \`edit_document\` ONLY.
|
|
1925
1925
|
|
|
@@ -2581,4 +2581,4 @@ In headless mode, write the recap into the research article's "Further reading"
|
|
|
2581
2581
|
`).split(`
|
|
2582
2582
|
`),s=[],g=!1,S=``;for(let e of t){let t=/^\s{0,3}([`~]{3,})/.exec(e);if(t){g?RegExp(`^\\s{0,3}${S[0]==="`"?"`":`~`}{${S.length},}\\s*$`).test(e)&&(g=!1,S=``):(g=!0,S=t[1]);continue}if(g)continue;let w=stripInlineCodeSpans(e);for(TAG_VALUE_RE.lastIndex=0;;){let e=TAG_VALUE_RE.exec(w);if(e===null)break;let t=e[2];t&&s.push(t)}}return s}var TagIndex=class{contentDir;contentFilter;state=createEmptyState();constructor(e){this.contentDir=e.contentDir,this.contentFilter=e.contentFilter}updateDocumentFromMarkdown(e,t){if(!(isSystemDoc(e)||isConfigDoc(e)))try{let{frontmatter:s,body:g}=stripFrontmatter(t),S=extractFrontmatterTags(s?unwrapFrontmatterFences(s):``),w=extractInlineTagsFromBody(g),E=new Set([...S,...w]),D=new Set;for(let e of E)for(let t of expandTagToHierarchy(e))D.add(t);this.applyDocSnapshot(e,E,D)}catch(t){console.warn(`[tag-index] Failed to scan ${e} for tag extraction:`,t),this.deleteDocument(e)}}deleteDocument(e){if(isSystemDoc(e)||isConfigDoc(e))return;let t=this.state.byDoc.get(e);if(t){for(let s of t){let t=this.state.byTag.get(s);t&&(t.delete(e),t.size===0&&this.state.byTag.delete(s))}this.state.byDoc.delete(e),this.state.byDocLiteral.delete(e)}}renameDocument(e,t,s){this.deleteDocument(e),this.updateDocumentFromMarkdown(t,s)}getDocsForTag(e){let t=this.state.byTag.get(e);return t?[...t].sort((e,t)=>e.localeCompare(t)):[]}getDocsForTagWithMatches(e){let t=this.state.byTag.get(e);if(!t)return[];let s=[];for(let g of t){let t=this.state.byDocLiteral.get(g);if(!t)continue;let S=tagsMatchingPrefix(t,e);s.push({docName:g,matchingTags:[...S].sort((e,t)=>e.localeCompare(t))})}return s.sort((e,t)=>e.docName.localeCompare(t.docName))}getAllTags(){let e=[...this.state.byTag.entries()],t=e.map(([e])=>e),s=new Set;for(let e of t){let t=e.indexOf(`/`);t>0&&s.add(e.slice(0,t));let g=t;for(;g>0;)s.add(e.slice(0,g)),g=e.indexOf(`/`,g+1)}return e.map(([e,t])=>({name:e,count:t.size,isLeaf:!s.has(e)})).sort((e,t)=>e.name.localeCompare(t.name))}init(){if(this.state=createEmptyState(),!existsSync(this.contentDir))return;let e=this.listDocsWithPaths();for(let{docName:t,filePath:s}of e)try{let e=readFileSync(s,`utf-8`);this.updateDocumentFromMarkdown(t,e)}catch(e){console.warn(`[tag-index] Failed to read ${t} during init:`,e)}}applyDocSnapshot(e,t,s){let g=this.state.byDoc.get(e)??new Set;for(let t of g){if(s.has(t))continue;let g=this.state.byTag.get(t);g&&(g.delete(e),g.size===0&&this.state.byTag.delete(t))}for(let t of s){let s=this.state.byTag.get(t);s||(s=new Set,this.state.byTag.set(t,s)),s.add(e)}s.size===0?(this.state.byDoc.delete(e),this.state.byDocLiteral.delete(e)):(this.state.byDoc.set(e,s),this.state.byDocLiteral.set(e,t))}listDocsWithPaths(){let e=[];this.walkContentDir(this.contentDir,e),e.sort((e,t)=>e.docName===t.docName?t.filePath.localeCompare(e.filePath):e.docName.localeCompare(t.docName));let t=new Set;return e.filter(({docName:e})=>t.has(e)?!1:(t.add(e),!0))}walkContentDir(e,t){let s;try{s=readdirSync(e,{withFileTypes:!0})}catch(t){console.warn(`[tag-index] Failed to read directory ${e}:`,t);return}for(let g of s){let s=join(e,g.name);if(g.isDirectory()){let e=relative(this.contentDir,s);if(this.contentFilter&&e&&this.contentFilter.isDirExcluded(e))continue;this.walkContentDir(s,t);continue}if(!g.isFile()||!isSupportedDocFile(g.name))continue;let S=relative(this.contentDir,s);this.contentFilter?.isExcluded(S)||t.push({docName:stripDocExtension(S),filePath:s})}}};const PARK_SNAPSHOT_ORIGIN=(()=>{let e=Object.freeze({origin:`park-snapshot`,paired:!0});return Object.freeze({source:`local`,skipStoreHooks:!1,context:e})})();function createServer$1(e){let{contentDir:t,projectDir:s=t,quiet:g=!0,debounce:S=2e3,maxDebounce:w=1e4,gitEnabled:E=!0,commitDebounceMs:D=3e4,wipRef:O=`refs/wip/main`,configHomedirOverride:k,enableTestRoutes:j=!1,shadowRepo:F,contentRoot:L,destroyTimeoutMs:B=1e4,localOpCliArgs:H,skipStateManifestCheck:q=!1}=e,J=getLogger(`server`);function Y(){let e=readConfigSafely({absPath:resolveConfigPath(`project-local`,s),sideline:!1,warn:e=>J.warn({message:e},`[config] could not read project-local config`)}),t=e.value.autoSync?.enabled;return t==null?(e.valid||J.warn({},`[config] project-local autoSync.enabled unavailable (config invalid) — falling back to project config`),readConfigSafely({absPath:resolveConfigPath(`project`,s),sideline:!1,warn:e=>J.warn({message:e},`[config] could not read project config`)}).value.autoSync?.enabled===!0):t===!0}initTelemetry();let ee=randomUUID(),te=getLocalDir(s);if(acquireServerLock(te,{port:e.port??0,worktreeRoot:s,kind:e.lockKind??`interactive`,capabilities:[`http`,`ws`]}),!q)try{assertCompatibleStateManifest({lockDir:te,shadowRepoDir:resolveShadowDir(s)})}catch(e){throw releaseServerLock(te),e}let ne=createBasenameIndex(),ae=(e,t)=>ne.resolveEmbed(e,t),oe=(e,s)=>{let g=ne.resolveEmbed(e,s);if(!g&&e.includes(`/`)&&(g=e.replace(/^\.?\//,``)),!g)return null;let S=resolve(t,g),w=resolve(t);if(S!==w&&!S.startsWith(`${w}/`))return null;try{let e=statSync(S);return e.isFile()?e.size:null}catch{return null}},se,ce,ue,de,fe,me,ge,_e=null,ve=null,ye=null,Ce=null,we=new Set,Te=!1,De,je,Me,Pe=new Promise((e,t)=>{je=e,Me=t});function Ie(e){_e?.signal(e)}let Re=2e3,ze=null;function Be(){ze!==null&&clearTimeout(ze),ze=setTimeout(()=>{ze=null,ce.saveToDisk().catch(e=>{console.warn(`[backlinks] Failed to persist debounced cache:`,e)})},2e3)}let Ve=new RecentlyRemovedDocs(void 0,{onEviction:()=>incrementRecentlyRemovedDocsEviction(),onSizeChange:e=>setRecentlyRemovedDocsSize(e)}),Ue=(e,t)=>{isSystemDoc(e)||isConfigDoc(e)||Ve.setRenamed(e,t)},We=e=>{if(!(isSystemDoc(e)||isConfigDoc(e))){if(Ve.peek(e)?.kind===`renamed`){console.info(JSON.stringify({event:`recently-removed-docs-unpaired-delete-suppressed`,docName:e,source:`watcher-delete`}));return}Ve.setDeleted(e)}},Ge=e=>{isSystemDoc(e)||isConfigDoc(e)||Ve.delete(e)};try{se=createContentFilter({projectDir:s,contentDir:t,onAfterRebuild:()=>{ce.rebuildFromDisk(getActiveBranch()).catch(e=>{getLogger(`server-factory`).warn({err:e},`[content-filter] backlink-index rebuild failed after onAfterRebuild`)});try{ue.init()}catch(e){getLogger(`server-factory`).warn({err:e},`[content-filter] tag-index rebuild failed after onAfterRebuild`)}try{let e=Ft?.pruneFileIndexNowExcluded()??0;e>0&&getLogger(`server-factory`).info({pruned:e},`[content-filter] pruned now-excluded entries from fileIndex`)}catch(e){getLogger(`server-factory`).warn({err:e},`[content-filter] fileIndex prune failed after onAfterRebuild`)}}}),ce=new BacklinkIndex({projectDir:s,contentDir:t,contentFilter:se}),ue=new TagIndex({contentDir:t,contentFilter:se});try{ue.init()}catch(e){console.warn(`[server-factory] tag-index init failed; continuing with empty index:`,e)}de={current:F},fe=createPersistenceExtension({contentDir:t,projectDir:s,gitEnabled:E,commitDebounceMs:D,wipRef:O,shadowRef:de,contentRoot:L,backlinkIndex:ce,configHomedirOverride:k,getCurrentBranch:()=>It?.getLastKnownBranch()??null,resolveEmbed:ae,resolveSize:oe,getPrincipal:()=>Ce,onAgentCommit:()=>_e?.signal(`session-activity`),onDiskFlush:(e,t)=>_e?.emitDiskAck(e,t),onConfigRejected:(e,t)=>_e?.emitConfigValidationRejected(e,t),mdManager:e.mdManager}),me=new Hocuspocus({quiet:g,debounce:S,maxDebounce:w,extensions:[fe.extension]});let B=me.shouldUnloadDocument.bind(me);me.shouldUnloadDocument=e=>{if((Te||we.has(e))&&B(e))return!0;let t=e.name;return isSystemDoc(t)||isConfigDoc(t)||getReconciledBase(t)!==void 0||e.getXmlFragment(`default`).length!==0||e.getText(`source`).length!==0?!1:B(e)},De=async e=>{we.add(e);try{await me.unloadDocument(e)}finally{we.delete(e)}},_e=new CC1Broadcaster(me),ve=new AgentFocusBroadcaster(me),ye=new AgentPresenceBroadcaster(me),ge=new AgentSessionManager(me);let q=createLiveDerivedIndexExtension({backlinkIndex:ce,tagIndex:ue,signalChannel:Ie});me.configuration.extensions.push(q),me.configuration.extensions.push({__kind:`principal-auth`,async onAuthenticate(e){let t=e.token,s=parseHocuspocusAuthToken(t),g=s?.expectedServerInstanceId;if(typeof g==`string`&&g.length>0&&g!==ee)throw new HocuspocusAuthRejection(`server-instance-mismatch`,`server instance mismatch: client claimed ${g}, this server is ${ee}`);let S=s?.expectedBranch,w=getActiveBranch();if(typeof S==`string`&&S.length>0&&S!==w)throw new HocuspocusAuthRejection(`branch-mismatch`,`branch mismatch: client claimed ${S}, server is on ${w}`);if(!s)return;let E=e.context;typeof s.principalId==`string`&&(Ce&&s.principalId===Ce.id?E.principalId=Ce.id:Ce?console.warn(JSON.stringify({event:`principal-token-mismatch`,claimed:s.principalId,loaded:Ce.id})):E.principalId=s.principalId),typeof s.tabSessionId==`string`&&(E.tabSessionId=s.tabSessionId),E.kind=`human`}}),me.configuration.extensions.push({__kind:`config-doc-admission-guard`,async onAuthenticate(e){if(!isConfigDoc(e.documentName))return;let t=e.request,s=t.socket?.remoteAddress;if(s!==void 0&&!isLoopbackAddress(s))throw Error(`config-doc admission requires loopback peer (peer=${s}, doc=${e.documentName})`);let g=e.requestHeaders,S=(g&&typeof g.get==`function`?g.get(`host`):null)??t.headers?.host??void 0;if(!isAllowedWorkspaceHostHeader(S))throw Error(`config-doc admission requires loopback Host header (host=${S??`<absent>`}, doc=${e.documentName})`)}});let J=resolve(t);function Y(e){if(!isSafeDocName(e))return null;let t=resolve(J,`${e}${getDocExtension(e)}`);return!t.startsWith(`${J}/`)&&t!==J?null:t}me.configuration.extensions.push({__kind:`removal-redirect-guard`,async onAuthenticate(e){await runRemovalRedirectGuard(e.documentName,{recentlyRemovedDocs:Ve,resolveFilePath:Y,fileExists:existsSync})}}),me.configuration.extensions.push({__kind:`system-doc-broadcast-guard`,async beforeHandleMessage(e){if(e.documentName!==`__system__`)return;let t=new IncomingMessage(e.update);if(t.readVarString(),t.readVarUint()===MessageType.BroadcastStateless)throw Error(`inbound BroadcastStateless on ${SYSTEM_DOC_NAME} rejected — server-only channel`)}});let te=createApiExtension({hocuspocus:me,sessionManager:ge,contentDir:t,contentFilter:se,serverInstanceId:ee,getFileIndex:()=>Ft?Ft.getFileIndex():new Map,getFolderIndex:()=>Ft?Ft.getFolderIndex():new Map,getAliasMap:()=>Ft?Ft.getAliasMap():new Map,enableTestRoutes:j,shadowRef:de,flushGitCommit:()=>fe.flushPendingGitCommit(),flushContributors:()=>fe.flushContributors(),getCurrentBranch:()=>It?.getLastKnownBranch()??null,getDiskAckSVs:()=>_e?.getLatestDiskAckSVsAsBase64()??{},contentRoot:L,backlinkIndex:ce,tagIndex:ue,signalChannel:Ie,agentFocusBroadcaster:ve,agentPresenceBroadcaster:ye,onAgentWrite:e.onAgentWrite,getSyncEngine:()=>Lt,localOpCliArgs:H,projectDir:s,resolveEmbed:ae,getPrincipal:()=>Ce,forceUnloadDocument:De,ready:Pe,recentlyRemovedDocs:Ve});me.configuration.extensions.push(te),me.configuration.extensions.push(createServerObserverExtension({mdManager,schema,shadowRef:de,contentRoot:L,getCurrentBranch:()=>It?.getLastKnownBranch()??null,resolveEmbed:ae,resolveSize:oe}))}catch(e){throw releaseServerLock(te),e}let Ke=null,Xe=new Map,$e=[];function nt(e,t){let s=resolve(e,`rescue`),g=resolve(s,`${t}${getDocExtension(t)}`);return g.startsWith(`${s}/`)?g:null}function rt(e){let t=me.documents.get(e);if(!t)return null;let{frontmatter:s,body:g}=stripFrontmatter(t.getText(`source`).toString());return prependFrontmatter(s,g)}let it=(e,t)=>applyExternalChange(me,e,t,ae,oe),at=e=>{if(!e)return;let t=`[[${e}]]`;for(let[s]of me.documents){if(isSystemDoc(s)||isConfigDoc(s))continue;let g=me.documents.get(s);if(!g)continue;let S=g.getText(`source`).toString();if(S.includes(t))try{g.transact(()=>{applyDiskContentToDoc(g,S,ae,s)},FILE_WATCHER_ORIGIN)}catch(t){J.error({err:t,docName:s,assetBasename:e},`[asset-event] failed to re-render ${s} for asset basename ${e}`)}}},st=null,vt=e=>{e&&(st===null&&(st=new Set,setImmediate(()=>{let e=st;if(st=null,e)try{for(let t of e)at(t)}catch(t){J.error({err:t,basenames:[...e]},`[asset-event] dedup rerender pass crashed`)}})),st.add(e))};function Tt(e){switch(e.kind){case`rename`:return e.newDocName;case`asset-create`:case`asset-delete`:case`folder-create`:case`folder-delete`:return e.relativePath;case`create`:case`update`:case`delete`:case`conflict`:return e.docName;default:return assertNeverDiskEvent(e)}}async function Et(e){try{switch(e.kind){case`create`:J.info({docName:e.docName},`[reconcile] create: ${e.docName}`),ce.updateDocumentFromMarkdown(e.docName,e.content),Be(),ue.updateDocumentFromMarkdown(e.docName,e.content),Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`),Ge(e.docName);break;case`update`:{let{docName:t,content:s}=e,g=me.documents.get(t);if(!g){ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`);return}let S=getReconciledBase(t)??``,w=rt(t)??S,E=reconcile({docName:t,base:S,ours:w,theirs:s}),D=contentHash(S).slice(0,6),O=contentHash(w).slice(0,6),k=contentHash(s).slice(0,6);switch(J.info({docName:t,base:D,ours:O,theirs:k,result:E.kind},`[reconcile] ${t} base=${D} ours=${O} theirs=${k} result=${E.kind}`),E.kind){case`noop`:ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`);break;case`clean`:try{it(t,E.newContent),setReconciledBase(t,E.newContent),incrementReconcile(),ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`)}catch(e){J.error({err:e,docName:t},`[reconcile] failed to apply clean content to Y.Doc for ${t}`),setReconciledBase(t,s)}break;case`merged`:try{it(t,E.newContent),setReconciledBase(t,E.newContent),incrementReconcile(),ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`)}catch(e){J.error({err:e,docName:t},`[reconcile] failed to apply merged content to Y.Doc for ${t}`),setReconciledBase(t,s)}break;case`conflicts`:try{it(t,E.newContent),setReconciledBase(t,E.newContent),incrementReconcile(),incrementConflict(),ce.updateDocumentFromMarkdown(t,s),Be(),ue.updateDocumentFromMarkdown(t,s),Ie(`backlinks`),Ie(`graph`),Ie(`tags`)}catch(e){J.error({err:e,docName:t},`[reconcile] failed to apply conflict content to Y.Doc for ${t}`),setReconciledBase(t,s)}break;case`refused`:{incrementConflict();let e=g.getMap(`lifecycle`);e.set(`status`,`conflict`),e.set(`reason`,E.reason);break}}break}case`delete`:{let{docName:t}=e,s=me.documents.get(t);if(!s){ce.deleteDocument(t),Be(),ue.deleteDocument(t),Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`),We(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));return}let g=getReconciledBase(t)??``,S=rt(t)??``,w=S!==g;if(w&&de.current){let e=de.current,s=It?.getLastKnownBranch()??`main`;queueMicrotask(()=>{saveInMemoryCheckpoint(e,L??``,{kind:`external-change-rescue`,docName:t,contents:S,label:`External change recovered @ ${new Date().toISOString()}`,branch:s,metadata:{incomingDiskSha:``}}).then(()=>{incrementRescueBuffer(),J.info({docName:t},`[reconcile] rescue checkpoint saved (delete): ${t}`)}).catch(e=>{J.error({docName:t,err:e},`[reconcile] rescue checkpoint write failed: ${t}`)})})}s.getMap(`lifecycle`).set(`status`,`deleted-upstream`),deleteReconciledBase(t),ce.deleteDocument(t),Be(),ue.deleteDocument(t),J.info({docName:t,isDirty:w},`[reconcile] delete: ${t} (dirty=${w})`),me.closeConnections(t),await De(s),Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`),We(t),console.info(JSON.stringify({event:`recently-removed-docs-populate`,docName:t,kind:`deleted`,source:`watcher-delete`}));break}case`rename`:{let{oldDocName:t,newDocName:s,content:g}=e,S=me.documents.get(t);if(deleteReconciledBase(t),setReconciledBase(s,g),ce.renameDocument(t,s,g),Be(),ue.renameDocument(t,s,g),S){let e=S.getMap(`lifecycle`);e.set(`status`,`renamed`),e.set(`newPath`,s)}J.info({oldDocName:t,newDocName:s},`[reconcile] rename: ${t} → ${s}`),Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`),Ue(t,s),console.info(JSON.stringify({event:`recently-removed-docs-populate`,from:t,to:s,kind:`renamed`,source:`watcher-rename`}));break}case`conflict`:{let{docName:t}=e,s=me.documents.get(t);if(!s)return;let g=s.getMap(`lifecycle`);g.set(`status`,`conflict`),g.set(`reason`,`conflict-markers`),J.info({docName:t},`[reconcile] conflict markers detected: ${t}`);break}case`asset-create`:ne.add(e.relativePath),Ie(`files`),vt(basename(e.relativePath));break;case`asset-delete`:ne.remove(e.relativePath),Ie(`files`),vt(basename(e.relativePath));break;case`folder-create`:case`folder-delete`:Ie(`files`);break;default:assertNeverDiskEvent(e)}}catch(t){let s=Tt(e);J.error({err:t,kind:e.kind,label:s},`[reconcile] failed to handle ${e.kind} for ${s}`)}}let Dt=[];async function jt(e){if(isBatchInProgress()){Dt.push(e);return}await Et(e)}async function Mt(){let e=Dt.splice(0,Dt.length);for(let t of e)await Et(t)}let Ft=null,It=null,Lt=null,Rt=null;async function zt(e){if(me.documents.size===0)return;let t=!1,s=new Promise(e=>{me.configuration.extensions.push({async afterUnloadDocument({instance:s}){!t&&s.getDocumentsCount()===0&&(t=!0,e())}})}),g=Array.from(me.documents.keys());me.closeConnections(),me.flushPendingStores();for(let e of me.documents.values())e.getConnectionsCount()===0&&me.unloadDocument(e).catch(t=>{console.warn(JSON.stringify({event:`ok-shutdown-unload-document-failed`,docName:e.name,reason:t instanceof Error?t.message:String(t)}))});let S,w=new Promise((s,w)=>{S=setTimeout(()=>{t=!0;let s=Array.from(me.documents.keys()),S=[],E=[];if(de.current){for(let e of s)if(!(isSystemDoc(e)||isConfigDoc(e)))try{let t=rt(e);if(t===null){J.warn({docName:e},`[rescue] skipping ${e} — document dropped from map mid-rescue`),E.push(e);continue}let s=nt(de.current.gitDir,e);if(!s){J.warn({docName:e,gitDir:de.current.gitDir},`[rescue] path-traversal guard rejected docName: ${e}`),E.push(e);continue}mkdirSync(dirname(s),{recursive:!0}),writeFileSync(s,t,`utf-8`),incrementRescueBuffer(),S.push(e),J.info({docName:e},`[rescue] rescue buffer saved on flush timeout: ${e}`)}catch(t){E.push(e),J.error({err:t,docName:e},`[rescue] failed to write rescue buffer for ${e}`)}}else J.warn({stillLoadedCount:s.length},`[rescue] shadow repo unavailable at flush timeout — ${s.length} doc(s) will be lost: [${s.join(`, `)}]`),E.push(...s);let D=S.length>0||E.length>0?` — rescued [${S.join(`, `)}]${E.length>0?`, lost [${E.join(`, `)}]`:``}`:``;w(Error(`flushAllStoresAndWait timeout after ${e}ms — ${s.length}/${g.length} docs did not unload: [${s.join(`, `)}]${D}`))},e)});try{await Promise.race([s,w])}finally{S!==void 0&&clearTimeout(S)}}async function Bt(){return Rt||(Rt=(async()=>{let e=Date.now(),t=[];Te=!0,ze!==null&&(clearTimeout(ze),ze=null);let g,S=await Promise.race([Pe.then(()=>`completed`,e=>(J.debug({err:e},`[server] init incomplete during shutdown`),`failed`)),new Promise(e=>{g=setTimeout(()=>e(`timeout`),5e3)})]);g!==void 0&&clearTimeout(g),S===`timeout`&&J.warn({},`[server] init did not complete within 5s during shutdown`);let w=me.documents.size;try{try{try{It&&=(await It.unsubscribe(),null),Ft&&=(await Ft.unsubscribe(),null);for(let{docName:e,cleanup:t}of $e)try{await t()}catch(t){J.warn({err:t,docName:e},`[server] failed to stop config-file-watcher for ${e}`)}$e.length=0}catch(e){t.push({phase:`watcher-unsubscribe`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-1 watcher unsubscribe failed`)}try{_e?.destroy(),ye?.destroy(),Ke&&=(await Ke.disconnect(),null);for(let[e,t]of Xe)try{await t.disconnect()}catch(t){J.warn({err:t,docName:e},`[server] failed to disconnect ${e} during shutdown`)}Xe.clear()}catch(e){t.push({phase:`cc1-teardown`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-1b CC1 teardown failed`)}try{await ge.closeAll()}catch(e){t.push({phase:`agent-session-drain`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-2 agent session drain failed`)}try{await zt(B)}catch(e){t.push({phase:`flush-all-stores`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-3 flush failed`)}let e;try{await Promise.race([(async()=>{await fe.flushPendingGitCommit(),await fe.waitForPendingCommits()})(),new Promise((t,s)=>{e=setTimeout(()=>s(Error(`L2 git flush timeout`)),B)})])}catch(e){t.push({phase:`git-commit-flush`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-4 git commit flush failed`)}finally{e!==void 0&&clearTimeout(e)}try{Lt&&=(await Lt.destroy(),null)}catch(e){t.push({phase:`sync-engine-stop`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown sync-engine-stop failed`)}}finally{if(de.current){try{let e=(await esm_default({baseDir:s,timeout:{block:5e3}}).revparse(`HEAD`)).trim();e&&writeFileSync(resolve(de.current.gitDir,`last-known-head`),e,`utf-8`)}catch{}try{destroyShadowRepo(de.current)}catch(e){t.push({phase:`shadow-repo-release`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-5 destroyShadowRepo failed`)}}let g=Date.now()-e;t.length===0?J.info({documentCount:w,durationMs:g},`[server] shutdown flushed ${w} documents in ${g}ms`):J.warn({documentCount:w,durationMs:g,phaseErrors:t},`[server] shutdown flushed ${w} documents in ${g}ms with ${t.length} phase error(s)`)}}finally{try{releaseServerLock(te)}catch(e){t.push({phase:`server-lock-release`,error:e instanceof Error?e.message:String(e)}),J.error({err:e},`[server] shutdown phase-6 releaseServerLock failed`)}try{await shutdownTelemetry()}catch(e){t.push({phase:`telemetry-shutdown`,error:e instanceof Error?e.message:String(e)})}}})(),Rt)}let Vt=[];async function Ht(){try{Ce=await loadPrincipal(s),J.info({principalId:Ce.id},`[server] principal loaded`)}catch(e){J.warn({err:e},`[server] principal load failed — browser writes will use SERVICE_WRITER`)}if(!de.current)try{de.current=await initShadowRepo(s),J.info({gitDir:de.current.gitDir},`[server] history repo initialized at ${de.current.gitDir}`)}catch(e){J.error({err:e},`[server] history repo init failed`),Vt.push(`shadow-repo`)}if(de.current){let e=null;try{e=loadRenameLogIndex(de.current.gitDir),sweepLazyPopOrphans(de.current.gitDir,e),setRenameLogIndex(de.current.gitDir,e),J.info({entries:e.byTo.size},`[server] rename log loaded (${e.byTo.size} entries)`)}catch(e){J.warn({err:e},`[rename-log] boot-time load/sweep failed; rename history unavailable`)}if(e){let t=1e4;try{await Promise.race([gcRenameLog(de.current,e,{rebuild:!0}),new Promise((e,s)=>setTimeout(()=>s(Error(`boot-time GC exceeded ${t}ms`)),t))])}catch(e){J.warn({err:e},`[rename-log] boot-time GC/rebuild failed; index loaded without GC`)}}}if(de.current)try{await shadowGit(de.current).raw(`rev-parse`,`--git-dir`)}catch(e){let t=e instanceof Error?e.message:String(e);if(t.includes(`not a git repository`)||t.includes(`invalid object`)){J.warn({},`[server] history repo appears corrupted — reinitializing`);try{de.current=await initShadowRepo(s)}catch(e){J.error({err:e},`[server] history repo reinit failed`),de.current=void 0,Vt.includes(`shadow-repo`)||Vt.push(`shadow-repo`)}}else J.error({err:e},`[server] history repo check failed (transient?)`)}if(de.current)try{let e=resolve(de.current.gitDir,`last-known-head`),t=null;try{t=readFileSync(e,`utf-8`).trim()||null}catch{}let g=null;try{g=(await esm_default({baseDir:s,timeout:{block:1e4}}).revparse(`HEAD`)).trim()||null}catch{}if(g!==null){if(g!==t){let e=`main`;try{let t=(await esm_default({baseDir:s,timeout:{block:1e4}}).raw(`rev-parse`,`--abbrev-ref`,`HEAD`)).trim();t&&t!==`HEAD`&&(e=t)}catch{}J.info({lastKnownHead:t,currentHead:g,branch:e},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${g}, action=import`);try{await commitUpstreamImport(de.current,L??``,t,g,e),incrementUpstreamImport()}catch(e){J.warn({err:e},`[head-drift] commitUpstreamImport failed — continuing`)}}else J.info({currentHead:g},`[head-drift] lastKnownHead=${t??`null`}, currentHead=${g}, action=noop`);try{writeFileSync(e,g,`utf-8`)}catch(e){J.warn({err:e},`[head-drift] failed to write last-known-head`)}}}catch(e){J.warn({err:e},`[head-drift] check failed — continuing`)}try{let e=recoverPendingManagedRename(t,s);if(e.recovered&&e.journal){let t=e.journal.version===2?e.journal.fromPath:e.journal.sourceDocName,s=e.journal.version===2?e.journal.toPath:e.journal.destinationDocName;J.warn({journalVersion:e.journal.version,fromPath:t,toPath:s,restoredDocNames:e.restoredDocNames},`[managed-rename] recovered pending rename ${t} -> ${s}`)}}catch(e){J.error({err:e},`[server] managed rename recovery failed`),Vt.push(`managed-rename-recovery`)}try{let e=cleanupOrphanUploadTempfiles(s);(e.deleted>0||e.errors>0)&&J.info({scanned:e.scanned,deleted:e.deleted,errors:e.errors},`[upload-tempfile-sweep] swept ${e.deleted} orphan tempfile(s)`)}catch(e){J.error({err:e},`[server] upload-tempfile sweep failed`),Vt.push(`upload-tempfile-sweep`)}try{Ke=await me.openDirectConnection(SYSTEM_DOC_NAME),_e?.emitServerInfo(ee,getActiveBranch())}catch(e){J.error({err:e},`[server] failed to open __system__ direct connection — CC1 push disabled`),Vt.push(`cc1-push`)}for(let e of CONFIG_DOC_NAMES)try{let t=await me.openDirectConnection(e);Xe.set(e,t)}catch(t){J.error({err:t,docName:e},`[server] failed to open ${e} direct connection — config bind degraded`),Vt.push(`config-doc:${e}`)}let e=new Map([[CONFIG_DOC_NAME_PROJECT,resolveConfigPath(`project`,s)],[CONFIG_DOC_NAME_PROJECT_LOCAL,resolveConfigPath(`project-local`,s)],[CONFIG_DOC_NAME_USER,resolveConfigPath(`user`,s,k)]]);for(let t of CONFIG_DOC_NAMES){let s=e.get(t);if(s)try{J.info({docName:t,path:s},`[config-file-watcher] starting`);let e=await startConfigFileWatcher(s,e=>{let s=me.documents.get(t);J.info({docName:t,hasDocument:s!==void 0,contentLength:e.length},`[config-file-watcher] file changed`);let g=applyExternalConfigChange(s??null,t,e,fe.configPersistenceCtx);if(J.info({docName:t,outcome:g},`[config-file-watcher] applyExternalConfigChange outcome`),t===`__config__/project`||t===`__local__/project`){let e=Y();Lt?.setEnabled(e).catch(t=>{J.warn({err:t,enabled:e},`[sync] failed to apply autoSync.enabled from config`)})}});$e.push({docName:t,cleanup:e}),J.info({docName:t,path:s},`[config-file-watcher] started`)}catch(e){J.warn({err:e,docName:t,path:s},`[config-file-watcher] failed to start for ${t}`),Vt.push(`config-file-watcher:${t}`)}}try{let e=resolve(t,`.okignore`),g=resolve(s,`.gitignore`),S=J;S.info({okignorePath:e,gitignorePath:g},`[ignore-watcher] starting multi-path watcher for .okignore + .gitignore`);let w=await startMultiPathConfigFileWatcher([e,g],(t,g)=>{(async()=>{if(t===e)try{let e=applyExternalConfigChange(me.documents.get(`__config__/okignore`)??null,CONFIG_DOC_NAME_OKIGNORE,g,fe.configPersistenceCtx);S.info({docName:CONFIG_DOC_NAME_OKIGNORE,outcome:e},`[ignore-watcher] applyExternalConfigChange outcome`)}catch(e){S.error({err:e,changedPath:relative(s,t)},`[ignore-watcher] applyExternalConfigChange failed; rebuild proceeds independently`)}let w=await se.rebuildIgnorePatterns();if(w.ok)S.info({changedPath:relative(s,t),patternCount:w.patternCount,nestedFileCount:w.nestedFileCount,durationMs:w.durationMs},`[ignore-watcher] rebuild succeeded — broadcasting files channel`),_e?.signal(`files`);else{let e=relative(s,t)||`.`;S.warn({changedPath:e,error:w.error.message},`[ignore-watcher] rebuild failed — emitting config-ignore-nested-error`),_e?.emitConfigIgnoreNestedError(e,w.error.message)}})().catch(e=>{S.error({err:e,changedPath:relative(s,t)||`.`},`[ignore-watcher] handler threw`)})});$e.push({docName:`__ignore-files__`,cleanup:w}),S.info({okignorePath:e,gitignorePath:g},`[ignore-watcher] multi-path watcher started`)}catch(e){J.warn({err:e,projectDir:s,contentDir:t},`[ignore-watcher] failed to start multi-path watcher`),Vt.push(`ignore-files-watcher`)}let g=resolveGitDir(s),S=g?readBranchFromHead(g)??`main`:`main`;switchReconciledBaseScope(S),ce.switchBranch(S);try{{let e=getActiveBranch();try{if(await ce.loadFromDisk(e)){let t=await ce.reconcileWithDisk(e);(t.added>0||t.updated>0||t.deleted>0)&&J.info(t,`[backlinks] startup reconcile: offline changes applied`)}else await ce.rebuildFromDisk(e);ce.saveToDisk().catch(t=>{console.warn(`[backlinks] Failed to persist startup cache for ${e}:`,t)})}catch(t){J.error({err:t,branch:e},`[backlinks] startup init failed; index will populate incrementally via watcher`)}}Ft=await startWatcher(t,jt,se),ue.init();let e=0;try{seedBasenameIndex({contentDir:t,contentFilter:se,basenameIndex:ne,onSkip:(t,s,g)=>{e++,J.warn({reason:t,code:s,path:g},`[basename-index] skipped entry during seed (${t}${s?` ${s}`:``})`)}}),e>0&&(J.warn({count:e},`[basename-index] startup seed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve`),Vt.push(`basename-index-partial`))}catch(e){J.error({err:e},`[basename-index] startup seed failed`),Vt.push(`basename-index`)}}catch(e){J.error({err:e},`[server] disk bridge watcher failed to start`),Vt.push(`file-watcher`)}try{It=await startHeadWatcher(s,async({trigger:e})=>{if(J.info({trigger:e},`[batch] begin trigger=${e}`),incrementBatch(),me.flushPendingStores(),await fe.flushPendingGitCommit(),setBatchInProgress(!0),de.current){let e=getActiveBranch(),t=resolveGitDir(s),g=t?readBranchFromHead(t)??e:e,S=[];for(let[e,t]of me.documents){if(isSystemDoc(e)||isConfigDoc(e))continue;let s=null;if(t.transact(()=>{s=rt(e)},PARK_SNAPSHOT_ORIGIN),s===null)continue;let g=getReconciledBase(e)??s;S.push({docName:e,markdown:s,diskSnapshot:g})}if(S.length>0)try{let t=await parkBranch(de.current,e,SERVICE_WRITER.id,S,g);t&&(incrementPark(),J.info({count:S.length,branch:e,sha:t.slice(0,8)},`[history] parked ${S.length} docs on ${e} → ${t.slice(0,8)}`))}catch(e){J.error({err:e},`[shadow] park failed`)}}},async e=>{let s=Dt.length,g=e.newBranch??`main`;if(J.info({kind:e.batchKind,headMoved:e.headMoved,docs:s,timeout:!!e.timeout},`[batch] end kind=${e.batchKind} headMoved=${e.headMoved} docs=${s}${e.timeout?` timeout`:``}`),e.batchKind===`within-branch`)setBatchInProgress(!1),await Mt(),await fe.flushDeferredStores(`within-branch`);else{incrementBranchSwitch(),Dt.splice(0,Dt.length),switchReconciledBaseScope(g),ze!==null&&(clearTimeout(ze),ze=null),ce.switchBranch(g),se.rebuildDirCount();try{let e=0;ne.clear(),seedBasenameIndex({contentDir:t,contentFilter:se,basenameIndex:ne,onSkip:(t,s,S)=>{e++,J.warn({reason:t,code:s,path:S,branch:g},`[basename-index] skipped entry during branch-switch reseed (${t}${s?` ${s}`:``})`)}}),e>0&&(J.warn({count:e,branch:g},`[basename-index] branch-switch reseed completed with ${e} skipped entries — embeds under inaccessible subtrees will not resolve on this branch`),Vt.includes(`basename-index-partial`)||Vt.push(`basename-index-partial`))}catch(e){J.error({err:e,branch:g},`[basename-index] branch-switch reseed failed`)}for(let[e,s]of me.documents)if(!(isSystemDoc(e)||isConfigDoc(e)))try{let S=safeContentPath(e,t);if(!existsSync(S)){let t=getReconciledBase(e)??``,S=rt(e)??``;if(S!==t&&de.current){let t=de.current;queueMicrotask(()=>{saveInMemoryCheckpoint(t,L??``,{kind:`external-change-rescue`,docName:e,contents:S,label:`External change recovered @ ${new Date().toISOString()}`,branch:g,metadata:{incomingDiskSha:``}}).then(()=>{incrementRescueBuffer(),J.info({docName:e},`[reconcile] rescue checkpoint saved on branch switch: ${e}`)}).catch(t=>{J.error({docName:e,err:t},`[reconcile] rescue checkpoint write failed: ${e}`)})})}s.getMap(`lifecycle`).set(`status`,`deleted-upstream`),J.info({docName:e,branch:g},`[branch-switch] tombstone: ${e} (not on ${g})`);continue}let w=readFileSync(S,`utf-8`);it(e,w),setReconciledBase(e,w),J.info({docName:e},`[branch-switch] reset: ${e}`)}catch(t){J.error({err:t,docName:e},`[branch-switch] failed to reset ${e}`)}J.info({branch:g,docCount:me.documents.size},`[branch-switch] loaded branch ${g} (${me.documents.size} docs)`);try{if(await ce.loadFromDisk(g)){let e=await ce.reconcileWithDisk(g);(e.added>0||e.updated>0||e.deleted>0)&&J.info(e,`[backlinks] branch-switch reconcile for ${g}`)}else await ce.rebuildFromDisk(g);ce.saveToDisk(g).catch(e=>{console.warn(`[backlinks] Failed to persist branch cache for ${g}:`,e)})}catch(e){J.error({err:e,branch:g},`[backlinks] branch-switch rebuild failed; backlinks may be stale`)}if(ue.init(),de.current&&e.batchKind===`cross-branch`){let e=0;for(let[t]of me.documents)if(!(isSystemDoc(t)||isConfigDoc(t)))try{let s=await readParkedState(de.current,g,SERVICE_WRITER.id,t);if(!s||s.markdown===s.diskSnapshot)continue;let S=getReconciledBase(t);if(!S)continue;let w=reconcile({docName:t,base:s.diskSnapshot,ours:s.markdown,theirs:S});switch(w.kind){case`merged`:case`clean`:it(t,w.newContent),setReconciledBase(t,w.newContent),e++;break;case`conflicts`:it(t,w.newContent),setReconciledBase(t,w.newContent),incrementConflict(),e++;break;case`noop`:case`refused`:break}}catch(e){J.error({err:e,docName:t},`[branch-switch] restore WIP failed for ${t}`)}e>0&&J.info({count:e,branch:g},`[branch-switch] restored ${e} parked docs on ${g}`)}if(e.oldBranch?.startsWith(`detached-`)&&de.current)try{let t=shadowGit(de.current),s=(await t.raw(`for-each-ref`,`refs/wip/${e.oldBranch}/`,`--format=%(refname)`)).trim();if(s){for(let e of s.split(`
|
|
2583
2583
|
`))e&&await t.raw(`update-ref`,`-d`,e);J.info({context:e.oldBranch},`[branch-switch] cleaned up detached context ${e.oldBranch}`)}}catch(e){J.error({err:e},`[branch-switch] detached cleanup failed`)}setBatchInProgress(!1),await fe.flushDeferredStores(`discard-stale`),_e?.emitBranchSwitched(g)}if(e.headMoved&&e.newHead&&de.current&&s>0){let t=L??`.`;try{let s=await commitUpstreamImport(de.current,t,e.oldHead,e.newHead,g);incrementUpstreamImport(),J.info({oldHead:e.oldHead?.slice(0,8)??`null`,newHead:e.newHead.slice(0,8),sha:s.slice(0,8)},`[history] upstream-import from ${e.oldHead?.slice(0,8)??`null`}..${e.newHead.slice(0,8)} → ${s.slice(0,8)}`)}catch(e){J.error({err:e},`[shadow] upstream-import failed`)}}})}catch(e){J.error({err:e},`[server] HEAD watcher failed to start`),Vt.push(`head-watcher`)}let w=H?.[0]??`open-knowledge`,E=[`-c`,`credential.helper=!${H&&H.length>1?H.join(` `):w} auth git-credential`];try{Lt=new SyncEngine({projectDir:s,contentDir:t,contentFilter:se,contentRoot:L,syncEnabled:Y(),credentialArgs:E,cc1Broadcaster:_e,setBatchInProgress:e=>{setBatchInProgress(e),e||fe.flushDeferredStores(`within-branch`).catch(e=>{J.error({err:e},`[persistence] deferred store drain failed after sync batch`)})},onStateChange:e=>{J.info({state:e},`[sync] state → ${e}`)},onAutoDisable:async e=>{J.warn({reason:e},`[sync] auto-disabled — persisting to project-local config`);let t=await writeConfigPatch({cwd:s,scope:`project-local`,patch:{autoSync:{enabled:!1}}});t.ok||J.error({result:t,reason:e,humanError:humanFormat(t.error),configPath:resolveConfigPath(`project-local`,s)},`[sync] failed to persist auto-disable — next restart WILL re-enable sync and re-trigger the same failure. Check permissions on the config path.`)}}),await Lt.start()}catch(e){J.warn({err:e},`[server] SyncEngine failed to start — sync disabled`),Lt=null}Ie(`files`),Ie(`backlinks`),Ie(`graph`),Ie(`tags`)}return Ht().then(je,Me),{hocuspocus:me,sessionManager:ge,cc1Broadcaster:_e,agentFocusBroadcaster:ve,agentPresenceBroadcaster:ye,contentFilter:se,basenameIndex:ne,serverInstanceId:ee,destroy:Bt,ready:Pe,degraded:Vt,lockDir:te,get syncEngine(){return Lt}}}const LEGACY_RUNTIME_FILENAMES=[`server.lock`,`ui.lock`,`state.json`,`principal.json`,`sync-state.json`,`conflicts.json`,`last-spawn-error.log`],LEGACY_RUNTIME_DIRNAMES=[`cache`,`tmp`];function findLegacyRuntimeFiles(e){let t=resolve(e,LOCAL_DIR);if(!(()=>{if(!existsSync(t))return!0;try{return readdirSync(t).length===0}catch{return!0}})())return[];let s=[];for(let t of LEGACY_RUNTIME_FILENAMES)existsSync(resolve(e,t))&&s.push(t);for(let t of LEGACY_RUNTIME_DIRNAMES){let g=resolve(e,t);try{existsSync(g)&&statSync(g).isDirectory()&&s.push(`${t}/`)}catch{}}return s}function computeWorktreeAttributes(e){let t=resolveGitDirDetailed(e);switch(t.kind){case`directory`:return{kind:`main`,gitdir:t.path};case`linked`:return{kind:`linked`,gitdir:t.path};case`malformed-pointer`:return{kind:`linked`,gitdir:null};case`inaccessible`:case`absent`:return{kind:`main`,gitdir:null}}}const DEFAULT_IDLE_THRESHOLD_MS=1800*1e3,DESTROY_STEP_TIMEOUT_MS=5e3;async function bootServer(e){initTelemetry();let{kind:t,gitdir:s}=computeWorktreeAttributes(e.projectDir??e.contentDir),g={"ok.worktree.kind":t};return s!==null&&(g[`ok.worktree.gitdir`]=normalizeFsPath(s)),withSpan(`ok.boot`,{attributes:g},async()=>bootServerInner(e))}async function bootServerInner(e){let t=e.skipAutoInit??!1,s=e.attachUiSibling??!0,g=e.idleShutdownMs,S=e.log??getLogger(`boot`),w=process.env.OK_LOCK_KIND===`mcp-spawned`||process.env.OK_LOCK_KIND===`interactive`?process.env.OK_LOCK_KIND:void 0,E=e.lockKind??w??`interactive`,{createServer:D}=await import(`node:http`),{updateServerLockPort:O}=await import(`./server-lock-D7DXNVql-B5nINglj.mjs`).then(e=>e.a),k=!1;if(!t&&e.autoInitFn)try{k=!!await e.autoInitFn()}catch(e){S.warn({err:e},`autoInitFn failed`)}let j=e.projectDir??e.contentDir,F=resolve(j,`.ok`);if(!existsSync(resolve(F,`config.yml`)))throw new MissingOkConfigError(existsSync(F)?`config`:`okdir`,j);existsSync(resolve(F,`.gitignore`))||console.warn("[boot] Note: .ok/.gitignore is missing — per-machine state files in .ok/ may show up as untracked changes. Run `ok init` to add the recommended ignore entries.");let L=findLegacyRuntimeFiles(F);L.length>0&&console.warn(`[boot] Found legacy runtime files at .ok/${L.join(`, `)}. Delete .ok/ and re-init — these files moved to .ok/${LOCAL_DIR}/.`);let B=createServer$1({contentDir:e.contentDir,projectDir:e.projectDir,contentRoot:e.contentRoot,port:e.port,host:e.host,quiet:e.quiet??!1,debounce:e.debounce,maxDebounce:e.maxDebounce,gitEnabled:e.gitEnabled,commitDebounceMs:e.commitDebounceMs,wipRef:e.wipRef,enableTestRoutes:e.enableTestRoutes,shadowRepo:e.shadowRepo,destroyTimeoutMs:e.destroyTimeoutMs,localOpCliArgs:e.localOpCliArgs,onAgentWrite:e.onAgentWrite,lockKind:E,skipStateManifestCheck:e.skipStateManifestCheck}),{hocuspocus:H,destroy:q,ready:J,degraded:Y,lockDir:ee,sessionManager:te,agentFocusBroadcaster:ne,agentPresenceBroadcaster:ae}=B,oe=(()=>{let t=e.host??`localhost`;return t===`0.0.0.0`||t===`::`?`localhost`:t.includes(`:`)&&!t.startsWith(`[`)?`[${t}]`:t})(),se=e.port??0,ce=createMcpHttpHandler({contentDir:e.contentDir,projectDir:e.projectDir??e.contentDir,config:e.config,getServerUrl:()=>`http://${oe}:${se}`,log:S}),ue=D();ue.headersTimeout=3e4,ue.requestTimeout=6e4;let de=e.serveContentAssets?createAssetServeMiddleware({contentFilter:B.contentFilter,contentSirv:build_default(e.contentDir,{dev:!0,dotfiles:!1}),inlineExtensions:INLINE_RENDERABLE_EXTENSIONS,assetExtensions:ASSET_EXTENSIONS,blocklistExtensions:EXECUTABLE_BLOCKLIST_EXTENSIONS}):void 0,fe=mountMcpAndApi({httpServer:ue,hocuspocus:H,mcpHttpHandler:ce,log:S,sessionManager:te,agentFocusBroadcaster:ne,agentPresenceBroadcaster:ae,keepaliveGraceMs:e.keepaliveGraceMs,contentAssetMiddleware:de}),me=null;g!==null&&(me=attachIdleShutdown({httpServer:ue,thresholdMs:g??DEFAULT_IDLE_THRESHOLD_MS,log:S,onShutdown:(e.idleShutdownHandler??(e=>async()=>{await e()}))(async()=>{await q()})})),await new Promise((t,s)=>{let g=e=>s(e);ue.once(`error`,g),ue.listen(e.port,e.host,()=>{ue.removeListener(`error`,g),t()})});let ge=ue.address(),_e=typeof ge==`object`&&ge?ge.port:e.port??0;if(se=_e,O(ee,_e),s&&e.spawnUiSiblingFn)try{await e.spawnUiSiblingFn({lockDir:ee,log:S})}catch(e){S.warn({err:e},`spawnUiSiblingFn failed`)}let ve=!1,ye=async(e,t)=>{let s;try{await Promise.race([t(),new Promise((t,g)=>{s=setTimeout(()=>{g(Error(`${e} timed out after ${DESTROY_STEP_TIMEOUT_MS}ms`))},DESTROY_STEP_TIMEOUT_MS),s.unref?.()})])}finally{s!==void 0&&clearTimeout(s)}};return{httpServer:ue,destroy:async()=>{if(ve)return;ve=!0;let e=[],t=async(t,s)=>{try{await ye(t,s)}catch(s){e.push(s),S.warn({err:s,step:t},`bootServer destroy step failed`)}};try{me?.detach()}catch(t){e.push(t),S.warn({err:t,step:`idleHandle.detach`},`bootServer destroy step failed`)}if(await t(`mount.shutdown`,()=>fe.shutdown()),await t(`mcpHttpHandler.close`,()=>ce.close()),await t(`mount.wss.close`,()=>new Promise((e,t)=>{fe.wss.close(s=>s?t(s):e())})),await t(`httpServer.closeAllConnections`,async()=>{ue.closeAllConnections?.()}),await t(`httpServer.close`,()=>new Promise((e,t)=>{ue.close(s=>s&&s.code!==`ERR_SERVER_NOT_RUNNING`?t(s):e())})),await t(`destroyHocuspocus`,()=>q()),await t(`shutdownTelemetry`,()=>shutdownTelemetry()),e.length>0)throw AggregateError(e,`bootServer destroy completed with errors`)},lockDir:ee,contentDir:e.contentDir,port:_e,ready:J,degraded:Y,didAutoInit:k,serverInstance:B}}const ConfigSchema=ConfigSchema$1;function detectClaudeDesktopPresence(e={}){let t=e.home??homedir(),s=e.platformName??process.platform,g=e.env??process.env;return s===`darwin`?existsSync(join(t,`Library`,`Application Support`,`Claude`)):s===`win32`?existsSync(join(g.APPDATA??join(t,`AppData`,`Roaming`),`Claude`)):!1}const ANCESTOR_WALK_DEPTH_LIMIT$1=30,GIT_MARKER=`.git`;function findEnclosingGitRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT$1;){let e=!1;try{e=existsSync(resolve(t,GIT_MARKER))}catch{e=!1}if(e)return{gitRoot:t,distance:s};let g=dirname(t);if(g===t)return null;t=g,s+=1}return null}const ANCESTOR_WALK_DEPTH_LIMIT=30,OK_CONFIG_MARKER=`.ok/config.yml`;function findEnclosingProjectRoot(e){let t=resolve(e),s=0;for(;s<ANCESTOR_WALK_DEPTH_LIMIT;){let e=!1;try{e=existsSync(resolve(t,OK_CONFIG_MARKER))}catch{e=!1}if(e)return{rootPath:t,distance:s};let g=dirname(t);if(g===t)return null;t=g,s+=1}return null}const execFileAsync=promisify(execFile);var ProjectGitInitError=class extends Error{stderr;constructor(e,t=``,s){super(e,s),this.name=`ProjectGitInitError`,this.stderr=t}};async function isInsideExistingWorkTree(e){try{let{stdout:t}=await execFileAsync(`git`,[`rev-parse`,`--is-inside-work-tree`],{cwd:e});return t.trim()===`true`}catch{return!1}}async function ensureProjectGit(e){let t=resolve(e),s=resolve(t,`.git`),g=resolve(s,`HEAD`),S=!1;if(existsSync(s)){if(!statSync(s).isDirectory()||existsSync(g))return{didInit:!1};console.log(`[project-git] detected partial .git/ — running git init to repair`),S=!0}else if(await isInsideExistingWorkTree(t))return{didInit:!1};let w=``;try{w=(await execFileAsync(`git`,[`init`,`--initial-branch=main`,t])).stderr??``}catch(e){let s=typeof e==`object`&&e&&`stderr`in e?String(e.stderr??``):``;throw new ProjectGitInitError(`git init failed at ${t}: ${e instanceof Error?e.message:String(e)}`,s,{cause:e})}if(!existsSync(g))throw new ProjectGitInitError(`git init reported success but ${s}/HEAD is missing (partial init detected)`,w);return S?(console.log(`[project-git] backfilled missing .git/HEAD at ${t}`),{didInit:!0,repaired:!0}):(console.log(`[project-git] initialized .git/ at ${t} (branch: main)`),{didInit:!0})}async function resolvePackageVersion(e,t){let s;try{s=createRequire(t).resolve(e)}catch(e){if(e?.code===`MODULE_NOT_FOUND`)return;throw e}for(let t=dirname(s),g=0;g<32;g+=1){let s=join(t,`package.json`);if(existsSync(s))try{let t=JSON.parse(await readFile$1(s,`utf-8`));if(t.name===e&&typeof t.version==`string`)return t.version}catch{}let g=dirname(t);if(g===t)return;t=g}}export{applySeed as $,runAuthReposSubprocess as $n,incrementCollabSocketFilteredError as $t,MissingOkConfigError as A,readServerPackageVersion as An,updateUiLockPort as Ar,createServer$1 as At,STARTER_FOLDER_FRONTMATTER_FILENAME as B,registerWrite as Bn,McpServer as Br,findEnclosingGitRoot as Bt,LOG_MD_TEMPLATE as C,parseHocuspocusAuthToken as Cn,tracedRenameSync as Cr,createContentFilter as Ct,MCP_SERVER_NAME as D,planSeed as Dn,tracedWriteFile as Dr,createMcpHttpHandler as Dt,MCP_CONNECTION_ID_HEADER as E,planPersonalTemplates as En,tracedUnlinkSync as Er,createLiveDerivedIndexExtension as Et,ProjectGitInitError as F,readUiLock as Fn,withSpanSync as Fr,detectProjectShape as Ft,SeedPrerequisiteError as G,resolveContentDir as Gn,isJSONRPCResultResponse as Gr,getCurrentMcpLogger as Gt,STARTER_PACK_IDS as H,removeLastKnownHash as Hn,LATEST_PROTOCOL_VERSION as Hr,formatAuthRejectionWire as Ht,ROLLBACK_ORIGIN as I,reconcile as In,writePersonalTemplates as Ir,ensureProjectGit as It,TagIndex as J,resolveLockDir as Jn,writeConfigPatch as Jr,getMeter as Jt,SeedRootDirError as K,resolveCursorBinaryDefault as Kn,readConfigSafely as Kr,getLocalDir as Kt,SERVICE_WRITER as L,recordContributor as Ln,writeStateManifest as Lr,errorResponse as Lt,PERSONAL_TEMPLATES as M,readStateManifest as Mn,validateCloneInputs as Mr,createStreamingErrorWriter as Mt,PERSONAL_TEMPLATE_NAMES as N,readTargetRecordedAt as Nn,validateSkillZip as Nr,createTestLogger as Nt,MISSING_OK_CONFIG_MESSAGE as O,readAllTargets as On,tracedWriteFileSync as Or,createOsProbe as Ot,PinoLogger as P,readTargetVersion as Pn,withSpan as Pr,detectClaudeDesktopPresence as Pt,applyExternalChange as Q,rewriteWikiLinksForDocumentRename as Qn,handleSpawnCursor as Qt,SKILL_INSTALL_EVENTS_FILE_REL as R,recordSkillInstallEvent as Rn,writeTargetVersion as Rr,evictStaleTrackerEntries as Rt,LIVE_DERIVED_INDEX_DEBOUNCE_MS as S,parseAuthRejectionWire as Sn,tracedRename as Sr,createAssetServeMiddleware as St,MAX_AGENT_SESSIONS as T,pathToDocName as Tn,tracedRmdirSync as Tr,createExternalChangeHandler as Tt,STARTER_TEMPLATES as U,resetMetrics as Un,isInitializedNotification as Ur,formatContributors as Ut,STARTER_PACKS as V,releaseUiLock as Vn,JSONRPCMessageSchema as Vr,findEnclosingProjectRoot as Vt,STATE_MANIFEST_FILENAME as W,resolveBundledSkillDir as Wn,isJSONRPCRequest as Wr,gcCheckpointRefs as Wt,acquireUiLock as X,resolvePackageVersion as Xn,MalformedGitPointerError as Xr,getTracer as Xt,UiLockCollisionError as Y,resolvePack as Yn,GitDirAccessError as Yr,getMetrics as Yt,applyAgentMarkdownWrite as Z,rewriteMarkdownLinksForDocumentRename as Zn,handleCollabSocketError as Zt,GIT_UPSTREAM_WRITER as _,listStarterPacks as _n,toBroadcasterKey as _r,commitWipFromTree as _t,AgentPresenceBroadcaster as a,isAllowedApiOrigin as an,safeSubdir as ar,buildExecResult as at,HocuspocusAuthTokenSchema as b,mountMcpAndApi as bn,tracedMkdir as br,contributorCount as bt,BacklinkIndex as c,isHocuspocusAuthRejectionReason as cn,saveInMemoryCheckpoint as cr,buildSkillZip as ct,CURSOR_BUNDLE_PATHS_BY_PLATFORM as d,isPairedWriteOrigin as dn,setActiveSpanAttributes as dr,classifyEvents as dt,incrementServerObserverFire as en,runAuthStatusSubprocess as er,assertCompatibleStateManifest as et,ConfigSchema as f,isPathWithinDir as fn,shadowGit as fr,classifyFsPath as ft,FILE_WATCHER_ORIGIN as g,listRescueCheckpoints as gn,streamingProblemEvent as gr,commitWip as gt,FILE_SYSTEM_WRITER as h,lastKnownHash as hn,startWatcher as hr,commitUpstreamImport as ht,AgentFocusBroadcaster as i,installUserSkill as in,safeContentPath as ir,buildAndOpenSkill as it,OBSERVER_SYNC_ORIGIN as j,readSkillInstallStateSnapshot as jn,validateAgentId as jr,createServerObserverExtension as jt,McpLogger as k,readBranchFromHead as kn,updateLastKnownHash as kr,createPersistenceExtension as kt,CC1Broadcaster as l,isKnownPackId as ln,saveVersion as lr,buildStarterFolderFrontmatterYaml as lt,DEFAULT_PACK_ID as m,isSystemDoc as mn,splitMarkdownBlocks as mr,coercePackId as mt,AGENT_ID_RE as n,initTelemetry as nn,runDeviceFlowSubprocess as nr,attachIdleShutdown as nt,AgentSessionCapacityError as o,isAllowedWorkspaceHostHeader as on,safetyCheckpoint as or,buildInstructions as ot,DEFAULT_CHECKPOINT_RETENTION as p,isSelfWrite as pn,shutdownTelemetry as pr,clearContributors as pt,StateManifestError as q,resolveCursorSpawnInvocation as qn,resolveConfigPath as qr,getLogger as qt,AGENT_WRITE_ORIGIN as r,installTestLoggers as rn,runWithMcpLogger as rr,bootServer as rt,AgentSessionManager as s,isConfigDoc as sn,sanitizeClientName as sr,buildReadResult as st,AGENT_ID_MAX_LEN as t,initShadowRepo as tn,runCloneSubprocess as tr,assertNeverDiskEvent as tt,CONFLICT_MARKER_RE as u,isLoopbackAddress as un,seedBasenameIndex as ur,buildWipTree as ut,HOCUSPOCUS_AUTH_REJECTION_REASONS as v,loadPrincipal as vn,tracedAppendFileSync as vr,containsConflictMarkers as vt,MANAGED_RENAME_ORIGIN as w,parseKeepaliveConnectionId as wn,tracedRmSync as wr,createContentFilterAsync as wt,INSTALLED_AGENTS_SCHEMES as x,normalizeFsPath as xn,tracedMkdirSync as xr,createApiExtension as xt,HocuspocusAuthRejection as y,loggerFactory as yn,tracedLinkSync as yr,contentHash as yt,STARTER_FOLDERS as z,registerAllTools as zn,writeTracker as zr,extractWikiLinksFromMarkdown as zt};
|
|
2584
|
-
//# sourceMappingURL=dist-
|
|
2584
|
+
//# sourceMappingURL=dist-C2XvqbzG.mjs.map
|